initial commit
This commit is contained in:
1
mne/report/js_and_css/bootstrap-icons/bootstrap-icons.mne.min.css
vendored
Normal file
1
mne/report/js_and_css/bootstrap-icons/bootstrap-icons.mne.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10
mne/report/js_and_css/bootstrap-table/bootstrap-table-copy-rows.min.js
vendored
Normal file
10
mne/report/js_and_css/bootstrap-table/bootstrap-table-copy-rows.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
mne/report/js_and_css/bootstrap-table/bootstrap-table-export.min.js
vendored
Normal file
10
mne/report/js_and_css/bootstrap-table/bootstrap-table-export.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
mne/report/js_and_css/bootstrap-table/bootstrap-table.min.css
vendored
Normal file
10
mne/report/js_and_css/bootstrap-table/bootstrap-table.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10
mne/report/js_and_css/bootstrap-table/bootstrap-table.min.js
vendored
Normal file
10
mne/report/js_and_css/bootstrap-table/bootstrap-table.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
13
mne/report/js_and_css/bootstrap-table/tableExport.min.js
vendored
Normal file
13
mne/report/js_and_css/bootstrap-table/tableExport.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
mne/report/js_and_css/bootstrap.bundle.min.js
vendored
Normal file
7
mne/report/js_and_css/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
mne/report/js_and_css/bootstrap.min.css
vendored
Normal file
7
mne/report/js_and_css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
mne/report/js_and_css/highlightjs/atom-one-dark-reasonable.min.css
vendored
Normal file
1
mne/report/js_and_css/highlightjs/atom-one-dark-reasonable.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-keyword,.hljs-operator,.hljs-pattern-match{color:#f92672}.hljs-function,.hljs-pattern-match .hljs-constructor{color:#61aeee}.hljs-function .hljs-params{color:#a6e22e}.hljs-function .hljs-params .hljs-typing{color:#fd971f}.hljs-module-access .hljs-module{color:#7e57c2}.hljs-constructor{color:#e2b93d}.hljs-constructor .hljs-string{color:#9ccc65}.hljs-comment,.hljs-quote{color:#b18eb1;font-style:italic}.hljs-doctag,.hljs-formula{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}
|
||||
1
mne/report/js_and_css/highlightjs/atom-one-light.min.css
vendored
Normal file
1
mne/report/js_and_css/highlightjs/atom-one-light.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}
|
||||
9
mne/report/js_and_css/highlightjs/default.min.css
vendored
Normal file
9
mne/report/js_and_css/highlightjs/default.min.css
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
Theme: Default
|
||||
Description: Original highlight.js style
|
||||
Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
Maintainer: @highlightjs/core-team
|
||||
Website: https://highlightjs.org/
|
||||
License: see project LICENSE
|
||||
Touched: 2021
|
||||
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f0f0f0;color:#444}.hljs-comment{color:#888}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#bc6060}.hljs-literal{color:#78a960}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
||||
1282
mne/report/js_and_css/highlightjs/highlight.min.js
vendored
Normal file
1282
mne/report/js_and_css/highlightjs/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
mne/report/js_and_css/jquery-3.6.0.min.js
vendored
Normal file
2
mne/report/js_and_css/jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
19
mne/report/js_and_css/report.css
Normal file
19
mne/report/js_and_css/report.css
Normal file
@@ -0,0 +1,19 @@
|
||||
#container {
|
||||
position: relative;
|
||||
padding-bottom: 8rem;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-top: 90px;
|
||||
scroll-behavior: smooth;
|
||||
position: relative; /* for scrollspy */
|
||||
}
|
||||
|
||||
#toc {
|
||||
margin-top: 90px;
|
||||
padding-bottom: 8rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 8rem;
|
||||
}
|
||||
269
mne/report/js_and_css/report.js
Normal file
269
mne/report/js_and_css/report.js
Normal file
@@ -0,0 +1,269 @@
|
||||
/* We need to refresh the scroll spy after (un)hiding elements */
|
||||
const refreshScrollSpy = () =>{
|
||||
const dataSpyList = [].slice.call(document.querySelectorAll('[data-bs-spy="scroll"]'));
|
||||
dataSpyList.forEach((dataSpyEl) => {
|
||||
bootstrap.ScrollSpy.getInstance(dataSpyEl)
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
const propagateScrollSpyURL = () => {
|
||||
window.addEventListener('activate.bs.scrollspy', (e) => {
|
||||
history.replaceState({}, "", e.relatedTarget);
|
||||
});
|
||||
}
|
||||
|
||||
/* Show or hide elements based on their tag */
|
||||
const toggleTagVisibility = (tagName) => {
|
||||
const tag = tags.find((element) => {
|
||||
return element.name === tagName;
|
||||
});
|
||||
tag.visible = !tag.visible;
|
||||
|
||||
const hiddenTagNames = tags.map((tag) => {
|
||||
if (tag.visible) {
|
||||
return
|
||||
} else {
|
||||
return tag.name
|
||||
}
|
||||
});
|
||||
const elements = $(`[data-mne-tags~="${tagName}"]`);
|
||||
elements.each((i) => {
|
||||
const currentElement = elements[i];
|
||||
const tagValuesOfCurrentElement = currentElement.getAttribute('data-mne-tags');
|
||||
|
||||
// TODO This can probably be refactored to not use a Set.
|
||||
const tagNamesOfCurrentElement = new Set(tagValuesOfCurrentElement.match(/\S+/g)); // non-whitespace
|
||||
const visibleTagNamesOfCurrentElement = new Set(
|
||||
[...tagNamesOfCurrentElement].filter(e => !hiddenTagNames.includes(e))
|
||||
);
|
||||
|
||||
if (visibleTagNamesOfCurrentElement.size === 0) { // hide
|
||||
$(currentElement).slideToggle('fast', () => {
|
||||
currentElement.classList.add('d-none');
|
||||
});
|
||||
} else if ($(currentElement).hasClass('d-none')) { // show
|
||||
currentElement.classList.remove('d-none');
|
||||
$(currentElement).slideToggle('fast');
|
||||
}
|
||||
})
|
||||
|
||||
const tagBadgeElements = document.querySelectorAll(`span.badge[data-mne-tag~="${tagName}"]`);
|
||||
tagBadgeElements.forEach((badgeElement) => {
|
||||
if (tag.visible) {
|
||||
badgeElement.removeAttribute('data-mne-tag-hidden');
|
||||
badgeElement.classList.remove('bg-secondary');
|
||||
badgeElement.classList.add('bg-primary');
|
||||
} else {
|
||||
badgeElement.setAttribute('data-mne-tag-hidden', true);
|
||||
badgeElement.classList.remove('bg-primary');
|
||||
badgeElement.classList.add('bg-secondary');
|
||||
}
|
||||
})
|
||||
|
||||
refreshScrollSpy();
|
||||
}
|
||||
|
||||
/* Gather all available tags and expose them in the global namespace */
|
||||
let tags = []; // array of objects
|
||||
|
||||
const gatherTags = () => {
|
||||
// only consider top-level elements
|
||||
const taggedElements = document.querySelectorAll("#content > div[data-mne-tags]");
|
||||
|
||||
taggedElements.forEach((element) => {
|
||||
const value = element.getAttribute('data-mne-tags');
|
||||
const tagNames = value.match(/\S+/g); // non-whitespace
|
||||
tagNames.forEach((tagName) => {
|
||||
const existingTag = tags.find((element) => {
|
||||
return element.name === tagName;
|
||||
})
|
||||
|
||||
if (existingTag === undefined) {
|
||||
const tag = {
|
||||
name : tagName,
|
||||
visible: true,
|
||||
count: 1
|
||||
};
|
||||
tags.push(tag);
|
||||
} else {
|
||||
existingTag.count = existingTag.count + 1;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/* Badges do display the tag count */
|
||||
const updateTagCountBadges = () => {
|
||||
const menuEntries = document
|
||||
.querySelectorAll("#filter-by-tags-dropdown-menu > ul > li > label[data-mne-tag]")
|
||||
|
||||
menuEntries.forEach((menuEntry) => {
|
||||
const tagName = menuEntry.getAttribute('data-mne-tag');
|
||||
const tag = tags.find((tag) => {
|
||||
return tag.name === tagName;
|
||||
})
|
||||
const tagCount = tag.count;
|
||||
|
||||
const tagCountBadge = menuEntry.querySelector('span.badge');
|
||||
tagCountBadge.innerHTML = tagCount.toString();
|
||||
});
|
||||
}
|
||||
|
||||
const addFilterByTagsCheckboxEventHandlers = () => {
|
||||
// "Filter by tag" checkbox event handling
|
||||
const selectAllTagsCheckboxLabel = document
|
||||
.querySelector('#selectAllTagsCheckboxLabel');
|
||||
const filterByTagsDropdownMenuLabels = document
|
||||
.querySelectorAll("#filter-by-tags-dropdown-menu > ul > li > label[data-mne-tag]")
|
||||
|
||||
filterByTagsDropdownMenuLabels.forEach((label) => {
|
||||
// Prevent dropdown menu from closing when clicking on a tag checkbox label
|
||||
label.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
})
|
||||
|
||||
// Show / hide content if a tag checkbox value has changed
|
||||
const tagName = label.getAttribute("data-mne-tag");
|
||||
const checkbox = label.querySelector("input");
|
||||
checkbox.addEventListener("change", () => {
|
||||
toggleTagVisibility(tagName);
|
||||
})
|
||||
})
|
||||
|
||||
// "Select all" checkbox
|
||||
selectAllTagsCheckboxLabel.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
})
|
||||
const selectAllTagsCheckbox = selectAllTagsCheckboxLabel.querySelector('input');
|
||||
|
||||
selectAllTagsCheckbox.addEventListener("change", (e) => {
|
||||
const selectAllCheckboxStatus = e.target.checked;
|
||||
|
||||
filterByTagsDropdownMenuLabels.forEach((element) => {
|
||||
const checkbox = element.querySelector('input');
|
||||
if (checkbox.checked !== selectAllCheckboxStatus) {
|
||||
checkbox.checked = selectAllCheckboxStatus
|
||||
|
||||
// we need to manually trigger the change event
|
||||
const changeEvent = new Event('change');
|
||||
checkbox.dispatchEvent(changeEvent);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/* Avoid top of content getting hidden behind navbar after clicking on a TOC
|
||||
link */
|
||||
const _handleTocLinkClick = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const topBarHeight = document.querySelector('#top-bar').scrollHeight
|
||||
const margin = 30 + topBarHeight;
|
||||
|
||||
const tocLinkElement = e.target;
|
||||
const targetDomId = tocLinkElement.getAttribute('href');
|
||||
const targetElement = document.querySelector(targetDomId);
|
||||
const top = targetElement.getBoundingClientRect().top + window.scrollY;
|
||||
|
||||
// Update URL to reflect the current scroll position.
|
||||
// We use history.pushState to change the URL without causing the browser to scroll.
|
||||
history.pushState(null, "", targetDomId);
|
||||
|
||||
// Now scroll to the correct position.
|
||||
window.scrollTo(0, top - margin);
|
||||
}
|
||||
|
||||
const fixScrollingForTocLinks = () => {
|
||||
const tocLinkElements = document.querySelectorAll('#toc-navbar > a');
|
||||
|
||||
tocLinkElements.forEach((element) => {
|
||||
element.removeEventListener('click', _handleTocLinkClick)
|
||||
element.addEventListener('click', _handleTocLinkClick)
|
||||
})
|
||||
}
|
||||
|
||||
const addSliderEventHandlers = () => {
|
||||
const accordionElementsWithSlider = document.querySelectorAll('div.accordion-item.slider');
|
||||
accordionElementsWithSlider.forEach((el) => {
|
||||
const accordionElement = el.querySelector('div.accordion-body');
|
||||
|
||||
const slider = accordionElement.querySelector('input');
|
||||
// const sliderLabel = accordionElement.querySelector('label');
|
||||
const carousel = accordionElement.querySelector('div.carousel');
|
||||
slider.addEventListener('input', (e) => {
|
||||
const sliderValue = parseInt(e.target.value);
|
||||
$(carousel).carousel(sliderValue);
|
||||
})
|
||||
|
||||
// Allow focussing the slider with a click on the slider or carousel, so keyboard
|
||||
// controls (left / right arrow) can be enabled.
|
||||
// This also appears to be the only way to focus the slider in Safari:
|
||||
// https://itnext.io/fixing-focus-for-safari-b5916fef1064?gi=c1b8b043fa9b
|
||||
slider.addEventListener('click', () => {
|
||||
slider.focus({preventScroll: true})
|
||||
})
|
||||
carousel.addEventListener('click', () => {
|
||||
slider.focus({preventScroll: true})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/* Avoid top of content gets hidden behind the top navbar */
|
||||
const fixTopMargin = () => {
|
||||
const topBarHeight = document.querySelector('#top-bar').scrollHeight
|
||||
const margin = 30 + topBarHeight;
|
||||
|
||||
document.getElementById('content').style.marginTop = `${margin}px`;
|
||||
document.getElementById('toc').style.marginTop = `${margin}px`;
|
||||
}
|
||||
|
||||
/* Show / hide all tags on keypress */
|
||||
const _globalKeyHandler = (e) => {
|
||||
if (e.code === "KeyT") {
|
||||
const selectAllTagsCheckbox = document
|
||||
.querySelector('#selectAllTagsCheckboxLabel > input');
|
||||
selectAllTagsCheckbox.checked = !selectAllTagsCheckbox.checked;
|
||||
|
||||
// we need to manually trigger the change event
|
||||
const changeEvent = new Event('change');
|
||||
selectAllTagsCheckbox.dispatchEvent(changeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
const enableGlobalKeyHandler = () => {
|
||||
window.onkeydown = (e) => _globalKeyHandler(e);
|
||||
}
|
||||
|
||||
const disableGlobalKeyHandler = () => {
|
||||
window.onkeydown = null;
|
||||
}
|
||||
|
||||
/* Disable processing global key events when a search box is active */
|
||||
const disableGlobalKeysInSearchBox = () => {
|
||||
const searchBoxElements = document.querySelectorAll('input.search-input');
|
||||
searchBoxElements.forEach((el) => {
|
||||
el.addEventListener('focus', () => disableGlobalKeyHandler());
|
||||
el.addEventListener('blur', () => enableGlobalKeyHandler());
|
||||
})
|
||||
}
|
||||
|
||||
/* Run once all content is fully loaded. */
|
||||
window.addEventListener('load', () => {
|
||||
gatherTags();
|
||||
updateTagCountBadges();
|
||||
addFilterByTagsCheckboxEventHandlers();
|
||||
addSliderEventHandlers();
|
||||
fixTopMargin();
|
||||
fixScrollingForTocLinks();
|
||||
hljs.highlightAll(); // enable highlight.js
|
||||
disableGlobalKeysInSearchBox();
|
||||
enableGlobalKeyHandler();
|
||||
propagateScrollSpyURL();
|
||||
});
|
||||
|
||||
/* Resizing the window throws off the scroll spy and top-margin handling. */
|
||||
window.onresize = () => {
|
||||
fixTopMargin();
|
||||
refreshScrollSpy();
|
||||
};
|
||||
Reference in New Issue
Block a user