Skip to content

Fix version menu bug #650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 121 additions & 27 deletions spec/_static/javascripts/version_dropdown.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,140 @@
function assign_href(a, url, path) {
fetch(url + "/" + path).then(response => {
/**
* Returns a promise for resolving a URL corresponding to a versioned resource (if one exists).
*
* @private
* @param {string} url - base URL
* @param {string} path - resource path
* @returns {Promise} promise which resolves a resource URL
*/
function href(url, path) {
const defaultURL = url + "/index.html";
url += "/" + path;

// If a versioned resource exists, return the resource's URL; otherwise, return a default URL:
const opts = {
'method': 'HEAD'
};
return fetch(url, opts).then(onResponse).catch(onError);

/**
* Callback invoked upon successfully resolving a resource.
*
* @private
* @param {Object} response - response object
*/
function onResponse(response) {
if (response.ok) {
a.href = url + "/" + path;
} else {
a.href = url + "/index.html";
return url;
}
}).catch(error => {
a.href = url + "/index.html";
});
return defaultURL;
}

/**
* Callback invoked upon failing to resolve a resource.
*
* @private
* @param {Error} error - error object
*/
function onError(error) {
return defaultURL;
}
}

function add_version_dropdown(json_loc, target_loc, text) {
var dropdown = document.createElement("div");
/**
* Adds a version dropdown menu with custom URL paths depending on the current page.
*
* @param {string} json_loc - JSON URL
* @param {string} target_loc - target URL
* @param {string} text - text
* @returns {Promise} promise which resolves upon adding a version menu
*/
async function add_version_dropdown(json_loc, target_loc, text) {
const dropdown = document.createElement("div");
dropdown.className = "md-flex__cell md-flex__cell--shrink dropdown";
var button = document.createElement("button");

const button = document.createElement("button");
button.className = "dropdownbutton";
var content = document.createElement("div");

const content = document.createElement("div");
content.className = "dropdown-content md-hero";

dropdown.appendChild(button);
dropdown.appendChild(content);
$.getJSON(json_loc, function(versions) {
var currentURL = window.location.href;
var path = currentURL.split(/_site|array_api/)[1];

const opts = {
'method': 'GET'
};
await fetch(json_loc, opts).then(onResponse).then(onVersions).catch(onError);

/**
* Callback invoked upon resolving a resource.
*
* @private
* @param {Object} response - response object
*/
function onResponse(response) {
return response.json();
}

/**
* Callback invoked upon resolving a JSON resource.
*
* @private
* @param {Object} versions - versions object
* @returns {Promise} promise which resolves upon processing version data
*/
async function onVersions(versions) {
// Resolve the current browser URL:
const currentURL = window.location.href;

// Check whether the user is currently on a resource page (e.g., is viewing the specification for a particular function):
let path = currentURL.split(/_site|array\-api/)[1];

// Extract the resource subpath:
if (path) {
path = path.split("/");
path = path.slice(2, path.length);
path = path.join("/");
for (var key in versions) {
if (versions.hasOwnProperty(key)) {
var a = document.createElement("a");
a.innerHTML = key;
a.title = key;
assign_href(a, target_loc + versions[key], path);
content.appendChild(a);
}
} else {
path = "";
}
// For each version, create an anchor element and attempt to resolve a given resource for that version...
const promises = [];
const el = [];
for (let key in versions) {
if (versions.hasOwnProperty(key)) {
let a = document.createElement("a");
a.innerHTML = key;
a.title = key;
el.push(a);
promises.push(href(target_loc + versions[key], path));
}
}
}).done(function() {
// Resolve all resource URLs:
const urls = await Promise.all(promises);

// Append the version links to the dropdown menu:
for (let i = 0; i < urls.length; i++) {
let a = el[i];
a.href = urls[i];
content.appendChild(a);
}
// Set the button text:
button.innerHTML = text;
}).fail(function() {

// Append dropdown:
$(".navheader").append(dropdown);
}

/**
* Callback invoked upon failing to resolve a resource.
*
* @private
*/
function onError() {
button.innerHTML = "Other Versions Not Found";
}).always(function() {

// Append dropdown:
$(".navheader").append(dropdown);
});
}
};