diff options
-rw-r--r-- | .github/workflows/docs-add-version-picker.yaml | 90 | ||||
-rw-r--r-- | .github/workflows/docs.yaml | 3 | ||||
-rw-r--r-- | book.toml | 7 | ||||
-rw-r--r-- | changelog.d/16533.doc | 1 | ||||
-rw-r--r-- | docs/website_files/README.md | 5 | ||||
-rw-r--r-- | docs/website_files/theme/index.hbs | 12 | ||||
-rw-r--r-- | docs/website_files/version-picker.css | 78 | ||||
-rw-r--r-- | docs/website_files/version-picker.js | 127 | ||||
-rw-r--r-- | docs/website_files/version.js | 1 |
9 files changed, 323 insertions, 1 deletions
diff --git a/.github/workflows/docs-add-version-picker.yaml b/.github/workflows/docs-add-version-picker.yaml new file mode 100644 index 0000000000..717d5c85d3 --- /dev/null +++ b/.github/workflows/docs-add-version-picker.yaml @@ -0,0 +1,90 @@ +name: Add Version Picker (RUN ONCE) + +on: + workflow_dispatch: + +jobs: + add-version-picker: + name: Add Version Picker + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Configure Git + run: | + git config user.email "action@synapse.bot.com" + git config user.name "Action Bot" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup mdbook + uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0 + with: + mdbook-version: '0.4.17' + + - name: Copy files to release branches + run: | + for version in "v1.98" "v1.97" "v1.96" "v1.95" "v1.94" "v1.93" "v1.92" "v1.91" "v1.90" "v1.89" "v1.88" "v1.87" "v1.86" "v1.85" "v1.84" "v1.83" "v1.82" "v1.81" "v1.80" "v1.79" "v1.78" "v1.77" "v1.76" "v1.75" "v1.74" "v1.73" "v1.72" "v1.71" "v1.70" "v1.69" "v1.68" "v1.67" "v1.66" "v1.65" "v1.64" "v1.63" "v1.62" "v1.61" "v1.60" "v1.59" "v1.58" "v1.57" "v1.56" "v1.55" "v1.54" "v1.53" "v1.52" "v1.51" "v1.50" "v1.49" "v1.48" "v1.47" "v1.46" "v1.45" "v1.44" "v1.43" "v1.42" "v1.41" "v1.40" "v1.39" "v1.38" "v1.37" + do + git fetch + git checkout -b release-$version origin/release-$version + + git checkout develop -- ./book.toml + git checkout develop -- ./docs/website_files/version-picker.js + git checkout develop -- ./docs/website_files/version-picker.css + git checkout develop -- ./docs/website_files/README.md + + echo "window.SYNAPSE_VERSION = '$version';" > ./docs/website_files/version.js + + # Adding version-picker element to index.hbs + awk '/<button id="search-toggle" class="icon-button" type="button" title="Search. \(Shortkey: s\)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">/{ + print; getline; print; getline; print; getline; print; + print "\ + <div class=\"version-picker\">\n\ + <div class=\"dropdown\">\n\ + <div class=\"select\">\n\ + <span></span>\n\ + <i class=\"fa fa-chevron-down\"></i>\n\ + </div>\n\ + <input type=\"hidden\" name=\"version\">\n\ + <ul class=\"dropdown-menu\">\n\ + <!-- Versions will be added dynamically in version-picker.js -->\n\ + </ul>\n\ + </div>\n\ + </div>\ + "; + next + } 1' ./docs/website_files/theme/index.hbs > output.html && mv output.html ./docs/website_files/theme/index.hbs + + git add ./book.toml ./docs/website_files/version-picker.js ./docs/website_files/version-picker.css ./docs/website_files/version.js ./docs/website_files/README.md ./docs/website_files/theme/index.hbs + git commit -m "Version picker added for $version docs" + git push + done + + - name: Build docs for Github Pages + run: | + git fetch + git branch gh-pages origin/gh-pages + + for version in "v1.98" "v1.97" "v1.96" "v1.95" "v1.94" "v1.93" "v1.92" "v1.91" "v1.90" "v1.89" "v1.88" "v1.87" "v1.86" "v1.85" "v1.84" "v1.83" "v1.82" "v1.81" "v1.80" "v1.79" "v1.78" "v1.77" "v1.76" "v1.75" "v1.74" "v1.73" "v1.72" "v1.71" "v1.70" "v1.69" "v1.68" "v1.67" "v1.66" "v1.65" "v1.64" "v1.63" "v1.62" "v1.61" "v1.60" "v1.59" "v1.58" "v1.57" "v1.56" "v1.55" "v1.54" "v1.53" "v1.52" "v1.51" "v1.50" "v1.49" "v1.48" "v1.47" "v1.46" "v1.45" "v1.44" "v1.43" "v1.42" "v1.41" "v1.40" "v1.39" "v1.38" "v1.37" + do + git checkout release-$version + + mdbook build && cp book/welcome_and_overview.html book/index.html + mkdir ver-temp && cp -r book/* ver-temp/ + rm -r ./book + + git checkout gh-pages + rm -r $version + mv ver-temp $version + + git add ./$version + git commit -m "Version picker deployed for $version docs to Github Pages" + done + + - name: Push to gh-pages + run: | + git checkout gh-pages + git status + git push \ No newline at end of file diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 31b9dbe3fe..6b9135a627 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -60,6 +60,9 @@ jobs: with: mdbook-version: '0.4.17' + - name: Set version of docs + run: echo 'window.SYNAPSE_VERSION = "${{ needs.pre.outputs.branch-version }}";' > ./docs/website_files/version.js + - name: Setup python uses: actions/setup-python@v4 with: diff --git a/book.toml b/book.toml index ed3f6151e0..977a8450bc 100644 --- a/book.toml +++ b/book.toml @@ -34,8 +34,13 @@ additional-css = [ "docs/website_files/table-of-contents.css", "docs/website_files/remove-nav-buttons.css", "docs/website_files/indent-section-headers.css", + "docs/website_files/version-picker.css", +] +additional-js = [ + "docs/website_files/table-of-contents.js", + "docs/website_files/version-picker.js", + "docs/website_files/version.js", ] -additional-js = ["docs/website_files/table-of-contents.js"] theme = "docs/website_files/theme" [preprocessor.schema_versions] diff --git a/changelog.d/16533.doc b/changelog.d/16533.doc new file mode 100644 index 0000000000..ae23a8a578 --- /dev/null +++ b/changelog.d/16533.doc @@ -0,0 +1 @@ +Added version picker for Synapse documentation. Contributed by @Dmytro27Ind. \ No newline at end of file diff --git a/docs/website_files/README.md b/docs/website_files/README.md index 04d191479b..bc51c4865e 100644 --- a/docs/website_files/README.md +++ b/docs/website_files/README.md @@ -24,6 +24,11 @@ Finally, we also stylise the chapter titles in the left sidebar by indenting the slightly so that they are more visually distinguishable from the section headers (the bold titles). This is done through the `indent-section-headers.css` file. +In addition to these modifications, we have added a version picker to the documentation. +Users can switch between documentations for different versions of Synapse. +This functionality was implemented through the `version-picker.js` and +`version-picker.css` files. + More information can be found in mdbook's official documentation for [injecting page JS/CSS](https://rust-lang.github.io/mdBook/format/config.html) and diff --git a/docs/website_files/theme/index.hbs b/docs/website_files/theme/index.hbs index 3b7a5b6163..f60a7e96aa 100644 --- a/docs/website_files/theme/index.hbs +++ b/docs/website_files/theme/index.hbs @@ -131,6 +131,18 @@ <i class="fa fa-search"></i> </button> {{/if}} + <div class="version-picker"> + <div class="dropdown"> + <div class="select"> + <span></span> + <i class="fa fa-chevron-down"></i> + </div> + <input type="hidden" name="version"> + <ul class="dropdown-menu"> + <!-- Versions will be added dynamically in version-picker.js --> + </ul> + </div> + </div> </div> <h1 class="menu-title">{{ book_title }}</h1> diff --git a/docs/website_files/version-picker.css b/docs/website_files/version-picker.css new file mode 100644 index 0000000000..28e5d5219a --- /dev/null +++ b/docs/website_files/version-picker.css @@ -0,0 +1,78 @@ +.version-picker { + display: flex; + align-items: center; +} + +.version-picker .dropdown { + width: 130px; + max-height: 29px; + margin-left: 10px; + display: inline-block; + border-radius: 4px; + border: 1px solid var(--theme-popup-border); + position: relative; + font-size: 13px; + color: var(--fg); + height: 100%; + text-align: left; +} +.version-picker .dropdown .select { + cursor: pointer; + display: block; + padding: 5px 2px 5px 15px; +} +.version-picker .dropdown .select > i { + font-size: 10px; + color: var(--fg); + cursor: pointer; + float: right; + line-height: 20px !important; +} +.version-picker .dropdown:hover { + border: 1px solid var(--theme-popup-border); +} +.version-picker .dropdown:active { + background-color: var(--theme-popup-bg); +} +.version-picker .dropdown.active:hover, +.version-picker .dropdown.active { + border: 1px solid var(--theme-popup-border); + border-radius: 2px 2px 0 0; + background-color: var(--theme-popup-bg); +} +.version-picker .dropdown.active .select > i { + transform: rotate(-180deg); +} +.version-picker .dropdown .dropdown-menu { + position: absolute; + background-color: var(--theme-popup-bg); + width: 100%; + left: -1px; + right: 1px; + margin-top: 1px; + border: 1px solid var(--theme-popup-border); + border-radius: 0 0 4px 4px; + overflow: hidden; + display: none; + max-height: 300px; + overflow-y: auto; + z-index: 9; +} +.version-picker .dropdown .dropdown-menu li { + font-size: 12px; + padding: 6px 20px; + cursor: pointer; +} +.version-picker .dropdown .dropdown-menu { + padding: 0; + list-style: none; +} +.version-picker .dropdown .dropdown-menu li:hover { + background-color: var(--theme-hover); +} +.version-picker .dropdown .dropdown-menu li.active::before { + display: inline-block; + content: "✓"; + margin-inline-start: -14px; + width: 14px; +} \ No newline at end of file diff --git a/docs/website_files/version-picker.js b/docs/website_files/version-picker.js new file mode 100644 index 0000000000..bb35a7d896 --- /dev/null +++ b/docs/website_files/version-picker.js @@ -0,0 +1,127 @@ + +const dropdown = document.querySelector('.version-picker .dropdown'); +const dropdownMenu = dropdown.querySelector('.dropdown-menu'); + +fetchVersions(dropdown, dropdownMenu).then(() => { + initializeVersionDropdown(dropdown, dropdownMenu); +}); + +/** + * Initialize the dropdown functionality for version selection. + * + * @param {Element} dropdown - The dropdown element. + * @param {Element} dropdownMenu - The dropdown menu element. + */ +function initializeVersionDropdown(dropdown, dropdownMenu) { + // Toggle the dropdown menu on click + dropdown.addEventListener('click', function () { + this.setAttribute('tabindex', 1); + this.classList.toggle('active'); + dropdownMenu.style.display = (dropdownMenu.style.display === 'block') ? 'none' : 'block'; + }); + + // Remove the 'active' class and hide the dropdown menu on focusout + dropdown.addEventListener('focusout', function () { + this.classList.remove('active'); + dropdownMenu.style.display = 'none'; + }); + + // Handle item selection within the dropdown menu + const dropdownMenuItems = dropdownMenu.querySelectorAll('li'); + dropdownMenuItems.forEach(function (item) { + item.addEventListener('click', function () { + dropdownMenuItems.forEach(function (item) { + item.classList.remove('active'); + }); + this.classList.add('active'); + dropdown.querySelector('span').textContent = this.textContent; + dropdown.querySelector('input').value = this.getAttribute('id'); + + window.location.href = changeVersion(window.location.href, this.textContent); + }); + }); +}; + +/** + * This function fetches the available versions from a GitHub repository + * and inserts them into the version picker. + * + * @param {Element} dropdown - The dropdown element. + * @param {Element} dropdownMenu - The dropdown menu element. + * @returns {Promise<Array<string>>} A promise that resolves with an array of available versions. + */ +function fetchVersions(dropdown, dropdownMenu) { + return new Promise((resolve, reject) => { + window.addEventListener("load", () => { + + fetch("https://api.github.com/repos/matrix-org/synapse/git/trees/gh-pages", { + cache: "force-cache", + }).then(res => + res.json() + ).then(resObject => { + const excluded = ['dev-docs', 'v1.91.0', 'v1.80.0', 'v1.69.0']; + const tree = resObject.tree.filter(item => item.type === "tree" && !excluded.includes(item.path)); + const versions = tree.map(item => item.path).sort(sortVersions); + + // Create a list of <li> items for versions + versions.forEach((version) => { + const li = document.createElement("li"); + li.textContent = version; + li.id = version; + + if (window.SYNAPSE_VERSION === version) { + li.classList.add('active'); + dropdown.querySelector('span').textContent = version; + dropdown.querySelector('input').value = version; + } + + dropdownMenu.appendChild(li); + }); + + resolve(versions); + + }).catch(ex => { + console.error("Failed to fetch version data", ex); + reject(ex); + }) + }); + }); +} + +/** + * Custom sorting function to sort an array of version strings. + * + * @param {string} a - The first version string to compare. + * @param {string} b - The second version string to compare. + * @returns {number} - A negative number if a should come before b, a positive number if b should come before a, or 0 if they are equal. + */ +function sortVersions(a, b) { + // Put 'develop' and 'latest' at the top + if (a === 'develop' || a === 'latest') return -1; + if (b === 'develop' || b === 'latest') return 1; + + const versionA = (a.match(/v\d+(\.\d+)+/) || [])[0]; + const versionB = (b.match(/v\d+(\.\d+)+/) || [])[0]; + + return versionB.localeCompare(versionA); +} + +/** + * Change the version in a URL path. + * + * @param {string} url - The original URL to be modified. + * @param {string} newVersion - The new version to replace the existing version in the URL. + * @returns {string} The updated URL with the new version. + */ +function changeVersion(url, newVersion) { + const parsedURL = new URL(url); + const pathSegments = parsedURL.pathname.split('/'); + + // Modify the version + pathSegments[2] = newVersion; + + // Reconstruct the URL + parsedURL.pathname = pathSegments.join('/'); + + return parsedURL.href; +} \ No newline at end of file diff --git a/docs/website_files/version.js b/docs/website_files/version.js new file mode 100644 index 0000000000..9065afcdbf --- /dev/null +++ b/docs/website_files/version.js @@ -0,0 +1 @@ +window.SYNAPSE_VERSION = "latest"; \ No newline at end of file |