@fluixi/devtools 0.2.0-alpha.3 → 0.2.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/callsite.cjs +72 -0
- package/dist/callsite.mjs +51 -0
- package/dist/change-view.cjs +134 -0
- package/dist/change-view.mjs +111 -0
- package/dist/copy.cjs +63 -0
- package/dist/copy.mjs +42 -0
- package/dist/describe.cjs +55 -0
- package/dist/describe.mjs +34 -0
- package/dist/detail-panel.cjs +307 -0
- package/dist/detail-panel.mjs +284 -0
- package/dist/diff.cjs +225 -0
- package/dist/diff.mjs +202 -0
- package/dist/dom.cjs +204 -0
- package/dist/dom.mjs +183 -0
- package/dist/export.cjs +221 -0
- package/dist/export.mjs +209 -0
- package/dist/float.cjs +232 -0
- package/dist/float.mjs +211 -0
- package/dist/format.cjs +175 -0
- package/dist/format.mjs +154 -0
- package/dist/graph-view.cjs +893 -0
- package/dist/graph-view.mjs +870 -0
- package/dist/highlight.cjs +140 -0
- package/dist/highlight.mjs +119 -0
- package/dist/history.cjs +95 -0
- package/dist/history.mjs +74 -0
- package/dist/hook.cjs +1562 -0
- package/dist/hook.mjs +1553 -0
- package/dist/index.cjs +4552 -0
- package/dist/index.mjs +4544 -0
- package/dist/inspector.cjs +688 -0
- package/dist/inspector.mjs +676 -0
- package/dist/instrument.cjs +497 -0
- package/dist/instrument.mjs +487 -0
- package/dist/kind-filter.cjs +172 -0
- package/dist/kind-filter.mjs +151 -0
- package/dist/menu.cjs +141 -0
- package/dist/menu.mjs +120 -0
- package/dist/observe.cjs +1352 -0
- package/dist/observe.mjs +1345 -0
- package/dist/palette.cjs +52 -0
- package/dist/palette.mjs +31 -0
- package/dist/path.cjs +45 -0
- package/dist/path.mjs +24 -0
- package/dist/plugin.cjs +87 -0
- package/dist/plugin.mjs +66 -0
- package/dist/plugins/context.cjs +98 -0
- package/dist/plugins/context.mjs +75 -0
- package/dist/plugins/directives.cjs +98 -0
- package/dist/plugins/directives.mjs +75 -0
- package/dist/plugins/index.cjs +162 -0
- package/dist/plugins/index.mjs +140 -0
- package/dist/source.cjs +111 -0
- package/dist/source.mjs +90 -0
- package/dist/timeline.cjs +350 -0
- package/dist/timeline.mjs +327 -0
- package/dist/tree.cjs +574 -0
- package/dist/tree.mjs +551 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/value-pane.cjs +223 -0
- package/dist/value-pane.mjs +200 -0
- package/dist/wire.cjs +109 -0
- package/dist/wire.mjs +89 -0
- package/package.json +13 -6
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/callsite.ts
|
|
21
|
+
var callsite_exports = {};
|
|
22
|
+
__export(callsite_exports, {
|
|
23
|
+
callSite: () => callSite,
|
|
24
|
+
currentCallSite: () => currentCallSite
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(callsite_exports);
|
|
27
|
+
var EXTENSION = ["chrome-extension://", "moz-extension://", "safari-web-extension://", "extension://"];
|
|
28
|
+
var INTERNAL = [
|
|
29
|
+
"/packages/reactive/",
|
|
30
|
+
"/packages/dom/",
|
|
31
|
+
"/packages/core/",
|
|
32
|
+
"/packages/devtools/",
|
|
33
|
+
"/@fluixi/",
|
|
34
|
+
"node_modules",
|
|
35
|
+
"fluixi-devtools",
|
|
36
|
+
...EXTENSION
|
|
37
|
+
];
|
|
38
|
+
var REPORTING = [
|
|
39
|
+
"/packages/reactive/src/lib/signal/graph/",
|
|
40
|
+
"/packages/devtools/",
|
|
41
|
+
"fluixi-devtools",
|
|
42
|
+
// Not a fallback either: naming the agent as where a node came from is worse than nothing.
|
|
43
|
+
...EXTENSION
|
|
44
|
+
];
|
|
45
|
+
var FRAME = /(?:at\s+(?:[^(]*\()?)([^()\s]+):(\d+):(\d+)\)?$/;
|
|
46
|
+
var isInternal = (frame) => INTERNAL.some((part) => frame.includes(part));
|
|
47
|
+
function locate(frame, origin) {
|
|
48
|
+
const match = FRAME.exec(frame);
|
|
49
|
+
if (!match) return void 0;
|
|
50
|
+
let file = match[1];
|
|
51
|
+
if (origin && file.startsWith(origin)) file = file.slice(origin.length);
|
|
52
|
+
file = file.replace(/^\/@fs\//, "/").replace(/\?.*$/, "").replace(/^\//, "");
|
|
53
|
+
return file ? { file, line: Number(match[2]), column: Number(match[3]) } : void 0;
|
|
54
|
+
}
|
|
55
|
+
function callSite(stack, origin) {
|
|
56
|
+
if (!stack) return void 0;
|
|
57
|
+
let fallback;
|
|
58
|
+
for (const line of stack.split("\n")) {
|
|
59
|
+
const frame = line.trim();
|
|
60
|
+
if (!frame.startsWith("at ")) continue;
|
|
61
|
+
if (!isInternal(frame)) {
|
|
62
|
+
const location = locate(frame, origin);
|
|
63
|
+
if (location) return { location, external: false };
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!fallback && !REPORTING.some((part) => frame.includes(part))) fallback = locate(frame, origin);
|
|
67
|
+
}
|
|
68
|
+
return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
|
|
69
|
+
}
|
|
70
|
+
function currentCallSite(origin) {
|
|
71
|
+
return callSite(new Error().stack, origin);
|
|
72
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/callsite.ts
|
|
2
|
+
var EXTENSION = ["chrome-extension://", "moz-extension://", "safari-web-extension://", "extension://"];
|
|
3
|
+
var INTERNAL = [
|
|
4
|
+
"/packages/reactive/",
|
|
5
|
+
"/packages/dom/",
|
|
6
|
+
"/packages/core/",
|
|
7
|
+
"/packages/devtools/",
|
|
8
|
+
"/@fluixi/",
|
|
9
|
+
"node_modules",
|
|
10
|
+
"fluixi-devtools",
|
|
11
|
+
...EXTENSION
|
|
12
|
+
];
|
|
13
|
+
var REPORTING = [
|
|
14
|
+
"/packages/reactive/src/lib/signal/graph/",
|
|
15
|
+
"/packages/devtools/",
|
|
16
|
+
"fluixi-devtools",
|
|
17
|
+
// Not a fallback either: naming the agent as where a node came from is worse than nothing.
|
|
18
|
+
...EXTENSION
|
|
19
|
+
];
|
|
20
|
+
var FRAME = /(?:at\s+(?:[^(]*\()?)([^()\s]+):(\d+):(\d+)\)?$/;
|
|
21
|
+
var isInternal = (frame) => INTERNAL.some((part) => frame.includes(part));
|
|
22
|
+
function locate(frame, origin) {
|
|
23
|
+
const match = FRAME.exec(frame);
|
|
24
|
+
if (!match) return void 0;
|
|
25
|
+
let file = match[1];
|
|
26
|
+
if (origin && file.startsWith(origin)) file = file.slice(origin.length);
|
|
27
|
+
file = file.replace(/^\/@fs\//, "/").replace(/\?.*$/, "").replace(/^\//, "");
|
|
28
|
+
return file ? { file, line: Number(match[2]), column: Number(match[3]) } : void 0;
|
|
29
|
+
}
|
|
30
|
+
function callSite(stack, origin) {
|
|
31
|
+
if (!stack) return void 0;
|
|
32
|
+
let fallback;
|
|
33
|
+
for (const line of stack.split("\n")) {
|
|
34
|
+
const frame = line.trim();
|
|
35
|
+
if (!frame.startsWith("at ")) continue;
|
|
36
|
+
if (!isInternal(frame)) {
|
|
37
|
+
const location = locate(frame, origin);
|
|
38
|
+
if (location) return { location, external: false };
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (!fallback && !REPORTING.some((part) => frame.includes(part))) fallback = locate(frame, origin);
|
|
42
|
+
}
|
|
43
|
+
return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
|
|
44
|
+
}
|
|
45
|
+
function currentCallSite(origin) {
|
|
46
|
+
return callSite(new Error().stack, origin);
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
callSite,
|
|
50
|
+
currentCallSite
|
|
51
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/change-view.ts
|
|
21
|
+
var change_view_exports = {};
|
|
22
|
+
__export(change_view_exports, {
|
|
23
|
+
CHANGE_CSS: () => CHANGE_CSS,
|
|
24
|
+
changeRows: () => changeRows,
|
|
25
|
+
handleCopyClick: () => handleCopyClick
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(change_view_exports);
|
|
28
|
+
|
|
29
|
+
// src/copy.ts
|
|
30
|
+
function confirmOn(button, said = "copied") {
|
|
31
|
+
if (!button) return;
|
|
32
|
+
const was = button.textContent;
|
|
33
|
+
button.textContent = said;
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
button.textContent = was;
|
|
36
|
+
}, 1200);
|
|
37
|
+
}
|
|
38
|
+
function fallback(text, button) {
|
|
39
|
+
try {
|
|
40
|
+
const doc = button?.ownerDocument ?? document;
|
|
41
|
+
const area = doc.createElement("textarea");
|
|
42
|
+
area.value = text;
|
|
43
|
+
area.setAttribute("readonly", "");
|
|
44
|
+
area.style.position = "fixed";
|
|
45
|
+
area.style.opacity = "0";
|
|
46
|
+
doc.body.appendChild(area);
|
|
47
|
+
area.select();
|
|
48
|
+
doc.execCommand("copy");
|
|
49
|
+
area.remove();
|
|
50
|
+
confirmOn(button);
|
|
51
|
+
return true;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function copyText(text, button) {
|
|
57
|
+
const clipboard = globalThis.navigator?.clipboard;
|
|
58
|
+
if (clipboard?.writeText) {
|
|
59
|
+
try {
|
|
60
|
+
await clipboard.writeText(text);
|
|
61
|
+
confirmOn(button);
|
|
62
|
+
return true;
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return fallback(text, button);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/change-view.ts
|
|
70
|
+
var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
71
|
+
var SIGN = { added: "+", removed: "−", changed: "~" };
|
|
72
|
+
function pretty(json) {
|
|
73
|
+
if (!json) return void 0;
|
|
74
|
+
try {
|
|
75
|
+
return JSON.stringify(JSON.parse(json), null, 2);
|
|
76
|
+
} catch {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function sideOf(text, json, cls) {
|
|
81
|
+
const block = pretty(json);
|
|
82
|
+
if (!block) return `<span class="ch-${cls}">${escape(text ?? "")}</span>`;
|
|
83
|
+
return `<div class="ch-block ch-${cls}"><button type="button" class="ch-copy" title="Copy" data-copy="${escape(block)}">copy</button><pre class="ch-json">${escape(block)}</pre></div>`;
|
|
84
|
+
}
|
|
85
|
+
function changeRows(change, limit = Infinity) {
|
|
86
|
+
if (!change?.entries?.length) return "";
|
|
87
|
+
const shown = change.entries.slice(0, limit);
|
|
88
|
+
const hidden = change.entries.length - shown.length + (change.more ?? 0);
|
|
89
|
+
const rows = shown.map((entry) => {
|
|
90
|
+
const from = sideOf(entry.from, entry.fromJson, "from");
|
|
91
|
+
const to = sideOf(entry.to, entry.toJson, "to");
|
|
92
|
+
const sides = entry.op === "changed" ? `${from}<span class="ch-arrow">→</span>${to}` : entry.op === "added" ? to : from;
|
|
93
|
+
const stacked = entry.fromJson || entry.toJson ? " ch-stacked" : "";
|
|
94
|
+
return `<div class="ch-row ch-${entry.op}${stacked}"><span class="ch-sign">${SIGN[entry.op] ?? "·"}</span><span class="ch-key">${escape(entry.key)}</span><span class="ch-sides">${sides}</span></div>`;
|
|
95
|
+
}).join("");
|
|
96
|
+
const size = change.length ? `<div class="ch-size">${change.length.from} → ${change.length.to} items</div>` : "";
|
|
97
|
+
return `<div class="ch-list">${size}${rows}${hidden > 0 ? `<div class="ch-more">and ${hidden} more</div>` : ""}</div>`;
|
|
98
|
+
}
|
|
99
|
+
function handleCopyClick(event) {
|
|
100
|
+
const button = event.target?.closest?.(".ch-copy");
|
|
101
|
+
if (!button) return false;
|
|
102
|
+
void copyText(button.dataset.copy ?? "", button);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
var CHANGE_CSS = `
|
|
106
|
+
.ch-list { margin-top: 4px; font-family: ui-monospace, monospace; font-size: 11px; }
|
|
107
|
+
.ch-size { color: var(--fx-muted, #8a90a2); margin-bottom: 2px; }
|
|
108
|
+
.ch-row { display: flex; gap: 6px; align-items: baseline; padding: 1px 0; }
|
|
109
|
+
.ch-row.ch-stacked { align-items: flex-start; padding: 3px 0; }
|
|
110
|
+
.ch-sign { flex: none; width: 9px; text-align: center; }
|
|
111
|
+
.ch-added .ch-sign { color: var(--state, #34d399); }
|
|
112
|
+
.ch-removed .ch-sign { color: var(--fx-write, #fb7185); }
|
|
113
|
+
.ch-changed .ch-sign { color: var(--effect, #fbbf24); }
|
|
114
|
+
.ch-key { flex: none; color: var(--fx-muted, #8a90a2); }
|
|
115
|
+
.ch-sides { min-width: 0; flex: 1; overflow-wrap: anywhere; }
|
|
116
|
+
.ch-stacked .ch-sides { display: flex; flex-direction: column; gap: 2px; }
|
|
117
|
+
.ch-from { color: var(--fx-muted, #8a90a2); }
|
|
118
|
+
.ch-row:not(.ch-stacked) .ch-from { text-decoration: line-through; }
|
|
119
|
+
.ch-arrow { color: var(--fx-muted, #8a90a2); margin: 0 4px; }
|
|
120
|
+
.ch-to { color: var(--fx-label, #e7e9ee); }
|
|
121
|
+
.ch-more { color: var(--fx-muted, #8a90a2); margin-top: 2px; }
|
|
122
|
+
/* In the corner: an object can be tall, and a button under it is a scroll away. */
|
|
123
|
+
.ch-block { position: relative; border-radius: 4px; border: 1px solid var(--fx-line, #ffffff14); }
|
|
124
|
+
.ch-block.ch-from { opacity: .72; }
|
|
125
|
+
.ch-json { margin: 0; padding: 5px 7px; overflow-x: auto; white-space: pre; font: inherit; }
|
|
126
|
+
.ch-copy {
|
|
127
|
+
position: absolute; top: 3px; right: 3px; padding: 1px 6px; cursor: pointer;
|
|
128
|
+
font: inherit; font-size: 9.5px; opacity: 0; transition: opacity .12s;
|
|
129
|
+
border: 1px solid var(--fx-line, #ffffff26); border-radius: 3px;
|
|
130
|
+
background: var(--fx-panel, #14161c); color: var(--fx-muted, #8a90a2);
|
|
131
|
+
}
|
|
132
|
+
.ch-block:hover .ch-copy, .ch-copy:focus { opacity: 1; }
|
|
133
|
+
.ch-copy:hover { color: var(--fx-label, #e7e9ee); }
|
|
134
|
+
`;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/copy.ts
|
|
2
|
+
function confirmOn(button, said = "copied") {
|
|
3
|
+
if (!button) return;
|
|
4
|
+
const was = button.textContent;
|
|
5
|
+
button.textContent = said;
|
|
6
|
+
setTimeout(() => {
|
|
7
|
+
button.textContent = was;
|
|
8
|
+
}, 1200);
|
|
9
|
+
}
|
|
10
|
+
function fallback(text, button) {
|
|
11
|
+
try {
|
|
12
|
+
const doc = button?.ownerDocument ?? document;
|
|
13
|
+
const area = doc.createElement("textarea");
|
|
14
|
+
area.value = text;
|
|
15
|
+
area.setAttribute("readonly", "");
|
|
16
|
+
area.style.position = "fixed";
|
|
17
|
+
area.style.opacity = "0";
|
|
18
|
+
doc.body.appendChild(area);
|
|
19
|
+
area.select();
|
|
20
|
+
doc.execCommand("copy");
|
|
21
|
+
area.remove();
|
|
22
|
+
confirmOn(button);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function copyText(text, button) {
|
|
29
|
+
const clipboard = globalThis.navigator?.clipboard;
|
|
30
|
+
if (clipboard?.writeText) {
|
|
31
|
+
try {
|
|
32
|
+
await clipboard.writeText(text);
|
|
33
|
+
confirmOn(button);
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return fallback(text, button);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/change-view.ts
|
|
42
|
+
var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
43
|
+
var SIGN = { added: "+", removed: "−", changed: "~" };
|
|
44
|
+
function pretty(json) {
|
|
45
|
+
if (!json) return void 0;
|
|
46
|
+
try {
|
|
47
|
+
return JSON.stringify(JSON.parse(json), null, 2);
|
|
48
|
+
} catch {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function sideOf(text, json, cls) {
|
|
53
|
+
const block = pretty(json);
|
|
54
|
+
if (!block) return `<span class="ch-${cls}">${escape(text ?? "")}</span>`;
|
|
55
|
+
return `<div class="ch-block ch-${cls}"><button type="button" class="ch-copy" title="Copy" data-copy="${escape(block)}">copy</button><pre class="ch-json">${escape(block)}</pre></div>`;
|
|
56
|
+
}
|
|
57
|
+
function changeRows(change, limit = Infinity) {
|
|
58
|
+
if (!change?.entries?.length) return "";
|
|
59
|
+
const shown = change.entries.slice(0, limit);
|
|
60
|
+
const hidden = change.entries.length - shown.length + (change.more ?? 0);
|
|
61
|
+
const rows = shown.map((entry) => {
|
|
62
|
+
const from = sideOf(entry.from, entry.fromJson, "from");
|
|
63
|
+
const to = sideOf(entry.to, entry.toJson, "to");
|
|
64
|
+
const sides = entry.op === "changed" ? `${from}<span class="ch-arrow">→</span>${to}` : entry.op === "added" ? to : from;
|
|
65
|
+
const stacked = entry.fromJson || entry.toJson ? " ch-stacked" : "";
|
|
66
|
+
return `<div class="ch-row ch-${entry.op}${stacked}"><span class="ch-sign">${SIGN[entry.op] ?? "·"}</span><span class="ch-key">${escape(entry.key)}</span><span class="ch-sides">${sides}</span></div>`;
|
|
67
|
+
}).join("");
|
|
68
|
+
const size = change.length ? `<div class="ch-size">${change.length.from} → ${change.length.to} items</div>` : "";
|
|
69
|
+
return `<div class="ch-list">${size}${rows}${hidden > 0 ? `<div class="ch-more">and ${hidden} more</div>` : ""}</div>`;
|
|
70
|
+
}
|
|
71
|
+
function handleCopyClick(event) {
|
|
72
|
+
const button = event.target?.closest?.(".ch-copy");
|
|
73
|
+
if (!button) return false;
|
|
74
|
+
void copyText(button.dataset.copy ?? "", button);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
var CHANGE_CSS = `
|
|
78
|
+
.ch-list { margin-top: 4px; font-family: ui-monospace, monospace; font-size: 11px; }
|
|
79
|
+
.ch-size { color: var(--fx-muted, #8a90a2); margin-bottom: 2px; }
|
|
80
|
+
.ch-row { display: flex; gap: 6px; align-items: baseline; padding: 1px 0; }
|
|
81
|
+
.ch-row.ch-stacked { align-items: flex-start; padding: 3px 0; }
|
|
82
|
+
.ch-sign { flex: none; width: 9px; text-align: center; }
|
|
83
|
+
.ch-added .ch-sign { color: var(--state, #34d399); }
|
|
84
|
+
.ch-removed .ch-sign { color: var(--fx-write, #fb7185); }
|
|
85
|
+
.ch-changed .ch-sign { color: var(--effect, #fbbf24); }
|
|
86
|
+
.ch-key { flex: none; color: var(--fx-muted, #8a90a2); }
|
|
87
|
+
.ch-sides { min-width: 0; flex: 1; overflow-wrap: anywhere; }
|
|
88
|
+
.ch-stacked .ch-sides { display: flex; flex-direction: column; gap: 2px; }
|
|
89
|
+
.ch-from { color: var(--fx-muted, #8a90a2); }
|
|
90
|
+
.ch-row:not(.ch-stacked) .ch-from { text-decoration: line-through; }
|
|
91
|
+
.ch-arrow { color: var(--fx-muted, #8a90a2); margin: 0 4px; }
|
|
92
|
+
.ch-to { color: var(--fx-label, #e7e9ee); }
|
|
93
|
+
.ch-more { color: var(--fx-muted, #8a90a2); margin-top: 2px; }
|
|
94
|
+
/* In the corner: an object can be tall, and a button under it is a scroll away. */
|
|
95
|
+
.ch-block { position: relative; border-radius: 4px; border: 1px solid var(--fx-line, #ffffff14); }
|
|
96
|
+
.ch-block.ch-from { opacity: .72; }
|
|
97
|
+
.ch-json { margin: 0; padding: 5px 7px; overflow-x: auto; white-space: pre; font: inherit; }
|
|
98
|
+
.ch-copy {
|
|
99
|
+
position: absolute; top: 3px; right: 3px; padding: 1px 6px; cursor: pointer;
|
|
100
|
+
font: inherit; font-size: 9.5px; opacity: 0; transition: opacity .12s;
|
|
101
|
+
border: 1px solid var(--fx-line, #ffffff26); border-radius: 3px;
|
|
102
|
+
background: var(--fx-panel, #14161c); color: var(--fx-muted, #8a90a2);
|
|
103
|
+
}
|
|
104
|
+
.ch-block:hover .ch-copy, .ch-copy:focus { opacity: 1; }
|
|
105
|
+
.ch-copy:hover { color: var(--fx-label, #e7e9ee); }
|
|
106
|
+
`;
|
|
107
|
+
export {
|
|
108
|
+
CHANGE_CSS,
|
|
109
|
+
changeRows,
|
|
110
|
+
handleCopyClick
|
|
111
|
+
};
|
package/dist/copy.cjs
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/copy.ts
|
|
21
|
+
var copy_exports = {};
|
|
22
|
+
__export(copy_exports, {
|
|
23
|
+
copyText: () => copyText
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(copy_exports);
|
|
26
|
+
function confirmOn(button, said = "copied") {
|
|
27
|
+
if (!button) return;
|
|
28
|
+
const was = button.textContent;
|
|
29
|
+
button.textContent = said;
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
button.textContent = was;
|
|
32
|
+
}, 1200);
|
|
33
|
+
}
|
|
34
|
+
function fallback(text, button) {
|
|
35
|
+
try {
|
|
36
|
+
const doc = button?.ownerDocument ?? document;
|
|
37
|
+
const area = doc.createElement("textarea");
|
|
38
|
+
area.value = text;
|
|
39
|
+
area.setAttribute("readonly", "");
|
|
40
|
+
area.style.position = "fixed";
|
|
41
|
+
area.style.opacity = "0";
|
|
42
|
+
doc.body.appendChild(area);
|
|
43
|
+
area.select();
|
|
44
|
+
doc.execCommand("copy");
|
|
45
|
+
area.remove();
|
|
46
|
+
confirmOn(button);
|
|
47
|
+
return true;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function copyText(text, button) {
|
|
53
|
+
const clipboard = globalThis.navigator?.clipboard;
|
|
54
|
+
if (clipboard?.writeText) {
|
|
55
|
+
try {
|
|
56
|
+
await clipboard.writeText(text);
|
|
57
|
+
confirmOn(button);
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return fallback(text, button);
|
|
63
|
+
}
|
package/dist/copy.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/copy.ts
|
|
2
|
+
function confirmOn(button, said = "copied") {
|
|
3
|
+
if (!button) return;
|
|
4
|
+
const was = button.textContent;
|
|
5
|
+
button.textContent = said;
|
|
6
|
+
setTimeout(() => {
|
|
7
|
+
button.textContent = was;
|
|
8
|
+
}, 1200);
|
|
9
|
+
}
|
|
10
|
+
function fallback(text, button) {
|
|
11
|
+
try {
|
|
12
|
+
const doc = button?.ownerDocument ?? document;
|
|
13
|
+
const area = doc.createElement("textarea");
|
|
14
|
+
area.value = text;
|
|
15
|
+
area.setAttribute("readonly", "");
|
|
16
|
+
area.style.position = "fixed";
|
|
17
|
+
area.style.opacity = "0";
|
|
18
|
+
doc.body.appendChild(area);
|
|
19
|
+
area.select();
|
|
20
|
+
doc.execCommand("copy");
|
|
21
|
+
area.remove();
|
|
22
|
+
confirmOn(button);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function copyText(text, button) {
|
|
29
|
+
const clipboard = globalThis.navigator?.clipboard;
|
|
30
|
+
if (clipboard?.writeText) {
|
|
31
|
+
try {
|
|
32
|
+
await clipboard.writeText(text);
|
|
33
|
+
confirmOn(button);
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return fallback(text, button);
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
copyText
|
|
42
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/describe.ts
|
|
21
|
+
var describe_exports = {};
|
|
22
|
+
__export(describe_exports, {
|
|
23
|
+
describeNode: () => describeNode
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(describe_exports);
|
|
26
|
+
var MAX_CLASSES = 2;
|
|
27
|
+
function textOwner(node) {
|
|
28
|
+
const parent = node.parentElement;
|
|
29
|
+
return parent ? `text in ${describeElement(parent)}` : "text";
|
|
30
|
+
}
|
|
31
|
+
function describeElement(el) {
|
|
32
|
+
const tag = el.tagName.toLowerCase();
|
|
33
|
+
const id = el.id ? `#${el.id}` : "";
|
|
34
|
+
const raw = typeof el.className === "string" ? el.className : el.getAttribute("class") ?? "";
|
|
35
|
+
const classes = raw.split(/\s+/).filter(Boolean).slice(0, MAX_CLASSES).map((c) => `.${c}`).join("");
|
|
36
|
+
return `${tag}${id}${classes}`;
|
|
37
|
+
}
|
|
38
|
+
function describeNode(target) {
|
|
39
|
+
const node = target;
|
|
40
|
+
if (!node || typeof node.nodeType !== "number") return "detached";
|
|
41
|
+
switch (node.nodeType) {
|
|
42
|
+
case 1:
|
|
43
|
+
return describeElement(node);
|
|
44
|
+
case 3:
|
|
45
|
+
return textOwner(node);
|
|
46
|
+
case 8: {
|
|
47
|
+
const parent = node.parentElement;
|
|
48
|
+
return parent ? `slot in ${describeElement(parent)}` : "slot";
|
|
49
|
+
}
|
|
50
|
+
case 11:
|
|
51
|
+
return "fragment";
|
|
52
|
+
default:
|
|
53
|
+
return node.nodeName?.toLowerCase() ?? "node";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/describe.ts
|
|
2
|
+
var MAX_CLASSES = 2;
|
|
3
|
+
function textOwner(node) {
|
|
4
|
+
const parent = node.parentElement;
|
|
5
|
+
return parent ? `text in ${describeElement(parent)}` : "text";
|
|
6
|
+
}
|
|
7
|
+
function describeElement(el) {
|
|
8
|
+
const tag = el.tagName.toLowerCase();
|
|
9
|
+
const id = el.id ? `#${el.id}` : "";
|
|
10
|
+
const raw = typeof el.className === "string" ? el.className : el.getAttribute("class") ?? "";
|
|
11
|
+
const classes = raw.split(/\s+/).filter(Boolean).slice(0, MAX_CLASSES).map((c) => `.${c}`).join("");
|
|
12
|
+
return `${tag}${id}${classes}`;
|
|
13
|
+
}
|
|
14
|
+
function describeNode(target) {
|
|
15
|
+
const node = target;
|
|
16
|
+
if (!node || typeof node.nodeType !== "number") return "detached";
|
|
17
|
+
switch (node.nodeType) {
|
|
18
|
+
case 1:
|
|
19
|
+
return describeElement(node);
|
|
20
|
+
case 3:
|
|
21
|
+
return textOwner(node);
|
|
22
|
+
case 8: {
|
|
23
|
+
const parent = node.parentElement;
|
|
24
|
+
return parent ? `slot in ${describeElement(parent)}` : "slot";
|
|
25
|
+
}
|
|
26
|
+
case 11:
|
|
27
|
+
return "fragment";
|
|
28
|
+
default:
|
|
29
|
+
return node.nodeName?.toLowerCase() ?? "node";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
describeNode
|
|
34
|
+
};
|