@abbox/inspector 0.4.20 → 0.4.22
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.
|
@@ -12,10 +12,24 @@ export declare function hideHighlight(highlight: HTMLDivElement): void;
|
|
|
12
12
|
export declare function hideSelectedHighlight(selectedHighlight: HTMLDivElement): void;
|
|
13
13
|
export declare function rectForElement(el: Element): ElementRect;
|
|
14
14
|
export declare function renderChangeMarkers(layer: HTMLDivElement, markers: ChangeMarker[], resolveElement: (refId: string) => Element | null, onSelect?: (changeId: string) => void): void;
|
|
15
|
+
type PlacedBadge = {
|
|
16
|
+
node: HTMLElement;
|
|
17
|
+
left: number;
|
|
18
|
+
top: number;
|
|
19
|
+
focused: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Keeps labelled badges readable: each stays inside the page, and one that
|
|
23
|
+
* would cover another moves up a row, keeping its left edge at its own element
|
|
24
|
+
* so it still reads as belonging there. The focused badge is placed first, so
|
|
25
|
+
* it stays exactly on its element.
|
|
26
|
+
*/
|
|
27
|
+
export declare function arrangeBadges(badges: PlacedBadge[], viewportWidth?: number): void;
|
|
15
28
|
/**
|
|
16
29
|
* A badge sits just above its element and moves with it. With no room above
|
|
17
30
|
* (the element starts at the top of the screen) it tucks inside the element's
|
|
18
31
|
* top edge instead, and scrolls away with the element rather than sticking.
|
|
19
32
|
*/
|
|
20
33
|
export declare function badgeTop(elementTop: number): number;
|
|
34
|
+
export {};
|
|
21
35
|
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMhE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,iBAAiB,EAAE,cAAc,CAAC;IAClC,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAgD5D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,cAAc,EACjC,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAQvD;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,EACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMhE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,iBAAiB,EAAE,cAAc,CAAC;IAClC,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAgD5D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,cAAc,EACjC,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAQvD;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,EACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,CAqGN;AAED,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAKF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,QAkC1E;AAID;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|
package/dist/runtime/overlay.js
CHANGED
|
@@ -92,6 +92,7 @@ export function renderChangeMarkers(layer, markers, resolveElement, onSelect) {
|
|
|
92
92
|
markerNodes.delete(id);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
const badges = [];
|
|
95
96
|
for (const marker of markers) {
|
|
96
97
|
const el = resolveElement(marker.elementRefId);
|
|
97
98
|
const rect = el?.getBoundingClientRect();
|
|
@@ -147,11 +148,12 @@ export function renderChangeMarkers(layer, markers, resolveElement, onSelect) {
|
|
|
147
148
|
event.stopPropagation();
|
|
148
149
|
onSelect?.(marker.elementRefId);
|
|
149
150
|
};
|
|
151
|
+
// A labelled pill is far wider than a dot, so it needs much less movement.
|
|
150
152
|
dot.style.animation = marker.pulse
|
|
151
|
-
?
|
|
153
|
+
? `abbox-inspector-pulse${marker.badge ? "-soft" : ""} 1.4s ease-in-out infinite`
|
|
152
154
|
: "";
|
|
153
155
|
dot.style.boxShadow = marker.pulse
|
|
154
|
-
?
|
|
156
|
+
? `0 0 0 ${marker.badge ? 2 : 4}px rgba(255,255,255,0.35)`
|
|
155
157
|
: "0 0 0 1px rgba(0,0,0,0.2)";
|
|
156
158
|
if (marker.pulse)
|
|
157
159
|
ensurePulseStyle(layer.ownerDocument);
|
|
@@ -165,6 +167,48 @@ export function renderChangeMarkers(layer, markers, resolveElement, onSelect) {
|
|
|
165
167
|
dot.style.display = onScreen ? "" : "none";
|
|
166
168
|
dot.style.left = `${rect.x - 6}px`;
|
|
167
169
|
dot.style.top = `${marker.badge ? badgeTop(rect.top) : rect.top - 6}px`;
|
|
170
|
+
dot.style.zIndex = marker.pulse ? "1" : "";
|
|
171
|
+
if (marker.badge && onScreen) {
|
|
172
|
+
badges.push({
|
|
173
|
+
node: dot,
|
|
174
|
+
left: rect.x - 6,
|
|
175
|
+
top: badgeTop(rect.top),
|
|
176
|
+
focused: Boolean(marker.pulse),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
arrangeBadges(badges, layer.ownerDocument.defaultView?.innerWidth);
|
|
181
|
+
}
|
|
182
|
+
const BADGE_GAP = 2;
|
|
183
|
+
const EDGE_MARGIN = 4;
|
|
184
|
+
/**
|
|
185
|
+
* Keeps labelled badges readable: each stays inside the page, and one that
|
|
186
|
+
* would cover another moves up a row, keeping its left edge at its own element
|
|
187
|
+
* so it still reads as belonging there. The focused badge is placed first, so
|
|
188
|
+
* it stays exactly on its element.
|
|
189
|
+
*/
|
|
190
|
+
export function arrangeBadges(badges, viewportWidth) {
|
|
191
|
+
const taken = [];
|
|
192
|
+
const ordered = [...badges].sort((a, b) => Number(b.focused) - Number(a.focused) || a.top - b.top || a.left - b.left);
|
|
193
|
+
for (const badge of ordered) {
|
|
194
|
+
const width = badge.node.offsetWidth;
|
|
195
|
+
const height = badge.node.offsetHeight;
|
|
196
|
+
const maxLeft = (viewportWidth ?? Number.POSITIVE_INFINITY) - width - EDGE_MARGIN;
|
|
197
|
+
const left = Math.max(EDGE_MARGIN, Math.min(badge.left, maxLeft));
|
|
198
|
+
const collides = (top) => taken.some((other) => left < other.right &&
|
|
199
|
+
left + width > other.left &&
|
|
200
|
+
top < other.bottom &&
|
|
201
|
+
top + height > other.top);
|
|
202
|
+
const step = height + BADGE_GAP;
|
|
203
|
+
let top = badge.top;
|
|
204
|
+
while (collides(top) && top - step >= 0)
|
|
205
|
+
top -= step;
|
|
206
|
+
// Out of room above: go below the row instead.
|
|
207
|
+
while (collides(top))
|
|
208
|
+
top += step;
|
|
209
|
+
taken.push({ left, top, right: left + width, bottom: top + height });
|
|
210
|
+
badge.node.style.left = `${left}px`;
|
|
211
|
+
badge.node.style.top = `${top}px`;
|
|
168
212
|
}
|
|
169
213
|
}
|
|
170
214
|
const BADGE_HEIGHT = 18;
|
|
@@ -208,6 +252,10 @@ function ensurePulseStyle(doc) {
|
|
|
208
252
|
style.textContent = `@keyframes abbox-inspector-pulse {
|
|
209
253
|
0%, 100% { transform: scale(1); opacity: 1; }
|
|
210
254
|
50% { transform: scale(1.35); opacity: 0.75; }
|
|
255
|
+
}
|
|
256
|
+
@keyframes abbox-inspector-pulse-soft {
|
|
257
|
+
0%, 100% { transform: scale(1); opacity: 1; }
|
|
258
|
+
50% { transform: scale(1.04); opacity: 0.9; }
|
|
211
259
|
}`;
|
|
212
260
|
doc.head.append(style);
|
|
213
261
|
}
|