Add copyright statements to SCSS and JS; fix indentation for JS
This commit is contained in:
parent
1dadff5701
commit
9b2d9cf6b7
3 changed files with 322 additions and 277 deletions
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
$primary: #FFF;
|
$primary: #FFF;
|
||||||
$secondary: #0098D4;
|
$secondary: #0098D4;
|
||||||
$dark: #333;
|
$dark: #333;
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Custom SCSS for the Matrix spec
|
Custom SCSS for the Matrix spec
|
||||||
*/
|
*/
|
||||||
|
|
169
static/js/toc.js
169
static/js/toc.js
|
@ -1,16 +1,32 @@
|
||||||
/*
|
/*
|
||||||
Account for id attributes that are in the sidebar nav
|
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
|
||||||
*/
|
|
||||||
function populateIds() {
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Account for id attributes that are in the sidebar nav
|
||||||
|
*/
|
||||||
|
function populateIds() {
|
||||||
const navItems = document.querySelectorAll(".td-sidebar-nav li");
|
const navItems = document.querySelectorAll(".td-sidebar-nav li");
|
||||||
return Array.from(navItems).map(item => item.id).filter(id => id != "");
|
return Array.from(navItems).map(item => item.id).filter(id => id != "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Given an ID and an array of IDs, return s version of the original ID that's
|
Given an ID and an array of IDs, return s version of the original ID that's
|
||||||
not equal to any of the IDs in the array.
|
not equal to any of the IDs in the array.
|
||||||
*/
|
*/
|
||||||
function uniquifyHeadingId(id, uniqueIDs) {
|
function uniquifyHeadingId(id, uniqueIDs) {
|
||||||
const baseId = id;
|
const baseId = id;
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
while (uniqueIDs.includes(id)) {
|
while (uniqueIDs.includes(id)) {
|
||||||
|
@ -18,41 +34,41 @@
|
||||||
id = baseId + "-" + counter.toString();
|
id = baseId + "-" + counter.toString();
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Given an array of heading nodes, ensure they all have unique IDs.
|
Given an array of heading nodes, ensure they all have unique IDs.
|
||||||
|
|
||||||
We have to do this mostly because of client-server modules, which are
|
We have to do this mostly because of client-server modules, which are
|
||||||
rendered separately then glued together with a template.
|
rendered separately then glued together with a template.
|
||||||
Because heading IDs are generated in rendering, this means they can and will
|
Because heading IDs are generated in rendering, this means they can and will
|
||||||
end up with duplicate IDs.
|
end up with duplicate IDs.
|
||||||
*/
|
*/
|
||||||
function uniquifyHeadingIds(headings) {
|
function uniquifyHeadingIds(headings) {
|
||||||
const uniqueIDs = populateIds();
|
const uniqueIDs = populateIds();
|
||||||
for (let heading of headings) {
|
for (let heading of headings) {
|
||||||
const uniqueID = uniquifyHeadingId(heading.id, uniqueIDs);
|
const uniqueID = uniquifyHeadingId(heading.id, uniqueIDs);
|
||||||
uniqueIDs.push(uniqueID);
|
uniqueIDs.push(uniqueID);
|
||||||
heading.id = uniqueID;
|
heading.id = uniqueID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The document contains "normal" headings, and these have corresponding items
|
The document contains "normal" headings, and these have corresponding items
|
||||||
in the ToC.
|
in the ToC.
|
||||||
|
|
||||||
The document might also contain H1 headings that act as titles for blocks of
|
The document might also contain H1 headings that act as titles for blocks of
|
||||||
rendered data, like HTTP APIs or event schemas. Unlike "normal" headings,
|
rendered data, like HTTP APIs or event schemas. Unlike "normal" headings,
|
||||||
these headings don't appear in the ToC. But they do have anchor IDs to enable
|
these headings don't appear in the ToC. But they do have anchor IDs to enable
|
||||||
links to them. When someone follows a link to one of these "rendered data"
|
links to them. When someone follows a link to one of these "rendered data"
|
||||||
headings we want to scroll the ToC to the item corresponding to the "normal"
|
headings we want to scroll the ToC to the item corresponding to the "normal"
|
||||||
heading preceding the "rendered data" heading we have visited.
|
heading preceding the "rendered data" heading we have visited.
|
||||||
|
|
||||||
To support this we need to add `data` attributes to ToC items.
|
To support this we need to add `data` attributes to ToC items.
|
||||||
These attributes identify which "rendered data" headings live underneath
|
These attributes identify which "rendered data" headings live underneath
|
||||||
the heading corresponding to that ToC item.
|
the heading corresponding to that ToC item.
|
||||||
*/
|
*/
|
||||||
function setTocItemChildren(toc, headings) {
|
function setTocItemChildren(toc, headings) {
|
||||||
let tocEntryForHeading = null;
|
let tocEntryForHeading = null;
|
||||||
for (const heading of headings) {
|
for (const heading of headings) {
|
||||||
// H1 headings are rendered-data headings
|
// H1 headings are rendered-data headings
|
||||||
|
@ -64,12 +80,12 @@
|
||||||
tocEntryForHeading.setAttribute(`data-${heading.id}`, "true");
|
tocEntryForHeading.setAttribute(`data-${heading.id}`, "true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generate a table of contents based on the headings in the document.
|
Generate a table of contents based on the headings in the document.
|
||||||
*/
|
*/
|
||||||
function makeToc() {
|
function makeToc() {
|
||||||
|
|
||||||
// make the title from the H1
|
// make the title from the H1
|
||||||
const h1 = document.body.querySelector("h1");
|
const h1 = document.body.querySelector("h1");
|
||||||
|
@ -102,30 +118,29 @@
|
||||||
|
|
||||||
// tell ToC items about any rendered-data headings they contain
|
// tell ToC items about any rendered-data headings they contain
|
||||||
setTocItemChildren(section.content, headings);
|
setTocItemChildren(section.content, headings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a single ToC entry
|
// create a single ToC entry
|
||||||
function makeTocEntry(heading) {
|
function makeTocEntry(heading) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.setAttribute("href", `#${heading.id}`);
|
a.setAttribute("href", `#${heading.id}`);
|
||||||
a.textContent = heading.textContent;
|
a.textContent = heading.textContent;
|
||||||
li.appendChild(a);
|
li.appendChild(a);
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Each ToC section is an `<ol>` element.
|
Each ToC section is an `<ol>` element.
|
||||||
ToC entries are `<li>` elements and these contain nested ToC sections,
|
ToC entries are `<li>` elements and these contain nested ToC sections,
|
||||||
whenever we go to the next heading level down.
|
whenever we go to the next heading level down.
|
||||||
*/
|
*/
|
||||||
function makeTocSection(headings, index) {
|
function makeTocSection(headings, index) {
|
||||||
const ol = document.createElement("ol");
|
const ol = document.createElement("ol");
|
||||||
let previousHeading = null;
|
let previousHeading = null;
|
||||||
let previousLi = null;
|
let previousLi = null;
|
||||||
let i = index;
|
let i = index;
|
||||||
const lis = [];
|
const lis = [];
|
||||||
|
|
||||||
for (i; i < headings.length; i++) {
|
for (i; i < headings.length; i++) {
|
||||||
const thisHeading = headings[i];
|
const thisHeading = headings[i];
|
||||||
if (previousHeading && (thisHeading.tagName > previousHeading.tagName)) {
|
if (previousHeading && (thisHeading.tagName > previousHeading.tagName)) {
|
||||||
|
@ -158,21 +173,20 @@
|
||||||
content: ol,
|
content: ol,
|
||||||
index: i
|
index: i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set a new ToC entry.
|
Set a new ToC entry.
|
||||||
Clear any previously highlighted ToC items, set the new one,
|
Clear any previously highlighted ToC items, set the new one,
|
||||||
and adjust the ToC scroll position.
|
and adjust the ToC scroll position.
|
||||||
*/
|
*/
|
||||||
function setTocEntry(newEntry) {
|
function setTocEntry(newEntry) {
|
||||||
const activeEntries = document.querySelectorAll("#toc a.active");
|
const activeEntries = document.querySelectorAll("#toc a.active");
|
||||||
for (const activeEntry of activeEntries) {
|
for (const activeEntry of activeEntries) {
|
||||||
activeEntry.classList.remove('active');
|
activeEntry.classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
newEntry.classList.add('active');
|
newEntry.classList.add('active');
|
||||||
|
|
||||||
// don't scroll the sidebar nav if the main content is not scrolled
|
// don't scroll the sidebar nav if the main content is not scrolled
|
||||||
const nav = document.querySelector("#td-section-nav");
|
const nav = document.querySelector("#td-section-nav");
|
||||||
const content = document.querySelector("html");
|
const content = document.querySelector("html");
|
||||||
|
@ -181,29 +195,28 @@
|
||||||
} else {
|
} else {
|
||||||
nav.scrollTop = 0;
|
nav.scrollTop = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test whether a node is in the viewport
|
Test whether a node is in the viewport
|
||||||
*/
|
*/
|
||||||
function isInViewport(node) {
|
function isInViewport(node) {
|
||||||
const rect = node.getBoundingClientRect();
|
const rect = node.getBoundingClientRect();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
rect.top >= 0 &&
|
rect.top >= 0 &&
|
||||||
rect.left >= 0 &&
|
rect.left >= 0 &&
|
||||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The callback we pass to the IntersectionObserver constructor.
|
The callback we pass to the IntersectionObserver constructor.
|
||||||
|
|
||||||
Called when any of our observed nodes starts or stops intersecting
|
Called when any of our observed nodes starts or stops intersecting
|
||||||
with the viewport.
|
with the viewport.
|
||||||
*/
|
*/
|
||||||
function handleIntersectionUpdate(entries) {
|
function handleIntersectionUpdate(entries) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Special case: If the current URL hash matches a ToC entry, and
|
Special case: If the current URL hash matches a ToC entry, and
|
||||||
|
@ -275,13 +288,13 @@
|
||||||
setTocEntry(newEntry);
|
setTocEntry(newEntry);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Track when headings enter the viewport, and use this to update the highlight
|
Track when headings enter the viewport, and use this to update the highlight
|
||||||
for the corresponding ToC entry.
|
for the corresponding ToC entry.
|
||||||
*/
|
*/
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
makeToc();
|
makeToc();
|
||||||
|
|
||||||
|
@ -298,4 +311,4 @@
|
||||||
observer.observe(section);
|
observer.observe(section);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue