mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-08-08 23:44:39 +02:00
add prettier for JS style
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
"use strict"
|
||||
|
||||
// https://gomakethings.com/finding-the-next-and-previous-sibling-elements-that-match-a-selector-with-vanilla-js/
|
||||
function getNextSibling(elem, selector) {
|
||||
@ -20,33 +20,34 @@ function getNextSibling(elem, selector) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Panel Stuff */
|
||||
|
||||
// true = open
|
||||
let COLLAPSIBLES_INITIALIZED = false;
|
||||
const COLLAPSIBLES_KEY = "collapsibles";
|
||||
const COLLAPSIBLE_PANELS = []; // filled in by createCollapsibles with all the elements matching .collapsible
|
||||
let COLLAPSIBLES_INITIALIZED = false
|
||||
const COLLAPSIBLES_KEY = "collapsibles"
|
||||
const COLLAPSIBLE_PANELS = [] // filled in by createCollapsibles with all the elements matching .collapsible
|
||||
|
||||
// on-init call this for any panels that are marked open
|
||||
function toggleCollapsible(element) {
|
||||
const collapsibleHeader = element.querySelector(".collapsible");
|
||||
const handle = element.querySelector(".collapsible-handle");
|
||||
const collapsibleHeader = element.querySelector(".collapsible")
|
||||
const handle = element.querySelector(".collapsible-handle")
|
||||
collapsibleHeader.classList.toggle("active")
|
||||
let content = getNextSibling(collapsibleHeader, '.collapsible-content')
|
||||
let content = getNextSibling(collapsibleHeader, ".collapsible-content")
|
||||
if (!collapsibleHeader.classList.contains("active")) {
|
||||
content.style.display = "none"
|
||||
if (handle != null) { // render results don't have a handle
|
||||
handle.innerHTML = '➕' // plus
|
||||
if (handle != null) {
|
||||
// render results don't have a handle
|
||||
handle.innerHTML = "➕" // plus
|
||||
}
|
||||
} else {
|
||||
content.style.display = "block"
|
||||
if (handle != null) { // render results don't have a handle
|
||||
handle.innerHTML = '➖' // minus
|
||||
if (handle != null) {
|
||||
// render results don't have a handle
|
||||
handle.innerHTML = "➖" // minus
|
||||
}
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('collapsibleClick', { detail: collapsibleHeader }))
|
||||
|
||||
document.dispatchEvent(new CustomEvent("collapsibleClick", { detail: collapsibleHeader }))
|
||||
|
||||
if (COLLAPSIBLES_INITIALIZED && COLLAPSIBLE_PANELS.includes(element)) {
|
||||
saveCollapsibles()
|
||||
}
|
||||
@ -54,7 +55,7 @@ function toggleCollapsible(element) {
|
||||
|
||||
function saveCollapsibles() {
|
||||
let values = {}
|
||||
COLLAPSIBLE_PANELS.forEach(element => {
|
||||
COLLAPSIBLE_PANELS.forEach((element) => {
|
||||
let value = element.querySelector(".collapsible").className.indexOf("active") !== -1
|
||||
values[element.id] = value
|
||||
})
|
||||
@ -72,31 +73,31 @@ function createCollapsibles(node) {
|
||||
if (save && c.parentElement.id) {
|
||||
COLLAPSIBLE_PANELS.push(c.parentElement)
|
||||
}
|
||||
let handle = document.createElement('span')
|
||||
handle.className = 'collapsible-handle'
|
||||
let handle = document.createElement("span")
|
||||
handle.className = "collapsible-handle"
|
||||
|
||||
if (c.classList.contains("active")) {
|
||||
handle.innerHTML = '➖' // minus
|
||||
handle.innerHTML = "➖" // minus
|
||||
} else {
|
||||
handle.innerHTML = '➕' // plus
|
||||
handle.innerHTML = "➕" // plus
|
||||
}
|
||||
c.insertBefore(handle, c.firstChild)
|
||||
|
||||
c.addEventListener('click', function() {
|
||||
c.addEventListener("click", function() {
|
||||
toggleCollapsible(c.parentElement)
|
||||
})
|
||||
})
|
||||
if (save) {
|
||||
let saved = localStorage.getItem(COLLAPSIBLES_KEY)
|
||||
if (!saved) {
|
||||
saved = tryLoadOldCollapsibles();
|
||||
if (!saved) {
|
||||
saved = tryLoadOldCollapsibles()
|
||||
}
|
||||
if (!saved) {
|
||||
saveCollapsibles()
|
||||
saved = localStorage.getItem(COLLAPSIBLES_KEY)
|
||||
}
|
||||
let values = JSON.parse(saved)
|
||||
COLLAPSIBLE_PANELS.forEach(element => {
|
||||
COLLAPSIBLE_PANELS.forEach((element) => {
|
||||
let value = element.querySelector(".collapsible").className.indexOf("active") !== -1
|
||||
if (values[element.id] != value) {
|
||||
toggleCollapsible(element)
|
||||
@ -108,24 +109,24 @@ function createCollapsibles(node) {
|
||||
|
||||
function tryLoadOldCollapsibles() {
|
||||
const old_map = {
|
||||
"advancedPanelOpen": "editor-settings",
|
||||
"modifiersPanelOpen": "editor-modifiers",
|
||||
"negativePromptPanelOpen": "editor-inputs-prompt"
|
||||
};
|
||||
advancedPanelOpen: "editor-settings",
|
||||
modifiersPanelOpen: "editor-modifiers",
|
||||
negativePromptPanelOpen: "editor-inputs-prompt"
|
||||
}
|
||||
if (localStorage.getItem(Object.keys(old_map)[0])) {
|
||||
let result = {};
|
||||
Object.keys(old_map).forEach(key => {
|
||||
const value = localStorage.getItem(key);
|
||||
let result = {}
|
||||
Object.keys(old_map).forEach((key) => {
|
||||
const value = localStorage.getItem(key)
|
||||
if (value !== null) {
|
||||
result[old_map[key]] = (value == true || value == "true")
|
||||
result[old_map[key]] = value == true || value == "true"
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
});
|
||||
})
|
||||
result = JSON.stringify(result)
|
||||
localStorage.setItem(COLLAPSIBLES_KEY, result)
|
||||
return result
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
function permute(arr) {
|
||||
@ -134,10 +135,12 @@ function permute(arr) {
|
||||
let n_permutations = Math.pow(2, n)
|
||||
for (let i = 0; i < n_permutations; i++) {
|
||||
let perm = []
|
||||
let mask = Number(i).toString(2).padStart(n, '0')
|
||||
let mask = Number(i)
|
||||
.toString(2)
|
||||
.padStart(n, "0")
|
||||
|
||||
for (let idx = 0; idx < mask.length; idx++) {
|
||||
if (mask[idx] === '1' && arr[idx].trim() !== '') {
|
||||
if (mask[idx] === "1" && arr[idx].trim() !== "") {
|
||||
perm.push(arr[idx])
|
||||
}
|
||||
}
|
||||
@ -152,23 +155,23 @@ function permute(arr) {
|
||||
|
||||
// https://stackoverflow.com/a/8212878
|
||||
function millisecondsToStr(milliseconds) {
|
||||
function numberEnding (number) {
|
||||
return (number > 1) ? 's' : ''
|
||||
function numberEnding(number) {
|
||||
return number > 1 ? "s" : ""
|
||||
}
|
||||
|
||||
let temp = Math.floor(milliseconds / 1000)
|
||||
let hours = Math.floor((temp %= 86400) / 3600)
|
||||
let s = ''
|
||||
let s = ""
|
||||
if (hours) {
|
||||
s += hours + ' hour' + numberEnding(hours) + ' '
|
||||
s += hours + " hour" + numberEnding(hours) + " "
|
||||
}
|
||||
let minutes = Math.floor((temp %= 3600) / 60)
|
||||
if (minutes) {
|
||||
s += minutes + ' minute' + numberEnding(minutes) + ' '
|
||||
s += minutes + " minute" + numberEnding(minutes) + " "
|
||||
}
|
||||
let seconds = temp % 60
|
||||
if (!hours && minutes < 4 && seconds) {
|
||||
s += seconds + ' second' + numberEnding(seconds)
|
||||
s += seconds + " second" + numberEnding(seconds)
|
||||
}
|
||||
|
||||
return s
|
||||
@ -176,101 +179,82 @@ function millisecondsToStr(milliseconds) {
|
||||
|
||||
// https://rosettacode.org/wiki/Brace_expansion#JavaScript
|
||||
function BraceExpander() {
|
||||
'use strict'
|
||||
"use strict"
|
||||
|
||||
// Index of any closing brace matching the opening
|
||||
// brace at iPosn,
|
||||
// with the indices of any immediately-enclosed commas.
|
||||
function bracePair(tkns, iPosn, iNest, lstCommas) {
|
||||
if (iPosn >= tkns.length || iPosn < 0) return null;
|
||||
if (iPosn >= tkns.length || iPosn < 0) return null
|
||||
|
||||
let t = tkns[iPosn],
|
||||
n = (t === '{') ? (
|
||||
iNest + 1
|
||||
) : (t === '}' ? (
|
||||
iNest - 1
|
||||
) : iNest),
|
||||
lst = (t === ',' && iNest === 1) ? (
|
||||
lstCommas.concat(iPosn)
|
||||
) : lstCommas;
|
||||
n = t === "{" ? iNest + 1 : t === "}" ? iNest - 1 : iNest,
|
||||
lst = t === "," && iNest === 1 ? lstCommas.concat(iPosn) : lstCommas
|
||||
|
||||
return n ? bracePair(tkns, iPosn + 1, n, lst) : {
|
||||
close: iPosn,
|
||||
commas: lst
|
||||
};
|
||||
return n
|
||||
? bracePair(tkns, iPosn + 1, n, lst)
|
||||
: {
|
||||
close: iPosn,
|
||||
commas: lst
|
||||
}
|
||||
}
|
||||
|
||||
// Parse of a SYNTAGM subtree
|
||||
function andTree(dctSofar, tkns) {
|
||||
if (!tkns.length) return [dctSofar, []];
|
||||
|
||||
let dctParse = dctSofar ? dctSofar : {
|
||||
fn: and,
|
||||
args: []
|
||||
},
|
||||
if (!tkns.length) return [dctSofar, []]
|
||||
|
||||
let dctParse = dctSofar
|
||||
? dctSofar
|
||||
: {
|
||||
fn: and,
|
||||
args: []
|
||||
},
|
||||
head = tkns[0],
|
||||
tail = head ? tkns.slice(1) : [],
|
||||
dctBrace = head === "{" ? bracePair(tkns, 0, 0, []) : null,
|
||||
lstOR = dctBrace && dctBrace.close && dctBrace.commas.length ? splitAt(dctBrace.close + 1, tkns) : null
|
||||
|
||||
dctBrace = head === '{' ? bracePair(
|
||||
tkns, 0, 0, []
|
||||
) : null,
|
||||
|
||||
lstOR = dctBrace && (
|
||||
dctBrace.close
|
||||
) && dctBrace.commas.length ? (
|
||||
splitAt(dctBrace.close + 1, tkns)
|
||||
) : null;
|
||||
|
||||
return andTree({
|
||||
fn: and,
|
||||
args: dctParse.args.concat(
|
||||
lstOR ? (
|
||||
orTree(dctParse, lstOR[0], dctBrace.commas)
|
||||
) : head
|
||||
)
|
||||
}, lstOR ? (
|
||||
lstOR[1]
|
||||
) : tail);
|
||||
return andTree(
|
||||
{
|
||||
fn: and,
|
||||
args: dctParse.args.concat(lstOR ? orTree(dctParse, lstOR[0], dctBrace.commas) : head)
|
||||
},
|
||||
lstOR ? lstOR[1] : tail
|
||||
)
|
||||
}
|
||||
|
||||
// Parse of a PARADIGM subtree
|
||||
function orTree(dctSofar, tkns, lstCommas) {
|
||||
if (!tkns.length) return [dctSofar, []];
|
||||
let iLast = lstCommas.length;
|
||||
if (!tkns.length) return [dctSofar, []]
|
||||
let iLast = lstCommas.length
|
||||
|
||||
return {
|
||||
fn: or,
|
||||
args: splitsAt(
|
||||
lstCommas, tkns
|
||||
).map(function (x, i) {
|
||||
let ts = x.slice(
|
||||
1, i === iLast ? (
|
||||
-1
|
||||
) : void 0
|
||||
);
|
||||
args: splitsAt(lstCommas, tkns)
|
||||
.map(function(x, i) {
|
||||
let ts = x.slice(1, i === iLast ? -1 : void 0)
|
||||
|
||||
return ts.length ? ts : [''];
|
||||
}).map(function (ts) {
|
||||
return ts.length > 1 ? (
|
||||
andTree(null, ts)[0]
|
||||
) : ts[0];
|
||||
})
|
||||
};
|
||||
return ts.length ? ts : [""]
|
||||
})
|
||||
.map(function(ts) {
|
||||
return ts.length > 1 ? andTree(null, ts)[0] : ts[0]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// List of unescaped braces and commas, and remaining strings
|
||||
function tokens(str) {
|
||||
// Filter function excludes empty splitting artefacts
|
||||
let toS = function (x) {
|
||||
return x.toString();
|
||||
};
|
||||
let toS = function(x) {
|
||||
return x.toString()
|
||||
}
|
||||
|
||||
return str.split(/(\\\\)/).filter(toS).reduce(function (a, s) {
|
||||
return a.concat(s.charAt(0) === '\\' ? s : s.split(
|
||||
/(\\*[{,}])/
|
||||
).filter(toS));
|
||||
}, []);
|
||||
return str
|
||||
.split(/(\\\\)/)
|
||||
.filter(toS)
|
||||
.reduce(function(a, s) {
|
||||
return a.concat(s.charAt(0) === "\\" ? s : s.split(/(\\*[{,}])/).filter(toS))
|
||||
}, [])
|
||||
}
|
||||
|
||||
// PARSE TREE OPERATOR (1 of 2)
|
||||
@ -278,76 +262,75 @@ function BraceExpander() {
|
||||
function and(args) {
|
||||
let lng = args.length,
|
||||
head = lng ? args[0] : null,
|
||||
lstHead = "string" === typeof head ? (
|
||||
[head]
|
||||
) : head;
|
||||
lstHead = "string" === typeof head ? [head] : head
|
||||
|
||||
return lng ? (
|
||||
1 < lng ? lstHead.reduce(function (a, h) {
|
||||
return a.concat(
|
||||
and(args.slice(1)).map(function (t) {
|
||||
return h + t;
|
||||
})
|
||||
);
|
||||
}, []) : lstHead
|
||||
) : [];
|
||||
return lng
|
||||
? 1 < lng
|
||||
? lstHead.reduce(function(a, h) {
|
||||
return a.concat(
|
||||
and(args.slice(1)).map(function(t) {
|
||||
return h + t
|
||||
})
|
||||
)
|
||||
}, [])
|
||||
: lstHead
|
||||
: []
|
||||
}
|
||||
|
||||
// PARSE TREE OPERATOR (2 of 2)
|
||||
// Each option flattened
|
||||
function or(args) {
|
||||
return args.reduce(function (a, b) {
|
||||
return a.concat(b);
|
||||
}, []);
|
||||
return args.reduce(function(a, b) {
|
||||
return a.concat(b)
|
||||
}, [])
|
||||
}
|
||||
|
||||
// One list split into two (first sublist length n)
|
||||
function splitAt(n, lst) {
|
||||
return n < lst.length + 1 ? [
|
||||
lst.slice(0, n), lst.slice(n)
|
||||
] : [lst, []];
|
||||
return n < lst.length + 1 ? [lst.slice(0, n), lst.slice(n)] : [lst, []]
|
||||
}
|
||||
|
||||
// One list split into several (sublist lengths [n])
|
||||
function splitsAt(lstN, lst) {
|
||||
return lstN.reduceRight(function (a, x) {
|
||||
return splitAt(x, a[0]).concat(a.slice(1));
|
||||
}, [lst]);
|
||||
return lstN.reduceRight(
|
||||
function(a, x) {
|
||||
return splitAt(x, a[0]).concat(a.slice(1))
|
||||
},
|
||||
[lst]
|
||||
)
|
||||
}
|
||||
|
||||
// Value of the parse tree
|
||||
function evaluated(e) {
|
||||
return typeof e === 'string' ? e :
|
||||
e.fn(e.args.map(evaluated));
|
||||
return typeof e === "string" ? e : e.fn(e.args.map(evaluated))
|
||||
}
|
||||
|
||||
// JSON prettyprint (for parse tree, token list etc)
|
||||
function pp(e) {
|
||||
return JSON.stringify(e, function (k, v) {
|
||||
return typeof v === 'function' ? (
|
||||
'[function ' + v.name + ']'
|
||||
) : v;
|
||||
}, 2)
|
||||
return JSON.stringify(
|
||||
e,
|
||||
function(k, v) {
|
||||
return typeof v === "function" ? "[function " + v.name + "]" : v
|
||||
},
|
||||
2
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// ----------------------- MAIN ------------------------
|
||||
|
||||
// s -> [s]
|
||||
this.expand = function(s) {
|
||||
// BRACE EXPRESSION PARSED
|
||||
let dctParse = andTree(null, tokens(s))[0];
|
||||
let dctParse = andTree(null, tokens(s))[0]
|
||||
|
||||
// ABSTRACT SYNTAX TREE LOGGED
|
||||
// console.log(pp(dctParse));
|
||||
|
||||
// AST EVALUATED TO LIST OF STRINGS
|
||||
return evaluated(dctParse);
|
||||
return evaluated(dctParse)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Pause the execution of an async function until timer elapse.
|
||||
* @Returns a promise that will resolve after the specified timeout.
|
||||
*/
|
||||
@ -360,12 +343,12 @@ function asyncDelay(timeout) {
|
||||
function PromiseSource() {
|
||||
const srcPromise = new Promise((resolve, reject) => {
|
||||
Object.defineProperties(this, {
|
||||
resolve: { value: resolve, writable: false }
|
||||
, reject: { value: reject, writable: false }
|
||||
resolve: { value: resolve, writable: false },
|
||||
reject: { value: reject, writable: false }
|
||||
})
|
||||
})
|
||||
Object.defineProperties(this, {
|
||||
promise: {value: makeQuerablePromise(srcPromise), writable: false}
|
||||
promise: { value: makeQuerablePromise(srcPromise), writable: false }
|
||||
})
|
||||
}
|
||||
|
||||
@ -375,7 +358,7 @@ function PromiseSource() {
|
||||
* If `immediate` is passed, trigger the function on the leading edge, instead of the trailing.
|
||||
* @Returns a promise that will resolve to func return value.
|
||||
*/
|
||||
function debounce (func, wait, immediate) {
|
||||
function debounce(func, wait, immediate) {
|
||||
if (typeof wait === "undefined") {
|
||||
wait = 40
|
||||
}
|
||||
@ -399,11 +382,11 @@ function debounce (func, wait, immediate) {
|
||||
}
|
||||
return function(...args) {
|
||||
const callNow = Boolean(immediate && !timeout)
|
||||
const context = this;
|
||||
const context = this
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
timeout = setTimeout(function () {
|
||||
timeout = setTimeout(function() {
|
||||
if (!immediate) {
|
||||
applyFn(context, args)
|
||||
}
|
||||
@ -418,14 +401,14 @@ function debounce (func, wait, immediate) {
|
||||
}
|
||||
|
||||
function preventNonNumericalInput(e) {
|
||||
e = e || window.event;
|
||||
let charCode = (typeof e.which == "undefined") ? e.keyCode : e.which;
|
||||
let charStr = String.fromCharCode(charCode);
|
||||
let re = e.target.getAttribute('pattern') || '^[0-9]+$'
|
||||
e = e || window.event
|
||||
let charCode = typeof e.which == "undefined" ? e.keyCode : e.which
|
||||
let charStr = String.fromCharCode(charCode)
|
||||
let re = e.target.getAttribute("pattern") || "^[0-9]+$"
|
||||
re = new RegExp(re)
|
||||
|
||||
if (!charStr.match(re)) {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,15 +417,15 @@ function preventNonNumericalInput(e) {
|
||||
* @Notes Allows unit testing and use of the engine outside of a browser.
|
||||
*/
|
||||
function getGlobal() {
|
||||
if (typeof globalThis === 'object') {
|
||||
if (typeof globalThis === "object") {
|
||||
return globalThis
|
||||
} else if (typeof global === 'object') {
|
||||
} else if (typeof global === "object") {
|
||||
return global
|
||||
} else if (typeof self === 'object') {
|
||||
} else if (typeof self === "object") {
|
||||
return self
|
||||
}
|
||||
try {
|
||||
return Function('return this')()
|
||||
return Function("return this")()
|
||||
} catch {
|
||||
// If the Function constructor fails, we're in a browser with eval disabled by CSP headers.
|
||||
return window
|
||||
@ -453,18 +436,18 @@ function getGlobal() {
|
||||
* @Returns true if x is an Array or a TypedArray, false otherwise.
|
||||
*/
|
||||
function isArrayOrTypedArray(x) {
|
||||
return Boolean(typeof x === 'object' && (Array.isArray(x) || (ArrayBuffer.isView(x) && !(x instanceof DataView))))
|
||||
return Boolean(typeof x === "object" && (Array.isArray(x) || (ArrayBuffer.isView(x) && !(x instanceof DataView))))
|
||||
}
|
||||
|
||||
function makeQuerablePromise(promise) {
|
||||
if (typeof promise !== 'object') {
|
||||
throw new Error('promise is not an object.')
|
||||
if (typeof promise !== "object") {
|
||||
throw new Error("promise is not an object.")
|
||||
}
|
||||
if (!(promise instanceof Promise)) {
|
||||
throw new Error('Argument is not a promise.')
|
||||
throw new Error("Argument is not a promise.")
|
||||
}
|
||||
// Don't modify a promise that's been already modified.
|
||||
if ('isResolved' in promise || 'isRejected' in promise || 'isPending' in promise) {
|
||||
if ("isResolved" in promise || "isRejected" in promise || "isPending" in promise) {
|
||||
return promise
|
||||
}
|
||||
let isPending = true
|
||||
@ -473,13 +456,13 @@ function makeQuerablePromise(promise) {
|
||||
let isResolved = false
|
||||
let resolvedValue = undefined
|
||||
const qurPro = promise.then(
|
||||
function(val){
|
||||
function(val) {
|
||||
isResolved = true
|
||||
isPending = false
|
||||
resolvedValue = val
|
||||
return val
|
||||
}
|
||||
, function(reason) {
|
||||
},
|
||||
function(reason) {
|
||||
rejectReason = reason
|
||||
isRejected = true
|
||||
isPending = false
|
||||
@ -487,19 +470,19 @@ function makeQuerablePromise(promise) {
|
||||
}
|
||||
)
|
||||
Object.defineProperties(qurPro, {
|
||||
'isResolved': {
|
||||
isResolved: {
|
||||
get: () => isResolved
|
||||
}
|
||||
, 'resolvedValue': {
|
||||
},
|
||||
resolvedValue: {
|
||||
get: () => resolvedValue
|
||||
}
|
||||
, 'isPending': {
|
||||
},
|
||||
isPending: {
|
||||
get: () => isPending
|
||||
}
|
||||
, 'isRejected': {
|
||||
},
|
||||
isRejected: {
|
||||
get: () => isRejected
|
||||
}
|
||||
, 'rejectReason': {
|
||||
},
|
||||
rejectReason: {
|
||||
get: () => rejectReason
|
||||
}
|
||||
})
|
||||
@ -508,25 +491,25 @@ function makeQuerablePromise(promise) {
|
||||
|
||||
/* inserts custom html to allow prettifying of inputs */
|
||||
function prettifyInputs(root_element) {
|
||||
root_element.querySelectorAll(`input[type="checkbox"]`).forEach(element => {
|
||||
root_element.querySelectorAll(`input[type="checkbox"]`).forEach((element) => {
|
||||
if (element.style.display === "none") {
|
||||
return
|
||||
}
|
||||
var parent = element.parentNode;
|
||||
var parent = element.parentNode
|
||||
if (!parent.classList.contains("input-toggle")) {
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.classList.add("input-toggle");
|
||||
parent.replaceChild(wrapper, element);
|
||||
wrapper.appendChild(element);
|
||||
var label = document.createElement("label");
|
||||
label.htmlFor = element.id;
|
||||
wrapper.appendChild(label);
|
||||
var wrapper = document.createElement("div")
|
||||
wrapper.classList.add("input-toggle")
|
||||
parent.replaceChild(wrapper, element)
|
||||
wrapper.appendChild(element)
|
||||
var label = document.createElement("label")
|
||||
label.htmlFor = element.id
|
||||
wrapper.appendChild(label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
class GenericEventSource {
|
||||
#events = {};
|
||||
#events = {}
|
||||
#types = []
|
||||
constructor(...eventsTypes) {
|
||||
if (Array.isArray(eventsTypes) && eventsTypes.length === 1 && Array.isArray(eventsTypes[0])) {
|
||||
@ -541,7 +524,7 @@ class GenericEventSource {
|
||||
*/
|
||||
addEventListener(name, handler) {
|
||||
if (!this.#types.includes(name)) {
|
||||
throw new Error('Invalid event name.')
|
||||
throw new Error("Invalid event name.")
|
||||
}
|
||||
if (this.#events.hasOwnProperty(name)) {
|
||||
this.#events[name].push(handler)
|
||||
@ -574,13 +557,15 @@ class GenericEventSource {
|
||||
if (evs.length <= 0) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return Promise.allSettled(evs.map((callback) => {
|
||||
try {
|
||||
return Promise.resolve(callback.apply(SD, args))
|
||||
} catch (ex) {
|
||||
return Promise.reject(ex)
|
||||
}
|
||||
}))
|
||||
return Promise.allSettled(
|
||||
evs.map((callback) => {
|
||||
try {
|
||||
return Promise.resolve(callback.apply(SD, args))
|
||||
} catch (ex) {
|
||||
return Promise.reject(ex)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,7 +575,7 @@ class ServiceContainer {
|
||||
constructor(...servicesParams) {
|
||||
servicesParams.forEach(this.register.bind(this))
|
||||
}
|
||||
get services () {
|
||||
get services() {
|
||||
return this.#services
|
||||
}
|
||||
get singletons() {
|
||||
@ -598,54 +583,52 @@ class ServiceContainer {
|
||||
}
|
||||
register(params) {
|
||||
if (ServiceContainer.isConstructor(params)) {
|
||||
if (typeof params.name !== 'string') {
|
||||
throw new Error('params.name is not a string.')
|
||||
if (typeof params.name !== "string") {
|
||||
throw new Error("params.name is not a string.")
|
||||
}
|
||||
params = {name:params.name, definition:params}
|
||||
params = { name: params.name, definition: params }
|
||||
}
|
||||
if (typeof params !== 'object') {
|
||||
throw new Error('params is not an object.')
|
||||
if (typeof params !== "object") {
|
||||
throw new Error("params is not an object.")
|
||||
}
|
||||
[ 'name',
|
||||
'definition',
|
||||
].forEach((key) => {
|
||||
;["name", "definition"].forEach((key) => {
|
||||
if (!(key in params)) {
|
||||
console.error('Invalid service %o registration.', params)
|
||||
console.error("Invalid service %o registration.", params)
|
||||
throw new Error(`params.${key} is not defined.`)
|
||||
}
|
||||
})
|
||||
const opts = {definition: params.definition}
|
||||
if ('dependencies' in params) {
|
||||
const opts = { definition: params.definition }
|
||||
if ("dependencies" in params) {
|
||||
if (Array.isArray(params.dependencies)) {
|
||||
params.dependencies.forEach((dep) => {
|
||||
if (typeof dep !== 'string') {
|
||||
throw new Error('dependency name is not a string.')
|
||||
if (typeof dep !== "string") {
|
||||
throw new Error("dependency name is not a string.")
|
||||
}
|
||||
})
|
||||
opts.dependencies = params.dependencies
|
||||
} else {
|
||||
throw new Error('params.dependencies is not an array.')
|
||||
throw new Error("params.dependencies is not an array.")
|
||||
}
|
||||
}
|
||||
if (params.singleton) {
|
||||
opts.singleton = true
|
||||
}
|
||||
this.#services.set(params.name, opts)
|
||||
return Object.assign({name: params.name}, opts)
|
||||
return Object.assign({ name: params.name }, opts)
|
||||
}
|
||||
get(name) {
|
||||
const ctorInfos = this.#services.get(name)
|
||||
if (!ctorInfos) {
|
||||
return
|
||||
}
|
||||
if(!ServiceContainer.isConstructor(ctorInfos.definition)) {
|
||||
if (!ServiceContainer.isConstructor(ctorInfos.definition)) {
|
||||
return ctorInfos.definition
|
||||
}
|
||||
if(!ctorInfos.singleton) {
|
||||
if (!ctorInfos.singleton) {
|
||||
return this._createInstance(ctorInfos)
|
||||
}
|
||||
const singletonInstance = this.#singletons.get(name)
|
||||
if(singletonInstance) {
|
||||
if (singletonInstance) {
|
||||
return singletonInstance
|
||||
}
|
||||
const newSingletonInstance = this._createInstance(ctorInfos)
|
||||
@ -655,7 +638,7 @@ class ServiceContainer {
|
||||
|
||||
_getResolvedDependencies(service) {
|
||||
let classDependencies = []
|
||||
if(service.dependencies) {
|
||||
if (service.dependencies) {
|
||||
classDependencies = service.dependencies.map(this.get.bind(this))
|
||||
}
|
||||
return classDependencies
|
||||
@ -671,10 +654,14 @@ class ServiceContainer {
|
||||
}
|
||||
|
||||
static isClass(definition) {
|
||||
return typeof definition === 'function' && Boolean(definition.prototype) && definition.prototype.constructor === definition
|
||||
return (
|
||||
typeof definition === "function" &&
|
||||
Boolean(definition.prototype) &&
|
||||
definition.prototype.constructor === definition
|
||||
)
|
||||
}
|
||||
static isConstructor(definition) {
|
||||
return typeof definition === 'function'
|
||||
return typeof definition === "function"
|
||||
}
|
||||
}
|
||||
|
||||
@ -693,14 +680,14 @@ function createElement(tagName, attributes, classes, textOrElements) {
|
||||
if (value !== undefined && value !== null) {
|
||||
element.setAttribute(key, value)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
if (classes) {
|
||||
(Array.isArray(classes) ? classes : [classes]).forEach(className => element.classList.add(className))
|
||||
;(Array.isArray(classes) ? classes : [classes]).forEach((className) => element.classList.add(className))
|
||||
}
|
||||
if (textOrElements) {
|
||||
const children = Array.isArray(textOrElements) ? textOrElements : [textOrElements]
|
||||
children.forEach(textOrElem => {
|
||||
children.forEach((textOrElem) => {
|
||||
if (textOrElem instanceof Node) {
|
||||
element.appendChild(textOrElem)
|
||||
} else {
|
||||
@ -750,33 +737,33 @@ Array.prototype.addEventListener = function(method, callback) {
|
||||
/**
|
||||
* @param {CreateTabRequest} request
|
||||
*/
|
||||
function createTab(request) {
|
||||
function createTab(request) {
|
||||
if (!request?.id) {
|
||||
console.error('createTab() error - id is required', Error().stack)
|
||||
console.error("createTab() error - id is required", Error().stack)
|
||||
return
|
||||
}
|
||||
|
||||
if (!request.label) {
|
||||
console.error('createTab() error - label is required', Error().stack)
|
||||
console.error("createTab() error - label is required", Error().stack)
|
||||
return
|
||||
}
|
||||
|
||||
if (!request.icon) {
|
||||
console.error('createTab() error - icon is required', Error().stack)
|
||||
console.error("createTab() error - icon is required", Error().stack)
|
||||
return
|
||||
}
|
||||
|
||||
if (!request.content && !request.onOpen) {
|
||||
console.error('createTab() error - content or onOpen required', Error().stack)
|
||||
console.error("createTab() error - content or onOpen required", Error().stack)
|
||||
return
|
||||
}
|
||||
|
||||
const tabsContainer = document.querySelector('.tab-container')
|
||||
const tabsContainer = document.querySelector(".tab-container")
|
||||
if (!tabsContainer) {
|
||||
return
|
||||
}
|
||||
|
||||
const tabsContentWrapper = document.querySelector('#tab-content-wrapper')
|
||||
const tabsContentWrapper = document.querySelector("#tab-content-wrapper")
|
||||
if (!tabsContentWrapper) {
|
||||
return
|
||||
}
|
||||
@ -784,41 +771,37 @@ Array.prototype.addEventListener = function(method, callback) {
|
||||
// console.debug('creating tab: ', request)
|
||||
|
||||
if (request.css) {
|
||||
document.querySelector('body').insertAdjacentElement(
|
||||
'beforeend',
|
||||
createElement('style', { id: `tab-${request.id}-css` }, undefined, request.css),
|
||||
)
|
||||
document
|
||||
.querySelector("body")
|
||||
.insertAdjacentElement(
|
||||
"beforeend",
|
||||
createElement("style", { id: `tab-${request.id}-css` }, undefined, request.css)
|
||||
)
|
||||
}
|
||||
|
||||
const label = typeof request.label === 'function' ? request.label() : request.label
|
||||
const labelElement = label instanceof Node ? label : createElement('span', undefined, undefined, label)
|
||||
const label = typeof request.label === "function" ? request.label() : request.label
|
||||
const labelElement = label instanceof Node ? label : createElement("span", undefined, undefined, label)
|
||||
|
||||
const tab = createElement(
|
||||
'span',
|
||||
{ id: `tab-${request.id}`, 'data-times-opened': 0 },
|
||||
['tab'],
|
||||
createElement(
|
||||
'span',
|
||||
undefined,
|
||||
undefined,
|
||||
[
|
||||
createElement(
|
||||
'i',
|
||||
{ style: 'margin-right: 0.25em' },
|
||||
['fa-solid', `${request.icon.startsWith('fa-') ? '' : 'fa-'}${request.icon}`, 'icon'],
|
||||
),
|
||||
labelElement,
|
||||
],
|
||||
)
|
||||
"span",
|
||||
{ id: `tab-${request.id}`, "data-times-opened": 0 },
|
||||
["tab"],
|
||||
createElement("span", undefined, undefined, [
|
||||
createElement("i", { style: "margin-right: 0.25em" }, [
|
||||
"fa-solid",
|
||||
`${request.icon.startsWith("fa-") ? "" : "fa-"}${request.icon}`,
|
||||
"icon"
|
||||
]),
|
||||
labelElement
|
||||
])
|
||||
)
|
||||
|
||||
tabsContainer.insertAdjacentElement("beforeend", tab)
|
||||
|
||||
tabsContainer.insertAdjacentElement('beforeend', tab)
|
||||
const wrapper = createElement("div", { id: request.id }, ["tab-content-inner"], "Loading..")
|
||||
|
||||
const wrapper = createElement('div', { id: request.id }, ['tab-content-inner'], 'Loading..')
|
||||
|
||||
const tabContent = createElement('div', { id: `tab-content-${request.id}` }, ['tab-content'], wrapper)
|
||||
tabsContentWrapper.insertAdjacentElement('beforeend', tabContent)
|
||||
const tabContent = createElement("div", { id: `tab-content-${request.id}` }, ["tab-content"], wrapper)
|
||||
tabsContentWrapper.insertAdjacentElement("beforeend", tabContent)
|
||||
|
||||
linkTabContents(tab)
|
||||
|
||||
@ -826,7 +809,7 @@ Array.prototype.addEventListener = function(method, callback) {
|
||||
if (resultFactory === undefined || resultFactory === null) {
|
||||
return
|
||||
}
|
||||
const result = typeof resultFactory === 'function' ? resultFactory() : resultFactory
|
||||
const result = typeof resultFactory === "function" ? resultFactory() : resultFactory
|
||||
if (result instanceof Promise) {
|
||||
result.then(replaceContent)
|
||||
} else if (result instanceof Node) {
|
||||
@ -838,7 +821,7 @@ Array.prototype.addEventListener = function(method, callback) {
|
||||
|
||||
replaceContent(request.content)
|
||||
|
||||
tab.addEventListener('click', (e) => {
|
||||
tab.addEventListener("click", (e) => {
|
||||
const timesOpened = +(tab.dataset.timesOpened || 0) + 1
|
||||
tab.dataset.timesOpened = timesOpened
|
||||
|
||||
@ -848,9 +831,9 @@ Array.prototype.addEventListener = function(method, callback) {
|
||||
contentElement: wrapper,
|
||||
labelElement,
|
||||
timesOpened,
|
||||
firstOpen: timesOpened === 1,
|
||||
firstOpen: timesOpened === 1
|
||||
},
|
||||
e,
|
||||
e
|
||||
)
|
||||
|
||||
replaceContent(result)
|
||||
|
Reference in New Issue
Block a user