aboutsummaryrefslogtreecommitdiff
path: root/docs/_static
diff options
context:
space:
mode:
authorJosh <[email protected]>2020-08-30 09:17:44 +1000
committerRapptz <[email protected]>2020-12-18 21:18:56 -0500
commitc2e5b734ad60d69909d0ca4da0d01c54fa8d9faf (patch)
treee8f7acf8765b6ef20064f370b234f0485f20c1a4 /docs/_static
parentReduce CSS variable usage (diff)
downloaddiscord.py-c2e5b734ad60d69909d0ca4da0d01c54fa8d9faf.tar.xz
discord.py-c2e5b734ad60d69909d0ca4da0d01c54fa8d9faf.zip
[matrix] Refactor JS & add searchbar to mobile.
Diffstat (limited to 'docs/_static')
-rw-r--r--docs/_static/copy.js22
-rw-r--r--docs/_static/custom.js198
-rw-r--r--docs/_static/settings.js106
-rw-r--r--docs/_static/sidebar.js139
-rw-r--r--docs/_static/style.css56
5 files changed, 306 insertions, 215 deletions
diff --git a/docs/_static/copy.js b/docs/_static/copy.js
index 64eaa35c..f70e3d67 100644
--- a/docs/_static/copy.js
+++ b/docs/_static/copy.js
@@ -17,18 +17,18 @@ document.addEventListener("DOMContentLoaded", () => {
let allCodeblocks = document.querySelectorAll("div[class='highlight']");
for (let codeblock of allCodeblocks) {
- codeblock.parentNode.className += " relative-copy";
- let copyEl = document.createElement("span");
- copyEl.addEventListener('click', () => copy(codeblock));
- copyEl.className = "copy";
- copyEl.setAttribute("aria-label", "Copy Code");
- copyEl.setAttribute("title", "Copy Code");
+ codeblock.parentNode.className += " relative-copy";
+ let copyEl = document.createElement("span");
+ copyEl.addEventListener('click', () => copy(codeblock));
+ copyEl.className = "copy";
+ copyEl.setAttribute("aria-label", "Copy Code");
+ copyEl.setAttribute("title", "Copy Code");
- let copyIcon = document.createElement("span");
- copyIcon.className = "material-icons";
- copyIcon.textContent = COPY;
- copyEl.append(copyIcon);
+ let copyIcon = document.createElement("span");
+ copyIcon.className = "material-icons";
+ copyIcon.textContent = COPY;
+ copyEl.append(copyIcon);
- codeblock.prepend(copyEl);
+ codeblock.prepend(copyEl);
}
});
diff --git a/docs/_static/custom.js b/docs/_static/custom.js
index bb03bdbf..6e5c4ff5 100644
--- a/docs/_static/custom.js
+++ b/docs/_static/custom.js
@@ -1,140 +1,69 @@
'use-strict';
let activeModal = null;
-let activeLink = null;
let bottomHeightThreshold, sections;
-let settingsModal;
let hamburgerToggle;
+let mobileSearch;
let sidebar;
-function resizeSidebar() {
- let rect = sidebar.getBoundingClientRect();
- sidebar.style.height = `calc(100vh - 1em - ${rect.top + document.body.offsetTop}px)`;
-}
-
-function closeModal(modal) {
- activeModal = null;
- modal.hidden = true;
-}
-
-function openModal(modal) {
- if (activeModal) {
- closeModal(activeModal);
+class Modal {
+ constructor(element) {
+ this.element = element;
}
- activeModal = modal;
- modal.hidden = false;
-}
-
-function changeDocumentation(element) {
- window.location = element.value;
-}
-
-function updateSetting(element) {
- let value;
- switch (element.type) {
- case "checkbox":
- localStorage.setItem(element.name, element.checked);
- value = element.checked;
- break;
- case "radio":
- localStorage.setItem(element.name, `"${element.value}"`);
- value = element.value;
- break;
+ close() {
+ activeModal = null;
+ this.element.hidden = true;
}
- if (element.name in settings) {
- settings[element.name]["setter"](value);
- }
-}
-function LoadSetting(name, defaultValue) {
- let value = JSON.parse(localStorage.getItem(name));
- return value === null ? defaultValue : value;
-}
-
-function getRootAttributeToggle(attributeName, valueName) {
- function toggleRootAttribute(set) {
- if (set) {
- document.documentElement.setAttribute(`data-${attributeName}`, valueName);
- } else {
- document.documentElement.removeAttribute(`data-${attributeName}`);
+ open() {
+ if (activeModal) {
+ activeModal.close();
}
+ activeModal = this;
+ this.element.hidden = false;
}
- return toggleRootAttribute;
}
-function setTheme(value) {
- if (value === "automatic") {
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
- document.documentElement.setAttribute(`data-theme`, "dark");
- } else{
- document.documentElement.setAttribute(`data-theme`, "light");
- }
- }
- else {
- document.documentElement.setAttribute(`data-theme`, value);
+class Search {
+
+ constructor() {
+ this.box = document.querySelector('nav.mobile-only');
+ this.bar = document.querySelector('nav.mobile-only input[type="search"]');
+ this.openButton = document.getElementById('open-search');
+ this.closeButton = document.getElementById('close-search');
}
-}
-const settings = {
- useSerifFont: {
- settingType: "checkbox",
- defaultValue: false,
- setter: getRootAttributeToggle('font', 'serif')
- },
- setTheme: {
- settingType: "radio",
- defaultValue: "automatic",
- setter: setTheme
+ open() {
+ this.openButton.hidden = true;
+ this.closeButton.hidden = false;
+ this.box.style.top = "100%";
+ this.bar.focus();
}
-};
-Object.entries(settings).forEach(([name, setting]) => {
- let { defaultValue, setter, ..._ } = setting;
- let value = LoadSetting(name, defaultValue);
- try {
- setter(value);
- } catch (error) {
- console.error(`Failed to apply setting "${name}" With value:`, value);
- console.error(error);
+ close() {
+ this.openButton.hidden = false;
+ this.closeButton.hidden = true;
+ this.box.style.top = "0";
}
-});
+
+}
document.addEventListener('DOMContentLoaded', () => {
+ mobileSearch = new Search();
bottomHeightThreshold = document.documentElement.scrollHeight - 30;
sections = document.querySelectorAll('section');
- settingsModal = document.querySelector('div#settings.modal');
- hamburgerToggle = document.getElementById("hamburger-toggle");
- sidebar = document.getElementById("sidebar");
-
- resizeSidebar();
+ hamburgerToggle = document.getElementById('hamburger-toggle');
- sidebar.addEventListener("click", (e) => {
- // If we click a navigation, close the hamburger menu
- if (e.target.tagName == "A" && sidebar.classList.contains("sidebar-toggle")) {
- sidebar.classList.remove("sidebar-toggle");
- let button = hamburgerToggle.firstElementChild;
- button.textContent = "menu";
-
- // Scroll a little up to actually see the header
- // Note: this is generally around ~55px
- // A proper solution is getComputedStyle but it can be slow
- // Instead let's just rely on this quirk and call it a day
- // This has to be done after the browser actually processes
- // the section movement
- setTimeout(() => window.scrollBy(0, -100), 75);
- }
- })
-
- hamburgerToggle.addEventListener("click", (e) => {
- sidebar.classList.toggle("sidebar-toggle");
+ hamburgerToggle.addEventListener('click', (e) => {
+ sidebar.element.classList.toggle('sidebar-toggle');
let button = hamburgerToggle.firstElementChild;
- if (button.textContent == "menu") {
- button.textContent = "close";
+ if (button.textContent == 'menu') {
+ button.textContent = 'close';
}
else {
- button.textContent = "menu";
+ button.textContent = 'menu';
}
});
@@ -145,59 +74,10 @@ document.addEventListener('DOMContentLoaded', () => {
// insert ourselves after the element
parent.insertBefore(table, element.nextSibling);
});
-
- Object.entries(settings).forEach(([name, setting]) => {
- let { settingType, defaultValue, ..._ } = setting;
- let value = LoadSetting(name, defaultValue);
- if (settingType === "checkbox") {
- let element = document.querySelector(`input[name=${name}]`);
- element.checked = value;
- } else {
- let element = document.querySelector(`input[name=${name}][value=${value}]`);
- element.checked = true;
- }
- });
-});
-
-window.addEventListener('scroll', () => {
- let currentSection = null;
-
- if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
- currentSection = sections[sections.length - 1];
- }
- else {
- if (sections) {
- sections.forEach(section => {
- let rect = section.getBoundingClientRect();
- if (rect.top + document.body.offsetTop < 1) {
- currentSection = section;
- }
- });
- }
- }
-
- if (activeLink) {
- activeLink.parentElement.classList.remove('active');
- }
-
- if (currentSection) {
- activeLink = document.querySelector(`#sidebar a[href="#${currentSection.id}"]`);
- if (activeLink) {
- let headingChildren = activeLink.parentElement.parentElement;
- let heading = headingChildren.previousElementSibling.previousElementSibling;
-
- if (heading && headingChildren.style.display === "none") {
- activeLink = heading;
- }
- activeLink.parentElement.classList.add('active');
- }
- }
-
- resizeSidebar();
});
document.addEventListener('keydown', (event) => {
- if (event.keyCode == 27 && activeModal) {
- closeModal(activeModal);
+ if (event.code == "Escape" && activeModal) {
+ activeModal.close();
}
});
diff --git a/docs/_static/settings.js b/docs/_static/settings.js
new file mode 100644
index 00000000..0573f856
--- /dev/null
+++ b/docs/_static/settings.js
@@ -0,0 +1,106 @@
+'use-strict';
+
+let settingsModal;
+
+class Setting {
+ constructor(name, defaultValue, setter) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ this.setValue = setter;
+ }
+
+ setElement() {
+ throw new TypeError('Abstract methods should be implemented.');
+ }
+
+ load() {
+ let value = JSON.parse(localStorage.getItem(this.name));
+ this.value = value === null ? this.defaultValue : value;
+ try {
+ this.setValue(value);
+ } catch (error) {
+ console.error(`Failed to apply setting "${this.name}" With value:`, this.value);
+ console.error(error);
+ }
+ }
+
+ update() {
+ throw new TypeError('Abstract methods should be implemented.');
+ }
+
+}
+
+class CheckboxSetting extends Setting {
+
+ setElement() {
+ let element = document.querySelector(`input[name=${this.name}]`);
+ element.checked = this.value;
+ }
+
+ update(element) {
+ localStorage.setItem(this.name, element.checked);
+ this.setValue(element.checked);
+ }
+
+}
+
+class RadioSetting extends Setting {
+
+ setElement() {
+ let element = document.querySelector(`input[name=${this.name}][value=${this.value}]`);
+ element.checked = true;
+ }
+
+ update(element) {
+ localStorage.setItem(this.name, `"${element.value}"`);
+ this.setValue(element.value);
+ }
+
+}
+
+function getRootAttributeToggle(attributeName, valueName) {
+ function toggleRootAttribute(set) {
+ if (set) {
+ document.documentElement.setAttribute(`data-${attributeName}`, valueName);
+ } else {
+ document.documentElement.removeAttribute(`data-${attributeName}`);
+ }
+ }
+ return toggleRootAttribute;
+}
+
+function setTheme(value) {
+ if (value === 'automatic') {
+ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ document.documentElement.setAttribute('data-theme', 'dark');
+ } else {
+ document.documentElement.setAttribute('data-theme', 'light');
+ }
+ }
+ else {
+ document.documentElement.setAttribute('data-theme', value);
+ }
+}
+
+const settings = [
+ new CheckboxSetting('useSerifFont', false, getRootAttributeToggle('font', 'serif')),
+ new RadioSetting('setTheme', 'automatic', setTheme)
+]
+
+function updateSetting(element) {
+ let setting = settings.find((s) => s.name == element.name);
+ if (setting) {
+ setting.update(element);
+ }
+}
+
+for (const setting of settings) {
+ setting.load();
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ settingsModal = new Modal(document.querySelector('div#settings.modal'));
+ for (const setting of settings) {
+ setting.setElement();
+ }
+});
diff --git a/docs/_static/sidebar.js b/docs/_static/sidebar.js
index 8c45a210..7849aea8 100644
--- a/docs/_static/sidebar.js
+++ b/docs/_static/sidebar.js
@@ -1,4 +1,64 @@
-function collapseSection(icon) {
+class Sidebar {
+ constructor(element) {
+ this.element = element;
+ this.activeLink = null;
+
+ this.element.addEventListener('click', (e) => {
+ // If we click a navigation, close the hamburger menu
+ if (e.target.tagName == 'A' && this.element.classList.contains('sidebar-toggle')) {
+ this.element.classList.remove('sidebar-toggle');
+ let button = hamburgerToggle.firstElementChild;
+ button.textContent = 'menu';
+
+ // Scroll a little up to actually see the header
+ // Note: this is generally around ~55px
+ // A proper solution is getComputedStyle but it can be slow
+ // Instead let's just rely on this quirk and call it a day
+ // This has to be done after the browser actually processes
+ // the section movement
+ setTimeout(() => window.scrollBy(0, -100), 75);
+ }
+ });
+ }
+
+ createCollapsableSections() {
+ let toc = this.element.querySelector('ul');
+ let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');
+
+ for (let ref of allReferences) {
+
+ let next = ref.nextElementSibling;
+
+ if (next && next.tagName === "UL") {
+
+ let icon = document.createElement('span');
+ icon.className = 'material-icons collapsible-arrow expanded';
+ icon.innerText = 'expand_more';
+
+ if (next.parentElement.tagName == "LI") {
+ next.parentElement.classList.add('no-list-style')
+ }
+
+ icon.addEventListener('click', () => {
+ if (icon.classList.contains('expanded')) {
+ collapseSection(icon);
+ } else {
+ expandSection(icon);
+ }
+ })
+
+ ref.classList.add('ref-internal-padding')
+ ref.parentNode.insertBefore(icon, ref);
+ }
+ }
+ }
+
+ resize() {
+ let rect = this.element.getBoundingClientRect();
+ this.element.style.height = `calc(100vh - 1em - ${rect.top + document.body.offsetTop}px)`;
+ }
+
+ collapseSection(icon) {
icon.classList.remove('expanded');
icon.classList.add('collapsed');
icon.innerText = 'chevron_right';
@@ -6,45 +66,62 @@ function collapseSection(icon) {
// <arrow><heading>
// --> <square><children>
children.style.display = "none";
-}
+ }
-function expandSection(icon) {
+ expandSection(icon) {
icon.classList.remove('collapse');
icon.classList.add('expanded');
icon.innerText = 'expand_more';
let children = icon.nextElementSibling.nextElementSibling;
children.style.display = "block";
-}
+ }
-document.addEventListener('DOMContentLoaded', () => {
- let sidebar = document.getElementById('sidebar');
- let toc = sidebar.querySelector('ul');
- let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');
+ setActiveLink(section) {
+ if (this.activeLink) {
+ this.activeLink.parentElement.classList.remove('active');
+ }
+ if (section) {
+ this.activeLink = document.querySelector(`#sidebar a[href="#${section.id}"]`);
+ if (this.activeLink) {
+ let headingChildren = this.activeLink.parentElement.parentElement;
+ let heading = headingChildren.previousElementSibling.previousElementSibling;
- for (let ref of allReferences) {
+ if (heading && headingChildren.style.display === 'none') {
+ this.activeLink = heading;
+ }
+ this.activeLink.parentElement.classList.add('active');
+ }
+ }
+ }
- let next = ref.nextElementSibling;
-
- if (next && next.tagName === "UL") {
-
- let icon = document.createElement('span');
- icon.className = 'material-icons collapsible-arrow expanded';
- icon.innerText = 'expand_more';
-
- if (next.parentElement.tagName == "LI") {
- next.parentElement.classList.add('no-list-style')
- }
-
- icon.addEventListener('click', () => {
- if (icon.classList.contains('expanded')) {
- collapseSection(icon);
- } else {
- expandSection(icon);
- }
- })
-
- ref.classList.add('ref-internal-padding')
- ref.parentNode.insertBefore(icon, ref);
+}
+
+function getCurrentSection() {
+ let currentSection;
+ if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
+ currentSection = sections[sections.length - 1];
+ }
+ else {
+ if (sections) {
+ sections.forEach(section => {
+ let rect = section.getBoundingClientRect();
+ if (rect.top + document.body.offsetTop < 1) {
+ currentSection = section;
}
+ });
}
+ }
+ return currentSection;
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ sidebar = new Sidebar(document.getElementById('sidebar'));
+ sidebar.resize();
+ sidebar.createCollapsableSections();
+
+ window.addEventListener('scroll', () => {
+ sidebar.setActiveLink(getCurrentSection());
+ sidebar.resize();
+ });
});
+
diff --git a/docs/_static/style.css b/docs/_static/style.css
index ae9b8032..b32e5464 100644
--- a/docs/_static/style.css
+++ b/docs/_static/style.css
@@ -233,22 +233,44 @@ a:hover {
/* headers */
-header {
+header.grid-item {
grid-area: h;
- background-color: var(--sub-header-background);
color: var(--main-text);
+ position: relative;
+ z-index: 1;
+ padding: 0;
}
header > nav {
+ background-color: var(--sub-header-background);
+ padding: 0.8em;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
-header > nav > a {
+header > nav a {
color: var(--white);
}
+header > nav.mobile-only {
+ width: 100%;
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: -1;
+ padding-top: 0;
+ transition: top 0.5s ease-in-out;
+}
+
+header > nav.mobile-only .search {
+ width: 100%;
+}
+
+header > nav.mobile-only .search-wrapper {
+ background-color: var(--sub-header-background);
+}
+
.main-heading {
margin-right: auto;
}
@@ -402,18 +424,20 @@ aside .material-icons,
/* search button stuff */
-.searchwrapper {
+.search-wrapper {
display: flex;
align-items: stretch;
}
-.searchwrapper > input[type=search] {
+.search-wrapper > input[type=search] {
font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif;
+ outline: none;
+ appearance: none;
font-size: 1em;
}
-.searchwrapper > input[type=search],
-.searchwrapper > button[type=submit] {
+.search-wrapper > input[type=search],
+.search-wrapper > button[type=submit] {
background-color: var(--sub-header-background);
border: none;
color: var(--search-text);
@@ -422,28 +446,28 @@ aside .material-icons,
flex: 9;
}
-.searchwrapper {
+.search-wrapper {
border-bottom: 1px solid var(--search-border);
}
-.searchwrapper:focus-within {
+.search-wrapper:focus-within {
border-bottom: 1px solid var(--search-focus);
}
-/* .searchwrapper > input[type=search] {
+/* .search-wrapper > input[type=search] {
border: 1px solid var(--search-border);
border-right: none;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
-.searchwrapper > input[type=search]:focus,
+.search-wrapper > input[type=search]:focus,
button[type=submit]:focus ~ input[type=search] {
border: 1px solid var(--search-focus);
border-right: none;
} */
-.searchwrapper > button[type=submit] {
+.search-wrapper > button[type=submit] {
color: var(--search-button);
/* border: 1px solid var(--search-border); */
/* border-left: none; */
@@ -453,13 +477,13 @@ button[type=submit]:focus ~ input[type=search] {
flex: 1;
}
-/* .searchwrapper > button[type=submit]:focus,
+/* .search-wrapper > button[type=submit]:focus,
input[type=search]:focus ~ button[type=submit] {
border: 1px solid var(--search-focus);
border-left: none;
} */
-.searchwrapper > button[type=submit]:hover {
+.search-wrapper > button[type=submit]:hover {
background-color: var(--search-border);
color: var(--search-button-hover);
}
@@ -1088,6 +1112,10 @@ div.code-block-caption {
background-color: var(--black);
}
+ header > nav {
+ background-color: unset;
+ }
+
.sub-header {
display: flex;
align-items: center;