summary refs log tree commit diff
diff options
context:
space:
mode:
authorDmytro Kagirov <dmytro27kagirov@gmail.com>2023-12-11 15:18:40 +0100
committerGitHub <noreply@github.com>2023-12-11 14:18:40 +0000
commit483d22afc39d96b5e25292843806d0c0487e6446 (patch)
tree38bc9ea07c1533abd3e088061fbe448bd011fb4c
parentWrite signing keys with file mode 0640 (#16740) (diff)
downloadsynapse-483d22afc39d96b5e25292843806d0c0487e6446.tar.xz
Adding a version picker for Synapse docs (#16533)
-rw-r--r--.github/workflows/docs-add-version-picker.yaml90
-rw-r--r--.github/workflows/docs.yaml3
-rw-r--r--book.toml7
-rw-r--r--changelog.d/16533.doc1
-rw-r--r--docs/website_files/README.md5
-rw-r--r--docs/website_files/theme/index.hbs12
-rw-r--r--docs/website_files/version-picker.css78
-rw-r--r--docs/website_files/version-picker.js127
-rw-r--r--docs/website_files/version.js1
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