browser-debugger-cli 0.9.0 → 0.11.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.
- package/.claude/skills/bdg/SKILL.md +268 -0
- package/README.md +15 -1
- package/dist/commands/dom/a11y.js +2 -1
- package/dist/commands/dom/formInteraction.js +56 -25
- package/dist/commands/dom/helpers/keyAttributes.d.ts +20 -0
- package/dist/commands/dom/helpers/keyAttributes.js +54 -0
- package/dist/commands/dom/helpers/query.d.ts +1 -1
- package/dist/commands/dom/helpers/query.js +66 -19
- package/dist/commands/dom/helpers/runElementCommand.js +4 -3
- package/dist/commands/dom/helpers/screenshot.js +85 -12
- package/dist/commands/dom/index.d.ts +1 -0
- package/dist/commands/dom/index.js +8 -3
- package/dist/commands/dom/inspect.d.ts +15 -0
- package/dist/commands/dom/inspect.js +82 -0
- package/dist/commands/dom/layout.js +2 -2
- package/dist/commands/dom/listeners.js +2 -2
- package/dist/commands/dom/semanticUtils.d.ts +14 -1
- package/dist/commands/dom/semanticUtils.js +44 -3
- package/dist/commands/installSkill.d.ts +20 -0
- package/dist/commands/installSkill.js +87 -0
- package/dist/commands/network/list.js +13 -2
- package/dist/commands/optionBehaviors.js +48 -6
- package/dist/commands/page.d.ts +1 -1
- package/dist/commands/page.js +62 -3
- package/dist/commands/shared/commonOptions.d.ts +4 -0
- package/dist/commands/shared/commonOptions.js +9 -0
- package/dist/commands/shared/optionTypes.d.ts +21 -0
- package/dist/commands/shared/startHelpers.d.ts +66 -0
- package/dist/commands/shared/startHelpers.js +91 -10
- package/dist/commands/shared/validation.d.ts +11 -0
- package/dist/commands/shared/validation.js +16 -0
- package/dist/commands.js +3 -0
- package/dist/daemon/launcher.d.ts +8 -1
- package/dist/daemon/launcher.js +3 -1
- package/dist/daemon/session/Session.d.ts +7 -0
- package/dist/daemon/session/Session.js +23 -1
- package/dist/daemon/session/commandRegistry.d.ts +14 -1
- package/dist/daemon/session/commandRegistry.js +65 -9
- package/dist/daemon/session/interactions.d.ts +18 -5
- package/dist/daemon/session/interactions.js +22 -12
- package/dist/daemon.js +3565 -329
- package/dist/errors/messages.d.ts +85 -0
- package/dist/errors/messages.js +128 -1
- package/dist/index.js +2151 -960
- package/dist/ipc/client.d.ts +9 -0
- package/dist/ipc/client.js +13 -0
- package/dist/ipc/protocol/commands.d.ts +56 -1
- package/dist/ipc/protocol/commands.js +2 -0
- package/dist/ipc/protocol/domTypes.d.ts +35 -2
- package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
- package/dist/ipc/protocol/inspectTypes.js +10 -0
- package/dist/runtime/dom/actionEffects.d.ts +94 -15
- package/dist/runtime/dom/actionEffects.js +173 -27
- package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -14
- package/dist/runtime/dom/actionEffectsScripts.js +224 -32
- package/dist/runtime/dom/elementInfo.d.ts +26 -0
- package/dist/runtime/dom/elementInfo.js +65 -0
- package/dist/runtime/dom/eventListeners.js +14 -4
- package/dist/runtime/dom/formFillHelpers/fill.d.ts +3 -4
- package/dist/runtime/dom/formFillHelpers/fill.js +77 -28
- package/dist/runtime/dom/frameSelection.d.ts +11 -0
- package/dist/runtime/dom/frameSelection.js +20 -1
- package/dist/runtime/dom/frames.d.ts +38 -5
- package/dist/runtime/dom/frames.js +136 -21
- package/dist/runtime/dom/inspect.d.ts +28 -0
- package/dist/runtime/dom/inspect.js +557 -0
- package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
- package/dist/runtime/dom/inspectAllStyles.js +385 -0
- package/dist/runtime/dom/inspectCascade.d.ts +94 -0
- package/dist/runtime/dom/inspectCascade.js +371 -0
- package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
- package/dist/runtime/dom/inspectCascadeModel.js +232 -0
- package/dist/runtime/dom/inspectHints.d.ts +62 -0
- package/dist/runtime/dom/inspectHints.js +305 -0
- package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
- package/dist/runtime/dom/inspectLayoutModel.js +346 -0
- package/dist/runtime/dom/inspectModel.d.ts +74 -0
- package/dist/runtime/dom/inspectModel.js +184 -0
- package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
- package/dist/runtime/dom/inspectPaintModel.js +461 -0
- package/dist/runtime/dom/inspectRules.d.ts +37 -0
- package/dist/runtime/dom/inspectRules.js +101 -0
- package/dist/runtime/dom/inspectScripts.d.ts +132 -0
- package/dist/runtime/dom/inspectScripts.js +263 -0
- package/dist/runtime/dom/inspectTree.d.ts +40 -0
- package/dist/runtime/dom/inspectTree.js +134 -0
- package/dist/runtime/dom/inspectVariables.d.ts +33 -0
- package/dist/runtime/dom/inspectVariables.js +94 -0
- package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
- package/dist/runtime/dom/inspectWhyModel.js +134 -0
- package/dist/runtime/dom/layout.d.ts +5 -1
- package/dist/runtime/dom/layout.js +10 -3
- package/dist/runtime/dom/listenerPageScripts.d.ts +11 -5
- package/dist/runtime/dom/listenerPageScripts.js +95 -9
- package/dist/runtime/dom/listenerSummary.d.ts +4 -0
- package/dist/runtime/dom/listenerSummary.js +26 -9
- package/dist/runtime/dom/reactEventHelpers.d.ts +5 -0
- package/dist/runtime/dom/reactEventHelpers.js +12 -4
- package/dist/runtime/page/emulation.d.ts +20 -0
- package/dist/runtime/page/emulation.js +37 -0
- package/dist/telemetry/a11y.d.ts +10 -0
- package/dist/telemetry/a11y.js +78 -1
- package/dist/telemetry/console.d.ts +1 -0
- package/dist/telemetry/console.js +100 -5
- package/dist/telemetry/network.js +3 -1
- package/dist/types.d.ts +40 -0
- package/dist/ui/formatters/details.d.ts +8 -0
- package/dist/ui/formatters/details.js +59 -3
- package/dist/ui/formatters/dom.d.ts +2 -1
- package/dist/ui/formatters/dom.js +25 -9
- package/dist/ui/formatters/inspect.d.ts +39 -0
- package/dist/ui/formatters/inspect.js +596 -0
- package/dist/ui/formatters/installSkill.d.ts +11 -0
- package/dist/ui/formatters/installSkill.js +31 -0
- package/dist/ui/formatters/keyAttributes.d.ts +19 -0
- package/dist/ui/formatters/keyAttributes.js +84 -0
- package/dist/ui/formatters/layout.js +2 -2
- package/dist/ui/formatters/networkHeaders.d.ts +13 -0
- package/dist/ui/formatters/networkHeaders.js +23 -3
- package/dist/ui/formatters/networkList.d.ts +29 -1
- package/dist/ui/formatters/networkList.js +86 -20
- package/dist/ui/formatters/status.js +1 -1
- package/dist/ui/formatting.d.ts +9 -0
- package/dist/ui/formatting.js +6 -3
- package/dist/ui/messages/commands.d.ts +123 -7
- package/dist/ui/messages/commands.js +181 -10
- package/dist/ui/messages/networkMessages.d.ts +14 -0
- package/dist/ui/messages/networkMessages.js +18 -0
- package/dist/ui/messages/session.d.ts +14 -0
- package/dist/ui/messages/session.js +20 -0
- package/dist/utils/async.d.ts +9 -0
- package/dist/utils/async.js +17 -0
- package/dist/utils/color.d.ts +84 -0
- package/dist/utils/color.js +376 -0
- package/dist/utils/cssValues.d.ts +109 -0
- package/dist/utils/cssValues.js +236 -0
- package/dist/utils/selectorFilters.d.ts +12 -0
- package/dist/utils/selectorFilters.js +29 -0
- package/package.json +2 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The child tree of `bdg dom inspect`: the page-side walk's children
|
|
3
|
+
* ({@link RawTreeNode}) with sizes rounded, consecutive identical siblings
|
|
4
|
+
* (same label, size and layout) grouped into one row with a count
|
|
5
|
+
* (`li.card ×33 266x107`), and cut to a number of rows in document order.
|
|
6
|
+
*/
|
|
7
|
+
import { containerKind } from './inspectLayoutModel.js';
|
|
8
|
+
/** Default depth of the tree */
|
|
9
|
+
export const DEFAULT_TREE_DEPTH = 2;
|
|
10
|
+
/** Default number of rows */
|
|
11
|
+
export const DEFAULT_TREE_LIMIT = 20;
|
|
12
|
+
/** Characters of text kept per row */
|
|
13
|
+
const ROW_TEXT_LENGTH = 30;
|
|
14
|
+
/**
|
|
15
|
+
* Cut a row's text on a whole character.
|
|
16
|
+
*
|
|
17
|
+
* @param text - Text
|
|
18
|
+
* @returns At most {@link ROW_TEXT_LENGTH} characters, with `…` when cut
|
|
19
|
+
*/
|
|
20
|
+
export function rowText(text) {
|
|
21
|
+
const characters = Array.from(text);
|
|
22
|
+
return characters.length > ROW_TEXT_LENGTH
|
|
23
|
+
? `${characters.slice(0, ROW_TEXT_LENGTH).join('').trimEnd()}…`
|
|
24
|
+
: text;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One child as a tree row (its children converted too).
|
|
28
|
+
*
|
|
29
|
+
* @param raw - Child from the page-side walk
|
|
30
|
+
* @returns Tree row
|
|
31
|
+
*/
|
|
32
|
+
function toNode(raw) {
|
|
33
|
+
const layout = containerKind(raw.display);
|
|
34
|
+
const children = raw.children ? groupSiblings(raw.children.map(toNode)) : undefined;
|
|
35
|
+
return {
|
|
36
|
+
element: raw.label,
|
|
37
|
+
x: Math.round(raw.x * 10) / 10,
|
|
38
|
+
y: Math.round(raw.y * 10) / 10,
|
|
39
|
+
w: Math.round(raw.w),
|
|
40
|
+
h: Math.round(raw.h),
|
|
41
|
+
...(layout && { layout }),
|
|
42
|
+
...(raw.text && { text: rowText(raw.text) }),
|
|
43
|
+
...(children && children.length > 0 && { children }),
|
|
44
|
+
...(raw.childCount && { childCount: raw.childCount }),
|
|
45
|
+
...(raw.hidden && { hiddenChildren: raw.hidden }),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Whether two siblings look the same in the tree.
|
|
50
|
+
*
|
|
51
|
+
* @param a - Row
|
|
52
|
+
* @param b - Row
|
|
53
|
+
* @returns True for the same label, size and layout
|
|
54
|
+
*/
|
|
55
|
+
function identical(a, b) {
|
|
56
|
+
return a.element === b.element && a.w === b.w && a.h === b.h && a.layout === b.layout;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Group runs of identical siblings into one row with a count. A group keeps
|
|
60
|
+
* its text only when every member has the same, and lists no children.
|
|
61
|
+
*
|
|
62
|
+
* @param nodes - Sibling rows
|
|
63
|
+
* @returns Rows with runs grouped
|
|
64
|
+
*/
|
|
65
|
+
export function groupSiblings(nodes) {
|
|
66
|
+
const grouped = [];
|
|
67
|
+
for (let i = 0; i < nodes.length;) {
|
|
68
|
+
const first = nodes[i];
|
|
69
|
+
let run = 1;
|
|
70
|
+
while (i + run < nodes.length && identical(first, nodes[i + run]))
|
|
71
|
+
run++;
|
|
72
|
+
if (run === 1) {
|
|
73
|
+
grouped.push(first);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const members = nodes.slice(i, i + run);
|
|
77
|
+
const sameText = members.every((member) => member.text === first.text);
|
|
78
|
+
const { children: _children, childCount: _count, hiddenChildren: _hidden, text, ...row } = first;
|
|
79
|
+
grouped.push({ ...row, ...(sameText && text && { text }), count: run });
|
|
80
|
+
}
|
|
81
|
+
i += run;
|
|
82
|
+
}
|
|
83
|
+
return grouped;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Rows a node takes in the tree (itself and its listed descendants).
|
|
87
|
+
*
|
|
88
|
+
* @param node - Row
|
|
89
|
+
* @returns Row count
|
|
90
|
+
*/
|
|
91
|
+
function rowCount(node) {
|
|
92
|
+
return 1 + (node.children ?? []).reduce((sum, child) => sum + rowCount(child), 0);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Keep the first rows in document order.
|
|
96
|
+
*
|
|
97
|
+
* @param nodes - Rows
|
|
98
|
+
* @param budget - Rows still allowed (decremented)
|
|
99
|
+
* @returns Kept rows and the number left out
|
|
100
|
+
*/
|
|
101
|
+
function prune(nodes, budget) {
|
|
102
|
+
const kept = [];
|
|
103
|
+
let dropped = 0;
|
|
104
|
+
for (const node of nodes) {
|
|
105
|
+
if (budget.left <= 0) {
|
|
106
|
+
dropped += rowCount(node);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
budget.left--;
|
|
110
|
+
if (!node.children) {
|
|
111
|
+
kept.push(node);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const sub = prune(node.children, budget);
|
|
115
|
+
dropped += sub.dropped;
|
|
116
|
+
const { children: _children, ...row } = node;
|
|
117
|
+
kept.push(sub.kept.length > 0 ? { ...row, children: sub.kept } : row);
|
|
118
|
+
}
|
|
119
|
+
return { kept, dropped };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The child tree from the page-side walk: grouped, then cut to `limit` rows.
|
|
123
|
+
*
|
|
124
|
+
* @param raw - Children from the walk
|
|
125
|
+
* @param limit - Rows shown at most
|
|
126
|
+
* @param skipped - Children the walk did not reach (counted as left out)
|
|
127
|
+
* @returns Rows and the number of rows left out
|
|
128
|
+
*/
|
|
129
|
+
export function buildTree(raw, limit, skipped = 0) {
|
|
130
|
+
const rows = groupSiblings(raw.map(toNode));
|
|
131
|
+
const { kept, dropped } = prune(rows, { left: limit });
|
|
132
|
+
return { children: kept, moreRows: dropped + skipped };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=inspectTree.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `var()` in declared values: which custom properties a value uses, which of
|
|
3
|
+
* them are not set, and the value with them substituted. A fallback counts
|
|
4
|
+
* only when its custom property is not set.
|
|
5
|
+
*/
|
|
6
|
+
import type { StyleMap } from './inspectLayoutModel.js';
|
|
7
|
+
/**
|
|
8
|
+
* The custom properties a value uses that are not set and have no fallback:
|
|
9
|
+
* the fallback of an unset one is used instead (and checked in turn).
|
|
10
|
+
*
|
|
11
|
+
* @param value - Value as written
|
|
12
|
+
* @param style - Computed styles (custom properties included)
|
|
13
|
+
* @returns Names of the unset custom properties
|
|
14
|
+
*/
|
|
15
|
+
export declare function unsetVariables(value: string, style: StyleMap): string[];
|
|
16
|
+
/**
|
|
17
|
+
* The custom properties a value takes its value from (fallbacks only when
|
|
18
|
+
* used).
|
|
19
|
+
*
|
|
20
|
+
* @param value - Value as written
|
|
21
|
+
* @param style - Computed styles
|
|
22
|
+
* @returns Names
|
|
23
|
+
*/
|
|
24
|
+
export declare function usedVariables(value: string, style: StyleMap): string[];
|
|
25
|
+
/**
|
|
26
|
+
* A value with its custom properties substituted.
|
|
27
|
+
*
|
|
28
|
+
* @param value - Value as written
|
|
29
|
+
* @param style - Computed styles
|
|
30
|
+
* @returns Substituted value (unset ones without fallback left as written)
|
|
31
|
+
*/
|
|
32
|
+
export declare function substituteVariables(value: string, style: StyleMap): string;
|
|
33
|
+
//# sourceMappingURL=inspectVariables.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `var()` in declared values: which custom properties a value uses, which of
|
|
3
|
+
* them are not set, and the value with them substituted. A fallback counts
|
|
4
|
+
* only when its custom property is not set.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The top-level `var()` calls of a value.
|
|
8
|
+
*
|
|
9
|
+
* @param value - Value as written
|
|
10
|
+
* @returns Calls in order (nested ones are inside a fallback)
|
|
11
|
+
*/
|
|
12
|
+
function varCalls(value) {
|
|
13
|
+
const calls = [];
|
|
14
|
+
for (let start = value.indexOf('var('); start !== -1; start = value.indexOf('var(', start + 1)) {
|
|
15
|
+
const end = closingParen(value, start + 3);
|
|
16
|
+
const [name = '', ...fallback] = value.slice(start + 4, end).split(',');
|
|
17
|
+
calls.push({
|
|
18
|
+
start,
|
|
19
|
+
end,
|
|
20
|
+
name: name.trim(),
|
|
21
|
+
...(fallback.length > 0 && { fallback: fallback.join(',').trim() }),
|
|
22
|
+
});
|
|
23
|
+
start = end;
|
|
24
|
+
}
|
|
25
|
+
return calls;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Index of the parenthesis that closes the one at `open`.
|
|
29
|
+
*
|
|
30
|
+
* @param text - Text
|
|
31
|
+
* @param open - Index of `(`
|
|
32
|
+
* @returns Index of the matching `)` (the end of the text when unbalanced)
|
|
33
|
+
*/
|
|
34
|
+
function closingParen(text, open) {
|
|
35
|
+
let depth = 0;
|
|
36
|
+
for (let i = open; i < text.length; i++) {
|
|
37
|
+
if (text[i] === '(')
|
|
38
|
+
depth++;
|
|
39
|
+
if (text[i] === ')' && --depth === 0)
|
|
40
|
+
return i;
|
|
41
|
+
}
|
|
42
|
+
return text.length;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The custom properties a value uses that are not set and have no fallback:
|
|
46
|
+
* the fallback of an unset one is used instead (and checked in turn).
|
|
47
|
+
*
|
|
48
|
+
* @param value - Value as written
|
|
49
|
+
* @param style - Computed styles (custom properties included)
|
|
50
|
+
* @returns Names of the unset custom properties
|
|
51
|
+
*/
|
|
52
|
+
export function unsetVariables(value, style) {
|
|
53
|
+
return varCalls(value).flatMap((call) => {
|
|
54
|
+
if (style[call.name] !== undefined)
|
|
55
|
+
return [];
|
|
56
|
+
return call.fallback !== undefined ? unsetVariables(call.fallback, style) : [call.name];
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The custom properties a value takes its value from (fallbacks only when
|
|
61
|
+
* used).
|
|
62
|
+
*
|
|
63
|
+
* @param value - Value as written
|
|
64
|
+
* @param style - Computed styles
|
|
65
|
+
* @returns Names
|
|
66
|
+
*/
|
|
67
|
+
export function usedVariables(value, style) {
|
|
68
|
+
return varCalls(value).flatMap((call) => style[call.name] !== undefined || call.fallback === undefined
|
|
69
|
+
? [call.name]
|
|
70
|
+
: usedVariables(call.fallback, style));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A value with its custom properties substituted.
|
|
74
|
+
*
|
|
75
|
+
* @param value - Value as written
|
|
76
|
+
* @param style - Computed styles
|
|
77
|
+
* @returns Substituted value (unset ones without fallback left as written)
|
|
78
|
+
*/
|
|
79
|
+
export function substituteVariables(value, style) {
|
|
80
|
+
let result = '';
|
|
81
|
+
let last = 0;
|
|
82
|
+
for (const call of varCalls(value)) {
|
|
83
|
+
const set = style[call.name];
|
|
84
|
+
const replacement = set !== undefined
|
|
85
|
+
? set.trim()
|
|
86
|
+
: call.fallback !== undefined
|
|
87
|
+
? substituteVariables(call.fallback, style)
|
|
88
|
+
: value.slice(call.start, call.end + 1);
|
|
89
|
+
result += value.slice(last, call.start) + replacement;
|
|
90
|
+
last = call.end + 1;
|
|
91
|
+
}
|
|
92
|
+
return result + value.slice(last);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=inspectVariables.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dom inspect --why <property>`: every declaration of a property on the
|
|
3
|
+
* element, the winner first, with `var()` values substituted and where the
|
|
4
|
+
* winner's custom properties are set. A shorthand gives one answer when one
|
|
5
|
+
* declaration sets all its longhands (listing every declaration it beats on
|
|
6
|
+
* any of them), else one per longhand.
|
|
7
|
+
*/
|
|
8
|
+
import type { InspectWhy } from '../../ipc/protocol/inspectTypes.js';
|
|
9
|
+
import { type Resolution } from './inspectCascade.js';
|
|
10
|
+
import type { CascadeInput, PropertyGroup } from './inspectCascadeModel.js';
|
|
11
|
+
/**
|
|
12
|
+
* `--why` for a property.
|
|
13
|
+
*
|
|
14
|
+
* @param group - The property and its longhands
|
|
15
|
+
* @param cascade - Resolved properties
|
|
16
|
+
* @param input - Matched rules, computed style and the label function
|
|
17
|
+
* @returns One entry, or one per longhand when they differ
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildWhy(group: PropertyGroup, cascade: Map<string, Resolution>, input: CascadeInput): InspectWhy[];
|
|
20
|
+
//# sourceMappingURL=inspectWhyModel.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dom inspect --why <property>`: every declaration of a property on the
|
|
3
|
+
* element, the winner first, with `var()` values substituted and where the
|
|
4
|
+
* winner's custom properties are set. A shorthand gives one answer when one
|
|
5
|
+
* declaration sets all its longhands (listing every declaration it beats on
|
|
6
|
+
* any of them), else one per longhand.
|
|
7
|
+
*/
|
|
8
|
+
import { normalizeProperty } from './inspectAllStyles.js';
|
|
9
|
+
import { resolveCascade } from './inspectCascade.js';
|
|
10
|
+
import { substituteVariables, unsetVariables, usedVariables, } from './inspectVariables.js';
|
|
11
|
+
/**
|
|
12
|
+
* `--why` for a property.
|
|
13
|
+
*
|
|
14
|
+
* @param group - The property and its longhands
|
|
15
|
+
* @param cascade - Resolved properties
|
|
16
|
+
* @param input - Matched rules, computed style and the label function
|
|
17
|
+
* @returns One entry, or one per longhand when they differ
|
|
18
|
+
*/
|
|
19
|
+
export function buildWhy(group, cascade, input) {
|
|
20
|
+
const whys = group.longhands.map((longhand) => whyOf(longhand, cascade.get(longhand), input));
|
|
21
|
+
const [first] = whys;
|
|
22
|
+
if (!first || group.shorthand === undefined)
|
|
23
|
+
return whys;
|
|
24
|
+
const winner = JSON.stringify(first.chain[0]);
|
|
25
|
+
if (!whys.every((why) => JSON.stringify(why.chain[0]) === winner))
|
|
26
|
+
return whys;
|
|
27
|
+
const values = whys.map((why) => why.computed);
|
|
28
|
+
const computed = values.every((value) => value === first.computed)
|
|
29
|
+
? first.computed
|
|
30
|
+
: values.join(' ');
|
|
31
|
+
const beaten = whys.flatMap((why) => why.chain.slice(1));
|
|
32
|
+
const overridden = [...new Map(beaten.map((entry) => [JSON.stringify(entry), entry])).values()];
|
|
33
|
+
const chain = [...first.chain.slice(0, 1), ...overridden];
|
|
34
|
+
return [{ ...first, property: group.shorthand, computed, chain }];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `--why` for one longhand.
|
|
38
|
+
*
|
|
39
|
+
* @param property - Longhand
|
|
40
|
+
* @param resolution - Its resolution
|
|
41
|
+
* @param input - Matched rules, computed style and the label function
|
|
42
|
+
* @returns Why
|
|
43
|
+
*/
|
|
44
|
+
function whyOf(property, resolution, input) {
|
|
45
|
+
const winner = resolution?.winner;
|
|
46
|
+
const chain = [
|
|
47
|
+
...(winner
|
|
48
|
+
? [whyEntry(winner, winner.ancestor !== undefined ? 'inherited' : 'applied', input)]
|
|
49
|
+
: []),
|
|
50
|
+
...(resolution?.overridden ?? []).map((d) => whyEntry(d, 'overridden', input)),
|
|
51
|
+
];
|
|
52
|
+
const variables = winner ? variableSources(winner, input) : [];
|
|
53
|
+
return {
|
|
54
|
+
property,
|
|
55
|
+
computed: normalizeProperty(property, input.style[property] ?? ''),
|
|
56
|
+
chain,
|
|
57
|
+
...(variables.length > 0 && { variables }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One declaration in a `--why` chain: a shorthand's as written, `var()`
|
|
62
|
+
* substituted (or the custom properties that are not set), with the
|
|
63
|
+
* selector's specificity.
|
|
64
|
+
*
|
|
65
|
+
* @param declaration - Declaration
|
|
66
|
+
* @param status - Applied, overridden or inherited
|
|
67
|
+
* @param input - Computed style and the label function
|
|
68
|
+
* @returns Entry
|
|
69
|
+
*/
|
|
70
|
+
function whyEntry(declaration, status, input) {
|
|
71
|
+
const value = declaration.via ? (declaration.written ?? declaration.value) : declaration.value;
|
|
72
|
+
const unset = value.includes('var(') ? unsetVariables(value, input.style) : [];
|
|
73
|
+
const resolved = value.includes('var(') ? resolvedValue(declaration, value, input) : value;
|
|
74
|
+
const { specificity, layer, condition } = declaration.source;
|
|
75
|
+
return {
|
|
76
|
+
value,
|
|
77
|
+
...(declaration.via && { via: declaration.via }),
|
|
78
|
+
...(unset.length > 0 ? { unset } : resolved !== value && { resolved }),
|
|
79
|
+
source: input.label(declaration),
|
|
80
|
+
...(specificity && { specificity }),
|
|
81
|
+
status,
|
|
82
|
+
...(declaration.important && { important: true }),
|
|
83
|
+
...(layer && { layer }),
|
|
84
|
+
...(condition && { condition }),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** How many levels of custom properties set from others are followed */
|
|
88
|
+
const MAX_VARIABLE_DEPTH = 5;
|
|
89
|
+
/**
|
|
90
|
+
* Where the custom properties the winning value uses are set, and those
|
|
91
|
+
* their values use in turn (`--bs-btn-border-width: var(--bs-border-width)`).
|
|
92
|
+
*
|
|
93
|
+
* @param winner - Winning declaration
|
|
94
|
+
* @param input - Matched rules, computed style and the label function
|
|
95
|
+
* @returns The variables with a declaration (on the element or an ancestor)
|
|
96
|
+
*/
|
|
97
|
+
function variableSources(winner, input) {
|
|
98
|
+
const found = [];
|
|
99
|
+
let names = usedVariables(winner.written ?? winner.value, input.style);
|
|
100
|
+
for (let depth = 0; names.length > 0 && depth < MAX_VARIABLE_DEPTH; depth++) {
|
|
101
|
+
const cascade = resolveCascade(input.matched, names);
|
|
102
|
+
const next = names.flatMap((name) => {
|
|
103
|
+
const declaration = cascade.get(name)?.winner;
|
|
104
|
+
if (!declaration || found.some((variable) => variable.name === name))
|
|
105
|
+
return [];
|
|
106
|
+
found.push({
|
|
107
|
+
name,
|
|
108
|
+
value: declaration.value,
|
|
109
|
+
source: input.label(declaration),
|
|
110
|
+
...(declaration.ancestor !== undefined && { inherited: declaration.ancestor }),
|
|
111
|
+
});
|
|
112
|
+
return usedVariables(declaration.value, input.style);
|
|
113
|
+
});
|
|
114
|
+
names = [...new Set(next)];
|
|
115
|
+
}
|
|
116
|
+
return found;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A `var()` value substituted; a color longhand's in hex (Tailwind's
|
|
120
|
+
* `lab()` and `oklch()` tokens are unreadable).
|
|
121
|
+
*
|
|
122
|
+
* @param declaration - Declaration
|
|
123
|
+
* @param value - Its value as shown
|
|
124
|
+
* @param input - Computed style
|
|
125
|
+
* @returns Substituted value
|
|
126
|
+
*/
|
|
127
|
+
function resolvedValue(declaration, value, input) {
|
|
128
|
+
const substituted = substituteVariables(value, input.style);
|
|
129
|
+
const isColor = declaration.via === undefined && declaration.property.endsWith('color');
|
|
130
|
+
return isColor && !substituted.includes('var(')
|
|
131
|
+
? normalizeProperty(declaration.property, substituted)
|
|
132
|
+
: substituted;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=inspectWhyModel.js.map
|
|
@@ -30,7 +30,11 @@ export interface RawElementLayout {
|
|
|
30
30
|
text: string;
|
|
31
31
|
context: string;
|
|
32
32
|
geometry: ElementGeometry;
|
|
33
|
-
|
|
33
|
+
/** The element on top at its visible center, and whether it paints nothing there */
|
|
34
|
+
cover: {
|
|
35
|
+
element: string;
|
|
36
|
+
transparent: boolean;
|
|
37
|
+
} | null;
|
|
34
38
|
computed: LayoutComputedStyle;
|
|
35
39
|
}
|
|
36
40
|
/** What {@link LAYOUT_JS} returns. */
|
|
@@ -150,6 +150,12 @@ const LAYOUT_JS = `function (found, index, limit) {
|
|
|
150
150
|
}
|
|
151
151
|
return best;
|
|
152
152
|
};
|
|
153
|
+
const paintsNothing = (node) => {
|
|
154
|
+
const s = node.ownerDocument.defaultView.getComputedStyle(node);
|
|
155
|
+
const clearColor = (c) => c === 'transparent' || /^rgba\\(.*,\\s*0\\)$/.test(c);
|
|
156
|
+
const ownText = Array.from(node.childNodes).some((n) => n.nodeType === 3 && n.data.trim() !== '');
|
|
157
|
+
return clearColor(s.backgroundColor) && s.backgroundImage === 'none' && s.boxShadow === 'none' && !ownText;
|
|
158
|
+
};
|
|
153
159
|
const hitTestable = (node) => node.ownerDocument.defaultView.getComputedStyle(node).pointerEvents !== 'none';
|
|
154
160
|
const coveredBy = (el, g) => {
|
|
155
161
|
const center = hitTestable(el) && visibleCenter(el, g);
|
|
@@ -164,7 +170,7 @@ const LAYOUT_JS = `function (found, index, limit) {
|
|
|
164
170
|
y += offset.y;
|
|
165
171
|
cover = coverAt(view.frameElement, x, y);
|
|
166
172
|
}
|
|
167
|
-
return cover ? describe(cover) : null;
|
|
173
|
+
return cover ? { element: describe(cover), transparent: paintsNothing(cover) } : null;
|
|
168
174
|
};
|
|
169
175
|
const elements = picked.map(([i, el]) => {
|
|
170
176
|
const style = el.ownerDocument.defaultView.getComputedStyle(el);
|
|
@@ -176,7 +182,7 @@ const LAYOUT_JS = `function (found, index, limit) {
|
|
|
176
182
|
text: String(textOf(el)).replace(/\\s+/g, ' ').trim().slice(0, 1000),
|
|
177
183
|
context: contextOf(el),
|
|
178
184
|
geometry: geometry,
|
|
179
|
-
|
|
185
|
+
cover: geometry.hidden ? null : coveredBy(el, geometry),
|
|
180
186
|
computed: { display: style.display, visibility: style.visibility, position: style.position, opacity: style.opacity, zIndex: style.zIndex }
|
|
181
187
|
};
|
|
182
188
|
});
|
|
@@ -324,7 +330,8 @@ function elementLayout(raw, page) {
|
|
|
324
330
|
},
|
|
325
331
|
viewport: { x: Math.round(rect.x), y: Math.round(rect.y) },
|
|
326
332
|
...placement,
|
|
327
|
-
...(inView && raw.
|
|
333
|
+
...(inView && raw.cover && { coveredBy: raw.cover.element }),
|
|
334
|
+
...(inView && raw.cover?.transparent && { coverTransparent: true }),
|
|
328
335
|
...(raw.geometry.invisible && { invisible: raw.geometry.invisible }),
|
|
329
336
|
...(raw.geometry.inert && { inert: true }),
|
|
330
337
|
computed: raw.computed,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Page-side functions of `bdg dom listeners`: what only the page can tell
|
|
3
3
|
* about an element's listeners (handler names and identities, React root
|
|
4
|
-
* containers, the handlers behind jQuery's dispatcher
|
|
5
|
-
* of the element and its ancestors, the
|
|
4
|
+
* containers, the handlers behind jQuery's dispatcher and Preact's event
|
|
5
|
+
* proxy, React's `on…` props of the element and its ancestors, the
|
|
6
|
+
* element's iframe).
|
|
6
7
|
*
|
|
7
8
|
* Each piece is a function expression in a string, combined into
|
|
8
9
|
* {@link ELEMENT_INFO_JS}; every lookup of page globals is guarded, so a
|
|
@@ -14,17 +15,18 @@ export declare const MAX_JQUERY_HANDLERS = 50;
|
|
|
14
15
|
export declare const MAX_REACT_HANDLERS = 50;
|
|
15
16
|
/**
|
|
16
17
|
* Page function, called on the element with the listeners (position in the
|
|
17
|
-
* chain
|
|
18
|
+
* chain, event type and capture flag of each), the requested event types (null for all;
|
|
18
19
|
* React props are filtered before the limit), then the chain's objects, then each
|
|
19
20
|
* listener's handler, then the function each handler calls (a bound
|
|
20
21
|
* function's target, else null).
|
|
21
22
|
*
|
|
22
|
-
* Returns `[info, ...
|
|
23
|
+
* Returns `[info, ...jQueryAndPreactHandlers, ...reactHandlers]`. `info` has the
|
|
23
24
|
* iframe element holding the element's document (`frame`), a framework
|
|
24
25
|
* label per chain entry (`roots`), per listener the handler's name, the
|
|
25
26
|
* identity and name of the function it calls (equal identities are the same
|
|
26
27
|
* function object) and, for jQuery's dispatcher, the jQuery handlers that
|
|
27
|
-
* run for the element
|
|
28
|
+
* run for the element, for Preact's event proxy the handler Preact runs
|
|
29
|
+
* (`preact`); then the React `on…` props that run for the
|
|
28
30
|
* element's events (`react`, see {@link REACT_HANDLERS_JS}). Their functions follow `info` in the same order.
|
|
29
31
|
* After {@link MAX_JQUERY_HANDLERS}, dispatchers stay unresolved and are
|
|
30
32
|
* counted in `jquerySkipped`; after {@link MAX_REACT_HANDLERS}, React props
|
|
@@ -44,6 +46,10 @@ export interface ElementInfo {
|
|
|
44
46
|
selector: string | null;
|
|
45
47
|
name: string;
|
|
46
48
|
}>;
|
|
49
|
+
/** The handler Preact runs from this listener (set when it is Preact's event proxy) */
|
|
50
|
+
preact?: {
|
|
51
|
+
name: string;
|
|
52
|
+
};
|
|
47
53
|
}>;
|
|
48
54
|
/** jQuery handlers left unresolved (over the limit) */
|
|
49
55
|
jquerySkipped: number;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Page-side functions of `bdg dom listeners`: what only the page can tell
|
|
3
3
|
* about an element's listeners (handler names and identities, React root
|
|
4
|
-
* containers, the handlers behind jQuery's dispatcher
|
|
5
|
-
* of the element and its ancestors, the
|
|
4
|
+
* containers, the handlers behind jQuery's dispatcher and Preact's event
|
|
5
|
+
* proxy, React's `on…` props of the element and its ancestors, the
|
|
6
|
+
* element's iframe).
|
|
6
7
|
*
|
|
7
8
|
* Each piece is a function expression in a string, combined into
|
|
8
9
|
* {@link ELEMENT_INFO_JS}; every lookup of page globals is guarded, so a
|
|
@@ -95,12 +96,30 @@ const REACT_PROPS_JS = `(node) => {
|
|
|
95
96
|
}`;
|
|
96
97
|
/** Most fibers walked up from the element (guards against cycles) */
|
|
97
98
|
const MAX_FIBER_STEPS = 1000;
|
|
99
|
+
/**
|
|
100
|
+
* `(fiber) => fiber | null`: for a React root's fiber, the fiber of the
|
|
101
|
+
* nearest React-rendered DOM element at or above its container (where
|
|
102
|
+
* React continues for nested roots: an outer root's handlers run for
|
|
103
|
+
* events in an inner one); null for other fibers and for top-level roots.
|
|
104
|
+
*/
|
|
105
|
+
const OUTER_ROOT_FIBER_JS = `(fiber) => {
|
|
106
|
+
const own = ${OWN_VALUE_JS};
|
|
107
|
+
const container = own(own(fiber, 'stateNode'), 'containerInfo');
|
|
108
|
+
try {
|
|
109
|
+
for (let node = container; node && typeof node === 'object'; node = node.parentNode) {
|
|
110
|
+
const outer = (${REACT_FIBER_JS})(node);
|
|
111
|
+
if (outer) return outer;
|
|
112
|
+
}
|
|
113
|
+
} catch (e) { return null; }
|
|
114
|
+
return null;
|
|
115
|
+
}`;
|
|
98
116
|
/**
|
|
99
117
|
* `(element, nodes) => Array<{ node, position }>`: the DOM elements whose
|
|
100
118
|
* React props run for events on the element, nearest first. With a fiber,
|
|
101
119
|
* the host components on its `.return` path (so a portal's React parents
|
|
102
|
-
* count and DOM parents outside the React path don't)
|
|
103
|
-
*
|
|
120
|
+
* count and DOM parents outside the React path don't), continued from a
|
|
121
|
+
* nested root's container into the outer root; `position` is the node's
|
|
122
|
+
* place in the chain, null outside it. Without one, the chain's elements.
|
|
104
123
|
*/
|
|
105
124
|
const REACT_HOSTS_JS = `(element, nodes) => {
|
|
106
125
|
const own = ${OWN_VALUE_JS};
|
|
@@ -115,10 +134,70 @@ const REACT_HOSTS_JS = `(element, nodes) => {
|
|
|
115
134
|
const position = nodes.indexOf(node);
|
|
116
135
|
hosts.push({ node, position: position === -1 ? null : position });
|
|
117
136
|
}
|
|
118
|
-
fiber = own(fiber, 'return');
|
|
137
|
+
fiber = own(fiber, 'return') || (${OUTER_ROOT_FIBER_JS})(fiber);
|
|
119
138
|
}
|
|
120
139
|
return hosts;
|
|
121
140
|
}`;
|
|
141
|
+
/** Longest source of a minified Preact event proxy (Preact 10 and 11: about 120 characters) */
|
|
142
|
+
const MAX_PREACT_PROXY_LENGTH = 200;
|
|
143
|
+
/**
|
|
144
|
+
* `(source, read) => boolean`: whether a proxy source calls the handler it
|
|
145
|
+
* reads (`read`: the match of `this.<key>[<event>.type + …]`) with the
|
|
146
|
+
* event, directly (`this.l[e.type + false](e)`) or through a variable
|
|
147
|
+
* (`var t = this.l[u.type + n]; … return t(l.event ? l.event(u) : u)`).
|
|
148
|
+
*/
|
|
149
|
+
const CALLS_READ_HANDLER_JS = `(source, read) => {
|
|
150
|
+
const event = read[2];
|
|
151
|
+
const passesEvent = (from) => {
|
|
152
|
+
const open = source.indexOf('(', from);
|
|
153
|
+
const close = source.indexOf(')', open);
|
|
154
|
+
if (open === -1 || close === -1 || source.slice(from, open).trim() !== '') return false;
|
|
155
|
+
return source.slice(open + 1, close).split(/[^\\w$]+/).includes(event);
|
|
156
|
+
};
|
|
157
|
+
const end = read.index + read[0].length;
|
|
158
|
+
if (passesEvent(end)) return true;
|
|
159
|
+
const assigned = /([\\w$]+)\\s*=\\s*$/.exec(source.slice(0, read.index));
|
|
160
|
+
if (!assigned) return false;
|
|
161
|
+
const variable = assigned[1];
|
|
162
|
+
for (let at = source.indexOf(variable, end); at !== -1; at = source.indexOf(variable, at + 1)) {
|
|
163
|
+
const before = source[at - 1] || '';
|
|
164
|
+
if (/[\\w$.]/.test(before)) continue;
|
|
165
|
+
if (passesEvent(at + variable.length)) return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}`;
|
|
169
|
+
/**
|
|
170
|
+
* `(node, type, capture, handler) => function | null`: the handler Preact
|
|
171
|
+
* runs from `handler` when it is Preact's event proxy on `node`. Preact
|
|
172
|
+
* keeps an element's handlers in an object on the element under a mangled
|
|
173
|
+
* key (`l` in Preact 10, `__e` in 11, `_listeners` unmangled), keyed by
|
|
174
|
+
* event type plus the capture flag (`clickfalse`); the key is read from the
|
|
175
|
+
* proxy's own source (`this.l[e.type + useCapture]`), so it follows
|
|
176
|
+
* Preact's renames. A proxy named `eventProxy`/`eventProxyCapture`
|
|
177
|
+
* (unminified builds; Preact 8 keys by type alone) is accepted as such;
|
|
178
|
+
* any other must look like Preact's minified one: a short function whose
|
|
179
|
+
* key holds a function for exactly the type plus capture flag, which it
|
|
180
|
+
* calls with the event. A generic dispatcher (`this.handlers[e.type](e)`)
|
|
181
|
+
* is left alone.
|
|
182
|
+
*/
|
|
183
|
+
const PREACT_HANDLER_JS = `(node, type, capture, handler) => {
|
|
184
|
+
const own = ${OWN_VALUE_JS};
|
|
185
|
+
try {
|
|
186
|
+
if (typeof handler !== 'function' || !node || typeof node !== 'object') return null;
|
|
187
|
+
const source = Function.prototype.toString.call(handler);
|
|
188
|
+
const read = /this\\.([\\w$]+)\\[([\\w$]+)\\.type(?:\\s*\\+\\s*(![01]|true|false|[\\w$]+))?\\s*\\]/.exec(source);
|
|
189
|
+
const store = read ? own(node, read[1]) : undefined;
|
|
190
|
+
if (!store || typeof store !== 'object') return null;
|
|
191
|
+
const flag = { true: true, '!0': true, false: false, '!1': false }[read[3]];
|
|
192
|
+
if (flag !== undefined && flag !== capture) return null;
|
|
193
|
+
const fn = own(store, read[3] ? type + capture : type);
|
|
194
|
+
if (typeof fn !== 'function') return null;
|
|
195
|
+
const name = own(handler, 'name');
|
|
196
|
+
if (name === 'eventProxy' || name === 'eventProxyCapture') return fn;
|
|
197
|
+
const minified = read[3] && source.length < ${MAX_PREACT_PROXY_LENGTH};
|
|
198
|
+
return minified && (${CALLS_READ_HANDLER_JS})(source, read) ? fn : null;
|
|
199
|
+
} catch (e) { return null; }
|
|
200
|
+
}`;
|
|
122
201
|
/** `(node) => string`: CDP-like description of an element, e.g. `div#app.card` */
|
|
123
202
|
const DESCRIBE_NODE_JS = `(node) => {
|
|
124
203
|
try {
|
|
@@ -222,17 +301,18 @@ const REACT_HANDLERS_JS = `(element, nodes, wanted, fns) => {
|
|
|
222
301
|
}`;
|
|
223
302
|
/**
|
|
224
303
|
* Page function, called on the element with the listeners (position in the
|
|
225
|
-
* chain
|
|
304
|
+
* chain, event type and capture flag of each), the requested event types (null for all;
|
|
226
305
|
* React props are filtered before the limit), then the chain's objects, then each
|
|
227
306
|
* listener's handler, then the function each handler calls (a bound
|
|
228
307
|
* function's target, else null).
|
|
229
308
|
*
|
|
230
|
-
* Returns `[info, ...
|
|
309
|
+
* Returns `[info, ...jQueryAndPreactHandlers, ...reactHandlers]`. `info` has the
|
|
231
310
|
* iframe element holding the element's document (`frame`), a framework
|
|
232
311
|
* label per chain entry (`roots`), per listener the handler's name, the
|
|
233
312
|
* identity and name of the function it calls (equal identities are the same
|
|
234
313
|
* function object) and, for jQuery's dispatcher, the jQuery handlers that
|
|
235
|
-
* run for the element
|
|
314
|
+
* run for the element, for Preact's event proxy the handler Preact runs
|
|
315
|
+
* (`preact`); then the React `on…` props that run for the
|
|
236
316
|
* element's events (`react`, see {@link REACT_HANDLERS_JS}). Their functions follow `info` in the same order.
|
|
237
317
|
* After {@link MAX_JQUERY_HANDLERS}, dispatchers stay unresolved and are
|
|
238
318
|
* counted in `jquerySkipped`; after {@link MAX_REACT_HANDLERS}, React props
|
|
@@ -264,7 +344,13 @@ export const ELEMENT_INFO_JS = `function (listeners, types, ...rest) {
|
|
|
264
344
|
const entry = { name: typeof handler === 'function' ? handler.name : null, identity: identity(target),
|
|
265
345
|
targetName: typeof target === 'function' ? target.name : null };
|
|
266
346
|
const resolved = jq ? (${JQUERY_HANDLERS_JS})(jq, this, nodes[listener.position], listener.type, handler) : null;
|
|
267
|
-
if (!resolved)
|
|
347
|
+
if (!resolved) {
|
|
348
|
+
const preact = (${PREACT_HANDLER_JS})(nodes[listener.position], listener.type, listener.capture, handler);
|
|
349
|
+
if (!preact) return entry;
|
|
350
|
+
fns.push(preact);
|
|
351
|
+
const preactName = (${OWN_VALUE_JS})(preact, 'name');
|
|
352
|
+
return { ...entry, preact: { name: typeof preactName === 'string' ? preactName : '' } };
|
|
353
|
+
}
|
|
268
354
|
if (fns.length + resolved.length > ${MAX_JQUERY_HANDLERS}) {
|
|
269
355
|
jquerySkipped += resolved.length;
|
|
270
356
|
return entry;
|