diff --git a/Debugger.html b/Debugger.html index 1257cd9..c80f005 100644 --- a/Debugger.html +++ b/Debugger.html @@ -4,7 +4,7 @@ Class: Debugger | DOCOLATTE - + @@ -169,7 +169,7 @@
Parameters:
Source:
- static/_src/scripts/Debugger.js, line 5 + src/scripts/Debugger.js, line 5
@@ -314,7 +314,7 @@
Parameters:
Source:
- static/_src/scripts/Debugger.js, line 40 + src/scripts/Debugger.js, line 40
@@ -390,7 +390,7 @@

disable
Source:
- static/_src/scripts/Debugger.js, line 23 + src/scripts/Debugger.js, line 23
@@ -445,7 +445,7 @@

enable
Source:
- static/_src/scripts/Debugger.js, line 17 + src/scripts/Debugger.js, line 17
@@ -548,7 +548,7 @@
Parameters:
Source:
- static/_src/scripts/Debugger.js, line 30 + src/scripts/Debugger.js, line 30
@@ -651,7 +651,7 @@
Parameters:
Source:
- static/_src/scripts/Debugger.js, line 48 + src/scripts/Debugger.js, line 48
@@ -698,7 +698,7 @@
Parameters:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -739,13 +739,13 @@
Parameters:
- +
- + \ No newline at end of file diff --git a/Docolatte.html b/Docolatte.html index f51d6e4..311829d 100644 --- a/Docolatte.html +++ b/Docolatte.html @@ -4,7 +4,7 @@ Class: Docolatte | DOCOLATTE - + @@ -348,7 +348,7 @@
Parameters:
Source:
- lib/Docolatte.js, line 242 + lib/Docolatte.js, line 244
@@ -480,7 +480,7 @@
Parameters:
Source:
- lib/Docolatte.js, line 222 + lib/Docolatte.js, line 224
@@ -696,7 +696,7 @@
Properties
Source:
- lib/Docolatte.js, line 322 + lib/Docolatte.js, line 324
See:
@@ -769,7 +769,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -810,13 +810,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/Exception.html b/Exception.html index ccaa896..8126575 100644 --- a/Exception.html +++ b/Exception.html @@ -4,7 +4,7 @@ Class: Exception | DOCOLATTE - + @@ -133,7 +133,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 5 + src/scripts/Exception.js, line 5
@@ -256,7 +256,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 31 + src/scripts/Exception.js, line 31
@@ -393,7 +393,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 17 + src/scripts/Exception.js, line 17
@@ -496,7 +496,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 24 + src/scripts/Exception.js, line 24
@@ -599,7 +599,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 48 + src/scripts/Exception.js, line 48
@@ -724,7 +724,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 40 + src/scripts/Exception.js, line 40
@@ -870,7 +870,7 @@
Parameters:
Source:
- static/_src/scripts/Exception.js, line 57 + src/scripts/Exception.js, line 57
@@ -938,7 +938,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -979,13 +979,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/FileImporter.html b/FileImporter.html index c637c0b..aab2c62 100644 --- a/FileImporter.html +++ b/FileImporter.html @@ -4,7 +4,7 @@ Class: FileImporter | DOCOLATTE - + @@ -612,7 +612,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -653,13 +653,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/Hooks.html b/Hooks.html index 4cb7e01..79e3e68 100644 --- a/Hooks.html +++ b/Hooks.html @@ -4,7 +4,7 @@ Class: Hooks | DOCOLATTE - + @@ -776,7 +776,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -817,13 +817,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/LightSwitch.html b/LightSwitch.html index 715de23..3e54de2 100644 --- a/LightSwitch.html +++ b/LightSwitch.html @@ -4,7 +4,7 @@ Class: LightSwitch | DOCOLATTE - + @@ -167,7 +167,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 11 + src/scripts/LightSwitch.js, line 11
@@ -226,7 +226,7 @@

Source:
- static/_src/scripts/LightSwitch.js, line 37 + src/scripts/LightSwitch.js, line 37
@@ -253,7 +253,7 @@

rea
Source:
- static/_src/scripts/LightSwitch.js, line 29 + src/scripts/LightSwitch.js, line 29
@@ -356,7 +356,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 45 + src/scripts/LightSwitch.js, line 45
@@ -433,7 +433,7 @@

load
Source:
- static/_src/scripts/LightSwitch.js, line 146 + src/scripts/LightSwitch.js, line 146
@@ -488,7 +488,7 @@

nextState
Source:
- static/_src/scripts/LightSwitch.js, line 114 + src/scripts/LightSwitch.js, line 114
@@ -543,7 +543,7 @@

prevState
Source:
- static/_src/scripts/LightSwitch.js, line 108 + src/scripts/LightSwitch.js, line 108
@@ -598,7 +598,7 @@

save
Source:
- static/_src/scripts/LightSwitch.js, line 172 + src/scripts/LightSwitch.js, line 172
@@ -723,7 +723,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 91 + src/scripts/LightSwitch.js, line 91
@@ -826,7 +826,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 100 + src/scripts/LightSwitch.js, line 100
@@ -958,7 +958,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 70 + src/scripts/LightSwitch.js, line 70
@@ -1090,7 +1090,7 @@
Parameters:
Source:
- static/_src/scripts/LightSwitch.js, line 78 + src/scripts/LightSwitch.js, line 78
@@ -1145,7 +1145,7 @@

sync
Source:
- static/_src/scripts/LightSwitch.js, line 120 + src/scripts/LightSwitch.js, line 120
@@ -1200,7 +1200,7 @@

syncRoom
Source:
- static/_src/scripts/LightSwitch.js, line 136 + src/scripts/LightSwitch.js, line 136
@@ -1255,7 +1255,7 @@

syncSwitch
Source:
- static/_src/scripts/LightSwitch.js, line 127 + src/scripts/LightSwitch.js, line 127
@@ -1302,7 +1302,7 @@

syncSwitch - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -1343,13 +1343,13 @@

syncSwitch
- +
- + \ No newline at end of file diff --git a/Nav.html b/Nav.html index a3451e0..ab54417 100644 --- a/Nav.html +++ b/Nav.html @@ -4,7 +4,7 @@ Class: Nav | DOCOLATTE - + @@ -1048,7 +1048,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -1089,13 +1089,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/Ref.html b/Ref.html index 7db1837..89346b8 100644 --- a/Ref.html +++ b/Ref.html @@ -4,7 +4,7 @@ Class: Ref | DOCOLATTE - + @@ -472,7 +472,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -513,13 +513,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/ScrollWatcher.html b/ScrollWatcher.html index cac7f24..56d6650 100644 --- a/ScrollWatcher.html +++ b/ScrollWatcher.html @@ -4,7 +4,7 @@ Class: ScrollWatcher | DOCOLATTE - + @@ -141,7 +141,7 @@
Parameters:
Source:
- static/_src/scripts/ScrollWatcher.js, line 8 + src/scripts/ScrollWatcher.js, line 8
@@ -286,7 +286,7 @@
Parameters:
Source:
- static/_src/scripts/ScrollWatcher.js, line 29 + src/scripts/ScrollWatcher.js, line 29
@@ -406,7 +406,7 @@
Parameters:
Source:
- static/_src/scripts/ScrollWatcher.js, line 40 + src/scripts/ScrollWatcher.js, line 40
@@ -453,7 +453,7 @@
Parameters:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -494,13 +494,13 @@
Parameters:
- +
- + \ No newline at end of file diff --git a/SearchDB.html b/SearchDB.html index 343b57a..03d0eb3 100644 --- a/SearchDB.html +++ b/SearchDB.html @@ -4,7 +4,7 @@ Class: SearchDB | DOCOLATTE - + @@ -662,7 +662,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -703,13 +703,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/SelectList.html b/SelectList.html index e6df701..6ae51e3 100644 --- a/SelectList.html +++ b/SelectList.html @@ -4,7 +4,7 @@ Class: SelectList | DOCOLATTE - + @@ -167,7 +167,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 5 + src/scripts/SelectList.js, line 5
@@ -237,7 +237,7 @@

curr
Source:
- static/_src/scripts/SelectList.js, line 32 + src/scripts/SelectList.js, line 32
@@ -264,7 +264,7 @@

length
Source:
- static/_src/scripts/SelectList.js, line 25 + src/scripts/SelectList.js, line 25
@@ -359,7 +359,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 69 + src/scripts/SelectList.js, line 69
@@ -479,7 +479,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 61 + src/scripts/SelectList.js, line 61
@@ -603,7 +603,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 46 + src/scripts/SelectList.js, line 46
@@ -714,7 +714,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 106 + src/scripts/SelectList.js, line 106
@@ -838,7 +838,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 53 + src/scripts/SelectList.js, line 53
@@ -949,7 +949,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 96 + src/scripts/SelectList.js, line 96
@@ -1073,7 +1073,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 77 + src/scripts/SelectList.js, line 77
@@ -1197,7 +1197,7 @@
Parameters:
Source:
- static/_src/scripts/SelectList.js, line 86 + src/scripts/SelectList.js, line 86
@@ -1265,7 +1265,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -1306,13 +1306,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/TmplUtil.html b/TmplUtil.html index d5d2a05..08b3623 100644 --- a/TmplUtil.html +++ b/TmplUtil.html @@ -4,7 +4,7 @@ Class: TmplUtil | DOCOLATTE - + @@ -2097,7 +2097,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -2138,13 +2138,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/Util.html b/Util.html index 6fa86db..3a9ef7d 100644 --- a/Util.html +++ b/Util.html @@ -4,7 +4,7 @@ Class: Util | DOCOLATTE - + @@ -456,7 +456,7 @@
Parameters:
Source:
- lib/Util.js, line 148 + lib/Util.js, line 160
See:
@@ -1517,7 +1517,7 @@
Returns:
-

toLiteral(x)string

+

toLiteral(x, optsopt)string

@@ -1575,7 +1575,113 @@
Parameters:
-

Any type of value

+

Value to convert

+ + + + + + + + optsopt + + + + + + +object + + + + + + +

Options

+
Properties
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
+ quote + + + +string + + + + + '"' + +

Quotation char for string values

+ quoteKeys + + + +boolean + + + + + true + +

Whether to quote object keys

+
+ + @@ -1591,7 +1697,7 @@
Parameters:
Source:
- lib/Util.js, line 130 + lib/Util.js, line 133
@@ -1659,7 +1765,7 @@
Returns:

- Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

@@ -1700,13 +1806,13 @@
Returns:
- +
- + \ No newline at end of file diff --git a/_src/scripts/Debugger.js b/_src/scripts/Debugger.js deleted file mode 100644 index f81cc88..0000000 --- a/_src/scripts/Debugger.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Debug utility. - * @author amekusa - */ -class Debugger { - /** - * @param {string} [label] - Log label - * @param {boolean} [enabled] - Whether to enable debugging - */ - constructor(label = '[DEBUG]', enabled = true) { - this.label = label; - this.enabled = enabled; - } - /** - * Enables debugging. - */ - enable() { - this.enabled = true; - } - /** - * Disables debugging. - */ - disable() { - this.enabled = false; - } - /** - * Outputs logs to console. - * @param {...any} args - Infos to log - */ - log(...args) { - if (!this.enabled) return false; - return console.debug(this.label, ...args); - } - /** - * Calls the given function. - * @param {function} fn - Function to call - * @param {...any} args - Arguments to pass to `fn` - * @return {any} Return of `fn` - */ - call(fn, ...args) { - if (!this.enabled) return false; - return fn(...args); - } - /** - * Simulates a heavy computing operation. - * @param {number} weight - How heavy - */ - slow(weight) { - if (!this.enabled) return false; - console.time(this.label + ' slow'); - let r = 0; - for (let i = Math.pow(weight, 7); i >= 0; i--) r += Math.atan(i) * Math.tan(i); - console.timeEnd(this.label + ' slow'); - return r; - } -} - -export default Debugger; diff --git a/_src/scripts/Exception.js b/_src/scripts/Exception.js deleted file mode 100644 index b889e9c..0000000 --- a/_src/scripts/Exception.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Exception thrower. - * @author amekusa - */ -class Exception { - /** - * @param {string} label - Log label - */ - constructor(label) { - this.label = label; - } - /** - * Generates a new exception instance. - * @param {string} msg - Message - * @param {any} [info] - Additional info - */ - new(msg, info = null) { - return new ExceptionInfo(this.label, msg, info); - } - /** - * Throws an exception. - * @param {...any} args - Same as {@link Exception#new} - */ - throw(...args) { - throw this.new(...args); - } - /** - * Logs an exception to console as an error. - * @param {...any} args - Same as {@link Exception#new} - */ - error(...args) { - console.error(this.new(...args)); - } - /** - * Logs an exception to console as an error, and returns the given value. - * @param {any} x - Return value - * @param {...any} args - Same as {@link Exception#new} - * @return {any} `x` - */ - withError(x, ...args) { - this.error(...args); - return x; - } - /** - * Logs an exception to console as a warning. - * @param {...any} args - Same as {@link Exception#new} - */ - warn(...args) { - console.warn(this.new(...args)); - } - /** - * Logs an exception to console as a warning, and returns the given value. - * @param {any} x - Return value - * @param {...any} args - Same as {@link Exception#new} - * @return {any} `x` - */ - withWarn(x, ...args) { - this.warn(...args); - return x; - } -} - -class ExceptionInfo extends Error { - constructor(label, msg, info = undefined) { - super(`${label} ${msg}` + (info === undefined ? '' : `\n:: info: ${info}`)); - this.info = info; - } -} - -export default Exception; diff --git a/_src/scripts/LightSwitch.js b/_src/scripts/LightSwitch.js deleted file mode 100644 index d11fd37..0000000 --- a/_src/scripts/LightSwitch.js +++ /dev/null @@ -1,180 +0,0 @@ -import SelectList from './SelectList.js'; -import Exception from './Exception.js'; -import Debugger from './Debugger.js'; -const E = new Exception('[LightSwitch]'); -const debug = new Debugger('[DBG:LS]', true); - -/** - * Color scheme switcher. - * @author amekusa - */ -class LightSwitch { - /** - * @param {string[]} [states] - All possible states. Default: `['auto', 'light', 'dark]` - * @param {number} [initial] - Initial state index - */ - constructor(states, initial = 0) { - this.switch = null; - this.room = null; - this.storage = null; - this.states = new SelectList(states || ['auto', 'light', 'dark'], initial); - this.states.onSelect(() => { this.sync(); }); - this._pref; - } - /** - * The current state. - * @type {string} - * @readonly - */ - get state() { - return this.states.curr; - } - /** - * The current state of the room. - * @type {string} - * @readonly - */ - get roomState() { - return this.state == 'auto' ? this.getPreference() : this.state; - } - /** - * Fetch user's system preference. - * @param {boolean} [update] - Force update - * @return {string} preferred state - */ - getPreference(update = false) { - if (this._pref === undefined || update) { - debug.log(`matching user preference...`); - let states = this.states.items; - for (let i = 0; i < states.length; i++) { - let state = states[i]; - if (state == 'auto') continue; - if (matchMedia(`(prefers-color-scheme: ${state})`).matches) { - debug.log(`matched user preference:`, state); - this._pref = i; - return state; - } - } - E.warn(`cannot find user preference`); - return this.states.item(this.states.initialPos); - } - return this.states.item(this._pref); - } - /** - * Sets a storage object to store state. - * @param {Storage} obj - * @param {string} key - * @example - * ls.setStorage(localStorage, 'lightSwitch'); - */ - setStorage(obj, key) { - this.storage = { obj, key }; - } - /** - * Connects a "switch" element to sync state. - * @param {Element} elem - Element - * @param {string} attr - Attribute to sync state - */ - setSwitch(elem, attr) { - this.switch = { elem, attr }; - elem.addEventListener('click', ev => { - ev.preventDefault(); - this.nextState(); - this.save(); - }); - } - /** - * Connects a "room" element to sync state. - * @param {Element} elem - Element - * @param {string} attr - Attribute to sync state - */ - setRoom(elem, attr) { - this.room = { elem, attr }; - } - /** - * Sets the current state. - * @param {number|string} state - State name or index - * @example - * ls.setState('dark'); - */ - setState(state) { - let pos = typeof state == 'number' ? state : this.states.indexOf(state); - if (pos < 0) return E.error(`invalid state`, { state }); - this.states.to(pos); - } - /** - * Switches to the previous state. - */ - prevState() { - this.states.prev(); - } - /** - * Switches to the next state. - */ - nextState() { - this.states.next(); - } - /** - * Syncs the "switch" and the "room" elements with the current state of this LightSwitch. - */ - sync() { - this.syncSwitch(); - this.syncRoom(); - } - /** - * Syncs the "switch" element with the current state of this LightSwitch. - */ - syncSwitch() { - if (this.switch) { - this.switch.elem.setAttribute(this.switch.attr, this.state); - debug.log(`synced switch`); - } - } - /** - * Syncs the "room" element with the current state of this LightSwitch. - */ - syncRoom() { - if (this.room) { - this.room.elem.setAttribute(this.room.attr, this.roomState); - debug.log(`synced room`); - } - } - /** - * Initializes the state by loading it from the browser storage, - * or reading the attribute values of "switch" or "room" element. - */ - load() { - // load saved state stored in the browser storage, if it exists - if (this.storage) { - debug.log(`loading state from storage...`); - debug.log(` - storage:`, this.storage); - let loaded = this.storage.obj.getItem(this.storage.key); - if (loaded) { - debug.log(`state loaded:`, loaded); - this.states.to(parseInt(loaded)); - return; - } - debug.log(`state not found`); - } - // if saved state was not found, use DOM attribute instead - debug.log(`retrieving state from doms...`); - let { elem, attr } = this.switch || this.room; - let state = elem.getAttribute(attr); - if (!state) return E.error(`load(): cannot find state`); - let pos = this.states.indexOf(state); - if (pos < 0) return E.error(`load(): invalid state`, { state }); - debug.log(`state found:`, state); - this.states.to(pos); - } - /** - * Saves the current state to the browser storage. - */ - save() { - if (this.storage) { - this.storage.obj.setItem(this.storage.key, this.states.pos); - debug.log(`saved state`); - } - } -} - -export default LightSwitch; diff --git a/_src/scripts/ScrollWatcher.js b/_src/scripts/ScrollWatcher.js deleted file mode 100644 index c3ea5df..0000000 --- a/_src/scripts/ScrollWatcher.js +++ /dev/null @@ -1,118 +0,0 @@ -import Debugger from './Debugger.js'; -const debug = new Debugger('[DBG:SW]', true); - -/** - * Scroll event watcher for smooth animation. - * @author amekusa - */ -class ScrollWatcher { - /** - * @param {Element} [target=window] - Element to watch - */ - constructor(target = window) { - this.target = target; - this.tasks = { - init: [], - scroll: [], - resize: [], - }; - } - /** - * Registers a callback. - * @param {string|string[]} ev - Event name(s). Pass `any` to register to all the available events - * @param {function} fn - Callback - * @example - * let sw.on('scroll', ev => { - * console.log('Scroll Detected'); - * }); - */ - on(ev, fn) { - if (Array.isArray(ev)) { - for (let i = 0; i < ev.length; i++) this.on(ev[i], fn); - } else if (ev == 'any') { - for (let key in this.tasks) this.on(key, fn); - } else this.tasks[ev].push(fn); - } - /** - * Starts watching scroll related events. - * @param {string|string[]} ev - Event name(s) to watch. `any` to watch all the available events - */ - watch(ev = 'any') { - if (ev == 'any') ev = Object.keys(this.tasks); - else if (!Array.isArray(ev)) ev = [ev]; - - // context - let c = new Stats({ x: 0, y: 0, mx: 0, my: 0, time: 0 }); - c.isFirst = true; - c.event = null; - - let request = false; // animation frame request id - let tick = time => { - c.set('time', time); - debug.log(`animation frame #${request} started @`, time); - debug.log(' - diff:', c.diff.time); - let tasks = this.tasks[c.event.type]; - for (let i = 0; i < tasks.length; i++) tasks[i](c); - if (c.isFirst) c.isFirst = false; - debug.log(`animation frame #${request} done`); - request = false; - }; - let propX, propY, propMX, propMY; - if (this.target === window) { - propX = 'scrollX'; - propY = 'scrollY'; - propMX = 'scrollMaxX'; - propMY = 'scrollMaxY'; - } else { - propX = 'scrollLeft'; - propY = 'scrollTop'; - propMX = 'scrollLeftMax'; - propMY = 'scrollTopMax'; - } - let handler = ev => { - debug.log(`--- ${ev.type} event ---`); - if (request) { // previous request is still in the queue - window.cancelAnimationFrame(request); // cancel the previous request - debug.log(` canceled animation frame #${request}`); - }; - c.event = ev; - c.set('x', this.target[propX]); - c.set('y', this.target[propY]); - c.set('mx', this.target[propMX]); - c.set('my', this.target[propMY]); - request = window.requestAnimationFrame(tick); - debug.log(`animation frame #${request} requested`); - }; - for (let i = 0; i < ev.length; i++) { - switch (ev[i]) { - case 'init': handler({ type: 'init' }); break; // fake event - case 'scroll': this.target.addEventListener('scroll', handler); break; - case 'resize': window.addEventListener('resize', handler); break; - } - } - } -} - -class Stats { - constructor(data) { - this.curr = {}; - this.prev = {}; - this.diff = {}; - for (let key in data) { - this.curr[key] = data[key]; - this.prev[key] = undefined; - this.diff[key] = undefined; - } - } - get(key) { - return this.curr[key]; - } - set(key, value) { - this.prev[key] = this.curr[key]; - this.curr[key] = value; - this.diff[key] = this.curr[key] - this.prev[key]; - return this; - } -} - -export default ScrollWatcher; diff --git a/_src/scripts/SelectList.js b/_src/scripts/SelectList.js deleted file mode 100644 index 4af8712..0000000 --- a/_src/scripts/SelectList.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * An array wrapper that has a pointer to one of its items. - * @author amekusa - */ -class SelectList { - /** - * @param {any[]} items - Array of items - * @param {number} [initial] - Initial position - * @example - * let difficulty = new SelectList([ - * 'easy', - * 'normal', // default - * 'hard' - * ], 1); - */ - constructor(items, initial = 0) { - this.items = items; - this.initialPos = this.pos = initial; - this.fn; - } - /** - * A number of items. - * @type {number} - */ - get length() { - return this.items.length; - } - /** - * The current item. - * @type {any} - */ - get curr() { - return this.items[this.pos]; - } - _checkIndex(index, or = 0) { - if (index < 0 || index >= this.items.length) { - console.error(`[SelectList] index out of bounds`); - return or; - } - return index; - } - /** - * Returns an item by the given index. - * @param {number} index - Item index - */ - item(index) { - return this.items[this._checkIndex(index)]; - } - /** - * Registers a callback that is invoked on every pointer movement. - * @param {function} fn - */ - onSelect(fn) { - this.fn = fn; - } - /** - * Returns the index of the given item. - * @param {any} item - Item to find - * @return {number} Index, or negative number if not found - */ - indexOf(item) { - return this.items.indexOf(item); - } - /** - * Whether the given item is in the list. - * @param {any} item - Item to find - * @return {boolean} - */ - has(item) { - return this.indexOf(item) >= 0; - } - /** - * Moves the pointer to the given item. - * @param {any} item - Item to find - * @return {any} Selected item - */ - select(item) { - let pos = this.indexOf(item); - return pos < 0 ? undefined : this.to(pos); - } - /** - * Moves the pointer to the given index. - * @param {number} pos - Index to move to - * @return {any} Selected item - */ - to(pos) { - this.pos = this._checkIndex(pos); - if (this.fn) this.fn(this.items[this.pos], this.pos, this); - return this.items[this.pos]; - } - /** - * Decrements the pointer. - * @param {boolean} [wrap] - * @return {any} Selected item - */ - prev(wrap = true) { - this.pos = this.pos > 0 ? this.pos - 1 : (wrap ? this.items.length - 1 : 0); - if (this.fn) this.fn(this.items[this.pos], this.pos, this); - return this.items[this.pos]; - } - /** - * Increments the pointer. - * @param {boolean} [wrap] - * @return {any} Selected item - */ - next(wrap = true) { - let last = this.items.length - 1; - this.pos = this.pos < last ? this.pos + 1 : (wrap ? 0 : last); - if (this.fn) this.fn(this.items[this.pos], this.pos, this); - return this.items[this.pos]; - } -} - -export default SelectList; \ No newline at end of file diff --git a/_src/scripts/main.js b/_src/scripts/main.js deleted file mode 100644 index 82dc84b..0000000 --- a/_src/scripts/main.js +++ /dev/null @@ -1,437 +0,0 @@ -import Fuse from 'fuse.js'; -import SimpleBar from 'simplebar'; -import HLJS from 'highlight.js/lib/common'; -import ScrollWatcher from './ScrollWatcher.js'; -import LightSwitch from './LightSwitch.js'; -import Debugger from './Debugger.js'; - -/*! - * The main script for docolatte - * @author Satoshi Soma (amekusa.com) - * - * Copyright 2020 Satoshi Soma - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -(() => { - const debug = new Debugger('[main]', true); - debug.log('script started'); - - // global namespace - const global = window.$docolatte = {}; - - - // ---- Functions -------- * - - /** - * @param {string} query - * @param {int} index - * @return {NodeList|Element|null} - */ - function q(query, index = null) { - return find(document, query, index); - } - - /** - * @param {Element} scope - * @param {string} query - * @param {int} index - * @return {NodeList|Element|null} - */ - function find(scope, query, index = null) { - let items = scope.querySelectorAll(query); - if (index == null) return items; - if ((index+1) > items.length) return null; - return items[index]; - } - - /** - * @param {Element} elem - * @param {string[]} queries - * @return {Element} - */ - function closest(elem, queries) { - let r = elem; - for (let i = 0; i < queries.length; i++) { - let _r = r.closest(queries[i]); - if (!_r) return r; - r = _r; - } - return r; - } - - /** - * @param {string} tag - * @param {object} attribs - * @param {string|array|Element} child - * @return {Element} - */ - function elem(tag, attribs = null, child = null) { - let r = document.createElement(tag); - if (attribs) { - for (let i in attribs) r.setAttribute(i, attribs[i]); - } - if (child) { - if (!Array.isArray(child)) child = [child]; - for (let item of child) { - switch (typeof item) { - case 'string': - case 'number': - r.innerHTML += item; - break; - default: - r.appendChild(item); - } - } - } - return r; - } - - /** - * Gets the offset position of an element from the specific ascendent node - * @param {Element} elem Node to get offset - * @param {Element} from Offset parent - * @param {number} recurse Recursion limit - * @return {number} offset.top - * @return {number} offset.left - */ - function getOffset(elem, from, recurse = 8) { - let r = { top: 0, left: 0 }; - let child = elem; - while (true) { - if ('offsetTop' in child) r.top += child.offsetTop; - if ('offsetLeft' in child) r.left += child.offsetLeft; - let parent = child.offsetParent; - if (!parent) return r; - if (parent.isSameNode(from)) break; - if (recurse < 1) break; - recurse--; - child = parent; - } - return r; - } - - /** - * Returns the least amount of camera movement required for showing the given target boundary - * @param {number} viewStart - * @param {number} viewEnd - * @param {number} targetStart - * @param {number} targetEnd - * @param {number} [align] 0: align to start, 1: align to end - * @return {number} - */ - function pan(viewStart, viewEnd, targetStart, targetEnd, align = 0) { - // console.debug(' viewStart:', viewStart); - // console.debug(' viewEnd:', viewEnd); - // console.debug('targetStart:', targetStart); - // console.debug(' targetEnd:', targetEnd); - // console.debug('------------'); - let viewLength = viewEnd - viewStart; - let targetLength = targetEnd - targetStart; - if (viewLength < targetLength) { - switch (align) { - case 1: return targetEnd - viewEnd; - default: return targetStart - viewStart; - } - } - if (viewStart > targetStart) return targetStart - viewStart; - if (viewEnd < targetEnd) return targetEnd - viewEnd; - return 0; - } - - - // ---- Tasks -------- * - - // initialize light switch - const ls = global.lightSwitch = new LightSwitch(); - ls.setStorage(localStorage, 'lightSwitch'); - ls.setRoom(document.documentElement, 'data-color-scheme'); - ls.load(); // apply color scheme to *BEFORE* DOM loaded - - // DOM setup - document.addEventListener('DOMContentLoaded', () => { - debug.log('dom content loaded'); - - // docolatte config - const config = global.config; - debug.log('config:', config); - - // current page path - const currentPage = location.pathname.substring(location.pathname.lastIndexOf('/')+1); - - // browser storage - const storage = sessionStorage; - - // window scroll watcher - const sw = new ScrollWatcher(window); - - // sidebar & TOC - const sidebar = q('.sidebar .wrap', 0); - const sidebarScr = new SimpleBar(sidebar).getScrollElement(); - const toc = find(sidebar, '.toc', 0); - - // restore sidebar scroll position - sidebarScr.scrollTo({ - left: parseInt(storage.getItem('scrollX') || 0), - top: parseInt(storage.getItem('scrollY') || 0), - behavior: 'instant' - }); - sidebar.setAttribute('data-ready', 1); - - // save sidebar scroll position - onbeforeunload = () => { - storage.setItem('scrollX', sidebarScr.scrollLeft); - storage.setItem('scrollY', sidebarScr.scrollTop); - }; - - // highlight TOC item that is pointing at the current page - find(toc, `a[href="${currentPage}"]`).forEach(a => { - a.setAttribute('data-current', 1); - }); - - // toggle switch for sidebar - const sidebarToggle = q('input#docolatte-sidebar-toggle', 0); - - // close sidebar when user clicked one of the menu items - find(sidebar, 'a').forEach(a => { - a.addEventListener('click', ev => { - sidebarToggle.checked = false; - }); - }); - - // close sidebar with Escape key - document.addEventListener('keydown', ev => { - if (ev.key == 'Escape') sidebarToggle.checked = false; - }); - - { // light switch - let btn = q('.light-switch', 0); - if (btn) { - ls.setSwitch(btn, 'data-state'); - ls.sync(); - } - } - - { // initialize search box - let fuse = new Fuse( - JSON.parse(q('#docolatte-search-items', 0).innerHTML), // records to search - JSON.parse(q('#docolatte-search-options', 0).innerHTML), // options (including keys) - Fuse.parseIndex(JSON.parse(q('#docolatte-search-index', 0).innerHTML)) // search index - ); - let base = find(sidebar, '.search-box', 0); - let input = find(base, 'input[type=text]', 0); - let dropdown = find(base, '.dropdown', 0); - let hint = find(base, '.hint', 0); // can be not present - let lastQuery = ''; - - // search as you type - input.addEventListener('input', ev => { - let query = ev.target.value; - if (query == lastQuery) return; - lastQuery = query; - - dropdown.innerHTML = ''; // clear - dropdown.setAttribute('data-select', 0); // reset the state - - if (!query.length) return; - let results = fuse.search(query, { limit: config.searchLimit || 8 }); - if (!results.length) return; - // console.debug('RESULTS:', results); - - if (hint) hint.classList.add('hidden'); // hide hint - - // show the results - let symbols = /([\/.#$:~-])/g; - for (let i = 0; i < results.length; i++) { - let item = results[i].item; - let url = item.$[0]; - let label = item.$[1].replaceAll(symbols, '$1'); // insert at every symbol chars - let li = elem('li', null, elem('a', { href: url }, label)); - if (i == 0) li.classList.add('selected'); // select the 1st item - dropdown.appendChild(li); - } - }); - - // navigate through dropdown-list with key presses - input.addEventListener('keydown', ev => { - if (ev.key == 'Escape') return ev.target.blur(); // ESC to unfocus - if (!dropdown.children.length) return; - - let select = Number.parseInt(dropdown.getAttribute('data-select') || 0); - let selectNew = select; - - // navigation - switch (ev.key) { - case 'ArrowDown': - selectNew++; - break; - case 'ArrowUp': - selectNew--; - break; - case 'Tab': - selectNew += (ev.shiftKey ? -1 : 1); - break; - case 'Enter': - find(dropdown.children[select], 'a', 0).click(); - break; - default: - return; // do nothing - } - if (selectNew < 0) selectNew = dropdown.children.length - 1; // jump to bottom from top - else if (selectNew >= dropdown.children.length) selectNew = 0; // jump to top from bottom - dropdown.children[select].classList.remove('selected'); // unselect the previous - dropdown.children[selectNew].classList.add('selected'); // select the new - dropdown.setAttribute('data-select', selectNew); - ev.preventDefault(); - }); - - // hint - if (hint) { - input.addEventListener('click', ev => { - if (ev.target.value) return; - hint.classList.remove('hidden'); - }); - input.addEventListener('blur', ev => { - hint.classList.add('hidden'); - }); - } - - // on focus searchbox - input.addEventListener('focus', ev => { - // force sidebar to show when searchbox gets focused - sidebarToggle.checked = true; - - // scroll sidebar to top - sidebarScr.scrollTo({ - left: 0, - top: 0, - behavior: 'instant' - }); - }); - - // type any "printable" key to start a search - document.addEventListener('keydown', ev => { - // console.debug('KEYDOWN:', ev); - if (ev.key.length != 1) return; // ignore non-printable keys - if (ev.key == ' ') return; // ignore SPACE key - if (ev.metaKey || ev.ctrlKey || ev.altKey) return; // ignore keys with modifiers - if (ev.target.tagName == 'INPUT' || ev.target.tagName == 'TEXTAREA') return; - input.value = ''; - input.focus(); - }); - } - - { // mark a TOC item as "current" on scroll - let headings = q('article.doc h4.name[id]'); - let curr = { i: -1, a: null, wrap: null }; - - sw.on(['init', 'scroll'], c => { - debug.log('toc update started'); - for (let i = 0; i < headings.length; i++) { - if (headings[i].offsetTop < c.curr.y) continue; - if (i == curr.i) break; - - // change current URL hash - let hash = '#' + headings[i].id; - history.replaceState(null, null, hash); - - // update "current" state of TOC - let flag = 'data-current'; - if (curr.i >= 0 && curr.a.length) curr.a.forEach(a => { a.removeAttribute(flag) }); - curr.i = i; - curr.a = find(toc, `a[href="${currentPage + hash}"]`); - if (!curr.a.length) break; - curr.a.forEach(a => { a.setAttribute(flag, 1) }); - - // scroll sidebar if necessary - let a = curr.a[curr.a.length - 1]; - if (!curr.wrap) curr.wrap = closest(a, ['ul', 'li']); - let view = sidebarScr; - let panning = pan( - view.scrollTop, - view.scrollTop + view.offsetHeight, - getOffset(curr.wrap, sidebar).top, - getOffset(a, sidebar).top + a.getBoundingClientRect().height, - 1 - ); - if (panning || view.scrollLeft) { - view.scrollBy({ - left: -view.scrollLeft, - top: panning, - behavior: 'smooth' - }); - } - break; - } - debug.log('toc update done'); - }); - } - - { // code highlight - const linenums = []; - - const linenumify = (pre) => { - let code = find(pre, 'code', 0); - let lines = (code.innerHTML.trimEnd().match(/\n/g) || '').length + 1; - let digits = lines.toString().length; - let charWidth = find(pre, '._char', 0).getBoundingClientRect().width; - let width = charWidth * (digits + 2); // px - code.style.paddingLeft = width + charWidth + 'px'; - - let r = elem('div', { class: 'linenums' }); - for (let i = 1; i <= lines; i++) { - let id = 'line' + i; - - let btn = elem('a', { href: '#' + id }, i); - btn.style.paddingRight = charWidth - 1 + 'px'; - btn.addEventListener('click', onClick); - - let linenum = elem('div', { id, class: 'linenum hljs' }, btn); - linenum.style.width = width + 'px'; - linenums.push(linenum); - r.appendChild(linenum); - } - pre.appendChild(r); - } - - const onClick = function (ev) { - ev.preventDefault(); - document.location = this.href; - selectLine(); - } - - const selectLine = () => { - let hash = document.location.hash; - if (!hash) return; - for (let i = 0; i < linenums.length; i++) { - let linenum = linenums[i]; - if (linenum.id == hash.substring(1)) linenum.setAttribute('data-selected', 1); - else linenum.removeAttribute('data-selected'); - } - } - - q('.prettyprint code').forEach(HLJS.highlightElement); - q('.prettyprint.linenums').forEach(linenumify); - - selectLine(); - } - - // start window scroll watcher - sw.watch(['init', 'scroll']); - - }); // DOM setup - - debug.log('script done'); - -})(); // END diff --git a/_src/styles/base.less b/_src/styles/base.less deleted file mode 100644 index 64980e2..0000000 --- a/_src/styles/base.less +++ /dev/null @@ -1,150 +0,0 @@ -:root, body { - .h(100%); - // scroll-behavior: smooth; - // overscroll-behavior: none; -} - -:root { - .fs(@fs-base); - scroll-padding-top: @topbar-h; -} - -body { - .bare; - .fs(@fs-m; @lh-base); - .ff(var(--font-body)); - .c(var(--c-text)); - .bg-c(var(--c-theme)); - - // [@FIX:iOS] Prevent iOS browser from making texts too large - -webkit-text-size-adjust: none; - text-size-adjust: none; -} - -* { - outline-style: none; -} - -h1, h2, h3, h4, h5, h6 { - .lh(1.25); -} -h2, h3, h4, h5, h6 { - .my(2em; .5em); -} -h1 { - .fs(@fs-xl); -} -h2, h3 { - .fs(@fs-l); -} -h4, h5, h6 { - .fs(@fs-m); -} - -a { - .no-deco; - .trans(color; .25s; ease-out); - - &, &:link, &:visited, &:active { - .c(inherit); - } -} - -p { - &:first-child { - .mt(0); - } - &:last-child { - .mb(0); - } -} - -small { - .fs(@fs-s); -} - -sub, sup { - .fs(@fs-s); -} - -tt, code, kbd, samp { - .fs(@fs-s); - .ff(var(--font-code)); -} - -pre { - -moz-tab-size: 4; - tab-size: 4; -} - -hr { - .my(@gutter*2; @gutter); -} - -ol, ul { - &:first-child { .mt(0); } - // &:last-child { .mb(0); } -} - -ul { - .pl(1em); - .no-bullets; - - li { - .pos(relative); - - // list bullet - &::before { - .empty; - .block; - .dim(.38em; 1px; border-box); - .bt(1px solid); - .pos-tl(.7em; -.75em; absolute); - .op(.5); - } - } -} - -table { - border-spacing: 0; - border-collapse: collapse; - - h3, h4, h5, h6 { - .mt(1em); - } - table { - .mb(.5em); - } -} -th, -thead { - .bold; - .fs(@fs-s); -} -td, th { - .p(.5rem 1rem); - .v-align(text-top); - .align(left); - - &:first-child { - .align(right); - } - td, th { - .p(.5rem); - } -} -td { - h4, h5, h6 { - &:first-child { - .mt(0); - } - } -} - -figure { - .m(0); // cancel the browser style -} - -*[data-ready="0"] { - .hidden; -} diff --git a/_src/styles/components.less b/_src/styles/components.less deleted file mode 100644 index 3e2a985..0000000 --- a/_src/styles/components.less +++ /dev/null @@ -1,94 +0,0 @@ -// scrollable table wrapper -.table-wrap { - .of(auto); - - .table-wrap { - .of(initial); - } -} - -// code highlighter -.prettyprint { - .pos(relative); - .w(auto); - .of(auto); - .fs(@fs-s; 1.5); - .round(.5rem); - .ff(var(--font-code)); - - ._char { // for measuring char width - .pos-tl(0; 0; absolute); - .op(0); - } - code { - .block; - .py(.5em) !important; - .px(1em); - } - .linenums { - .pos-tl(0; 0; absolute); - - .linenum { - .border-box; - .op(.9); - - &:first-child { .pt(.5em); } - &:last-child { .pb(.5em); } - - a { - .block; - .br(solid 1px); - .align(right); - .no-deco; - .c(inherit); - .op(.35); - - &:hover, &:focus { - .op(.75); - } - } - - &[data-selected] { - - a { - .op(1); - } - } - } - } - &.has-caption { - @capt-h: 2.5em; - - // @example ... - .code-caption { - .ff(var(--font-body)); - .block; - .pos-tl(0; 0; absolute); - .w(100%; border-box); - .px(1em); - .oneline(@capt-h; auto); - .no-scrollbar; - .align(right); - - .bg-c(var(--c-code-capt)); - .stripes(var(--stripes-angle); var(--c-code-capt-stripe1); var(--c-code-capt-stripe2); 1px; 3px); - } - code { - .pt((@capt-h + .5em)) !important; - } - } -} - -.icon { - .pos(relative); - .iblock; - .v-align(middle); - - svg& { - stroke: currentColor; - stroke-width: 2; - stroke-linecap: round; - stroke-linejoin: round; - fill: none; - } -} diff --git a/_src/styles/content.less b/_src/styles/content.less deleted file mode 100644 index a862ca3..0000000 --- a/_src/styles/content.less +++ /dev/null @@ -1,265 +0,0 @@ -h1, h2, h3, h4, h5, h6 { - .c(var(--c-heading)); - - a { - .c(var(--c-heading-link)); - - &:hover, &:focus { - .c(var(--c-heading-link-hov)); - } - &:visited { - .c(var(--c-heading-link-vis)); - } - } -} - -a { - .c(var(--c-link)); - overflow-wrap: break-word; - - &:hover, &:focus { - .c(var(--c-link-hov)); - .underline; - } - &:visited { - .c(var(--c-link-vis)); - } - code { - .c(inherit); - } -} - -code:not(.hljs) { - .px(.25em); - .c(var(--c-code)); -} - -table { - .bb(4px solid var(--c-table-border); 1px solid var(--c-table-border)); -} -tr { - + tr > * { - .bt(1px solid var(--c-table-border)); - } -} -td + td, -th + th, -th + td { - .bl(1px dashed var(--c-table-border)); -} -td + th { - .bl(1px solid var(--c-table-border)); -} -thead { - .c(var(--c-thead-text)); - - > tr { - .bg-c(var(--c-thead)); - .stripes(var(--stripes-angle); var(--c-thead-stripe1); var(--c-thead-stripe2); 1px; 3px); - - > * + * { - .bl(none); - } - } -} - -dl { - .dl-side-by-side(fit-content(6rem); (@gutter * .25) (@gutter * .5)); - .my((@gutter * .5); 0); - .bl(1px solid var(--c-border-thin)); - .pl(@gutter); - .of(auto); - - &:empty { - .no-disp; - } - &.details { - .mt(@gutter); - } -} -dt { - .fs(@fs-s; 1.25); - .py(.25em); - .align(right); - white-space: nowrap; - .c(var(--c-text-thin)); -} -dd { - // return type - &.type { - .ff(var(--font-code)); - } -} - -hr { - .bt(var(--border-style) var(--c-border); none); -} - -img, -video, -iframe { - .w-max(100%); -} - -blockquote { - .ml(0); - .pl(@gutter); - .bl(1px solid var(--c-border-thin)); -} - -article { - .m(@gutter); - .w-max(960px); - .of(hidden); - - &.readme { - &:first-child { - .mt((@gutter * 2)); - } - h1 { - .fs(@fs-xl); - } - h2, h3 { - .fs(@fs-l); - } - h2 { - .subsection-title; - } - h4, h5, h6 { - .fs(@fs-m); - } - pre > code { - .fs(@fs-s); - } - } - &.src { - .w-max(1280px); - - .prettyprint { - .m(0); - } - } - &.tutorial { - // TODO - } -} - -// class overview -.container-overview { - - // "Constructor" heading - h2 { - .subsection-title; - } -} - -// method parameters -.signature { - .ml(.5em); - .ff(var(--font-code)); - .fs(@fs-m); - - .signature-attributes { - .tag; - .ml(.25em); - .c(var(--c-params-attr-text)); - } -} - -// class name in header -h2.name { - .signature { - .signature-attributes { - .bg-c(var(--c-heading)); - } - } -} - -// member name -h4.name { - .mt((@gutter * 2)); - .pt(@gutter); - .bt(var(--border-style) var(--c-border)); - .regular; - .ff(var(--font-code)); - .lh(1.5); - .c(var(--c-member)); - - // 'static', 'abstract', 'readonly', etc. - .attribute { - .tag; - .mr(.25rem); - .bg-c(var(--c-member-attr)); - .c(var(--c-member-attr-text)); - - &:last-child { - .mr(.5rem); - } - } - // parameters - .signature { - .c(var(--c-params)); - - .signature-attributes { - .bg-c(var(--c-params-attr)); - } - } - // type - .type-signature { - .c(var(--c-text-thin)); - - .type { - &::before, - &::after { - .op(.5); - } - &::before { - content: "<"; - .pr(.1em); - } - &::after { - content: ">"; - .pl(.1em); - } - .sep { - .op(.5); - .mx(.25em); - .bl(1px solid); - } - } - a { - .c(var(--c-link)); - } - } -} - -h4.name:first-of-type, -.subsection-title + h4.name { - .mt(0); - .bt(none); -} - -// "Members", "Methods" headings -.subsection-title { - .mt((@gutter * 3)); - .heading; -} - -td { - &.name, - &.type, - &.default { - .ff(var(--font-code)); - .fs(@fs-s); - } - i.attribute { - .tag; - .v-align(middle); - .bg-c(var(--c-params-attr)); - .c(var(--c-params-attr-text)); - - + i.attribute { - .ml(.25em); - } - } -} diff --git a/_src/styles/fonts.less b/_src/styles/fonts.less deleted file mode 100644 index e69de29..0000000 diff --git a/_src/styles/main.less b/_src/styles/main.less deleted file mode 100644 index d939710..0000000 --- a/_src/styles/main.less +++ /dev/null @@ -1,605 +0,0 @@ -@charset "utf-8"; - -/*! - * Style for docolatte - * @author Satoshi Soma (amekusa.com) - * - * Copyright 2020 Satoshi Soma - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@import "util"; -@import "vars"; -@import "fonts"; -@import "base"; -@import "mixins"; -@import "components"; - -@import (less) "skin.css"; - -.site { - .pos(relative; 0); - .wh(100%); - .w-min(320px); -} - -.header { - .flex; - .pos-tl(0; 0; fixed; @z-header); - .dim(100%; @topbar-h; border-box); - .of(hidden); - .c(var(--c-header-text)); - - .masthead { - flex-shrink: 0; // No shrink - .flex; - .dim(@sidebar-w; 100%; border-box); - .bg-c(var(--c-header)); - .fs(@fs-l; 1); - .regular; - - .link, - .title { - .h(100%); - .trans(color, background-color; .25s; ease-out); - - &:hover, &:focus { - .c(var(--c-header-text-hov)); - .bg-c(var(--c-header-hov)); - } - } - .link { - flex-shrink: 0; - .flex-center; - .w(@topbar-h); - - svg.icon { - .wh(1.25em); - } - } - .title { - flex-grow: 1; - .flex-center-y; - // justify-content: right; // Doesn't work on Chrome :( - justify-content: flex-end; // This works on Chrome :) - .px(@gutter); - } - } - .topbar { - @shadow: 0 .05em .25em #000f; - flex-grow: 1; // Grows - .flex-center-y; - .dim(auto; 100%; border-box); - .px(@gutter); - .bg-c(var(--c-topbar)); - .stripes(var(--stripes-angle); var(--c-topbar-stripe1); var(--c-topbar-stripe2); 1px; 2px); - text-shadow: @shadow; - backdrop-filter: var(--topbar-filter); - - svg { - filter: drop-shadow(@shadow); - } - .page-title { - flex-grow: 1; - .m(0); - .fs(@fs-l; 1); - .regular; - } - .light-switch { - flex-grow: 0; - .block; - - .label { - .no-disp; - } - &[data-state="auto"] { - .label.auto { .block; } - } - &[data-state="light"] { - .label.light { .block; } - } - &[data-state="dark"] { - .label.dark { .block; } - } - } - } -} - -.primary { - .pos(relative); - .w(100%; border-box); - .h-min(100%); - .py(@topbar-h; @footer-h + @gutter * 2); - .px(@sidebar-w; 0); - .bg-c(var(--c-backdrop)); - - .config.no-footer & { - .pb(@gutter * 4); - } -} - -.main { - @import "content"; -} - -.footer { - .fs(@fs-m); - .dim(100%; auto; border-box); - .h-max(@footer-h); - .pos-br(0; 0; absolute); - .pl(@sidebar-w); - .c(var(--c-footer-text)); - .bg-c(var(--c-footer)); - .stripes(var(--stripes-angle); var(--c-footer-stripe1); var(--c-footer-stripe2); 1px; 4px); - .bg-fixed; - - .config.no-footer & { - .bg(none); - } - - .lines { - .p-b(@gutter); - - a { - .c(var(--c-footer-link)); - - &:hover, &:focus { - .c(var(--c-footer-link-hov)); - } - } - p { - .m(0); - } - } - .copyright, - .license { - .lh(1.25); - } - .copyright { - .bold; - } - .generator { - .fs(@fs-xs); - } - .license + .generator { - .mt((@gutter * .5)); - } - .bottom { - .pos(relative); - .h((@bottom-h + @gutter)); - .c(var(--c-bottom-text)); - .of(hidden); - - &::before { // background - .empty; - .pos-bl(0; 0; absolute; 0); - .block; - .dim(100%; @bottom-h); - .bg-c(var(--c-bottom)); - } - .to-top { // button - @size: 10em; - .pos(relative; 1); - .block; - .dim(@size; @size; border-box); - .mt(@gutter); - .mx(auto); - .pt(0); - .round(50%); - .align(center); - .bg-c(var(--c-bottom)); - .c(var(--c-bottom-text)); - .ff(var(--font-heading)); - .trans(margin-top, padding-top, color, background-color; .25s; ease-out); - - &:hover, &:focus { - .mt(0); - .pt(@gutter * .5); - .bg-c(var(--c-bottom-hov)); - .c(var(--c-bottom-text-hov)); - } - .label { - .h(@bottom-h); - .flex-center; - .no-hover; - } - .icon { - .wh(1.25em); - .ml(.25em); - .op(.5); - } - } - } -} - -.sidebar { - .fs(@fs-m); - .pos-tl(0; 0; fixed; @z-sidebar); - .dim(@sidebar-w; 100%; border-box); - .of(hidden); - .bg-c(var(--c-sidebar)); - -webkit-overflow-scrolling: touch; // momentum scrolling for mobile - - .wrap { - .pos-bl(0; 0; absolute); - .dim(100%; calc(100% - @topbar-h); border-box); - .p-b(@gutter; @gutter * 2); - .of(hidden auto); - - .config.sidebar-h-scroll & { - .of-x(auto); - } - } - .toc { - .menu { - .mt(@gutter); - } - h3 { - .fs(unit(@fs-xs, em)); - .ff(var(--font-toc-heading)); - .regular; - .uppercase; - .ls(.15em); - .align(right); - .c(var(--c-toc-heading)); - } - ul { - .pl(0); - .m(0); - .no-bullets; - .ff(var(--font-toc-item)); - - li { - &::before { - .remove; // remove pseudo bullet - } - &.has-child { - + li { - .mt(@gutter * .5); - } - } - } - a { - .pos(relative); - .iblock; - .lh(1.25); - .py(.33em); - .mr(@gutter); - .c(var(--c-toc-link)); - .trans(padding-left, color; .25s; ease-out); - - overflow-wrap: break-word; - word-break: break-word; - - .config.sidebar-h-scroll & { - overflow-wrap: normal; - word-break: normal; - } - - &:hover, &:focus { - .c(var(--c-toc-link-hov)); - } - // highlight border - &::after { - .empty; - .pos-tl(0; -@gutter; absolute); - .block; - .dim(0; 100%; content-box); - .br(0 solid); - .op(.5); - .trans(opacity, border-right-width; .25s; ease-out); - } - &:hover, &:focus, - &[data-current] { - &::after { - border-right-width: .33em; - } - } - &[data-current] { - .c(var(--c-toc-link-sel)); - .pl(.25em); - .bold; - - &::after { - .op(1); - } - } - } - - // variables, functions - ul { - .ff(var(--font-toc-member)); - .regular; - - a { - --c-hl: inherit; // highlight color - .pl(1.25em); - - &[data-current] { - .pl(1.5em); - } - &::after { - border-color: var(--c-hl); - } - } - &.variables { - --c-hl: var(--c-icon-variable); - } - &.functions { - --c-hl: var(--c-icon-function); - } - &.has-icons { - @icon-size: 1em; - - a { - // icon - &::before { - .pos-tl(.45em; 0; absolute); - .block; - .wh(@icon-size); - .lh(@icon-size); - .of(hidden); - .mr(.25em); - .round(.5em); - .align(center); - .bg-c(var(--c-hl)); - .c(var(--c-sidebar)); - .regular; - .fw(var(--bold-in-dark)); - .ff(Georgia, serif;); - .trans(left; .25s; ease-out); - } - &[data-current] { - &::before { - left: .25em; - } - } - } - &.variables { - a { - &::before { - content: "v"; - .roman; - } - } - } - &.functions { - a { - &::before { - content: "ƒ"; - .italic; - } - } - } - } - } - } - } - .search-box { - @h: 1.75em; - .pos(relative); - - input[type=text] { - .pos(relative); - .block; - .fs(unit(@fs-m, em)); - .dim(100%; @h; border-box); - .px(.75em; 2em); - .b(none); - .round((@h / 2)); - - .c(var(--c-search-text)); - .bg-c(var(--c-search)); - - &::placeholder { - .c(var(--c-search-ph)); - } - &:focus ~ .dropdown { - .visible; - } - + .icon { - .wh(1em); - .pos-tr(.35em; .5em; absolute); - .c(var(--c-search-icon)); - } - } - .dropdown { - .no-bullets; - .pos-tl(@h + .5em; 0; absolute; (@z-sidebar + 2)); - .w-max(100%); - .of(hidden); - .m(0); - .p(0); - .bg-c(var(--c-dropdown)); - .round(.5em); - box-shadow: .1em .2em .4em var(--c-dropdown-shadow); - - .hidden; - transition: visibility .25s; // needs delay for touch devices (because no :hover) - - &:hover { - .visible; - } - li { - .ff(var(--font-code)); - .fs(unit(@fs-s, em); 1.5); - - > a { - .block; - .p(.5em .75em); - overflow-wrap: break-word; - .c(var(--c-dropdown-text)); - transition: none; - - > i.symbol { - .op(.33); - .roman; - } - } - > a:hover, - > a:focus { - .bg-c(var(--c-dropdown-hov)); - .c(var(--c-dropdown-text-hov)); - } - &.selected > a { - .bg-c(var(--c-dropdown-sel)); - .c(var(--c-dropdown-text-sel)); - } - + li > a { - .bt(1px solid var(--c-dropdown-border)); - } - } - } - .hint { // speech bubble - .fs(unit(@fs-s, em); 1.25); - .pos-r(0; absolute; @z-sidebar+1); - .mt(.5em); - .p(.5em .75em); - .round(.38em); - .bg-c(var(--c-hint)); - .c(var(--c-hint-text)); - box-shadow: .1em .2em .4em var(--c-hint-shadow); - - &::before { // tail - @w: 1em; - @h: .62em; - .empty; - .block; - .pos-tl(calc(-@h + 1px); 1.5em; absolute); - .dim(0; 0; content-box); - .by(none; @h solid var(--c-hint)); - .bx((@w / 2) solid transparent); - } - &.hidden { - .no-disp; - } - .icon { - .wh(1.25em); - .v-align(bottom); - .c(var(--c-link)); - } - em { - .bold; - .roman; - .underline; - } - } - } -} - -input#docolatte-sidebar-toggle, -.menu-button { - .no-disp; -} -.menu-button { - @size: @menu-btn-size; - .wh(@size); - .pos-br(@gutter; @gutter; fixed; @z-header+10); - cursor: pointer; - - // [@FIX:iOS] Remove rectangle highlight on touch - -webkit-tap-highlight-color: transparent; - - > .shape { - .flex-center; - .overlay(auto); - .round(50%); - box-shadow: 0 .1rem .4rem var(--c-menu-btn-shadow); - transition: all .25s ease-out; - .bg-c(var(--c-menu-btn)); - - .icon { - &.burger { - .dim(26px; 20px); - - .top, .middle, .bottom { - .block; - .pos-l(0; absolute); - .dim(26px; 4px); - .round(2px); - .bg-c(var(--c-menu-btn-icon)); - } - .top { top: 0 } - .middle { top: 8px } - .bottom { top: 16px } - } - } - } - // *boop* - &:active { - > .shape { - transform: scale(.8, .8); - transition: all .05s ease-out; - box-shadow: 0 .1rem .2rem var(--c-menu-btn-shadow); - } - } -} -.overlay, -.overlay::before { - .block; - .pos-tl(0; 0); - .wh(100%); -} -.overlay { - .pos(fixed; -1); // hidden behind the entire page - - // actual overlay - &::before { - .empty; - .pos(absolute; auto); - .bg-c(black); - .op(0); - transition: opacity .25s ease-out; - } -} - -@media only screen { - @media (max-width: 1440px) { - .main article.src { - .m((@gutter * .5)); - } - } - - @media (max-width: 1280px) { - :root { - .fs(16px); - } - } - - @media (max-width: 1024px) { - :root { - .fs(15px); - } - .main article.src { - .m(0); - - .prettyprint { - .round(0); - } - } - } - - @media (max-width: 828px) { - :root { - .fs(14px); - } - .main { - td, th { - .p(.5rem); - } - } - } - - @import "mobile"; -} diff --git a/_src/styles/mixins.less b/_src/styles/mixins.less deleted file mode 100644 index 07e1bfc..0000000 --- a/_src/styles/mixins.less +++ /dev/null @@ -1,23 +0,0 @@ -// general heading style -.heading() { - .bl(.35em solid); - .pt(.1em); - .pl(.75em); - .lh(1); - .ff(var(--font-heading)); - .regular; - text-transform: uppercase; - letter-spacing: .12em; -} - -.tag() { - .iblock; - .fs(@fs-xs); - .regular; - .roman; - .px(.5em); - .round(.25em); - .v-align(15%); - .lh(1.25); - .fw(var(--bold-in-dark)); -} diff --git a/_src/styles/mobile.less b/_src/styles/mobile.less deleted file mode 100644 index cd53f31..0000000 --- a/_src/styles/mobile.less +++ /dev/null @@ -1,175 +0,0 @@ -@media (max-width: 680px) { - @masthead-h: (@topbar-h * 1.618); - @bottom-h: (@gutter * 3); - - .not-for-mobile { - .no-disp !important; - } - :root { - .fs(16px); - } - body { - .of(auto); - } - .header { - .block; - .of(visible); - .pos(absolute); - .h(auto); - - .masthead { - flex-direction: row-reverse; - .w(auto); - .h(@masthead-h); - .fs(@fs-xl); - - .link { - .w(@masthead-h); - } - .title { - justify-content: left; - } - } - .topbar { - .h(@topbar-h); - } - } - .primary, - .footer { - .pl(0); - } - .primary { - .w-min(320px); - .pt((@topbar-h + @masthead-h)); - } - .footer { - .bottom { - .h((@bottom-h + @gutter)); - - &::before { // background - .h(@bottom-h); - } - .to-top { // button - @size: 12em; - .wh(@size); - - .label { - .h(@bottom-h); - .fs(@fs-l); // this shouldn't affect height - } - } - } - } - - @sidebar-w2: 320px; - .sidebar { - .z((@z-header + 2)); - .pos-l(-100%); - .w(70%); - .w-min(@sidebar-w2); - transition: left .16s ease-out; - - .wrap { - .h(100%); - .fs(@fs-xl); - } - } - - // pop-up sidebar mechanic - input#docolatte-sidebar-toggle:checked { - ~ .sidebar { - .pos-l(0); - box-shadow: .5rem 0 .5rem var(--c-menu-shadow); - } - ~ .overlay { - .z((@z-header + 1)); - - &::before { - .op(.618); - } - } - ~ .menu-button { - > .shape { - .bg-c(var(--c-menu-btn-close)); - - .icon { - &.burger { - .a(count; 1); - - .top, .middle, .bottom { - .bg-c(var(--c-menu-btn-close-icon)); - transform: none; - transform-box: fill-box; - transform-origin: center; - .a(duration; .35s); - .a(curve; ease-out); - .a(count; inherit); - .a(fill-mode; forwards); - } - .top { .a(name; burger-top) } - .middle { .a(name; burger-middle) } - .bottom { .a(name; burger-bottom) } - - @k1: 45%; - @k2: 66%; - @keyframes burger-top { - @{k1}, @{k2} { transform: translateY(8px) } - 100% { transform: translateY(8px) rotateZ(45deg) } - } - @keyframes burger-middle { - @{k1}, @{k2} { transform: rotateZ(90deg) } - 100% { transform: rotateZ(135deg) } - } - @keyframes burger-bottom { - @{k1} { transform: translateY(-8px); opacity: 1 } - @{k2} { transform: translateY(-8px); opacity: 0 } - 100% { transform: translateY(-8px) rotateZ(45deg) } - } - } - } - } - } - } - .menu-button { - .block; - } -} - -@media (max-width: 512px) { - @_gutter: (@gutter / 2); - - .header { - .masthead { - .title { - .px(@_gutter); - } - } - .topbar { - .px(@_gutter); - } - } - .main { - article { - .mx(@_gutter); - } - } - .footer { - .lines { - .px(@_gutter); - } - } -} - -@media (max-width: 414px) { - :root { - .fs(15px); - } - .header { - .masthead { - .fs(@fs-l); - } - .topbar { - .fs(@fs-m); - } - } -} diff --git a/_src/styles/skin.css b/_src/styles/skin.css deleted file mode 100644 index 75e2bbd..0000000 --- a/_src/styles/skin.css +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Custom CSS properties for Docolatte - * - * ## How to customise - * 1. Copy this file (skin.css) to under your project directory, and edit it. - * 2. Import the file with `templates.docolatte.import` option in your JSDoc config JSON. - * - * Example JSON: - * { - * "templates": { - * "docolatte": { - * "import": [ - * "./skin.css" - * ] - * } - * } - * } - * - * ## TIPs - * - You can reference a property via `var()` from one another - */ -:root { - /* Fonts */ - --font-body: HelveticaNeue, Helvetica, Arial, sans-serif; - --font-heading: Avenir, "Century Gothic", var(--font-body); - --font-code: "Fira Code", "Source Code Pro", Menlo, "DejaVu Sans Mono", "Liberation Mono", Consolas, monospace; - --font-toc-heading: var(--font-heading); - --font-toc-item: var(--font-body); - --font-toc-member: var(--font-code); /* variables, functions */ - - /* Misc. */ - --border-style: 1px dashed; - --stripes-angle: 300deg; - --topbar-filter: blur(8px); - --bold-in-dark: normal; /* some texts should be bold in dark mode */ - - /* Colors */ - --c-theme: hsl(34, 23%, 88%); /* thematic color */ - --c-backdrop: white; /* background of the main content area */ - - --c-text: hsl(239, 4%, 31%); /* default text color */ - --c-text-thin: hsla(239, 21%, 47%, 0.5); /* opacity variant 1 */ - --c-text-thinner: hsla(239, 21%, 47%, 0.25); /* opacity variant 2 */ - - --c-heading: hsl(239, 21%, 47%); /* color */ - --c-heading-thin: hsla(239, 21%, 47%, 0.75); /* opacity variant 1 */ - --c-heading-thinner: hsla(239, 21%, 47%, 0.5); /* opacity variant 2 */ - --c-heading-link: var(--c-heading-thinner); /* link in */ - --c-heading-link-vis: var(--c-heading-link); /* :visited link */ - --c-heading-link-hov: var(--c-heading); /* :hover, :focus link */ - - --c-border: var(--c-text-thin); - --c-border-thin: var(--c-text-thinner); - - --c-link: hsl(200, 100%, 43%); - --c-link-vis: var(--c-link); /* :visited link */ - --c-link-hov: var(--c-link); /* :hover, :focus link */ - - --c-code: hsl(177, 70%, 41%); /* color */ - --c-code-capt: transparent; /* @example code caption */ - --c-code-capt-stripe1: hsla(0, 0%, 62%, 0.25); - --c-code-capt-stripe2: hsla(0, 0%, 62%, 0.1); - - --c-member: hsl(330, 100%, 71%); /* methods and properties */ - --c-member-attr: var(--c-member); /* member attributes ("static", "readonly", etc.) */ - --c-member-attr-text: var(--c-backdrop); - --c-params: hsl(355, 100%, 86%); /* method parameters */ - --c-params-attr: hsl(28, 100%, 70%); /* parameter attributes ("opt", "nullable", "non-null") */ - --c-params-attr-text: var(--c-backdrop); - - --c-table-border: var(--c-theme); - --c-thead: transparent; - --c-thead-stripe1: var(--c-theme); - --c-thead-stripe2: var(--c-backdrop); - --c-thead-text: var(--c-text); - - /* Header */ - --c-header: hsl(34, 3%, 26%); - --c-header-text: white; - --c-header-hov: var(--c-heading); - --c-header-text-hov: white; - --c-topbar: transparent; - --c-topbar-stripe1: hsla(34, 3%, 26%, 0.75); - --c-topbar-stripe2: hsla(34, 3%, 26%, 0.5); - - /* Footer */ - --c-footer: transparent; - --c-footer-stripe1: var(--c-theme); - --c-footer-stripe2: var(--c-backdrop); - --c-footer-text: hsl(0, 9%, 62%); - --c-footer-link: var(--c-link); - --c-footer-link-hov: var(--c-link-hov); - --c-bottom: var(--c-theme); - --c-bottom-text: var(--c-footer-text); - --c-bottom-hov: var(--c-heading); - --c-bottom-text-hov: white; - - /* Sidebar */ - --c-sidebar: var(--c-theme); - --c-toc-heading: var(--c-text-thin); - --c-toc-link: var(--c-heading); - --c-toc-link-hov: var(--c-toc-link); - --c-toc-link-sel: var(--c-toc-link-hov); - --c-icon-variable: var(--c-params-attr); - --c-icon-function: var(--c-member); - - /* Search Box */ - --c-search: var(--c-backdrop); - --c-search-text: var(--c-text); - --c-search-ph: var(--c-text-thin); /* placeholder */ - --c-search-icon: var(--c-text-thinner); /* magnifier icon */ - --c-dropdown: var(--c-search); - --c-dropdown-text: var(--c-heading-thin); - --c-dropdown-hov: var(--c-dropdown-text); - --c-dropdown-text-hov: var(--c-dropdown); - --c-dropdown-sel: var(--c-heading); - --c-dropdown-text-sel: var(--c-dropdown); - --c-dropdown-border: var(--c-border-thin); - --c-dropdown-shadow: hsla(0, 0%, 0%, 0.25); - --c-hint: black; - --c-hint-text: white; - --c-hint-shadow: hsla(0, 0%, 0%, 0.5); - - /* Only for mobile */ - --c-menu-btn: var(--c-sidebar); - --c-menu-btn-icon: var(--c-toc-link); - --c-menu-btn-close: var(--c-backdrop); - --c-menu-btn-close-icon: var(--c-text); - --c-menu-btn-shadow: hsla(0, 0%, 0%, 0.5); - --c-menu-shadow: hsla(0, 0%, 0%, 0.25); -} - -/** - * Dark theme - */ -:root[data-color-scheme="dark"] { - /* Misc. */ - --bold-in-dark: bold; /* some texts should be bold in dark mode */ - - /* Colors */ - --c-theme: hsl(239, 12%, 10%); /* thematic color */ - --c-backdrop: hsl(239, 12%, 12%); /* background of the main content area */ - - --c-text: hsl(239, 12%, 50%); /* default text color */ - --c-text-thin: hsla(239, 12%, 50%, 0.5); /* opacity variant 1 */ - --c-text-thinner: hsla(239, 12%, 50%, 0.3); /* opacity variant 2 */ - - --c-heading: hsl(239, 60%, 60%); /* color */ - --c-heading-thin: hsla(239, 60%, 60%, 0.75); /* opacity variant 1 */ - --c-heading-thinner: hsla(239, 60%, 60%, 0.5); /* opacity variant 2 */ - --c-heading-link: var(--c-heading-thinner); /* link in */ - --c-heading-link-vis: var(--c-heading-link); /* :visited link */ - --c-heading-link-hov: var(--c-heading); /* :hover, :focus link */ - - --c-border: var(--c-text-thin); - --c-border-thin: var(--c-text-thinner); - - --c-link: hsl(200, 100%, 43%); - --c-link-vis: var(--c-link); /* :visited link */ - --c-link-hov: var(--c-link); /* :hover, :focus link */ - - --c-code: hsl(177, 70%, 41%); /* color */ - --c-code-capt: transparent; /* @example code caption */ - --c-code-capt-stripe1: hsla(0, 0%, 67%, 0.25); - --c-code-capt-stripe2: hsla(0, 0%, 67%, 0.1); - - --c-member: hsl(320, 80%, 45%); /* methods and properties */ - --c-member-attr: var(--c-member); /* member attributes ("static", "readonly", etc.) */ - --c-member-attr-text: var(--c-backdrop); - --c-params: hsl(320, 20%, 40%); /* method parameters */ - --c-params-attr: hsl(10, 30%, 50%); /* parameter attributes ("opt", "nullable", "non-null") */ - --c-params-attr-text: var(--c-backdrop); - - --c-table-border: var(--c-text-thinner); - --c-thead: transparent; - --c-thead-stripe1: var(--c-table-border); - --c-thead-stripe2: var(--c-backdrop); - --c-thead-text: var(--c-text); - - /* Header */ - --c-header: hsl(239, 12%, 14%); - --c-header-text: hsl(239, 12%, 70%); - --c-header-hov: hsl(239, 25%, 35%); - --c-header-text-hov: white; - --c-topbar: transparent; - --c-topbar-stripe1: hsla(239, 12%, 25%, 1); - --c-topbar-stripe2: hsla(239, 12%, 25%, 0); - - /* Footer */ - --c-footer: transparent; - --c-footer-stripe1: var(--c-text-thinner); - --c-footer-stripe2: var(--c-backdrop); - --c-footer-text: var(--c-text); - --c-footer-link: var(--c-link); - --c-footer-link-hov: var(--c-link-hov); - --c-bottom: var(--c-theme); - --c-bottom-text: var(--c-footer-text); - --c-bottom-hov: var(--c-heading); - --c-bottom-text-hov: white; - - /* Sidebar */ - --c-sidebar: var(--c-theme); - --c-toc-heading: var(--c-text-thin); - --c-toc-link: var(--c-heading); - --c-toc-link-hov: var(--c-toc-link); - --c-toc-link-sel: var(--c-toc-link-hov); - --c-icon-variable: var(--c-params-attr); - --c-icon-function: var(--c-member); - - /* Search Box */ - --c-search: hsl(239, 12%, 16%); - --c-search-text: var(--c-text); - --c-search-ph: var(--c-text); /* placeholder */ - --c-search-icon: var(--c-text-thin); /* magnifier icon */ - --c-dropdown: var(--c-search); - --c-dropdown-text: var(--c-heading); - --c-dropdown-hov: var(--c-heading-thinner); - --c-dropdown-text-hov: white; - --c-dropdown-sel: var(--c-heading-thin); - --c-dropdown-text-sel: white; - --c-dropdown-border: hsla(239, 12%, 50%, 0.15); - --c-dropdown-shadow: hsla(0, 0%, 0%, 0.25); - --c-hint: black; - --c-hint-text: white; - --c-hint-shadow: hsla(0, 0%, 0%, 0.5); - - /* Only for mobile */ - --c-menu-btn: var(--c-sidebar); - --c-menu-btn-icon: var(--c-toc-link); - --c-menu-btn-close: var(--c-backdrop); - --c-menu-btn-close-icon: var(--c-text); - --c-menu-btn-shadow: hsla(0, 0%, 0%, 0.5); - --c-menu-shadow: hsla(0, 0%, 0%, 0.25); -} diff --git a/_src/styles/util.less b/_src/styles/util.less deleted file mode 100644 index 7392c47..0000000 --- a/_src/styles/util.less +++ /dev/null @@ -1,500 +0,0 @@ -// ---- Misc. ---- - -.c(@color) { color: @color } -.op(@opacity) { opacity: @opacity } -.align(@text-align) { text-align: @text-align } -.empty() { content: "" } -.remove() { content: none } -.no-hover() { pointer-events: none } -.no-bullets() { list-style-type: none } - -.no-deco() { text-decoration: none } -.underline() { text-decoration: underline } - -.hidden() { visibility: hidden } -.visible() { visibility: visible } - -.v-align(@v-align) { vertical-align: @v-align } - -.of(@overflow) { - overflow: @overflow; -} -.of-x(@overflow-x) { overflow-x: @overflow-x } -.of-y(@overflow-y) { overflow-y: @overflow-y } -.tof(@text-overflow) { text-overflow: @text-overflow } -.ellipsis() { text-overflow: ellipsis } - - -// ---- Background ---- - -.bg(@background) { background: @background } -.bg-c(@background-color) { background-color: @background-color } -.bg-img(@background-image) { background-image: @background-image } -.bg-fixed() { background-attachment: fixed } - - -// ---- Font ---- - -// font-family -.ff(@font-family) { font-family: @font-family } - -// font-size + line-height -.fs(@font-size; @lh: -) { - font-size: @font-size; - & when not(@lh = -) { line-height: @lh } -} - -// line-height -.lh(@line-height) { line-height: @line-height } - -// letter-spacing -.ls(@letter-spacing) { letter-spacing: @letter-spacing } - -// font-weight -.fw(@font-weight) { font-weight: @font-weight } -.thin() { font-weight: 100 } -.xlight() { font-weight: 200 } -.ex-light() { .xlight } -.light() { font-weight: 300 } -.regular() { font-weight: normal } // 400 -.bold() { font-weight: bold } // 700 -.xbold() { font-weight: 800 } -.ex-bold() { .xbold } -.black() { font-weight: 900 } -.xblack() { font-weight: 950 } -.ex-black() { .xblack } -.lighter() { font-weight: lighter } -.bolder() { font-weight: bolder } - -// font-style -.roman() { font-style: normal } -.italic() { font-style: italic } -.oblique() { font-style: oblique } - -// capitalization style -.caps(@font-variant-caps) { font-variant-caps: @font-variant-caps } -.smallcaps() { font-variant-caps: small-caps } -.capitalize() { text-transform: capitalize } -.uppercase() { text-transform: uppercase } -.lowercase() { text-transform: lowercase } - - -// ---- Display ---- - -.nodisp() { display: none } -.no-disp() { .nodisp } -.inline() { display: inline } -.block() { display: block } -.iblock() { display: inline-block } -.inline-block() { .iblock } -.flex() { display: flex } - -.flex-center() { - display: flex; - align-items: center; - justify-content: center; -} -.flex-center-y() { - display: flex; - align-items: center; -} -.flex-center-x() { - display: flex; - justify-content: center; -} - -.grid(@grid: -) { - display: grid; - & when not(@grid = -) { grid: @grid } -} - -// Positioning -.z(@z-index) { z-index: @z-index } -.pos(@pos; @z: -) { - position: @pos; - & when not(@z = -) { z-index: @z } -} -.pos-t(@t; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - top: @t; -} -.pos-b(@b; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - bottom: @b; -} -.pos-l(@l; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - left: @l; -} -.pos-r(@r; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - right: @r; -} -.pos-tl(@t; @l; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - top: @t; - left: @l; -} -.pos-tr(@t; @r; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - top: @t; - right: @r; -} -.pos-bl(@b; @l; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - bottom: @b; - left: @l; -} -.pos-br(@b; @r; @pos: -; @z: -) { - & when not(@pos = -) { position: @pos } - & when not(@z = -) { z-index: @z } - bottom: @b; - right: @r; -} -.pos-center(@z: -) { - .pos(absolute; @z); - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; -} -.pos-center-y(@z: -) { - .pos(absolute; @z); - top: 0; - bottom: 0; - .my(auto); -} -.pos-center-x(@z: -) { - .pos(absolute; @z); - left: 0; - right: 0; - .mx(auto); -} - -// Dimension -.w(@w; @sizing: -) { - & when not(@sizing = -) { box-sizing: @sizing } - width: @w; -} -.h(@h; @sizing: -) { - & when not(@sizing = -) { box-sizing: @sizing } - height: @h; -} -.wh(@wh; @sizing: -) { .dim(@wh; @wh; @sizing) } -.dim(@w; @h; @sizing: -) { - .w(@w; @sizing); - .h(@h); -} -.w-max(@x) { max-width: @x } -.w-min(@x) { min-width: @x } -.h-max(@x) { max-height: @x } -.h-min(@x) { min-height: @x } - -.overlay(@z: -) { - .pos-tl(0; 0; absolute; @z); - .dim(100%; 100%; border-box); -} -.content-box() { box-sizing: content-box } -.border-box() { box-sizing: border-box } - -// Margin -.m(@m) { margin: @m } -.mt(@t; @others: -) { - & when (@others = -) { margin-top: @t } - & when not(@others = -) { margin: @t @others @others @others } -} -.mb(@b; @others: -) { - & when (@others = -) { margin-bottom: @b } - & when not(@others = -) { margin: @others @others @b @others } -} -.my(@y) { .my(@y; @y) } -.my(@t; @b) { - margin-top: @t; - margin-bottom: @b; -} -.ml(@l; @others: -) { - & when (@others = -) { margin-left: @l } - & when not(@others = -) { margin: @others @others @others @l } -} -.mr(@r; @others: -) { - & when (@others = -) { margin-right: @r } - & when not(@others = -) { margin: @others @r @others @others } -} -.mx(@x) { .mx(@x; @x) } -.mx(@l; @r) { - margin-left: @l; - margin-right: @r; -} -.m-t(@-t; @t: -) { - & when (@t = -) { - margin-bottom: @-t; - margin-left: @-t; - margin-right: @-t; - } - & when not(@t = -) { margin: @t @-t @-t @-t } -} -.m-b(@-b; @b: -) { - & when (@b = -) { - margin-top: @-b; - margin-left: @-b; - margin-right: @-b; - } - & when not(@b = -) { margin: @-b @-b @b @-b } -} -.m-l(@-l; @l: -) { - & when (@l = -) { - margin-top: @-l; - margin-bottom: @-l; - margin-right: @-l; - } - & when not(@l = -) { margin: @-l @-l @-l @l } -} -.m-r(@-r; @r: -) { - & when (@r = -) { - margin-top: @-r; - margin-bottom: @-r; - margin-left: @-r; - } - & when not(@r = -) { margin: @-r @r @-r @-r } -} - -// Padding -.p(@p) { padding: @p } -.pt(@t; @others: -) { - & when (@others = -) { padding-top: @t } - & when not(@others = -) { padding: @t @others @others @others } -} -.pb(@b; @others: -) { - & when (@others = -) { padding-bottom: @b } - & when not(@others = -) { padding: @others @others @b @others } -} -.py(@y) { .py(@y; @y) } -.py(@t; @b) { - padding-top: @t; - padding-bottom: @b; -} -.pl(@l; @others: -) { - & when (@others = -) { padding-left: @l } - & when not(@others = -) { padding: @others @others @others @l } -} -.pr(@r; @others: -) { - & when (@others = -) { padding-right: @r } - & when not(@others = -) { padding: @others @r @others @others } -} -.px(@x) { .px(@x; @x) } -.px(@l; @r) { - padding-left: @l; - padding-right: @r; -} -.p-t(@-t; @t: -) { - & when (@t = -) { - padding-bottom: @-t; - padding-left: @-t; - padding-right: @-t; - } - & when not(@t = -) { padding: @t @-t @-t @-t } -} -.p-b(@-b; @b: -) { - & when (@b = -) { - padding-top: @-b; - padding-left: @-b; - padding-right: @-b; - } - & when not(@b = -) { padding: @-b @-b @b @-b } -} -.p-l(@-l; @l: -) { - & when (@l = -) { - padding-top: @-l; - padding-bottom: @-l; - padding-right: @-l; - } - & when not(@l = -) { padding: @-l @-l @-l @l } -} -.p-r(@-r; @r: -) { - & when (@r = -) { - padding-top: @-r; - padding-bottom: @-r; - padding-left: @-r; - } - & when not(@r = -) { padding: @-r @r @-r @-r } -} - -// Border -.b(@b) { border: @b } -.bt(@t; @others: -) { - border-top: @t; - & when not(@others = -) { - border-bottom: @others; - border-left: @others; - border-right: @others; - } -} -.bb(@b; @others: -) { - border-bottom: @b; - & when not(@others = -) { - border-top: @others; - border-left: @others; - border-right: @others; - } -} -.by(@y) { .by(@y; @y) } -.by(@t; @b) { - border-top: @t; - border-bottom: @b; -} -.bl(@l; @others: -) { - border-left: @l; - & when not(@others = -) { - border-top: @others; - border-bottom: @others; - border-right: @others; - } -} -.br(@r; @others: -) { - border-right: @r; - & when not(@others = -) { - border-top: @others; - border-bottom: @others; - border-left: @others; - } -} -.bx(@x) { .bx(@x; @x) } -.bx(@l; @r) { - border-left: @l; - border-right: @r; -} -.b-t(@-t; @t: -) { - & when not(@t = -) { border-top: @t } - border-bottom: @-t; - border-left: @-t; - border-right: @-t; -} -.b-b(@-b; @b: -) { - & when not(@b = -) { border-bottom: @b } - border-top: @-b; - border-left: @-b; - border-right: @-b; -} -.b-l(@-l; @l: -) { - & when not(@l = -) { border-left: @l } - border-top: @-l; - border-bottom: @-l; - border-right: @-l; -} -.b-r(@-r; @r: -) { - & when not(@r = -) { border-right: @r } - border-top: @-r; - border-bottom: @-r; - border-left: @-r; -} -.round(@rad) { border-radius: @rad } -.round-tl(@rad) { border-top-left-radius: @rad } -.round-tr(@rad) { border-top-right-radius: @rad } -.round-bl(@rad) { border-bottom-left-radius: @rad } -.round-br(@rad) { border-bottom-right-radius: @rad } -.round-t(@rad) { .round-t(@rad; @rad) } -.round-t(@l; @r) { - border-top-left-radius: @l; - border-top-right-radius: @r; -} -.round-b(@rad) { .round-b(@rad; @rad) } -.round-b(@l; @r) { - border-bottom-left-radius: @l; - border-bottom-right-radius: @r; -} -.round-l(@rad) { .round-l(@rad; @rad) } -.round-l(@t; @b) { - border-top-left-radius: @t; - border-bottom-left-radius: @b; -} -.round-r(@rad) { .round-r(@rad; @rad) } -.round-r(@t; @b) { - border-top-right-radius: @t; - border-bottom-right-radius: @b; -} - -.trans(@props: -; @duration: -; @easing: -; @delay: -) { - & when not(@props = -) { transition-property: @props } - & when not(@duration = -) { transition-duration: @duration } - & when not(@easing = -) { transition-timing-function: @easing } - & when not(@delay = -) { transition-delay: @delay } -} - -.bare() { - .m(0); - .p(0); - .b(0); -} - -.clearfix() { - &::after { - display: table; - clear: both; - } -} - -.oneline(@h; @overflow: hidden; @text-overflow: ellipsis) { - height: @h; - line-height: @h; - white-space: nowrap; - overflow: @overflow; - - & when (@overflow = hidden) { - text-overflow: @text-overflow; - } - br, wbr { - display: none; - } -} - -.no-scrollbar() { - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } -} - -.stripes(@angle; @color1; @color2; @c1-width; @c2-width: -) { - @c2w: if((@c2-width = -), @c1-width, @c2-width); - background-image: repeating-linear-gradient( - @angle, - @color2 0, - @color1 1px, - @color1 @c1-width, - @color2 (@c1-width + 1), - @color2 (@c1-width + @c2w) - ); -} - -// animation -.a(state; @value) { animation-play-state: @value } -.a(curve; @value) { animation-timing-function: @value } -.a(count; @value) { animation-iteration-count: @value } -.a(dir; @value) { animation-direction: @value } -.a(@prop; @value) when (default()) { - animation-@{prop}: @value; -} - -// columned definition list -.dl-side-by-side(@dt-width; @gap) { - .grid; - grid-template-columns: @dt-width auto; - gap: @gap; - - > dt { - grid-column: 1; - } - > dd { - grid-column: 2; - .m(0); // cancel the browser default style - } -} diff --git a/_src/styles/vars.less b/_src/styles/vars.less deleted file mode 100644 index 2ba7f7e..0000000 --- a/_src/styles/vars.less +++ /dev/null @@ -1,22 +0,0 @@ -// font sizes -@fs-base: 18px; -@fs-xxl: 2rem; -@fs-xl: 1.5rem; -@fs-l: 1.25rem; -@fs-m: 1rem; -@fs-s: .85rem; -@fs-xs: .7rem; - -// layout -@lh-base: 1.5; // line height -@gutter: 1.5rem; - -@topbar-h: 3rem; -@sidebar-w: 16rem; -@footer-h: 12rem; -@bottom-h: 3rem; -@menu-btn-size: 4rem; - -// z-index -@z-sidebar: 10; -@z-header: 20; diff --git a/index.html b/index.html index daf16ca..e155ea5 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ DOCOLATTE - + @@ -57,7 +57,7 @@

Docolatte

-

🍫 Bittersweet theme for JSDoc 3

+

🍫 Bittersweet theme for JSDoc 3 & 4

npm package

    @@ -109,6 +109,7 @@

    Docolatte<

    Docolatte v4 is out! 🎉

    New Features

      +
    • [NEW] Now it's fully compatible with JSDoc 4! (from Docolatte v4.3)
    • Finally, dark theme is implemented!
    • All the colors and fonts are now CSS variables, which means you can customize the overall look & feel of Docolatte just by overwriting the variables in your custom CSS. On top of that, you can customize light theme and dark theme separately.
    • A lot of design improvements
    • @@ -133,7 +134,7 @@

      Notes for users

      Is this compatible with JSDoc v4.x?

      -

      Search-indexing is partially not working with jsdoc@4.0.0. I recommend sticking with jsdoc v3.

      +

      Yes! Now it's fully compatible with JSDoc 4. JSDoc 3 is still supported as well.

      Screenshots

      Light Theme

      @@ -482,7 +483,7 @@

      Ordering imports

      </head>

      Customizing CSS Variables

      -

      All the CSS variables that Docolatte is using are defined in static/_src/styles/skin.css.
      +

      All the CSS variables that Docolatte is using are defined in src/styles/skin.css.
      To customize those variables, copy the file and import it. Then, edit the variable values as you like.

      License

      Docolatte is licensed under the Apache License 2.0.

      @@ -505,7 +506,7 @@

      License

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -546,13 +547,13 @@

      License

      - +
      - + \ No newline at end of file diff --git a/lib_Docolatte.js.html b/lib_Docolatte.js.html index 14600d4..49e1573 100644 --- a/lib_Docolatte.js.html +++ b/lib_Docolatte.js.html @@ -5,7 +5,7 @@ Source: lib/Docolatte.js | DOCOLATTE - + @@ -92,9 +92,10 @@

      }); } excludes = data({ ___id: excludes }); - if (excludes.count()) { + let found = excludes.get(); + if (found.length) { console.log('---- Excluded Entries ----'); - console.table(excludes.get(), ['___id', 'kind', 'longname', 'memberof']); + console.table(found, ['___id', 'kind', 'longname', 'memberof']); excludes.remove(); } } @@ -109,15 +110,16 @@

      } else if (!data({ longname: member.memberof, kind: { isString: true } - }).count()) { + }).get().length) { deadParents.push(member.memberof); orphans.push(member.___id); } }); orphans = data({ ___id: orphans }); - if (orphans.count()) { + let found = orphans.get(); + if (found.length) { console.log('---- Orphaned Members ----'); - console.table(orphans.get(), ['___id', 'kind', 'longname', 'memberof']); + console.table(found, ['___id', 'kind', 'longname', 'memberof']); orphans.remove(); } } @@ -400,7 +402,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -441,13 +443,13 @@

      - +
      - + diff --git a/lib_FileImporter.js.html b/lib_FileImporter.js.html index 3dea717..c080f7b 100644 --- a/lib_FileImporter.js.html +++ b/lib_FileImporter.js.html @@ -5,7 +5,7 @@ Source: lib/FileImporter.js | DOCOLATTE - + @@ -211,7 +211,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -252,13 +252,13 @@

      - +
      - + diff --git a/lib_Hooks.js.html b/lib_Hooks.js.html index 92c326c..9740a01 100644 --- a/lib_Hooks.js.html +++ b/lib_Hooks.js.html @@ -5,7 +5,7 @@ Source: lib/Hooks.js | DOCOLATTE - + @@ -125,7 +125,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -166,13 +166,13 @@

      - +
      - + diff --git a/lib_Nav.js.html b/lib_Nav.js.html index 599a128..012bf61 100644 --- a/lib_Nav.js.html +++ b/lib_Nav.js.html @@ -5,7 +5,7 @@ Source: lib/Nav.js | DOCOLATTE - + @@ -215,7 +215,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -256,13 +256,13 @@

      - +
      - + diff --git a/lib_SearchDB.js.html b/lib_SearchDB.js.html index d78f92a..3c5353d 100644 --- a/lib_SearchDB.js.html +++ b/lib_SearchDB.js.html @@ -5,7 +5,7 @@ Source: lib/SearchDB.js | DOCOLATTE - + @@ -141,7 +141,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -182,13 +182,13 @@

      - +
      - + diff --git a/lib_TmplUtil.js.html b/lib_TmplUtil.js.html index d6b3d83..4fb3456 100644 --- a/lib_TmplUtil.js.html +++ b/lib_TmplUtil.js.html @@ -5,7 +5,7 @@ Source: lib/TmplUtil.js | DOCOLATTE - + @@ -295,7 +295,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -336,13 +336,13 @@

      - +
      - + diff --git a/lib_Util.js.html b/lib_Util.js.html index 3169e97..fe87378 100644 --- a/lib_Util.js.html +++ b/lib_Util.js.html @@ -5,7 +5,7 @@ Source: lib/Util.js | DOCOLATTE - + @@ -167,20 +167,32 @@

      } /** * Converts the given value into a literal string. - * @param {any} x - Any type of value + * @param {any} x - Value to convert + * @param {object} [opts] - Options + * @param {string} opts.quote='"' - Quotation char for string values + * @param {boolean} opts.quoteKeys=true - Whether to quote object keys * @return {string} Literal string */ - toLiteral(x) { + toLiteral(x, opts = {}) { + let { quote = '"', quoteKeys = true } = opts; switch (typeof x) { case 'undefined': return 'undefined'; - case 'string': return `"${x}"`; - case 'boolean': return x ? 'true' : 'false'; + case 'string': return quote + x.replaceAll(quote, `\\${quote}`) + quote; + case 'boolean': return x ? 'true' : 'false'; + case 'number': return '' + x; case 'object': if (x === null) return 'null'; - if (Array.isArray(x)) return '[' + x.map(i => $.toLiteral(i)).join(',') + ']'; - return '{' + Object.keys(x).map(k => `"${k}":${$.toLiteral(x[k])}`).join(',') + '}'; + if (Array.isArray(x)) return '[' + x.map(i => $.toLiteral(i, opts)).join(',') + ']'; + return '{' + + Object.keys(x).map(k => { + let v = $.toLiteral(x[k], opts); + if (quoteKeys && typeof k == 'string') + k = quote + k.replaceAll(quote, `\\${quote}`) + quote; + return k + ':' + v; + }).join(',') + + '}'; } - return `${x}`; + throw `unsupported type: ${typeof x}`; } /** * Escapes regex's special characters in the given string. @@ -226,7 +238,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -267,13 +279,13 @@

      - +
      - + diff --git a/lib_icons.js.html b/lib_icons.js.html new file mode 100644 index 0000000..9233fc3 --- /dev/null +++ b/lib_icons.js.html @@ -0,0 +1,132 @@ + + + + + + + Source: lib/icons.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _/**
      + * Custom SVG icons.
      + * `{ATTRS}` should be replaced with proper attributes, or an empty string.
      + * @author amekusa
      + */
      +module.exports = {
      +
      +	'halfmoon': `
      +<svg {ATTRS} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      +	<path d="M 12 3 A 9 9 0 0 0 12 21 Z" stroke="none" fill="currentColor"/>
      +	<circle cx="12" cy="12" r="9"/>
      +</svg>`,
      +	/**
      +	 * NOTE: About SVG <path>:
      +	 * 'M x y' = Move to x y
      +	 * 'A rx ry 0 0 0 x y' = Draw arc to x y with radius rx ry
      +	 * 'Z' = Close the path
      +	 **/
      +
      +};
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/module-jsdoc_doclet.Doclet.html b/module-jsdoc_doclet.Doclet.html index 87d272b..93111d1 100644 --- a/module-jsdoc_doclet.Doclet.html +++ b/module-jsdoc_doclet.Doclet.html @@ -4,7 +4,7 @@ Class: Doclet | DOCOLATTE - + @@ -1244,7 +1244,7 @@

      Throws:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -1285,13 +1285,13 @@
      Throws:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_doclet.Doclet_meta.code.html b/module-jsdoc_doclet.Doclet_meta.code.html index 7524e31..66adbef 100644 --- a/module-jsdoc_doclet.Doclet_meta.code.html +++ b/module-jsdoc_doclet.Doclet_meta.code.html @@ -4,7 +4,7 @@ Namespace: code | DOCOLATTE - + @@ -191,7 +191,7 @@

      st

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -232,13 +232,13 @@

      st
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_doclet.Doclet_meta.html b/module-jsdoc_doclet.Doclet_meta.html index 7409a15..99b57c9 100644 --- a/module-jsdoc_doclet.Doclet_meta.html +++ b/module-jsdoc_doclet.Doclet_meta.html @@ -4,7 +4,7 @@ Namespace: meta | DOCOLATTE - + @@ -225,7 +225,7 @@

      st

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -266,13 +266,13 @@

      st
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_doclet.html b/module-jsdoc_doclet.html index cfe6d0c..4342050 100644 --- a/module-jsdoc_doclet.html +++ b/module-jsdoc_doclet.html @@ -4,7 +4,7 @@ Module: jsdoc/doclet | DOCOLATTE - + @@ -42,8 +42,6 @@

      - -
      @@ -51,6 +49,17 @@

      + + +
      +
      Source:
      +
      + node_modules/jsdoc/lib/jsdoc/doclet.js, line 1 +
      +
      + + +

      @@ -250,7 +259,7 @@
      Returns:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -291,13 +300,13 @@
      Returns:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_name.html b/module-jsdoc_name.html index 0a8fc65..1080558 100644 --- a/module-jsdoc_name.html +++ b/module-jsdoc_name.html @@ -4,7 +4,7 @@ Module: jsdoc/name | DOCOLATTE - + @@ -42,10 +42,6 @@

      - - - -
      @@ -55,20 +51,6 @@

      - - - - - - - - - - - - - -
      @@ -78,24 +60,6 @@

      - - - - - - - - - - - - - - - - - - @@ -1473,7 +1437,7 @@

      Returns:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -1514,13 +1478,13 @@
      Returns:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_schema.html b/module-jsdoc_schema.html index b0a02ba..bb60f2f 100644 --- a/module-jsdoc_schema.html +++ b/module-jsdoc_schema.html @@ -4,7 +4,7 @@ Module: jsdoc/schema | DOCOLATTE - + @@ -42,10 +42,6 @@

      - - - -
      @@ -55,20 +51,6 @@

      - - - - - - - - - - - - - -
      @@ -83,24 +65,6 @@

      - - - - - - - - - - - - - - - - - - @@ -143,7 +107,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -184,13 +148,13 @@

      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_tutorial-RootTutorial.html b/module-jsdoc_tutorial-RootTutorial.html index 1d638f8..1add874 100644 --- a/module-jsdoc_tutorial-RootTutorial.html +++ b/module-jsdoc_tutorial-RootTutorial.html @@ -4,7 +4,7 @@ Class: RootTutorial | DOCOLATTE - + @@ -382,7 +382,7 @@
      Returns:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -423,13 +423,13 @@
      Returns:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_tutorial-Tutorial.html b/module-jsdoc_tutorial-Tutorial.html index 8bea726..5267c7c 100644 --- a/module-jsdoc_tutorial-Tutorial.html +++ b/module-jsdoc_tutorial-Tutorial.html @@ -4,7 +4,7 @@ Class: Tutorial | DOCOLATTE - + @@ -625,7 +625,7 @@
      Parameters:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -666,13 +666,13 @@
      Parameters:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_tutorial.html b/module-jsdoc_tutorial.html index 8ce9985..d40b242 100644 --- a/module-jsdoc_tutorial.html +++ b/module-jsdoc_tutorial.html @@ -4,7 +4,7 @@ Module: jsdoc/tutorial | DOCOLATTE - + @@ -42,8 +42,6 @@

      - -
      @@ -51,6 +49,17 @@

      + + +
      +
      Source:
      +
      + node_modules/jsdoc/lib/jsdoc/tutorial.js, line 1 +
      +
      + + +

      @@ -207,7 +216,7 @@
      Properties:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -248,13 +257,13 @@
      Properties:
      - +
      - + \ No newline at end of file diff --git a/module-jsdoc_util_templateHelper.html b/module-jsdoc_util_templateHelper.html index 2648be4..6dfdbdf 100644 --- a/module-jsdoc_util_templateHelper.html +++ b/module-jsdoc_util_templateHelper.html @@ -4,7 +4,7 @@ Module: jsdoc/util/templateHelper | DOCOLATTE - + @@ -42,8 +42,6 @@

      - -
      @@ -51,6 +49,17 @@

      + + +
      +
      Source:
      +
      + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 1 +
      +
      + + +

      @@ -152,7 +161,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 863 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 870
      @@ -259,7 +268,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 948 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 955
      @@ -427,7 +436,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 839 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 846
      @@ -573,7 +582,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 809 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 816
      @@ -699,7 +708,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 675 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 682
      @@ -832,7 +841,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 638 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 645
      @@ -982,7 +991,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 755 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 762
      @@ -1129,7 +1138,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 781 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 788
      @@ -1275,7 +1284,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 731 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 738
      @@ -1572,7 +1581,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 1005 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 1012
      See:
      @@ -1708,7 +1717,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 910 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 917
      @@ -1832,7 +1841,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 594 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 601
      @@ -1956,7 +1965,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 522 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 529
      @@ -2522,7 +2531,7 @@
      Parameters:
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 622 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 629
      @@ -3110,7 +3119,7 @@
      Properties
      Source:
      - node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 471 + node_modules/jsdoc/lib/jsdoc/util/templateHelper.js, line 478
      To Do:
      @@ -3184,7 +3193,7 @@
      Returns:

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -3225,13 +3234,13 @@
      Returns:
      - +
      - + \ No newline at end of file diff --git a/node_modules_jsdoc_lib_jsdoc_doclet.js.html b/node_modules_jsdoc_lib_jsdoc_doclet.js.html index 6b49214..1f04586 100644 --- a/node_modules_jsdoc_lib_jsdoc_doclet.js.html +++ b/node_modules_jsdoc_lib_jsdoc_doclet.js.html @@ -5,7 +5,7 @@ Source: node_modules/jsdoc/lib/jsdoc/doclet.js | DOCOLATTE - + @@ -622,7 +622,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -663,13 +663,13 @@

      - +
      - + diff --git a/node_modules_jsdoc_lib_jsdoc_name.js.html b/node_modules_jsdoc_lib_jsdoc_name.js.html index 3d1ea97..2536b04 100644 --- a/node_modules_jsdoc_lib_jsdoc_name.js.html +++ b/node_modules_jsdoc_lib_jsdoc_name.js.html @@ -5,7 +5,7 @@ Source: node_modules/jsdoc/lib/jsdoc/name.js | DOCOLATTE - + @@ -655,7 +655,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -696,13 +696,13 @@

      - +
      - + diff --git a/node_modules_jsdoc_lib_jsdoc_schema.js.html b/node_modules_jsdoc_lib_jsdoc_schema.js.html index 80db69e..5c10447 100644 --- a/node_modules_jsdoc_lib_jsdoc_schema.js.html +++ b/node_modules_jsdoc_lib_jsdoc_schema.js.html @@ -5,7 +5,7 @@ Source: node_modules/jsdoc/lib/jsdoc/schema.js | DOCOLATTE - + @@ -724,7 +724,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -765,13 +765,13 @@

      - +
      - + diff --git a/node_modules_jsdoc_lib_jsdoc_tutorial.js.html b/node_modules_jsdoc_lib_jsdoc_tutorial.js.html index da6b9af..04a0a4c 100644 --- a/node_modules_jsdoc_lib_jsdoc_tutorial.js.html +++ b/node_modules_jsdoc_lib_jsdoc_tutorial.js.html @@ -5,7 +5,7 @@ Source: node_modules/jsdoc/lib/jsdoc/tutorial.js | DOCOLATTE - + @@ -213,7 +213,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -254,13 +254,13 @@

      - +
      - + diff --git a/node_modules_jsdoc_lib_jsdoc_util_templateHelper.js.html b/node_modules_jsdoc_lib_jsdoc_util_templateHelper.js.html index a92ea87..a274a44 100644 --- a/node_modules_jsdoc_lib_jsdoc_util_templateHelper.js.html +++ b/node_modules_jsdoc_lib_jsdoc_util_templateHelper.js.html @@ -5,7 +5,7 @@ Source: node_modules/jsdoc/lib/jsdoc/util/templateHelper.js | DOCOLATTE - + @@ -468,6 +468,13 @@

      target = text.substr(0, splitIndex); } + if (linkText) { + linkText = linkText.trim(); + } + if (target) { + target = target.trim(); + } + return { linkText: linkText, target: target || text @@ -1078,7 +1085,7 @@

      - Documentation generated by JSDoc 3.6.11 + Documentation generated by JSDoc 4.0.2 using Docolatte theme

      @@ -1119,13 +1126,13 @@

      - +
      - + diff --git a/src_scripts_Debugger.js.html b/src_scripts_Debugger.js.html new file mode 100644 index 0000000..15a3169 --- /dev/null +++ b/src_scripts_Debugger.js.html @@ -0,0 +1,171 @@ + + + + + + + Source: src/scripts/Debugger.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _/**
      + * Debug utility.
      + * @author amekusa
      + */
      +class Debugger {
      +	/**
      +	 * @param {string} [label] - Log label
      +	 * @param {boolean} [enabled] - Whether to enable debugging
      +	 */
      +	constructor(label = '[DEBUG]', enabled = true) {
      +		this.label = label;
      +		this.enabled = enabled;
      +	}
      +	/**
      +	 * Enables debugging.
      +	 */
      +	enable() {
      +		this.enabled = true;
      +	}
      +	/**
      +	 * Disables debugging.
      +	 */
      +	disable() {
      +		this.enabled = false;
      +	}
      +	/**
      +	 * Outputs logs to console.
      +	 * @param {...any} args - Infos to log
      +	 */
      +	log(...args) {
      +		if (!this.enabled) return false;
      +		return console.debug(this.label, ...args);
      +	}
      +	/**
      +	 * Calls the given function.
      +	 * @param {function} fn - Function to call
      +	 * @param {...any} args - Arguments to pass to `fn`
      +	 * @return {any} Return of `fn`
      +	 */
      +	call(fn, ...args) {
      +		if (!this.enabled) return false;
      +		return fn(...args);
      +	}
      +	/**
      +	 * Simulates a heavy computing operation.
      +	 * @param {number} weight - How heavy
      +	 */
      +	slow(weight) {
      +		if (!this.enabled) return false;
      +		console.time(this.label + ' slow');
      +		let r = 0;
      +		for (let i = Math.pow(weight, 7); i >= 0; i--) r += Math.atan(i) * Math.tan(i);
      +		console.timeEnd(this.label + ' slow');
      +		return r;
      +	}
      +}
      +
      +export default Debugger;
      +
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/src_scripts_Exception.js.html b/src_scripts_Exception.js.html new file mode 100644 index 0000000..ee0dda8 --- /dev/null +++ b/src_scripts_Exception.js.html @@ -0,0 +1,183 @@ + + + + + + + Source: src/scripts/Exception.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _/**
      + * Exception thrower.
      + * @author amekusa
      + */
      +class Exception {
      +	/**
      +	 * @param {string} label - Log label
      +	 */
      +	constructor(label) {
      +		this.label = label;
      +	}
      +	/**
      +	 * Generates a new exception instance.
      +	 * @param {string} msg - Message
      +	 * @param {any} [info] - Additional info
      +	 */
      +	new(msg, info = null) {
      +		return new ExceptionInfo(this.label, msg, info);
      +	}
      +	/**
      +	 * Throws an exception.
      +	 * @param {...any} args - Same as {@link Exception#new}
      +	 */
      +	throw(...args) {
      +		throw this.new(...args);
      +	}
      +	/**
      +	 * Logs an exception to console as an error.
      +	 * @param {...any} args - Same as {@link Exception#new}
      +	 */
      +	error(...args) {
      +		console.error(this.new(...args));
      +	}
      +	/**
      +	 * Logs an exception to console as an error, and returns the given value.
      +	 * @param {any} x - Return value
      +	 * @param {...any} args - Same as {@link Exception#new}
      +	 * @return {any} `x`
      +	 */
      +	withError(x, ...args) {
      +		this.error(...args);
      +		return x;
      +	}
      +	/**
      +	 * Logs an exception to console as a warning.
      +	 * @param {...any} args - Same as {@link Exception#new}
      +	 */
      +	warn(...args) {
      +		console.warn(this.new(...args));
      +	}
      +	/**
      +	 * Logs an exception to console as a warning, and returns the given value.
      +	 * @param {any} x - Return value
      +	 * @param {...any} args - Same as {@link Exception#new}
      +	 * @return {any} `x`
      +	 */
      +	withWarn(x, ...args) {
      +		this.warn(...args);
      +		return x;
      +	}
      +}
      +
      +class ExceptionInfo extends Error {
      +	constructor(label, msg, info = undefined) {
      +		super(`${label} ${msg}` + (info === undefined ? '' : `\n:: info: ${info}`));
      +		this.info = info;
      +	}
      +}
      +
      +export default Exception;
      +
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/src_scripts_LightSwitch.js.html b/src_scripts_LightSwitch.js.html new file mode 100644 index 0000000..e1018a7 --- /dev/null +++ b/src_scripts_LightSwitch.js.html @@ -0,0 +1,293 @@ + + + + + + + Source: src/scripts/LightSwitch.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _import SelectList from './SelectList.js';
      +import Exception from './Exception.js';
      +import Debugger from './Debugger.js';
      +const E = new Exception('[LightSwitch]');
      +const debug = new Debugger('[DBG:LS]', true);
      +
      +/**
      + * Color scheme switcher.
      + * @author amekusa
      + */
      +class LightSwitch {
      +	/**
      +	 * @param {string[]} [states] - All possible states. Default: `['auto', 'light', 'dark]`
      +	 * @param {number} [initial] - Initial state index
      +	 */
      +	constructor(states, initial = 0) {
      +		this.switch = null;
      +		this.room = null;
      +		this.storage = null;
      +		this.states = new SelectList(states || ['auto', 'light', 'dark'], initial);
      +		this.states.onSelect(() => { this.sync(); });
      +		this._pref;
      +	}
      +	/**
      +	 * The current state.
      +	 * @type {string}
      +	 * @readonly
      +	 */
      +	get state() {
      +		return this.states.curr;
      +	}
      +	/**
      +	 * The current state of the room.
      +	 * @type {string}
      +	 * @readonly
      +	 */
      +	get roomState() {
      +		return this.state == 'auto' ? this.getPreference() : this.state;
      +	}
      +	/**
      +	 * Fetch user's system preference.
      +	 * @param {boolean} [update] - Force update
      +	 * @return {string} preferred state
      +	 */
      +	getPreference(update = false) {
      +		if (this._pref === undefined || update) {
      +			debug.log(`matching user preference...`);
      +			let states = this.states.items;
      +			for (let i = 0; i < states.length; i++) {
      +				let state = states[i];
      +				if (state == 'auto') continue;
      +				if (matchMedia(`(prefers-color-scheme: ${state})`).matches) {
      +					debug.log(`matched user preference:`, state);
      +					this._pref = i;
      +					return state;
      +				}
      +			}
      +			E.warn(`cannot find user preference`);
      +			return this.states.item(this.states.initialPos);
      +		}
      +		return this.states.item(this._pref);
      +	}
      +	/**
      +	 * Sets a storage object to store state.
      +	 * @param {Storage} obj
      +	 * @param {string} key
      +	 * @example
      +	 * ls.setStorage(localStorage, 'lightSwitch');
      +	 */
      +	setStorage(obj, key) {
      +		this.storage = { obj, key };
      +	}
      +	/**
      +	 * Connects a "switch" element to sync state.
      +	 * @param {Element} elem - Element
      +	 * @param {string} attr - Attribute to sync state
      +	 */
      +	setSwitch(elem, attr) {
      +		this.switch = { elem, attr };
      +		elem.addEventListener('click', ev => {
      +			ev.preventDefault();
      +			this.nextState();
      +			this.save();
      +		});
      +	}
      +	/**
      +	 * Connects a "room" element to sync state.
      +	 * @param {Element} elem - Element
      +	 * @param {string} attr - Attribute to sync state
      +	 */
      +	setRoom(elem, attr) {
      +		this.room = { elem, attr };
      +	}
      +	/**
      +	 * Sets the current state.
      +	 * @param {number|string} state - State name or index
      +	 * @example
      +	 * ls.setState('dark');
      +	 */
      +	setState(state) {
      +		let pos = typeof state == 'number' ? state : this.states.indexOf(state);
      +		if (pos < 0) return E.error(`invalid state`, { state });
      +		this.states.to(pos);
      +	}
      +	/**
      +	 * Switches to the previous state.
      +	 */
      +	prevState() {
      +		this.states.prev();
      +	}
      +	/**
      +	 * Switches to the next state.
      +	 */
      +	nextState() {
      +		this.states.next();
      +	}
      +	/**
      +	 * Syncs the "switch" and the "room" elements with the current state of this LightSwitch.
      +	 */
      +	sync() {
      +		this.syncSwitch();
      +		this.syncRoom();
      +	}
      +	/**
      +	 * Syncs the "switch" element with the current state of this LightSwitch.
      +	 */
      +	syncSwitch() {
      +		if (this.switch) {
      +			this.switch.elem.setAttribute(this.switch.attr, this.state);
      +			debug.log(`synced switch`);
      +		}
      +	}
      +	/**
      +	 * Syncs the "room" element with the current state of this LightSwitch.
      +	 */
      +	syncRoom() {
      +		if (this.room) {
      +			this.room.elem.setAttribute(this.room.attr, this.roomState);
      +			debug.log(`synced room`);
      +		}
      +	}
      +	/**
      +	 * Initializes the state by loading it from the browser storage,
      +	 * or reading the attribute values of "switch" or "room" element.
      +	 */
      +	load() {
      +		// load saved state stored in the browser storage, if it exists
      +		if (this.storage) {
      +			debug.log(`loading state from storage...`);
      +			debug.log(` - storage:`, this.storage);
      +			let loaded = this.storage.obj.getItem(this.storage.key);
      +			if (loaded) {
      +				debug.log(`state loaded:`, loaded);
      +				this.states.to(parseInt(loaded));
      +				return;
      +			}
      +			debug.log(`state not found`);
      +		}
      +		// if saved state was not found, use DOM attribute instead
      +		debug.log(`retrieving state from doms...`);
      +		let { elem, attr } = this.switch || this.room;
      +		let state = elem.getAttribute(attr);
      +		if (!state) return E.error(`load(): cannot find state`);
      +		let pos = this.states.indexOf(state);
      +		if (pos < 0) return E.error(`load(): invalid state`, { state });
      +		debug.log(`state found:`, state);
      +		this.states.to(pos);
      +	}
      +	/**
      +	 * Saves the current state to the browser storage.
      +	 */
      +	save() {
      +		if (this.storage) {
      +			this.storage.obj.setItem(this.storage.key, this.states.pos);
      +			debug.log(`saved state`);
      +		}
      +	}
      +}
      +
      +export default LightSwitch;
      +
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/src_scripts_ScrollWatcher.js.html b/src_scripts_ScrollWatcher.js.html new file mode 100644 index 0000000..297a663 --- /dev/null +++ b/src_scripts_ScrollWatcher.js.html @@ -0,0 +1,231 @@ + + + + + + + Source: src/scripts/ScrollWatcher.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _import Debugger from './Debugger.js';
      +const debug = new Debugger('[DBG:SW]', true);
      +
      +/**
      + * Scroll event watcher for smooth animation.
      + * @author amekusa
      + */
      +class ScrollWatcher {
      +	/**
      +	 * @param {Element} [target=window] - Element to watch
      +	 */
      +	constructor(target = window) {
      +		this.target = target;
      +		this.tasks = {
      +			init: [],
      +			scroll: [],
      +			resize: [],
      +		};
      +	}
      +	/**
      +	 * Registers a callback.
      +	 * @param {string|string[]} ev - Event name(s). Pass `any` to register to all the available events
      +	 * @param {function} fn - Callback
      +	 * @example
      +	 * let sw.on('scroll', ev => {
      +	 *   console.log('Scroll Detected');
      +	 * });
      +	 */
      +	on(ev, fn) {
      +		if (Array.isArray(ev)) {
      +			for (let i = 0; i < ev.length; i++) this.on(ev[i], fn);
      +		} else if (ev == 'any') {
      +			for (let key in this.tasks) this.on(key, fn);
      +		} else this.tasks[ev].push(fn);
      +	}
      +	/**
      +	 * Starts watching scroll related events.
      +	 * @param {string|string[]} ev - Event name(s) to watch. `any` to watch all the available events
      +	 */
      +	watch(ev = 'any') {
      +		if (ev == 'any') ev = Object.keys(this.tasks);
      +		else if (!Array.isArray(ev)) ev = [ev];
      +
      +		// context
      +		let c = new Stats({ x: 0, y: 0, mx: 0, my: 0, time: 0 });
      +		c.isFirst = true;
      +		c.event = null;
      +
      +		let request = false; // animation frame request id
      +		let tick = time => {
      +			c.set('time', time);
      +			debug.log(`animation frame #${request} started @`, time);
      +			debug.log(' - diff:', c.diff.time);
      +			let tasks = this.tasks[c.event.type];
      +			for (let i = 0; i < tasks.length; i++) tasks[i](c);
      +			if (c.isFirst) c.isFirst = false;
      +			debug.log(`animation frame #${request} done`);
      +			request = false;
      +		};
      +		let propX, propY, propMX, propMY;
      +		if (this.target === window) {
      +			propX = 'scrollX';
      +			propY = 'scrollY';
      +			propMX = 'scrollMaxX';
      +			propMY = 'scrollMaxY';
      +		} else {
      +			propX = 'scrollLeft';
      +			propY = 'scrollTop';
      +			propMX = 'scrollLeftMax';
      +			propMY = 'scrollTopMax';
      +		}
      +		let handler = ev => {
      +			debug.log(`--- ${ev.type} event ---`);
      +			if (request) { // previous request is still in the queue
      +				window.cancelAnimationFrame(request); // cancel the previous request
      +				debug.log(`<BUSY!> canceled animation frame #${request}`);
      +			};
      +			c.event = ev;
      +			c.set('x', this.target[propX]);
      +			c.set('y', this.target[propY]);
      +			c.set('mx', this.target[propMX]);
      +			c.set('my', this.target[propMY]);
      +			request = window.requestAnimationFrame(tick);
      +			debug.log(`animation frame #${request} requested`);
      +		};
      +		for (let i = 0; i < ev.length; i++) {
      +			switch (ev[i]) {
      +				case 'init':   handler({ type: 'init' }); break; // fake event
      +				case 'scroll': this.target.addEventListener('scroll', handler); break;
      +				case 'resize': window.addEventListener('resize', handler); break;
      +			}
      +		}
      +	}
      +}
      +
      +class Stats {
      +	constructor(data) {
      +		this.curr = {};
      +		this.prev = {};
      +		this.diff = {};
      +		for (let key in data) {
      +			this.curr[key] = data[key];
      +			this.prev[key] = undefined;
      +			this.diff[key] = undefined;
      +		}
      +	}
      +	get(key) {
      +		return this.curr[key];
      +	}
      +	set(key, value) {
      +		this.prev[key] = this.curr[key];
      +		this.curr[key] = value;
      +		this.diff[key] = this.curr[key] - this.prev[key];
      +		return this;
      +	}
      +}
      +
      +export default ScrollWatcher;
      +
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/src_scripts_SelectList.js.html b/src_scripts_SelectList.js.html new file mode 100644 index 0000000..f4287f9 --- /dev/null +++ b/src_scripts_SelectList.js.html @@ -0,0 +1,226 @@ + + + + + + + Source: src/scripts/SelectList.js | DOCOLATTE + + + + + + + + + +
      + +
      +
      + + DOCOLATTE +
      + +
      + +
      +
      + + + + + +
      +
      _/**
      + * An array wrapper that has a pointer to one of its items.
      + * @author amekusa
      + */
      +class SelectList {
      +	/**
      +	 * @param {any[]} items - Array of items
      +	 * @param {number} [initial] - Initial position
      +	 * @example
      +	 * let difficulty = new SelectList([
      +	 *   'easy',
      +	 *   'normal', // default
      +	 *   'hard'
      +	 * ], 1);
      +	 */
      +	constructor(items, initial = 0) {
      +		this.items = items;
      +		this.initialPos = this.pos = initial;
      +		this.fn;
      +	}
      +	/**
      +	 * A number of items.
      +	 * @type {number}
      +	 */
      +	get length() {
      +		return this.items.length;
      +	}
      +	/**
      +	 * The current item.
      +	 * @type {any}
      +	 */
      +	get curr() {
      +		return this.items[this.pos];
      +	}
      +	_checkIndex(index, or = 0) {
      +		if (index < 0 || index >= this.items.length) {
      +			console.error(`[SelectList] index out of bounds`);
      +			return or;
      +		}
      +		return index;
      +	}
      +	/**
      +	 * Returns an item by the given index.
      +	 * @param {number} index - Item index
      +	 */
      +	item(index) {
      +		return this.items[this._checkIndex(index)];
      +	}
      +	/**
      +	 * Registers a callback that is invoked on every pointer movement.
      +	 * @param {function} fn
      +	 */
      +	onSelect(fn) {
      +		this.fn = fn;
      +	}
      +	/**
      +	 * Returns the index of the given item.
      +	 * @param {any} item - Item to find
      +	 * @return {number} Index, or negative number if not found
      +	 */
      +	indexOf(item) {
      +		return this.items.indexOf(item);
      +	}
      +	/**
      +	 * Whether the given item is in the list.
      +	 * @param {any} item - Item to find
      +	 * @return {boolean}
      +	 */
      +	has(item) {
      +		return this.indexOf(item) >= 0;
      +	}
      +	/**
      +	 * Moves the pointer to the given item.
      +	 * @param {any} item - Item to find
      +	 * @return {any} Selected item
      +	 */
      +	select(item) {
      +		let pos = this.indexOf(item);
      +		return pos < 0 ? undefined : this.to(pos);
      +	}
      +	/**
      +	 * Moves the pointer to the given index.
      +	 * @param {number} pos - Index to move to
      +	 * @return {any} Selected item
      +	 */
      +	to(pos) {
      +		this.pos = this._checkIndex(pos);
      +		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      +		return this.items[this.pos];
      +	}
      +	/**
      +	 * Decrements the pointer.
      +	 * @param {boolean} [wrap]
      +	 * @return {any} Selected item
      +	 */
      +	prev(wrap = true) {
      +		this.pos = this.pos > 0 ? this.pos - 1 : (wrap ? this.items.length - 1 : 0);
      +		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      +		return this.items[this.pos];
      +	}
      +	/**
      +	 * Increments the pointer.
      +	 * @param {boolean} [wrap]
      +	 * @return {any} Selected item
      +	 */
      +	next(wrap = true) {
      +		let last = this.items.length - 1;
      +		this.pos = this.pos < last ? this.pos + 1 : (wrap ? 0 : last);
      +		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      +		return this.items[this.pos];
      +	}
      +}
      +
      +export default SelectList;
      +
      + + + + + +
      +
      + +
      + + + + +

      Licensed under the Apache License 2.0

      + + +

      + Documentation generated by JSDoc 4.0.2 + using Docolatte theme + +

      + +
      + + +
      +
      + + + + + + +
      + + + + + diff --git a/static__src_scripts_Debugger.js.html b/static__src_scripts_Debugger.js.html deleted file mode 100644 index 6027c52..0000000 --- a/static__src_scripts_Debugger.js.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - Source: static/_src/scripts/Debugger.js | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      - - - - - -
      -
      _/**
      - * Debug utility.
      - * @author amekusa
      - */
      -class Debugger {
      -	/**
      -	 * @param {string} [label] - Log label
      -	 * @param {boolean} [enabled] - Whether to enable debugging
      -	 */
      -	constructor(label = '[DEBUG]', enabled = true) {
      -		this.label = label;
      -		this.enabled = enabled;
      -	}
      -	/**
      -	 * Enables debugging.
      -	 */
      -	enable() {
      -		this.enabled = true;
      -	}
      -	/**
      -	 * Disables debugging.
      -	 */
      -	disable() {
      -		this.enabled = false;
      -	}
      -	/**
      -	 * Outputs logs to console.
      -	 * @param {...any} args - Infos to log
      -	 */
      -	log(...args) {
      -		if (!this.enabled) return false;
      -		return console.debug(this.label, ...args);
      -	}
      -	/**
      -	 * Calls the given function.
      -	 * @param {function} fn - Function to call
      -	 * @param {...any} args - Arguments to pass to `fn`
      -	 * @return {any} Return of `fn`
      -	 */
      -	call(fn, ...args) {
      -		if (!this.enabled) return false;
      -		return fn(...args);
      -	}
      -	/**
      -	 * Simulates a heavy computing operation.
      -	 * @param {number} weight - How heavy
      -	 */
      -	slow(weight) {
      -		if (!this.enabled) return false;
      -		console.time(this.label + ' slow');
      -		let r = 0;
      -		for (let i = Math.pow(weight, 7); i >= 0; i--) r += Math.atan(i) * Math.tan(i);
      -		console.timeEnd(this.label + ' slow');
      -		return r;
      -	}
      -}
      -
      -export default Debugger;
      -
      -
      - - - - - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - diff --git a/static__src_scripts_Exception.js.html b/static__src_scripts_Exception.js.html deleted file mode 100644 index 6302982..0000000 --- a/static__src_scripts_Exception.js.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - Source: static/_src/scripts/Exception.js | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      - - - - - -
      -
      _/**
      - * Exception thrower.
      - * @author amekusa
      - */
      -class Exception {
      -	/**
      -	 * @param {string} label - Log label
      -	 */
      -	constructor(label) {
      -		this.label = label;
      -	}
      -	/**
      -	 * Generates a new exception instance.
      -	 * @param {string} msg - Message
      -	 * @param {any} [info] - Additional info
      -	 */
      -	new(msg, info = null) {
      -		return new ExceptionInfo(this.label, msg, info);
      -	}
      -	/**
      -	 * Throws an exception.
      -	 * @param {...any} args - Same as {@link Exception#new}
      -	 */
      -	throw(...args) {
      -		throw this.new(...args);
      -	}
      -	/**
      -	 * Logs an exception to console as an error.
      -	 * @param {...any} args - Same as {@link Exception#new}
      -	 */
      -	error(...args) {
      -		console.error(this.new(...args));
      -	}
      -	/**
      -	 * Logs an exception to console as an error, and returns the given value.
      -	 * @param {any} x - Return value
      -	 * @param {...any} args - Same as {@link Exception#new}
      -	 * @return {any} `x`
      -	 */
      -	withError(x, ...args) {
      -		this.error(...args);
      -		return x;
      -	}
      -	/**
      -	 * Logs an exception to console as a warning.
      -	 * @param {...any} args - Same as {@link Exception#new}
      -	 */
      -	warn(...args) {
      -		console.warn(this.new(...args));
      -	}
      -	/**
      -	 * Logs an exception to console as a warning, and returns the given value.
      -	 * @param {any} x - Return value
      -	 * @param {...any} args - Same as {@link Exception#new}
      -	 * @return {any} `x`
      -	 */
      -	withWarn(x, ...args) {
      -		this.warn(...args);
      -		return x;
      -	}
      -}
      -
      -class ExceptionInfo extends Error {
      -	constructor(label, msg, info = undefined) {
      -		super(`${label} ${msg}` + (info === undefined ? '' : `\n:: info: ${info}`));
      -		this.info = info;
      -	}
      -}
      -
      -export default Exception;
      -
      -
      - - - - - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - diff --git a/static__src_scripts_LightSwitch.js.html b/static__src_scripts_LightSwitch.js.html deleted file mode 100644 index 4b5fa8c..0000000 --- a/static__src_scripts_LightSwitch.js.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - - Source: static/_src/scripts/LightSwitch.js | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      - - - - - -
      -
      _import SelectList from './SelectList.js';
      -import Exception from './Exception.js';
      -import Debugger from './Debugger.js';
      -const E = new Exception('[LightSwitch]');
      -const debug = new Debugger('[DBG:LS]', true);
      -
      -/**
      - * Color scheme switcher.
      - * @author amekusa
      - */
      -class LightSwitch {
      -	/**
      -	 * @param {string[]} [states] - All possible states. Default: `['auto', 'light', 'dark]`
      -	 * @param {number} [initial] - Initial state index
      -	 */
      -	constructor(states, initial = 0) {
      -		this.switch = null;
      -		this.room = null;
      -		this.storage = null;
      -		this.states = new SelectList(states || ['auto', 'light', 'dark'], initial);
      -		this.states.onSelect(() => { this.sync(); });
      -		this._pref;
      -	}
      -	/**
      -	 * The current state.
      -	 * @type {string}
      -	 * @readonly
      -	 */
      -	get state() {
      -		return this.states.curr;
      -	}
      -	/**
      -	 * The current state of the room.
      -	 * @type {string}
      -	 * @readonly
      -	 */
      -	get roomState() {
      -		return this.state == 'auto' ? this.getPreference() : this.state;
      -	}
      -	/**
      -	 * Fetch user's system preference.
      -	 * @param {boolean} [update] - Force update
      -	 * @return {string} preferred state
      -	 */
      -	getPreference(update = false) {
      -		if (this._pref === undefined || update) {
      -			debug.log(`matching user preference...`);
      -			let states = this.states.items;
      -			for (let i = 0; i < states.length; i++) {
      -				let state = states[i];
      -				if (state == 'auto') continue;
      -				if (matchMedia(`(prefers-color-scheme: ${state})`).matches) {
      -					debug.log(`matched user preference:`, state);
      -					this._pref = i;
      -					return state;
      -				}
      -			}
      -			E.warn(`cannot find user preference`);
      -			return this.states.item(this.states.initialPos);
      -		}
      -		return this.states.item(this._pref);
      -	}
      -	/**
      -	 * Sets a storage object to store state.
      -	 * @param {Storage} obj
      -	 * @param {string} key
      -	 * @example
      -	 * ls.setStorage(localStorage, 'lightSwitch');
      -	 */
      -	setStorage(obj, key) {
      -		this.storage = { obj, key };
      -	}
      -	/**
      -	 * Connects a "switch" element to sync state.
      -	 * @param {Element} elem - Element
      -	 * @param {string} attr - Attribute to sync state
      -	 */
      -	setSwitch(elem, attr) {
      -		this.switch = { elem, attr };
      -		elem.addEventListener('click', ev => {
      -			ev.preventDefault();
      -			this.nextState();
      -			this.save();
      -		});
      -	}
      -	/**
      -	 * Connects a "room" element to sync state.
      -	 * @param {Element} elem - Element
      -	 * @param {string} attr - Attribute to sync state
      -	 */
      -	setRoom(elem, attr) {
      -		this.room = { elem, attr };
      -	}
      -	/**
      -	 * Sets the current state.
      -	 * @param {number|string} state - State name or index
      -	 * @example
      -	 * ls.setState('dark');
      -	 */
      -	setState(state) {
      -		let pos = typeof state == 'number' ? state : this.states.indexOf(state);
      -		if (pos < 0) return E.error(`invalid state`, { state });
      -		this.states.to(pos);
      -	}
      -	/**
      -	 * Switches to the previous state.
      -	 */
      -	prevState() {
      -		this.states.prev();
      -	}
      -	/**
      -	 * Switches to the next state.
      -	 */
      -	nextState() {
      -		this.states.next();
      -	}
      -	/**
      -	 * Syncs the "switch" and the "room" elements with the current state of this LightSwitch.
      -	 */
      -	sync() {
      -		this.syncSwitch();
      -		this.syncRoom();
      -	}
      -	/**
      -	 * Syncs the "switch" element with the current state of this LightSwitch.
      -	 */
      -	syncSwitch() {
      -		if (this.switch) {
      -			this.switch.elem.setAttribute(this.switch.attr, this.state);
      -			debug.log(`synced switch`);
      -		}
      -	}
      -	/**
      -	 * Syncs the "room" element with the current state of this LightSwitch.
      -	 */
      -	syncRoom() {
      -		if (this.room) {
      -			this.room.elem.setAttribute(this.room.attr, this.roomState);
      -			debug.log(`synced room`);
      -		}
      -	}
      -	/**
      -	 * Initializes the state by loading it from the browser storage,
      -	 * or reading the attribute values of "switch" or "room" element.
      -	 */
      -	load() {
      -		// load saved state stored in the browser storage, if it exists
      -		if (this.storage) {
      -			debug.log(`loading state from storage...`);
      -			debug.log(` - storage:`, this.storage);
      -			let loaded = this.storage.obj.getItem(this.storage.key);
      -			if (loaded) {
      -				debug.log(`state loaded:`, loaded);
      -				this.states.to(parseInt(loaded));
      -				return;
      -			}
      -			debug.log(`state not found`);
      -		}
      -		// if saved state was not found, use DOM attribute instead
      -		debug.log(`retrieving state from doms...`);
      -		let { elem, attr } = this.switch || this.room;
      -		let state = elem.getAttribute(attr);
      -		if (!state) return E.error(`load(): cannot find state`);
      -		let pos = this.states.indexOf(state);
      -		if (pos < 0) return E.error(`load(): invalid state`, { state });
      -		debug.log(`state found:`, state);
      -		this.states.to(pos);
      -	}
      -	/**
      -	 * Saves the current state to the browser storage.
      -	 */
      -	save() {
      -		if (this.storage) {
      -			this.storage.obj.setItem(this.storage.key, this.states.pos);
      -			debug.log(`saved state`);
      -		}
      -	}
      -}
      -
      -export default LightSwitch;
      -
      -
      - - - - - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - diff --git a/static__src_scripts_ScrollWatcher.js.html b/static__src_scripts_ScrollWatcher.js.html deleted file mode 100644 index 006fc10..0000000 --- a/static__src_scripts_ScrollWatcher.js.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - Source: static/_src/scripts/ScrollWatcher.js | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      - - - - - -
      -
      _import Debugger from './Debugger.js';
      -const debug = new Debugger('[DBG:SW]', true);
      -
      -/**
      - * Scroll event watcher for smooth animation.
      - * @author amekusa
      - */
      -class ScrollWatcher {
      -	/**
      -	 * @param {Element} [target=window] - Element to watch
      -	 */
      -	constructor(target = window) {
      -		this.target = target;
      -		this.tasks = {
      -			init: [],
      -			scroll: [],
      -			resize: [],
      -		};
      -	}
      -	/**
      -	 * Registers a callback.
      -	 * @param {string|string[]} ev - Event name(s). Pass `any` to register to all the available events
      -	 * @param {function} fn - Callback
      -	 * @example
      -	 * let sw.on('scroll', ev => {
      -	 *   console.log('Scroll Detected');
      -	 * });
      -	 */
      -	on(ev, fn) {
      -		if (Array.isArray(ev)) {
      -			for (let i = 0; i < ev.length; i++) this.on(ev[i], fn);
      -		} else if (ev == 'any') {
      -			for (let key in this.tasks) this.on(key, fn);
      -		} else this.tasks[ev].push(fn);
      -	}
      -	/**
      -	 * Starts watching scroll related events.
      -	 * @param {string|string[]} ev - Event name(s) to watch. `any` to watch all the available events
      -	 */
      -	watch(ev = 'any') {
      -		if (ev == 'any') ev = Object.keys(this.tasks);
      -		else if (!Array.isArray(ev)) ev = [ev];
      -
      -		// context
      -		let c = new Stats({ x: 0, y: 0, mx: 0, my: 0, time: 0 });
      -		c.isFirst = true;
      -		c.event = null;
      -
      -		let request = false; // animation frame request id
      -		let tick = time => {
      -			c.set('time', time);
      -			debug.log(`animation frame #${request} started @`, time);
      -			debug.log(' - diff:', c.diff.time);
      -			let tasks = this.tasks[c.event.type];
      -			for (let i = 0; i < tasks.length; i++) tasks[i](c);
      -			if (c.isFirst) c.isFirst = false;
      -			debug.log(`animation frame #${request} done`);
      -			request = false;
      -		};
      -		let propX, propY, propMX, propMY;
      -		if (this.target === window) {
      -			propX = 'scrollX';
      -			propY = 'scrollY';
      -			propMX = 'scrollMaxX';
      -			propMY = 'scrollMaxY';
      -		} else {
      -			propX = 'scrollLeft';
      -			propY = 'scrollTop';
      -			propMX = 'scrollLeftMax';
      -			propMY = 'scrollTopMax';
      -		}
      -		let handler = ev => {
      -			debug.log(`--- ${ev.type} event ---`);
      -			if (request) { // previous request is still in the queue
      -				window.cancelAnimationFrame(request); // cancel the previous request
      -				debug.log(`<BUSY!> canceled animation frame #${request}`);
      -			};
      -			c.event = ev;
      -			c.set('x', this.target[propX]);
      -			c.set('y', this.target[propY]);
      -			c.set('mx', this.target[propMX]);
      -			c.set('my', this.target[propMY]);
      -			request = window.requestAnimationFrame(tick);
      -			debug.log(`animation frame #${request} requested`);
      -		};
      -		for (let i = 0; i < ev.length; i++) {
      -			switch (ev[i]) {
      -				case 'init':   handler({ type: 'init' }); break; // fake event
      -				case 'scroll': this.target.addEventListener('scroll', handler); break;
      -				case 'resize': window.addEventListener('resize', handler); break;
      -			}
      -		}
      -	}
      -}
      -
      -class Stats {
      -	constructor(data) {
      -		this.curr = {};
      -		this.prev = {};
      -		this.diff = {};
      -		for (let key in data) {
      -			this.curr[key] = data[key];
      -			this.prev[key] = undefined;
      -			this.diff[key] = undefined;
      -		}
      -	}
      -	get(key) {
      -		return this.curr[key];
      -	}
      -	set(key, value) {
      -		this.prev[key] = this.curr[key];
      -		this.curr[key] = value;
      -		this.diff[key] = this.curr[key] - this.prev[key];
      -		return this;
      -	}
      -}
      -
      -export default ScrollWatcher;
      -
      -
      - - - - - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - diff --git a/static__src_scripts_SelectList.js.html b/static__src_scripts_SelectList.js.html deleted file mode 100644 index 0c2d154..0000000 --- a/static__src_scripts_SelectList.js.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - Source: static/_src/scripts/SelectList.js | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      - - - - - -
      -
      _/**
      - * An array wrapper that has a pointer to one of its items.
      - * @author amekusa
      - */
      -class SelectList {
      -	/**
      -	 * @param {any[]} items - Array of items
      -	 * @param {number} [initial] - Initial position
      -	 * @example
      -	 * let difficulty = new SelectList([
      -	 *   'easy',
      -	 *   'normal', // default
      -	 *   'hard'
      -	 * ], 1);
      -	 */
      -	constructor(items, initial = 0) {
      -		this.items = items;
      -		this.initialPos = this.pos = initial;
      -		this.fn;
      -	}
      -	/**
      -	 * A number of items.
      -	 * @type {number}
      -	 */
      -	get length() {
      -		return this.items.length;
      -	}
      -	/**
      -	 * The current item.
      -	 * @type {any}
      -	 */
      -	get curr() {
      -		return this.items[this.pos];
      -	}
      -	_checkIndex(index, or = 0) {
      -		if (index < 0 || index >= this.items.length) {
      -			console.error(`[SelectList] index out of bounds`);
      -			return or;
      -		}
      -		return index;
      -	}
      -	/**
      -	 * Returns an item by the given index.
      -	 * @param {number} index - Item index
      -	 */
      -	item(index) {
      -		return this.items[this._checkIndex(index)];
      -	}
      -	/**
      -	 * Registers a callback that is invoked on every pointer movement.
      -	 * @param {function} fn
      -	 */
      -	onSelect(fn) {
      -		this.fn = fn;
      -	}
      -	/**
      -	 * Returns the index of the given item.
      -	 * @param {any} item - Item to find
      -	 * @return {number} Index, or negative number if not found
      -	 */
      -	indexOf(item) {
      -		return this.items.indexOf(item);
      -	}
      -	/**
      -	 * Whether the given item is in the list.
      -	 * @param {any} item - Item to find
      -	 * @return {boolean}
      -	 */
      -	has(item) {
      -		return this.indexOf(item) >= 0;
      -	}
      -	/**
      -	 * Moves the pointer to the given item.
      -	 * @param {any} item - Item to find
      -	 * @return {any} Selected item
      -	 */
      -	select(item) {
      -		let pos = this.indexOf(item);
      -		return pos < 0 ? undefined : this.to(pos);
      -	}
      -	/**
      -	 * Moves the pointer to the given index.
      -	 * @param {number} pos - Index to move to
      -	 * @return {any} Selected item
      -	 */
      -	to(pos) {
      -		this.pos = this._checkIndex(pos);
      -		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      -		return this.items[this.pos];
      -	}
      -	/**
      -	 * Decrements the pointer.
      -	 * @param {boolean} [wrap]
      -	 * @return {any} Selected item
      -	 */
      -	prev(wrap = true) {
      -		this.pos = this.pos > 0 ? this.pos - 1 : (wrap ? this.items.length - 1 : 0);
      -		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      -		return this.items[this.pos];
      -	}
      -	/**
      -	 * Increments the pointer.
      -	 * @param {boolean} [wrap]
      -	 * @return {any} Selected item
      -	 */
      -	next(wrap = true) {
      -		let last = this.items.length - 1;
      -		this.pos = this.pos < last ? this.pos + 1 : (wrap ? 0 : last);
      -		if (this.fn) this.fn(this.items[this.pos], this.pos, this);
      -		return this.items[this.pos];
      -	}
      -}
      -
      -export default SelectList;
      -
      - - - - - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - diff --git a/tutorial-Brush Teeth.html b/tutorial-Brush Teeth.html deleted file mode 100644 index a75ee87..0000000 --- a/tutorial-Brush Teeth.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Tutorial: Brush Teeth | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      -
      -
      - - -

      Brush Teeth

      -
      - -

      #Lorem ipsum dolor sit amet

      -

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra, tellus et fermentum tincidunt, massa ligula dignissim augue, ut aliquam tortor odio in odio. In faucibus metus metus. Curabitur est mi, fermentum lacinia tincidunt vitae, mattis sit amet neque. Quisque diam nisl, accumsan ac porta tincidunt, iaculis facilisis ipsum. Nulla facilisi. Aenean a metus tortor. Pellentesque congue, mauris vitae viverra varius, elit nunc dictum nisl, rhoncus ultrices nulla sapien at leo. Duis ultricies porttitor diam. Nulla facilisi. Nullam elementum, lorem eu imperdiet laoreet, est turpis sollicitudin velit, in porttitor justo dolor vel urna. Mauris in ante magna. Curabitur vitae lacus in magna mollis commodo.

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      Fusce laciniamauris ac aliquamconsequatlacus urna feugiat eratid viverra mi mi sit amet tortor
      Etiam ac134.56.78910
      Pellentesque e2234
      -

      neque lacus, quis posuere orci. Fusce molestie blandit velit, sit amet dictum eros pharetra vitae. In erat urna, condimentum ac feugiat id, rutrum et nisi. Cras ac velit lorem. Nulla facilisi. Maecenas dignissim nulla in turpis tempus sed rhoncus augue dapibus. Nulla feugiat, urna non sagittis laoreet, dolor metus rhoncus justo, sed semper ante lacus eget quam. Sed ac ligula magna. Sed tincidunt pulvinar neque in porta. Nullam quis lacus orci. Pellentesque ornare viverra lacus, id aliquam magna venenatis a.

      -

      Sed id tristique lorem. Ut sodales turpis nec mauris gravida interdum. Cras pellentesque, purus at suscipit euismod, elit nunc cursus nisi, ut venenatis metus sapien id velit. Sed lectus orci, pharetra non pulvinar vel, ullamcorper id lorem. Donec vulputate tincidunt ipsum, ut lacinia tortor sollicitudin id. Nunc nec nibh ut felis venenatis egestas. Proin risus mauris, eleifend eget interdum in, venenatis sed velit. Praesent sodales elit ut odio viverra posuere. Donec sapien lorem, molestie in egestas eget, vulputate sed orci. Aenean elit sapien, pellentesque vitae tempor sit amet, sagittis et ligula. Mauris aliquam sapien sit amet lacus ultrices rutrum. Curabitur nec dolor sed elit varius dignissim a a lacus. Aliquam ac convallis enim.

      -

      Suspendisse orci massa, hendrerit sagittis lacinia consectetur, sagittis vitae purus. Aliquam id eros diam, eget elementum turpis. Nullam tellus magna, mollis in molestie id, venenatis rhoncus est. Proin id diam justo. Nunc tempus gravida justo at lobortis. Nam vitae venenatis nisi. Donec vel odio massa. Quisque interdum metus sit amet est iaculis tincidunt. Donec bibendum blandit purus, id semper orci aliquam quis. Nam tincidunt dolor eu felis ultricies tempor. Nulla non consectetur erat.

      -

      Nunc faucibus lacus eget odio ultricies nec ullamcorper risus pharetra. Nunc nec consequat urna. Curabitur condimentum ante vitae erat tristique vitae gravida quam dapibus. Cras ac justo dui, at faucibus urna. Nunc tristique, velit id feugiat fermentum, dolor enim egestas erat, at vestibulum ante ipsum vel orci. Duis quis ante id justo vehicula eleifend sed et urna. Sed sapien tortor, rutrum id ultrices eu, tincidunt tincidunt mi. Etiam blandit, neque eget interdum dignissim, lacus ante facilisis dolor, non viverra dui lorem vitae nibh. Morbi volutpat augue eget nulla luctus eu aliquam sem facilisis. Pellentesque sollicitudin commodo dolor sit amet vestibulum. Nam dictum posuere quam, in tincidunt erat rutrum eu.

      -

      Etiam nec turpis purus, at lacinia sem. In commodo lacinia euismod. Curabitur tincidunt congue leo, eget iaculis orci volutpat pharetra. Fusce dignissim lacus lacus. Integer consectetur lacus rutrum risus malesuada at consectetur erat rutrum. Sed magna ipsum, fringilla eget auctor non, fringilla nec massa. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum nec tortor id nisi luctus aliquam. Maecenas cursus tincidunt ornare. Nulla a vestibulum odio. Mauris malesuada commodo justo quis mattis. Suspendisse mauris ligula, placerat at egestas in, tincidunt quis nibh. Aliquam ullamcorper elit at augue cursus quis pellentesque purus viverra.

      -

      Nulla ultricies justo ac nisi consectetur posuere. Donec ornare pharetra erat, nec facilisis dui cursus quis. Quisque porttitor porttitor orci, sed facilisis urna facilisis sed. Sed tincidunt adipiscing turpis et hendrerit. Cras posuere orci ut mauris ullamcorper vitae laoreet nisi luctus. In rutrum tristique augue. Nam eleifend dignissim dui.

      -

      Donec viverra egestas tellus non viverra. Aenean est ante, egestas sed scelerisque quis, aliquet sed lacus. Praesent non mauris neque, et adipiscing ante. Vestibulum quis quam vitae ipsum aliquet blandit. Vivamus condimentum euismod orci, in tincidunt justo rutrum faucibus. Phasellus nec lorem arcu. Donec tortor dui, facilisis in rutrum sit amet, pulvinar vitae lacus. Nam sodales sem eu nunc scelerisque vitae ullamcorper dolor facilisis. Duis imperdiet nisi in magna tempor convallis. Fusce at metus augue. Quisque dictum tempus mauris, in mattis ligula dignissim ut.

      -

      Proin sodales, mi at tincidunt ornare, mi dui sagittis velit, sed dictum risus orci eu erat. Sed nunc leo, congue sed rutrum eget, lobortis ac lectus. Etiam non arcu nulla. Vestibulum rutrum dolor pulvinar lorem posuere blandit. Sed quis sapien dui. Nunc sagittis erat commodo quam porta cursus in non erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin a molestie neque. Aliquam iaculis lacus sed neque hendrerit at dignissim ligula imperdiet. Suspendisse venenatis, lorem at luctus scelerisque, sem purus pellentesque sapien, vitae ornare ipsum quam nec dui. Mauris neque est, interdum nec pulvinar eget, dapibus eleifend tellus. Fusce non lorem tortor. Nullam eget nunc quis felis aliquam consectetur. Aliquam tristique, turpis in feugiat blandit, lectus erat condimentum tortor, non egestas nisl sapien eget nibh.

      -

      Aliquam elit turpis, faucibus et porta et, egestas nec nibh. Sed nisl est, pharetra a eleifend a, pretium ac eros. Sed leo eros, pulvinar vel faucibus dictum, aliquet ut quam. Maecenas et felis non ligula fringilla pretium fringilla sit amet ante. Nam varius imperdiet interdum. Ut non metus mauris, vel volutpat lorem. Nullam sagittis est quis lacus feugiat fringilla. Quisque orci lorem, semper ac accumsan vitae, blandit quis velit. Proin luctus sodales ultrices. Fusce mauris erat, facilisis ut consectetur at, fringilla feugiat orci. Aliquam a nisi a neque interdum suscipit id eget purus. Pellentesque tincidunt justo ut urna posuere non molestie quam auctor.

      -
      - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - \ No newline at end of file diff --git a/tutorial-Drive Car.html b/tutorial-Drive Car.html deleted file mode 100644 index 4f2dfe9..0000000 --- a/tutorial-Drive Car.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - Tutorial: Drive Car | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      -
      -
      - - -

      Drive Car

      -
      - -

      #Lorem ipsum dolor sit amet

      -

      Curabitur est mi, fermentum lacinia tincidunt vitae, mattis sit amet neque. Quisque diam nisl, accumsan ac porta tincidunt, iaculis facilisis ipsum. Nulla facilisi. Aenean a metus tortor. Pellentesque congue, mauris vitae viverra varius, elit nunc dictum nisl, rhoncus ultrices nulla sapien at leo. Duis ultricies porttitor diam. Nulla facilisi. Nullam elementum, lorem eu imperdiet laoreet, est turpis sollicitudin velit, in porttitor justo dolor vel urna. Mauris in ante magna. Curabitur vitae lacus in magna mollis commodo.

      -

      ##Fusce lacinia, mauris ac aliquam consequat
      -Fusce molestie blandit velit, sit amet dictum eros pharetra vitae. In erat urna, condimentum ac feugiat id, rutrum et nisi. Cras ac velit lorem. Nulla facilisi. Maecenas dignissim nulla in turpis tempus sed rhoncus augue dapibus. Nulla feugiat, urna non sagittis laoreet, dolor metus rhoncus justo, sed semper ante lacus eget quam. Sed ac ligula magna. Sed tincidunt pulvinar neque in porta. Nullam quis lacus orci. Pellentesque ornare viverra lacus, id aliquam magna venenatis a.

      -

      Sed id tristique lorem. Ut sodales turpis nec mauris gravida interdum. Cras pellentesque, purus at suscipit euismod, elit nunc cursus nisi, ut venenatis metus sapien id velit. Sed lectus orci, pharetra non pulvinar vel, ullamcorper id lorem. Donec vulputate tincidunt ipsum, ut lacinia tortor sollicitudin id. Nunc nec nibh ut felis venenatis egestas. Proin risus mauris, eleifend eget interdum in, venenatis sed velit. Praesent sodales elit ut odio viverra posuere. Donec sapien lorem, molestie in egestas eget, vulputate sed orci. Aenean elit sapien, pellentesque vitae tempor sit amet, sagittis et ligula. Mauris aliquam sapien sit amet lacus ultrices rutrum. Curabitur nec dolor sed elit varius dignissim a a lacus. Aliquam ac convallis enim.

      -

      Suspendisse orci massa, hendrerit sagittis lacinia consectetur, sagittis vitae purus. Aliquam id eros diam, eget elementum turpis. Nullam tellus magna, mollis in molestie id, venenatis rhoncus est. Proin id diam justo. Nunc tempus gravida justo at lobortis. Nam vitae venenatis nisi. Donec vel odio massa. Quisque interdum metus sit amet est iaculis tincidunt. Donec bibendum blandit purus, id semper orci aliquam quis. Nam tincidunt dolor eu felis ultricies tempor. Nulla non consectetur erat.

      -
      - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - \ No newline at end of file diff --git a/tutorial-Fence Test.html b/tutorial-Fence Test.html deleted file mode 100644 index 5344470..0000000 --- a/tutorial-Fence Test.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - Tutorial: Fence Test | DOCOLATTE - - - - - - - - - -
      - -
      -
      - - DOCOLATTE -
      - -
      - -
      -
      -
      -
      - - -

      Fence Test

      -
      - -

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non libero tristique, interdum quam in, fermentum massa. Aenean vestibulum velit eu massa faucibus accumsan. Aenean tempus quam ornare ligula gravida adipiscing. Suspendisse vestibulum diam quis quam lacinia convallis. Nunc rhoncus a elit ut dictum. Maecenas porta mi et risus convallis commodo. In hac habitasse platea dictumst. Morbi placerat sem nec eleifend hendrerit. Donec hendrerit pulvinar tristique. Pellentesque at nunc blandit, fringilla elit nec, dignissim arcu. Quisque sit amet enim urna. Nunc adipiscing lacinia justo. Pellentesque euismod nisi id elit auctor porttitor. Phasellus rutrum viverra felis, ac cursus ante vulputate ut. Donec laoreet felis ac risus vulputate sodales.

      -

      Mauris sit amet risus non ligula lacinia iaculis. Sed ornare tellus velit, vel elementum quam porttitor tempus. Duis vestibulum augue eu diam malesuada auctor. Maecenas dignissim odio ut elit fermentum, id mollis leo mattis. Phasellus posuere augue sed interdum vestibulum. Etiam ac pharetra est. Integer tortor ligula, pharetra ac nisi nec, faucibus laoreet dolor. Nunc vehicula, enim et cursus tincidunt, nulla purus mollis urna, vel ultricies nisl mi a risus. Vestibulum sed urna sodales, pretium nisi sed, pretium sapien. Vivamus et massa tincidunt, semper nibh nec, eleifend urna. Integer auctor, eros at pharetra blandit, erat nibh mattis turpis, rhoncus elementum nisi mi vitae purus.

      -

      Quisque elementum sapien id neque volutpat cursus non mattis velit.

      -
      $mod       : function ( qu, value ) {
      -		var operands = sys.flatten( qu.operands );
      -		if ( operands.length !== 2 ) {
      -			throw new Error( "$mod requires two operands" );
      -		}
      -		var mod = operands[0];
      -		var rem = operands[1];
      -		return value % mod === rem;
      -	},
      -
      -
      -
      {@lang bash}
      -#!/bin/bash
      -echo Please, enter your firstname and lastname
      -read FN LN
      -echo "Hi! $LN, $FN !"
      -
      -
      #!/bin/bash
      -echo Please, enter your firstname and lastname
      -read FN LN
      -echo "Hi! $LN, $FN !"
      -
      -
      - -
      -
      - -
      - - - - -

      Licensed under the Apache License 2.0

      - - -

      - Documentation generated by JSDoc 3.6.11 - using Docolatte theme - -

      - -
      - - -
      -
      - - - - - - -
      - - - - - \ No newline at end of file