Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 483d22a

Browse files
authored
Adding a version picker for Synapse docs (#16533)
1 parent 10ada2f commit 483d22a

File tree

9 files changed

+323
-1
lines changed

9 files changed

+323
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Add Version Picker (RUN ONCE)
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
add-version-picker:
8+
name: Add Version Picker
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Configure Git
15+
run: |
16+
git config user.email "[email protected]"
17+
git config user.name "Action Bot"
18+
env:
19+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20+
21+
- name: Setup mdbook
22+
uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0
23+
with:
24+
mdbook-version: '0.4.17'
25+
26+
- name: Copy files to release branches
27+
run: |
28+
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"
29+
do
30+
git fetch
31+
git checkout -b release-$version origin/release-$version
32+
33+
git checkout develop -- ./book.toml
34+
git checkout develop -- ./docs/website_files/version-picker.js
35+
git checkout develop -- ./docs/website_files/version-picker.css
36+
git checkout develop -- ./docs/website_files/README.md
37+
38+
echo "window.SYNAPSE_VERSION = '$version';" > ./docs/website_files/version.js
39+
40+
# Adding version-picker element to index.hbs
41+
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">/{
42+
print; getline; print; getline; print; getline; print;
43+
print "\
44+
<div class=\"version-picker\">\n\
45+
<div class=\"dropdown\">\n\
46+
<div class=\"select\">\n\
47+
<span></span>\n\
48+
<i class=\"fa fa-chevron-down\"></i>\n\
49+
</div>\n\
50+
<input type=\"hidden\" name=\"version\">\n\
51+
<ul class=\"dropdown-menu\">\n\
52+
<!-- Versions will be added dynamically in version-picker.js -->\n\
53+
</ul>\n\
54+
</div>\n\
55+
</div>\
56+
";
57+
next
58+
} 1' ./docs/website_files/theme/index.hbs > output.html && mv output.html ./docs/website_files/theme/index.hbs
59+
60+
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
61+
git commit -m "Version picker added for $version docs"
62+
git push
63+
done
64+
65+
- name: Build docs for Github Pages
66+
run: |
67+
git fetch
68+
git branch gh-pages origin/gh-pages
69+
70+
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"
71+
do
72+
git checkout release-$version
73+
74+
mdbook build && cp book/welcome_and_overview.html book/index.html
75+
mkdir ver-temp && cp -r book/* ver-temp/
76+
rm -r ./book
77+
78+
git checkout gh-pages
79+
rm -r $version
80+
mv ver-temp $version
81+
82+
git add ./$version
83+
git commit -m "Version picker deployed for $version docs to Github Pages"
84+
done
85+
86+
- name: Push to gh-pages
87+
run: |
88+
git checkout gh-pages
89+
git status
90+
git push

.github/workflows/docs.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ jobs:
6060
with:
6161
mdbook-version: '0.4.17'
6262

63+
- name: Set version of docs
64+
run: echo 'window.SYNAPSE_VERSION = "${{ needs.pre.outputs.branch-version }}";' > ./docs/website_files/version.js
65+
6366
- name: Setup python
6467
uses: actions/setup-python@v4
6568
with:

book.toml

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ additional-css = [
3434
"docs/website_files/table-of-contents.css",
3535
"docs/website_files/remove-nav-buttons.css",
3636
"docs/website_files/indent-section-headers.css",
37+
"docs/website_files/version-picker.css",
38+
]
39+
additional-js = [
40+
"docs/website_files/table-of-contents.js",
41+
"docs/website_files/version-picker.js",
42+
"docs/website_files/version.js",
3743
]
38-
additional-js = ["docs/website_files/table-of-contents.js"]
3944
theme = "docs/website_files/theme"
4045

4146
[preprocessor.schema_versions]

changelog.d/16533.doc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added version picker for Synapse documentation. Contributed by @Dmytro27Ind.

docs/website_files/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ Finally, we also stylise the chapter titles in the left sidebar by indenting the
2424
slightly so that they are more visually distinguishable from the section headers
2525
(the bold titles). This is done through the `indent-section-headers.css` file.
2626

27+
In addition to these modifications, we have added a version picker to the documentation.
28+
Users can switch between documentations for different versions of Synapse.
29+
This functionality was implemented through the `version-picker.js` and
30+
`version-picker.css` files.
31+
2732
More information can be found in mdbook's official documentation for
2833
[injecting page JS/CSS](https://rust-lang.github.io/mdBook/format/config.html)
2934
and

docs/website_files/theme/index.hbs

+12
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@
131131
<i class="fa fa-search"></i>
132132
</button>
133133
{{/if}}
134+
<div class="version-picker">
135+
<div class="dropdown">
136+
<div class="select">
137+
<span></span>
138+
<i class="fa fa-chevron-down"></i>
139+
</div>
140+
<input type="hidden" name="version">
141+
<ul class="dropdown-menu">
142+
<!-- Versions will be added dynamically in version-picker.js -->
143+
</ul>
144+
</div>
145+
</div>
134146
</div>
135147

136148
<h1 class="menu-title">{{ book_title }}</h1>

docs/website_files/version-picker.css

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
.version-picker {
2+
display: flex;
3+
align-items: center;
4+
}
5+
6+
.version-picker .dropdown {
7+
width: 130px;
8+
max-height: 29px;
9+
margin-left: 10px;
10+
display: inline-block;
11+
border-radius: 4px;
12+
border: 1px solid var(--theme-popup-border);
13+
position: relative;
14+
font-size: 13px;
15+
color: var(--fg);
16+
height: 100%;
17+
text-align: left;
18+
}
19+
.version-picker .dropdown .select {
20+
cursor: pointer;
21+
display: block;
22+
padding: 5px 2px 5px 15px;
23+
}
24+
.version-picker .dropdown .select > i {
25+
font-size: 10px;
26+
color: var(--fg);
27+
cursor: pointer;
28+
float: right;
29+
line-height: 20px !important;
30+
}
31+
.version-picker .dropdown:hover {
32+
border: 1px solid var(--theme-popup-border);
33+
}
34+
.version-picker .dropdown:active {
35+
background-color: var(--theme-popup-bg);
36+
}
37+
.version-picker .dropdown.active:hover,
38+
.version-picker .dropdown.active {
39+
border: 1px solid var(--theme-popup-border);
40+
border-radius: 2px 2px 0 0;
41+
background-color: var(--theme-popup-bg);
42+
}
43+
.version-picker .dropdown.active .select > i {
44+
transform: rotate(-180deg);
45+
}
46+
.version-picker .dropdown .dropdown-menu {
47+
position: absolute;
48+
background-color: var(--theme-popup-bg);
49+
width: 100%;
50+
left: -1px;
51+
right: 1px;
52+
margin-top: 1px;
53+
border: 1px solid var(--theme-popup-border);
54+
border-radius: 0 0 4px 4px;
55+
overflow: hidden;
56+
display: none;
57+
max-height: 300px;
58+
overflow-y: auto;
59+
z-index: 9;
60+
}
61+
.version-picker .dropdown .dropdown-menu li {
62+
font-size: 12px;
63+
padding: 6px 20px;
64+
cursor: pointer;
65+
}
66+
.version-picker .dropdown .dropdown-menu {
67+
padding: 0;
68+
list-style: none;
69+
}
70+
.version-picker .dropdown .dropdown-menu li:hover {
71+
background-color: var(--theme-hover);
72+
}
73+
.version-picker .dropdown .dropdown-menu li.active::before {
74+
display: inline-block;
75+
content: "✓";
76+
margin-inline-start: -14px;
77+
width: 14px;
78+
}

docs/website_files/version-picker.js

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
2+
const dropdown = document.querySelector('.version-picker .dropdown');
3+
const dropdownMenu = dropdown.querySelector('.dropdown-menu');
4+
5+
fetchVersions(dropdown, dropdownMenu).then(() => {
6+
initializeVersionDropdown(dropdown, dropdownMenu);
7+
});
8+
9+
/**
10+
* Initialize the dropdown functionality for version selection.
11+
*
12+
* @param {Element} dropdown - The dropdown element.
13+
* @param {Element} dropdownMenu - The dropdown menu element.
14+
*/
15+
function initializeVersionDropdown(dropdown, dropdownMenu) {
16+
// Toggle the dropdown menu on click
17+
dropdown.addEventListener('click', function () {
18+
this.setAttribute('tabindex', 1);
19+
this.classList.toggle('active');
20+
dropdownMenu.style.display = (dropdownMenu.style.display === 'block') ? 'none' : 'block';
21+
});
22+
23+
// Remove the 'active' class and hide the dropdown menu on focusout
24+
dropdown.addEventListener('focusout', function () {
25+
this.classList.remove('active');
26+
dropdownMenu.style.display = 'none';
27+
});
28+
29+
// Handle item selection within the dropdown menu
30+
const dropdownMenuItems = dropdownMenu.querySelectorAll('li');
31+
dropdownMenuItems.forEach(function (item) {
32+
item.addEventListener('click', function () {
33+
dropdownMenuItems.forEach(function (item) {
34+
item.classList.remove('active');
35+
});
36+
this.classList.add('active');
37+
dropdown.querySelector('span').textContent = this.textContent;
38+
dropdown.querySelector('input').value = this.getAttribute('id');
39+
40+
window.location.href = changeVersion(window.location.href, this.textContent);
41+
});
42+
});
43+
};
44+
45+
/**
46+
* This function fetches the available versions from a GitHub repository
47+
* and inserts them into the version picker.
48+
*
49+
* @param {Element} dropdown - The dropdown element.
50+
* @param {Element} dropdownMenu - The dropdown menu element.
51+
* @returns {Promise<Array<string>>} A promise that resolves with an array of available versions.
52+
*/
53+
function fetchVersions(dropdown, dropdownMenu) {
54+
return new Promise((resolve, reject) => {
55+
window.addEventListener("load", () => {
56+
57+
fetch("https://api.github.com/repos/matrix-org/synapse/git/trees/gh-pages", {
58+
cache: "force-cache",
59+
}).then(res =>
60+
res.json()
61+
).then(resObject => {
62+
const excluded = ['dev-docs', 'v1.91.0', 'v1.80.0', 'v1.69.0'];
63+
const tree = resObject.tree.filter(item => item.type === "tree" && !excluded.includes(item.path));
64+
const versions = tree.map(item => item.path).sort(sortVersions);
65+
66+
// Create a list of <li> items for versions
67+
versions.forEach((version) => {
68+
const li = document.createElement("li");
69+
li.textContent = version;
70+
li.id = version;
71+
72+
if (window.SYNAPSE_VERSION === version) {
73+
li.classList.add('active');
74+
dropdown.querySelector('span').textContent = version;
75+
dropdown.querySelector('input').value = version;
76+
}
77+
78+
dropdownMenu.appendChild(li);
79+
});
80+
81+
resolve(versions);
82+
83+
}).catch(ex => {
84+
console.error("Failed to fetch version data", ex);
85+
reject(ex);
86+
})
87+
});
88+
});
89+
}
90+
91+
/**
92+
* Custom sorting function to sort an array of version strings.
93+
*
94+
* @param {string} a - The first version string to compare.
95+
* @param {string} b - The second version string to compare.
96+
* @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.
97+
*/
98+
function sortVersions(a, b) {
99+
// Put 'develop' and 'latest' at the top
100+
if (a === 'develop' || a === 'latest') return -1;
101+
if (b === 'develop' || b === 'latest') return 1;
102+
103+
const versionA = (a.match(/v\d+(\.\d+)+/) || [])[0];
104+
const versionB = (b.match(/v\d+(\.\d+)+/) || [])[0];
105+
106+
return versionB.localeCompare(versionA);
107+
}
108+
109+
/**
110+
* Change the version in a URL path.
111+
*
112+
* @param {string} url - The original URL to be modified.
113+
* @param {string} newVersion - The new version to replace the existing version in the URL.
114+
* @returns {string} The updated URL with the new version.
115+
*/
116+
function changeVersion(url, newVersion) {
117+
const parsedURL = new URL(url);
118+
const pathSegments = parsedURL.pathname.split('/');
119+
120+
// Modify the version
121+
pathSegments[2] = newVersion;
122+
123+
// Reconstruct the URL
124+
parsedURL.pathname = pathSegments.join('/');
125+
126+
return parsedURL.href;
127+
}

docs/website_files/version.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
window.SYNAPSE_VERSION = "latest";

0 commit comments

Comments
 (0)