Merge pull request #2554 from GuillaumeGomez/eslint
Fix eslint warnings and add eslint check in CI
This commit is contained in:
commit
b47d1cff33
8 changed files with 636 additions and 417 deletions
95
.eslintrc.json
Normal file
95
.eslintrc.json
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"globals": {
|
||||||
|
"module": "readonly",
|
||||||
|
"require": "readonly"
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018,
|
||||||
|
"requireConfigFile": false,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"ignorePatterns": ["**min.js", "**/highlight.js", "**/playground_editor/*"],
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"brace-style": [
|
||||||
|
"error",
|
||||||
|
"1tbs",
|
||||||
|
{ "allowSingleLine": false }
|
||||||
|
],
|
||||||
|
"curly": "error",
|
||||||
|
"no-trailing-spaces": "error",
|
||||||
|
"no-multi-spaces": "error",
|
||||||
|
"keyword-spacing": [
|
||||||
|
"error",
|
||||||
|
{ "before": true, "after": true }
|
||||||
|
],
|
||||||
|
"comma-spacing": [
|
||||||
|
"error",
|
||||||
|
{ "before": false, "after": true }
|
||||||
|
],
|
||||||
|
"arrow-spacing": [
|
||||||
|
"error",
|
||||||
|
{ "before": true, "after": true }
|
||||||
|
],
|
||||||
|
"key-spacing": [
|
||||||
|
"error",
|
||||||
|
{ "beforeColon": false, "afterColon": true, "mode": "strict" }
|
||||||
|
],
|
||||||
|
"func-call-spacing": ["error", "never"],
|
||||||
|
"space-infix-ops": "error",
|
||||||
|
"space-before-function-paren": ["error", "never"],
|
||||||
|
"space-before-blocks": "error",
|
||||||
|
"no-console": [
|
||||||
|
"error",
|
||||||
|
{ "allow": ["warn", "error"] }
|
||||||
|
],
|
||||||
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
|
"comma-style": ["error", "last"],
|
||||||
|
"max-len": ["error", { "code": 100, "tabWidth": 2 }],
|
||||||
|
"eol-last": ["error", "always"],
|
||||||
|
"no-extra-parens": "error",
|
||||||
|
"arrow-parens": ["error", "as-needed"],
|
||||||
|
"no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"argsIgnorePattern": "^_",
|
||||||
|
"varsIgnorePattern": "^_"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prefer-const": ["error"],
|
||||||
|
"no-var": "error",
|
||||||
|
"eqeqeq": "error"
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"tests/**/*.js"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"jest": true,
|
||||||
|
"node": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
.github/workflows/main.yml
vendored
7
.github/workflows/main.yml
vendored
|
|
@ -3,9 +3,6 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
merge_group:
|
merge_group:
|
||||||
|
|
||||||
env:
|
|
||||||
BROWSER_UI_TEST_VERSION: '0.19.0'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
@ -85,7 +82,9 @@ jobs:
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
- name: Install browser-ui-test
|
- name: Install browser-ui-test
|
||||||
run: npm install browser-ui-test@"${BROWSER_UI_TEST_VERSION}"
|
run: npm install
|
||||||
|
- name: Run eslint
|
||||||
|
run: npm run lint
|
||||||
- name: Build and run tests (+ GUI)
|
- name: Build and run tests (+ GUI)
|
||||||
run: cargo test --locked --target x86_64-unknown-linux-gnu --test gui
|
run: cargo test --locked --target x86_64-unknown-linux-gnu --test gui
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,8 @@ If you want to only run some tests, you can filter them by passing (part of) the
|
||||||
cargo test --test gui -- search
|
cargo test --test gui -- search
|
||||||
```
|
```
|
||||||
|
|
||||||
The first time, it'll fail and ask you to install the `browser-ui-test` package. Install it then re-run the tests.
|
The first time, it'll fail and ask you to install the `browser-ui-test` package. Install it with the provided
|
||||||
|
command then re-run the tests.
|
||||||
|
|
||||||
If you want to disable the headless mode, use the `--disable-headless-test` option:
|
If you want to disable the headless mode, use the `--disable-headless-test` option:
|
||||||
|
|
||||||
|
|
@ -162,6 +163,21 @@ The GUI tests are in the directory `tests/gui` in text files with the `.goml` ex
|
||||||
using a `node.js` framework called `browser-ui-test`. You can find documentation for this language on its
|
using a `node.js` framework called `browser-ui-test`. You can find documentation for this language on its
|
||||||
[repository](https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md).
|
[repository](https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md).
|
||||||
|
|
||||||
|
### Checking changes in `.js` files
|
||||||
|
|
||||||
|
The `.js` files source code is checked using [`eslint`](https://eslint.org/). This is a linter (just like `clippy` in Rust)
|
||||||
|
for the Javascript language. You can install it with `npm` by running the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can run it using:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
## Updating highlight.js
|
## Updating highlight.js
|
||||||
|
|
||||||
The following are instructions for updating [highlight.js](https://highlightjs.org/).
|
The following are instructions for updating [highlight.js](https://highlightjs.org/).
|
||||||
|
|
|
||||||
10
package.json
Normal file
10
package.json
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"browser-ui-test": "0.19.0",
|
||||||
|
"eslint": "^8.57.1"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint src/theme/*js src/theme/**/*js",
|
||||||
|
"lint-fix": "eslint --fix src/theme/*js src/theme/**/*js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
|
/* global default_theme, hljs, ClipboardJS */
|
||||||
|
|
||||||
// Fix back button cache problem
|
// Fix back button cache problem
|
||||||
window.onunload = function () { };
|
window.onunload = function() { };
|
||||||
|
|
||||||
// Global variable, shared between modules
|
// Global variable, shared between modules
|
||||||
function playground_text(playground, hidden = true) {
|
function playground_text(playground, hidden = true) {
|
||||||
let code_block = playground.querySelector("code");
|
const code_block = playground.querySelector('code');
|
||||||
|
|
||||||
if (window.ace && code_block.classList.contains("editable")) {
|
if (window.ace && code_block.classList.contains('editable')) {
|
||||||
let editor = window.ace.edit(code_block);
|
const editor = window.ace.edit(code_block);
|
||||||
return editor.getValue();
|
return editor.getValue();
|
||||||
} else if (hidden) {
|
} else if (hidden) {
|
||||||
return code_block.textContent;
|
return code_block.textContent;
|
||||||
|
|
@ -21,25 +23,25 @@ function playground_text(playground, hidden = true) {
|
||||||
function fetch_with_timeout(url, options, timeout = 6000) {
|
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||||
return Promise.race([
|
return Promise.race([
|
||||||
fetch(url, options),
|
fetch(url, options),
|
||||||
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
|
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var playgrounds = Array.from(document.querySelectorAll(".playground"));
|
const playgrounds = Array.from(document.querySelectorAll('.playground'));
|
||||||
if (playgrounds.length > 0) {
|
if (playgrounds.length > 0) {
|
||||||
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
|
fetch_with_timeout('https://play.rust-lang.org/meta/crates', {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
// get list of crates available in the rust playground
|
// get list of crates available in the rust playground
|
||||||
let playground_crates = response.crates.map(item => item["id"]);
|
const playground_crates = response.crates.map(item => item['id']);
|
||||||
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_crate_list_update(playground_block, playground_crates) {
|
function handle_crate_list_update(playground_block, playground_crates) {
|
||||||
|
|
@ -48,20 +50,20 @@ function playground_text(playground, hidden = true) {
|
||||||
|
|
||||||
// and install on change listener to dynamically update ACE editors
|
// and install on change listener to dynamically update ACE editors
|
||||||
if (window.ace) {
|
if (window.ace) {
|
||||||
let code_block = playground_block.querySelector("code");
|
const code_block = playground_block.querySelector('code');
|
||||||
if (code_block.classList.contains("editable")) {
|
if (code_block.classList.contains('editable')) {
|
||||||
let editor = window.ace.edit(code_block);
|
const editor = window.ace.edit(code_block);
|
||||||
editor.addEventListener("change", function (e) {
|
editor.addEventListener('change', () => {
|
||||||
update_play_button(playground_block, playground_crates);
|
update_play_button(playground_block, playground_crates);
|
||||||
});
|
});
|
||||||
// add Ctrl-Enter command to execute rust code
|
// add Ctrl-Enter command to execute rust code
|
||||||
editor.commands.addCommand({
|
editor.commands.addCommand({
|
||||||
name: "run",
|
name: 'run',
|
||||||
bindKey: {
|
bindKey: {
|
||||||
win: "Ctrl-Enter",
|
win: 'Ctrl-Enter',
|
||||||
mac: "Ctrl-Enter"
|
mac: 'Ctrl-Enter',
|
||||||
},
|
},
|
||||||
exec: _editor => run_rust_code(playground_block)
|
exec: _editor => run_rust_code(playground_block),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,37 +72,38 @@ function playground_text(playground, hidden = true) {
|
||||||
// updates the visibility of play button based on `no_run` class and
|
// updates the visibility of play button based on `no_run` class and
|
||||||
// used crates vs ones available on https://play.rust-lang.org
|
// used crates vs ones available on https://play.rust-lang.org
|
||||||
function update_play_button(pre_block, playground_crates) {
|
function update_play_button(pre_block, playground_crates) {
|
||||||
var play_button = pre_block.querySelector(".play-button");
|
const play_button = pre_block.querySelector('.play-button');
|
||||||
|
|
||||||
// skip if code is `no_run`
|
// skip if code is `no_run`
|
||||||
if (pre_block.querySelector('code').classList.contains("no_run")) {
|
if (pre_block.querySelector('code').classList.contains('no_run')) {
|
||||||
play_button.classList.add("hidden");
|
play_button.classList.add('hidden');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get list of `extern crate`'s from snippet
|
// get list of `extern crate`'s from snippet
|
||||||
var txt = playground_text(pre_block);
|
const txt = playground_text(pre_block);
|
||||||
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
const re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
||||||
var snippet_crates = [];
|
const snippet_crates = [];
|
||||||
var item;
|
let item;
|
||||||
|
// eslint-disable-next-line no-cond-assign
|
||||||
while (item = re.exec(txt)) {
|
while (item = re.exec(txt)) {
|
||||||
snippet_crates.push(item[1]);
|
snippet_crates.push(item[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if all used crates are available on play.rust-lang.org
|
// check if all used crates are available on play.rust-lang.org
|
||||||
var all_available = snippet_crates.every(function (elem) {
|
const all_available = snippet_crates.every(function(elem) {
|
||||||
return playground_crates.indexOf(elem) > -1;
|
return playground_crates.indexOf(elem) > -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (all_available) {
|
if (all_available) {
|
||||||
play_button.classList.remove("hidden");
|
play_button.classList.remove('hidden');
|
||||||
} else {
|
} else {
|
||||||
play_button.classList.add("hidden");
|
play_button.classList.add('hidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_rust_code(code_block) {
|
function run_rust_code(code_block) {
|
||||||
var result_block = code_block.querySelector(".result");
|
let result_block = code_block.querySelector('.result');
|
||||||
if (!result_block) {
|
if (!result_block) {
|
||||||
result_block = document.createElement('code');
|
result_block = document.createElement('code');
|
||||||
result_block.className = 'result hljs language-bash';
|
result_block.className = 'result hljs language-bash';
|
||||||
|
|
@ -108,93 +111,110 @@ function playground_text(playground, hidden = true) {
|
||||||
code_block.append(result_block);
|
code_block.append(result_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = playground_text(code_block);
|
const text = playground_text(code_block);
|
||||||
let classes = code_block.querySelector('code').classList;
|
const classes = code_block.querySelector('code').classList;
|
||||||
let edition = "2015";
|
let edition = '2015';
|
||||||
classes.forEach(className => {
|
classes.forEach(className => {
|
||||||
if (className.startsWith("edition")) {
|
if (className.startsWith('edition')) {
|
||||||
edition = className.slice(7);
|
edition = className.slice(7);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var params = {
|
const params = {
|
||||||
version: "stable",
|
version: 'stable',
|
||||||
optimize: "0",
|
optimize: '0',
|
||||||
code: text,
|
code: text,
|
||||||
edition: edition
|
edition: edition,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (text.indexOf("#![feature") !== -1) {
|
if (text.indexOf('#![feature') !== -1) {
|
||||||
params.version = "nightly";
|
params.version = 'nightly';
|
||||||
}
|
}
|
||||||
|
|
||||||
result_block.innerText = "Running...";
|
result_block.innerText = 'Running...';
|
||||||
|
|
||||||
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
|
fetch_with_timeout('https://play.rust-lang.org/evaluate.json', {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
body: JSON.stringify(params)
|
body: JSON.stringify(params),
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.result.trim() === '') {
|
if (response.result.trim() === '') {
|
||||||
result_block.innerText = "No output";
|
result_block.innerText = 'No output';
|
||||||
result_block.classList.add("result-no-output");
|
result_block.classList.add('result-no-output');
|
||||||
} else {
|
} else {
|
||||||
result_block.innerText = response.result;
|
result_block.innerText = response.result;
|
||||||
result_block.classList.remove("result-no-output");
|
result_block.classList.remove('result-no-output');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
|
.catch(error => result_block.innerText = 'Playground Communication: ' + error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syntax highlighting Configuration
|
// Syntax highlighting Configuration
|
||||||
hljs.configure({
|
hljs.configure({
|
||||||
tabReplace: ' ', // 4 spaces
|
tabReplace: ' ', // 4 spaces
|
||||||
languages: [], // Languages used for auto-detection
|
languages: [], // Languages used for auto-detection
|
||||||
});
|
});
|
||||||
|
|
||||||
let code_nodes = Array
|
const code_nodes = Array
|
||||||
.from(document.querySelectorAll('code'))
|
.from(document.querySelectorAll('code'))
|
||||||
// Don't highlight `inline code` blocks in headers.
|
// Don't highlight `inline code` blocks in headers.
|
||||||
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
|
.filter(function(node) {
|
||||||
|
return !node.parentElement.classList.contains('header');
|
||||||
|
});
|
||||||
|
|
||||||
if (window.ace) {
|
if (window.ace) {
|
||||||
// language-rust class needs to be removed for editable
|
// language-rust class needs to be removed for editable
|
||||||
// blocks or highlightjs will capture events
|
// blocks or highlightjs will capture events
|
||||||
code_nodes
|
code_nodes
|
||||||
.filter(function (node) {return node.classList.contains("editable"); })
|
.filter(function(node) {
|
||||||
.forEach(function (block) { block.classList.remove('language-rust'); });
|
return node.classList.contains('editable');
|
||||||
|
})
|
||||||
|
.forEach(function(block) {
|
||||||
|
block.classList.remove('language-rust');
|
||||||
|
});
|
||||||
|
|
||||||
code_nodes
|
code_nodes
|
||||||
.filter(function (node) {return !node.classList.contains("editable"); })
|
.filter(function(node) {
|
||||||
.forEach(function (block) { hljs.highlightBlock(block); });
|
return !node.classList.contains('editable');
|
||||||
|
})
|
||||||
|
.forEach(function(block) {
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
|
code_nodes.forEach(function(block) {
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding the hljs class gives code blocks the color css
|
// Adding the hljs class gives code blocks the color css
|
||||||
// even if highlighting doesn't apply
|
// even if highlighting doesn't apply
|
||||||
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
|
code_nodes.forEach(function(block) {
|
||||||
|
block.classList.add('hljs');
|
||||||
|
});
|
||||||
|
|
||||||
Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) {
|
Array.from(document.querySelectorAll('code.hljs')).forEach(function(block) {
|
||||||
|
|
||||||
var lines = Array.from(block.querySelectorAll('.boring'));
|
const lines = Array.from(block.querySelectorAll('.boring'));
|
||||||
// If no lines were hidden, return
|
// If no lines were hidden, return
|
||||||
if (!lines.length) { return; }
|
if (!lines.length) {
|
||||||
block.classList.add("hide-boring");
|
return;
|
||||||
|
}
|
||||||
|
block.classList.add('hide-boring');
|
||||||
|
|
||||||
var buttons = document.createElement('div');
|
const buttons = document.createElement('div');
|
||||||
buttons.className = 'buttons';
|
buttons.className = 'buttons';
|
||||||
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
buttons.innerHTML = '<button class="fa fa-eye" title="Show hidden lines" \
|
||||||
|
aria-label="Show hidden lines"></button>';
|
||||||
|
|
||||||
// add expand button
|
// add expand button
|
||||||
var pre_block = block.parentNode;
|
const pre_block = block.parentNode;
|
||||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
|
||||||
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
|
pre_block.querySelector('.buttons').addEventListener('click', function(e) {
|
||||||
if (e.target.classList.contains('fa-eye')) {
|
if (e.target.classList.contains('fa-eye')) {
|
||||||
e.target.classList.remove('fa-eye');
|
e.target.classList.remove('fa-eye');
|
||||||
e.target.classList.add('fa-eye-slash');
|
e.target.classList.add('fa-eye-slash');
|
||||||
|
|
@ -214,21 +234,21 @@ function playground_text(playground, hidden = true) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (window.playground_copyable) {
|
if (window.playground_copyable) {
|
||||||
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
|
Array.from(document.querySelectorAll('pre code')).forEach(function(block) {
|
||||||
var pre_block = block.parentNode;
|
const pre_block = block.parentNode;
|
||||||
if (!pre_block.classList.contains('playground')) {
|
if (!pre_block.classList.contains('playground')) {
|
||||||
var buttons = pre_block.querySelector(".buttons");
|
let buttons = pre_block.querySelector('.buttons');
|
||||||
if (!buttons) {
|
if (!buttons) {
|
||||||
buttons = document.createElement('div');
|
buttons = document.createElement('div');
|
||||||
buttons.className = 'buttons';
|
buttons.className = 'buttons';
|
||||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
var clipButton = document.createElement('button');
|
const clipButton = document.createElement('button');
|
||||||
clipButton.className = 'clip-button';
|
clipButton.className = 'clip-button';
|
||||||
clipButton.title = 'Copy to clipboard';
|
clipButton.title = 'Copy to clipboard';
|
||||||
clipButton.setAttribute('aria-label', clipButton.title);
|
clipButton.setAttribute('aria-label', clipButton.title);
|
||||||
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
|
clipButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||||
|
|
||||||
buttons.insertBefore(clipButton, buttons.firstChild);
|
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||||
}
|
}
|
||||||
|
|
@ -236,28 +256,28 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process playground code blocks
|
// Process playground code blocks
|
||||||
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
|
Array.from(document.querySelectorAll('.playground')).forEach(function(pre_block) {
|
||||||
// Add play button
|
// Add play button
|
||||||
var buttons = pre_block.querySelector(".buttons");
|
let buttons = pre_block.querySelector('.buttons');
|
||||||
if (!buttons) {
|
if (!buttons) {
|
||||||
buttons = document.createElement('div');
|
buttons = document.createElement('div');
|
||||||
buttons.className = 'buttons';
|
buttons.className = 'buttons';
|
||||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
var runCodeButton = document.createElement('button');
|
const runCodeButton = document.createElement('button');
|
||||||
runCodeButton.className = 'fa fa-play play-button';
|
runCodeButton.className = 'fa fa-play play-button';
|
||||||
runCodeButton.hidden = true;
|
runCodeButton.hidden = true;
|
||||||
runCodeButton.title = 'Run this code';
|
runCodeButton.title = 'Run this code';
|
||||||
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||||
|
|
||||||
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||||
runCodeButton.addEventListener('click', function (e) {
|
runCodeButton.addEventListener('click', () => {
|
||||||
run_rust_code(pre_block);
|
run_rust_code(pre_block);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (window.playground_copyable) {
|
if (window.playground_copyable) {
|
||||||
var copyCodeClipboardButton = document.createElement('button');
|
const copyCodeClipboardButton = document.createElement('button');
|
||||||
copyCodeClipboardButton.className = 'clip-button';
|
copyCodeClipboardButton.className = 'clip-button';
|
||||||
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||||
copyCodeClipboardButton.title = 'Copy to clipboard';
|
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||||
|
|
@ -266,17 +286,17 @@ function playground_text(playground, hidden = true) {
|
||||||
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
let code_block = pre_block.querySelector("code");
|
const code_block = pre_block.querySelector('code');
|
||||||
if (window.ace && code_block.classList.contains("editable")) {
|
if (window.ace && code_block.classList.contains('editable')) {
|
||||||
var undoChangesButton = document.createElement('button');
|
const undoChangesButton = document.createElement('button');
|
||||||
undoChangesButton.className = 'fa fa-history reset-button';
|
undoChangesButton.className = 'fa fa-history reset-button';
|
||||||
undoChangesButton.title = 'Undo changes';
|
undoChangesButton.title = 'Undo changes';
|
||||||
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||||
|
|
||||||
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||||
|
|
||||||
undoChangesButton.addEventListener('click', function () {
|
undoChangesButton.addEventListener('click', function() {
|
||||||
let editor = window.ace.edit(code_block);
|
const editor = window.ace.edit(code_block);
|
||||||
editor.setValue(editor.originalCode);
|
editor.setValue(editor.originalCode);
|
||||||
editor.clearSelection();
|
editor.clearSelection();
|
||||||
});
|
});
|
||||||
|
|
@ -285,31 +305,31 @@ function playground_text(playground, hidden = true) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function themes() {
|
(function themes() {
|
||||||
var html = document.querySelector('html');
|
const html = document.querySelector('html');
|
||||||
var themeToggleButton = document.getElementById('theme-toggle');
|
const themeToggleButton = document.getElementById('theme-toggle');
|
||||||
var themePopup = document.getElementById('theme-list');
|
const themePopup = document.getElementById('theme-list');
|
||||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
const themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||||
var themeIds = [];
|
const themeIds = [];
|
||||||
themePopup.querySelectorAll('button.theme').forEach(function (el) {
|
themePopup.querySelectorAll('button.theme').forEach(function(el) {
|
||||||
themeIds.push(el.id);
|
themeIds.push(el.id);
|
||||||
});
|
});
|
||||||
var stylesheets = {
|
const stylesheets = {
|
||||||
ayuHighlight: document.querySelector("#ayu-highlight-css"),
|
ayuHighlight: document.querySelector('#ayu-highlight-css'),
|
||||||
tomorrowNight: document.querySelector("#tomorrow-night-css"),
|
tomorrowNight: document.querySelector('#tomorrow-night-css'),
|
||||||
highlight: document.querySelector("#highlight-css"),
|
highlight: document.querySelector('#highlight-css'),
|
||||||
};
|
};
|
||||||
|
|
||||||
function showThemes() {
|
function showThemes() {
|
||||||
themePopup.style.display = 'block';
|
themePopup.style.display = 'block';
|
||||||
themeToggleButton.setAttribute('aria-expanded', true);
|
themeToggleButton.setAttribute('aria-expanded', true);
|
||||||
themePopup.querySelector("button#" + get_theme()).focus();
|
themePopup.querySelector('button#' + get_theme()).focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateThemeSelected() {
|
function updateThemeSelected() {
|
||||||
themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
|
themePopup.querySelectorAll('.theme-selected').forEach(function(el) {
|
||||||
el.classList.remove('theme-selected');
|
el.classList.remove('theme-selected');
|
||||||
});
|
});
|
||||||
themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
|
themePopup.querySelector('button#' + get_theme()).classList.add('theme-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideThemes() {
|
function hideThemes() {
|
||||||
|
|
@ -319,8 +339,12 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_theme() {
|
function get_theme() {
|
||||||
var theme;
|
let theme;
|
||||||
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
try {
|
||||||
|
theme = localStorage.getItem('mdbook-theme');
|
||||||
|
} catch (e) {
|
||||||
|
// ignore error.
|
||||||
|
}
|
||||||
if (theme === null || theme === undefined || !themeIds.includes(theme)) {
|
if (theme === null || theme === undefined || !themeIds.includes(theme)) {
|
||||||
return default_theme;
|
return default_theme;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -331,38 +355,42 @@ function playground_text(playground, hidden = true) {
|
||||||
function set_theme(theme, store = true) {
|
function set_theme(theme, store = true) {
|
||||||
let ace_theme;
|
let ace_theme;
|
||||||
|
|
||||||
if (theme == 'coal' || theme == 'navy') {
|
if (theme === 'coal' || theme === 'navy') {
|
||||||
stylesheets.ayuHighlight.disabled = true;
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
stylesheets.tomorrowNight.disabled = false;
|
stylesheets.tomorrowNight.disabled = false;
|
||||||
stylesheets.highlight.disabled = true;
|
stylesheets.highlight.disabled = true;
|
||||||
|
|
||||||
ace_theme = "ace/theme/tomorrow_night";
|
ace_theme = 'ace/theme/tomorrow_night';
|
||||||
} else if (theme == 'ayu') {
|
} else if (theme === 'ayu') {
|
||||||
stylesheets.ayuHighlight.disabled = false;
|
stylesheets.ayuHighlight.disabled = false;
|
||||||
stylesheets.tomorrowNight.disabled = true;
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
stylesheets.highlight.disabled = true;
|
stylesheets.highlight.disabled = true;
|
||||||
ace_theme = "ace/theme/tomorrow_night";
|
ace_theme = 'ace/theme/tomorrow_night';
|
||||||
} else {
|
} else {
|
||||||
stylesheets.ayuHighlight.disabled = true;
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
stylesheets.tomorrowNight.disabled = true;
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
stylesheets.highlight.disabled = false;
|
stylesheets.highlight.disabled = false;
|
||||||
ace_theme = "ace/theme/dawn";
|
ace_theme = 'ace/theme/dawn';
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function() {
|
||||||
themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
|
themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
if (window.ace && window.editors) {
|
if (window.ace && window.editors) {
|
||||||
window.editors.forEach(function (editor) {
|
window.editors.forEach(function(editor) {
|
||||||
editor.setTheme(ace_theme);
|
editor.setTheme(ace_theme);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var previousTheme = get_theme();
|
const previousTheme = get_theme();
|
||||||
|
|
||||||
if (store) {
|
if (store) {
|
||||||
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
|
try {
|
||||||
|
localStorage.setItem('mdbook-theme', theme);
|
||||||
|
} catch (e) {
|
||||||
|
// ignore error.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.classList.remove(previousTheme);
|
html.classList.remove(previousTheme);
|
||||||
|
|
@ -371,11 +399,11 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set theme
|
// Set theme
|
||||||
var theme = get_theme();
|
const theme = get_theme();
|
||||||
|
|
||||||
set_theme(theme, false);
|
set_theme(theme, false);
|
||||||
|
|
||||||
themeToggleButton.addEventListener('click', function () {
|
themeToggleButton.addEventListener('click', function() {
|
||||||
if (themePopup.style.display === 'block') {
|
if (themePopup.style.display === 'block') {
|
||||||
hideThemes();
|
hideThemes();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -383,11 +411,11 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
themePopup.addEventListener('click', function (e) {
|
themePopup.addEventListener('click', function(e) {
|
||||||
var theme;
|
let theme;
|
||||||
if (e.target.className === "theme") {
|
if (e.target.className === 'theme') {
|
||||||
theme = e.target.id;
|
theme = e.target.id;
|
||||||
} else if (e.target.parentElement.className === "theme") {
|
} else if (e.target.parentElement.className === 'theme') {
|
||||||
theme = e.target.parentElement.id;
|
theme = e.target.parentElement.id;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
|
@ -397,88 +425,108 @@ function playground_text(playground, hidden = true) {
|
||||||
|
|
||||||
themePopup.addEventListener('focusout', function(e) {
|
themePopup.addEventListener('focusout', function(e) {
|
||||||
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||||
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
|
if (!!e.relatedTarget &&
|
||||||
|
!themeToggleButton.contains(e.relatedTarget) &&
|
||||||
|
!themePopup.contains(e.relatedTarget)
|
||||||
|
) {
|
||||||
hideThemes();
|
hideThemes();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
// Should not be needed, but it works around an issue on macOS & iOS:
|
||||||
|
// https://github.com/rust-lang/mdBook/issues/628
|
||||||
document.addEventListener('click', function(e) {
|
document.addEventListener('click', function(e) {
|
||||||
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
|
if (themePopup.style.display === 'block' &&
|
||||||
|
!themeToggleButton.contains(e.target) &&
|
||||||
|
!themePopup.contains(e.target)
|
||||||
|
) {
|
||||||
hideThemes();
|
hideThemes();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('keydown', function (e) {
|
document.addEventListener('keydown', function(e) {
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||||
if (!themePopup.contains(e.target)) { return; }
|
return;
|
||||||
|
}
|
||||||
|
if (!themePopup.contains(e.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let li;
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
hideThemes();
|
hideThemes();
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var li = document.activeElement.parentElement;
|
li = document.activeElement.parentElement;
|
||||||
if (li && li.previousElementSibling) {
|
if (li && li.previousElementSibling) {
|
||||||
li.previousElementSibling.querySelector('button').focus();
|
li.previousElementSibling.querySelector('button').focus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var li = document.activeElement.parentElement;
|
li = document.activeElement.parentElement;
|
||||||
if (li && li.nextElementSibling) {
|
if (li && li.nextElementSibling) {
|
||||||
li.nextElementSibling.querySelector('button').focus();
|
li.nextElementSibling.querySelector('button').focus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Home':
|
case 'Home':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
themePopup.querySelector('li:first-child button').focus();
|
themePopup.querySelector('li:first-child button').focus();
|
||||||
break;
|
break;
|
||||||
case 'End':
|
case 'End':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
themePopup.querySelector('li:last-child button').focus();
|
themePopup.querySelector('li:last-child button').focus();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function sidebar() {
|
(function sidebar() {
|
||||||
var body = document.querySelector("body");
|
const body = document.querySelector('body');
|
||||||
var sidebar = document.getElementById("sidebar");
|
const sidebar = document.getElementById('sidebar');
|
||||||
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
const sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||||
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
const sidebarToggleButton = document.getElementById('sidebar-toggle');
|
||||||
var sidebarToggleAnchor = document.getElementById("sidebar-toggle-anchor");
|
const sidebarToggleAnchor = document.getElementById('sidebar-toggle-anchor');
|
||||||
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
|
const sidebarResizeHandle = document.getElementById('sidebar-resize-handle');
|
||||||
var firstContact = null;
|
let firstContact = null;
|
||||||
|
|
||||||
function showSidebar() {
|
function showSidebar() {
|
||||||
body.classList.remove('sidebar-hidden')
|
body.classList.remove('sidebar-hidden');
|
||||||
body.classList.add('sidebar-visible');
|
body.classList.add('sidebar-visible');
|
||||||
Array.from(sidebarLinks).forEach(function (link) {
|
Array.from(sidebarLinks).forEach(function(link) {
|
||||||
link.setAttribute('tabIndex', 0);
|
link.setAttribute('tabIndex', 0);
|
||||||
});
|
});
|
||||||
sidebarToggleButton.setAttribute('aria-expanded', true);
|
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||||||
sidebar.setAttribute('aria-hidden', false);
|
sidebar.setAttribute('aria-hidden', false);
|
||||||
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
|
try {
|
||||||
|
localStorage.setItem('mdbook-sidebar', 'visible');
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideSidebar() {
|
function hideSidebar() {
|
||||||
body.classList.remove('sidebar-visible')
|
body.classList.remove('sidebar-visible');
|
||||||
body.classList.add('sidebar-hidden');
|
body.classList.add('sidebar-hidden');
|
||||||
Array.from(sidebarLinks).forEach(function (link) {
|
Array.from(sidebarLinks).forEach(function(link) {
|
||||||
link.setAttribute('tabIndex', -1);
|
link.setAttribute('tabIndex', -1);
|
||||||
});
|
});
|
||||||
sidebarToggleButton.setAttribute('aria-expanded', false);
|
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||||||
sidebar.setAttribute('aria-hidden', true);
|
sidebar.setAttribute('aria-hidden', true);
|
||||||
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
|
try {
|
||||||
|
localStorage.setItem('mdbook-sidebar', 'hidden');
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle sidebar
|
// Toggle sidebar
|
||||||
sidebarToggleAnchor.addEventListener('change', function sidebarToggle() {
|
sidebarToggleAnchor.addEventListener('change', function sidebarToggle() {
|
||||||
if (sidebarToggleAnchor.checked) {
|
if (sidebarToggleAnchor.checked) {
|
||||||
var current_width = parseInt(
|
const current_width = parseInt(
|
||||||
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||||
if (current_width < 150) {
|
if (current_width < 150) {
|
||||||
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||||
|
|
@ -491,17 +539,17 @@ function playground_text(playground, hidden = true) {
|
||||||
|
|
||||||
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||||||
|
|
||||||
function initResize(e) {
|
function initResize() {
|
||||||
window.addEventListener('mousemove', resize, false);
|
window.addEventListener('mousemove', resize, false);
|
||||||
window.addEventListener('mouseup', stopResize, false);
|
window.addEventListener('mouseup', stopResize, false);
|
||||||
body.classList.add('sidebar-resizing');
|
body.classList.add('sidebar-resizing');
|
||||||
}
|
}
|
||||||
function resize(e) {
|
function resize(e) {
|
||||||
var pos = (e.clientX - sidebar.offsetLeft);
|
let pos = e.clientX - sidebar.offsetLeft;
|
||||||
if (pos < 20) {
|
if (pos < 20) {
|
||||||
hideSidebar();
|
hideSidebar();
|
||||||
} else {
|
} else {
|
||||||
if (body.classList.contains("sidebar-hidden")) {
|
if (body.classList.contains('sidebar-hidden')) {
|
||||||
showSidebar();
|
showSidebar();
|
||||||
}
|
}
|
||||||
pos = Math.min(pos, window.innerWidth - 100);
|
pos = Math.min(pos, window.innerWidth - 100);
|
||||||
|
|
@ -509,32 +557,34 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//on mouseup remove windows functions mousemove & mouseup
|
//on mouseup remove windows functions mousemove & mouseup
|
||||||
function stopResize(e) {
|
function stopResize() {
|
||||||
body.classList.remove('sidebar-resizing');
|
body.classList.remove('sidebar-resizing');
|
||||||
window.removeEventListener('mousemove', resize, false);
|
window.removeEventListener('mousemove', resize, false);
|
||||||
window.removeEventListener('mouseup', stopResize, false);
|
window.removeEventListener('mouseup', stopResize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('touchstart', function (e) {
|
document.addEventListener('touchstart', function(e) {
|
||||||
firstContact = {
|
firstContact = {
|
||||||
x: e.touches[0].clientX,
|
x: e.touches[0].clientX,
|
||||||
time: Date.now()
|
time: Date.now(),
|
||||||
};
|
};
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
|
|
||||||
document.addEventListener('touchmove', function (e) {
|
document.addEventListener('touchmove', function(e) {
|
||||||
if (!firstContact)
|
if (!firstContact) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var curX = e.touches[0].clientX;
|
const curX = e.touches[0].clientX;
|
||||||
var xDiff = curX - firstContact.x,
|
const xDiff = curX - firstContact.x,
|
||||||
tDiff = Date.now() - firstContact.time;
|
tDiff = Date.now() - firstContact.time;
|
||||||
|
|
||||||
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||||||
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
|
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) {
|
||||||
showSidebar();
|
showSidebar();
|
||||||
else if (xDiff < 0 && curX < 300)
|
} else if (xDiff < 0 && curX < 300) {
|
||||||
hideSidebar();
|
hideSidebar();
|
||||||
|
}
|
||||||
|
|
||||||
firstContact = null;
|
firstContact = null;
|
||||||
}
|
}
|
||||||
|
|
@ -542,49 +592,53 @@ function playground_text(playground, hidden = true) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function chapterNavigation() {
|
(function chapterNavigation() {
|
||||||
document.addEventListener('keydown', function (e) {
|
document.addEventListener('keydown', function(e) {
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||||
if (window.search && window.search.hasFocus()) { return; }
|
return;
|
||||||
var html = document.querySelector('html');
|
}
|
||||||
|
if (window.search && window.search.hasFocus()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
var nextButton = document.querySelector('.nav-chapters.next');
|
const nextButton = document.querySelector('.nav-chapters.next');
|
||||||
if (nextButton) {
|
if (nextButton) {
|
||||||
window.location.href = nextButton.href;
|
window.location.href = nextButton.href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function prev() {
|
function prev() {
|
||||||
var previousButton = document.querySelector('.nav-chapters.previous');
|
const previousButton = document.querySelector('.nav-chapters.previous');
|
||||||
if (previousButton) {
|
if (previousButton) {
|
||||||
window.location.href = previousButton.href;
|
window.location.href = previousButton.href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (html.dir == 'rtl') {
|
if (html.dir === 'rtl') {
|
||||||
prev();
|
prev();
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (html.dir == 'rtl') {
|
if (html.dir === 'rtl') {
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
prev();
|
prev();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function clipboard() {
|
(function clipboard() {
|
||||||
var clipButtons = document.querySelectorAll('.clip-button');
|
const clipButtons = document.querySelectorAll('.clip-button');
|
||||||
|
|
||||||
function hideTooltip(elem) {
|
function hideTooltip(elem) {
|
||||||
elem.firstChild.innerText = "";
|
elem.firstChild.innerText = '';
|
||||||
elem.className = 'clip-button';
|
elem.className = 'clip-button';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -593,58 +647,58 @@ function playground_text(playground, hidden = true) {
|
||||||
elem.className = 'clip-button tooltipped';
|
elem.className = 'clip-button tooltipped';
|
||||||
}
|
}
|
||||||
|
|
||||||
var clipboardSnippets = new ClipboardJS('.clip-button', {
|
const clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||||
text: function (trigger) {
|
text: function(trigger) {
|
||||||
hideTooltip(trigger);
|
hideTooltip(trigger);
|
||||||
let playground = trigger.closest("pre");
|
const playground = trigger.closest('pre');
|
||||||
return playground_text(playground, false);
|
return playground_text(playground, false);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Array.from(clipButtons).forEach(function (clipButton) {
|
Array.from(clipButtons).forEach(function(clipButton) {
|
||||||
clipButton.addEventListener('mouseout', function (e) {
|
clipButton.addEventListener('mouseout', function(e) {
|
||||||
hideTooltip(e.currentTarget);
|
hideTooltip(e.currentTarget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
clipboardSnippets.on('success', function (e) {
|
clipboardSnippets.on('success', function(e) {
|
||||||
e.clearSelection();
|
e.clearSelection();
|
||||||
showTooltip(e.trigger, "Copied!");
|
showTooltip(e.trigger, 'Copied!');
|
||||||
});
|
});
|
||||||
|
|
||||||
clipboardSnippets.on('error', function (e) {
|
clipboardSnippets.on('error', function(e) {
|
||||||
showTooltip(e.trigger, "Clipboard error!");
|
showTooltip(e.trigger, 'Clipboard error!');
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function scrollToTop () {
|
(function scrollToTop() {
|
||||||
var menuTitle = document.querySelector('.menu-title');
|
const menuTitle = document.querySelector('.menu-title');
|
||||||
|
|
||||||
menuTitle.addEventListener('click', function () {
|
menuTitle.addEventListener('click', function() {
|
||||||
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function controllMenu() {
|
(function controllMenu() {
|
||||||
var menu = document.getElementById('menu-bar');
|
const menu = document.getElementById('menu-bar');
|
||||||
|
|
||||||
(function controllPosition() {
|
(function controllPosition() {
|
||||||
var scrollTop = document.scrollingElement.scrollTop;
|
let scrollTop = document.scrollingElement.scrollTop;
|
||||||
var prevScrollTop = scrollTop;
|
let prevScrollTop = scrollTop;
|
||||||
var minMenuY = -menu.clientHeight - 50;
|
const minMenuY = -menu.clientHeight - 50;
|
||||||
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
||||||
menu.style.top = scrollTop + 'px';
|
menu.style.top = scrollTop + 'px';
|
||||||
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
||||||
var topCache = menu.style.top.slice(0, -2);
|
let topCache = menu.style.top.slice(0, -2);
|
||||||
menu.classList.remove('sticky');
|
menu.classList.remove('sticky');
|
||||||
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
let stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
||||||
document.addEventListener('scroll', function () {
|
document.addEventListener('scroll', function() {
|
||||||
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
||||||
// `null` means that it doesn't need to be updated
|
// `null` means that it doesn't need to be updated
|
||||||
var nextSticky = null;
|
let nextSticky = null;
|
||||||
var nextTop = null;
|
let nextTop = null;
|
||||||
var scrollDown = scrollTop > prevScrollTop;
|
const scrollDown = scrollTop > prevScrollTop;
|
||||||
var menuPosAbsoluteY = topCache - scrollTop;
|
const menuPosAbsoluteY = topCache - scrollTop;
|
||||||
if (scrollDown) {
|
if (scrollDown) {
|
||||||
nextSticky = false;
|
nextSticky = false;
|
||||||
if (menuPosAbsoluteY > 0) {
|
if (menuPosAbsoluteY > 0) {
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@
|
||||||
|
|
||||||
<!-- Provide site root to javascript -->
|
<!-- Provide site root to javascript -->
|
||||||
<script>
|
<script>
|
||||||
var path_to_root = "{{ path_to_root }}";
|
const path_to_root = "{{ path_to_root }}";
|
||||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
|
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
|
||||||
</script>
|
</script>
|
||||||
<!-- Start loading toc.js asap -->
|
<!-- Start loading toc.js asap -->
|
||||||
<script src="{{ resource "toc.js" }}"></script>
|
<script src="{{ resource "toc.js" }}"></script>
|
||||||
|
|
@ -66,8 +66,8 @@
|
||||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||||
<script>
|
<script>
|
||||||
try {
|
try {
|
||||||
var theme = localStorage.getItem('mdbook-theme');
|
let theme = localStorage.getItem('mdbook-theme');
|
||||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
let sidebar = localStorage.getItem('mdbook-sidebar');
|
||||||
|
|
||||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||||
<script>
|
<script>
|
||||||
var theme;
|
let theme;
|
||||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
|
|
@ -94,8 +94,8 @@
|
||||||
|
|
||||||
<!-- Hide / unhide sidebar before it is displayed -->
|
<!-- Hide / unhide sidebar before it is displayed -->
|
||||||
<script>
|
<script>
|
||||||
var sidebar = null;
|
let sidebar = null;
|
||||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||||
if (document.body.clientWidth >= 1080) {
|
if (document.body.clientWidth >= 1080) {
|
||||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||||
sidebar = sidebar || 'visible';
|
sidebar = sidebar || 'visible';
|
||||||
|
|
@ -251,7 +251,7 @@
|
||||||
{{#if google_analytics}}
|
{{#if google_analytics}}
|
||||||
<!-- Google Analytics Tag -->
|
<!-- Google Analytics Tag -->
|
||||||
<script>
|
<script>
|
||||||
var localAddrs = ["localhost", "127.0.0.1", ""];
|
const localAddrs = ["localhost", "127.0.0.1", ""];
|
||||||
|
|
||||||
// make sure we don't activate google analytics if the developer is
|
// make sure we don't activate google analytics if the developer is
|
||||||
// inspecting the book locally...
|
// inspecting the book locally...
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
|
/* global Mark, elasticlunr, path_to_root */
|
||||||
|
|
||||||
window.search = window.search || {};
|
window.search = window.search || {};
|
||||||
(function search(search) {
|
(function search(search) {
|
||||||
// Search functionality
|
// Search functionality
|
||||||
|
|
@ -10,43 +13,26 @@ window.search = window.search || {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
// eslint-disable-next-line max-len
|
||||||
|
// IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
||||||
if (!String.prototype.startsWith) {
|
if (!String.prototype.startsWith) {
|
||||||
String.prototype.startsWith = function(search, pos) {
|
String.prototype.startsWith = function(search, pos) {
|
||||||
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
|
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var search_wrap = document.getElementById('search-wrapper'),
|
const search_wrap = document.getElementById('search-wrapper'),
|
||||||
searchbar = document.getElementById('searchbar'),
|
searchbar = document.getElementById('searchbar'),
|
||||||
searchbar_outer = document.getElementById('searchbar-outer'),
|
|
||||||
searchresults = document.getElementById('searchresults'),
|
searchresults = document.getElementById('searchresults'),
|
||||||
searchresults_outer = document.getElementById('searchresults-outer'),
|
searchresults_outer = document.getElementById('searchresults-outer'),
|
||||||
searchresults_header = document.getElementById('searchresults-header'),
|
searchresults_header = document.getElementById('searchresults-header'),
|
||||||
searchicon = document.getElementById('search-toggle'),
|
searchicon = document.getElementById('search-toggle'),
|
||||||
content = document.getElementById('content'),
|
content = document.getElementById('content'),
|
||||||
|
|
||||||
searchindex = null,
|
|
||||||
doc_urls = [],
|
|
||||||
results_options = {
|
|
||||||
teaser_word_count: 30,
|
|
||||||
limit_results: 30,
|
|
||||||
},
|
|
||||||
search_options = {
|
|
||||||
bool: "AND",
|
|
||||||
expand: true,
|
|
||||||
fields: {
|
|
||||||
title: {boost: 1},
|
|
||||||
body: {boost: 1},
|
|
||||||
breadcrumbs: {boost: 0}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mark_exclude = [],
|
mark_exclude = [],
|
||||||
marker = new Mark(content),
|
marker = new Mark(content),
|
||||||
current_searchterm = "",
|
|
||||||
URL_SEARCH_PARAM = 'search',
|
URL_SEARCH_PARAM = 'search',
|
||||||
URL_MARK_PARAM = 'highlight',
|
URL_MARK_PARAM = 'highlight',
|
||||||
teaser_count = 0,
|
|
||||||
|
|
||||||
SEARCH_HOTKEY_KEYCODE = 83,
|
SEARCH_HOTKEY_KEYCODE = 83,
|
||||||
ESCAPE_KEYCODE = 27,
|
ESCAPE_KEYCODE = 27,
|
||||||
|
|
@ -54,6 +40,24 @@ window.search = window.search || {};
|
||||||
UP_KEYCODE = 38,
|
UP_KEYCODE = 38,
|
||||||
SELECT_KEYCODE = 13;
|
SELECT_KEYCODE = 13;
|
||||||
|
|
||||||
|
let current_searchterm = '',
|
||||||
|
doc_urls = [],
|
||||||
|
search_options = {
|
||||||
|
bool: 'AND',
|
||||||
|
expand: true,
|
||||||
|
fields: {
|
||||||
|
title: {boost: 1},
|
||||||
|
body: {boost: 1},
|
||||||
|
breadcrumbs: {boost: 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchindex = null,
|
||||||
|
results_options = {
|
||||||
|
teaser_word_count: 30,
|
||||||
|
limit_results: 30,
|
||||||
|
},
|
||||||
|
teaser_count = 0;
|
||||||
|
|
||||||
function hasFocus() {
|
function hasFocus() {
|
||||||
return searchbar === document.activeElement;
|
return searchbar === document.activeElement;
|
||||||
}
|
}
|
||||||
|
|
@ -66,96 +70,99 @@ window.search = window.search || {};
|
||||||
|
|
||||||
// Helper to parse a url into its building blocks.
|
// Helper to parse a url into its building blocks.
|
||||||
function parseURL(url) {
|
function parseURL(url) {
|
||||||
var a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
return {
|
return {
|
||||||
source: url,
|
source: url,
|
||||||
protocol: a.protocol.replace(':',''),
|
protocol: a.protocol.replace(':', ''),
|
||||||
host: a.hostname,
|
host: a.hostname,
|
||||||
port: a.port,
|
port: a.port,
|
||||||
params: (function(){
|
params: (function() {
|
||||||
var ret = {};
|
const ret = {};
|
||||||
var seg = a.search.replace(/^\?/,'').split('&');
|
const seg = a.search.replace(/^\?/, '').split('&');
|
||||||
var len = seg.length, i = 0, s;
|
for (const part of seg) {
|
||||||
for (;i<len;i++) {
|
if (!part) {
|
||||||
if (!seg[i]) { continue; }
|
continue;
|
||||||
s = seg[i].split('=');
|
}
|
||||||
|
const s = part.split('=');
|
||||||
ret[s[0]] = s[1];
|
ret[s[0]] = s[1];
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
})(),
|
})(),
|
||||||
file: (a.pathname.match(/\/([^/?#]+)$/i) || [,''])[1],
|
file: (a.pathname.match(/\/([^/?#]+)$/i) || ['', ''])[1],
|
||||||
hash: a.hash.replace('#',''),
|
hash: a.hash.replace('#', ''),
|
||||||
path: a.pathname.replace(/^([^/])/,'/$1')
|
path: a.pathname.replace(/^([^/])/, '/$1'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to recreate a url string from its building blocks.
|
// Helper to recreate a url string from its building blocks.
|
||||||
function renderURL(urlobject) {
|
function renderURL(urlobject) {
|
||||||
var url = urlobject.protocol + "://" + urlobject.host;
|
let url = urlobject.protocol + '://' + urlobject.host;
|
||||||
if (urlobject.port != "") {
|
if (urlobject.port !== '') {
|
||||||
url += ":" + urlobject.port;
|
url += ':' + urlobject.port;
|
||||||
}
|
}
|
||||||
url += urlobject.path;
|
url += urlobject.path;
|
||||||
var joiner = "?";
|
let joiner = '?';
|
||||||
for(var prop in urlobject.params) {
|
for (const prop in urlobject.params) {
|
||||||
if(urlobject.params.hasOwnProperty(prop)) {
|
if (Object.prototype.hasOwnProperty.call(urlobject.params, prop)) {
|
||||||
url += joiner + prop + "=" + urlobject.params[prop];
|
url += joiner + prop + '=' + urlobject.params[prop];
|
||||||
joiner = "&";
|
joiner = '&';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (urlobject.hash != "") {
|
if (urlobject.hash !== '') {
|
||||||
url += "#" + urlobject.hash;
|
url += '#' + urlobject.hash;
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to escape html special chars for displaying the teasers
|
// Helper to escape html special chars for displaying the teasers
|
||||||
var escapeHTML = (function() {
|
const escapeHTML = (function() {
|
||||||
var MAP = {
|
const MAP = {
|
||||||
'&': '&',
|
'&': '&',
|
||||||
'<': '<',
|
'<': '<',
|
||||||
'>': '>',
|
'>': '>',
|
||||||
'"': '"',
|
'"': '"',
|
||||||
"'": '''
|
'\'': ''',
|
||||||
|
};
|
||||||
|
const repl = function(c) {
|
||||||
|
return MAP[c];
|
||||||
};
|
};
|
||||||
var repl = function(c) { return MAP[c]; };
|
|
||||||
return function(s) {
|
return function(s) {
|
||||||
return s.replace(/[&<>'"]/g, repl);
|
return s.replace(/[&<>'"]/g, repl);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function formatSearchMetric(count, searchterm) {
|
function formatSearchMetric(count, searchterm) {
|
||||||
if (count == 1) {
|
if (count === 1) {
|
||||||
return count + " search result for '" + searchterm + "':";
|
return count + ' search result for \'' + searchterm + '\':';
|
||||||
} else if (count == 0) {
|
} else if (count === 0) {
|
||||||
return "No search results for '" + searchterm + "'.";
|
return 'No search results for \'' + searchterm + '\'.';
|
||||||
} else {
|
} else {
|
||||||
return count + " search results for '" + searchterm + "':";
|
return count + ' search results for \'' + searchterm + '\':';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSearchResult(result, searchterms) {
|
function formatSearchResult(result, searchterms) {
|
||||||
var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms);
|
const teaser = makeTeaser(escapeHTML(result.doc.body), searchterms);
|
||||||
teaser_count++;
|
teaser_count++;
|
||||||
|
|
||||||
// The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor
|
// The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor
|
||||||
var url = doc_urls[result.ref].split("#");
|
const url = doc_urls[result.ref].split('#');
|
||||||
if (url.length == 1) { // no anchor found
|
if (url.length === 1) { // no anchor found
|
||||||
url.push("");
|
url.push('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeURIComponent escapes all chars that could allow an XSS except
|
// encodeURIComponent escapes all chars that could allow an XSS except
|
||||||
// for '. Due to that we also manually replace ' with its url-encoded
|
// for '. Due to that we also manually replace ' with its url-encoded
|
||||||
// representation (%27).
|
// representation (%27).
|
||||||
var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27");
|
const encoded_search = encodeURIComponent(searchterms.join(' ')).replace(/'/g, '%27');
|
||||||
|
|
||||||
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
|
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + encoded_search
|
||||||
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
|
+ '#' + url[1] + '" aria-details="teaser_' + teaser_count + '">'
|
||||||
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
|
+ result.doc.breadcrumbs + '</a>' + '<span class="teaser" id="teaser_' + teaser_count
|
||||||
+ teaser + '</span>';
|
+ '" aria-label="Search Result Teaser">' + teaser + '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTeaser(body, searchterms) {
|
function makeTeaser(body, searchterms) {
|
||||||
// The strategy is as follows:
|
// The strategy is as follows:
|
||||||
// First, assign a value to each word in the document:
|
// First, assign a value to each word in the document:
|
||||||
|
|
@ -166,88 +173,90 @@ window.search = window.search || {};
|
||||||
// sum of the values of the words within the window. Then use the window that got the
|
// sum of the values of the words within the window. Then use the window that got the
|
||||||
// maximum sum. If there are multiple maximas, then get the last one.
|
// maximum sum. If there are multiple maximas, then get the last one.
|
||||||
// Enclose the terms in <em>.
|
// Enclose the terms in <em>.
|
||||||
var stemmed_searchterms = searchterms.map(function(w) {
|
const stemmed_searchterms = searchterms.map(function(w) {
|
||||||
return elasticlunr.stemmer(w.toLowerCase());
|
return elasticlunr.stemmer(w.toLowerCase());
|
||||||
});
|
});
|
||||||
var searchterm_weight = 40;
|
const searchterm_weight = 40;
|
||||||
var weighted = []; // contains elements of ["word", weight, index_in_document]
|
const weighted = []; // contains elements of ["word", weight, index_in_document]
|
||||||
// split in sentences, then words
|
// split in sentences, then words
|
||||||
var sentences = body.toLowerCase().split('. ');
|
const sentences = body.toLowerCase().split('. ');
|
||||||
var index = 0;
|
let index = 0;
|
||||||
var value = 0;
|
let value = 0;
|
||||||
var searchterm_found = false;
|
let searchterm_found = false;
|
||||||
for (var sentenceindex in sentences) {
|
for (const sentenceindex in sentences) {
|
||||||
var words = sentences[sentenceindex].split(' ');
|
const words = sentences[sentenceindex].split(' ');
|
||||||
value = 8;
|
value = 8;
|
||||||
for (var wordindex in words) {
|
for (const wordindex in words) {
|
||||||
var word = words[wordindex];
|
const word = words[wordindex];
|
||||||
if (word.length > 0) {
|
if (word.length > 0) {
|
||||||
for (var searchtermindex in stemmed_searchterms) {
|
for (const searchtermindex in stemmed_searchterms) {
|
||||||
if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) {
|
if (elasticlunr.stemmer(word).startsWith(
|
||||||
|
stemmed_searchterms[searchtermindex])
|
||||||
|
) {
|
||||||
value = searchterm_weight;
|
value = searchterm_weight;
|
||||||
searchterm_found = true;
|
searchterm_found = true;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
weighted.push([word, value, index]);
|
weighted.push([word, value, index]);
|
||||||
value = 2;
|
value = 2;
|
||||||
}
|
}
|
||||||
index += word.length;
|
index += word.length;
|
||||||
index += 1; // ' ' or '.' if last word in sentence
|
index += 1; // ' ' or '.' if last word in sentence
|
||||||
};
|
}
|
||||||
index += 1; // because we split at a two-char boundary '. '
|
index += 1; // because we split at a two-char boundary '. '
|
||||||
};
|
}
|
||||||
|
|
||||||
if (weighted.length == 0) {
|
if (weighted.length === 0) {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
var window_weight = [];
|
const window_weight = [];
|
||||||
var window_size = Math.min(weighted.length, results_options.teaser_word_count);
|
const window_size = Math.min(weighted.length, results_options.teaser_word_count);
|
||||||
|
|
||||||
var cur_sum = 0;
|
let cur_sum = 0;
|
||||||
for (var wordindex = 0; wordindex < window_size; wordindex++) {
|
for (let wordindex = 0; wordindex < window_size; wordindex++) {
|
||||||
cur_sum += weighted[wordindex][1];
|
cur_sum += weighted[wordindex][1];
|
||||||
};
|
}
|
||||||
window_weight.push(cur_sum);
|
window_weight.push(cur_sum);
|
||||||
for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) {
|
for (let wordindex = 0; wordindex < weighted.length - window_size; wordindex++) {
|
||||||
cur_sum -= weighted[wordindex][1];
|
cur_sum -= weighted[wordindex][1];
|
||||||
cur_sum += weighted[wordindex + window_size][1];
|
cur_sum += weighted[wordindex + window_size][1];
|
||||||
window_weight.push(cur_sum);
|
window_weight.push(cur_sum);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
let max_sum_window_index = 0;
|
||||||
if (searchterm_found) {
|
if (searchterm_found) {
|
||||||
var max_sum = 0;
|
let max_sum = 0;
|
||||||
var max_sum_window_index = 0;
|
|
||||||
// backwards
|
// backwards
|
||||||
for (var i = window_weight.length - 1; i >= 0; i--) {
|
for (let i = window_weight.length - 1; i >= 0; i--) {
|
||||||
if (window_weight[i] > max_sum) {
|
if (window_weight[i] > max_sum) {
|
||||||
max_sum = window_weight[i];
|
max_sum = window_weight[i];
|
||||||
max_sum_window_index = i;
|
max_sum_window_index = i;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
max_sum_window_index = 0;
|
max_sum_window_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add <em/> around searchterms
|
// add <em/> around searchterms
|
||||||
var teaser_split = [];
|
const teaser_split = [];
|
||||||
var index = weighted[max_sum_window_index][2];
|
index = weighted[max_sum_window_index][2];
|
||||||
for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) {
|
for (let i = max_sum_window_index; i < max_sum_window_index + window_size; i++) {
|
||||||
var word = weighted[i];
|
const word = weighted[i];
|
||||||
if (index < word[2]) {
|
if (index < word[2]) {
|
||||||
// missing text from index to start of `word`
|
// missing text from index to start of `word`
|
||||||
teaser_split.push(body.substring(index, word[2]));
|
teaser_split.push(body.substring(index, word[2]));
|
||||||
index = word[2];
|
index = word[2];
|
||||||
}
|
}
|
||||||
if (word[1] == searchterm_weight) {
|
if (word[1] === searchterm_weight) {
|
||||||
teaser_split.push("<em>")
|
teaser_split.push('<em>');
|
||||||
}
|
}
|
||||||
index = word[2] + word[0].length;
|
index = word[2] + word[0].length;
|
||||||
teaser_split.push(body.substring(word[2], index));
|
teaser_split.push(body.substring(word[2], index));
|
||||||
if (word[1] == searchterm_weight) {
|
if (word[1] === searchterm_weight) {
|
||||||
teaser_split.push("</em>")
|
teaser_split.push('</em>');
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return teaser_split.join('');
|
return teaser_split.join('');
|
||||||
}
|
}
|
||||||
|
|
@ -255,74 +264,95 @@ window.search = window.search || {};
|
||||||
function init(config) {
|
function init(config) {
|
||||||
results_options = config.results_options;
|
results_options = config.results_options;
|
||||||
search_options = config.search_options;
|
search_options = config.search_options;
|
||||||
searchbar_outer = config.searchbar_outer;
|
|
||||||
doc_urls = config.doc_urls;
|
doc_urls = config.doc_urls;
|
||||||
searchindex = elasticlunr.Index.load(config.index);
|
searchindex = elasticlunr.Index.load(config.index);
|
||||||
|
|
||||||
// Set up events
|
// Set up events
|
||||||
searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false);
|
searchicon.addEventListener('click', () => {
|
||||||
searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false);
|
searchIconClickHandler();
|
||||||
document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false);
|
}, false);
|
||||||
|
searchbar.addEventListener('keyup', () => {
|
||||||
|
searchbarKeyUpHandler();
|
||||||
|
}, false);
|
||||||
|
document.addEventListener('keydown', e => {
|
||||||
|
globalKeyHandler(e);
|
||||||
|
}, false);
|
||||||
// If the user uses the browser buttons, do the same as if a reload happened
|
// If the user uses the browser buttons, do the same as if a reload happened
|
||||||
window.onpopstate = function(e) { doSearchOrMarkFromUrl(); };
|
window.onpopstate = () => {
|
||||||
|
doSearchOrMarkFromUrl();
|
||||||
|
};
|
||||||
// Suppress "submit" events so the page doesn't reload when the user presses Enter
|
// Suppress "submit" events so the page doesn't reload when the user presses Enter
|
||||||
document.addEventListener('submit', function(e) { e.preventDefault(); }, false);
|
document.addEventListener('submit', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
// If reloaded, do the search or mark again, depending on the current url parameters
|
// If reloaded, do the search or mark again, depending on the current url parameters
|
||||||
doSearchOrMarkFromUrl();
|
doSearchOrMarkFromUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
function unfocusSearchbar() {
|
function unfocusSearchbar() {
|
||||||
// hacky, but just focusing a div only works once
|
// hacky, but just focusing a div only works once
|
||||||
var tmp = document.createElement('input');
|
const tmp = document.createElement('input');
|
||||||
tmp.setAttribute('style', 'position: absolute; opacity: 0;');
|
tmp.setAttribute('style', 'position: absolute; opacity: 0;');
|
||||||
searchicon.appendChild(tmp);
|
searchicon.appendChild(tmp);
|
||||||
tmp.focus();
|
tmp.focus();
|
||||||
tmp.remove();
|
tmp.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// On reload or browser history backwards/forwards events, parse the url and do search or mark
|
// On reload or browser history backwards/forwards events, parse the url and do search or mark
|
||||||
function doSearchOrMarkFromUrl() {
|
function doSearchOrMarkFromUrl() {
|
||||||
// Check current URL for search request
|
// Check current URL for search request
|
||||||
var url = parseURL(window.location.href);
|
const url = parseURL(window.location.href);
|
||||||
if (url.params.hasOwnProperty(URL_SEARCH_PARAM)
|
if (Object.prototype.hasOwnProperty.call(url.params, URL_SEARCH_PARAM)
|
||||||
&& url.params[URL_SEARCH_PARAM] != "") {
|
&& url.params[URL_SEARCH_PARAM] !== '') {
|
||||||
showSearch(true);
|
showSearch(true);
|
||||||
searchbar.value = decodeURIComponent(
|
searchbar.value = decodeURIComponent(
|
||||||
(url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20'));
|
(url.params[URL_SEARCH_PARAM] + '').replace(/\+/g, '%20'));
|
||||||
searchbarKeyUpHandler(); // -> doSearch()
|
searchbarKeyUpHandler(); // -> doSearch()
|
||||||
} else {
|
} else {
|
||||||
showSearch(false);
|
showSearch(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.params.hasOwnProperty(URL_MARK_PARAM)) {
|
if (Object.prototype.hasOwnProperty.call(url.params, URL_MARK_PARAM)) {
|
||||||
var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' ');
|
const words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' ');
|
||||||
marker.mark(words, {
|
marker.mark(words, {
|
||||||
exclude: mark_exclude
|
exclude: mark_exclude,
|
||||||
});
|
});
|
||||||
|
|
||||||
var markers = document.querySelectorAll("mark");
|
const markers = document.querySelectorAll('mark');
|
||||||
function hide() {
|
const hide = () => {
|
||||||
for (var i = 0; i < markers.length; i++) {
|
for (let i = 0; i < markers.length; i++) {
|
||||||
markers[i].classList.add("fade-out");
|
markers[i].classList.add('fade-out');
|
||||||
window.setTimeout(function(e) { marker.unmark(); }, 300);
|
window.setTimeout(() => {
|
||||||
|
marker.unmark();
|
||||||
|
}, 300);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
for (var i = 0; i < markers.length; i++) {
|
|
||||||
|
for (let i = 0; i < markers.length; i++) {
|
||||||
markers[i].addEventListener('click', hide);
|
markers[i].addEventListener('click', hide);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eventhandler for keyevents on `document`
|
// Eventhandler for keyevents on `document`
|
||||||
function globalKeyHandler(e) {
|
function globalKeyHandler(e) {
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text' || !hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName)) { return; }
|
if (e.altKey ||
|
||||||
|
e.ctrlKey ||
|
||||||
|
e.metaKey ||
|
||||||
|
e.shiftKey ||
|
||||||
|
e.target.type === 'textarea' ||
|
||||||
|
e.target.type === 'text' ||
|
||||||
|
!hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.keyCode === ESCAPE_KEYCODE) {
|
if (e.keyCode === ESCAPE_KEYCODE) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
searchbar.classList.remove("active");
|
searchbar.classList.remove('active');
|
||||||
setSearchUrlParameters("",
|
setSearchUrlParameters('',
|
||||||
(searchbar.value.trim() !== "") ? "push" : "replace");
|
searchbar.value.trim() !== '' ? 'push' : 'replace');
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
unfocusSearchbar();
|
unfocusSearchbar();
|
||||||
}
|
}
|
||||||
|
|
@ -336,25 +366,27 @@ window.search = window.search || {};
|
||||||
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
|
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
unfocusSearchbar();
|
unfocusSearchbar();
|
||||||
searchresults.firstElementChild.classList.add("focus");
|
searchresults.firstElementChild.classList.add('focus');
|
||||||
} else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE
|
} else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE
|
||||||
|| e.keyCode === UP_KEYCODE
|
|| e.keyCode === UP_KEYCODE
|
||||||
|| e.keyCode === SELECT_KEYCODE)) {
|
|| e.keyCode === SELECT_KEYCODE)) {
|
||||||
// not `:focus` because browser does annoying scrolling
|
// not `:focus` because browser does annoying scrolling
|
||||||
var focused = searchresults.querySelector("li.focus");
|
const focused = searchresults.querySelector('li.focus');
|
||||||
if (!focused) return;
|
if (!focused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.keyCode === DOWN_KEYCODE) {
|
if (e.keyCode === DOWN_KEYCODE) {
|
||||||
var next = focused.nextElementSibling;
|
const next = focused.nextElementSibling;
|
||||||
if (next) {
|
if (next) {
|
||||||
focused.classList.remove("focus");
|
focused.classList.remove('focus');
|
||||||
next.classList.add("focus");
|
next.classList.add('focus');
|
||||||
}
|
}
|
||||||
} else if (e.keyCode === UP_KEYCODE) {
|
} else if (e.keyCode === UP_KEYCODE) {
|
||||||
focused.classList.remove("focus");
|
focused.classList.remove('focus');
|
||||||
var prev = focused.previousElementSibling;
|
const prev = focused.previousElementSibling;
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev.classList.add("focus");
|
prev.classList.add('focus');
|
||||||
} else {
|
} else {
|
||||||
searchbar.select();
|
searchbar.select();
|
||||||
}
|
}
|
||||||
|
|
@ -371,9 +403,9 @@ window.search = window.search || {};
|
||||||
} else {
|
} else {
|
||||||
search_wrap.classList.add('hidden');
|
search_wrap.classList.add('hidden');
|
||||||
searchicon.setAttribute('aria-expanded', 'false');
|
searchicon.setAttribute('aria-expanded', 'false');
|
||||||
var results = searchresults.children;
|
const results = searchresults.children;
|
||||||
for (var i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
results[i].classList.remove("focus");
|
results[i].classList.remove('focus');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -396,36 +428,37 @@ window.search = window.search || {};
|
||||||
showSearch(false);
|
showSearch(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eventhandler for keyevents while the searchbar is focused
|
// Eventhandler for keyevents while the searchbar is focused
|
||||||
function searchbarKeyUpHandler() {
|
function searchbarKeyUpHandler() {
|
||||||
var searchterm = searchbar.value.trim();
|
const searchterm = searchbar.value.trim();
|
||||||
if (searchterm != "") {
|
if (searchterm !== '') {
|
||||||
searchbar.classList.add("active");
|
searchbar.classList.add('active');
|
||||||
doSearch(searchterm);
|
doSearch(searchterm);
|
||||||
} else {
|
} else {
|
||||||
searchbar.classList.remove("active");
|
searchbar.classList.remove('active');
|
||||||
showResults(false);
|
showResults(false);
|
||||||
removeChildren(searchresults);
|
removeChildren(searchresults);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSearchUrlParameters(searchterm, "push_if_new_search_else_replace");
|
setSearchUrlParameters(searchterm, 'push_if_new_search_else_replace');
|
||||||
|
|
||||||
// Remove marks
|
// Remove marks
|
||||||
marker.unmark();
|
marker.unmark();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor .
|
// Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and
|
||||||
// `action` can be one of "push", "replace", "push_if_new_search_else_replace"
|
// `#heading-anchor`. `action` can be one of "push", "replace",
|
||||||
// and replaces or pushes a new browser history item.
|
// "push_if_new_search_else_replace" and replaces or pushes a new browser history item.
|
||||||
// "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet.
|
// "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet.
|
||||||
function setSearchUrlParameters(searchterm, action) {
|
function setSearchUrlParameters(searchterm, action) {
|
||||||
var url = parseURL(window.location.href);
|
const url = parseURL(window.location.href);
|
||||||
var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM);
|
const first_search = !Object.prototype.hasOwnProperty.call(url.params, URL_SEARCH_PARAM);
|
||||||
if (searchterm != "" || action == "push_if_new_search_else_replace") {
|
|
||||||
|
if (searchterm !== '' || action === 'push_if_new_search_else_replace') {
|
||||||
url.params[URL_SEARCH_PARAM] = searchterm;
|
url.params[URL_SEARCH_PARAM] = searchterm;
|
||||||
delete url.params[URL_MARK_PARAM];
|
delete url.params[URL_MARK_PARAM];
|
||||||
url.hash = "";
|
url.hash = '';
|
||||||
} else {
|
} else {
|
||||||
delete url.params[URL_MARK_PARAM];
|
delete url.params[URL_MARK_PARAM];
|
||||||
delete url.params[URL_SEARCH_PARAM];
|
delete url.params[URL_SEARCH_PARAM];
|
||||||
|
|
@ -433,32 +466,40 @@ window.search = window.search || {};
|
||||||
// A new search will also add a new history item, so the user can go back
|
// A new search will also add a new history item, so the user can go back
|
||||||
// to the page prior to searching. A updated search term will only replace
|
// to the page prior to searching. A updated search term will only replace
|
||||||
// the url.
|
// the url.
|
||||||
if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) {
|
if (action === 'push' || action === 'push_if_new_search_else_replace' && first_search ) {
|
||||||
history.pushState({}, document.title, renderURL(url));
|
history.pushState({}, document.title, renderURL(url));
|
||||||
} else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) {
|
} else if (action === 'replace' ||
|
||||||
|
action === 'push_if_new_search_else_replace' &&
|
||||||
|
!first_search
|
||||||
|
) {
|
||||||
history.replaceState({}, document.title, renderURL(url));
|
history.replaceState({}, document.title, renderURL(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSearch(searchterm) {
|
function doSearch(searchterm) {
|
||||||
// Don't search the same twice
|
// Don't search the same twice
|
||||||
if (current_searchterm == searchterm) { return; }
|
if (current_searchterm === searchterm) {
|
||||||
else { current_searchterm = searchterm; }
|
return;
|
||||||
|
} else {
|
||||||
|
current_searchterm = searchterm;
|
||||||
|
}
|
||||||
|
|
||||||
if (searchindex == null) { return; }
|
if (searchindex === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Do the actual search
|
// Do the actual search
|
||||||
var results = searchindex.search(searchterm, search_options);
|
const results = searchindex.search(searchterm, search_options);
|
||||||
var resultcount = Math.min(results.length, results_options.limit_results);
|
const resultcount = Math.min(results.length, results_options.limit_results);
|
||||||
|
|
||||||
// Display search metrics
|
// Display search metrics
|
||||||
searchresults_header.innerText = formatSearchMetric(resultcount, searchterm);
|
searchresults_header.innerText = formatSearchMetric(resultcount, searchterm);
|
||||||
|
|
||||||
// Clear and insert results
|
// Clear and insert results
|
||||||
var searchterms = searchterm.split(' ');
|
const searchterms = searchterm.split(' ');
|
||||||
removeChildren(searchresults);
|
removeChildren(searchresults);
|
||||||
for(var i = 0; i < resultcount ; i++){
|
for (let i = 0; i < resultcount ; i++) {
|
||||||
var resultElem = document.createElement('li');
|
const resultElem = document.createElement('li');
|
||||||
resultElem.innerHTML = formatSearchResult(results[i], searchterms);
|
resultElem.innerHTML = formatSearchResult(results[i], searchterms);
|
||||||
searchresults.appendChild(resultElem);
|
searchresults.appendChild(resultElem);
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +514,7 @@ window.search = window.search || {};
|
||||||
script.id = id;
|
script.id = id;
|
||||||
script.onload = () => init(window.search);
|
script.onload = () => init(window.search);
|
||||||
script.onerror = error => {
|
script.onerror = error => {
|
||||||
console.error(`Failed to load \`${url}\`: ${error}`);
|
console.error(`Failed to load \`${url}\`: ${error}`);
|
||||||
};
|
};
|
||||||
document.head.append(script);
|
document.head.append(script);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use serde_json::Value;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::fs::{read_dir, read_to_string, remove_dir_all};
|
use std::fs::{read_dir, read_to_string, remove_dir_all};
|
||||||
|
|
@ -27,15 +28,18 @@ fn get_available_browser_ui_test_version() -> Option<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_browser_ui_test_version() -> String {
|
fn expected_browser_ui_test_version() -> String {
|
||||||
let content = read_to_string(".github/workflows/main.yml")
|
let content = read_to_string("package.json").expect("failed to read `package.json`");
|
||||||
.expect("failed to read `.github/workflows/main.yml`");
|
let v: Value = serde_json::from_str(&content).expect("failed to parse `package.json`");
|
||||||
for line in content.lines() {
|
let Some(dependencies) = v.get("dependencies") else {
|
||||||
let line = line.trim();
|
panic!("Missing `dependencies` key in `package.json`");
|
||||||
if let Some(version) = line.strip_prefix("BROWSER_UI_TEST_VERSION:") {
|
};
|
||||||
return version.trim().replace('\'', "");
|
let Some(browser_ui_test) = dependencies.get("browser-ui-test") else {
|
||||||
}
|
panic!("Missing `browser-ui-test` key in \"dependencies\" object in `package.json`");
|
||||||
}
|
};
|
||||||
panic!("failed to retrieved `browser-ui-test` version");
|
let Value::String(version) = browser_ui_test else {
|
||||||
|
panic!("`browser-ui-test` version is not a string");
|
||||||
|
};
|
||||||
|
version.trim().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue