-
Notifications
You must be signed in to change notification settings - Fork 95
Implement a new version selection dropdown in the header with custom styling and JavaScript logic. #2106
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
Implement a new version selection dropdown in the header with custom styling and JavaScript logic. #2106
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,15 +22,15 @@ | |
| /* | ||
| * Initialize highlightjs | ||
| */ | ||
| window.addEventListener("DOMContentLoaded", function() { | ||
| window.addEventListener("DOMContentLoaded", function () { | ||
| hljs.initHighlightingOnLoad(); | ||
| }); | ||
| (function() { | ||
| if(document.querySelector('.tab-selector')){ | ||
| document.querySelector('.tab-selector').addEventListener('click', function(e) { | ||
| (function () { | ||
| if (document.querySelector('.tab-selector')) { | ||
| document.querySelector('.tab-selector').addEventListener('click', function (e) { | ||
| // Show hide tab content next to the clicked tab | ||
| var tabContentToShow = e.target.nextElementSibling; | ||
| if(tabContentToShow.style.display === 'none') { | ||
| if (tabContentToShow.style.display === 'none') { | ||
| tabContentToShow.style.display = 'block'; | ||
| } else { | ||
| tabContentToShow.style.display = 'none'; | ||
|
|
@@ -39,18 +39,18 @@ window.addEventListener("DOMContentLoaded", function() { | |
| } | ||
| })(); | ||
|
|
||
| /* | ||
| * Initialize custom dropdown component | ||
|
|
||
| // Initialize custom dropdown component | ||
|
|
||
| var dropdowns = document.getElementsByClassName('md-tabs__dropdown-link'); | ||
| var dropdownItems = document.getElementsByClassName('mb-tabs__dropdown-item'); | ||
|
|
||
| function indexInParent(node) { | ||
| var children = node.parentNode.childNodes; | ||
| var num = 0; | ||
| for (var i=0; i < children.length; i++) { | ||
| if (children[i]==node) return num; | ||
| if (children[i].nodeType==1) num++; | ||
| for (var i = 0; i < children.length; i++) { | ||
| if (children[i] == node) return num; | ||
| if (children[i].nodeType == 1) num++; | ||
| } | ||
| return -1; | ||
| } | ||
|
|
@@ -77,7 +77,7 @@ for (var i = 0; i < dropdowns.length; i++) { | |
| }; | ||
|
|
||
|
|
||
| * Reading versions | ||
| // Reading versions | ||
|
|
||
| var pageHeader = document.getElementById('page-header'); | ||
| var docSetLang = pageHeader.getAttribute('data-lang'); | ||
|
|
@@ -87,104 +87,135 @@ var docSetLang = pageHeader.getAttribute('data-lang'); | |
| docSetLang = docSetLang + '/'; | ||
|
|
||
| var docSetUrl = window.location.origin + '/' + docSetLang; | ||
| var request = new XMLHttpRequest(); | ||
|
|
||
| request.open('GET', docSetUrl + | ||
| 'versions/assets/versions.json', true); | ||
| var langRoot = window.location.origin + '/' + docSetLang; | ||
| var activeRoot = window.location.origin + window.location.pathname.substring(0, window.location.pathname.indexOf('/', 4) + 1); | ||
|
|
||
| request.onload = function() { | ||
| if (request.status >= 200 && request.status < 400) { | ||
|
|
||
| var data = JSON.parse(request.responseText); | ||
| var dropdown = document.getElementById('version-select-dropdown'); | ||
| var checkVersionsPage = document.getElementById('current-version-stable'); | ||
|
|
||
|
|
||
| * Appending versions to the version selector dropdown | ||
| if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { | ||
| docSetUrl = window.location.origin + '/en/latest/'; | ||
| activeRoot = window.location.origin + '/en/latest/'; | ||
| langRoot = window.location.origin + '/en/'; | ||
| } | ||
|
|
||
| if (dropdown){ | ||
| data.list.sort().forEach(function(key, index){ | ||
| var versionData = data.all[key]; | ||
| var request = new XMLHttpRequest(); | ||
|
|
||
| if(versionData) { | ||
| var liElem = document.createElement('li'); | ||
| var docLinkType = data.all[key].doc.split(':')[0]; | ||
| var target = '_self'; | ||
| var url = data.all[key].doc; | ||
| request.open('GET', activeRoot + | ||
| 'versions/assets/versions.json', true); | ||
|
|
||
| var currentPath= window.location.pathname; | ||
| // Find the index of '/en/' | ||
| var pathWithoutEn = currentPath.substring(4,currentPath.length); | ||
| var pathWithoutVersion = pathWithoutEn.substring(pathWithoutEn.indexOf("/"), pathWithoutEn.length) | ||
| request.onload = function () { | ||
| if (request.status >= 200 && request.status < 400) { | ||
|
|
||
| url = docSetUrl + key+ pathWithoutVersion; | ||
| var data = JSON.parse(request.responseText); | ||
| var dropdown = document.getElementById('version-select-dropdown'); | ||
| var checkVersionsPage = document.getElementById('current-version-stable'); | ||
|
|
||
|
|
||
| liElem.className = 'md-tabs__item mb-tabs__dropdown'; | ||
| liElem.innerHTML = '<a href="'+ url+'">' + key + '</a>'; | ||
| // Appending versions to the version selector dropdown | ||
|
|
||
| dropdown.insertBefore(liElem, dropdown.firstChild); | ||
| } | ||
| }); | ||
| function compareSemVer(a, b) { | ||
| // implement a compareSemVer function that splits version strings by '.' and compares each numeric segment | ||
| var partsA = a.split('.').map(Number); | ||
| var partsB = b.split('.').map(Number); | ||
| for (var i = 0; i < Math.max(partsA.length, partsB.length); i++) { | ||
| var valA = partsA[i] || 0; | ||
| var valB = partsB[i] || 0; | ||
| if (valA !== valB) return valA - valB; // Ascending like default sort() | ||
| } | ||
| return a.localeCompare(b); | ||
| } | ||
|
|
||
| document.getElementById('show-all-versions-link') | ||
| .setAttribute('href', docSetUrl + 'versions'); | ||
| } | ||
| if (dropdown) { | ||
| data.list.sort(compareSemVer).forEach(function (key, index) { | ||
| var versionData = data.all[key]; | ||
|
|
||
| if (versionData) { | ||
| var liElem = document.createElement('li'); | ||
| var docLinkType = data.all[key].doc.split(':')[0]; | ||
| var target = '_self'; | ||
| var url = data.all[key].doc; | ||
|
|
||
| var currentPath = window.location.pathname; | ||
| // Find the index of '/en/' | ||
| var pathWithoutEn = currentPath.substring(4, currentPath.length); | ||
| var pathWithoutVersion = pathWithoutEn.substring(pathWithoutEn.indexOf("/"), pathWithoutEn.length); | ||
|
|
||
| if (docLinkType === 'https' || docLinkType === 'http') { | ||
| // For external links (older versions), go directly to the configured URL for that version plus the path | ||
| url = data.all[key].doc.replace(/\/$/, "") + pathWithoutVersion; | ||
| } else { | ||
| // For relative internal branches (like 'latest') | ||
| var baseDocUrl = langRoot; | ||
| if (baseDocUrl.endsWith('latest/')) { | ||
| // Trim trailing 'latest/' so we can properly append relative paths from versions.json | ||
| baseDocUrl = baseDocUrl.substring(0, baseDocUrl.length - 7); | ||
| } | ||
| url = baseDocUrl + data.all[key].doc + pathWithoutVersion; | ||
| } | ||
|
Comment on lines
+136
to
+152
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded path offset and confusing
🔧 Suggested fix var currentPath = window.location.pathname;
- // Find the index of '/en/'
- var pathWithoutEn = currentPath.substring(4, currentPath.length);
- var pathWithoutVersion = pathWithoutEn.substring(pathWithoutEn.indexOf("/"), pathWithoutEn.length);
+ // Extract path after language and version segments
+ var pathParts = currentPath.split('/').filter(Boolean);
+ // pathParts[0] = language (e.g., 'en'), pathParts[1] = version (e.g., 'latest')
+ var pathWithoutVersion = '/' + pathParts.slice(2).join('/');
if (docLinkType === 'https' || docLinkType === 'http') {
// For external links (older versions), go directly to the configured URL for that version plus the path
url = data.all[key].doc.replace(/\/$/, "") + pathWithoutVersion;
} else {
// For relative internal branches (like 'latest')
- var baseDocUrl = langRoot;
- if (baseDocUrl.endsWith('latest/')) {
- // Trim trailing 'latest/' so we can properly append relative paths from versions.json
- baseDocUrl = baseDocUrl.substring(0, baseDocUrl.length - 7);
- }
- url = baseDocUrl + data.all[key].doc + pathWithoutVersion;
+ url = langRoot + data.all[key].doc + pathWithoutVersion;
}🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| liElem.className = 'md-tabs__item mb-tabs__dropdown'; | ||
| liElem.innerHTML = '<a href="' + url + '">' + key + '</a>'; | ||
|
|
||
| dropdown.insertBefore(liElem, dropdown.firstChild); | ||
| } | ||
| }); | ||
|
|
||
| document.getElementById('show-all-versions-link') | ||
| .setAttribute('href', activeRoot + 'versions'); | ||
| } | ||
|
|
||
|
|
||
| * Appending versions to the version tables in versions page | ||
| // Appending versions to the version tables in versions page | ||
|
|
||
| if (checkVersionsPage){ | ||
| var previousVersions = []; | ||
| if (checkVersionsPage) { | ||
| var previousVersions = []; | ||
|
|
||
| Object.keys(data.all).forEach(function(key, index){ | ||
| if ((key !== data.current) && (key !== data['pre-release'])) { | ||
| var docLinkType = data.all[key].doc.split(':')[0]; | ||
| var target = '_self'; | ||
| Object.keys(data.all).forEach(function (key, index) { | ||
| if ((key !== data.current) && (key !== data['pre-release'])) { | ||
| var docLinkType = data.all[key].doc.split(':')[0]; | ||
| var target = '_self'; | ||
|
|
||
| if ((docLinkType == 'https') || (docLinkType == 'http')) { | ||
| target = '_blank' | ||
| } | ||
| if ((docLinkType == 'https') || (docLinkType == 'http')) { | ||
| target = '_blank' | ||
| } | ||
|
|
||
| previousVersions.push('<tr>' + | ||
| '<th>' + key + '</th>' + | ||
| previousVersions.push('<tr>' + | ||
| '<th>' + key + '</th>' + | ||
| '<td>' + | ||
| '<a href="' + data.all[key].doc + '" target="' + | ||
| target + '">Documentation</a>' + | ||
| '<a href="' + data.all[key].doc + '" target="' + | ||
| target + '">Documentation</a>' + | ||
| '</td>' + | ||
| '<td>' + | ||
| '<a href="' + data.all[key].notes + '" target="' + | ||
| target + '">Release Notes</a>' + | ||
| '<a href="' + data.all[key].notes + '" target="' + | ||
| target + '">Release Notes</a>' + | ||
| '</td>' + | ||
| '</tr>'); | ||
| } | ||
| }); | ||
|
|
||
| // Past releases update | ||
| document.getElementById('previous-versions').innerHTML = | ||
| previousVersions.join(' '); | ||
|
|
||
| // Current released version update | ||
| document.getElementById('current-version-number').innerHTML = | ||
| data.current; | ||
| document.getElementById('current-version-documentation-link') | ||
| .setAttribute('href', docSetUrl + data.all[data.current].doc); | ||
| document.getElementById('current-version-release-notes-link') | ||
| .setAttribute('href', docSetUrl + data.all[data.current].notes); | ||
|
|
||
| // Pre-release version update | ||
| document.getElementById('pre-release-version-documentation-link') | ||
| .setAttribute('href', docSetUrl + 'next/'); | ||
| } | ||
|
|
||
| } else { | ||
| console.error("We reached our target server, but it returned an error"); | ||
| } | ||
| '</tr>'); | ||
| } | ||
| }); | ||
|
|
||
| // Past releases update | ||
| document.getElementById('previous-versions').innerHTML = | ||
| previousVersions.join(' '); | ||
|
|
||
| // Current released version update | ||
| document.getElementById('current-version-number').innerHTML = | ||
| data.current; | ||
| document.getElementById('current-version-documentation-link') | ||
| .setAttribute('href', langRoot + data.all[data.current].doc); | ||
| document.getElementById('current-version-release-notes-link') | ||
| .setAttribute('href', langRoot + data.all[data.current].notes); | ||
|
|
||
| // Pre-release version update | ||
| document.getElementById('pre-release-version-documentation-link') | ||
| .setAttribute('href', langRoot + 'next/'); | ||
| } | ||
|
Comment on lines
+169
to
+210
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify if any template defines the required IDs for the versions page
echo "=== Searching for required element IDs in templates ==="
rg -n 'id=["\x27](current-version-stable|current-version-number|current-version-documentation-link|current-version-release-notes-link|pre-release-version-documentation-link|previous-versions)["\x27]' --type html
echo ""
echo "=== Contents of versions.html template ==="
fd -t f 'versions.html' --exec cat {}Repository: wso2/docs-mi Length of output: 2415 Versions page DOM manipulation code is dead—targeted elements don't exist in template. Lines 169-210 attempt to dynamically update the versions page by manipulating elements with IDs Since 🤖 Prompt for AI Agents |
||
|
|
||
| } else { | ||
| console.error("We reached our target server, but it returned an error"); | ||
| } | ||
| }; | ||
|
|
||
| request.onerror = function() { | ||
| request.onerror = function () { | ||
| console.error("There was a connection error of some sort"); | ||
| }; | ||
|
|
||
| request.send(); | ||
| */ | ||
| request.send(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "4.6.0": "main", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As the publicly available version is 4.5.0, shall we remove 4.6.0 from the versions? |
||
| "current": "4.6.0", | ||
| "list": [ | ||
| "4.6.0", | ||
| "4.5.0", | ||
| "4.4.0", | ||
| "4.3.0", | ||
| "4.2.0" | ||
| ], | ||
| "all": { | ||
| "4.6.0": { | ||
| "doc": "latest", | ||
| "notes": "latest/get-started/about-this-release" | ||
| }, | ||
| "4.5.0": { | ||
| "doc": "https://mi.docs.wso2.com/en/4.5.0/", | ||
| "notes": "https://mi.docs.wso2.com/en/4.5.0/get-started/about-this-release/" | ||
| }, | ||
| "4.4.0": { | ||
| "doc": "https://mi.docs.wso2.com/en/4.4.0/", | ||
| "notes": "https://mi.docs.wso2.com/en/4.4.0/get-started/about-this-release/" | ||
| }, | ||
| "4.3.0": { | ||
| "doc": "https://mi.docs.wso2.com/en/4.3.0/", | ||
| "notes": "https://mi.docs.wso2.com/en/4.3.0/get-started/about-this-release/" | ||
| }, | ||
| "4.2.0": { | ||
| "doc": "https://mi.docs.wso2.com/en/4.2.0/", | ||
| "notes": "https://mi.docs.wso2.com/en/4.2.0/get-started/about-this-release/" | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.