made-refine 0.2.17 → 0.2.19
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/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +476 -506
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +476 -506
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-lksVP2Wq.d.mts → utils-CpmjloNg.d.mts} +0 -8
- package/dist/{utils-lksVP2Wq.d.ts → utils-CpmjloNg.d.ts} +0 -8
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1756 -1754
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +1756 -1754
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
package/dist/utils.mjs
CHANGED
|
@@ -40,1932 +40,1934 @@ function getZoomScale() {
|
|
|
40
40
|
return snap.active ? snap.zoom : 1;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// src/utils/
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
// src/utils/debug-stack.ts
|
|
44
|
+
var STACK_SOURCE_FILE_EXTENSION_REGEX = /\.(jsx|tsx|ts|js)$/;
|
|
45
|
+
var STACK_BUNDLED_FILE_PATTERN_REGEX = /(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i;
|
|
46
|
+
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
|
|
47
|
+
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/;
|
|
48
|
+
var SERVER_FRAME_MARKER = "(at Server)";
|
|
49
|
+
var STACK_INTERNAL_SCHEME_PREFIXES = [
|
|
50
|
+
"rsc://",
|
|
51
|
+
"about://React/",
|
|
52
|
+
"React/Server/",
|
|
53
|
+
"file:///",
|
|
54
|
+
"webpack://",
|
|
55
|
+
"webpack-internal://",
|
|
56
|
+
"node:",
|
|
57
|
+
"turbopack://",
|
|
58
|
+
"/app-pages-browser/"
|
|
59
|
+
];
|
|
60
|
+
function formatOwnerDebugStack(stack) {
|
|
61
|
+
if (!stack) return "";
|
|
62
|
+
const lines = stack.split("\n");
|
|
63
|
+
const filtered = [];
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
const trimmed = line.trim();
|
|
66
|
+
if (!trimmed) continue;
|
|
67
|
+
if (trimmed === "Error: react-stack-top-frame") continue;
|
|
68
|
+
if (trimmed.includes("react_stack_bottom_frame") || trimmed.includes("react-stack-bottom-frame")) {
|
|
69
|
+
continue;
|
|
63
70
|
}
|
|
71
|
+
filtered.push(line);
|
|
64
72
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
function getComponentProps(fiber) {
|
|
68
|
-
const props = fiber?.memoizedProps ?? fiber?.pendingProps;
|
|
69
|
-
if (!props || typeof props !== "object") return {};
|
|
70
|
-
const result = {};
|
|
71
|
-
for (const [key, value] of Object.entries(props)) {
|
|
72
|
-
if (EXCLUDED_PROP_KEYS.has(key)) continue;
|
|
73
|
-
if (key.startsWith("data-")) continue;
|
|
74
|
-
const serialized = serializePropValue(value);
|
|
75
|
-
if (serialized !== void 0) {
|
|
76
|
-
result[key] = serialized;
|
|
77
|
-
}
|
|
73
|
+
if (filtered.length > 0 && filtered[0].includes("fakeJSXCallSite")) {
|
|
74
|
+
filtered.shift();
|
|
78
75
|
}
|
|
79
|
-
return
|
|
76
|
+
return filtered.join("\n");
|
|
80
77
|
}
|
|
81
|
-
function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
function extractStackLocation(urlLike) {
|
|
79
|
+
if (!urlLike.includes(":")) return [urlLike, void 0, void 0];
|
|
80
|
+
const isWrappedLocation = urlLike.startsWith("(") && /:\d+\)$/.test(urlLike);
|
|
81
|
+
const sanitizedResult = isWrappedLocation ? urlLike.slice(1, -1) : urlLike;
|
|
82
|
+
const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(sanitizedResult);
|
|
83
|
+
if (!parts) return [sanitizedResult, void 0, void 0];
|
|
84
|
+
return [
|
|
85
|
+
parts[1],
|
|
86
|
+
parts[2] !== void 0 ? Number(parts[2]) : void 0,
|
|
87
|
+
parts[3] !== void 0 ? Number(parts[3]) : void 0
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
function parseV8StackLine(line) {
|
|
91
|
+
let currentLine = line;
|
|
92
|
+
if (currentLine.includes("(eval ")) {
|
|
93
|
+
currentLine = currentLine.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
|
|
89
94
|
}
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
let sanitizedLine = currentLine.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
|
|
96
|
+
const locationMatch = sanitizedLine.match(/ (\(.+\)$)/);
|
|
97
|
+
if (locationMatch) {
|
|
98
|
+
sanitizedLine = sanitizedLine.replace(locationMatch[0], "");
|
|
99
|
+
}
|
|
100
|
+
const [fileName, lineNumber, columnNumber] = extractStackLocation(
|
|
101
|
+
locationMatch ? locationMatch[1] : sanitizedLine
|
|
102
|
+
);
|
|
103
|
+
const functionName = locationMatch && sanitizedLine ? sanitizedLine : void 0;
|
|
104
|
+
if (fileName === "eval" || fileName === "<anonymous>") {
|
|
92
105
|
return {
|
|
93
|
-
|
|
94
|
-
line: typeof pending.lineNumber === "number" ? pending.lineNumber : void 0,
|
|
95
|
-
column: typeof pending.columnNumber === "number" ? pending.columnNumber : void 0
|
|
106
|
+
functionName
|
|
96
107
|
};
|
|
97
108
|
}
|
|
98
|
-
return
|
|
109
|
+
return {
|
|
110
|
+
functionName,
|
|
111
|
+
fileName,
|
|
112
|
+
lineNumber,
|
|
113
|
+
columnNumber,
|
|
114
|
+
source: currentLine,
|
|
115
|
+
isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
|
|
116
|
+
};
|
|
99
117
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
function parseFFOrSafariStackLine(line) {
|
|
119
|
+
let currentLine = line;
|
|
120
|
+
if (currentLine.includes(" > eval")) {
|
|
121
|
+
currentLine = currentLine.replace(
|
|
122
|
+
/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
|
|
123
|
+
":$1"
|
|
124
|
+
);
|
|
105
125
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/(?:^|\/)components\/ui\//,
|
|
110
|
-
/(?:^|\/)ui\/primitives\//,
|
|
111
|
-
/(?:^|\/)design-system\//
|
|
112
|
-
];
|
|
113
|
-
var PRIMITIVE_NPM_PATTERNS = [
|
|
114
|
-
/@base-ui\//,
|
|
115
|
-
/@radix-ui\//,
|
|
116
|
-
/@headlessui\//,
|
|
117
|
-
/@chakra-ui\//,
|
|
118
|
-
/@mantine\//,
|
|
119
|
-
/@mui\//,
|
|
120
|
-
/@ark-ui\//
|
|
121
|
-
];
|
|
122
|
-
var FRAMEWORK_EXCLUSION_PATTERNS = [
|
|
123
|
-
/node_modules\/react\//,
|
|
124
|
-
/node_modules\/react-dom\//,
|
|
125
|
-
/node_modules\/next\/dist\//,
|
|
126
|
-
/node_modules\/scheduler\//,
|
|
127
|
-
/node_modules\/react-server\//
|
|
128
|
-
];
|
|
129
|
-
function isComponentPrimitivePath(filePath) {
|
|
130
|
-
const normalized = filePath.replace(/\\/g, "/");
|
|
131
|
-
for (const pattern of FRAMEWORK_EXCLUSION_PATTERNS) {
|
|
132
|
-
if (pattern.test(normalized)) return false;
|
|
126
|
+
const trimmed = currentLine.trim();
|
|
127
|
+
if (!trimmed || SAFARI_NATIVE_CODE_REGEXP.test(trimmed)) {
|
|
128
|
+
return null;
|
|
133
129
|
}
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
if (!trimmed.includes("@") && !trimmed.includes(":")) {
|
|
131
|
+
return {
|
|
132
|
+
functionName: trimmed,
|
|
133
|
+
source: currentLine,
|
|
134
|
+
isServer: trimmed.includes(SERVER_FRAME_MARKER)
|
|
135
|
+
};
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
const atIndex = trimmed.lastIndexOf("@");
|
|
138
|
+
if (atIndex === -1) {
|
|
139
|
+
return null;
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
+
const maybeFunctionName = trimmed.slice(0, atIndex);
|
|
142
|
+
const location = trimmed.slice(atIndex + 1);
|
|
143
|
+
const [fileName, lineNumber, columnNumber] = extractStackLocation(location);
|
|
144
|
+
return {
|
|
145
|
+
functionName: maybeFunctionName || void 0,
|
|
146
|
+
fileName,
|
|
147
|
+
lineNumber,
|
|
148
|
+
columnNumber,
|
|
149
|
+
source: currentLine,
|
|
150
|
+
isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
|
|
151
|
+
};
|
|
141
152
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
|
|
153
|
+
function parseInStackLine(line) {
|
|
154
|
+
const functionName = line.replace(/^\s*in\s+/, "").replace(/\s*\(at .*\)$/, "").trim();
|
|
155
|
+
if (!functionName) return null;
|
|
156
|
+
return {
|
|
157
|
+
functionName,
|
|
158
|
+
source: line,
|
|
159
|
+
isServer: line.includes(SERVER_FRAME_MARKER)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function parseDebugStack(stack) {
|
|
163
|
+
const frames = [];
|
|
164
|
+
for (const rawLine of stack.split("\n")) {
|
|
165
|
+
if (FIREFOX_SAFARI_STACK_REGEXP.test(rawLine)) {
|
|
166
|
+
const parsed = parseFFOrSafariStackLine(rawLine);
|
|
167
|
+
if (parsed) frames.push(parsed);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (/^\s*at\s+/.test(rawLine)) {
|
|
171
|
+
const parsed = parseV8StackLine(rawLine);
|
|
172
|
+
if (parsed) frames.push(parsed);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (/^\s*in\s+/.test(rawLine)) {
|
|
176
|
+
const parsed = parseInStackLine(rawLine);
|
|
177
|
+
if (parsed) frames.push(parsed);
|
|
178
|
+
}
|
|
145
179
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
180
|
+
return frames;
|
|
181
|
+
}
|
|
182
|
+
function normalizeStackFileName(fileName) {
|
|
183
|
+
if (!fileName) return "";
|
|
184
|
+
let normalized = fileName;
|
|
185
|
+
const isHttpUrl = normalized.startsWith("http://") || normalized.startsWith("https://");
|
|
186
|
+
if (isHttpUrl) {
|
|
187
|
+
try {
|
|
188
|
+
normalized = new URL(normalized).pathname;
|
|
189
|
+
} catch {
|
|
190
|
+
}
|
|
150
191
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
192
|
+
let didStripPrefix = true;
|
|
193
|
+
while (didStripPrefix) {
|
|
194
|
+
didStripPrefix = false;
|
|
195
|
+
for (const prefix of STACK_INTERNAL_SCHEME_PREFIXES) {
|
|
196
|
+
if (normalized.startsWith(prefix)) {
|
|
197
|
+
normalized = normalized.slice(prefix.length);
|
|
198
|
+
if (prefix === "file:///") {
|
|
199
|
+
normalized = `/${normalized.replace(/^\/+/, "")}`;
|
|
200
|
+
}
|
|
201
|
+
didStripPrefix = true;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
154
204
|
}
|
|
155
205
|
}
|
|
156
|
-
|
|
157
|
-
|
|
206
|
+
normalized = normalized.replace(/^\/\(app-pages-browser\)\//, "/").replace(/^\/\.\//, "/").replace(/^\.\//, "");
|
|
207
|
+
const queryIndex = normalized.indexOf("?");
|
|
208
|
+
if (queryIndex !== -1) {
|
|
209
|
+
normalized = normalized.slice(0, queryIndex);
|
|
158
210
|
}
|
|
159
|
-
return
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// src/utils.ts
|
|
163
|
-
function clamp(value, min, max) {
|
|
164
|
-
if (!Number.isFinite(value)) return min;
|
|
165
|
-
if (max < min) return min;
|
|
166
|
-
return Math.max(min, Math.min(max, value));
|
|
211
|
+
return normalized;
|
|
167
212
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
213
|
+
function isSourceStackFile(fileName) {
|
|
214
|
+
const normalizedFileName = normalizeStackFileName(fileName);
|
|
215
|
+
if (!normalizedFileName) return false;
|
|
216
|
+
if (!STACK_SOURCE_FILE_EXTENSION_REGEX.test(normalizedFileName)) return false;
|
|
217
|
+
return !STACK_BUNDLED_FILE_PATTERN_REGEX.test(normalizedFileName);
|
|
174
218
|
}
|
|
175
|
-
function
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
function buildFunctionNameToRscFramesMap(fiber) {
|
|
220
|
+
const functionNameToRscFrames = /* @__PURE__ */ new Map();
|
|
221
|
+
const visited = /* @__PURE__ */ new Set();
|
|
222
|
+
let current = fiber;
|
|
223
|
+
while (current && !visited.has(current)) {
|
|
224
|
+
visited.add(current);
|
|
225
|
+
const rawStack = current?._debugStack?.stack;
|
|
226
|
+
const stack = typeof rawStack === "string" ? formatOwnerDebugStack(rawStack) : "";
|
|
227
|
+
if (stack) {
|
|
228
|
+
const frames = parseDebugStack(stack);
|
|
229
|
+
for (const frame of frames) {
|
|
230
|
+
if (!frame.functionName || !frame.fileName) continue;
|
|
231
|
+
if (!frame.fileName.startsWith("rsc://")) continue;
|
|
232
|
+
const normalized = normalizeStackFileName(frame.fileName);
|
|
233
|
+
if (!normalized) continue;
|
|
234
|
+
const existing = functionNameToRscFrames.get(frame.functionName) ?? [];
|
|
235
|
+
const duplicate = existing.some(
|
|
236
|
+
(candidate) => candidate.fileName === normalized && candidate.lineNumber === frame.lineNumber && candidate.columnNumber === frame.columnNumber
|
|
237
|
+
);
|
|
238
|
+
if (!duplicate) {
|
|
239
|
+
existing.push({
|
|
240
|
+
fileName: normalized,
|
|
241
|
+
lineNumber: frame.lineNumber,
|
|
242
|
+
columnNumber: frame.columnNumber
|
|
243
|
+
});
|
|
244
|
+
functionNameToRscFrames.set(frame.functionName, existing);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
200
247
|
}
|
|
201
|
-
|
|
248
|
+
current = current._debugOwner ?? current.return ?? null;
|
|
249
|
+
}
|
|
250
|
+
return functionNameToRscFrames;
|
|
202
251
|
}
|
|
203
|
-
function
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
const rightWidth = parsePropertyValue(computed.borderRightWidth);
|
|
211
|
-
const bottomWidth = parsePropertyValue(computed.borderBottomWidth);
|
|
212
|
-
const leftWidth = parsePropertyValue(computed.borderLeftWidth);
|
|
252
|
+
function enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) {
|
|
253
|
+
if (!frame.functionName) return frame;
|
|
254
|
+
const available = functionNameToRscFrames.get(frame.functionName);
|
|
255
|
+
if (!available) return frame;
|
|
256
|
+
const usageIndex = functionNameToUsageIndex.get(frame.functionName) ?? 0;
|
|
257
|
+
const resolved = available[usageIndex % available.length];
|
|
258
|
+
functionNameToUsageIndex.set(frame.functionName, usageIndex + 1);
|
|
213
259
|
return {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
borderBottomStyle: bottomStyle,
|
|
219
|
-
borderBottomWidth: bottomWidth,
|
|
220
|
-
borderLeftStyle: leftStyle,
|
|
221
|
-
borderLeftWidth: leftWidth
|
|
260
|
+
...frame,
|
|
261
|
+
fileName: resolved.fileName,
|
|
262
|
+
lineNumber: resolved.lineNumber,
|
|
263
|
+
columnNumber: resolved.columnNumber
|
|
222
264
|
};
|
|
223
265
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
"
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
"border-top-width",
|
|
246
|
-
"border-right-style",
|
|
247
|
-
"border-right-width",
|
|
248
|
-
"border-bottom-style",
|
|
249
|
-
"border-bottom-width",
|
|
250
|
-
"border-left-style",
|
|
251
|
-
"border-left-width",
|
|
252
|
-
"display",
|
|
253
|
-
"flex-direction",
|
|
254
|
-
"justify-content",
|
|
255
|
-
"align-items",
|
|
256
|
-
"width",
|
|
257
|
-
"height",
|
|
258
|
-
"background-color",
|
|
259
|
-
"background",
|
|
260
|
-
"color",
|
|
261
|
-
"border-color",
|
|
262
|
-
"outline-color",
|
|
263
|
-
"outline-style",
|
|
264
|
-
"outline-width",
|
|
265
|
-
"box-shadow",
|
|
266
|
-
"font-family",
|
|
267
|
-
"font-weight",
|
|
268
|
-
"font-size",
|
|
269
|
-
"line-height",
|
|
270
|
-
"letter-spacing",
|
|
271
|
-
"text-align"
|
|
272
|
-
];
|
|
273
|
-
function getOriginalInlineStyles(element) {
|
|
274
|
-
const styles = {};
|
|
275
|
-
for (const prop of ORIGINAL_STYLE_PROPS) {
|
|
276
|
-
const value = element.style.getPropertyValue(prop);
|
|
277
|
-
if (value) {
|
|
278
|
-
styles[prop] = value;
|
|
266
|
+
function getSourceFromDebugStack(fiber) {
|
|
267
|
+
const rawStack = fiber?._debugStack?.stack;
|
|
268
|
+
if (typeof rawStack !== "string" || rawStack.length === 0) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const formattedStack = formatOwnerDebugStack(rawStack);
|
|
272
|
+
if (!formattedStack) return null;
|
|
273
|
+
const stackFrames = parseDebugStack(formattedStack);
|
|
274
|
+
const functionNameToRscFrames = buildFunctionNameToRscFramesMap(fiber);
|
|
275
|
+
const functionNameToUsageIndex = /* @__PURE__ */ new Map();
|
|
276
|
+
for (const frame of stackFrames) {
|
|
277
|
+
const maybeEnriched = frame.isServer ? enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) : frame;
|
|
278
|
+
if (!maybeEnriched.fileName) continue;
|
|
279
|
+
const normalizedFileName = normalizeStackFileName(maybeEnriched.fileName);
|
|
280
|
+
if (!normalizedFileName) continue;
|
|
281
|
+
if (isSourceStackFile(normalizedFileName)) {
|
|
282
|
+
return {
|
|
283
|
+
fileName: normalizedFileName,
|
|
284
|
+
lineNumber: maybeEnriched.lineNumber,
|
|
285
|
+
columnNumber: maybeEnriched.columnNumber
|
|
286
|
+
};
|
|
279
287
|
}
|
|
280
288
|
}
|
|
281
|
-
return
|
|
289
|
+
return null;
|
|
282
290
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
margin: { prefix: "m", scale: spacingScale },
|
|
293
|
-
"margin-inline": { prefix: "mx", scale: spacingScale },
|
|
294
|
-
"margin-block": { prefix: "my", scale: spacingScale },
|
|
295
|
-
"margin-top": { prefix: "mt", scale: spacingScale },
|
|
296
|
-
"margin-right": { prefix: "mr", scale: spacingScale },
|
|
297
|
-
"margin-bottom": { prefix: "mb", scale: spacingScale },
|
|
298
|
-
"margin-left": { prefix: "ml", scale: spacingScale },
|
|
299
|
-
gap: { prefix: "gap", scale: spacingScale },
|
|
300
|
-
"border-width": {
|
|
301
|
-
prefix: "border",
|
|
302
|
-
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
303
|
-
},
|
|
304
|
-
"border-top-width": {
|
|
305
|
-
prefix: "border-t",
|
|
306
|
-
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
307
|
-
},
|
|
308
|
-
"border-right-width": {
|
|
309
|
-
prefix: "border-r",
|
|
310
|
-
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
311
|
-
},
|
|
312
|
-
"border-bottom-width": {
|
|
313
|
-
prefix: "border-b",
|
|
314
|
-
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
315
|
-
},
|
|
316
|
-
"border-left-width": {
|
|
317
|
-
prefix: "border-l",
|
|
318
|
-
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
319
|
-
},
|
|
320
|
-
"border-radius": {
|
|
321
|
-
prefix: "rounded",
|
|
322
|
-
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
323
|
-
},
|
|
324
|
-
"border-top-left-radius": {
|
|
325
|
-
prefix: "rounded-tl",
|
|
326
|
-
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
327
|
-
},
|
|
328
|
-
"border-top-right-radius": {
|
|
329
|
-
prefix: "rounded-tr",
|
|
330
|
-
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
331
|
-
},
|
|
332
|
-
"border-bottom-right-radius": {
|
|
333
|
-
prefix: "rounded-br",
|
|
334
|
-
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
335
|
-
},
|
|
336
|
-
"border-bottom-left-radius": {
|
|
337
|
-
prefix: "rounded-bl",
|
|
338
|
-
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
var flexDirectionMap = {
|
|
342
|
-
row: "flex-row",
|
|
343
|
-
"row-reverse": "flex-row-reverse",
|
|
344
|
-
column: "flex-col",
|
|
345
|
-
"column-reverse": "flex-col-reverse"
|
|
346
|
-
};
|
|
347
|
-
var justifyContentMap = {
|
|
348
|
-
"flex-start": "justify-start",
|
|
349
|
-
"flex-end": "justify-end",
|
|
350
|
-
center: "justify-center",
|
|
351
|
-
"space-between": "justify-between",
|
|
352
|
-
"space-around": "justify-around",
|
|
353
|
-
"space-evenly": "justify-evenly",
|
|
354
|
-
start: "justify-start",
|
|
355
|
-
end: "justify-end"
|
|
356
|
-
};
|
|
357
|
-
var alignItemsMap = {
|
|
358
|
-
"flex-start": "items-start",
|
|
359
|
-
"flex-end": "items-end",
|
|
360
|
-
center: "items-center",
|
|
361
|
-
baseline: "items-baseline",
|
|
362
|
-
stretch: "items-stretch",
|
|
363
|
-
start: "items-start",
|
|
364
|
-
end: "items-end"
|
|
365
|
-
};
|
|
366
|
-
function getExactScaleValue(value, scale) {
|
|
367
|
-
if (Object.prototype.hasOwnProperty.call(scale, value)) {
|
|
368
|
-
return scale[value];
|
|
291
|
+
|
|
292
|
+
// src/utils/react-fiber.ts
|
|
293
|
+
function getFiberForElement(element) {
|
|
294
|
+
if (typeof window !== "undefined") {
|
|
295
|
+
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
296
|
+
if (devtools?.getFiberForElement) {
|
|
297
|
+
const fiber = devtools.getFiberForElement(element);
|
|
298
|
+
if (fiber) return fiber;
|
|
299
|
+
}
|
|
369
300
|
}
|
|
301
|
+
const fiberKey = Object.keys(element).find(
|
|
302
|
+
(key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
|
|
303
|
+
);
|
|
304
|
+
if (!fiberKey) return null;
|
|
305
|
+
return element[fiberKey] || null;
|
|
306
|
+
}
|
|
307
|
+
function getSourceFromFiber(fiber) {
|
|
308
|
+
const debugSource = fiber?._debugSource;
|
|
309
|
+
if (debugSource?.fileName) return debugSource;
|
|
310
|
+
const owner = fiber?._debugOwner;
|
|
311
|
+
const ownerPending = owner?.pendingProps?.__source;
|
|
312
|
+
if (ownerPending?.fileName) return ownerPending;
|
|
313
|
+
const ownerMemo = owner?.memoizedProps?.__source;
|
|
314
|
+
if (ownerMemo?.fileName) return ownerMemo;
|
|
315
|
+
const pending = fiber?.pendingProps?.__source;
|
|
316
|
+
if (pending?.fileName) return pending;
|
|
317
|
+
const memo = fiber?.memoizedProps?.__source;
|
|
318
|
+
if (memo?.fileName) return memo;
|
|
319
|
+
const fromDebugStack = getSourceFromDebugStack(fiber);
|
|
320
|
+
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
370
321
|
return null;
|
|
371
322
|
}
|
|
372
|
-
function
|
|
373
|
-
|
|
323
|
+
function buildFrame(fiber) {
|
|
324
|
+
const type = fiber?.type;
|
|
325
|
+
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
326
|
+
const name = type?.displayName || type?.name || null;
|
|
327
|
+
if (!name || name === "Fragment") return null;
|
|
328
|
+
const frame = { name };
|
|
329
|
+
const source = getSourceFromFiber(fiber);
|
|
330
|
+
if (source?.fileName) {
|
|
331
|
+
frame.file = source.fileName;
|
|
332
|
+
if (typeof source.lineNumber === "number") {
|
|
333
|
+
frame.line = source.lineNumber;
|
|
334
|
+
}
|
|
335
|
+
if (typeof source.columnNumber === "number") {
|
|
336
|
+
frame.column = source.columnNumber;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return frame;
|
|
374
340
|
}
|
|
375
|
-
function
|
|
376
|
-
|
|
341
|
+
function shouldIncludeFrame(frame, lastFrame) {
|
|
342
|
+
if (!lastFrame) return true;
|
|
343
|
+
if (frame.name !== lastFrame.name) return true;
|
|
344
|
+
if (!lastFrame.file && frame.file) return true;
|
|
345
|
+
if (lastFrame.file && frame.file && lastFrame.line == null && frame.line != null) return true;
|
|
346
|
+
if (lastFrame.file && frame.file && lastFrame.line != null && frame.line != null && lastFrame.column == null && frame.column != null) {
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
return false;
|
|
377
350
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const classes = [];
|
|
391
|
-
for (const [prop, value] of Object.entries(styles)) {
|
|
392
|
-
if (tailwindClassMap[prop]) {
|
|
393
|
-
const parsed = parsePropertyValue(value);
|
|
394
|
-
const mapping = tailwindClassMap[prop];
|
|
395
|
-
if (value === "auto") {
|
|
396
|
-
classes.push(`${mapping.prefix}-auto`);
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
if (parsed.unit === "px") {
|
|
400
|
-
const exactScale = getExactScaleValue(parsed.numericValue, mapping.scale);
|
|
401
|
-
if (exactScale !== null) {
|
|
402
|
-
if (exactScale === "") {
|
|
403
|
-
classes.push(mapping.prefix);
|
|
404
|
-
} else {
|
|
405
|
-
classes.push(`${mapping.prefix}-${exactScale}`);
|
|
406
|
-
}
|
|
407
|
-
continue;
|
|
408
|
-
}
|
|
351
|
+
function getOwnerStack(fiber) {
|
|
352
|
+
const frames = [];
|
|
353
|
+
let current = fiber;
|
|
354
|
+
let lastFrame = null;
|
|
355
|
+
let nearestComponentFiber = null;
|
|
356
|
+
while (current) {
|
|
357
|
+
const frame = buildFrame(current);
|
|
358
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
359
|
+
frames.push(frame);
|
|
360
|
+
lastFrame = frame;
|
|
361
|
+
if (!nearestComponentFiber) {
|
|
362
|
+
nearestComponentFiber = current;
|
|
409
363
|
}
|
|
410
|
-
classes.push(`${mapping.prefix}-[${value}]`);
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
if (prop === "flex-direction" && flexDirectionMap[value]) {
|
|
414
|
-
classes.push(flexDirectionMap[value]);
|
|
415
|
-
continue;
|
|
416
|
-
}
|
|
417
|
-
if (prop === "justify-content" && justifyContentMap[value]) {
|
|
418
|
-
classes.push(justifyContentMap[value]);
|
|
419
|
-
continue;
|
|
420
|
-
}
|
|
421
|
-
if (prop === "align-items" && alignItemsMap[value]) {
|
|
422
|
-
classes.push(alignItemsMap[value]);
|
|
423
|
-
continue;
|
|
424
|
-
}
|
|
425
|
-
if (prop === "display") {
|
|
426
|
-
if (value === "flex") classes.push("flex");
|
|
427
|
-
else if (value === "inline-flex") classes.push("inline-flex");
|
|
428
|
-
else if (value === "grid") classes.push("grid");
|
|
429
|
-
else if (value === "block") classes.push("block");
|
|
430
|
-
else if (value === "inline-block") classes.push("inline-block");
|
|
431
|
-
else if (value === "none") classes.push("hidden");
|
|
432
|
-
continue;
|
|
433
364
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
continue;
|
|
365
|
+
current = current._debugOwner;
|
|
366
|
+
}
|
|
367
|
+
return { frames, nearestComponentFiber };
|
|
368
|
+
}
|
|
369
|
+
function getRenderStack(fiber) {
|
|
370
|
+
const frames = [];
|
|
371
|
+
let current = fiber;
|
|
372
|
+
let lastFrame = null;
|
|
373
|
+
let nearestComponentFiber = null;
|
|
374
|
+
while (current) {
|
|
375
|
+
const frame = buildFrame(current);
|
|
376
|
+
if (frame && shouldIncludeFrame(frame, lastFrame)) {
|
|
377
|
+
frames.push(frame);
|
|
378
|
+
lastFrame = frame;
|
|
379
|
+
if (!nearestComponentFiber) {
|
|
380
|
+
nearestComponentFiber = current;
|
|
381
|
+
}
|
|
452
382
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
383
|
+
current = current.return;
|
|
384
|
+
}
|
|
385
|
+
return { frames, nearestComponentFiber };
|
|
386
|
+
}
|
|
387
|
+
function getReactComponentInfo(element) {
|
|
388
|
+
const fiber = getFiberForElement(element);
|
|
389
|
+
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
390
|
+
const elementSource = getSourceFromFiber(fiber);
|
|
391
|
+
const elementSourceFile = elementSource?.fileName || void 0;
|
|
392
|
+
const ownerResult = getOwnerStack(fiber);
|
|
393
|
+
if (ownerResult.frames.length > 0) {
|
|
394
|
+
return { ...ownerResult, elementSourceFile };
|
|
395
|
+
}
|
|
396
|
+
return { ...getRenderStack(fiber), elementSourceFile };
|
|
397
|
+
}
|
|
398
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
399
|
+
"className",
|
|
400
|
+
"style",
|
|
401
|
+
"children",
|
|
402
|
+
"ref",
|
|
403
|
+
"key",
|
|
404
|
+
"render"
|
|
405
|
+
]);
|
|
406
|
+
function serializePropValue(value) {
|
|
407
|
+
if (typeof value === "function") return "[function]";
|
|
408
|
+
if (typeof value === "symbol") return void 0;
|
|
409
|
+
if (value === void 0) return void 0;
|
|
410
|
+
if (value !== null && typeof value === "object") {
|
|
411
|
+
if ("$$typeof" in value) return "[element]";
|
|
412
|
+
try {
|
|
413
|
+
JSON.stringify(value);
|
|
414
|
+
return value;
|
|
415
|
+
} catch {
|
|
416
|
+
return "[object]";
|
|
457
417
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
418
|
+
}
|
|
419
|
+
return value;
|
|
420
|
+
}
|
|
421
|
+
function getComponentProps(fiber) {
|
|
422
|
+
const props = fiber?.memoizedProps ?? fiber?.pendingProps;
|
|
423
|
+
if (!props || typeof props !== "object") return {};
|
|
424
|
+
const result = {};
|
|
425
|
+
for (const [key, value] of Object.entries(props)) {
|
|
426
|
+
if (EXCLUDED_PROP_KEYS.has(key)) continue;
|
|
427
|
+
if (key.startsWith("data-")) continue;
|
|
428
|
+
const serialized = serializePropValue(value);
|
|
429
|
+
if (serialized !== void 0) {
|
|
430
|
+
result[key] = serialized;
|
|
462
431
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
classes.push(`[border-top-style:${styles["border-top-style"]}]`);
|
|
490
|
-
classes.push(`[border-right-style:${styles["border-right-style"]}]`);
|
|
491
|
-
classes.push(`[border-bottom-style:${styles["border-bottom-style"]}]`);
|
|
492
|
-
classes.push(`[border-left-style:${styles["border-left-style"]}]`);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
} else {
|
|
496
|
-
classes.push(`[${prop}:${value}]`);
|
|
497
|
-
}
|
|
498
|
-
continue;
|
|
499
|
-
}
|
|
500
|
-
if (prop === "outline-color") {
|
|
501
|
-
const colorValue = parseColorValue(value);
|
|
502
|
-
classes.push(colorToTailwind("outlineColor", colorValue));
|
|
503
|
-
continue;
|
|
504
|
-
}
|
|
505
|
-
if (prop === "box-shadow") {
|
|
506
|
-
const trimmed = value.trim();
|
|
507
|
-
if (trimmed === "none" || trimmed === "") {
|
|
508
|
-
classes.push("shadow-none");
|
|
509
|
-
} else {
|
|
510
|
-
const normalized = normalizeShadowForComparison(trimmed);
|
|
511
|
-
const preset = tailwindShadowClassValues.find(
|
|
512
|
-
(entry) => normalizeShadowForComparison(entry.css) === normalized
|
|
513
|
-
);
|
|
514
|
-
if (preset) classes.push(preset.className);
|
|
515
|
-
else classes.push(`shadow-[${normalizeTailwindArbitraryValue(value)}]`);
|
|
516
|
-
}
|
|
517
|
-
continue;
|
|
518
|
-
}
|
|
519
|
-
if (prop === "font-size") {
|
|
520
|
-
classes.push(`text-[${value}]`);
|
|
521
|
-
continue;
|
|
522
|
-
}
|
|
523
|
-
if (prop === "font-weight") {
|
|
524
|
-
const weightMap = {
|
|
525
|
-
"100": "font-thin",
|
|
526
|
-
"200": "font-extralight",
|
|
527
|
-
"300": "font-light",
|
|
528
|
-
"400": "font-normal",
|
|
529
|
-
"500": "font-medium",
|
|
530
|
-
"600": "font-semibold",
|
|
531
|
-
"700": "font-bold",
|
|
532
|
-
"800": "font-extrabold",
|
|
533
|
-
"900": "font-black"
|
|
534
|
-
};
|
|
535
|
-
classes.push(weightMap[value] || `font-[${value}]`);
|
|
536
|
-
continue;
|
|
537
|
-
}
|
|
538
|
-
if (prop === "line-height") {
|
|
539
|
-
classes.push(`leading-[${value}]`);
|
|
540
|
-
continue;
|
|
541
|
-
}
|
|
542
|
-
if (prop === "letter-spacing") {
|
|
543
|
-
classes.push(`tracking-[${value}]`);
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
if (prop === "text-align") {
|
|
547
|
-
const alignMap = {
|
|
548
|
-
left: "text-left",
|
|
549
|
-
center: "text-center",
|
|
550
|
-
right: "text-right",
|
|
551
|
-
justify: "text-justify"
|
|
552
|
-
};
|
|
553
|
-
if (alignMap[value]) classes.push(alignMap[value]);
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
if (prop === "font-family") {
|
|
557
|
-
classes.push(`font-[${value.replace(/\s+/g, "_")}]`);
|
|
558
|
-
continue;
|
|
432
|
+
}
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
function getCallSiteSource(fiber) {
|
|
436
|
+
const source = fiber?._debugSource;
|
|
437
|
+
if (source?.fileName) {
|
|
438
|
+
return {
|
|
439
|
+
file: source.fileName,
|
|
440
|
+
line: typeof source.lineNumber === "number" ? source.lineNumber : void 0,
|
|
441
|
+
column: typeof source.columnNumber === "number" ? source.columnNumber : void 0
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
const pending = fiber?.pendingProps?.__source;
|
|
445
|
+
if (pending?.fileName) {
|
|
446
|
+
return {
|
|
447
|
+
file: pending.fileName,
|
|
448
|
+
line: typeof pending.lineNumber === "number" ? pending.lineNumber : void 0,
|
|
449
|
+
column: typeof pending.columnNumber === "number" ? pending.columnNumber : void 0
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
function deriveDefinitionSource(frames) {
|
|
455
|
+
for (const frame of frames) {
|
|
456
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
457
|
+
return { file: frame.file, line: frame.line, column: frame.column };
|
|
559
458
|
}
|
|
560
459
|
}
|
|
561
|
-
return
|
|
562
|
-
}
|
|
563
|
-
var propertyToCSSMap = {
|
|
564
|
-
paddingTop: "padding-top",
|
|
565
|
-
paddingRight: "padding-right",
|
|
566
|
-
paddingBottom: "padding-bottom",
|
|
567
|
-
paddingLeft: "padding-left",
|
|
568
|
-
marginTop: "margin-top",
|
|
569
|
-
marginRight: "margin-right",
|
|
570
|
-
marginBottom: "margin-bottom",
|
|
571
|
-
marginLeft: "margin-left",
|
|
572
|
-
gap: "gap"
|
|
573
|
-
};
|
|
574
|
-
var borderRadiusPropertyToCSSMap = {
|
|
575
|
-
borderTopLeftRadius: "border-top-left-radius",
|
|
576
|
-
borderTopRightRadius: "border-top-right-radius",
|
|
577
|
-
borderBottomRightRadius: "border-bottom-right-radius",
|
|
578
|
-
borderBottomLeftRadius: "border-bottom-left-radius"
|
|
579
|
-
};
|
|
580
|
-
var borderPropertyToCSSMap = {
|
|
581
|
-
borderTopStyle: "border-top-style",
|
|
582
|
-
borderTopWidth: "border-top-width",
|
|
583
|
-
borderRightStyle: "border-right-style",
|
|
584
|
-
borderRightWidth: "border-right-width",
|
|
585
|
-
borderBottomStyle: "border-bottom-style",
|
|
586
|
-
borderBottomWidth: "border-bottom-width",
|
|
587
|
-
borderLeftStyle: "border-left-style",
|
|
588
|
-
borderLeftWidth: "border-left-width"
|
|
589
|
-
};
|
|
590
|
-
var flexPropertyToCSSMap = {
|
|
591
|
-
display: "display",
|
|
592
|
-
flexDirection: "flex-direction",
|
|
593
|
-
justifyContent: "justify-content",
|
|
594
|
-
alignItems: "align-items"
|
|
595
|
-
};
|
|
596
|
-
var sizingPropertyToCSSMap = {
|
|
597
|
-
width: "width",
|
|
598
|
-
height: "height"
|
|
599
|
-
};
|
|
600
|
-
var typographyPropertyToCSSMap = {
|
|
601
|
-
fontFamily: "font-family",
|
|
602
|
-
fontWeight: "font-weight",
|
|
603
|
-
fontSize: "font-size",
|
|
604
|
-
lineHeight: "line-height",
|
|
605
|
-
letterSpacing: "letter-spacing",
|
|
606
|
-
textAlign: "text-align",
|
|
607
|
-
textVerticalAlign: "align-items"
|
|
608
|
-
};
|
|
609
|
-
var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
610
|
-
"p",
|
|
611
|
-
"h1",
|
|
612
|
-
"h2",
|
|
613
|
-
"h3",
|
|
614
|
-
"h4",
|
|
615
|
-
"h5",
|
|
616
|
-
"h6",
|
|
617
|
-
"span",
|
|
618
|
-
"label",
|
|
619
|
-
"a",
|
|
620
|
-
"strong",
|
|
621
|
-
"em",
|
|
622
|
-
"small",
|
|
623
|
-
"blockquote",
|
|
624
|
-
"li",
|
|
625
|
-
"td",
|
|
626
|
-
"th",
|
|
627
|
-
"caption",
|
|
628
|
-
"figcaption",
|
|
629
|
-
"legend",
|
|
630
|
-
"dt",
|
|
631
|
-
"dd",
|
|
632
|
-
"abbr",
|
|
633
|
-
"cite",
|
|
634
|
-
"code",
|
|
635
|
-
"pre"
|
|
636
|
-
]);
|
|
637
|
-
function hasDirectNonWhitespaceText(element) {
|
|
638
|
-
return Array.from(element.childNodes).some(
|
|
639
|
-
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
640
|
-
);
|
|
460
|
+
return null;
|
|
641
461
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
462
|
+
var PRIMITIVE_PATH_PATTERNS = [
|
|
463
|
+
/(?:^|\/)components\/ui\//,
|
|
464
|
+
/(?:^|\/)ui\/primitives\//,
|
|
465
|
+
/(?:^|\/)design-system\//
|
|
466
|
+
];
|
|
467
|
+
var PRIMITIVE_NPM_PATTERNS = [
|
|
468
|
+
/@base-ui\//,
|
|
469
|
+
/@radix-ui\//,
|
|
470
|
+
/@headlessui\//,
|
|
471
|
+
/@chakra-ui\//,
|
|
472
|
+
/@mantine\//,
|
|
473
|
+
/@mui\//,
|
|
474
|
+
/@ark-ui\//
|
|
475
|
+
];
|
|
476
|
+
var FRAMEWORK_EXCLUSION_PATTERNS = [
|
|
477
|
+
/node_modules\/react\//,
|
|
478
|
+
/node_modules\/react-dom\//,
|
|
479
|
+
/node_modules\/next\/dist\//,
|
|
480
|
+
/node_modules\/scheduler\//,
|
|
481
|
+
/node_modules\/react-server\//
|
|
482
|
+
];
|
|
483
|
+
function isComponentPrimitivePath(filePath) {
|
|
484
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
485
|
+
for (const pattern of FRAMEWORK_EXCLUSION_PATTERNS) {
|
|
486
|
+
if (pattern.test(normalized)) return false;
|
|
646
487
|
}
|
|
647
|
-
|
|
648
|
-
return true;
|
|
488
|
+
for (const pattern of PRIMITIVE_NPM_PATTERNS) {
|
|
489
|
+
if (pattern.test(normalized)) return true;
|
|
649
490
|
}
|
|
650
|
-
|
|
651
|
-
return true;
|
|
491
|
+
for (const pattern of PRIMITIVE_PATH_PATTERNS) {
|
|
492
|
+
if (pattern.test(normalized)) return true;
|
|
652
493
|
}
|
|
653
494
|
return false;
|
|
654
495
|
}
|
|
655
|
-
function
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
659
|
-
const alignItems = computed.alignItems;
|
|
660
|
-
if (alignItems === "center") textVerticalAlign = "center";
|
|
661
|
-
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
496
|
+
function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
497
|
+
if (elementSourceFile && isComponentPrimitivePath(elementSourceFile)) {
|
|
498
|
+
return { isComponentPrimitive: true };
|
|
662
499
|
}
|
|
663
|
-
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
672
|
-
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
673
|
-
} else {
|
|
674
|
-
letterSpacing = parsed;
|
|
500
|
+
if (!fiber) return { isComponentPrimitive: false };
|
|
501
|
+
const callSite = getCallSiteSource(fiber);
|
|
502
|
+
if (callSite?.file && isComponentPrimitivePath(callSite.file)) {
|
|
503
|
+
return { isComponentPrimitive: true };
|
|
504
|
+
}
|
|
505
|
+
for (const frame of frames) {
|
|
506
|
+
if (frame.file && isComponentPrimitivePath(frame.file)) {
|
|
507
|
+
return { isComponentPrimitive: true };
|
|
675
508
|
}
|
|
676
509
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
fontWeight: computed.fontWeight,
|
|
680
|
-
fontSize: parsePropertyValue(computed.fontSize),
|
|
681
|
-
lineHeight,
|
|
682
|
-
letterSpacing,
|
|
683
|
-
textAlign: computed.textAlign,
|
|
684
|
-
textVerticalAlign
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
function detectSizingMode(element, dimension) {
|
|
688
|
-
const computed = window.getComputedStyle(element);
|
|
689
|
-
const inlineValue = element.style[dimension];
|
|
690
|
-
if (inlineValue === "100%") return "fill";
|
|
691
|
-
if (inlineValue === "auto" || inlineValue === "fit-content") return "fit";
|
|
692
|
-
const computedValue = computed[dimension];
|
|
693
|
-
if (computedValue === "100%") return "fill";
|
|
694
|
-
if (computedValue === "auto" || computedValue === "fit-content" || computedValue === "max-content") {
|
|
695
|
-
return "fit";
|
|
510
|
+
if (!elementSourceFile && fiber._debugSource) {
|
|
511
|
+
return { isComponentPrimitive: true };
|
|
696
512
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
if (computed.display === "inline-block" || computed.display === "inline-flex" || computed.display === "inline") {
|
|
712
|
-
return "fit";
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (dimension === "height") {
|
|
716
|
-
if (!inlineValue) {
|
|
717
|
-
return "fit";
|
|
718
|
-
}
|
|
513
|
+
return { isComponentPrimitive: false };
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// src/utils.ts
|
|
517
|
+
function clamp(value, min, max) {
|
|
518
|
+
if (!Number.isFinite(value)) return min;
|
|
519
|
+
if (max < min) return min;
|
|
520
|
+
return Math.max(min, Math.min(max, value));
|
|
521
|
+
}
|
|
522
|
+
function isInputFocused() {
|
|
523
|
+
let active = document.activeElement;
|
|
524
|
+
while (active?.shadowRoot?.activeElement) {
|
|
525
|
+
active = active.shadowRoot.activeElement;
|
|
719
526
|
}
|
|
720
|
-
return
|
|
527
|
+
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
721
528
|
}
|
|
722
|
-
function
|
|
723
|
-
const
|
|
724
|
-
const numericValue = Math.round(dimension === "width" ? element.offsetWidth : element.offsetHeight);
|
|
529
|
+
function getComputedStyles(element) {
|
|
530
|
+
const computed = window.getComputedStyle(element);
|
|
725
531
|
return {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
532
|
+
spacing: {
|
|
533
|
+
paddingTop: parsePropertyValue(computed.paddingTop),
|
|
534
|
+
paddingRight: parsePropertyValue(computed.paddingRight),
|
|
535
|
+
paddingBottom: parsePropertyValue(computed.paddingBottom),
|
|
536
|
+
paddingLeft: parsePropertyValue(computed.paddingLeft),
|
|
537
|
+
marginTop: parsePropertyValue(computed.marginTop),
|
|
538
|
+
marginRight: parsePropertyValue(computed.marginRight),
|
|
539
|
+
marginBottom: parsePropertyValue(computed.marginBottom),
|
|
540
|
+
marginLeft: parsePropertyValue(computed.marginLeft),
|
|
541
|
+
gap: parsePropertyValue(computed.gap || "0px")
|
|
542
|
+
},
|
|
543
|
+
borderRadius: {
|
|
544
|
+
borderTopLeftRadius: parsePropertyValue(computed.borderTopLeftRadius),
|
|
545
|
+
borderTopRightRadius: parsePropertyValue(computed.borderTopRightRadius),
|
|
546
|
+
borderBottomRightRadius: parsePropertyValue(computed.borderBottomRightRadius),
|
|
547
|
+
borderBottomLeftRadius: parsePropertyValue(computed.borderBottomLeftRadius)
|
|
548
|
+
},
|
|
549
|
+
flex: {
|
|
550
|
+
display: computed.display,
|
|
551
|
+
flexDirection: computed.flexDirection,
|
|
552
|
+
justifyContent: computed.justifyContent,
|
|
553
|
+
alignItems: computed.alignItems
|
|
731
554
|
}
|
|
732
555
|
};
|
|
733
556
|
}
|
|
734
|
-
function
|
|
557
|
+
function getComputedBorderStyles(element) {
|
|
558
|
+
const computed = window.getComputedStyle(element);
|
|
559
|
+
const topStyle = computed.borderTopStyle;
|
|
560
|
+
const rightStyle = computed.borderRightStyle;
|
|
561
|
+
const bottomStyle = computed.borderBottomStyle;
|
|
562
|
+
const leftStyle = computed.borderLeftStyle;
|
|
563
|
+
const topWidth = parsePropertyValue(computed.borderTopWidth);
|
|
564
|
+
const rightWidth = parsePropertyValue(computed.borderRightWidth);
|
|
565
|
+
const bottomWidth = parsePropertyValue(computed.borderBottomWidth);
|
|
566
|
+
const leftWidth = parsePropertyValue(computed.borderLeftWidth);
|
|
735
567
|
return {
|
|
736
|
-
|
|
737
|
-
|
|
568
|
+
borderTopStyle: topStyle,
|
|
569
|
+
borderTopWidth: topWidth,
|
|
570
|
+
borderRightStyle: rightStyle,
|
|
571
|
+
borderRightWidth: rightWidth,
|
|
572
|
+
borderBottomStyle: bottomStyle,
|
|
573
|
+
borderBottomWidth: bottomWidth,
|
|
574
|
+
borderLeftStyle: leftStyle,
|
|
575
|
+
borderLeftWidth: leftWidth
|
|
738
576
|
};
|
|
739
577
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
578
|
+
var ORIGINAL_STYLE_PROPS = [
|
|
579
|
+
"padding-top",
|
|
580
|
+
"padding-right",
|
|
581
|
+
"padding-bottom",
|
|
582
|
+
"padding-left",
|
|
583
|
+
"padding",
|
|
584
|
+
"margin-top",
|
|
585
|
+
"margin-right",
|
|
586
|
+
"margin-bottom",
|
|
587
|
+
"margin-left",
|
|
588
|
+
"margin",
|
|
589
|
+
"gap",
|
|
590
|
+
"border-radius",
|
|
591
|
+
"border-top-left-radius",
|
|
592
|
+
"border-top-right-radius",
|
|
593
|
+
"border-bottom-right-radius",
|
|
594
|
+
"border-bottom-left-radius",
|
|
595
|
+
"border",
|
|
596
|
+
"border-style",
|
|
597
|
+
"border-width",
|
|
598
|
+
"border-top-style",
|
|
599
|
+
"border-top-width",
|
|
600
|
+
"border-right-style",
|
|
601
|
+
"border-right-width",
|
|
602
|
+
"border-bottom-style",
|
|
603
|
+
"border-bottom-width",
|
|
604
|
+
"border-left-style",
|
|
605
|
+
"border-left-width",
|
|
606
|
+
"display",
|
|
607
|
+
"flex-direction",
|
|
608
|
+
"justify-content",
|
|
609
|
+
"align-items",
|
|
610
|
+
"width",
|
|
611
|
+
"height",
|
|
612
|
+
"background-color",
|
|
613
|
+
"background",
|
|
614
|
+
"color",
|
|
615
|
+
"border-color",
|
|
616
|
+
"outline-color",
|
|
617
|
+
"outline-style",
|
|
618
|
+
"outline-width",
|
|
619
|
+
"box-shadow",
|
|
620
|
+
"font-family",
|
|
621
|
+
"font-weight",
|
|
622
|
+
"font-size",
|
|
623
|
+
"line-height",
|
|
624
|
+
"letter-spacing",
|
|
625
|
+
"text-align"
|
|
626
|
+
];
|
|
627
|
+
function getOriginalInlineStyles(element) {
|
|
628
|
+
const styles = {};
|
|
629
|
+
for (const prop of ORIGINAL_STYLE_PROPS) {
|
|
630
|
+
const value = element.style.getPropertyValue(prop);
|
|
631
|
+
if (value) {
|
|
632
|
+
styles[prop] = value;
|
|
633
|
+
}
|
|
759
634
|
}
|
|
635
|
+
return styles;
|
|
760
636
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
637
|
+
var spacingScale = { 0: "0", 1: "px", 2: "0.5", 4: "1", 8: "2", 12: "3", 16: "4", 20: "5", 24: "6", 32: "8" };
|
|
638
|
+
var tailwindClassMap = {
|
|
639
|
+
padding: { prefix: "p", scale: spacingScale },
|
|
640
|
+
"padding-inline": { prefix: "px", scale: spacingScale },
|
|
641
|
+
"padding-block": { prefix: "py", scale: spacingScale },
|
|
642
|
+
"padding-top": { prefix: "pt", scale: spacingScale },
|
|
643
|
+
"padding-right": { prefix: "pr", scale: spacingScale },
|
|
644
|
+
"padding-bottom": { prefix: "pb", scale: spacingScale },
|
|
645
|
+
"padding-left": { prefix: "pl", scale: spacingScale },
|
|
646
|
+
margin: { prefix: "m", scale: spacingScale },
|
|
647
|
+
"margin-inline": { prefix: "mx", scale: spacingScale },
|
|
648
|
+
"margin-block": { prefix: "my", scale: spacingScale },
|
|
649
|
+
"margin-top": { prefix: "mt", scale: spacingScale },
|
|
650
|
+
"margin-right": { prefix: "mr", scale: spacingScale },
|
|
651
|
+
"margin-bottom": { prefix: "mb", scale: spacingScale },
|
|
652
|
+
"margin-left": { prefix: "ml", scale: spacingScale },
|
|
653
|
+
gap: { prefix: "gap", scale: spacingScale },
|
|
654
|
+
"border-width": {
|
|
655
|
+
prefix: "border",
|
|
656
|
+
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
657
|
+
},
|
|
658
|
+
"border-top-width": {
|
|
659
|
+
prefix: "border-t",
|
|
660
|
+
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
661
|
+
},
|
|
662
|
+
"border-right-width": {
|
|
663
|
+
prefix: "border-r",
|
|
664
|
+
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
665
|
+
},
|
|
666
|
+
"border-bottom-width": {
|
|
667
|
+
prefix: "border-b",
|
|
668
|
+
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
669
|
+
},
|
|
670
|
+
"border-left-width": {
|
|
671
|
+
prefix: "border-l",
|
|
672
|
+
scale: { 0: "0", 1: "", 2: "2", 4: "4", 8: "8" }
|
|
673
|
+
},
|
|
674
|
+
"border-radius": {
|
|
675
|
+
prefix: "rounded",
|
|
676
|
+
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
677
|
+
},
|
|
678
|
+
"border-top-left-radius": {
|
|
679
|
+
prefix: "rounded-tl",
|
|
680
|
+
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
681
|
+
},
|
|
682
|
+
"border-top-right-radius": {
|
|
683
|
+
prefix: "rounded-tr",
|
|
684
|
+
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
685
|
+
},
|
|
686
|
+
"border-bottom-right-radius": {
|
|
687
|
+
prefix: "rounded-br",
|
|
688
|
+
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
689
|
+
},
|
|
690
|
+
"border-bottom-left-radius": {
|
|
691
|
+
prefix: "rounded-bl",
|
|
692
|
+
scale: { 0: "none", 2: "sm", 4: "", 6: "md", 8: "lg", 12: "xl", 16: "2xl", 24: "3xl", 9999: "full" }
|
|
766
693
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
694
|
+
};
|
|
695
|
+
var flexDirectionMap = {
|
|
696
|
+
row: "flex-row",
|
|
697
|
+
"row-reverse": "flex-row-reverse",
|
|
698
|
+
column: "flex-col",
|
|
699
|
+
"column-reverse": "flex-col-reverse"
|
|
700
|
+
};
|
|
701
|
+
var justifyContentMap = {
|
|
702
|
+
"flex-start": "justify-start",
|
|
703
|
+
"flex-end": "justify-end",
|
|
704
|
+
center: "justify-center",
|
|
705
|
+
"space-between": "justify-between",
|
|
706
|
+
"space-around": "justify-around",
|
|
707
|
+
"space-evenly": "justify-evenly",
|
|
708
|
+
start: "justify-start",
|
|
709
|
+
end: "justify-end"
|
|
710
|
+
};
|
|
711
|
+
var alignItemsMap = {
|
|
712
|
+
"flex-start": "items-start",
|
|
713
|
+
"flex-end": "items-end",
|
|
714
|
+
center: "items-center",
|
|
715
|
+
baseline: "items-baseline",
|
|
716
|
+
stretch: "items-stretch",
|
|
717
|
+
start: "items-start",
|
|
718
|
+
end: "items-end"
|
|
719
|
+
};
|
|
720
|
+
function getExactScaleValue(value, scale) {
|
|
721
|
+
if (Object.prototype.hasOwnProperty.call(scale, value)) {
|
|
722
|
+
return scale[value];
|
|
770
723
|
}
|
|
771
|
-
return
|
|
724
|
+
return null;
|
|
772
725
|
}
|
|
773
|
-
function
|
|
774
|
-
|
|
775
|
-
if (!token) return null;
|
|
776
|
-
if (token.endsWith("%")) {
|
|
777
|
-
const numeric2 = parseFloat(token.slice(0, -1));
|
|
778
|
-
if (!Number.isFinite(numeric2)) return null;
|
|
779
|
-
return Math.round(Math.max(0, Math.min(100, numeric2)) / 100 * 255);
|
|
780
|
-
}
|
|
781
|
-
const numeric = parseFloat(token);
|
|
782
|
-
if (!Number.isFinite(numeric)) return null;
|
|
783
|
-
return Math.round(Math.max(0, Math.min(255, numeric)));
|
|
726
|
+
function normalizeTailwindArbitraryValue(value) {
|
|
727
|
+
return value.trim().replace(/\s+/g, "_");
|
|
784
728
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
787
|
-
const token = value.trim();
|
|
788
|
-
if (token.endsWith("%")) {
|
|
789
|
-
const numeric2 = parseFloat(token.slice(0, -1));
|
|
790
|
-
if (!Number.isFinite(numeric2)) return null;
|
|
791
|
-
return Math.max(0, Math.min(100, numeric2)) / 100;
|
|
792
|
-
}
|
|
793
|
-
const numeric = parseFloat(token);
|
|
794
|
-
if (!Number.isFinite(numeric)) return null;
|
|
795
|
-
return Math.max(0, Math.min(1, numeric));
|
|
729
|
+
function normalizeShadowForComparison(value) {
|
|
730
|
+
return value.trim().toLowerCase().replace(/\s*\/\s*/g, "/").replace(/\(\s+/g, "(").replace(/\s+\)/g, ")").replace(/\s*,\s*/g, ",").replace(/\s+/g, " ");
|
|
796
731
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
const
|
|
814
|
-
if (
|
|
815
|
-
|
|
816
|
-
|
|
732
|
+
var tailwindShadowClassValues = [
|
|
733
|
+
{ className: "shadow-2xs", css: "0 1px rgb(0 0 0 / 0.05)" },
|
|
734
|
+
{ className: "shadow-xs", css: "0 1px 2px 0 rgb(0 0 0 / 0.05)" },
|
|
735
|
+
{ className: "shadow", css: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)" },
|
|
736
|
+
{ className: "shadow-sm", css: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)" },
|
|
737
|
+
{ className: "shadow-md", css: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)" },
|
|
738
|
+
{ className: "shadow-lg", css: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)" },
|
|
739
|
+
{ className: "shadow-xl", css: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)" },
|
|
740
|
+
{ className: "shadow-2xl", css: "0 25px 50px -12px rgb(0 0 0 / 0.25)" },
|
|
741
|
+
{ className: "shadow-inner", css: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)" }
|
|
742
|
+
];
|
|
743
|
+
function stylesToTailwind(styles) {
|
|
744
|
+
const classes = [];
|
|
745
|
+
for (const [prop, value] of Object.entries(styles)) {
|
|
746
|
+
if (tailwindClassMap[prop]) {
|
|
747
|
+
const parsed = parsePropertyValue(value);
|
|
748
|
+
const mapping = tailwindClassMap[prop];
|
|
749
|
+
if (value === "auto") {
|
|
750
|
+
classes.push(`${mapping.prefix}-auto`);
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
if (parsed.unit === "px") {
|
|
754
|
+
const exactScale = getExactScaleValue(parsed.numericValue, mapping.scale);
|
|
755
|
+
if (exactScale !== null) {
|
|
756
|
+
if (exactScale === "") {
|
|
757
|
+
classes.push(mapping.prefix);
|
|
758
|
+
} else {
|
|
759
|
+
classes.push(`${mapping.prefix}-${exactScale}`);
|
|
760
|
+
}
|
|
761
|
+
continue;
|
|
762
|
+
}
|
|
817
763
|
}
|
|
764
|
+
classes.push(`${mapping.prefix}-[${value}]`);
|
|
765
|
+
continue;
|
|
818
766
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
return { hex: "000000", alpha: 100, raw: rgba };
|
|
822
|
-
}
|
|
823
|
-
const r = parseRgbChannel(channelTokens[0]);
|
|
824
|
-
const g = parseRgbChannel(channelTokens[1]);
|
|
825
|
-
const b = parseRgbChannel(channelTokens[2]);
|
|
826
|
-
const a = parseRgbAlpha(alphaToken);
|
|
827
|
-
if (r === null || g === null || b === null || a === null) {
|
|
828
|
-
return { hex: "000000", alpha: 100, raw: rgba };
|
|
829
|
-
}
|
|
830
|
-
const hex = [r, g, b].map((v) => v.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
831
|
-
const alpha = Math.round(a * 100);
|
|
832
|
-
return { hex, alpha, raw: rgba };
|
|
833
|
-
}
|
|
834
|
-
function parseNamedColor(name) {
|
|
835
|
-
const ctx = document.createElement("canvas").getContext("2d");
|
|
836
|
-
if (!ctx) {
|
|
837
|
-
return { hex: "000000", alpha: 100, raw: name };
|
|
838
|
-
}
|
|
839
|
-
ctx.fillStyle = name;
|
|
840
|
-
const computed = ctx.fillStyle;
|
|
841
|
-
if (computed.startsWith("#")) {
|
|
842
|
-
return parseHexColor(computed);
|
|
843
|
-
}
|
|
844
|
-
return parseRgbaColor(computed);
|
|
845
|
-
}
|
|
846
|
-
function parseColorValue(cssValue) {
|
|
847
|
-
const raw = cssValue.trim();
|
|
848
|
-
if (raw === "transparent") {
|
|
849
|
-
return { hex: "000000", alpha: 0, raw };
|
|
850
|
-
}
|
|
851
|
-
if (raw.startsWith("#")) {
|
|
852
|
-
return parseHexColor(raw);
|
|
853
|
-
}
|
|
854
|
-
if (raw.startsWith("rgb")) {
|
|
855
|
-
return parseRgbaColor(raw);
|
|
856
|
-
}
|
|
857
|
-
return parseNamedColor(raw);
|
|
858
|
-
}
|
|
859
|
-
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
860
|
-
function isVisibleBorderSide(side) {
|
|
861
|
-
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
862
|
-
}
|
|
863
|
-
function hasVisibleOutline(computed) {
|
|
864
|
-
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
865
|
-
}
|
|
866
|
-
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
867
|
-
const raw = value.trim();
|
|
868
|
-
const lowered = raw.toLowerCase();
|
|
869
|
-
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
870
|
-
return null;
|
|
871
|
-
}
|
|
872
|
-
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
873
|
-
const parsed = parseColorValue(resolved);
|
|
874
|
-
if (parsed.alpha <= 0) {
|
|
875
|
-
return null;
|
|
876
|
-
}
|
|
877
|
-
return parsed;
|
|
878
|
-
}
|
|
879
|
-
function addUniqueColor(colors, color) {
|
|
880
|
-
if (!color) return;
|
|
881
|
-
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
882
|
-
}
|
|
883
|
-
function isTextRenderingFormControl(element) {
|
|
884
|
-
if (element instanceof HTMLTextAreaElement) return true;
|
|
885
|
-
if (element instanceof HTMLSelectElement) return true;
|
|
886
|
-
if (element instanceof HTMLButtonElement) return true;
|
|
887
|
-
if (element instanceof HTMLInputElement) {
|
|
888
|
-
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
889
|
-
"hidden",
|
|
890
|
-
"checkbox",
|
|
891
|
-
"radio",
|
|
892
|
-
"range",
|
|
893
|
-
"color",
|
|
894
|
-
"file",
|
|
895
|
-
"image"
|
|
896
|
-
]);
|
|
897
|
-
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
898
|
-
}
|
|
899
|
-
return false;
|
|
900
|
-
}
|
|
901
|
-
function hasRenderableTextNode(element) {
|
|
902
|
-
if (element.isContentEditable) return true;
|
|
903
|
-
if (isTextRenderingFormControl(element)) return true;
|
|
904
|
-
if (!element.textContent?.trim()) return false;
|
|
905
|
-
if (hasDirectNonWhitespaceText(element)) return true;
|
|
906
|
-
const tagName = element.tagName.toLowerCase();
|
|
907
|
-
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
908
|
-
}
|
|
909
|
-
function getComputedBoxShadow(element) {
|
|
910
|
-
const computed = window.getComputedStyle(element);
|
|
911
|
-
const value = computed.boxShadow.trim();
|
|
912
|
-
return value || "none";
|
|
913
|
-
}
|
|
914
|
-
function getComputedColorStyles(element) {
|
|
915
|
-
const computed = window.getComputedStyle(element);
|
|
916
|
-
const borderSides = [
|
|
917
|
-
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
918
|
-
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
919
|
-
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
920
|
-
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
921
|
-
];
|
|
922
|
-
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
923
|
-
const hasBorder = Boolean(visibleBorderSide);
|
|
924
|
-
const hasOutline = hasVisibleOutline(computed);
|
|
925
|
-
return {
|
|
926
|
-
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
927
|
-
color: parseColorValue(computed.color),
|
|
928
|
-
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
929
|
-
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
|
-
function getSelectionColors(element) {
|
|
933
|
-
const uniqueColors = /* @__PURE__ */ new Map();
|
|
934
|
-
const queue = [element];
|
|
935
|
-
for (let index = 0; index < queue.length; index++) {
|
|
936
|
-
const node = queue[index];
|
|
937
|
-
const computed = window.getComputedStyle(node);
|
|
938
|
-
if (computed.display === "none") {
|
|
767
|
+
if (prop === "flex-direction" && flexDirectionMap[value]) {
|
|
768
|
+
classes.push(flexDirectionMap[value]);
|
|
939
769
|
continue;
|
|
940
770
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
771
|
+
if (prop === "justify-content" && justifyContentMap[value]) {
|
|
772
|
+
classes.push(justifyContentMap[value]);
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
if (prop === "align-items" && alignItemsMap[value]) {
|
|
776
|
+
classes.push(alignItemsMap[value]);
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
if (prop === "display") {
|
|
780
|
+
if (value === "flex") classes.push("flex");
|
|
781
|
+
else if (value === "inline-flex") classes.push("inline-flex");
|
|
782
|
+
else if (value === "grid") classes.push("grid");
|
|
783
|
+
else if (value === "block") classes.push("block");
|
|
784
|
+
else if (value === "inline-block") classes.push("inline-block");
|
|
785
|
+
else if (value === "none") classes.push("hidden");
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
if (prop === "width") {
|
|
789
|
+
if (value === "100%") classes.push("w-full");
|
|
790
|
+
else if (value === "fit-content") classes.push("w-fit");
|
|
791
|
+
else if (value === "auto") classes.push("w-auto");
|
|
792
|
+
else classes.push(`w-[${value}]`);
|
|
793
|
+
continue;
|
|
794
|
+
}
|
|
795
|
+
if (prop === "height") {
|
|
796
|
+
if (value === "100%") classes.push("h-full");
|
|
797
|
+
else if (value === "fit-content") classes.push("h-fit");
|
|
798
|
+
else if (value === "auto") classes.push("h-auto");
|
|
799
|
+
else classes.push(`h-[${value}]`);
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
if (prop === "background-color") {
|
|
803
|
+
const colorValue = parseColorValue(value);
|
|
804
|
+
classes.push(colorToTailwind("backgroundColor", colorValue));
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
if (prop === "color") {
|
|
808
|
+
const colorValue = parseColorValue(value);
|
|
809
|
+
classes.push(colorToTailwind("color", colorValue));
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
if (prop === "border-color") {
|
|
813
|
+
const colorValue = parseColorValue(value);
|
|
814
|
+
classes.push(colorToTailwind("borderColor", colorValue));
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
if (prop === "border-style") {
|
|
818
|
+
const styleMap = {
|
|
819
|
+
none: "border-none",
|
|
820
|
+
solid: "border-solid",
|
|
821
|
+
dashed: "border-dashed",
|
|
822
|
+
dotted: "border-dotted",
|
|
823
|
+
double: "border-double"
|
|
824
|
+
};
|
|
825
|
+
classes.push(styleMap[value] || `[border-style:${value}]`);
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
if (prop === "border-top-style" || prop === "border-right-style" || prop === "border-bottom-style" || prop === "border-left-style") {
|
|
829
|
+
const allPresent = "border-top-style" in styles && "border-right-style" in styles && "border-bottom-style" in styles && "border-left-style" in styles;
|
|
830
|
+
if (allPresent) {
|
|
831
|
+
if (prop === "border-top-style") {
|
|
832
|
+
const allSame = styles["border-top-style"] === styles["border-right-style"] && styles["border-top-style"] === styles["border-bottom-style"] && styles["border-top-style"] === styles["border-left-style"];
|
|
833
|
+
if (allSame) {
|
|
834
|
+
const styleMap = {
|
|
835
|
+
none: "border-none",
|
|
836
|
+
solid: "border-solid",
|
|
837
|
+
dashed: "border-dashed",
|
|
838
|
+
dotted: "border-dotted",
|
|
839
|
+
double: "border-double"
|
|
840
|
+
};
|
|
841
|
+
classes.push(styleMap[value] || `[border-style:${value}]`);
|
|
842
|
+
} else {
|
|
843
|
+
classes.push(`[border-top-style:${styles["border-top-style"]}]`);
|
|
844
|
+
classes.push(`[border-right-style:${styles["border-right-style"]}]`);
|
|
845
|
+
classes.push(`[border-bottom-style:${styles["border-bottom-style"]}]`);
|
|
846
|
+
classes.push(`[border-left-style:${styles["border-left-style"]}]`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
} else {
|
|
850
|
+
classes.push(`[${prop}:${value}]`);
|
|
960
851
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
if (prop === "outline-color") {
|
|
855
|
+
const colorValue = parseColorValue(value);
|
|
856
|
+
classes.push(colorToTailwind("outlineColor", colorValue));
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
if (prop === "box-shadow") {
|
|
860
|
+
const trimmed = value.trim();
|
|
861
|
+
if (trimmed === "none" || trimmed === "") {
|
|
862
|
+
classes.push("shadow-none");
|
|
863
|
+
} else {
|
|
864
|
+
const normalized = normalizeShadowForComparison(trimmed);
|
|
865
|
+
const preset = tailwindShadowClassValues.find(
|
|
866
|
+
(entry) => normalizeShadowForComparison(entry.css) === normalized
|
|
867
|
+
);
|
|
868
|
+
if (preset) classes.push(preset.className);
|
|
869
|
+
else classes.push(`shadow-[${normalizeTailwindArbitraryValue(value)}]`);
|
|
966
870
|
}
|
|
871
|
+
continue;
|
|
967
872
|
}
|
|
968
|
-
|
|
969
|
-
|
|
873
|
+
if (prop === "font-size") {
|
|
874
|
+
classes.push(`text-[${value}]`);
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
877
|
+
if (prop === "font-weight") {
|
|
878
|
+
const weightMap = {
|
|
879
|
+
"100": "font-thin",
|
|
880
|
+
"200": "font-extralight",
|
|
881
|
+
"300": "font-light",
|
|
882
|
+
"400": "font-normal",
|
|
883
|
+
"500": "font-medium",
|
|
884
|
+
"600": "font-semibold",
|
|
885
|
+
"700": "font-bold",
|
|
886
|
+
"800": "font-extrabold",
|
|
887
|
+
"900": "font-black"
|
|
888
|
+
};
|
|
889
|
+
classes.push(weightMap[value] || `font-[${value}]`);
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (prop === "line-height") {
|
|
893
|
+
classes.push(`leading-[${value}]`);
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
if (prop === "letter-spacing") {
|
|
897
|
+
classes.push(`tracking-[${value}]`);
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
if (prop === "text-align") {
|
|
901
|
+
const alignMap = {
|
|
902
|
+
left: "text-left",
|
|
903
|
+
center: "text-center",
|
|
904
|
+
right: "text-right",
|
|
905
|
+
justify: "text-justify"
|
|
906
|
+
};
|
|
907
|
+
if (alignMap[value]) classes.push(alignMap[value]);
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
if (prop === "font-family") {
|
|
911
|
+
classes.push(`font-[${value.replace(/\s+/g, "_")}]`);
|
|
912
|
+
continue;
|
|
970
913
|
}
|
|
971
914
|
}
|
|
972
|
-
return
|
|
973
|
-
}
|
|
974
|
-
function getAllComputedStyles(element) {
|
|
975
|
-
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
976
|
-
return {
|
|
977
|
-
spacing,
|
|
978
|
-
borderRadius,
|
|
979
|
-
border: getComputedBorderStyles(element),
|
|
980
|
-
flex,
|
|
981
|
-
sizing: getComputedSizing(element),
|
|
982
|
-
color: getComputedColorStyles(element),
|
|
983
|
-
boxShadow: getComputedBoxShadow(element),
|
|
984
|
-
typography: getComputedTypography(element)
|
|
985
|
-
};
|
|
915
|
+
return classes.join(" ");
|
|
986
916
|
}
|
|
987
|
-
var
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
917
|
+
var propertyToCSSMap = {
|
|
918
|
+
paddingTop: "padding-top",
|
|
919
|
+
paddingRight: "padding-right",
|
|
920
|
+
paddingBottom: "padding-bottom",
|
|
921
|
+
paddingLeft: "padding-left",
|
|
922
|
+
marginTop: "margin-top",
|
|
923
|
+
marginRight: "margin-right",
|
|
924
|
+
marginBottom: "margin-bottom",
|
|
925
|
+
marginLeft: "margin-left",
|
|
926
|
+
gap: "gap"
|
|
992
927
|
};
|
|
993
|
-
var
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
928
|
+
var borderRadiusPropertyToCSSMap = {
|
|
929
|
+
borderTopLeftRadius: "border-top-left-radius",
|
|
930
|
+
borderTopRightRadius: "border-top-right-radius",
|
|
931
|
+
borderBottomRightRadius: "border-bottom-right-radius",
|
|
932
|
+
borderBottomLeftRadius: "border-bottom-left-radius"
|
|
933
|
+
};
|
|
934
|
+
var borderPropertyToCSSMap = {
|
|
935
|
+
borderTopStyle: "border-top-style",
|
|
936
|
+
borderTopWidth: "border-top-width",
|
|
937
|
+
borderRightStyle: "border-right-style",
|
|
938
|
+
borderRightWidth: "border-right-width",
|
|
939
|
+
borderBottomStyle: "border-bottom-style",
|
|
940
|
+
borderBottomWidth: "border-bottom-width",
|
|
941
|
+
borderLeftStyle: "border-left-style",
|
|
942
|
+
borderLeftWidth: "border-left-width"
|
|
943
|
+
};
|
|
944
|
+
var flexPropertyToCSSMap = {
|
|
945
|
+
display: "display",
|
|
946
|
+
flexDirection: "flex-direction",
|
|
947
|
+
justifyContent: "justify-content",
|
|
948
|
+
alignItems: "align-items"
|
|
949
|
+
};
|
|
950
|
+
var sizingPropertyToCSSMap = {
|
|
951
|
+
width: "width",
|
|
952
|
+
height: "height"
|
|
953
|
+
};
|
|
954
|
+
var typographyPropertyToCSSMap = {
|
|
955
|
+
fontFamily: "font-family",
|
|
956
|
+
fontWeight: "font-weight",
|
|
957
|
+
fontSize: "font-size",
|
|
958
|
+
lineHeight: "line-height",
|
|
959
|
+
letterSpacing: "letter-spacing",
|
|
960
|
+
textAlign: "text-align",
|
|
961
|
+
textVerticalAlign: "align-items"
|
|
998
962
|
};
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
963
|
+
var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
964
|
+
"p",
|
|
965
|
+
"h1",
|
|
966
|
+
"h2",
|
|
967
|
+
"h3",
|
|
968
|
+
"h4",
|
|
969
|
+
"h5",
|
|
970
|
+
"h6",
|
|
971
|
+
"span",
|
|
972
|
+
"label",
|
|
973
|
+
"a",
|
|
974
|
+
"strong",
|
|
975
|
+
"em",
|
|
976
|
+
"small",
|
|
977
|
+
"blockquote",
|
|
978
|
+
"li",
|
|
979
|
+
"td",
|
|
980
|
+
"th",
|
|
981
|
+
"caption",
|
|
982
|
+
"figcaption",
|
|
983
|
+
"legend",
|
|
984
|
+
"dt",
|
|
985
|
+
"dd",
|
|
986
|
+
"abbr",
|
|
987
|
+
"cite",
|
|
988
|
+
"code",
|
|
989
|
+
"pre"
|
|
990
|
+
]);
|
|
991
|
+
function hasDirectNonWhitespaceText(element) {
|
|
992
|
+
return Array.from(element.childNodes).some(
|
|
993
|
+
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
994
|
+
);
|
|
1005
995
|
}
|
|
1006
|
-
function
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
let isFlexItem = false;
|
|
1011
|
-
if (parentElement) {
|
|
1012
|
-
const parentComputed = window.getComputedStyle(parentElement);
|
|
1013
|
-
isFlexItem = parentComputed.display === "flex" || parentComputed.display === "inline-flex";
|
|
996
|
+
function isTextElement2(element) {
|
|
997
|
+
const tagName = element.tagName.toLowerCase();
|
|
998
|
+
if (TEXT_ELEMENT_TAGS.has(tagName)) {
|
|
999
|
+
return true;
|
|
1014
1000
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
id: element.id || null,
|
|
1018
|
-
classList: Array.from(element.classList),
|
|
1019
|
-
isFlexContainer: isFlexContainer2,
|
|
1020
|
-
isFlexItem,
|
|
1021
|
-
isTextElement: isTextElement2(element),
|
|
1022
|
-
parentElement,
|
|
1023
|
-
hasChildren: element.children.length > 0
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
function isFitSizing(element, dimension) {
|
|
1027
|
-
const computed = window.getComputedStyle(element);
|
|
1028
|
-
const inlineValue = element.style[dimension];
|
|
1029
|
-
if (inlineValue === "auto") return true;
|
|
1030
|
-
const computedValue = computed[dimension];
|
|
1031
|
-
if (!inlineValue) {
|
|
1032
|
-
const parent = element.parentElement;
|
|
1033
|
-
if (parent) {
|
|
1034
|
-
const parentComputed = window.getComputedStyle(parent);
|
|
1035
|
-
if (parentComputed.display === "flex" || parentComputed.display === "inline-flex") {
|
|
1036
|
-
const flexBasis = computed.flexBasis;
|
|
1037
|
-
const flexGrow = computed.flexGrow;
|
|
1038
|
-
if (flexBasis === "auto" && flexGrow === "0") {
|
|
1039
|
-
return true;
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
if (dimension === "width") {
|
|
1044
|
-
if (computed.display === "block" && !inlineValue) {
|
|
1045
|
-
return false;
|
|
1046
|
-
}
|
|
1047
|
-
if (computed.display === "inline-block" || computed.display === "inline-flex" || computed.display === "inline") {
|
|
1048
|
-
return true;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
if (dimension === "height") {
|
|
1052
|
-
return !inlineValue;
|
|
1053
|
-
}
|
|
1001
|
+
if (hasDirectNonWhitespaceText(element)) {
|
|
1002
|
+
return true;
|
|
1054
1003
|
}
|
|
1055
|
-
if (
|
|
1004
|
+
if (element.children.length === 0 && element.textContent?.trim()) {
|
|
1056
1005
|
return true;
|
|
1057
1006
|
}
|
|
1058
1007
|
return false;
|
|
1059
1008
|
}
|
|
1060
|
-
function
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1009
|
+
function getComputedTypography(element) {
|
|
1010
|
+
const computed = window.getComputedStyle(element);
|
|
1011
|
+
let textVerticalAlign = "flex-start";
|
|
1012
|
+
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
1013
|
+
const alignItems = computed.alignItems;
|
|
1014
|
+
if (alignItems === "center") textVerticalAlign = "center";
|
|
1015
|
+
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
1016
|
+
}
|
|
1017
|
+
const lineHeight = computed.lineHeight === "normal" ? { numericValue: parseFloat(computed.fontSize) * 1.2, unit: "px", raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px` } : parsePropertyValue(computed.lineHeight);
|
|
1018
|
+
const fontSize = parseFloat(computed.fontSize);
|
|
1019
|
+
let letterSpacing;
|
|
1020
|
+
if (computed.letterSpacing === "normal") {
|
|
1021
|
+
letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
|
|
1022
|
+
} else {
|
|
1023
|
+
const parsed = parsePropertyValue(computed.letterSpacing);
|
|
1024
|
+
if (parsed.unit === "px" && fontSize > 0) {
|
|
1025
|
+
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
1026
|
+
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
1027
|
+
} else {
|
|
1028
|
+
letterSpacing = parsed;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1065
1031
|
return {
|
|
1066
|
-
|
|
1067
|
-
|
|
1032
|
+
fontFamily: computed.fontFamily,
|
|
1033
|
+
fontWeight: computed.fontWeight,
|
|
1034
|
+
fontSize: parsePropertyValue(computed.fontSize),
|
|
1035
|
+
lineHeight,
|
|
1036
|
+
letterSpacing,
|
|
1037
|
+
textAlign: computed.textAlign,
|
|
1038
|
+
textVerticalAlign
|
|
1068
1039
|
};
|
|
1069
1040
|
}
|
|
1070
|
-
function
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
let parentInnerLeft;
|
|
1080
|
-
let parentInnerTop;
|
|
1081
|
-
let parentInnerRight;
|
|
1082
|
-
let parentInnerBottom;
|
|
1083
|
-
if (container) {
|
|
1084
|
-
parentInnerLeft = paddingBoxLeft;
|
|
1085
|
-
parentInnerTop = paddingBoxTop;
|
|
1086
|
-
parentInnerRight = paddingBoxRight;
|
|
1087
|
-
parentInnerBottom = paddingBoxBottom;
|
|
1088
|
-
} else {
|
|
1089
|
-
const parentStyles = window.getComputedStyle(parent);
|
|
1090
|
-
parentInnerLeft = paddingBoxLeft + (parseFloat(parentStyles.paddingLeft) || 0);
|
|
1091
|
-
parentInnerTop = paddingBoxTop + (parseFloat(parentStyles.paddingTop) || 0);
|
|
1092
|
-
parentInnerRight = paddingBoxRight - (parseFloat(parentStyles.paddingRight) || 0);
|
|
1093
|
-
parentInnerBottom = paddingBoxBottom - (parseFloat(parentStyles.paddingBottom) || 0);
|
|
1094
|
-
}
|
|
1095
|
-
const zoom = getZoomScale();
|
|
1096
|
-
const measurements = [];
|
|
1097
|
-
const topDistance = Math.round((elementRect.top - parentInnerTop) / zoom);
|
|
1098
|
-
if (topDistance > 0) {
|
|
1099
|
-
const midX = elementRect.left + elementRect.width / 2;
|
|
1100
|
-
measurements.push({
|
|
1101
|
-
direction: "vertical",
|
|
1102
|
-
x1: midX,
|
|
1103
|
-
y1: parentInnerTop,
|
|
1104
|
-
x2: midX,
|
|
1105
|
-
y2: elementRect.top,
|
|
1106
|
-
distance: topDistance,
|
|
1107
|
-
labelPosition: { x: midX, y: (parentInnerTop + elementRect.top) / 2 }
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
const bottomDistance = Math.round((parentInnerBottom - elementRect.bottom) / zoom);
|
|
1111
|
-
if (bottomDistance > 0) {
|
|
1112
|
-
const midX = elementRect.left + elementRect.width / 2;
|
|
1113
|
-
measurements.push({
|
|
1114
|
-
direction: "vertical",
|
|
1115
|
-
x1: midX,
|
|
1116
|
-
y1: elementRect.bottom,
|
|
1117
|
-
x2: midX,
|
|
1118
|
-
y2: parentInnerBottom,
|
|
1119
|
-
distance: bottomDistance,
|
|
1120
|
-
labelPosition: { x: midX, y: (elementRect.bottom + parentInnerBottom) / 2 }
|
|
1121
|
-
});
|
|
1122
|
-
}
|
|
1123
|
-
const leftDistance = Math.round((elementRect.left - parentInnerLeft) / zoom);
|
|
1124
|
-
if (leftDistance > 0) {
|
|
1125
|
-
const midY = elementRect.top + elementRect.height / 2;
|
|
1126
|
-
measurements.push({
|
|
1127
|
-
direction: "horizontal",
|
|
1128
|
-
x1: parentInnerLeft,
|
|
1129
|
-
y1: midY,
|
|
1130
|
-
x2: elementRect.left,
|
|
1131
|
-
y2: midY,
|
|
1132
|
-
distance: leftDistance,
|
|
1133
|
-
labelPosition: { x: (parentInnerLeft + elementRect.left) / 2, y: midY }
|
|
1134
|
-
});
|
|
1135
|
-
}
|
|
1136
|
-
const rightDistance = Math.round((parentInnerRight - elementRect.right) / zoom);
|
|
1137
|
-
if (rightDistance > 0) {
|
|
1138
|
-
const midY = elementRect.top + elementRect.height / 2;
|
|
1139
|
-
measurements.push({
|
|
1140
|
-
direction: "horizontal",
|
|
1141
|
-
x1: elementRect.right,
|
|
1142
|
-
y1: midY,
|
|
1143
|
-
x2: parentInnerRight,
|
|
1144
|
-
y2: midY,
|
|
1145
|
-
distance: rightDistance,
|
|
1146
|
-
labelPosition: { x: (elementRect.right + parentInnerRight) / 2, y: midY }
|
|
1147
|
-
});
|
|
1041
|
+
function detectSizingMode(element, dimension) {
|
|
1042
|
+
const computed = window.getComputedStyle(element);
|
|
1043
|
+
const inlineValue = element.style[dimension];
|
|
1044
|
+
if (inlineValue === "100%") return "fill";
|
|
1045
|
+
if (inlineValue === "auto" || inlineValue === "fit-content") return "fit";
|
|
1046
|
+
const computedValue = computed[dimension];
|
|
1047
|
+
if (computedValue === "100%") return "fill";
|
|
1048
|
+
if (computedValue === "auto" || computedValue === "fit-content" || computedValue === "max-content") {
|
|
1049
|
+
return "fit";
|
|
1148
1050
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
const verticalOverlap = fromRect.top < toRect.bottom && fromRect.bottom > toRect.top;
|
|
1158
|
-
if (verticalOverlap) {
|
|
1159
|
-
const overlapTop = Math.max(fromRect.top, toRect.top);
|
|
1160
|
-
const overlapBottom = Math.min(fromRect.bottom, toRect.bottom);
|
|
1161
|
-
const midY = (overlapTop + overlapBottom) / 2;
|
|
1162
|
-
if (fromRect.right <= toRect.left) {
|
|
1163
|
-
const distance = Math.round((toRect.left - fromRect.right) / zoom);
|
|
1164
|
-
measurements.push({
|
|
1165
|
-
direction: "horizontal",
|
|
1166
|
-
x1: fromRect.right,
|
|
1167
|
-
y1: midY,
|
|
1168
|
-
x2: toRect.left,
|
|
1169
|
-
y2: midY,
|
|
1170
|
-
distance,
|
|
1171
|
-
labelPosition: { x: (fromRect.right + toRect.left) / 2, y: midY }
|
|
1172
|
-
});
|
|
1173
|
-
} else if (fromRect.left >= toRect.right) {
|
|
1174
|
-
const distance = Math.round((fromRect.left - toRect.right) / zoom);
|
|
1175
|
-
measurements.push({
|
|
1176
|
-
direction: "horizontal",
|
|
1177
|
-
x1: toRect.right,
|
|
1178
|
-
y1: midY,
|
|
1179
|
-
x2: fromRect.left,
|
|
1180
|
-
y2: midY,
|
|
1181
|
-
distance,
|
|
1182
|
-
labelPosition: { x: (toRect.right + fromRect.left) / 2, y: midY }
|
|
1183
|
-
});
|
|
1051
|
+
const parent = element.parentElement;
|
|
1052
|
+
if (parent) {
|
|
1053
|
+
const parentComputed = window.getComputedStyle(parent);
|
|
1054
|
+
if (parentComputed.display === "flex" || parentComputed.display === "inline-flex") {
|
|
1055
|
+
const flexGrow = computed.flexGrow;
|
|
1056
|
+
if (flexGrow !== "0") {
|
|
1057
|
+
return "fill";
|
|
1058
|
+
}
|
|
1184
1059
|
}
|
|
1185
1060
|
}
|
|
1186
|
-
if (
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
const midX = (overlapLeft + overlapRight) / 2;
|
|
1190
|
-
if (fromRect.bottom <= toRect.top) {
|
|
1191
|
-
const distance = Math.round((toRect.top - fromRect.bottom) / zoom);
|
|
1192
|
-
measurements.push({
|
|
1193
|
-
direction: "vertical",
|
|
1194
|
-
x1: midX,
|
|
1195
|
-
y1: fromRect.bottom,
|
|
1196
|
-
x2: midX,
|
|
1197
|
-
y2: toRect.top,
|
|
1198
|
-
distance,
|
|
1199
|
-
labelPosition: { x: midX, y: (fromRect.bottom + toRect.top) / 2 }
|
|
1200
|
-
});
|
|
1201
|
-
} else if (fromRect.top >= toRect.bottom) {
|
|
1202
|
-
const distance = Math.round((fromRect.top - toRect.bottom) / zoom);
|
|
1203
|
-
measurements.push({
|
|
1204
|
-
direction: "vertical",
|
|
1205
|
-
x1: midX,
|
|
1206
|
-
y1: toRect.bottom,
|
|
1207
|
-
x2: midX,
|
|
1208
|
-
y2: fromRect.top,
|
|
1209
|
-
distance,
|
|
1210
|
-
labelPosition: { x: midX, y: (toRect.bottom + fromRect.top) / 2 }
|
|
1211
|
-
});
|
|
1061
|
+
if (dimension === "width") {
|
|
1062
|
+
if (computed.display === "block" && !inlineValue) {
|
|
1063
|
+
return "fill";
|
|
1212
1064
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
const fromCenterX = fromRect.left + fromRect.width / 2;
|
|
1216
|
-
const fromCenterY = fromRect.top + fromRect.height / 2;
|
|
1217
|
-
const toCenterX = toRect.left + toRect.width / 2;
|
|
1218
|
-
const toCenterY = toRect.top + toRect.height / 2;
|
|
1219
|
-
const hDistance = toCenterX > fromCenterX ? Math.round((toRect.left - fromRect.right) / zoom) : Math.round((fromRect.left - toRect.right) / zoom);
|
|
1220
|
-
if (hDistance > 0) {
|
|
1221
|
-
const startX = toCenterX > fromCenterX ? fromRect.right : fromRect.left;
|
|
1222
|
-
const endX = toCenterX > fromCenterX ? toRect.left : toRect.right;
|
|
1223
|
-
const y = (fromCenterY + toCenterY) / 2;
|
|
1224
|
-
measurements.push({
|
|
1225
|
-
direction: "horizontal",
|
|
1226
|
-
x1: startX,
|
|
1227
|
-
y1: y,
|
|
1228
|
-
x2: endX,
|
|
1229
|
-
y2: y,
|
|
1230
|
-
distance: hDistance,
|
|
1231
|
-
labelPosition: { x: (startX + endX) / 2, y }
|
|
1232
|
-
});
|
|
1065
|
+
if (computed.display === "inline-block" || computed.display === "inline-flex" || computed.display === "inline") {
|
|
1066
|
+
return "fit";
|
|
1233
1067
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const endY = toCenterY > fromCenterY ? toRect.top : toRect.bottom;
|
|
1239
|
-
measurements.push({
|
|
1240
|
-
direction: "vertical",
|
|
1241
|
-
x1: x,
|
|
1242
|
-
y1: startY,
|
|
1243
|
-
x2: x,
|
|
1244
|
-
y2: endY,
|
|
1245
|
-
distance: vDistance,
|
|
1246
|
-
labelPosition: { x, y: (startY + endY) / 2 }
|
|
1247
|
-
});
|
|
1068
|
+
}
|
|
1069
|
+
if (dimension === "height") {
|
|
1070
|
+
if (!inlineValue) {
|
|
1071
|
+
return "fit";
|
|
1248
1072
|
}
|
|
1249
1073
|
}
|
|
1250
|
-
return
|
|
1074
|
+
return "fixed";
|
|
1251
1075
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
if (snap.active) {
|
|
1262
|
-
const pan = g.orientation === "horizontal" ? snap.panY : snap.panX;
|
|
1263
|
-
const bo = g.orientation === "horizontal" ? getBodyOffset().y : getBodyOffset().x;
|
|
1264
|
-
viewportPos = bo + (g.position - bo + pan) * zoom;
|
|
1265
|
-
} else {
|
|
1266
|
-
const scroll = g.orientation === "horizontal" ? window.scrollY : window.scrollX;
|
|
1267
|
-
viewportPos = g.position - scroll;
|
|
1076
|
+
function getSizingValue(element, dimension) {
|
|
1077
|
+
const mode = detectSizingMode(element, dimension);
|
|
1078
|
+
const numericValue = Math.round(dimension === "width" ? element.offsetWidth : element.offsetHeight);
|
|
1079
|
+
return {
|
|
1080
|
+
mode,
|
|
1081
|
+
value: {
|
|
1082
|
+
numericValue,
|
|
1083
|
+
unit: "px",
|
|
1084
|
+
raw: `${numericValue}px`
|
|
1268
1085
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
function getComputedSizing(element) {
|
|
1089
|
+
return {
|
|
1090
|
+
width: getSizingValue(element, "width"),
|
|
1091
|
+
height: getSizingValue(element, "height")
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
function sizingValueToCSS(sizing) {
|
|
1095
|
+
switch (sizing.mode) {
|
|
1096
|
+
case "fill":
|
|
1097
|
+
return "100%";
|
|
1098
|
+
case "fit":
|
|
1099
|
+
return "fit-content";
|
|
1100
|
+
case "fixed":
|
|
1101
|
+
return `${sizing.value.numericValue}${sizing.value.unit}`;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
function sizingToTailwind(dimension, sizing) {
|
|
1105
|
+
const prefix = dimension === "width" ? "w" : "h";
|
|
1106
|
+
switch (sizing.mode) {
|
|
1107
|
+
case "fill":
|
|
1108
|
+
return `${prefix}-full`;
|
|
1109
|
+
case "fit":
|
|
1110
|
+
return `${prefix}-fit`;
|
|
1111
|
+
case "fixed":
|
|
1112
|
+
return `${prefix}-[${sizing.value.numericValue}${sizing.value.unit}]`;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function parseHexColor(hex) {
|
|
1116
|
+
const raw = hex;
|
|
1117
|
+
let h = hex.replace("#", "");
|
|
1118
|
+
if (h.length === 3) {
|
|
1119
|
+
h = h.split("").map((c) => c + c).join("");
|
|
1120
|
+
}
|
|
1121
|
+
if (h.length === 8) {
|
|
1122
|
+
const alpha = Math.round(parseInt(h.slice(6, 8), 16) / 255 * 100);
|
|
1123
|
+
return { hex: h.slice(0, 6).toUpperCase(), alpha, raw };
|
|
1124
|
+
}
|
|
1125
|
+
return { hex: h.toUpperCase(), alpha: 100, raw };
|
|
1126
|
+
}
|
|
1127
|
+
function parseRgbChannel(value) {
|
|
1128
|
+
const token = value.trim();
|
|
1129
|
+
if (!token) return null;
|
|
1130
|
+
if (token.endsWith("%")) {
|
|
1131
|
+
const numeric2 = parseFloat(token.slice(0, -1));
|
|
1132
|
+
if (!Number.isFinite(numeric2)) return null;
|
|
1133
|
+
return Math.round(Math.max(0, Math.min(100, numeric2)) / 100 * 255);
|
|
1134
|
+
}
|
|
1135
|
+
const numeric = parseFloat(token);
|
|
1136
|
+
if (!Number.isFinite(numeric)) return null;
|
|
1137
|
+
return Math.round(Math.max(0, Math.min(255, numeric)));
|
|
1138
|
+
}
|
|
1139
|
+
function parseRgbAlpha(value) {
|
|
1140
|
+
if (value == null || value.trim() === "") return 1;
|
|
1141
|
+
const token = value.trim();
|
|
1142
|
+
if (token.endsWith("%")) {
|
|
1143
|
+
const numeric2 = parseFloat(token.slice(0, -1));
|
|
1144
|
+
if (!Number.isFinite(numeric2)) return null;
|
|
1145
|
+
return Math.max(0, Math.min(100, numeric2)) / 100;
|
|
1146
|
+
}
|
|
1147
|
+
const numeric = parseFloat(token);
|
|
1148
|
+
if (!Number.isFinite(numeric)) return null;
|
|
1149
|
+
return Math.max(0, Math.min(1, numeric));
|
|
1150
|
+
}
|
|
1151
|
+
function parseRgbaColor(rgba) {
|
|
1152
|
+
const raw = rgba.trim();
|
|
1153
|
+
const fnMatch = raw.match(/^rgba?\((.*)\)$/i);
|
|
1154
|
+
if (!fnMatch) {
|
|
1155
|
+
return { hex: "000000", alpha: 100, raw: rgba };
|
|
1156
|
+
}
|
|
1157
|
+
const body = fnMatch[1].trim();
|
|
1158
|
+
let channelTokens = null;
|
|
1159
|
+
let alphaToken;
|
|
1160
|
+
const commaParts = body.split(",").map((part) => part.trim()).filter(Boolean);
|
|
1161
|
+
if (commaParts.length === 3 || commaParts.length === 4) {
|
|
1162
|
+
channelTokens = [commaParts[0], commaParts[1], commaParts[2]];
|
|
1163
|
+
alphaToken = commaParts[3];
|
|
1164
|
+
} else {
|
|
1165
|
+
const slashParts = body.split("/");
|
|
1166
|
+
if (slashParts.length === 1 || slashParts.length === 2) {
|
|
1167
|
+
const channels = slashParts[0].trim().split(/\s+/).filter(Boolean);
|
|
1168
|
+
if (channels.length === 3) {
|
|
1169
|
+
channelTokens = [channels[0], channels[1], channels[2]];
|
|
1170
|
+
alphaToken = slashParts[1]?.trim();
|
|
1328
1171
|
}
|
|
1329
1172
|
}
|
|
1330
1173
|
}
|
|
1331
|
-
|
|
1174
|
+
if (!channelTokens) {
|
|
1175
|
+
return { hex: "000000", alpha: 100, raw: rgba };
|
|
1176
|
+
}
|
|
1177
|
+
const r = parseRgbChannel(channelTokens[0]);
|
|
1178
|
+
const g = parseRgbChannel(channelTokens[1]);
|
|
1179
|
+
const b = parseRgbChannel(channelTokens[2]);
|
|
1180
|
+
const a = parseRgbAlpha(alphaToken);
|
|
1181
|
+
if (r === null || g === null || b === null || a === null) {
|
|
1182
|
+
return { hex: "000000", alpha: 100, raw: rgba };
|
|
1183
|
+
}
|
|
1184
|
+
const hex = [r, g, b].map((v) => v.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1185
|
+
const alpha = Math.round(a * 100);
|
|
1186
|
+
return { hex, alpha, raw: rgba };
|
|
1187
|
+
}
|
|
1188
|
+
function parseNamedColor(name) {
|
|
1189
|
+
const ctx = document.createElement("canvas").getContext("2d");
|
|
1190
|
+
if (!ctx) {
|
|
1191
|
+
return { hex: "000000", alpha: 100, raw: name };
|
|
1192
|
+
}
|
|
1193
|
+
ctx.fillStyle = name;
|
|
1194
|
+
const computed = ctx.fillStyle;
|
|
1195
|
+
if (computed.startsWith("#")) {
|
|
1196
|
+
return parseHexColor(computed);
|
|
1197
|
+
}
|
|
1198
|
+
return parseRgbaColor(computed);
|
|
1332
1199
|
}
|
|
1333
|
-
function
|
|
1334
|
-
const
|
|
1335
|
-
|
|
1200
|
+
function parseColorValue(cssValue) {
|
|
1201
|
+
const raw = cssValue.trim();
|
|
1202
|
+
if (raw === "transparent") {
|
|
1203
|
+
return { hex: "000000", alpha: 0, raw };
|
|
1204
|
+
}
|
|
1205
|
+
if (raw.startsWith("#")) {
|
|
1206
|
+
return parseHexColor(raw);
|
|
1207
|
+
}
|
|
1208
|
+
if (raw.startsWith("rgb")) {
|
|
1209
|
+
return parseRgbaColor(raw);
|
|
1210
|
+
}
|
|
1211
|
+
return parseNamedColor(raw);
|
|
1336
1212
|
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
return
|
|
1213
|
+
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
1214
|
+
function isVisibleBorderSide(side) {
|
|
1215
|
+
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
1340
1216
|
}
|
|
1341
|
-
function
|
|
1342
|
-
|
|
1343
|
-
return cs.display !== "none" && cs.position !== "absolute" && cs.position !== "fixed";
|
|
1217
|
+
function hasVisibleOutline(computed) {
|
|
1218
|
+
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
1344
1219
|
}
|
|
1345
|
-
function
|
|
1346
|
-
const
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
return
|
|
1350
|
-
axis: dir === "row" || dir === "row-reverse" ? "horizontal" : "vertical",
|
|
1351
|
-
reversed: dir === "row-reverse" || dir === "column-reverse"
|
|
1352
|
-
};
|
|
1220
|
+
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
1221
|
+
const raw = value.trim();
|
|
1222
|
+
const lowered = raw.toLowerCase();
|
|
1223
|
+
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
1224
|
+
return null;
|
|
1353
1225
|
}
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
visible.push(c);
|
|
1359
|
-
if (visible.length === 2) break;
|
|
1226
|
+
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
1227
|
+
const parsed = parseColorValue(resolved);
|
|
1228
|
+
if (parsed.alpha <= 0) {
|
|
1229
|
+
return null;
|
|
1360
1230
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1231
|
+
return parsed;
|
|
1232
|
+
}
|
|
1233
|
+
function addUniqueColor(colors, color) {
|
|
1234
|
+
if (!color) return;
|
|
1235
|
+
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
1236
|
+
}
|
|
1237
|
+
function isTextRenderingFormControl(element) {
|
|
1238
|
+
if (element instanceof HTMLTextAreaElement) return true;
|
|
1239
|
+
if (element instanceof HTMLSelectElement) return true;
|
|
1240
|
+
if (element instanceof HTMLButtonElement) return true;
|
|
1241
|
+
if (element instanceof HTMLInputElement) {
|
|
1242
|
+
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
1243
|
+
"hidden",
|
|
1244
|
+
"checkbox",
|
|
1245
|
+
"radio",
|
|
1246
|
+
"range",
|
|
1247
|
+
"color",
|
|
1248
|
+
"file",
|
|
1249
|
+
"image"
|
|
1250
|
+
]);
|
|
1251
|
+
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
1367
1252
|
}
|
|
1368
|
-
return
|
|
1253
|
+
return false;
|
|
1369
1254
|
}
|
|
1370
|
-
function
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1255
|
+
function hasRenderableTextNode(element) {
|
|
1256
|
+
if (element.isContentEditable) return true;
|
|
1257
|
+
if (isTextRenderingFormControl(element)) return true;
|
|
1258
|
+
if (!element.textContent?.trim()) return false;
|
|
1259
|
+
if (hasDirectNonWhitespaceText(element)) return true;
|
|
1260
|
+
const tagName = element.tagName.toLowerCase();
|
|
1261
|
+
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
1262
|
+
}
|
|
1263
|
+
function getComputedBoxShadow(element) {
|
|
1264
|
+
const computed = window.getComputedStyle(element);
|
|
1265
|
+
const value = computed.boxShadow.trim();
|
|
1266
|
+
return value || "none";
|
|
1267
|
+
}
|
|
1268
|
+
function getComputedColorStyles(element) {
|
|
1269
|
+
const computed = window.getComputedStyle(element);
|
|
1270
|
+
const borderSides = [
|
|
1271
|
+
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1272
|
+
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1273
|
+
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1274
|
+
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1275
|
+
];
|
|
1276
|
+
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
1277
|
+
const hasBorder = Boolean(visibleBorderSide);
|
|
1278
|
+
const hasOutline = hasVisibleOutline(computed);
|
|
1279
|
+
return {
|
|
1280
|
+
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
1281
|
+
color: parseColorValue(computed.color),
|
|
1282
|
+
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
1283
|
+
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
function getSelectionColors(element) {
|
|
1287
|
+
const uniqueColors = /* @__PURE__ */ new Map();
|
|
1288
|
+
const queue = [element];
|
|
1289
|
+
for (let index = 0; index < queue.length; index++) {
|
|
1290
|
+
const node = queue[index];
|
|
1291
|
+
const computed = window.getComputedStyle(node);
|
|
1292
|
+
if (computed.display === "none") {
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
|
|
1296
|
+
const currentTextColor = computed.color;
|
|
1297
|
+
if (!isVisibilityHidden) {
|
|
1298
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
|
|
1299
|
+
if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
|
|
1300
|
+
addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
|
|
1301
|
+
}
|
|
1302
|
+
const borderSides = [
|
|
1303
|
+
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1304
|
+
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1305
|
+
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1306
|
+
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1307
|
+
];
|
|
1308
|
+
for (const side of borderSides) {
|
|
1309
|
+
if (!isVisibleBorderSide(side)) continue;
|
|
1310
|
+
addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
|
|
1311
|
+
}
|
|
1312
|
+
if (hasVisibleOutline(computed)) {
|
|
1313
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
|
|
1314
|
+
}
|
|
1315
|
+
if (node instanceof SVGElement) {
|
|
1316
|
+
const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
|
|
1317
|
+
const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
1318
|
+
addUniqueColor(uniqueColors, fillColor);
|
|
1319
|
+
addUniqueColor(uniqueColors, strokeColor);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
for (const child of node.children) {
|
|
1323
|
+
queue.push(child);
|
|
1324
|
+
}
|
|
1380
1325
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1326
|
+
return Array.from(uniqueColors.values());
|
|
1327
|
+
}
|
|
1328
|
+
function getAllComputedStyles(element) {
|
|
1329
|
+
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
1330
|
+
return {
|
|
1331
|
+
spacing,
|
|
1332
|
+
borderRadius,
|
|
1333
|
+
border: getComputedBorderStyles(element),
|
|
1334
|
+
flex,
|
|
1335
|
+
sizing: getComputedSizing(element),
|
|
1336
|
+
color: getComputedColorStyles(element),
|
|
1337
|
+
boxShadow: getComputedBoxShadow(element),
|
|
1338
|
+
typography: getComputedTypography(element)
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
var colorPropertyToCSSMap = {
|
|
1342
|
+
backgroundColor: "background-color",
|
|
1343
|
+
color: "color",
|
|
1344
|
+
borderColor: "border-color",
|
|
1345
|
+
outlineColor: "outline-color"
|
|
1346
|
+
};
|
|
1347
|
+
var colorTailwindPrefixMap = {
|
|
1348
|
+
backgroundColor: "bg",
|
|
1349
|
+
color: "text",
|
|
1350
|
+
borderColor: "border",
|
|
1351
|
+
outlineColor: "outline"
|
|
1352
|
+
};
|
|
1353
|
+
function colorToTailwind(property, colorValue) {
|
|
1354
|
+
const prefix = colorTailwindPrefixMap[property];
|
|
1355
|
+
if (colorValue.alpha === 100) {
|
|
1356
|
+
return `${prefix}-[#${colorValue.hex}]`;
|
|
1383
1357
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1358
|
+
return `${prefix}-[#${colorValue.hex}]/${colorValue.alpha}`;
|
|
1359
|
+
}
|
|
1360
|
+
function getElementInfo(element) {
|
|
1361
|
+
const computed = window.getComputedStyle(element);
|
|
1362
|
+
const parentElement = element === document.body ? null : element.parentElement;
|
|
1363
|
+
const isFlexContainer2 = computed.display === "flex" || computed.display === "inline-flex";
|
|
1364
|
+
let isFlexItem = false;
|
|
1365
|
+
if (parentElement) {
|
|
1366
|
+
const parentComputed = window.getComputedStyle(parentElement);
|
|
1367
|
+
isFlexItem = parentComputed.display === "flex" || parentComputed.display === "inline-flex";
|
|
1368
|
+
}
|
|
1369
|
+
return {
|
|
1370
|
+
tagName: element.tagName.toLowerCase(),
|
|
1371
|
+
id: element.id || null,
|
|
1372
|
+
classList: Array.from(element.classList),
|
|
1373
|
+
isFlexContainer: isFlexContainer2,
|
|
1374
|
+
isFlexItem,
|
|
1375
|
+
isTextElement: isTextElement2(element),
|
|
1376
|
+
parentElement,
|
|
1377
|
+
hasChildren: element.children.length > 0
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function isFitSizing(element, dimension) {
|
|
1381
|
+
const computed = window.getComputedStyle(element);
|
|
1382
|
+
const inlineValue = element.style[dimension];
|
|
1383
|
+
if (inlineValue === "auto") return true;
|
|
1384
|
+
const computedValue = computed[dimension];
|
|
1385
|
+
if (!inlineValue) {
|
|
1386
|
+
const parent = element.parentElement;
|
|
1387
|
+
if (parent) {
|
|
1388
|
+
const parentComputed = window.getComputedStyle(parent);
|
|
1389
|
+
if (parentComputed.display === "flex" || parentComputed.display === "inline-flex") {
|
|
1390
|
+
const flexBasis = computed.flexBasis;
|
|
1391
|
+
const flexGrow = computed.flexGrow;
|
|
1392
|
+
if (flexBasis === "auto" && flexGrow === "0") {
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (dimension === "width") {
|
|
1398
|
+
if (computed.display === "block" && !inlineValue) {
|
|
1399
|
+
return false;
|
|
1400
|
+
}
|
|
1401
|
+
if (computed.display === "inline-block" || computed.display === "inline-flex" || computed.display === "inline") {
|
|
1402
|
+
return true;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (dimension === "height") {
|
|
1406
|
+
return !inlineValue;
|
|
1389
1407
|
}
|
|
1390
1408
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
function htmlChildren(el) {
|
|
1394
|
-
return Array.from(el.children).filter(
|
|
1395
|
-
(child) => child instanceof HTMLElement
|
|
1396
|
-
);
|
|
1397
|
-
}
|
|
1398
|
-
function findFlexAncestor(element, boundary) {
|
|
1399
|
-
let current = element;
|
|
1400
|
-
while (current && current !== document.body) {
|
|
1401
|
-
const parent = current.parentElement;
|
|
1402
|
-
if (!parent) break;
|
|
1403
|
-
const display = getComputedStyle(parent).display;
|
|
1404
|
-
if (display === "flex" || display === "inline-flex") {
|
|
1405
|
-
return { flexParent: parent, child: current };
|
|
1406
|
-
}
|
|
1407
|
-
if (boundary && parent === boundary) break;
|
|
1408
|
-
current = parent;
|
|
1409
|
+
if (computedValue.includes("fit-content") || computedValue.includes("max-content")) {
|
|
1410
|
+
return true;
|
|
1409
1411
|
}
|
|
1410
|
-
return
|
|
1412
|
+
return false;
|
|
1411
1413
|
}
|
|
1412
|
-
function
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1414
|
+
function getDimensionDisplay(element) {
|
|
1415
|
+
const width = Math.round(element.offsetWidth);
|
|
1416
|
+
const height = Math.round(element.offsetHeight);
|
|
1417
|
+
const widthIsFit = isFitSizing(element, "width");
|
|
1418
|
+
const heightIsFit = isFitSizing(element, "height");
|
|
1419
|
+
return {
|
|
1420
|
+
width: widthIsFit ? `Fit ${width}` : `${width}`,
|
|
1421
|
+
height: heightIsFit ? `Fit ${height}` : `${height}`
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
function calculateParentMeasurements(element, container) {
|
|
1425
|
+
const parent = container ?? element.parentElement;
|
|
1426
|
+
if (!parent) return [];
|
|
1427
|
+
const elementRect = element.getBoundingClientRect();
|
|
1428
|
+
const parentRect = parent.getBoundingClientRect();
|
|
1429
|
+
const paddingBoxLeft = parentRect.left + parent.clientLeft;
|
|
1430
|
+
const paddingBoxTop = parentRect.top + parent.clientTop;
|
|
1431
|
+
const paddingBoxRight = parentRect.left + parent.clientLeft + parent.clientWidth;
|
|
1432
|
+
const paddingBoxBottom = parentRect.top + parent.clientTop + parent.clientHeight;
|
|
1433
|
+
let parentInnerLeft;
|
|
1434
|
+
let parentInnerTop;
|
|
1435
|
+
let parentInnerRight;
|
|
1436
|
+
let parentInnerBottom;
|
|
1437
|
+
if (container) {
|
|
1438
|
+
parentInnerLeft = paddingBoxLeft;
|
|
1439
|
+
parentInnerTop = paddingBoxTop;
|
|
1440
|
+
parentInnerRight = paddingBoxRight;
|
|
1441
|
+
parentInnerBottom = paddingBoxBottom;
|
|
1442
|
+
} else {
|
|
1443
|
+
const parentStyles = window.getComputedStyle(parent);
|
|
1444
|
+
parentInnerLeft = paddingBoxLeft + (parseFloat(parentStyles.paddingLeft) || 0);
|
|
1445
|
+
parentInnerTop = paddingBoxTop + (parseFloat(parentStyles.paddingTop) || 0);
|
|
1446
|
+
parentInnerRight = paddingBoxRight - (parseFloat(parentStyles.paddingRight) || 0);
|
|
1447
|
+
parentInnerBottom = paddingBoxBottom - (parseFloat(parentStyles.paddingBottom) || 0);
|
|
1420
1448
|
}
|
|
1421
|
-
const
|
|
1422
|
-
|
|
1423
|
-
|
|
1449
|
+
const zoom = getZoomScale();
|
|
1450
|
+
const measurements = [];
|
|
1451
|
+
const topDistance = Math.round((elementRect.top - parentInnerTop) / zoom);
|
|
1452
|
+
if (topDistance > 0) {
|
|
1453
|
+
const midX = elementRect.left + elementRect.width / 2;
|
|
1454
|
+
measurements.push({
|
|
1455
|
+
direction: "vertical",
|
|
1456
|
+
x1: midX,
|
|
1457
|
+
y1: parentInnerTop,
|
|
1458
|
+
x2: midX,
|
|
1459
|
+
y2: elementRect.top,
|
|
1460
|
+
distance: topDistance,
|
|
1461
|
+
labelPosition: { x: midX, y: (parentInnerTop + elementRect.top) / 2 }
|
|
1462
|
+
});
|
|
1424
1463
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
const textNode = caretNode;
|
|
1438
|
-
if (!(textNode.nodeValue ?? "").trim()) return null;
|
|
1439
|
-
const owner = textNode.parentElement;
|
|
1440
|
-
if (!owner || !boundary.contains(owner)) return null;
|
|
1441
|
-
if (owner.closest("[data-direct-edit]") || owner.closest("[data-direct-edit-host]")) return null;
|
|
1442
|
-
const range = document.createRange();
|
|
1443
|
-
range.selectNodeContents(textNode);
|
|
1444
|
-
const hitsText = Array.from(range.getClientRects()).some(
|
|
1445
|
-
(r) => clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom
|
|
1446
|
-
);
|
|
1447
|
-
range.detach?.();
|
|
1448
|
-
return hitsText ? owner : null;
|
|
1449
|
-
}
|
|
1450
|
-
function findTextOwnerByRangeScan(boundary, clientX, clientY) {
|
|
1451
|
-
const walker = document.createTreeWalker(boundary, NodeFilter.SHOW_TEXT);
|
|
1452
|
-
let current = walker.nextNode();
|
|
1453
|
-
while (current) {
|
|
1454
|
-
const textNode = current;
|
|
1455
|
-
if ((textNode.nodeValue ?? "").trim()) {
|
|
1456
|
-
const owner = textNode.parentElement;
|
|
1457
|
-
if (owner && boundary.contains(owner) && !owner.closest("[data-direct-edit]") && !owner.closest("[data-direct-edit-host]")) {
|
|
1458
|
-
const range = document.createRange();
|
|
1459
|
-
range.selectNodeContents(textNode);
|
|
1460
|
-
const hitsText = Array.from(range.getClientRects()).some(
|
|
1461
|
-
(r) => clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom
|
|
1462
|
-
);
|
|
1463
|
-
range.detach?.();
|
|
1464
|
-
if (hitsText) return owner;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
current = walker.nextNode();
|
|
1464
|
+
const bottomDistance = Math.round((parentInnerBottom - elementRect.bottom) / zoom);
|
|
1465
|
+
if (bottomDistance > 0) {
|
|
1466
|
+
const midX = elementRect.left + elementRect.width / 2;
|
|
1467
|
+
measurements.push({
|
|
1468
|
+
direction: "vertical",
|
|
1469
|
+
x1: midX,
|
|
1470
|
+
y1: elementRect.bottom,
|
|
1471
|
+
x2: midX,
|
|
1472
|
+
y2: parentInnerBottom,
|
|
1473
|
+
distance: bottomDistance,
|
|
1474
|
+
labelPosition: { x: midX, y: (elementRect.bottom + parentInnerBottom) / 2 }
|
|
1475
|
+
});
|
|
1468
1476
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
);
|
|
1481
|
-
range.detach?.();
|
|
1482
|
-
if (!hitsText) continue;
|
|
1483
|
-
const span = document.createElement("span");
|
|
1484
|
-
span.setAttribute("data-direct-edit-generated", "text-span");
|
|
1485
|
-
span.textContent = textNode.textContent ?? "";
|
|
1486
|
-
parent.replaceChild(span, textNode);
|
|
1487
|
-
return span;
|
|
1477
|
+
const leftDistance = Math.round((elementRect.left - parentInnerLeft) / zoom);
|
|
1478
|
+
if (leftDistance > 0) {
|
|
1479
|
+
const midY = elementRect.top + elementRect.height / 2;
|
|
1480
|
+
measurements.push({
|
|
1481
|
+
direction: "horizontal",
|
|
1482
|
+
x1: parentInnerLeft,
|
|
1483
|
+
y1: midY,
|
|
1484
|
+
x2: elementRect.left,
|
|
1485
|
+
y2: midY,
|
|
1486
|
+
distance: leftDistance,
|
|
1487
|
+
labelPosition: { x: (parentInnerLeft + elementRect.left) / 2, y: midY }
|
|
1488
|
+
});
|
|
1488
1489
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
function elementFromPointWithoutOverlays(x, y) {
|
|
1503
|
-
const host = document.querySelector("[data-direct-edit-host]");
|
|
1504
|
-
if (host) host.style.display = "none";
|
|
1505
|
-
const el = document.elementFromPoint(x, y);
|
|
1506
|
-
if (host) host.style.display = "";
|
|
1507
|
-
return el;
|
|
1508
|
-
}
|
|
1509
|
-
function isLayoutContainer(element) {
|
|
1510
|
-
const display = window.getComputedStyle(element).display;
|
|
1511
|
-
return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
|
|
1512
|
-
}
|
|
1513
|
-
function isBlockContainer(element) {
|
|
1514
|
-
const display = window.getComputedStyle(element).display;
|
|
1515
|
-
return display === "block" || display === "flow-root" || display === "inline-block" || display === "list-item";
|
|
1516
|
-
}
|
|
1517
|
-
function skipElement(el, exclude) {
|
|
1518
|
-
if (exclude && exclude.contains(el)) return true;
|
|
1519
|
-
if (el === document.body || el === document.documentElement) return true;
|
|
1520
|
-
if (el.closest("[data-direct-edit]") || el.closest("[data-direct-edit-host]")) return true;
|
|
1521
|
-
return false;
|
|
1522
|
-
}
|
|
1523
|
-
function findContainerViaTraversal(x, y, exclude) {
|
|
1524
|
-
const el = elementFromPointWithoutOverlays(x, y);
|
|
1525
|
-
if (!el) return null;
|
|
1526
|
-
let current = el;
|
|
1527
|
-
while (current) {
|
|
1528
|
-
if (!skipElement(current, exclude)) {
|
|
1529
|
-
if (isLayoutContainer(current) || isBlockContainer(current)) return current;
|
|
1530
|
-
}
|
|
1531
|
-
current = current.parentElement;
|
|
1490
|
+
const rightDistance = Math.round((parentInnerRight - elementRect.right) / zoom);
|
|
1491
|
+
if (rightDistance > 0) {
|
|
1492
|
+
const midY = elementRect.top + elementRect.height / 2;
|
|
1493
|
+
measurements.push({
|
|
1494
|
+
direction: "horizontal",
|
|
1495
|
+
x1: elementRect.right,
|
|
1496
|
+
y1: midY,
|
|
1497
|
+
x2: parentInnerRight,
|
|
1498
|
+
y2: midY,
|
|
1499
|
+
distance: rightDistance,
|
|
1500
|
+
labelPosition: { x: (elementRect.right + parentInnerRight) / 2, y: midY }
|
|
1501
|
+
});
|
|
1532
1502
|
}
|
|
1533
|
-
return
|
|
1503
|
+
return measurements;
|
|
1534
1504
|
}
|
|
1535
|
-
function
|
|
1536
|
-
const
|
|
1537
|
-
|
|
1538
|
-
const
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1505
|
+
function calculateElementMeasurements(from, to) {
|
|
1506
|
+
const fromRect = from.getBoundingClientRect();
|
|
1507
|
+
const toRect = to.getBoundingClientRect();
|
|
1508
|
+
const zoom = getZoomScale();
|
|
1509
|
+
const measurements = [];
|
|
1510
|
+
const horizontalOverlap = fromRect.left < toRect.right && fromRect.right > toRect.left;
|
|
1511
|
+
const verticalOverlap = fromRect.top < toRect.bottom && fromRect.bottom > toRect.top;
|
|
1512
|
+
if (verticalOverlap) {
|
|
1513
|
+
const overlapTop = Math.max(fromRect.top, toRect.top);
|
|
1514
|
+
const overlapBottom = Math.min(fromRect.bottom, toRect.bottom);
|
|
1515
|
+
const midY = (overlapTop + overlapBottom) / 2;
|
|
1516
|
+
if (fromRect.right <= toRect.left) {
|
|
1517
|
+
const distance = Math.round((toRect.left - fromRect.right) / zoom);
|
|
1518
|
+
measurements.push({
|
|
1519
|
+
direction: "horizontal",
|
|
1520
|
+
x1: fromRect.right,
|
|
1521
|
+
y1: midY,
|
|
1522
|
+
x2: toRect.left,
|
|
1523
|
+
y2: midY,
|
|
1524
|
+
distance,
|
|
1525
|
+
labelPosition: { x: (fromRect.right + toRect.left) / 2, y: midY }
|
|
1526
|
+
});
|
|
1527
|
+
} else if (fromRect.left >= toRect.right) {
|
|
1528
|
+
const distance = Math.round((fromRect.left - toRect.right) / zoom);
|
|
1529
|
+
measurements.push({
|
|
1530
|
+
direction: "horizontal",
|
|
1531
|
+
x1: toRect.right,
|
|
1532
|
+
y1: midY,
|
|
1533
|
+
x2: fromRect.left,
|
|
1534
|
+
y2: midY,
|
|
1535
|
+
distance,
|
|
1536
|
+
labelPosition: { x: (toRect.right + fromRect.left) / 2, y: midY }
|
|
1537
|
+
});
|
|
1547
1538
|
}
|
|
1548
1539
|
}
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1540
|
+
if (horizontalOverlap) {
|
|
1541
|
+
const overlapLeft = Math.max(fromRect.left, toRect.left);
|
|
1542
|
+
const overlapRight = Math.min(fromRect.right, toRect.right);
|
|
1543
|
+
const midX = (overlapLeft + overlapRight) / 2;
|
|
1544
|
+
if (fromRect.bottom <= toRect.top) {
|
|
1545
|
+
const distance = Math.round((toRect.top - fromRect.bottom) / zoom);
|
|
1546
|
+
measurements.push({
|
|
1547
|
+
direction: "vertical",
|
|
1548
|
+
x1: midX,
|
|
1549
|
+
y1: fromRect.bottom,
|
|
1550
|
+
x2: midX,
|
|
1551
|
+
y2: toRect.top,
|
|
1552
|
+
distance,
|
|
1553
|
+
labelPosition: { x: midX, y: (fromRect.bottom + toRect.top) / 2 }
|
|
1554
|
+
});
|
|
1555
|
+
} else if (fromRect.top >= toRect.bottom) {
|
|
1556
|
+
const distance = Math.round((fromRect.top - toRect.bottom) / zoom);
|
|
1557
|
+
measurements.push({
|
|
1558
|
+
direction: "vertical",
|
|
1559
|
+
x1: midX,
|
|
1560
|
+
y1: toRect.bottom,
|
|
1561
|
+
x2: midX,
|
|
1562
|
+
y2: fromRect.top,
|
|
1563
|
+
distance,
|
|
1564
|
+
labelPosition: { x: midX, y: (toRect.bottom + fromRect.top) / 2 }
|
|
1565
|
+
});
|
|
1563
1566
|
}
|
|
1564
1567
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
(
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
}
|
|
1585
|
-
const containerRect = container.getBoundingClientRect();
|
|
1586
|
-
let insertBefore = null;
|
|
1587
|
-
let indicatorPosition = 0;
|
|
1588
|
-
for (let i = 0; i < children.length; i++) {
|
|
1589
|
-
const child = children[i];
|
|
1590
|
-
const rect = child.getBoundingClientRect();
|
|
1591
|
-
const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
|
|
1592
|
-
const pointer = isHorizontal ? pointerX : pointerY;
|
|
1593
|
-
const beforeMidpoint = isReversed ? pointer > midpoint : pointer < midpoint;
|
|
1594
|
-
if (beforeMidpoint) {
|
|
1595
|
-
insertBefore = child;
|
|
1596
|
-
indicatorPosition = isHorizontal ? rect.left : rect.top;
|
|
1597
|
-
break;
|
|
1568
|
+
if (!horizontalOverlap && !verticalOverlap) {
|
|
1569
|
+
const fromCenterX = fromRect.left + fromRect.width / 2;
|
|
1570
|
+
const fromCenterY = fromRect.top + fromRect.height / 2;
|
|
1571
|
+
const toCenterX = toRect.left + toRect.width / 2;
|
|
1572
|
+
const toCenterY = toRect.top + toRect.height / 2;
|
|
1573
|
+
const hDistance = toCenterX > fromCenterX ? Math.round((toRect.left - fromRect.right) / zoom) : Math.round((fromRect.left - toRect.right) / zoom);
|
|
1574
|
+
if (hDistance > 0) {
|
|
1575
|
+
const startX = toCenterX > fromCenterX ? fromRect.right : fromRect.left;
|
|
1576
|
+
const endX = toCenterX > fromCenterX ? toRect.left : toRect.right;
|
|
1577
|
+
const y = (fromCenterY + toCenterY) / 2;
|
|
1578
|
+
measurements.push({
|
|
1579
|
+
direction: "horizontal",
|
|
1580
|
+
x1: startX,
|
|
1581
|
+
y1: y,
|
|
1582
|
+
x2: endX,
|
|
1583
|
+
y2: y,
|
|
1584
|
+
distance: hDistance,
|
|
1585
|
+
labelPosition: { x: (startX + endX) / 2, y }
|
|
1586
|
+
});
|
|
1598
1587
|
}
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
width: containerRect.width - 8,
|
|
1614
|
-
height: 2
|
|
1615
|
-
};
|
|
1616
|
-
return { insertBefore, indicator };
|
|
1617
|
-
}
|
|
1618
|
-
function getFiberForElement(element) {
|
|
1619
|
-
if (typeof window !== "undefined") {
|
|
1620
|
-
const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
|
|
1621
|
-
if (devtools?.getFiberForElement) {
|
|
1622
|
-
const fiber = devtools.getFiberForElement(element);
|
|
1623
|
-
if (fiber) return fiber;
|
|
1588
|
+
const vDistance = toCenterY > fromCenterY ? Math.round((toRect.top - fromRect.bottom) / zoom) : Math.round((fromRect.top - toRect.bottom) / zoom);
|
|
1589
|
+
if (vDistance > 0) {
|
|
1590
|
+
const x = (fromCenterX + toCenterX) / 2;
|
|
1591
|
+
const startY = toCenterY > fromCenterY ? fromRect.bottom : fromRect.top;
|
|
1592
|
+
const endY = toCenterY > fromCenterY ? toRect.top : toRect.bottom;
|
|
1593
|
+
measurements.push({
|
|
1594
|
+
direction: "vertical",
|
|
1595
|
+
x1: x,
|
|
1596
|
+
y1: startY,
|
|
1597
|
+
x2: x,
|
|
1598
|
+
y2: endY,
|
|
1599
|
+
distance: vDistance,
|
|
1600
|
+
labelPosition: { x, y: (startY + endY) / 2 }
|
|
1601
|
+
});
|
|
1624
1602
|
}
|
|
1625
1603
|
}
|
|
1626
|
-
|
|
1627
|
-
(key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
|
|
1628
|
-
);
|
|
1629
|
-
if (!fiberKey) return null;
|
|
1630
|
-
return element[fiberKey] || null;
|
|
1604
|
+
return measurements;
|
|
1631
1605
|
}
|
|
1632
|
-
var
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1606
|
+
var GUIDELINE_PROXIMITY = 80;
|
|
1607
|
+
function calculateGuidelineMeasurements(element, guidelines, mousePosition) {
|
|
1608
|
+
if (guidelines.length === 0) return [];
|
|
1609
|
+
const snap = getCanvasSnapshot();
|
|
1610
|
+
const zoom = snap.active ? snap.zoom : 1;
|
|
1611
|
+
const rect = element.getBoundingClientRect();
|
|
1612
|
+
const measurements = [];
|
|
1613
|
+
for (const g of guidelines) {
|
|
1614
|
+
let viewportPos;
|
|
1615
|
+
if (snap.active) {
|
|
1616
|
+
const pan = g.orientation === "horizontal" ? snap.panY : snap.panX;
|
|
1617
|
+
const bo = g.orientation === "horizontal" ? getBodyOffset().y : getBodyOffset().x;
|
|
1618
|
+
viewportPos = bo + (g.position - bo + pan) * zoom;
|
|
1619
|
+
} else {
|
|
1620
|
+
const scroll = g.orientation === "horizontal" ? window.scrollY : window.scrollX;
|
|
1621
|
+
viewportPos = g.position - scroll;
|
|
1622
|
+
}
|
|
1623
|
+
if (g.orientation === "horizontal") {
|
|
1624
|
+
const midX = rect.left + rect.width / 2;
|
|
1625
|
+
if (mousePosition && Math.abs(mousePosition.y - viewportPos) > GUIDELINE_PROXIMITY) continue;
|
|
1626
|
+
if (viewportPos < rect.top) {
|
|
1627
|
+
const distance = Math.round((rect.top - viewportPos) / zoom);
|
|
1628
|
+
if (distance > 0) {
|
|
1629
|
+
measurements.push({
|
|
1630
|
+
direction: "vertical",
|
|
1631
|
+
x1: midX,
|
|
1632
|
+
y1: viewportPos,
|
|
1633
|
+
x2: midX,
|
|
1634
|
+
y2: rect.top,
|
|
1635
|
+
distance,
|
|
1636
|
+
labelPosition: { x: midX, y: (viewportPos + rect.top) / 2 }
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
} else if (viewportPos > rect.bottom) {
|
|
1640
|
+
const distance = Math.round((viewportPos - rect.bottom) / zoom);
|
|
1641
|
+
if (distance > 0) {
|
|
1642
|
+
measurements.push({
|
|
1643
|
+
direction: "vertical",
|
|
1644
|
+
x1: midX,
|
|
1645
|
+
y1: rect.bottom,
|
|
1646
|
+
x2: midX,
|
|
1647
|
+
y2: viewportPos,
|
|
1648
|
+
distance,
|
|
1649
|
+
labelPosition: { x: midX, y: (rect.bottom + viewportPos) / 2 }
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
} else {
|
|
1654
|
+
const midY = rect.top + rect.height / 2;
|
|
1655
|
+
if (mousePosition && Math.abs(mousePosition.x - viewportPos) > GUIDELINE_PROXIMITY) continue;
|
|
1656
|
+
if (viewportPos < rect.left) {
|
|
1657
|
+
const distance = Math.round((rect.left - viewportPos) / zoom);
|
|
1658
|
+
if (distance > 0) {
|
|
1659
|
+
measurements.push({
|
|
1660
|
+
direction: "horizontal",
|
|
1661
|
+
x1: viewportPos,
|
|
1662
|
+
y1: midY,
|
|
1663
|
+
x2: rect.left,
|
|
1664
|
+
y2: midY,
|
|
1665
|
+
distance,
|
|
1666
|
+
labelPosition: { x: (viewportPos + rect.left) / 2, y: midY }
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
} else if (viewportPos > rect.right) {
|
|
1670
|
+
const distance = Math.round((viewportPos - rect.right) / zoom);
|
|
1671
|
+
if (distance > 0) {
|
|
1672
|
+
measurements.push({
|
|
1673
|
+
direction: "horizontal",
|
|
1674
|
+
x1: rect.right,
|
|
1675
|
+
y1: midY,
|
|
1676
|
+
x2: viewportPos,
|
|
1677
|
+
y2: midY,
|
|
1678
|
+
distance,
|
|
1679
|
+
labelPosition: { x: (rect.right + viewportPos) / 2, y: midY }
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1658
1683
|
}
|
|
1659
|
-
filtered.push(line);
|
|
1660
|
-
}
|
|
1661
|
-
if (filtered.length > 0 && filtered[0].includes("fakeJSXCallSite")) {
|
|
1662
|
-
filtered.shift();
|
|
1663
1684
|
}
|
|
1664
|
-
return
|
|
1685
|
+
return measurements;
|
|
1665
1686
|
}
|
|
1666
|
-
function
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
const sanitizedResult = isWrappedLocation ? urlLike.slice(1, -1) : urlLike;
|
|
1670
|
-
const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(sanitizedResult);
|
|
1671
|
-
if (!parts) return [sanitizedResult, void 0, void 0];
|
|
1672
|
-
return [
|
|
1673
|
-
parts[1],
|
|
1674
|
-
parts[2] !== void 0 ? Number(parts[2]) : void 0,
|
|
1675
|
-
parts[3] !== void 0 ? Number(parts[3]) : void 0
|
|
1676
|
-
];
|
|
1687
|
+
function isFlexContainer(element) {
|
|
1688
|
+
const computed = window.getComputedStyle(element);
|
|
1689
|
+
return computed.display === "flex" || computed.display === "inline-flex";
|
|
1677
1690
|
}
|
|
1678
|
-
function
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
);
|
|
1691
|
-
const functionName = locationMatch && sanitizedLine ? sanitizedLine : void 0;
|
|
1692
|
-
if (fileName === "eval" || fileName === "<anonymous>") {
|
|
1691
|
+
function getFlexDirection(element) {
|
|
1692
|
+
const computed = window.getComputedStyle(element);
|
|
1693
|
+
return computed.flexDirection;
|
|
1694
|
+
}
|
|
1695
|
+
function isInFlowChild(el) {
|
|
1696
|
+
const cs = window.getComputedStyle(el);
|
|
1697
|
+
return cs.display !== "none" && cs.position !== "absolute" && cs.position !== "fixed";
|
|
1698
|
+
}
|
|
1699
|
+
function detectChildrenDirection(container, exclude) {
|
|
1700
|
+
const computed = window.getComputedStyle(container);
|
|
1701
|
+
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
1702
|
+
const dir = computed.flexDirection;
|
|
1693
1703
|
return {
|
|
1694
|
-
|
|
1704
|
+
axis: dir === "row" || dir === "row-reverse" ? "horizontal" : "vertical",
|
|
1705
|
+
reversed: dir === "row-reverse" || dir === "column-reverse"
|
|
1695
1706
|
};
|
|
1696
1707
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
|
|
1704
|
-
};
|
|
1705
|
-
}
|
|
1706
|
-
function parseFFOrSafariStackLine(line) {
|
|
1707
|
-
let currentLine = line;
|
|
1708
|
-
if (currentLine.includes(" > eval")) {
|
|
1709
|
-
currentLine = currentLine.replace(
|
|
1710
|
-
/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
|
|
1711
|
-
":$1"
|
|
1712
|
-
);
|
|
1708
|
+
const visible = [];
|
|
1709
|
+
for (const c of container.children) {
|
|
1710
|
+
if (!(c instanceof HTMLElement) || c === exclude) continue;
|
|
1711
|
+
if (!isInFlowChild(c)) continue;
|
|
1712
|
+
visible.push(c);
|
|
1713
|
+
if (visible.length === 2) break;
|
|
1713
1714
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1715
|
+
if (visible.length < 2) return { axis: "vertical", reversed: false };
|
|
1716
|
+
const first = visible[0].getBoundingClientRect();
|
|
1717
|
+
const second = visible[1].getBoundingClientRect();
|
|
1718
|
+
const yOverlap = first.bottom - 2 > second.top && second.bottom - 2 > first.top;
|
|
1719
|
+
if (yOverlap) {
|
|
1720
|
+
return { axis: "horizontal", reversed: second.right < first.left };
|
|
1717
1721
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1722
|
+
return { axis: "vertical", reversed: second.bottom < first.top };
|
|
1723
|
+
}
|
|
1724
|
+
function computeIntendedIndex(parent, draggedElement) {
|
|
1725
|
+
const { axis } = detectChildrenDirection(parent, draggedElement);
|
|
1726
|
+
const isHorizontal = axis === "horizontal";
|
|
1727
|
+
const draggedRect = draggedElement.getBoundingClientRect();
|
|
1728
|
+
const intendedCenter = isHorizontal ? draggedRect.left + draggedRect.width / 2 : draggedRect.top + draggedRect.height / 2;
|
|
1729
|
+
const siblings = [];
|
|
1730
|
+
for (const c of parent.children) {
|
|
1731
|
+
if (!(c instanceof HTMLElement) || c === draggedElement) continue;
|
|
1732
|
+
if (!isInFlowChild(c)) continue;
|
|
1733
|
+
siblings.push(c);
|
|
1724
1734
|
}
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
return null;
|
|
1735
|
+
if (siblings.length === 0) {
|
|
1736
|
+
return { index: 0, siblingBefore: null, siblingAfter: null };
|
|
1728
1737
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
source: currentLine,
|
|
1738
|
-
isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
|
|
1739
|
-
};
|
|
1738
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
1739
|
+
const rect = siblings[i].getBoundingClientRect();
|
|
1740
|
+
const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
|
|
1741
|
+
if (intendedCenter < midpoint) {
|
|
1742
|
+
return { index: i, siblingBefore: i > 0 ? siblings[i - 1] : null, siblingAfter: siblings[i] };
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
return { index: siblings.length, siblingBefore: siblings[siblings.length - 1], siblingAfter: null };
|
|
1740
1746
|
}
|
|
1741
|
-
function
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
functionName,
|
|
1746
|
-
source: line,
|
|
1747
|
-
isServer: line.includes(SERVER_FRAME_MARKER)
|
|
1748
|
-
};
|
|
1747
|
+
function htmlChildren(el) {
|
|
1748
|
+
return Array.from(el.children).filter(
|
|
1749
|
+
(child) => child instanceof HTMLElement
|
|
1750
|
+
);
|
|
1749
1751
|
}
|
|
1750
|
-
function
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
if (/^\s*at\s+/.test(rawLine)) {
|
|
1759
|
-
const parsed = parseV8StackLine(rawLine);
|
|
1760
|
-
if (parsed) frames.push(parsed);
|
|
1761
|
-
continue;
|
|
1762
|
-
}
|
|
1763
|
-
if (/^\s*in\s+/.test(rawLine)) {
|
|
1764
|
-
const parsed = parseInStackLine(rawLine);
|
|
1765
|
-
if (parsed) frames.push(parsed);
|
|
1752
|
+
function findFlexAncestor(element, boundary) {
|
|
1753
|
+
let current = element;
|
|
1754
|
+
while (current && current !== document.body) {
|
|
1755
|
+
const parent = current.parentElement;
|
|
1756
|
+
if (!parent) break;
|
|
1757
|
+
const display = getComputedStyle(parent).display;
|
|
1758
|
+
if (display === "flex" || display === "inline-flex") {
|
|
1759
|
+
return { flexParent: parent, child: current };
|
|
1766
1760
|
}
|
|
1761
|
+
if (boundary && parent === boundary) break;
|
|
1762
|
+
current = parent;
|
|
1767
1763
|
}
|
|
1768
|
-
return
|
|
1764
|
+
return null;
|
|
1769
1765
|
}
|
|
1770
|
-
function
|
|
1771
|
-
if (!
|
|
1772
|
-
|
|
1773
|
-
const isHttpUrl = normalized.startsWith("http://") || normalized.startsWith("https://");
|
|
1774
|
-
if (isHttpUrl) {
|
|
1775
|
-
try {
|
|
1776
|
-
normalized = new URL(normalized).pathname;
|
|
1777
|
-
} catch {
|
|
1778
|
-
}
|
|
1766
|
+
function computeHoverHighlight(elementUnder, selectedElement) {
|
|
1767
|
+
if (!elementUnder || elementUnder === document.body || elementUnder === document.documentElement || elementUnder.closest("[data-direct-edit]") || elementUnder.closest("[data-direct-edit-host]") || elementUnder === selectedElement) {
|
|
1768
|
+
return null;
|
|
1779
1769
|
}
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
if (normalized.startsWith(prefix)) {
|
|
1785
|
-
normalized = normalized.slice(prefix.length);
|
|
1786
|
-
if (prefix === "file:///") {
|
|
1787
|
-
normalized = `/${normalized.replace(/^\/+/, "")}`;
|
|
1788
|
-
}
|
|
1789
|
-
didStripPrefix = true;
|
|
1790
|
-
break;
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1770
|
+
const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
|
|
1771
|
+
const ownDisplay = getComputedStyle(elementUnder).display;
|
|
1772
|
+
if (ownDisplay === "flex" || ownDisplay === "inline-flex") {
|
|
1773
|
+
return { flexContainer: elementUnder, children: htmlChildren(elementUnder) };
|
|
1793
1774
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
normalized = normalized.slice(0, queryIndex);
|
|
1775
|
+
const found = findFlexAncestor(elementUnder, boundary);
|
|
1776
|
+
if (found) {
|
|
1777
|
+
return { flexContainer: found.flexParent, children: htmlChildren(found.flexParent) };
|
|
1798
1778
|
}
|
|
1799
|
-
return
|
|
1779
|
+
return { flexContainer: elementUnder, children: [] };
|
|
1800
1780
|
}
|
|
1801
|
-
function
|
|
1802
|
-
const
|
|
1803
|
-
|
|
1804
|
-
if (
|
|
1805
|
-
return
|
|
1781
|
+
function resolveElementTarget(elementUnder, selectedElement) {
|
|
1782
|
+
const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
|
|
1783
|
+
const found = findFlexAncestor(elementUnder, boundary);
|
|
1784
|
+
if (found && found.flexParent === boundary) return elementUnder;
|
|
1785
|
+
return found?.child ?? elementUnder;
|
|
1806
1786
|
}
|
|
1807
|
-
function
|
|
1808
|
-
const
|
|
1809
|
-
const
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1787
|
+
function findTextOwnerAtPoint(boundary, clientX, clientY) {
|
|
1788
|
+
const doc = document;
|
|
1789
|
+
const caretNode = doc.caretPositionFromPoint?.(clientX, clientY)?.offsetNode ?? doc.caretRangeFromPoint?.(clientX, clientY)?.startContainer ?? null;
|
|
1790
|
+
if (!caretNode || caretNode.nodeType !== Node.TEXT_NODE) return null;
|
|
1791
|
+
const textNode = caretNode;
|
|
1792
|
+
if (!(textNode.nodeValue ?? "").trim()) return null;
|
|
1793
|
+
const owner = textNode.parentElement;
|
|
1794
|
+
if (!owner || !boundary.contains(owner)) return null;
|
|
1795
|
+
if (owner.closest("[data-direct-edit]") || owner.closest("[data-direct-edit-host]")) return null;
|
|
1796
|
+
const range = document.createRange();
|
|
1797
|
+
range.selectNodeContents(textNode);
|
|
1798
|
+
const hitsText = Array.from(range.getClientRects()).some(
|
|
1799
|
+
(r) => clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom
|
|
1800
|
+
);
|
|
1801
|
+
range.detach?.();
|
|
1802
|
+
return hitsText ? owner : null;
|
|
1803
|
+
}
|
|
1804
|
+
function findTextOwnerByRangeScan(boundary, clientX, clientY) {
|
|
1805
|
+
const walker = document.createTreeWalker(boundary, NodeFilter.SHOW_TEXT);
|
|
1806
|
+
let current = walker.nextNode();
|
|
1807
|
+
while (current) {
|
|
1808
|
+
const textNode = current;
|
|
1809
|
+
if ((textNode.nodeValue ?? "").trim()) {
|
|
1810
|
+
const owner = textNode.parentElement;
|
|
1811
|
+
if (owner && boundary.contains(owner) && !owner.closest("[data-direct-edit]") && !owner.closest("[data-direct-edit-host]")) {
|
|
1812
|
+
const range = document.createRange();
|
|
1813
|
+
range.selectNodeContents(textNode);
|
|
1814
|
+
const hitsText = Array.from(range.getClientRects()).some(
|
|
1815
|
+
(r) => clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom
|
|
1825
1816
|
);
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
fileName: normalized,
|
|
1829
|
-
lineNumber: frame.lineNumber,
|
|
1830
|
-
columnNumber: frame.columnNumber
|
|
1831
|
-
});
|
|
1832
|
-
functionNameToRscFrames.set(frame.functionName, existing);
|
|
1833
|
-
}
|
|
1817
|
+
range.detach?.();
|
|
1818
|
+
if (hitsText) return owner;
|
|
1834
1819
|
}
|
|
1835
1820
|
}
|
|
1836
|
-
current =
|
|
1821
|
+
current = walker.nextNode();
|
|
1837
1822
|
}
|
|
1838
|
-
return
|
|
1839
|
-
}
|
|
1840
|
-
function enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) {
|
|
1841
|
-
if (!frame.functionName) return frame;
|
|
1842
|
-
const available = functionNameToRscFrames.get(frame.functionName);
|
|
1843
|
-
if (!available) return frame;
|
|
1844
|
-
const usageIndex = functionNameToUsageIndex.get(frame.functionName) ?? 0;
|
|
1845
|
-
const resolved = available[usageIndex % available.length];
|
|
1846
|
-
functionNameToUsageIndex.set(frame.functionName, usageIndex + 1);
|
|
1847
|
-
return {
|
|
1848
|
-
...frame,
|
|
1849
|
-
fileName: resolved.fileName,
|
|
1850
|
-
lineNumber: resolved.lineNumber,
|
|
1851
|
-
columnNumber: resolved.columnNumber
|
|
1852
|
-
};
|
|
1823
|
+
return null;
|
|
1853
1824
|
}
|
|
1854
|
-
function
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
fileName: normalizedFileName,
|
|
1872
|
-
lineNumber: maybeEnriched.lineNumber,
|
|
1873
|
-
columnNumber: maybeEnriched.columnNumber
|
|
1874
|
-
};
|
|
1875
|
-
}
|
|
1825
|
+
function ensureDirectTextSpanAtPoint(parent, clientX, clientY) {
|
|
1826
|
+
const directTextNodes = Array.from(parent.childNodes).filter(
|
|
1827
|
+
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
1828
|
+
);
|
|
1829
|
+
for (const textNode of directTextNodes) {
|
|
1830
|
+
const range = document.createRange();
|
|
1831
|
+
range.selectNodeContents(textNode);
|
|
1832
|
+
const hitsText = Array.from(range.getClientRects()).some(
|
|
1833
|
+
(r) => clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom
|
|
1834
|
+
);
|
|
1835
|
+
range.detach?.();
|
|
1836
|
+
if (!hitsText) continue;
|
|
1837
|
+
const span = document.createElement("span");
|
|
1838
|
+
span.setAttribute("data-direct-edit-generated", "text-span");
|
|
1839
|
+
span.textContent = textNode.textContent ?? "";
|
|
1840
|
+
parent.replaceChild(span, textNode);
|
|
1841
|
+
return span;
|
|
1876
1842
|
}
|
|
1877
1843
|
return null;
|
|
1878
1844
|
}
|
|
1879
|
-
function
|
|
1880
|
-
const
|
|
1881
|
-
if (
|
|
1882
|
-
const
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
if (
|
|
1887
|
-
|
|
1888
|
-
if (pending?.fileName) return pending;
|
|
1889
|
-
const memo = fiber?.memoizedProps?.__source;
|
|
1890
|
-
if (memo?.fileName) return memo;
|
|
1891
|
-
const fromDebugStack = getSourceFromDebugStack(fiber);
|
|
1892
|
-
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
1845
|
+
function findChildAtPoint(parent, clientX, clientY) {
|
|
1846
|
+
const children = htmlChildren(parent);
|
|
1847
|
+
if (children.length === 0) return null;
|
|
1848
|
+
const hit = children.find((child) => {
|
|
1849
|
+
const r = child.getBoundingClientRect();
|
|
1850
|
+
return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
|
|
1851
|
+
});
|
|
1852
|
+
if (hit) return hit;
|
|
1853
|
+
if (children.length === 1 && !hasDirectNonWhitespaceText(parent)) return children[0];
|
|
1893
1854
|
return null;
|
|
1894
1855
|
}
|
|
1895
|
-
function
|
|
1896
|
-
const
|
|
1897
|
-
if (
|
|
1898
|
-
const
|
|
1899
|
-
if (
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1856
|
+
function elementFromPointWithoutOverlays(x, y) {
|
|
1857
|
+
const host = document.querySelector("[data-direct-edit-host]");
|
|
1858
|
+
if (host) host.style.display = "none";
|
|
1859
|
+
const el = document.elementFromPoint(x, y);
|
|
1860
|
+
if (host) host.style.display = "";
|
|
1861
|
+
return el;
|
|
1862
|
+
}
|
|
1863
|
+
function isLayoutContainer(element) {
|
|
1864
|
+
const display = window.getComputedStyle(element).display;
|
|
1865
|
+
return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
|
|
1866
|
+
}
|
|
1867
|
+
function isBlockContainer(element) {
|
|
1868
|
+
const display = window.getComputedStyle(element).display;
|
|
1869
|
+
return display === "block" || display === "flow-root" || display === "inline-block" || display === "list-item";
|
|
1870
|
+
}
|
|
1871
|
+
function skipElement(el, exclude) {
|
|
1872
|
+
if (exclude && exclude.contains(el)) return true;
|
|
1873
|
+
if (el === document.body || el === document.documentElement) return true;
|
|
1874
|
+
if (el.closest("[data-direct-edit]") || el.closest("[data-direct-edit-host]")) return true;
|
|
1875
|
+
return false;
|
|
1876
|
+
}
|
|
1877
|
+
function findContainerViaTraversal(x, y, exclude) {
|
|
1878
|
+
const el = elementFromPointWithoutOverlays(x, y);
|
|
1879
|
+
if (!el) return null;
|
|
1880
|
+
let current = el;
|
|
1881
|
+
while (current) {
|
|
1882
|
+
if (!skipElement(current, exclude)) {
|
|
1883
|
+
if (isLayoutContainer(current) || isBlockContainer(current)) return current;
|
|
1909
1884
|
}
|
|
1885
|
+
current = current.parentElement;
|
|
1910
1886
|
}
|
|
1911
|
-
return
|
|
1887
|
+
return null;
|
|
1912
1888
|
}
|
|
1913
|
-
function
|
|
1914
|
-
|
|
1915
|
-
if (
|
|
1916
|
-
|
|
1917
|
-
if (
|
|
1918
|
-
|
|
1919
|
-
|
|
1889
|
+
function findContainerAtPoint(x, y, exclude, preferredParent) {
|
|
1890
|
+
const host = document.querySelector("[data-direct-edit-host]");
|
|
1891
|
+
if (host) host.style.display = "none";
|
|
1892
|
+
const elements = document.elementsFromPoint(x, y);
|
|
1893
|
+
if (host) host.style.display = "";
|
|
1894
|
+
for (const el of elements) {
|
|
1895
|
+
if (skipElement(el, exclude)) continue;
|
|
1896
|
+
if (isLayoutContainer(el) || isBlockContainer(el)) return el;
|
|
1920
1897
|
}
|
|
1921
|
-
|
|
1898
|
+
if (preferredParent && (isLayoutContainer(preferredParent) || isBlockContainer(preferredParent))) {
|
|
1899
|
+
for (const el of elements) {
|
|
1900
|
+
if (el === preferredParent) return preferredParent;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
return findContainerViaTraversal(x, y, exclude);
|
|
1922
1904
|
}
|
|
1923
|
-
function
|
|
1924
|
-
const
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
if (
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
}
|
|
1905
|
+
function findLayoutContainerAtPoint(x, y, exclude, preferredParent) {
|
|
1906
|
+
const host = document.querySelector("[data-direct-edit-host]");
|
|
1907
|
+
if (host) host.style.display = "none";
|
|
1908
|
+
const elements = document.elementsFromPoint(x, y);
|
|
1909
|
+
if (host) host.style.display = "";
|
|
1910
|
+
for (const el of elements) {
|
|
1911
|
+
if (skipElement(el, exclude)) continue;
|
|
1912
|
+
if (isLayoutContainer(el)) return el;
|
|
1913
|
+
}
|
|
1914
|
+
if (preferredParent && isLayoutContainer(preferredParent)) {
|
|
1915
|
+
for (const el of elements) {
|
|
1916
|
+
if (el === preferredParent) return preferredParent;
|
|
1936
1917
|
}
|
|
1937
|
-
current = current._debugOwner;
|
|
1938
1918
|
}
|
|
1939
|
-
return
|
|
1919
|
+
return null;
|
|
1940
1920
|
}
|
|
1941
|
-
function
|
|
1942
|
-
const
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1921
|
+
function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
1922
|
+
const { axis, reversed: isReversed } = detectChildrenDirection(container, draggedElement);
|
|
1923
|
+
const isHorizontal = axis === "horizontal";
|
|
1924
|
+
const children = Array.from(container.children).filter(
|
|
1925
|
+
(child) => child !== draggedElement && child instanceof HTMLElement
|
|
1926
|
+
);
|
|
1927
|
+
if (children.length === 0) {
|
|
1928
|
+
const containerRect2 = container.getBoundingClientRect();
|
|
1929
|
+
return {
|
|
1930
|
+
insertBefore: null,
|
|
1931
|
+
indicator: {
|
|
1932
|
+
x: containerRect2.left + 4,
|
|
1933
|
+
y: containerRect2.top + 4,
|
|
1934
|
+
width: isHorizontal ? 1 : containerRect2.width - 8,
|
|
1935
|
+
height: isHorizontal ? containerRect2.height - 8 : 1
|
|
1953
1936
|
}
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
const containerRect = container.getBoundingClientRect();
|
|
1940
|
+
let insertBefore = null;
|
|
1941
|
+
let indicatorPosition = 0;
|
|
1942
|
+
for (let i = 0; i < children.length; i++) {
|
|
1943
|
+
const child = children[i];
|
|
1944
|
+
const rect = child.getBoundingClientRect();
|
|
1945
|
+
const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
|
|
1946
|
+
const pointer = isHorizontal ? pointerX : pointerY;
|
|
1947
|
+
const beforeMidpoint = isReversed ? pointer > midpoint : pointer < midpoint;
|
|
1948
|
+
if (beforeMidpoint) {
|
|
1949
|
+
insertBefore = child;
|
|
1950
|
+
indicatorPosition = isHorizontal ? rect.left : rect.top;
|
|
1951
|
+
break;
|
|
1954
1952
|
}
|
|
1955
|
-
current = current.return;
|
|
1956
1953
|
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
if (!fiber) return { frames: [], nearestComponentFiber: null };
|
|
1962
|
-
const elementSource = getSourceFromFiber(fiber);
|
|
1963
|
-
const elementSourceFile = elementSource?.fileName || void 0;
|
|
1964
|
-
const ownerResult = getOwnerStack(fiber);
|
|
1965
|
-
if (ownerResult.frames.length > 0) {
|
|
1966
|
-
return { ...ownerResult, elementSourceFile };
|
|
1954
|
+
if (!insertBefore) {
|
|
1955
|
+
const lastChild = children[children.length - 1];
|
|
1956
|
+
const lastRect = lastChild.getBoundingClientRect();
|
|
1957
|
+
indicatorPosition = isHorizontal ? lastRect.right : lastRect.bottom;
|
|
1967
1958
|
}
|
|
1968
|
-
|
|
1959
|
+
const indicator = isHorizontal ? {
|
|
1960
|
+
x: indicatorPosition,
|
|
1961
|
+
y: containerRect.top + 4,
|
|
1962
|
+
width: 2,
|
|
1963
|
+
height: containerRect.height - 8
|
|
1964
|
+
} : {
|
|
1965
|
+
x: containerRect.left + 4,
|
|
1966
|
+
y: indicatorPosition,
|
|
1967
|
+
width: containerRect.width - 8,
|
|
1968
|
+
height: 2
|
|
1969
|
+
};
|
|
1970
|
+
return { insertBefore, indicator };
|
|
1969
1971
|
}
|
|
1970
1972
|
function getElementDisplayName(element) {
|
|
1971
1973
|
const tag = element.tagName.toLowerCase();
|