jqx-es 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,464 @@
1
+ /**
2
+ generated (synced) file for:
3
+ - lifeCSS
4
+ - typeofAnything
5
+ Last updated on 03-06-2025 11:30:28
6
+ */
7
+
8
+ /* typeOfAnything */
9
+ const { IS, maybe, $Wrap, xProxy, isNothing } = TOAFactory();
10
+ function TOAFactory() {
11
+ Symbol.proxy = Symbol.for(`toa.proxy`);
12
+ Symbol.is = Symbol.for(`toa.is`);
13
+ Symbol.type = Symbol.for(`toa.type`);
14
+ Symbol.isSymbol = Symbol.for(`toa.isASymbol`);
15
+ addSymbols2Anything();
16
+ const maybe = maybeFactory();
17
+ const [$Wrap, xProxy] = [WrapAnyFactory(), setProxyFactory()];
18
+ xProxy.custom();
19
+ return {IS, maybe, $Wrap, isNothing, xProxy};
20
+
21
+ function IS(anything, ...shouldBe) {
22
+ if (maybe({trial: _ => `isTypes` in (shouldBe?.[0] ?? {})})) {
23
+ const isTypeObj = shouldBe[0];
24
+ return `defaultValue` in (isTypeObj)
25
+ ? isOrDefault(anything, isTypeObj) : `notTypes` in isTypeObj
26
+ ? isExcept(anything, isTypeObj) : IS(anything, ...[isTypeObj.isTypes].flat());
27
+ }
28
+
29
+ const input = typeof anything === `symbol` ? Symbol.isSymbol : anything;
30
+ return shouldBe.length > 1 ? ISOneOf(input, ...shouldBe) : determineType(anything, ...shouldBe);
31
+ }
32
+
33
+ function typeOf(anything) {
34
+ return anything?.[Symbol.proxy] ?? IS(anything);
35
+ }
36
+
37
+ function determineType(input, ...shouldBe) {
38
+ let {
39
+ noInput,
40
+ noShouldbe,
41
+ compareTo,
42
+ inputCTOR,
43
+ isNaN,
44
+ isInfinity,
45
+ shouldBeFirstElementIsNothing
46
+ } = processInput(input, ...shouldBe);
47
+ shouldBe = shouldBe.length && shouldBe[0];
48
+
49
+ switch (true) {
50
+ case shouldBeFirstElementIsNothing:
51
+ return String(input) === String(compareTo);
52
+ case input?.[Symbol.proxy] && noShouldbe:
53
+ return input[Symbol.proxy];
54
+ case isNaN:
55
+ return noShouldbe ? `NaN` : maybe({trial: _ => String(compareTo)}) === String(input);
56
+ case isInfinity:
57
+ return noShouldbe ? `Infinity` : maybe({trial: _ => String(compareTo)}) === String(input);
58
+ case noInput:
59
+ return noShouldbe ? String(input) : String(compareTo) === String(input);
60
+ case inputCTOR === Boolean:
61
+ return !shouldBe ? `Boolean` : inputCTOR === shouldBe;
62
+ default:
63
+ return getResult(input, shouldBe, noShouldbe, getMe(input, inputCTOR));
64
+ }
65
+ }
66
+
67
+ function getMe(input, inputCTOR) {
68
+ return input === 0 ? Number : input === `` ? String : !input ? {name: String(input)} : inputCTOR;
69
+ }
70
+
71
+ function processInput(input, ...shouldBe) {
72
+ const noShouldbe = shouldBe.length < 1;
73
+ const compareTo = !noShouldbe && shouldBe[0];
74
+ const shouldBeFirstElementIsNothing = !noShouldbe && isNothing(shouldBe[0]);
75
+ const noInput = input === undefined || input === null;
76
+ const inputCTOR = !noInput && Object.getPrototypeOf(input)?.constructor;
77
+ const isNaN = Number.isNaN(input) || maybe({trial: _ => String(input) === `NaN`});
78
+ const isInfinity = maybe({trial: _ => String(input)}) === `Infinity`;
79
+ return {noInput, noShouldbe, compareTo, inputCTOR, isNaN, isInfinity, shouldBeFirstElementIsNothing};
80
+ }
81
+
82
+ function getResult(input, compareWith, noShouldbe, me) {
83
+ switch(true) {
84
+ case (!noShouldbe && compareWith === input) ||
85
+ (input?.[Symbol.proxy] && compareWith === Proxy):
86
+ return true;
87
+ case maybe({trial: _ => String(compareWith)}) === `NaN`:
88
+ return String(input) === `NaN`;
89
+ case input?.[Symbol.toStringTag] && IS(compareWith, String):
90
+ return String(compareWith) === input[Symbol.toStringTag];
91
+ default:
92
+ return compareWith
93
+ ? maybe({trial: _ => input instanceof compareWith,}) ||
94
+ compareWith === me || compareWith === Object.getPrototypeOf(me) ||
95
+ `${compareWith?.name}` === me?.name
96
+ : input?.[Symbol.toStringTag] && `[object ${input?.[Symbol.toStringTag]}]` ||
97
+ me?.name ||
98
+ String(me);
99
+ }
100
+ }
101
+
102
+ function ISOneOf(obj, ...params) {
103
+ return params.some(param => IS(obj, param));
104
+ }
105
+
106
+ function isNothing(maybeNothing, all = false) {
107
+ let nada = maybeNothing === null || maybeNothing === undefined;
108
+ nada = all ? nada || IS(maybeNothing, Infinity) || IS(maybeNothing, NaN) : nada;
109
+ return nada;
110
+ }
111
+
112
+ function maybeFactory() {
113
+ const tryFn = (maybeFn, maybeError) => maybeFn?.constructor === Function ? maybeFn(maybeError) : undefined;
114
+ return function ({trial, whenError = () => undefined} = {}) {
115
+ try {
116
+ return tryFn(trial)
117
+ } catch (err) {
118
+ return tryFn(whenError, err)
119
+ }
120
+ };
121
+ }
122
+
123
+ function WrapAnyFactory() {
124
+ return function (someObj) {
125
+ return Object.freeze({
126
+ get value() { return someObj; },
127
+ get [Symbol.type]() { return typeOf(someObj); },
128
+ get type() { return typeOf(someObj); },
129
+ [Symbol.is](...args) { return IS(someObj, ...args); },
130
+ is(...args) { return IS(someObj, ...args); }
131
+ });
132
+ }
133
+ }
134
+
135
+ function isOrDefault(input, {defaultValue, isTypes = [undefined], notTypes} = {}) {
136
+ isTypes = isTypes?.constructor !== Array ? [isTypes] : isTypes;
137
+ notTypes = notTypes && notTypes?.constructor !== Array ? [notTypes] : [];
138
+ return notTypes.length < 1
139
+ ? IS(input, ...isTypes) ? input : defaultValue
140
+ : isExcept(input, {isTypes, notTypes}) ? input : defaultValue;
141
+ }
142
+
143
+ function isExcept(input, {isTypes = [undefined], notTypes = [undefined]} = {}) {
144
+ isTypes = isTypes?.constructor !== Array ? [isTypes] : isTypes;
145
+ notTypes = notTypes?.constructor !== Array ? [notTypes] : notTypes;
146
+ return IS(input, ...isTypes) && !IS(input, ...notTypes);
147
+ }
148
+
149
+ function addSymbols2Anything() {
150
+ if (!Object.getOwnPropertyDescriptors(Object.prototype)[Symbol.is]) {
151
+ Object.defineProperties(Object.prototype, {
152
+ [Symbol.type]: { get() { return typeOf(this); }, enumerable: false, configurable: false },
153
+ [Symbol.is]: { value: function (...args) { return IS(this, ...args); }, enumerable: false, configurable: false },
154
+ });
155
+ Object.defineProperties(Object, {
156
+ [Symbol.type]: { value(obj) { return typeOf(obj); }, enumerable: false, configurable: false },
157
+ [Symbol.is]: { value: function (obj, ...args) { return IS(obj, ...args); }, enumerable: false, configurable: false },
158
+ });
159
+ }
160
+ }
161
+
162
+ function ctor2String(obj) {
163
+ const str = String(Object.getPrototypeOf(obj)?.constructor);
164
+ return str.slice(str.indexOf(`ion`) + 3, str.indexOf(`(`)).trim();
165
+ }
166
+
167
+ function modifySetter(setterMethod2Modify) {
168
+ const oldSetter = setterMethod2Modify.set;
169
+ setterMethod2Modify.set = (target, key, value) => {
170
+ if (key === Symbol.proxy) {
171
+ return target[key] = value;
172
+ }
173
+
174
+ return oldSetter(target, key, value);
175
+ }
176
+
177
+ return setterMethod2Modify;
178
+ }
179
+
180
+ function setProxyFactory() {
181
+ const nativeProxy = Proxy;
182
+ return {
183
+ native() {
184
+ Proxy = nativeProxy;
185
+ },
186
+ custom() {
187
+ // adaptation of https://stackoverflow.com/a/53463589
188
+ Proxy = new nativeProxy(nativeProxy, {
189
+ construct(target, args) {
190
+ for (let item of args) {
191
+ if (item.set) {
192
+ item = modifySetter(item);
193
+ }
194
+ }
195
+
196
+ const wrappedProxy = new target(...args);
197
+ wrappedProxy[Symbol.proxy] = `Proxy (${ctor2String(args[0])})`;
198
+ return wrappedProxy;
199
+ }
200
+ })
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+
207
+ /* lifeCSS */
208
+ function LifeStyleFactory({styleSheet, createWithId} = {}) {
209
+ const { tryParseAtOrNestedRules, ruleExists, checkParams,
210
+ sheet, removeRules, consider, currentSheetID } = sheetHelpers({styleSheet, createWithId});
211
+
212
+ function setRules4Selector(rule, properties) {
213
+ if (rule && properties.removeProperties) {
214
+ Object.keys(properties.removeProperties)
215
+ .forEach( prop => rule.style.removeProperty(toDashedNotation(prop)) );
216
+ return;
217
+ }
218
+
219
+ Object.entries(properties)
220
+ .forEach( ([prop, value]) => {
221
+ prop = toDashedNotation(prop.trim());
222
+ value = value.trim();
223
+
224
+ let priority;
225
+
226
+ if (/!important/.test(value)) {
227
+ value = value.slice(0, value.indexOf(`!important`)).trim();
228
+ priority = `important`;
229
+ }
230
+
231
+ if (!CSS.supports(prop, value)) {
232
+ return console.error(`StylingFactory ${currentSheetID} error: '${
233
+ prop}' with value '${value}' not supported (yet)`);
234
+ }
235
+
236
+ tryAndCatch( () => rule.style.setProperty(prop, value, priority),
237
+ `StylingFactory ${currentSheetID} (setRule4Selector) failed`);
238
+ });
239
+ }
240
+
241
+ function setRules(selector, styleRules, sheetOrMediaRules = sheet) {
242
+ selector = selector?.trim?.();
243
+ if (!IS(selector, String) || !selector.length || /[;,]$/g.test(selector)) {
244
+ return console.error(`StylingFactory ${currentSheetID} (setRules): [${
245
+ selector || `[no selector given]` }] is not a valid selector`);
246
+ }
247
+
248
+ if (styleRules.removeRule) {
249
+ return removeRules(selector);
250
+ }
251
+
252
+ const exists = ruleExists(selector, true);
253
+ const rule4Selector = exists
254
+ || sheetOrMediaRules.cssRules[sheetOrMediaRules.insertRule(`${selector} {}`, sheetOrMediaRules.cssRules.length || 0)];
255
+
256
+ return consider( () => setRules4Selector(rule4Selector, styleRules), selector, exists );
257
+ }
258
+
259
+ function doParse(cssDeclarationString) {
260
+ const rule = cssDeclarationString.trim().split(/{/, 2);
261
+ const selector = rule.shift().trim();
262
+
263
+ if (!IS(selector, String) || !selector?.trim()?.length) {
264
+ return console.error(`StylingFactory ${currentSheetID} (doParse): no (valid) selector could be extracted from rule ${
265
+ shortenRule(cssDeclarationString)}`);
266
+ }
267
+
268
+ const cssRules = cssRuleFromText(rule.shift());
269
+
270
+ return tryAndCatch( () => setRules(selector, cssRules), `StylingFactory ${currentSheetID} (setRules) failed` );
271
+ }
272
+
273
+ function styleFromString(cssDeclarationString) {
274
+ const checkAts = tryParseAtOrNestedRules(cssDeclarationString);
275
+ return checkAts.done ? checkAts.existing : doParse(cssDeclarationString);
276
+ }
277
+
278
+ function styleFromObject(selector, rulesObj) {
279
+ if (selector.trim().startsWith(`@media`)) {
280
+ return styleFromString(atMedia2String(selector, rulesObj));
281
+ }
282
+ return setRules(selector, rulesObj);
283
+ }
284
+
285
+ return function(cssBlockOrSelector, rulesObj = {}) {
286
+ const checksOk = checkParams(cssBlockOrSelector, rulesObj);
287
+
288
+ return checksOk && (
289
+ Object.keys(rulesObj).length ?
290
+ styleFromObject(cssBlockOrSelector, rulesObj) :
291
+ styleFromString(cssBlockOrSelector) );
292
+ };
293
+ }
294
+
295
+
296
+
297
+ function sheetHelpers({styleSheet, createWithId}) {
298
+ const notification = `Note: The rule or some of its properties may not be supported by your browser (yet)`;
299
+ const currentSheetID = `for style#${createWithId}`;
300
+ styleSheet = createWithId ? retrieveOrCreateSheet(createWithId) : styleSheet;
301
+
302
+ function retrieveOrCreateSheet(id) {
303
+ const existingSheet = document.querySelector(`#${id}`)?.sheet;
304
+
305
+ if (existingSheet) { return existingSheet; }
306
+
307
+ const newSheet = Object.assign(document.createElement(`style`), { id });
308
+ document.head.insertAdjacentElement(`beforeend`, newSheet);
309
+ return newSheet.sheet;
310
+ }
311
+
312
+ function notSupported(rule) {
313
+ console.error(`StylingFactory ${currentSheetID} [rule: ${rule}]
314
+ => @charset, @namespace and @import are not supported here`);
315
+ return {done: true};
316
+ }
317
+
318
+ function ruleExists(ruleFragOrSelector, isSelector) {
319
+ return [...styleSheet.rules].find( r =>
320
+ isSelector ?
321
+ compareSelectors((r.selectorText || ``), ruleFragOrSelector) :
322
+ createRE`${escape4RegExp(ruleFragOrSelector)}${[...`gim`]}`.test(r.cssText));
323
+ }
324
+
325
+ function tryParseAtOrNestedRules(cssDeclarationString) {
326
+ if (/^@charset|@import|namespace/i.test(cssDeclarationString.trim())) {
327
+ return notSupported(cssDeclarationString);
328
+ }
329
+
330
+ if (cssDeclarationString.match(/}/g)?.length > 1) {
331
+ return {existing: tryParse(cssDeclarationString, 1), done: true}
332
+ }
333
+
334
+ return { done: false };
335
+ }
336
+
337
+ function removeRules(selector) {
338
+ const rulesAt = [...styleSheet.cssRules].reduce( (acc, v, i) =>
339
+ compareSelectors(v.selectorText || ``, selector) && acc.concat(i) || acc, [] );
340
+ const len = rulesAt.length;
341
+ rulesAt.forEach(idx => styleSheet.deleteRule(idx));
342
+
343
+ return len > 0
344
+ ? console.info(`✔ Removed ${len} instance${len > 1 ? `s` : ``} of selector ${
345
+ selector} from ${currentSheetID.slice(4)}`)
346
+ : console.info(`✔ Remove rule: selector ${selector} does not exist in ${
347
+ currentSheetID.slice(4)}`);
348
+ }
349
+
350
+ function checkParams(cssBlockOrSelector, rulesObj) {
351
+ return cssBlockOrSelector
352
+ && IS(cssBlockOrSelector, String)
353
+ && cssBlockOrSelector.trim().length > 0
354
+ && IS(rulesObj, Object) ||
355
+ (console.error(`StylingFactory ${currentSheetID} called with invalid parameters`), false);
356
+ }
357
+
358
+ function tryParse(cssDeclarationString) {
359
+ cssDeclarationString = cssDeclarationString.trim();
360
+ const rule = cssDeclarationString.slice(0, cssDeclarationString.indexOf(`{`)).trim();
361
+ const exists = !!ruleExists(rule);
362
+
363
+ try {
364
+ return (styleSheet.insertRule(`${cssDeclarationString}`, styleSheet.cssRules.length), exists);
365
+ } catch(err) {
366
+ return (console.error(`StylingFactory ${currentSheetID} (tryParse) ${err.name} Error:\n${
367
+ err.message}\nRule: ${
368
+ shortenRule(cssDeclarationString)}\n${
369
+ notification}`),
370
+ exists);
371
+ }
372
+ }
373
+
374
+ function consider(fn, rule, existing) {
375
+ try {
376
+ return (fn(), existing);
377
+ } catch(err) {
378
+ return (
379
+ console.error(`StylingFactory ${currentSheetID} (tryAddOrModify) ${err.name} Error:\n${
380
+ err.message}\nRule: ${shortenRule(rule)}\n${notification}`),
381
+ existing
382
+ );
383
+ }
384
+ }
385
+
386
+ return {
387
+ sheet: styleSheet, removeRules, tryParseAtOrNestedRules,
388
+ ruleExists, checkParams, tryParse, consider,
389
+ currentSheetID };
390
+ }
391
+
392
+
393
+
394
+ function atMedia2String(selector, rulesObj) {
395
+ return `${selector.trim()} ${
396
+ Object.entries(rulesObj).map( ( [ selectr, rule] ) =>
397
+ `${selectr}: { ${stringifyMediaRule(rule) }` ) }`;
398
+ }
399
+
400
+ function shortenRule(rule) {
401
+ const shortRule = (rule || `NO RULE`).trim().slice(0, 50).replace(/\n/g, `\\n`).replace(/\s{2,}/g, ` `);
402
+ return rule.length > shortRule.length ? `${shortRule.trim()}...truncated` : shortRule;
403
+ }
404
+
405
+ function stringifyMediaRule(mediaObj) {
406
+ return Object.entries(mediaObj)
407
+ .map( ([key, value]) => `${key}: ${value.trim()}`).join(`;\n`);
408
+ }
409
+
410
+ function escape4RegExp(str) {
411
+ return str.replace(/([*\[\]()-+{}.$?\\])/g, a => `\\${a}`);
412
+ }
413
+
414
+ function createRE(regexStr, ...args) {
415
+ const flags = args.length && Array.isArray(args.slice(-1)) ? args.pop().join(``) : ``;
416
+
417
+ return new RegExp(
418
+ (args.length &&
419
+ regexStr.raw.reduce( (a, v, i ) => a.concat(args[i-1] || ``).concat(v), ``) ||
420
+ regexStr.raw.join(``))
421
+ .split(`\n`)
422
+ .map( line => line.replace(/\s|\/\/.*$/g, ``).trim().replace(/(@s!)/g, ` `) )
423
+ .join(``), flags);
424
+ }
425
+
426
+ function toDashedNotation(str2Convert) {
427
+ return str2Convert.replace(/[A-Z]/g, a => `-${a.toLowerCase()}`).replace(/[^--]^-|-$/, ``);
428
+ }
429
+
430
+ function tryAndCatch(fn, msg) {
431
+ try { return fn(); }
432
+ catch(err) { console.error( `${msg || `an error occured`}: ${err.message}` ); }
433
+ }
434
+
435
+ function prepareCssRuleFromText(rule) {
436
+ return rule
437
+ .replace(/\/\*.+?\*\//gm, ``)
438
+ .replace(/[}{\r\n]/g, ``)
439
+ .replace(/(data:.+?);/g, (_,b) => `${b}\\3b`)
440
+ .split(`;`)
441
+ .map(l => l.trim())
442
+ .join(`;\n`)
443
+ .replaceAll(`\\3b`, `;`)
444
+ .split(`\n`);
445
+ }
446
+
447
+ function toRuleObject(preparedRule) {
448
+ return preparedRule
449
+ .reduce( (acc, v) => {
450
+ const [key, value] = [
451
+ v.slice(0, v.indexOf(`:`)).trim(),
452
+ v.slice(v.indexOf(`:`) + 1).trim().replace(/;$|;.+(?=\/*).+\/$/, ``)];
453
+ return key && value ? {...acc, [key]: value} : acc; }, {} );
454
+ }
455
+
456
+ function cssRuleFromText(rule) {
457
+ return toRuleObject(prepareCssRuleFromText(rule));
458
+ }
459
+
460
+ function compareSelectors(s1, s2) {
461
+ return s1?.replace(`::`, `:`) === s2?.replace(`::`, `:`);
462
+ }
463
+
464
+ export {IS, maybe, LifeStyleFactory};
@@ -0,0 +1,126 @@
1
+ import jqx from "../index.js";
2
+ import {default as tagFNFactory} from "./tinyDOM.js";
3
+ import { IS, maybe, LifeStyleFactory as styleFactory } from "./SyncedExternals.js";
4
+ const characters4RandomString = [...Array(26)]
5
+ .map((x, i) => String.fromCharCode(i + 65))
6
+ .concat([...Array(26)].map((x, i) => String.fromCharCode(i + 97)))
7
+ .concat([...Array(10)].map((x, i) => `${i}`));
8
+ const pad0 = (nr, n=2) => `${nr}`.padStart(n, `0`);
9
+ const randomNr = (max, min = 0) => {
10
+ [max, min] = [Math.floor(max), Math.ceil(min)];
11
+ return Math.floor( ([...crypto.getRandomValues(new Uint32Array(1))].shift() / 2 ** 32 ) * (max - min + 1) + min );
12
+ };
13
+ const shuffle = array => {
14
+ let i = array.length;
15
+ while (i--) {
16
+ const ri = randomNr(i);
17
+ [array[i], array[ri]] = [array[ri], array[i]];
18
+ }
19
+ return array;
20
+ };
21
+ const hex2Full = hex => {
22
+ hex = (hex.trim().startsWith("#") ? hex.slice(1) : hex).trim();
23
+ return hex.length === 3 ? [...hex].map(v => v + v).join("") : hex;
24
+ };
25
+ const truncateHtmlStr = (str, maxLength = 120) => `${str}`.trim()
26
+ .slice(0, maxLength)
27
+ .replace(/>\s+</g, `><`)
28
+ .replace(/</g, `&lt;`)
29
+ .replace(/\s{2,}/g, ` `)
30
+ .replace(/\n/g, `\\n`) + (str.length > maxLength ? ` &hellip;` : ``).trim();
31
+ const toDashedNotation = str2Convert =>str2Convert.replace(/[A-Z]/g, a => `-${a.toLowerCase()}`).replace(/^-|-$/, ``);
32
+ const ucFirst = ([first, ...theRest]) => `${first.toUpperCase()}${theRest.join(``)}`;
33
+ const toCamelcase = str2Convert =>
34
+ IS(str2Convert, String) ? str2Convert.toLowerCase()
35
+ .split(`-`)
36
+ .map( (str, i) => i && `${ucFirst(str)}` || str)
37
+ .join(``) : str2Convert;
38
+ const randomString = () => `_${shuffle(characters4RandomString).slice(0, 8).join(``)}`;
39
+ const truncate2SingleStr = (str, maxLength = 120) =>
40
+ truncateHtmlStr(str, maxLength).replace(/&lt;/g, `<`);
41
+ const logTime = () => ((d) =>
42
+ `[${pad0(d.getHours())}:${pad0(d.getMinutes())}:${
43
+ pad0(d.getSeconds())}.${pad0(d.getMilliseconds(), 3)}]`)(new Date());
44
+ const hex2RGBA = function (hex, opacity = 100) {
45
+ hex = hex2Full(hex.slice(1));
46
+ const op = opacity % 100 !== 0;
47
+ return `rgb${op ? "a" : ""}(${
48
+ parseInt(hex.slice(0, 2), 16)}, ${
49
+ parseInt(hex.slice(2, 4), 16)}, ${
50
+ parseInt(hex.slice(-2), 16)}${op ? `, ${opacity / 100}` : ""})`;
51
+ };
52
+ const escHtml = html => html.replace(/</g, `&lt;`);
53
+
54
+ function ExamineElementFeatureFactory() {
55
+ const isVisible = function(el) {
56
+ if (!el) { return undefined; }
57
+ const elStyle = el.style;
58
+ const computedStyle = getComputedStyle(el);
59
+ const invisible = [elStyle.visibility, computedStyle.visibility].includes("hidden");
60
+ const noDisplay = [elStyle.display, computedStyle.display].includes("none");
61
+ const offscreen = el.offsetTop < 0 || (el.offsetLeft + el.offsetWidth) < 0
62
+ || el.offsetLeft > document.body.offsetWidth;
63
+ const noOpacity = +computedStyle.opacity === 0 || +(elStyle.opacity || 1) === 0;
64
+ return !(offscreen || noOpacity || noDisplay || invisible);
65
+ };
66
+ const notApplicable = `n/a`;
67
+ const isWritable = function(elem) {
68
+ return elem.parentNode
69
+ ? !!jqx.nodes(`:is(:read-write)`, elem?.parentNode)?.find(el => el === elem) : false;
70
+ };
71
+
72
+ const isModal = function(elem) {
73
+ return elem.parentNode
74
+ ? !!jqx.nodes(`:is(:modal)`, elem?.parentNode)?.find(el => el === elem) : false;
75
+ };
76
+
77
+ const noElements = { notInDOM: true, writable: notApplicable, modal: notApplicable, empty: true, open: notApplicable, visible: notApplicable, };
78
+
79
+ return self => {
80
+ const firstElem = self[0];
81
+
82
+ return firstElem ? {
83
+ get writable() {
84
+ return isWritable(firstElem);
85
+ },
86
+ get modal() {
87
+ return isModal(firstElem);
88
+ },
89
+ get inDOM() {
90
+ return !!firstElem.parentNode;
91
+ },
92
+ get open() {
93
+ return firstElem.open ?? false;
94
+ },
95
+ get visible() {
96
+ return isVisible(firstElem);
97
+ },
98
+ get disabled() {
99
+ return firstElem.hasAttribute("readonly") || firstElem.hasAttribute("disabled");
100
+ },
101
+ get empty() {
102
+ return self.collection.length < 1;
103
+ },
104
+ get virtual() {
105
+ return self.isVirtual;
106
+ }
107
+ } : noElements;
108
+ };
109
+ }
110
+
111
+ export {
112
+ IS,
113
+ maybe,
114
+ randomString,
115
+ toDashedNotation,
116
+ toCamelcase,
117
+ truncateHtmlStr,
118
+ truncate2SingleStr,
119
+ logTime,
120
+ randomNr,
121
+ hex2RGBA,
122
+ escHtml,
123
+ ExamineElementFeatureFactory,
124
+ styleFactory,
125
+ tagFNFactory,
126
+ };
package/src/tinyDOM.js ADDED
@@ -0,0 +1,104 @@
1
+ // JQx adapted from https://github.com/KooiInc/tinyDOM
2
+ import { IS, maybe } from "./Utilities.js";
3
+ const defaultTinyDOM = tinyDOM();
4
+ const converts = { html: `innerHTML`, text: `textContent`, class: `className` };
5
+
6
+ export default defaultTinyDOM;
7
+
8
+ function tinyDOM() {
9
+ const tinyDOMProxyGetter = { get(obj, key) {
10
+ const tag = String(key)?.toLowerCase();
11
+ switch(true) {
12
+ case tag in obj: return obj[tag];
13
+ case validateTag(tag): return createTagFunctionProperty(obj, tag, key);
14
+ default: return createTagFunctionProperty(obj, tag, key, true);
15
+ }
16
+ }, enumerable: false, configurable: false
17
+ };
18
+ return new Proxy({}, tinyDOMProxyGetter);
19
+ }
20
+
21
+ function createTagFunctionProperty(obj, tag, key, isError = false) {
22
+ Object.defineProperty(obj, tag, { get() { return isError ? _ => errorElement(key) : tag2FN(tag); } } );
23
+ return obj[tag];
24
+ }
25
+
26
+ function processNext(root, next, tagName) {
27
+ next = next?.isJQx && next.first() || next;
28
+
29
+ return maybe({
30
+ trial: _ => {
31
+ return isText(next)
32
+ ? root.append(next)
33
+ : containsHTML(next)
34
+ ? root.insertAdjacentHTML(`beforeend`, next) : root.append(next)
35
+ },
36
+ whenError: err => console.info(`${tagName} (for root ${root}) not created, reason\n`, err)
37
+ });
38
+ }
39
+
40
+ function tagFN(tagName, initial, ...nested) {
41
+ const elem = retrieveElementFromInitial(initial, tagName);
42
+ nested?.forEach(arg => processNext(elem, arg, tagName));
43
+ return elem;
44
+ }
45
+
46
+ function retrieveElementFromInitial(initial, tag) {
47
+ initial = isComment(tag) ? cleanupComment(initial) : initial?.isJQx ? initial.first() : initial;
48
+
49
+ switch(true) {
50
+ case IS(initial, String): return createElement(tag, containsHTML(initial, tag) ? {html: initial} : {text: initial});
51
+ case IS(initial, Node): return createElementAndAppend(tag, initial);
52
+ default: return createElement(tag, initial);
53
+ }
54
+ }
55
+
56
+ function cleanupProps(props) {
57
+ delete props.data;
58
+ if (Object.keys(props).length < 1) {
59
+ return props;
60
+ }
61
+
62
+ Object.keys(props).forEach(key => {
63
+ const keyLowercase = key.toLowerCase();
64
+
65
+ if (keyLowercase in converts) {
66
+ props[converts[keyLowercase]] = props[key];
67
+ delete props[key];
68
+ }
69
+ });
70
+
71
+ return props;
72
+ }
73
+
74
+ function createElementAndAppend(tag, element2Append) {
75
+ const elem = createElement(tag);
76
+ elem.append(element2Append);
77
+ return elem;
78
+ }
79
+
80
+ function createElement(tagName, props = {}) {
81
+ props = isObjectCheck(props, {});
82
+
83
+ const data = Object.entries(props.data ?? {});
84
+ const elem = Object.assign(
85
+ isComment(tagName) ? new Comment(props?.text) : document.createElement(tagName),
86
+ cleanupProps( props ) );
87
+ data.length && data.forEach(([key, value]) => elem.dataset[key] = String(value));
88
+ return elem;
89
+ }
90
+
91
+ function isObjectCheck(someObject, defaultValue) {
92
+ return defaultValue
93
+ ? IS(someObject, {isTypes: Object, notTypes: [Array, null, NaN, Proxy], defaultValue})
94
+ : IS(someObject, {isTypes: Object, notTypes: [Array, null, NaN, Proxy]});
95
+ }
96
+
97
+ function toCommentTag(commentElement) {}
98
+ function cleanupComment(initial) { return isObjectCheck(initial) ? initial?.text ?? initial?.textContent ?? `` : String(initial); }
99
+ function errorElement(key) { return createElement(`b`, {style:`color:red`,text:`'${key}' is not a valid HTML-tag`}); }
100
+ function containsHTML(str, tag) { return !isComment(tag) && IS(str, String) && /<.*>|&[#|0-9a-z]+[^;];/i.test(str); }
101
+ function isText(tag) { return tag?.constructor === Comment || tag?.constructor === CharacterData; }
102
+ function isComment(tag) { return tag?.constructor === Comment || /comment/i.test(tag); }
103
+ function validateTag(name) { return !IS(createElement(name), HTMLUnknownElement); }
104
+ function tag2FN(tagName) { return (initial, ...args) => tagFN(tagName, initial, ...args); }