Added generated doc.
This commit is contained in:
parent
a29d8130a9
commit
4948aaa970
18 changed files with 3605 additions and 6 deletions
501
doc/api/static-assets/script.js
Normal file
501
doc/api/static-assets/script.js
Normal file
|
@ -0,0 +1,501 @@
|
|||
/*
|
||||
*
|
||||
* Update script.js versions in all lib/templates when modifying this file!
|
||||
*
|
||||
*/
|
||||
function initSideNav() {
|
||||
const leftNavToggle = document.getElementById('sidenav-left-toggle');
|
||||
const leftDrawer = document.querySelector('.sidebar-offcanvas-left');
|
||||
const overlay = document.getElementById('overlay-under-drawer');
|
||||
|
||||
function toggleBoth() {
|
||||
if (leftDrawer) {
|
||||
leftDrawer.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (overlay) {
|
||||
overlay.classList.toggle('active');
|
||||
}
|
||||
}
|
||||
|
||||
if (overlay) {
|
||||
overlay.addEventListener('click', toggleBoth);
|
||||
}
|
||||
|
||||
if (leftNavToggle) {
|
||||
leftNavToggle.addEventListener('click', toggleBoth);
|
||||
}
|
||||
}
|
||||
|
||||
function saveLeftScroll() {
|
||||
const leftSidebar = document.getElementById('dartdoc-sidebar-left');
|
||||
sessionStorage.setItem('dartdoc-sidebar-left-scrollt' + window.location.pathname, leftSidebar.scrollTop.toString());
|
||||
sessionStorage.setItem('dartdoc-sidebar-left-scrolll' + window.location.pathname, leftSidebar.scrollLeft.toString());
|
||||
}
|
||||
|
||||
function saveMainContentScroll() {
|
||||
const mainContent = document.getElementById('dartdoc-main-content');
|
||||
sessionStorage.setItem('dartdoc-main-content-scrollt' + window.location.pathname, mainContent.scrollTop.toString());
|
||||
sessionStorage.setItem('dartdoc-main-content-scrolll' + window.location.pathname, mainContent.scrollLeft.toString());
|
||||
}
|
||||
|
||||
function saveRightScroll() {
|
||||
const rightSidebar = document.getElementById('dartdoc-sidebar-right');
|
||||
sessionStorage.setItem('dartdoc-sidebar-right-scrollt' + window.location.pathname, rightSidebar.scrollTop.toString());
|
||||
sessionStorage.setItem('dartdoc-sidebar-right-scrolll' + window.location.pathname, rightSidebar.scrollLeft.toString());
|
||||
}
|
||||
|
||||
function restoreScrolls() {
|
||||
const leftSidebar = document.getElementById('dartdoc-sidebar-left');
|
||||
const mainContent = document.getElementById('dartdoc-main-content');
|
||||
const rightSidebar = document.getElementById('dartdoc-sidebar-right');
|
||||
|
||||
try {
|
||||
const leftSidebarX = sessionStorage.getItem('dartdoc-sidebar-left-scrolll' + window.location.pathname);
|
||||
const leftSidebarY = sessionStorage.getItem('dartdoc-sidebar-left-scrollt' + window.location.pathname);
|
||||
|
||||
const mainContentX = sessionStorage.getItem('dartdoc-main-content-scrolll' + window.location.pathname);
|
||||
const mainContentY = sessionStorage.getItem('dartdoc-main-content-scrollt' + window.location.pathname);
|
||||
|
||||
const rightSidebarX = sessionStorage.getItem('dartdoc-sidebar-right-scrolll' + window.location.pathname);
|
||||
const rightSidebarY = sessionStorage.getItem('dartdoc-sidebar-right-scrollt' + window.location.pathname);
|
||||
|
||||
leftSidebar.scrollTo(parseFloat(leftSidebarX), parseFloat(leftSidebarY));
|
||||
mainContent.scrollTo(parseFloat(mainContentX), parseFloat(mainContentY));
|
||||
rightSidebar.scrollTo(parseFloat(rightSidebarX), parseFloat(rightSidebarY));
|
||||
} finally {
|
||||
// Set visibility to visible after scroll to prevent the brief appearance of the
|
||||
// panel in the wrong position.
|
||||
leftSidebar.style.visibility = 'visible';
|
||||
mainContent.style.visibility = 'visible';
|
||||
rightSidebar.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
|
||||
function initScrollSave() {
|
||||
const leftSidebar = document.getElementById('dartdoc-sidebar-left');
|
||||
const mainContent = document.getElementById('dartdoc-main-content');
|
||||
const rightSidebar = document.getElementById('dartdoc-sidebar-right');
|
||||
|
||||
leftSidebar.addEventListener("scroll", saveLeftScroll, true);
|
||||
mainContent.addEventListener("scroll", saveMainContentScroll, true);
|
||||
rightSidebar.addEventListener("scroll", saveRightScroll, true);
|
||||
}
|
||||
|
||||
const weights = {
|
||||
'library' : 2,
|
||||
'class' : 2,
|
||||
'mixin' : 3,
|
||||
'extension' : 3,
|
||||
'typedef' : 3,
|
||||
'method' : 4,
|
||||
'accessor' : 4,
|
||||
'operator' : 4,
|
||||
'constant' : 4,
|
||||
'property' : 4,
|
||||
'constructor' : 4
|
||||
};
|
||||
|
||||
function findMatches(index, query) {
|
||||
if (query === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const allMatches = [];
|
||||
|
||||
index.forEach(element => {
|
||||
function score(value) {
|
||||
value -= element.overriddenDepth * 10;
|
||||
const weightFactor = weights[element.type] || 4;
|
||||
allMatches.push({element: element, score: (value / weightFactor) >> 0});
|
||||
}
|
||||
|
||||
const name = element.name;
|
||||
const qualifiedName = element.qualifiedName;
|
||||
const lowerName = name.toLowerCase();
|
||||
const lowerQualifiedName = qualifiedName.toLowerCase();
|
||||
const lowerQuery = query.toLowerCase();
|
||||
|
||||
if (name === query || qualifiedName === query || name === `dart:${query}`) {
|
||||
score(2000);
|
||||
} else if (lowerName === `dart:${lowerQuery}`) {
|
||||
score(1800);
|
||||
} else if (lowerName === lowerQuery || lowerQualifiedName === lowerQuery) {
|
||||
score(1700);
|
||||
} else if (query.length > 1) {
|
||||
if (name.startsWith(query) || qualifiedName.startsWith(query)) {
|
||||
score(750);
|
||||
} else if (lowerName.startsWith(lowerQuery) || lowerQualifiedName.startsWith(lowerQuery)) {
|
||||
score(650);
|
||||
} else if (name.includes(query) || qualifiedName.includes(query)) {
|
||||
score(500);
|
||||
} else if (lowerName.includes(lowerQuery) || lowerQualifiedName.includes(query)) {
|
||||
score(400);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
allMatches.sort((a, b) => {
|
||||
const x = b.score - a.score;
|
||||
if (x === 0) {
|
||||
return a.element.name.length - b.element.name.length;
|
||||
}
|
||||
return x;
|
||||
});
|
||||
|
||||
const justElements = [];
|
||||
|
||||
for (let i = 0; i < allMatches.length; i++) {
|
||||
justElements.push(allMatches[i].element);
|
||||
}
|
||||
|
||||
return justElements;
|
||||
}
|
||||
|
||||
let baseHref = '';
|
||||
|
||||
const minLength = 1;
|
||||
const suggestionLimit = 10;
|
||||
|
||||
function initializeSearch(input, index) {
|
||||
input.disabled = false;
|
||||
input.setAttribute('placeholder', 'Search API Docs');
|
||||
|
||||
// Handle grabbing focus when the users types / outside of the input
|
||||
document.addEventListener('keypress', (event) => {
|
||||
if (event.code === 'Slash' && !(document.activeElement instanceof HTMLInputElement)) {
|
||||
event.preventDefault();
|
||||
input.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare elements
|
||||
|
||||
const parentForm = input.parentNode;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.classList.add('tt-wrapper');
|
||||
|
||||
parentForm.replaceChild(wrapper, input);
|
||||
|
||||
const inputHint = document.createElement('input');
|
||||
inputHint.setAttribute('type', 'text');
|
||||
inputHint.setAttribute('autocomplete', 'off');
|
||||
inputHint.setAttribute('readonly', 'true');
|
||||
inputHint.setAttribute('spellcheck', 'false');
|
||||
inputHint.setAttribute('tabindex', '-1');
|
||||
inputHint.classList.add('typeahead', 'tt-hint');
|
||||
|
||||
wrapper.appendChild(inputHint);
|
||||
|
||||
input.setAttribute('autocomplete', 'off');
|
||||
input.setAttribute('spellcheck', 'false');
|
||||
input.classList.add('tt-input');
|
||||
|
||||
wrapper.appendChild(input);
|
||||
|
||||
const listBox = document.createElement('div');
|
||||
listBox.setAttribute('role', 'listbox');
|
||||
listBox.setAttribute('aria-expanded', 'false');
|
||||
listBox.style.display = 'none';
|
||||
listBox.classList.add('tt-menu');
|
||||
|
||||
const presentation = document.createElement('div');
|
||||
presentation.classList.add('tt-elements');
|
||||
|
||||
listBox.appendChild(presentation);
|
||||
|
||||
wrapper.appendChild(listBox);
|
||||
|
||||
// Set up various search functionality
|
||||
|
||||
function highlight(text, query) {
|
||||
query = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
return text.replace(new RegExp(query, 'gi'), (matched) => {
|
||||
return `<strong class='tt-highlight'>${matched}</strong>`;
|
||||
});
|
||||
}
|
||||
|
||||
function createSuggestion(query, match) {
|
||||
const suggestion = document.createElement('div');
|
||||
suggestion.setAttribute('data-href', match.href);
|
||||
suggestion.classList.add('tt-suggestion');
|
||||
|
||||
const suggestionTitle = document.createElement('span');
|
||||
suggestionTitle.classList.add('tt-suggestion-title');
|
||||
suggestionTitle.innerHTML = highlight(`${match.name} ${match.type.toLowerCase()}`, query);
|
||||
|
||||
suggestion.appendChild(suggestionTitle);
|
||||
|
||||
if (match.enclosedBy) {
|
||||
const fromLib = document.createElement('div');
|
||||
fromLib.classList.add('search-from-lib');
|
||||
fromLib.innerHTML = `from ${highlight(match.enclosedBy.name, query)}`;
|
||||
|
||||
suggestion.appendChild(fromLib);
|
||||
}
|
||||
|
||||
suggestion.addEventListener('mousedown', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
suggestion.addEventListener('click', event => {
|
||||
if (match.href) {
|
||||
window.location = baseHref + match.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
let storedValue = null;
|
||||
let actualValue = '';
|
||||
let hint = null;
|
||||
|
||||
let suggestionElements = [];
|
||||
let suggestionsInfo = [];
|
||||
let selectedElement = null;
|
||||
|
||||
function setHint(value) {
|
||||
hint = value;
|
||||
inputHint.value = value || '';
|
||||
}
|
||||
|
||||
function updateSuggestions(query, suggestions) {
|
||||
suggestionsInfo = [];
|
||||
suggestionElements = [];
|
||||
presentation.textContent = '';
|
||||
|
||||
if (suggestions.length < minLength) {
|
||||
setHint(null)
|
||||
hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < suggestions.length; i++) {
|
||||
const element = createSuggestion(query, suggestions[i]);
|
||||
suggestionElements.push(element);
|
||||
presentation.appendChild(element);
|
||||
}
|
||||
|
||||
suggestionsInfo = suggestions;
|
||||
|
||||
setHint(query + suggestions[0].name.slice(query.length));
|
||||
selectedElement = null;
|
||||
|
||||
showSuggestions();
|
||||
}
|
||||
|
||||
function handle(newValue, forceUpdate) {
|
||||
if (actualValue === newValue && !forceUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newValue === null || newValue.length === 0) {
|
||||
updateSuggestions('', []);
|
||||
return;
|
||||
}
|
||||
|
||||
const suggestions = findMatches(index, newValue).slice(0, suggestionLimit);
|
||||
actualValue = newValue;
|
||||
|
||||
updateSuggestions(newValue, suggestions);
|
||||
}
|
||||
|
||||
function showSuggestions() {
|
||||
if (presentation.hasChildNodes()) {
|
||||
listBox.style.display = 'block';
|
||||
listBox.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
function hideSuggestions() {
|
||||
listBox.style.display = 'none';
|
||||
listBox.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
|
||||
// Hook up events
|
||||
|
||||
input.addEventListener('focus', () => {
|
||||
handle(input.value, true);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
selectedElement = null;
|
||||
if (storedValue !== null) {
|
||||
input.value = storedValue;
|
||||
storedValue = null;
|
||||
}
|
||||
hideSuggestions();
|
||||
setHint(null);
|
||||
});
|
||||
|
||||
input.addEventListener('input', event => {
|
||||
handle(event.target.value);
|
||||
});
|
||||
|
||||
input.addEventListener('keydown', event => {
|
||||
if (suggestionElements.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.code === 'Enter') {
|
||||
const selectingElement = selectedElement || 0;
|
||||
const href = suggestionElements[selectingElement].dataset.href;
|
||||
if (href) {
|
||||
window.location = baseHref + href;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.code === 'Tab') {
|
||||
if (selectedElement === null) {
|
||||
// The user wants to fill the field with the hint
|
||||
if (hint !== null) {
|
||||
input.value = hint;
|
||||
handle(hint);
|
||||
event.preventDefault();
|
||||
}
|
||||
} else {
|
||||
// The user wants to fill the input field with their currently selected suggestion
|
||||
handle(suggestionsInfo[selectedElement].name);
|
||||
storedValue = null;
|
||||
selectedElement = null;
|
||||
event.preventDefault();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const lastIndex = suggestionElements.length - 1;
|
||||
const previousSelectedElement = selectedElement;
|
||||
|
||||
if (event.code === 'ArrowUp') {
|
||||
if (selectedElement === null) {
|
||||
selectedElement = lastIndex;
|
||||
} else if (selectedElement === 0) {
|
||||
selectedElement = null;
|
||||
} else {
|
||||
selectedElement--;
|
||||
}
|
||||
} else if (event.code === 'ArrowDown') {
|
||||
if (selectedElement === null) {
|
||||
selectedElement = 0;
|
||||
} else if (selectedElement === lastIndex) {
|
||||
selectedElement = null;
|
||||
} else {
|
||||
selectedElement++;
|
||||
}
|
||||
} else {
|
||||
if (storedValue !== null) {
|
||||
storedValue = null;
|
||||
handle(input.value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousSelectedElement !== null) {
|
||||
suggestionElements[previousSelectedElement].classList.remove('tt-cursor');
|
||||
}
|
||||
|
||||
if (selectedElement !== null) {
|
||||
const selected = suggestionElements[selectedElement];
|
||||
selected.classList.add('tt-cursor');
|
||||
|
||||
// Guarantee the selected element is visible
|
||||
if (selectedElement === 0) {
|
||||
listBox.scrollTop = 0;
|
||||
} else if (selectedElement === lastIndex) {
|
||||
listBox.scrollTop = listBox.scrollHeight;
|
||||
} else {
|
||||
const offsetTop = selected.offsetTop;
|
||||
const parentOffsetHeight = listBox.offsetHeight;
|
||||
if (offsetTop < parentOffsetHeight || parentOffsetHeight < (offsetTop + selected.offsetHeight)) {
|
||||
selected.scrollIntoView({behavior: 'auto', block: 'nearest'});
|
||||
}
|
||||
}
|
||||
|
||||
if (storedValue === null) {
|
||||
// Store the actual input value to display their currently selected item
|
||||
storedValue = input.value;
|
||||
}
|
||||
input.value = suggestionsInfo[selectedElement].name;
|
||||
setHint('');
|
||||
} else if (storedValue !== null && previousSelectedElement !== null) {
|
||||
// They are moving back to the input field, so return the stored value
|
||||
input.value = storedValue;
|
||||
setHint(storedValue + suggestionsInfo[0].name.slice(storedValue.length));
|
||||
storedValue = null;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Place this first so that unexpected exceptions in other JavaScript do not block page visibility.
|
||||
restoreScrolls();
|
||||
hljs.highlightAll();
|
||||
initSideNav();
|
||||
initScrollSave();
|
||||
|
||||
const searchBox = document.getElementById('search-box');
|
||||
const searchBody = document.getElementById('search-body');
|
||||
const searchSidebar = document.getElementById('search-sidebar');
|
||||
|
||||
if (document.body.getAttribute('data-using-base-href') === 'false') {
|
||||
// If dartdoc did not add a base-href tag, we will need to add the relative
|
||||
// path ourselves.
|
||||
baseHref = document.body.getAttribute('data-base-href');
|
||||
}
|
||||
|
||||
function disableSearch() {
|
||||
console.log('Could not activate search functionality.');
|
||||
if (searchBox) {
|
||||
searchBox.placeholder = 'Failed to initialize search';
|
||||
}
|
||||
|
||||
if (searchBody) {
|
||||
searchBody.placeholder = 'Failed to initialize search';
|
||||
}
|
||||
|
||||
if (searchSidebar) {
|
||||
searchSidebar.placeholder = 'Failed to initialize search';
|
||||
}
|
||||
}
|
||||
|
||||
if ('fetch' in window) {
|
||||
fetch(baseHref + 'index.json', {method: 'GET'})
|
||||
.then(response => response.json())
|
||||
.then(index => {
|
||||
// Handle if the user specified a `search` parameter in the URL
|
||||
if ('URLSearchParams' in window) {
|
||||
const search = new URLSearchParams(window.location.search).get('search');
|
||||
if (search) {
|
||||
const matches = findMatches(search);
|
||||
if (matches.length !== 0) {
|
||||
window.location = baseHref + matches[0].href;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize all three search fields
|
||||
if (searchBox) {
|
||||
initializeSearch(searchBox, index);
|
||||
}
|
||||
|
||||
if (searchBody) {
|
||||
initializeSearch(searchBody, index);
|
||||
}
|
||||
|
||||
if (searchSidebar) {
|
||||
initializeSearch(searchSidebar, index);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
disableSearch();
|
||||
});
|
||||
} else {
|
||||
disableSearch();
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue