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