jqx-es 1.2.2 → 1.2.4
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.
- package/Bundle/jqx.browser.min.js +14 -15
- package/Bundle/jqx.min.js +14 -15
- package/index.js +7 -22
- package/package.json +1 -1
- package/src/DOM.js +30 -36
- package/src/DOMCleanup.js +12 -11
- package/src/HTMLTags.js +1 -1
- package/src/HandlerFactory.js +2 -1
- package/src/{JQxExtensionHelpers.js → JQxFactory.js} +19 -40
- package/src/JQxMethods.js +23 -34
- package/src/Popup.js +2 -3
- package/src/Utilities.js +106 -51
- package/src/_JQxX.js +500 -0
package/package.json
CHANGED
package/src/DOM.js
CHANGED
|
@@ -2,53 +2,57 @@ import {
|
|
|
2
2
|
cleanupHtml,
|
|
3
3
|
getRestricted,
|
|
4
4
|
ATTRS, } from "./DOMCleanup.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const htmlToVirtualElement = htmlString => {
|
|
5
|
+
import {IS, insertPositions, isNode, truncateHtmlStr} from "./Utilities.js";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
getRestricted, createElementFromHtmlString, element2DOM,
|
|
9
|
+
cleanupHtml, inject2DOMTree, ATTRS
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function htmlToVirtualElement(htmlString) {
|
|
14
13
|
const placeholderNode = document.createElement("div");
|
|
15
14
|
placeholderNode.insertAdjacentHTML(insertPositions.end, htmlString);
|
|
16
15
|
return placeholderNode.childNodes.length
|
|
17
16
|
? cleanupHtml(placeholderNode)
|
|
18
17
|
: undefined;
|
|
19
|
-
}
|
|
20
|
-
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function characterDataElement2DOM(elem, root, position) {
|
|
21
21
|
if (IS(elem, Comment)) {
|
|
22
22
|
return root.insertAdjacentHTML(position, `<!--${elem.data}-->`);
|
|
23
23
|
}
|
|
24
24
|
return root.insertAdjacentText(position, elem.data);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
collection.reduce( (acc, elem) => {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function inject2DOMTree( collection = [], root = document.body, position = insertPositions.BeforeEnd ) {
|
|
28
|
+
position = position || insertPositions.BeforeEnd;
|
|
29
|
+
return collection.reduce( (acc, elem) => {
|
|
31
30
|
const created = isNode(elem) && element2DOM(elem, root, position);
|
|
32
31
|
return created ? [...acc, created] : acc;
|
|
33
32
|
}, []);
|
|
34
|
-
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function element2DOM(elem, root = document.body, position = insertPositions.BeforeEnd) {
|
|
36
|
+
position = position || insertPositions.BeforeEnd;
|
|
35
37
|
root = root?.isJQx ? root?.[0] : root;
|
|
36
38
|
|
|
37
|
-
return IS(elem, Comment, Text)
|
|
38
|
-
characterDataElement2DOM(elem, root, position)
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
return IS(elem, Comment, Text)
|
|
40
|
+
? characterDataElement2DOM(elem, root, position)
|
|
41
|
+
: IS(elem, HTMLElement) ? root.insertAdjacentElement(position, elem) : undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createElementFromHtmlString(htmlStr) {
|
|
41
45
|
if (IS(htmlStr, Text, Comment)) {
|
|
42
46
|
return htmlStr;
|
|
43
47
|
}
|
|
44
|
-
|
|
48
|
+
|
|
45
49
|
const testStr = htmlStr?.trim();
|
|
46
50
|
let text = testStr?.split(/<text>|<\/text>/i) ?? [];
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
if (text?.length) {
|
|
49
53
|
text = text.length > 1 ? text.filter(v => v.length).shift() : undefined;
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
|
|
52
56
|
if (testStr.startsWith(`<!--`) && testStr.endsWith(`-->`)) {
|
|
53
57
|
return document.createComment(htmlStr.replace(/<!--|-->$/g, ''));
|
|
54
58
|
}
|
|
@@ -64,14 +68,4 @@ const createElementFromHtmlString = htmlStr => {
|
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
return nwElem.children[0];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export {
|
|
70
|
-
getRestricted,
|
|
71
|
-
createElementFromHtmlString,
|
|
72
|
-
element2DOM,
|
|
73
|
-
cleanupHtml,
|
|
74
|
-
inject2DOMTree,
|
|
75
|
-
insertPositions,
|
|
76
|
-
ATTRS,
|
|
77
|
-
};
|
|
71
|
+
}
|
package/src/DOMCleanup.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { truncate2SingleStr, IS/*, debugLog*/ } from "./JQxExtensionHelpers.js";
|
|
2
1
|
import cleanupTagInfo from "./HTMLTags.js";
|
|
3
2
|
import {ATTRS} from "./EmbedResources.js";
|
|
4
|
-
import {escHtml, systemLog} from "./Utilities.js";
|
|
3
|
+
import {IS, truncate2SingleStr, escHtml, systemLog} from "./Utilities.js";
|
|
5
4
|
|
|
6
5
|
let logElementCreationErrors2Console = true;
|
|
7
6
|
const attrRegExpStore = {
|
|
@@ -10,22 +9,25 @@ const attrRegExpStore = {
|
|
|
10
9
|
whiteSpace: /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g,
|
|
11
10
|
notAllowedValues: /^javascript|injected|noreferrer|alert|DataURL/gi
|
|
12
11
|
};
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
function logContingentErrors(elCreationInfo) {
|
|
14
14
|
if (logElementCreationErrors2Console && Object.keys(elCreationInfo.removed).length) {
|
|
15
15
|
const msgs = Object.entries(elCreationInfo.removed)
|
|
16
16
|
.reduce( (acc, [k, v]) => [...acc, `${escHtml(k)} => ${v}`], [])
|
|
17
17
|
.join(`\\000A`);
|
|
18
|
-
systemLog.error(`JQx HTML creation
|
|
18
|
+
systemLog.error(`JQx: HTML creation error(s): ${msgs}`);
|
|
19
19
|
}
|
|
20
|
-
}
|
|
21
|
-
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function elementCheck(child) {
|
|
22
23
|
const name = child.nodeName.toLowerCase();
|
|
23
24
|
const notAllowedCustomElementNames = [
|
|
24
25
|
`annotation-xml`, `color-profile`, `font-face`, `font-face-src`,
|
|
25
26
|
`font-face-uri`, `font-face-format`, `font-face-name`, `missing-glyph` ];
|
|
26
27
|
return /-/.test(name) && !notAllowedCustomElementNames.find(v => v === name) || cleanupTagInfo.isAllowed(name);
|
|
27
|
-
}
|
|
28
|
-
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function cleanupHtml(el2Clean) {
|
|
29
31
|
const elCreationInfo = {
|
|
30
32
|
rawHTML: el2Clean?.parentElement?.getHTML() ?? `no html`,
|
|
31
33
|
removed: { },
|
|
@@ -75,7 +77,7 @@ const cleanupHtml = el2Clean => {
|
|
|
75
77
|
logContingentErrors(elCreationInfo);
|
|
76
78
|
|
|
77
79
|
return el2Clean;
|
|
78
|
-
}
|
|
80
|
+
}
|
|
79
81
|
const emphasize = str => `***${str}***`;
|
|
80
82
|
const getRestricted = emphasizeTag =>
|
|
81
83
|
Object.entries(cleanupTagInfo)
|
|
@@ -83,6 +85,5 @@ const getRestricted = emphasizeTag =>
|
|
|
83
85
|
!value.allowed &&
|
|
84
86
|
[...acc, (emphasizeTag && key === emphasizeTag ? emphasize(key) : key)] ||
|
|
85
87
|
acc, []);
|
|
86
|
-
const logElementCreationErrors = onOff => logElementCreationErrors2Console = onOff;
|
|
87
88
|
|
|
88
|
-
export { cleanupHtml, getRestricted,
|
|
89
|
+
export { cleanupHtml, getRestricted, ATTRS};
|
package/src/HTMLTags.js
CHANGED
package/src/HandlerFactory.js
CHANGED
|
@@ -1,44 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cleanupHtml } from "./DOM.js";
|
|
2
2
|
import allMethodsFactory from "./JQxMethods.js";
|
|
3
3
|
import PopupFactory from "./Popup.js";
|
|
4
4
|
import { listeners, default as HandleFactory } from "./HandlerFactory.js";
|
|
5
5
|
import tagLib from "./HTMLTags.js";
|
|
6
6
|
import {
|
|
7
|
-
randomString, toDashedNotation, IS,
|
|
8
|
-
|
|
9
|
-
isNonEmptyString, resolveEventTypeParameter, extensionHelpers,
|
|
7
|
+
randomString, toDashedNotation, IS, tagFNFactory as $T, styleFactory, toCamelcase, systemLog, escHtml,
|
|
8
|
+
isNonEmptyString, resolveEventTypeParameter, selectedExtensionHelpers, insertPositions,
|
|
10
9
|
} from "./Utilities.js";
|
|
11
10
|
|
|
12
11
|
let instanceGetters, instanceMethods;
|
|
13
12
|
const {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} = localHelpersFactory();
|
|
13
|
+
isComment, isText, isHtmlString, isArrayOfHtmlElements, isArrayOfHtmlStrings,
|
|
14
|
+
ElemArray2HtmlString, addHandlerId, cssRuleEdit, addFn
|
|
15
|
+
} = selectedUtilitiesFactory();
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
addHandlerId, isHtmlString, isNode, isArrayOfHtmlStrings, isArrayOfHtmlElements, isCommentOrTextNode,
|
|
22
|
-
inject2DOMTree, ElemArray2HtmlString, input2Collection, setCollectionFromCssSelector,
|
|
23
|
-
truncateHtmlStr, truncate2SingleStr, proxify, addJQxStaticMethods, createElementFromHtmlString,
|
|
24
|
-
insertPositions, IS, };
|
|
17
|
+
export { proxify, addJQxStaticMethods };
|
|
25
18
|
|
|
26
19
|
/* region functions */
|
|
27
|
-
function
|
|
20
|
+
function selectedUtilitiesFactory() {
|
|
28
21
|
const cssRuleEdit = styleFactory({createWithId: `JQxStylesheet`});
|
|
29
22
|
const addFn = (name, fn) => instanceMethods[name] = (self, ...params) => fn(self, ...params);
|
|
30
|
-
return {...
|
|
23
|
+
return { ...selectedExtensionHelpers(), ...{ cssRuleEdit, addFn } };
|
|
31
24
|
}
|
|
32
25
|
|
|
33
26
|
function proxify(instance) {
|
|
34
27
|
return new Proxy( instance, { get: (obj, key) => proxyKeyFactory(obj, key, instance) } );
|
|
35
28
|
}
|
|
36
29
|
|
|
37
|
-
function
|
|
38
|
-
return (...args) => IS(method, Function) && method(proxify(instance), ...args);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function wrapGetter(method, instance) {
|
|
30
|
+
function wrap(method, instance) {
|
|
42
31
|
return (...args) => IS(method, Function) && method(proxify(instance), ...args);
|
|
43
32
|
}
|
|
44
33
|
|
|
@@ -46,8 +35,8 @@ function proxyKeyFactory(self, key, instance) {
|
|
|
46
35
|
switch(true) {
|
|
47
36
|
case IS(key, Symbol): return self;
|
|
48
37
|
case IS(+key, Number): return self.collection?.[key] || undefined;
|
|
49
|
-
case (key in instanceGetters): return
|
|
50
|
-
case (key in instanceMethods): return
|
|
38
|
+
case (key in instanceGetters): return wrap(instanceGetters[key], instance)();
|
|
39
|
+
case (key in instanceMethods): return wrap(instanceMethods[key], instance);
|
|
51
40
|
default: return self[key];
|
|
52
41
|
}
|
|
53
42
|
}
|
|
@@ -101,7 +90,7 @@ function cssRemove(...rules) {
|
|
|
101
90
|
function virtualFactory(jqx) {
|
|
102
91
|
return function(html, root, position) {
|
|
103
92
|
root = root?.isJQx ? root?.[0] : root;
|
|
104
|
-
position = position && Object.values(insertPositions).find(pos => position === pos)
|
|
93
|
+
position = position && Object.values(insertPositions).find(pos => position === pos);
|
|
105
94
|
const virtualElem = jqx(html, document.createElement(`br`));
|
|
106
95
|
if (root && !IS(root, HTMLBRElement)) {
|
|
107
96
|
for (const elem of virtualElem.collection) {
|
|
@@ -123,18 +112,12 @@ function combineObjectSources(...sources) {
|
|
|
123
112
|
return result;
|
|
124
113
|
}
|
|
125
114
|
|
|
126
|
-
function tagNotAllowed(tagName) {
|
|
127
|
-
console.error(`JQx: "${tagName}" not allowed, not rendered`);
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
115
|
function tagGetterFactory(tagName, cando, jqx, webComponentTagName) {
|
|
132
116
|
tagName = toDashedNotation(webComponentTagName || tagName.toLowerCase());
|
|
133
117
|
return {
|
|
134
118
|
get() {
|
|
135
|
-
return
|
|
136
|
-
|
|
137
|
-
return jqx.virtual(cleanupHtml($T[tagName](...args)));
|
|
119
|
+
return (...args) => {
|
|
120
|
+
return cando && jqx.virtual(cleanupHtml($T[tagName](...args)));
|
|
138
121
|
}
|
|
139
122
|
},
|
|
140
123
|
enumerable: false,
|
|
@@ -165,7 +148,6 @@ function staticTagsLambda(jqx) {
|
|
|
165
148
|
|
|
166
149
|
function delegateFactory(listen) {
|
|
167
150
|
return function(type, selector, ...listeners) {
|
|
168
|
-
|
|
169
151
|
if (IS(selector, Function)) {
|
|
170
152
|
listeners.push(selector);
|
|
171
153
|
selector = undefined;
|
|
@@ -184,7 +166,7 @@ function delegateCaptureFactory(listen) {
|
|
|
184
166
|
handlers = IS(handlers, Function) ? [handlers] : handlers;
|
|
185
167
|
canRemove = IS(canRemove, Boolean) ? canRemove : false;
|
|
186
168
|
const params = { eventType: typesResolved, selector: selector || origin, capture,
|
|
187
|
-
name: specifiedName, once, canRemove};
|
|
169
|
+
name: specifiedName, once, canRemove };
|
|
188
170
|
switch(true) {
|
|
189
171
|
case IS(typesResolved, Array) && typesResolved.length > 0:
|
|
190
172
|
for (const type of typesResolved) {
|
|
@@ -203,11 +185,9 @@ function delegateCaptureFactory(listen) {
|
|
|
203
185
|
}
|
|
204
186
|
|
|
205
187
|
function getNamedListener(type, name) {
|
|
206
|
-
name = isNonEmptyString(name)
|
|
207
|
-
type = isNonEmptyString(type)
|
|
208
|
-
|
|
209
|
-
return [...listeners[type].values()].find(h => (h.name || ``) === name);
|
|
210
|
-
}
|
|
188
|
+
name = isNonEmptyString(name) && name;
|
|
189
|
+
type = isNonEmptyString(type) && type;
|
|
190
|
+
return name && type && [...listeners[type].values()].find(h => (h.name || ``) === name);
|
|
211
191
|
}
|
|
212
192
|
|
|
213
193
|
function popupGetter(jqx) {
|
|
@@ -250,7 +230,6 @@ function staticMethodsFactory(jqx) {
|
|
|
250
230
|
text: (str, isComment = false) => isComment ? jqx.comment(str) : document.createTextNode(str),
|
|
251
231
|
node: (selector, root = document) => root.querySelector(selector, root),
|
|
252
232
|
nodes: (selector, root = document) => [...root.querySelectorAll(selector, root)],
|
|
253
|
-
//get logger() { return loggerFactory() },
|
|
254
233
|
get getNamedListener() { return getNamedListener; },
|
|
255
234
|
get virtual() { return virtualFactory(jqx); },
|
|
256
235
|
get allowTag() { return allowProhibit.allow; },
|
package/src/JQxMethods.js
CHANGED
|
@@ -1,42 +1,26 @@
|
|
|
1
|
-
import {createElementFromHtmlString,
|
|
2
|
-
import {
|
|
3
|
-
IS,
|
|
4
|
-
addHandlerId,
|
|
5
|
-
isNode,
|
|
6
|
-
inject2DOMTree,
|
|
7
|
-
isCommentOrTextNode,
|
|
8
|
-
truncateHtmlStr,
|
|
9
|
-
} from "./JQxExtensionHelpers.js";
|
|
1
|
+
import {createElementFromHtmlString, inject2DOMTree} from "./DOM.js";
|
|
10
2
|
import {ATTRS} from "./EmbedResources.js";
|
|
11
3
|
import {
|
|
12
|
-
ExamineElementFeatureFactory,
|
|
13
|
-
isNonEmptyString,
|
|
14
|
-
|
|
15
|
-
toCamelcase,
|
|
16
|
-
randomString,
|
|
17
|
-
escHtml,
|
|
18
|
-
systemLog,
|
|
4
|
+
IS, isNode, truncateHtmlStr, addHandlerId, ExamineElementFeatureFactory,
|
|
5
|
+
isNonEmptyString, toDashedNotation, randomString, escHtml, systemLog,
|
|
6
|
+
insertPositions, isCommentOrTextNode, datasetKeyProxy
|
|
19
7
|
} from "./Utilities.js";
|
|
20
|
-
const loop = (instance, callback) => {
|
|
21
|
-
const cleanCollection = instance.collection.filter(el => !isCommentOrTextNode(el));
|
|
22
|
-
for (let i = 0; i < cleanCollection.length; i += 1) {
|
|
23
|
-
callback(cleanCollection[i], i);
|
|
24
|
-
}
|
|
25
8
|
|
|
26
|
-
return instance;
|
|
27
|
-
};
|
|
28
9
|
const isIt = ExamineElementFeatureFactory();
|
|
29
|
-
const datasetKeyProxy = { get(obj, key) {
|
|
30
|
-
return obj[toCamelcase(key)] || obj[key]; },
|
|
31
|
-
enumerable: false,
|
|
32
|
-
configurable: false
|
|
33
|
-
};
|
|
34
10
|
|
|
35
11
|
/* region functions */
|
|
36
12
|
function emptyElement(el) {
|
|
37
13
|
return el && (el.textContent = "");
|
|
38
14
|
}
|
|
39
15
|
|
|
16
|
+
function loop(instance, callback) {
|
|
17
|
+
const cleanCollection = instance.collection.filter(el => !isCommentOrTextNode(el));
|
|
18
|
+
for (let i = 0; i < cleanCollection.length; i += 1) {
|
|
19
|
+
callback(cleanCollection[i], i);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return instance;
|
|
23
|
+
}
|
|
40
24
|
|
|
41
25
|
function compareCI(key, compareTo) {
|
|
42
26
|
return key.toLowerCase().trim() === compareTo.trim().toLowerCase();
|
|
@@ -341,9 +325,15 @@ function instanceExtensionsFactory(jqx) {
|
|
|
341
325
|
computedStyle: (instance, property) => instance.first() && getComputedStyle(instance.first())[property],
|
|
342
326
|
css: (instance, keyOrKvPairs, value) => loop(instance, el => css(el, keyOrKvPairs, value, jqx)),
|
|
343
327
|
duplicate: (instance, toDOM = false, root = document.body) => {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
328
|
+
if (instance.collection.length > 0) {
|
|
329
|
+
const clone = instance.collection[0].cloneNode(true);
|
|
330
|
+
clone.childNodes.forEach((node) => {
|
|
331
|
+
node.removeAttribute && node?.removeAttribute(`id`)
|
|
332
|
+
});
|
|
333
|
+
return toDOM ? jqx(clone).toDOM(root) : jqx.virtual(clone);
|
|
334
|
+
}
|
|
335
|
+
systemLog.error(`Duplicating an empty JQx instance is not possible`);
|
|
336
|
+
return instance;
|
|
347
337
|
},
|
|
348
338
|
each: (instance, cb) => loop(instance, cb),
|
|
349
339
|
empty: instance => loop(instance, emptyElement),
|
|
@@ -510,7 +500,7 @@ function instanceExtensionsFactory(jqx) {
|
|
|
510
500
|
removeClass: (instance, ...classNames) =>
|
|
511
501
|
loop(instance, el => { if (el) { for (const cn of classNames) { el.classList.remove(cn); } } }),
|
|
512
502
|
renderTo: (instance, root = document.body, at = jqx.at.end) => {
|
|
513
|
-
instance.toDOM(root, at);
|
|
503
|
+
instance.first$().toDOM(root, at);
|
|
514
504
|
return instance;
|
|
515
505
|
},
|
|
516
506
|
replace: (instance, oldChild, newChild) => {
|
|
@@ -594,8 +584,7 @@ function instanceExtensionsFactory(jqx) {
|
|
|
594
584
|
},
|
|
595
585
|
toDOM: (instance, root = document.body, position = insertPositions.BeforeEnd) => {
|
|
596
586
|
if (instance.isVirtual) { instance.isVirtual = false; }
|
|
597
|
-
|
|
598
|
-
|
|
587
|
+
inject2DOMTree(instance.collection, root, position);
|
|
599
588
|
return instance;
|
|
600
589
|
},
|
|
601
590
|
toggleClass: (instance, className) => loop(instance, el => el.classList.toggle(className)),
|
package/src/Popup.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { popupStyling as styleRules } from "./EmbedResources.js";
|
|
2
2
|
|
|
3
3
|
export default function($) {
|
|
4
|
-
if (
|
|
5
|
-
|
|
4
|
+
if ($.node(`#jqxPopup`)) { return; }
|
|
5
|
+
$.logger.log(`JQx: [JQx].Popup first call. Dialog element created.`);
|
|
6
6
|
$.dialog({id: `jqxPopup`}, $.div({ id: "jqxPopupContent" })).render;
|
|
7
7
|
$.editCssRules(...styleRules);
|
|
8
8
|
const [popupContent, popupNode] = [$(`#jqxPopupContent`), $.node(`#jqxPopup`)];
|
|
9
9
|
let currentProps = {};
|
|
10
10
|
$.handle( { type: `click, keydown`, handlers: genericPopupCloseHandler, capture: true } );
|
|
11
|
-
|
|
12
11
|
return Object.freeze({show: initPopup, removeModal});
|
|
13
12
|
|
|
14
13
|
function initPopup(props) {
|
package/src/Utilities.js
CHANGED
|
@@ -7,6 +7,18 @@ const characters4RandomString = [...Array(26)]
|
|
|
7
7
|
.concat([...Array(26)].map((x, i) => String.fromCharCode(i + 97)))
|
|
8
8
|
.concat([...Array(10)].map((x, i) => `${i}`));
|
|
9
9
|
const systemLog = systemLogFactory();
|
|
10
|
+
const datasetKeyProxy = {
|
|
11
|
+
get(obj, key) { return obj[toCamelcase(key)] || obj[key]; },
|
|
12
|
+
enumerable: false,
|
|
13
|
+
configurable: false
|
|
14
|
+
};
|
|
15
|
+
const insertPositions = new Proxy({
|
|
16
|
+
start: "afterbegin", afterbegin: "afterbegin",
|
|
17
|
+
end: "beforeend", beforeend: "beforeend",
|
|
18
|
+
before: "beforebegin", beforebegin: "beforebegin",
|
|
19
|
+
after: "afterend", afterend: "afterend" }, {
|
|
20
|
+
get(obj, key) { return obj[String(key).toLowerCase()] ?? obj[key]; }
|
|
21
|
+
});
|
|
10
22
|
|
|
11
23
|
function pad0(nr, n=2) {
|
|
12
24
|
return `${nr}`.padStart(n, `0`);
|
|
@@ -97,68 +109,100 @@ function escHtml(html) {
|
|
|
97
109
|
return html.replace(/</g, `<`).replace(/>/g, `>`);
|
|
98
110
|
}
|
|
99
111
|
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
function isCommentOrTextNode(node) {
|
|
113
|
+
return IS(node, Comment, Text);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function isNode(input) {
|
|
117
|
+
return IS(input, Text, HTMLElement, Comment)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function isComment(input) {
|
|
121
|
+
IS(input, Comment);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isText(input) {
|
|
125
|
+
return IS(input, Text);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isHtmlString(input) {
|
|
129
|
+
return IS(input, String) && /^<|>$/.test(`${input}`.trim());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function isArrayOfHtmlElements(input) {
|
|
133
|
+
return IS(input, Array) && !input?.find(el => !isNode(el));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function isArrayOfHtmlStrings(input) {
|
|
137
|
+
return IS(input, Array) && !input?.find(s => !isHtmlString(s));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function ElemArray2HtmlString(elems) {
|
|
141
|
+
return elems?.filter(el => el).reduce((acc, el) =>
|
|
109
142
|
acc.concat(isComment(el) ? `<!--${el.data}-->`
|
|
110
143
|
: isCommentOrTextNode(el) ? el.textContent
|
|
111
144
|
: el.outerHTML), ``);
|
|
112
|
-
|
|
113
|
-
!input ? []
|
|
114
|
-
: IS(input, Proxy) ? [input.EL]
|
|
115
|
-
: IS(input, NodeList) ? [...input]
|
|
116
|
-
: isNode(input) ? [input]
|
|
117
|
-
: isArrayOfHtmlElements(input) ? input
|
|
118
|
-
: input.isJQx ? input.collection : undefined;
|
|
119
|
-
const setCollectionFromCssSelector = (input, root, self) => {
|
|
120
|
-
const selectorRoot = root !== document.body && (IS(input, String) && input.toLowerCase() !== "body") ? root : document;
|
|
121
|
-
let errorStr = undefined;
|
|
122
|
-
|
|
123
|
-
try { self.collection = [...selectorRoot.querySelectorAll(input)]; }
|
|
124
|
-
catch (err) { errorStr = `Invalid CSS querySelector. [${!IS(input, String) ? `Nothing valid given!` : input}]`; }
|
|
125
|
-
|
|
126
|
-
return errorStr ?? `CSS querySelector "${input}", output ${self.collection.length} element(s)`;
|
|
127
|
-
};
|
|
128
|
-
const addHandlerId = instance => {
|
|
129
|
-
const handleId = instance.data.get(`hid`) || `HID${randomString()}`;
|
|
130
|
-
instance.data.add({hid: handleId});
|
|
131
|
-
return `[data-hid="${handleId}"]`;
|
|
132
|
-
};
|
|
145
|
+
}
|
|
133
146
|
|
|
147
|
+
function input2Collection(input) {
|
|
148
|
+
return !input ? []
|
|
149
|
+
: IS(input, Proxy) ? [input.EL]
|
|
150
|
+
: IS(input, NodeList) ? [...input]
|
|
151
|
+
: isNode(input) ? [input]
|
|
152
|
+
: isArrayOfHtmlElements(input) ? input
|
|
153
|
+
: input.isJQx ? input.collection : undefined;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function setCollectionFromCssSelector(input, root, self) {
|
|
157
|
+
const selectorRoot = root !== document.body && (IS(input, String) && input.toLowerCase() !== "body") ? root : document;
|
|
158
|
+
let errorStr = undefined;
|
|
159
|
+
|
|
160
|
+
try { self.collection = [...selectorRoot.querySelectorAll(input)]; }
|
|
161
|
+
catch (err) { errorStr = `Invalid CSS querySelector. [${!IS(input, String) ? `Nothing valid given!` : input}]`; }
|
|
162
|
+
const collectionLen = self.collection.length;
|
|
163
|
+
return collectionLen < 1
|
|
164
|
+
? `CSS querySelector "${input}", output: nothing`
|
|
165
|
+
: errorStr ?? `CSS querySelector "${input}", output ${collectionLen} element${collectionLen > 1 ? `s` : ``}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function addHandlerId(instance) {
|
|
169
|
+
const handleId = instance.data.get(`hid`) || `HID${randomString()}`;
|
|
170
|
+
instance.data.add({hid: handleId});
|
|
171
|
+
return `[data-hid="${handleId}"]`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function selectedExtensionHelpers() {
|
|
134
175
|
return {
|
|
135
176
|
isCommentOrTextNode, isNode, isComment, isText, isHtmlString, isArrayOfHtmlElements,
|
|
136
177
|
isArrayOfHtmlStrings, ElemArray2HtmlString, input2Collection, setCollectionFromCssSelector,
|
|
137
178
|
addHandlerId };
|
|
138
179
|
}
|
|
139
180
|
|
|
140
|
-
function
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
};
|
|
152
|
-
const notApplicable = `n/a`;
|
|
153
|
-
const isWritable = function(elem) {
|
|
154
|
-
return [...elem.parentNode.querySelectorAll(`:is(:read-write)`)]?.find(el => el === elem) ?? false;
|
|
155
|
-
};
|
|
181
|
+
function isVisible(el) {
|
|
182
|
+
if (!el) { return undefined; }
|
|
183
|
+
const elStyle = el.style;
|
|
184
|
+
const computedStyle = getComputedStyle(el);
|
|
185
|
+
const invisible = [elStyle.visibility, computedStyle.visibility].includes("hidden");
|
|
186
|
+
const noDisplay = [elStyle.display, computedStyle.display].includes("none");
|
|
187
|
+
const offscreen = el.offsetTop < 0 || (el.offsetLeft + el.offsetWidth) < 0
|
|
188
|
+
|| el.offsetLeft > document.body.offsetWidth;
|
|
189
|
+
const noOpacity = +computedStyle.opacity === 0 || +(elStyle.opacity || 1) === 0;
|
|
190
|
+
return !(offscreen || noOpacity || noDisplay || invisible);
|
|
191
|
+
}
|
|
156
192
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
193
|
+
function isWritable(elem) {
|
|
194
|
+
return [...elem.parentNode.querySelectorAll(`:is(:read-write)`)]?.find(el => el === elem) ?? false;
|
|
195
|
+
}
|
|
160
196
|
|
|
161
|
-
|
|
197
|
+
function isModal(elem) {
|
|
198
|
+
return [...elem.parentNode.querySelectorAll(`:is(:modal)`)]?.find(el => el === elem) ?? false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function ExamineElementFeatureFactory() {
|
|
202
|
+
const notApplicable = `n/a`;
|
|
203
|
+
const noElements = {
|
|
204
|
+
notInDOM: true, writable: notApplicable, modal: notApplicable, empty: true,
|
|
205
|
+
open: notApplicable, visible: notApplicable, };
|
|
162
206
|
|
|
163
207
|
return self => {
|
|
164
208
|
const firstElem = self.node;
|
|
@@ -228,10 +272,20 @@ function systemLogFactory() {
|
|
|
228
272
|
}
|
|
229
273
|
|
|
230
274
|
export {
|
|
275
|
+
addHandlerId,
|
|
231
276
|
IS,
|
|
232
277
|
maybe,
|
|
278
|
+
isCommentOrTextNode,
|
|
279
|
+
isHtmlString,
|
|
280
|
+
isArrayOfHtmlStrings,
|
|
281
|
+
isArrayOfHtmlElements,
|
|
282
|
+
ElemArray2HtmlString,
|
|
283
|
+
input2Collection,
|
|
284
|
+
setCollectionFromCssSelector,
|
|
285
|
+
isNode,
|
|
233
286
|
randomString,
|
|
234
287
|
isNonEmptyString,
|
|
288
|
+
insertPositions,
|
|
235
289
|
toDashedNotation,
|
|
236
290
|
toCamelcase,
|
|
237
291
|
truncateHtmlStr,
|
|
@@ -244,6 +298,7 @@ export {
|
|
|
244
298
|
styleFactory,
|
|
245
299
|
tagFNFactory,
|
|
246
300
|
resolveEventTypeParameter,
|
|
247
|
-
|
|
301
|
+
selectedExtensionHelpers,
|
|
248
302
|
systemLog,
|
|
303
|
+
datasetKeyProxy,
|
|
249
304
|
};
|