chrome-devtools-frontend 1.0.1581449 → 1.0.1582745
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/agents/prompts/merging-devtools-module.md +144 -0
- package/agents/prompts/ui-widgets.md +351 -0
- package/agents/prompts/verification.md +2 -1
- package/docs/contributing/README.md +5 -6
- package/docs/contributing/changes.md +1 -2
- package/docs/styleguide/ux/README.md +1 -1
- package/front_end/core/sdk/OverlayModel.ts +4 -2
- package/front_end/core/sdk/RemoteObject.ts +7 -1
- package/front_end/core/sdk/StorageKeyManager.ts +6 -1
- package/front_end/core/sdk/Target.ts +4 -2
- package/front_end/entrypoint_template.html +5 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +31 -40
- package/front_end/entrypoints/greendev_floaty/floaty.css +41 -1
- package/front_end/entrypoints/greendev_floaty/floaty.html +8 -1
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +5 -5
- package/front_end/entrypoints/node_app/app/NodeMain.ts +19 -1
- package/front_end/entrypoints/node_app/node_app.ts +34 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +2 -0
- package/front_end/generated/protocol.ts +0 -6
- package/front_end/models/ai_assistance/AiConversation.ts +10 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +26 -4
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +85 -7
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -6
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +66 -2
- package/front_end/models/computed_style/ComputedStyleModel.ts +26 -0
- package/front_end/models/greendev/Prototypes.ts +1 -10
- package/front_end/models/issues_manager/ConnectionAllowlistIssue.ts +75 -0
- package/front_end/models/issues_manager/CookieIssue.ts +0 -28
- package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +0 -30
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidHeader.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistItemNotInnerList.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistMoreThanOneList.md +7 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +93 -6
- package/front_end/panels/ai_assistance/components/ChatInput.ts +8 -4
- package/front_end/panels/application/ApplicationPanelSidebar.ts +13 -11
- package/front_end/panels/application/DOMStorageModel.ts +1 -1
- package/front_end/panels/application/ResourcesPanel.ts +10 -5
- package/front_end/panels/application/preloading/PreloadingView.ts +8 -1
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +4 -1
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -1
- package/front_end/panels/application/preloading/components/PreloadingString.ts +12 -3
- package/front_end/panels/application/preloading/helper/PreloadingForward.ts +14 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +37 -3
- package/front_end/panels/changes/ChangesSidebar.ts +2 -6
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +13 -3
- package/front_end/panels/common/aiCodeCompletionTeaser.css +6 -0
- package/front_end/panels/console/ConsoleSidebar.ts +3 -11
- package/front_end/panels/console_counters/WarningErrorCounter.ts +16 -10
- package/front_end/panels/elements/ComputedStyleWidget.ts +55 -37
- package/front_end/panels/elements/PlatformFontsWidget.ts +23 -10
- package/front_end/panels/greendev/GreenDevPanel.css +42 -1
- package/front_end/panels/greendev/GreenDevPanel.ts +30 -1
- package/front_end/panels/lighthouse/LighthouseStartView.ts +3 -5
- package/front_end/panels/lighthouse/lighthouseStartView.css +6 -0
- package/front_end/panels/network/NetworkLogView.ts +6 -6
- package/front_end/panels/network/RequestInitiatorView.ts +27 -19
- package/front_end/panels/network/RequestTimingView.ts +1 -1
- package/front_end/panels/settings/AISettingsTab.ts +1 -5
- package/front_end/panels/settings/KeybindsSettingsTab.ts +4 -3
- package/front_end/panels/settings/SettingsScreen.ts +0 -51
- package/front_end/panels/sources/OutlineQuickOpen.ts +19 -0
- package/front_end/panels/timeline/AnimationsTrackAppender.ts +4 -1
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +1 -1
- package/front_end/panels/timeline/TimelinePanel.ts +25 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +13 -16
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +145 -144
- package/front_end/third_party/lighthouse/report/bundle.js +12 -5
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -1
- package/front_end/ui/legacy/ListControl.ts +28 -1
- package/front_end/ui/legacy/Toolbar.ts +4 -4
- package/front_end/ui/legacy/Treeoutline.ts +5 -5
- package/front_end/ui/legacy/UIUtils.ts +26 -10
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +10 -13
- package/front_end/ui/legacy/components/utils/Linkifier.ts +4 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/inspector_overlay/main.ts +18 -3
- package/inspector_overlay/tool_green_dev_anchors.css +54 -0
- package/inspector_overlay/tool_green_dev_anchors.ts +164 -0
- package/inspector_overlay/tool_persistent.ts +14 -0
- package/package.json +1 -1
- package/docs/contributing/design.md +0 -166
- package/docs/design_guidelines.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataHttpNotFound.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataInvalidResponse.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataNoResponse.md +0 -1
|
@@ -58,9 +58,12 @@ export const markdownLinks = new Map<string, string>([
|
|
|
58
58
|
['signatureHeader', 'https://www.rfc-editor.org/rfc/rfc9421.html#name-the-signature-http-field'],
|
|
59
59
|
['signatureInputHeader', 'https://www.rfc-editor.org/rfc/rfc9421.html#name-the-signature-input-http-fi'],
|
|
60
60
|
['signatureParameters', 'https://www.rfc-editor.org/rfc/rfc9421.html#name-signature-parameters'],
|
|
61
|
-
['sfDictionary', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-dictionaries'],
|
|
62
61
|
['sfByteSequence', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-byte-sequences'],
|
|
62
|
+
['sfDictionary', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-dictionaries'],
|
|
63
63
|
['sfInnerList', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-inner-lists'],
|
|
64
|
+
['sfList', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-lists'],
|
|
65
|
+
['sfString', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-strings'],
|
|
66
|
+
['sfToken', 'https://www.rfc-editor.org/rfc/rfc8941.html#name-tokens'],
|
|
64
67
|
['componentParameterSf', 'https://www.rfc-editor.org/rfc/rfc9421.html#name-strict-serialization-of-htt'],
|
|
65
68
|
['componentParameterReq', 'https://www.rfc-editor.org/rfc/rfc9421.html#content-request-response'],
|
|
66
69
|
[
|
|
@@ -74,6 +77,7 @@ export const markdownLinks = new Map<string, string>([
|
|
|
74
77
|
'https://privacysandbox.com/news/update-on-plans-for-privacy-sandbox-technologies/',
|
|
75
78
|
'https://privacysandbox.com/news/update-on-plans-for-privacy-sandbox-technologies/'
|
|
76
79
|
],
|
|
80
|
+
['urlPatternSpec', 'https://urlpattern.spec.whatwg.org/'],
|
|
77
81
|
]);
|
|
78
82
|
|
|
79
83
|
export const getMarkdownLink = (key: string): string => {
|
|
@@ -282,6 +282,26 @@ export class ListControl<T> {
|
|
|
282
282
|
return false;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
selectFirstItem(center?: boolean): boolean {
|
|
286
|
+
const index = this.findFirstSelectable(0, +1, false);
|
|
287
|
+
if (index !== -1) {
|
|
288
|
+
this.scrollIntoView(index, center);
|
|
289
|
+
this.select(index);
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
selectLastItem(center?: boolean): boolean {
|
|
296
|
+
const index = this.findFirstSelectable(this.model.length - 1, -1, false);
|
|
297
|
+
if (index !== -1) {
|
|
298
|
+
this.scrollIntoView(index, center);
|
|
299
|
+
this.select(index);
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
|
|
285
305
|
private scrollIntoView(index: number, center?: boolean): void {
|
|
286
306
|
if (this.mode === ListMode.NonViewport) {
|
|
287
307
|
this.elementAtIndex(index).scrollIntoViewIfNeeded(Boolean(center));
|
|
@@ -328,6 +348,12 @@ export class ListControl<T> {
|
|
|
328
348
|
case 'PageDown':
|
|
329
349
|
selected = this.selectItemNextPage(false);
|
|
330
350
|
break;
|
|
351
|
+
case 'Home':
|
|
352
|
+
selected = this.selectFirstItem();
|
|
353
|
+
break;
|
|
354
|
+
case 'End':
|
|
355
|
+
selected = this.selectLastItem();
|
|
356
|
+
break;
|
|
331
357
|
}
|
|
332
358
|
if (selected) {
|
|
333
359
|
event.consume(true);
|
|
@@ -364,7 +390,8 @@ export class ListControl<T> {
|
|
|
364
390
|
element = this.delegate.createElementForItem(item);
|
|
365
391
|
if (!element.hasAttribute('jslog')) {
|
|
366
392
|
element.setAttribute(
|
|
367
|
-
'jslog',
|
|
393
|
+
'jslog',
|
|
394
|
+
`${VisualLogging.item().track({click: true, keydown: 'ArrowUp|ArrowDown|PageUp|PageDown|Home|End'})}`);
|
|
368
395
|
}
|
|
369
396
|
this.itemToElement.set(item, element);
|
|
370
397
|
this.updateElementARIA(element, index);
|
|
@@ -1321,11 +1321,11 @@ export class ToolbarCheckbox extends ToolbarItem<void> {
|
|
|
1321
1321
|
constructor(
|
|
1322
1322
|
text: Common.UIString.LocalizedString, tooltip?: Common.UIString.LocalizedString,
|
|
1323
1323
|
listener?: ((arg0: MouseEvent) => void), jslogContext?: string) {
|
|
1324
|
-
|
|
1324
|
+
// Pass tooltip to CheckboxLabel.create so it's set on the inner input/text elements,
|
|
1325
|
+
// rather than installing it on the wrapper element which causes screen readers to
|
|
1326
|
+
// incorrectly announce it as a group name.
|
|
1327
|
+
const checkboxLabel = CheckboxLabel.create(text, undefined, undefined, jslogContext, undefined, tooltip);
|
|
1325
1328
|
super(checkboxLabel);
|
|
1326
|
-
if (tooltip) {
|
|
1327
|
-
Tooltip.install(this.element, tooltip);
|
|
1328
|
-
}
|
|
1329
1329
|
if (listener) {
|
|
1330
1330
|
this.element.addEventListener('click', listener, false);
|
|
1331
1331
|
}
|
|
@@ -1566,7 +1566,7 @@ class TreeViewTreeElement extends TreeElement {
|
|
|
1566
1566
|
this.listItemElement.classList.add(className);
|
|
1567
1567
|
this.#clonedClasses.add(className);
|
|
1568
1568
|
}
|
|
1569
|
-
InterceptBindingDirective.
|
|
1569
|
+
InterceptBindingDirective.setEventListeners(this.configElement, this.listItemElement);
|
|
1570
1570
|
|
|
1571
1571
|
for (const child of this.configElement.childNodes) {
|
|
1572
1572
|
if (child instanceof HTMLUListElement && child.role === 'group') {
|
|
@@ -1704,7 +1704,7 @@ export class TreeViewElement extends HTMLElementWithLightDOMTemplate {
|
|
|
1704
1704
|
super();
|
|
1705
1705
|
this.#treeOutline.addEventListener(Events.ElementSelected, event => {
|
|
1706
1706
|
if (event.data instanceof TreeViewTreeElement) {
|
|
1707
|
-
|
|
1707
|
+
event.data.listItemElement.dispatchEvent(new TreeViewElement.SelectEvent());
|
|
1708
1708
|
}
|
|
1709
1709
|
});
|
|
1710
1710
|
this.#treeOutline.addEventListener(Events.ElementExpanded, event => {
|
|
@@ -1859,9 +1859,9 @@ export class TreeViewElement extends HTMLElementWithLightDOMTemplate {
|
|
|
1859
1859
|
}
|
|
1860
1860
|
|
|
1861
1861
|
export namespace TreeViewElement {
|
|
1862
|
-
export class SelectEvent extends CustomEvent<
|
|
1863
|
-
constructor(
|
|
1864
|
-
super('select'
|
|
1862
|
+
export class SelectEvent extends CustomEvent<void> {
|
|
1863
|
+
constructor() {
|
|
1864
|
+
super('select');
|
|
1865
1865
|
}
|
|
1866
1866
|
}
|
|
1867
1867
|
|
|
@@ -1173,7 +1173,7 @@ export class CheckboxLabel extends HTMLElement {
|
|
|
1173
1173
|
|
|
1174
1174
|
static create(
|
|
1175
1175
|
title?: Platform.UIString.LocalizedString, checked?: boolean, subtitle?: Platform.UIString.LocalizedString,
|
|
1176
|
-
jslogContext?: string, small?: boolean): CheckboxLabel {
|
|
1176
|
+
jslogContext?: string, small?: boolean, tooltip?: Platform.UIString.LocalizedString): CheckboxLabel {
|
|
1177
1177
|
const element = document.createElement('devtools-checkbox');
|
|
1178
1178
|
element.#checkboxElement.checked = Boolean(checked);
|
|
1179
1179
|
if (jslogContext) {
|
|
@@ -1182,11 +1182,17 @@ export class CheckboxLabel extends HTMLElement {
|
|
|
1182
1182
|
}
|
|
1183
1183
|
if (title !== undefined) {
|
|
1184
1184
|
element.#textElement.textContent = title;
|
|
1185
|
-
element.#checkboxElement.title = title;
|
|
1186
1185
|
if (subtitle !== undefined) {
|
|
1187
1186
|
element.#textElement.createChild('div', 'devtools-checkbox-subtitle').textContent = subtitle;
|
|
1188
1187
|
}
|
|
1189
1188
|
}
|
|
1189
|
+
// checkboxElement tooltip: tooltip first, then title (custom tooltip takes precedence for the input)
|
|
1190
|
+
const inputTooltip = tooltip ?? title;
|
|
1191
|
+
if (inputTooltip) {
|
|
1192
|
+
element.#checkboxElement.title = inputTooltip;
|
|
1193
|
+
// Set aria-description for screen reader announcement
|
|
1194
|
+
element.#checkboxElement.setAttribute('aria-description', inputTooltip);
|
|
1195
|
+
}
|
|
1190
1196
|
element.#checkboxElement.classList.toggle('small', small);
|
|
1191
1197
|
return element;
|
|
1192
1198
|
}
|
|
@@ -1970,6 +1976,7 @@ export function bindToAction(actionName: string): ReturnType<typeof Directives.r
|
|
|
1970
1976
|
type BindingEventListener = (arg: any) => any;
|
|
1971
1977
|
export class InterceptBindingDirective extends Lit.Directive.Directive {
|
|
1972
1978
|
static readonly #interceptedBindings = new WeakMap<Element, Map<string, BindingEventListener>>();
|
|
1979
|
+
static readonly #attachedBindings = new WeakMap<Element, Map<string, BindingEventListener>>();
|
|
1973
1980
|
|
|
1974
1981
|
override update(part: Lit.Directive.Part, [listener]: [BindingEventListener]): unknown {
|
|
1975
1982
|
if (part.type !== Lit.Directive.PartType.EVENT) {
|
|
@@ -1990,13 +1997,22 @@ export class InterceptBindingDirective extends Lit.Directive.Directive {
|
|
|
1990
1997
|
return undefined;
|
|
1991
1998
|
}
|
|
1992
1999
|
|
|
1993
|
-
static
|
|
1994
|
-
const
|
|
1995
|
-
if (
|
|
1996
|
-
|
|
2000
|
+
static setEventListeners(templateElement: Element, renderedElement: Element): void {
|
|
2001
|
+
const attachedListeners = InterceptBindingDirective.#attachedBindings.get(renderedElement);
|
|
2002
|
+
if (attachedListeners) {
|
|
2003
|
+
for (const [name, listener] of attachedListeners) {
|
|
2004
|
+
renderedElement.removeEventListener(name, listener);
|
|
2005
|
+
}
|
|
1997
2006
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2007
|
+
|
|
2008
|
+
const newListeners = InterceptBindingDirective.#interceptedBindings.get(templateElement);
|
|
2009
|
+
if (newListeners?.size) {
|
|
2010
|
+
for (const [name, listener] of newListeners) {
|
|
2011
|
+
renderedElement.addEventListener(name, listener);
|
|
2012
|
+
}
|
|
2013
|
+
InterceptBindingDirective.#attachedBindings.set(renderedElement, new Map(newListeners));
|
|
2014
|
+
} else {
|
|
2015
|
+
InterceptBindingDirective.#attachedBindings.delete(renderedElement);
|
|
2000
2016
|
}
|
|
2001
2017
|
}
|
|
2002
2018
|
}
|
|
@@ -2029,7 +2045,7 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2029
2045
|
clone.appendChild(HTMLElementWithLightDOMTemplate.cloneNode(child));
|
|
2030
2046
|
}
|
|
2031
2047
|
if (node instanceof Element && clone instanceof Element) {
|
|
2032
|
-
InterceptBindingDirective.
|
|
2048
|
+
InterceptBindingDirective.setEventListeners(node, clone);
|
|
2033
2049
|
}
|
|
2034
2050
|
return clone;
|
|
2035
2051
|
}
|
|
@@ -2059,7 +2075,7 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2059
2075
|
HTMLElementWithLightDOMTemplate.patchLitTemplate(value);
|
|
2060
2076
|
return value;
|
|
2061
2077
|
}
|
|
2062
|
-
if (Array.isArray(value)) {
|
|
2078
|
+
if (Array.isArray(value) || value instanceof Iterator) {
|
|
2063
2079
|
return value.map(patchValue);
|
|
2064
2080
|
}
|
|
2065
2081
|
|
|
@@ -96,7 +96,7 @@ function populateContextMenu(link: Element, event: Event): void {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// TODO(crbug.com/456517732): remove when all usages of runtimeStackTrace are migrated.
|
|
99
|
-
|
|
99
|
+
function buildStackTraceRowsForLegacyRuntimeStackTrace(
|
|
100
100
|
stackTrace: Protocol.Runtime.StackTrace,
|
|
101
101
|
target: SDK.Target.Target|null,
|
|
102
102
|
linkifier: Linkifier,
|
|
@@ -159,7 +159,7 @@ export function buildStackTraceRowsForLegacyRuntimeStackTrace(
|
|
|
159
159
|
return stackTraceRows;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
function buildStackTraceRows(
|
|
163
163
|
stackTrace: StackTrace.StackTrace.StackTrace,
|
|
164
164
|
target: SDK.Target.Target|null,
|
|
165
165
|
linkifier: Linkifier,
|
|
@@ -189,14 +189,9 @@ export function buildStackTraceRows(
|
|
|
189
189
|
inlineFrameIndex: 0,
|
|
190
190
|
revealBreakpoint: previousStackFrameWasBreakpointCondition,
|
|
191
191
|
});
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
|
|
192
|
+
link.setAttribute('jslog', `${VisualLogging.link('stack-trace').track({click: true})}`);
|
|
193
|
+
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
|
|
195
194
|
|
|
196
|
-
if (!link.textContent) {
|
|
197
|
-
link.textContent = i18nString(UIStrings.unknownSource);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
195
|
stackTraceRows.push({functionName, link});
|
|
201
196
|
previousStackFrameWasBreakpointCondition = [
|
|
202
197
|
SDK.DebuggerModel.COND_BREAKPOINT_SOURCE_URL,
|
|
@@ -306,12 +301,12 @@ export interface Options {
|
|
|
306
301
|
expandable?: boolean;
|
|
307
302
|
}
|
|
308
303
|
|
|
309
|
-
|
|
304
|
+
interface StackTraceRegularRow {
|
|
310
305
|
functionName: string;
|
|
311
306
|
link: HTMLElement|null;
|
|
312
307
|
}
|
|
313
308
|
|
|
314
|
-
|
|
309
|
+
interface StackTraceAsyncRow {
|
|
315
310
|
asyncDescription: string;
|
|
316
311
|
}
|
|
317
312
|
|
|
@@ -353,8 +348,6 @@ export class StackTracePreviewContent extends UI.Widget.Widget {
|
|
|
353
348
|
this.#table = this.contentElement.createChild('table', 'stack-preview-container');
|
|
354
349
|
this.#table.classList.toggle('width-constrained', this.#options.widthConstrained ?? false);
|
|
355
350
|
|
|
356
|
-
this.#stackTrace?.addEventListener(StackTrace.StackTrace.Events.UPDATED, this.performUpdate.bind(this));
|
|
357
|
-
|
|
358
351
|
this.performUpdate();
|
|
359
352
|
}
|
|
360
353
|
|
|
@@ -407,7 +400,11 @@ export class StackTracePreviewContent extends UI.Widget.Widget {
|
|
|
407
400
|
}
|
|
408
401
|
|
|
409
402
|
set stackTrace(stackTrace: StackTrace.StackTrace.StackTrace) {
|
|
403
|
+
if (this.#stackTrace) {
|
|
404
|
+
this.#stackTrace.removeEventListener(StackTrace.StackTrace.Events.UPDATED, this.requestUpdate, this);
|
|
405
|
+
}
|
|
410
406
|
this.#stackTrace = stackTrace;
|
|
407
|
+
this.#stackTrace.addEventListener(StackTrace.StackTrace.Events.UPDATED, this.requestUpdate, this);
|
|
411
408
|
this.requestUpdate();
|
|
412
409
|
}
|
|
413
410
|
|
|
@@ -345,8 +345,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
maybeLinkifyStackTraceFrame(
|
|
348
|
-
target: SDK.Target.Target|null, frame: StackTrace.StackTrace.Frame, options?: LinkifyOptions): HTMLElement
|
|
349
|
-
let fallbackAnchor: HTMLElement|null = null;
|
|
348
|
+
target: SDK.Target.Target|null, frame: StackTrace.StackTrace.Frame, options?: LinkifyOptions): HTMLElement {
|
|
350
349
|
const linkifyURLOptions: LinkifyURLOptions = {
|
|
351
350
|
...options,
|
|
352
351
|
lineNumber: frame.line,
|
|
@@ -361,10 +360,8 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
361
360
|
omitOrigin: options?.omitOrigin,
|
|
362
361
|
};
|
|
363
362
|
const {className = ''} = linkifyURLOptions;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
if (!target || target.isDisposed()) {
|
|
363
|
+
const fallbackAnchor = Linkifier.linkifyURL(frame.url as Platform.DevToolsPath.UrlString, linkifyURLOptions);
|
|
364
|
+
if (!target || target.isDisposed() || !frame.uiSourceCode) {
|
|
368
365
|
return fallbackAnchor;
|
|
369
366
|
}
|
|
370
367
|
|
|
@@ -383,7 +380,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
383
380
|
revealBreakpoint: options?.revealBreakpoint,
|
|
384
381
|
};
|
|
385
382
|
|
|
386
|
-
const uiLocation = frame.uiSourceCode
|
|
383
|
+
const uiLocation = frame.uiSourceCode.uiLocation(frame.line, frame.column) ?? null;
|
|
387
384
|
this.updateAnchorFromUILocation(link, linkDisplayOptions, uiLocation);
|
|
388
385
|
|
|
389
386
|
const anchors = (this.anchorsByTarget.get(target) as Element[]);
|
|
@@ -923,12 +923,14 @@ export const knownContextValues = new Set([
|
|
|
923
923
|
'content-type',
|
|
924
924
|
'content-visibility',
|
|
925
925
|
'context',
|
|
926
|
+
'context-added',
|
|
926
927
|
'context-change-drjones-file',
|
|
927
928
|
'context-change-drjones-network-request',
|
|
928
929
|
'context-change-drjones-performance',
|
|
929
930
|
'context-change-freestyler',
|
|
930
931
|
'context-change-none',
|
|
931
932
|
'context-change-performance-insight',
|
|
933
|
+
'context-removed',
|
|
932
934
|
'context3',
|
|
933
935
|
'contextmenu',
|
|
934
936
|
'continue',
|
|
@@ -7,6 +7,13 @@ import commonStyle from './common.css';
|
|
|
7
7
|
import {adoptStyleSheet} from './common.js';
|
|
8
8
|
import {gridStyle} from './highlight_grid_common.js';
|
|
9
9
|
// @ts-expect-error Importing CSS is handled in Rollup.
|
|
10
|
+
import greenDevAnchorsStyle from './tool_green_dev_anchors.css';
|
|
11
|
+
import {
|
|
12
|
+
type GreenDevAnchorsDispatchMessage,
|
|
13
|
+
GreenDevAnchorsOverlay,
|
|
14
|
+
type GreenDevAnchorsToolMessage
|
|
15
|
+
} from './tool_green_dev_anchors.js';
|
|
16
|
+
// @ts-expect-error Importing CSS is handled in Rollup.
|
|
10
17
|
import highlightGridStyle from './tool_grid.css';
|
|
11
18
|
// @ts-expect-error Importing CSS is handled in Rollup.
|
|
12
19
|
import highlightStyle from './tool_highlight.css';
|
|
@@ -29,7 +36,9 @@ import {WindowControlsOverlay} from './tool_window_controls.js';
|
|
|
29
36
|
declare global {
|
|
30
37
|
interface Window {
|
|
31
38
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
32
|
-
InspectorOverlayHost: {
|
|
39
|
+
InspectorOverlayHost: {
|
|
40
|
+
send(data: PausedToolMessage|PersistentToolMessage|ScreenshotToolMessage|GreenDevAnchorsToolMessage|string): void,
|
|
41
|
+
};
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
|
|
@@ -39,14 +48,18 @@ const gridStyleSheet = new CSSStyleSheet();
|
|
|
39
48
|
gridStyleSheet.replaceSync(gridStyle);
|
|
40
49
|
|
|
41
50
|
const highlightOverlay = new HighlightOverlay(window, [highlightStyle, gridStyleSheet]);
|
|
42
|
-
const persistentOverlay = new PersistentOverlay(window, [highlightGridStyle, gridStyleSheet]);
|
|
51
|
+
const persistentOverlay = new PersistentOverlay(window, [highlightGridStyle, greenDevAnchorsStyle, gridStyleSheet]);
|
|
43
52
|
const pausedOverlay = new PausedOverlay(window, pausedStyle);
|
|
44
53
|
const screenshotOverlay = new ScreenshotOverlay(window, screenshotStyle);
|
|
54
|
+
const greenDevAnchorsOverlay = new GreenDevAnchorsOverlay(window, greenDevAnchorsStyle);
|
|
45
55
|
const sourceOrderOverlay = new SourceOrderOverlay(window, sourceOrderStyle);
|
|
46
56
|
const viewportSizeOverlay = new ViewportSizeOverlay(window);
|
|
47
57
|
const windowControlsOverlay = new WindowControlsOverlay(window, [wcoStyle]);
|
|
48
58
|
|
|
59
|
+
persistentOverlay.setGreenDevAnchorsOverlay(greenDevAnchorsOverlay);
|
|
60
|
+
|
|
49
61
|
interface Overlays {
|
|
62
|
+
greenDevFloaty: GreenDevAnchorsOverlay;
|
|
50
63
|
highlight: HighlightOverlay;
|
|
51
64
|
persistent: PersistentOverlay;
|
|
52
65
|
paused: PausedOverlay;
|
|
@@ -60,6 +73,7 @@ type PlatformName = string;
|
|
|
60
73
|
|
|
61
74
|
// Key in this object is the name the backend refers to a particular overlay by.
|
|
62
75
|
const overlays: Overlays = {
|
|
76
|
+
greenDevFloaty: greenDevAnchorsOverlay,
|
|
63
77
|
highlight: highlightOverlay,
|
|
64
78
|
persistent: persistentOverlay,
|
|
65
79
|
paused: pausedOverlay,
|
|
@@ -76,6 +90,7 @@ interface MessageLookup {
|
|
|
76
90
|
setOverlay: keyof Overlays;
|
|
77
91
|
setPlatform: PlatformName;
|
|
78
92
|
drawingFinished: '';
|
|
93
|
+
update: GreenDevAnchorsDispatchMessage;
|
|
79
94
|
}
|
|
80
95
|
|
|
81
96
|
const dispatch = <K extends keyof MessageLookup>(message: [a: K, b: MessageLookup[K]]) => {
|
|
@@ -93,7 +108,7 @@ const dispatch = <K extends keyof MessageLookup>(message: [a: K, b: MessageLooku
|
|
|
93
108
|
currentOverlay.install();
|
|
94
109
|
}
|
|
95
110
|
} else if (functionName === 'setPlatform') {
|
|
96
|
-
platformName = message[1];
|
|
111
|
+
platformName = message[1] as PlatformName;
|
|
97
112
|
} else if (functionName === 'drawingFinished') {
|
|
98
113
|
// TODO The logic needs to be added here once the backend starts sending this event.
|
|
99
114
|
} else {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The Chromium Authors
|
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/* eslint-disable color-named, plugin/use_theme_colors */
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
--gemini-logo: url("data:image/svg+xml,%0A%3Csvg%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2065%2065%22%3E%3Cmask%20id%3D%22maskme%22%20style%3D%22mask-type%3Aalpha%22%20maskUnits%3D%22userSpaceOnUse%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2265%22%20height%3D%2265%22%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3C/mask%3E%3Cg%20mask%3D%22url(%23maskme)%22%3E%3Cpath%20fill%3D%22%234285F4%22%20d%3D%22M0%200h38.235L65%2027.66%2065%2065H0z%22/%3E%3Cpath%20fill%3D%22%23EA4335%22%20d%3D%22M26.765%200H65v38.235z%22/%3E%3Cpath%20fill%3D%22%2334A853%22%20d%3D%22M0%2026.765H38.235V65H0z%22/%3E%3Cpath%20fill%3D%22%23FBBC04%22%20d%3D%22M27.66%2065L65%2038.235V65z%22/%3E%3C/g%3E%3C/svg%3E");
|
|
10
|
+
--open-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6' /%3E%3Cpolyline points='15 3 21 3 21 9' /%3E%3Cline x1='10' y1='14' x2='21' y2='3' /%3E%3C/svg%3E");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
#green-dev-anchors-container {
|
|
14
|
+
position: absolute;
|
|
15
|
+
top: 0;
|
|
16
|
+
left: 0;
|
|
17
|
+
width: 100%;
|
|
18
|
+
height: 100%;
|
|
19
|
+
z-index: 1000;
|
|
20
|
+
pointer-events: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.green-dev-anchor-minimal {
|
|
24
|
+
position: absolute;
|
|
25
|
+
width: 70px;
|
|
26
|
+
height: 40px;
|
|
27
|
+
background-color: #fff;
|
|
28
|
+
border-radius: 12px;
|
|
29
|
+
box-shadow: 0 4px 8px rgb(0 0 0 / 20%);
|
|
30
|
+
pointer-events: auto;
|
|
31
|
+
z-index: 1001;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
padding: 0 5px;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.green-dev-anchor-icon-gemini {
|
|
40
|
+
width: 24px;
|
|
41
|
+
height: 24px;
|
|
42
|
+
background-image: var(--gemini-logo);
|
|
43
|
+
background-size: cover;
|
|
44
|
+
background-repeat: no-repeat;
|
|
45
|
+
margin-right: 5px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.green-dev-anchor-icon-open {
|
|
49
|
+
width: 20px;
|
|
50
|
+
height: 20px;
|
|
51
|
+
background-image: var(--open-icon);
|
|
52
|
+
background-size: cover;
|
|
53
|
+
background-repeat: no-repeat;
|
|
54
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Copyright 2026 The Chromium Authors
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import {Overlay} from './common.js';
|
|
6
|
+
|
|
7
|
+
export interface GreenDevAnchorsHighlight {
|
|
8
|
+
nodeId: number;
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type GreenDevAnchorsToolMessage = {
|
|
14
|
+
highlightType: 'greenDevFloaty',
|
|
15
|
+
command: 'setInputValue',
|
|
16
|
+
nodeId: number,
|
|
17
|
+
value: string,
|
|
18
|
+
}|{
|
|
19
|
+
highlightType: 'greenDevFloaty',
|
|
20
|
+
command: 'debugMessage',
|
|
21
|
+
message: string,
|
|
22
|
+
}|{
|
|
23
|
+
highlightType: 'greenDevFloaty',
|
|
24
|
+
command: 'openDevTools',
|
|
25
|
+
nodeId: number,
|
|
26
|
+
}|{
|
|
27
|
+
highlightType: 'greenDevFloaty',
|
|
28
|
+
command: 'restoreFloaty',
|
|
29
|
+
nodeId: number,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function consoleLog(message: string) {
|
|
33
|
+
window.InspectorOverlayHost.send({highlightType: 'greenDevFloaty', command: 'debugMessage', message});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface GreenDevAnchorsDispatchMessage {
|
|
37
|
+
nodeId: number;
|
|
38
|
+
value: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class GreenDevAnchorsOverlay extends Overlay {
|
|
42
|
+
#anchorsContainer!: HTMLElement;
|
|
43
|
+
#anchorsByNodeId = new Map<number, HTMLElement>();
|
|
44
|
+
|
|
45
|
+
override install() {
|
|
46
|
+
consoleLog('GreenDevAnchorsOverlay.install() called');
|
|
47
|
+
|
|
48
|
+
this.document.body.classList.add('fill');
|
|
49
|
+
|
|
50
|
+
const canvas = this.document.createElement('canvas');
|
|
51
|
+
canvas.id = 'canvas';
|
|
52
|
+
canvas.classList.add('fill');
|
|
53
|
+
canvas.style.pointerEvents = 'none';
|
|
54
|
+
this.document.body.append(canvas);
|
|
55
|
+
|
|
56
|
+
const anchorsContainer = this.document.createElement('div');
|
|
57
|
+
anchorsContainer.id = 'green-dev-anchors-container';
|
|
58
|
+
this.document.body.append(anchorsContainer);
|
|
59
|
+
this.#anchorsContainer = anchorsContainer;
|
|
60
|
+
|
|
61
|
+
this.setCanvas(canvas);
|
|
62
|
+
super.install();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
override uninstall() {
|
|
66
|
+
consoleLog('GreenDevAnchorsOverlay.uninstall() called');
|
|
67
|
+
|
|
68
|
+
this.document.body.classList.remove('fill');
|
|
69
|
+
if (this.#anchorsContainer && this.#anchorsContainer.parentElement) {
|
|
70
|
+
this.#anchorsContainer.parentElement.removeChild(this.#anchorsContainer);
|
|
71
|
+
}
|
|
72
|
+
// Clear the map as the elements are removed from DOM.
|
|
73
|
+
this.#anchorsByNodeId.clear();
|
|
74
|
+
super.uninstall();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
drawGreenDevAnchors(highlights: GreenDevAnchorsHighlight[]) {
|
|
78
|
+
if (this.#anchorsContainer && !this.#anchorsContainer.isConnected) {
|
|
79
|
+
// The container was removed from the DOM (likely by PersistentOverlay.uninstall cleaning up),
|
|
80
|
+
// but this overlay still thinks it's installed. We need to re-install to restore the DOM.
|
|
81
|
+
try {
|
|
82
|
+
this.uninstall();
|
|
83
|
+
} catch (e) {
|
|
84
|
+
console.error('Error during uninstall in drawGreenDevAnchors:', e);
|
|
85
|
+
}
|
|
86
|
+
this.install();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const newAnchorsByNodeId = new Map<number, HTMLElement>();
|
|
90
|
+
|
|
91
|
+
for (const highlight of highlights) {
|
|
92
|
+
const {x, y, nodeId} = highlight;
|
|
93
|
+
let anchor = this.#anchorsByNodeId.get(nodeId);
|
|
94
|
+
|
|
95
|
+
if (anchor) {
|
|
96
|
+
anchor.style.left = `${x}px`;
|
|
97
|
+
anchor.style.top = `${y}px`;
|
|
98
|
+
// Remove from the old map so only anchors that need to be deleted remain.
|
|
99
|
+
this.#anchorsByNodeId.delete(nodeId);
|
|
100
|
+
} else {
|
|
101
|
+
const newAnchor = this.drawGreenDevAnchor(highlight);
|
|
102
|
+
if (!newAnchor) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
anchor = newAnchor;
|
|
106
|
+
anchor.style.left = `${x}px`;
|
|
107
|
+
anchor.style.top = `${y}px`;
|
|
108
|
+
this.#anchorsContainer.append(anchor);
|
|
109
|
+
}
|
|
110
|
+
newAnchorsByNodeId.set(nodeId, anchor);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Remove any anchors that were not present in the new highlights list.
|
|
114
|
+
for (const anchor of this.#anchorsByNodeId.values()) {
|
|
115
|
+
anchor.remove();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.#anchorsByNodeId = newAnchorsByNodeId;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private drawGreenDevAnchor(highlight: GreenDevAnchorsHighlight): HTMLElement {
|
|
122
|
+
const {nodeId} = highlight;
|
|
123
|
+
const anchor = this.document.createElement('div');
|
|
124
|
+
anchor.classList.add('green-dev-anchor-minimal');
|
|
125
|
+
|
|
126
|
+
const geminiIcon = this.document.createElement('div');
|
|
127
|
+
geminiIcon.classList.add('green-dev-anchor-icon-gemini');
|
|
128
|
+
anchor.append(geminiIcon);
|
|
129
|
+
|
|
130
|
+
const openIcon = this.document.createElement('div');
|
|
131
|
+
openIcon.classList.add('green-dev-anchor-icon-open');
|
|
132
|
+
anchor.append(openIcon);
|
|
133
|
+
|
|
134
|
+
const onEvent = (event: MouseEvent) => {
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
openIcon.addEventListener('mousedown', onEvent);
|
|
140
|
+
openIcon.addEventListener('mouseup', onEvent);
|
|
141
|
+
openIcon.addEventListener('mousemove', onEvent);
|
|
142
|
+
openIcon.addEventListener('mouseenter', onEvent);
|
|
143
|
+
openIcon.addEventListener('mouseleave', onEvent);
|
|
144
|
+
openIcon.addEventListener('click', (event: MouseEvent) => {
|
|
145
|
+
onEvent(event);
|
|
146
|
+
window.InspectorOverlayHost.send({highlightType: 'greenDevFloaty', command: 'openDevTools', nodeId});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
anchor.addEventListener('mousedown', onEvent);
|
|
150
|
+
anchor.addEventListener('mouseup', onEvent);
|
|
151
|
+
anchor.addEventListener('mousemove', onEvent);
|
|
152
|
+
anchor.addEventListener('mouseenter', onEvent);
|
|
153
|
+
anchor.addEventListener('mouseleave', onEvent);
|
|
154
|
+
anchor.addEventListener('click', (event: MouseEvent) => {
|
|
155
|
+
if (event.target !== anchor && !anchor.contains(event.target as Node)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
onEvent(event);
|
|
159
|
+
window.InspectorOverlayHost.send({highlightType: 'greenDevFloaty', command: 'restoreFloaty', nodeId});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return anchor;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -9,6 +9,7 @@ import {drawLayoutFlexContainerHighlight, type FlexContainerHighlight} from './h
|
|
|
9
9
|
import {drawLayoutGridHighlight, type GridHighlight} from './highlight_grid_common.js';
|
|
10
10
|
import {drawIsolatedElementHighlight, type IsolatedElementHighlight} from './highlight_isolated_element.js';
|
|
11
11
|
import {drawScrollSnapHighlight, type ScrollSnapHighlight} from './highlight_scroll_snap.js';
|
|
12
|
+
import type {GreenDevAnchorsHighlight, GreenDevAnchorsOverlay} from './tool_green_dev_anchors.js';
|
|
12
13
|
|
|
13
14
|
export interface PersistentToolMessage {
|
|
14
15
|
highlightType: string;
|
|
@@ -65,11 +66,17 @@ export class PersistentOverlay extends Overlay {
|
|
|
65
66
|
initialHeight: number,
|
|
66
67
|
}>();
|
|
67
68
|
private dragHandler?: DragResizeHandler;
|
|
69
|
+
private greenDevAnchorsOverlay?: GreenDevAnchorsOverlay;
|
|
70
|
+
|
|
71
|
+
setGreenDevAnchorsOverlay(greenDevAnchorsOverlay: GreenDevAnchorsOverlay) {
|
|
72
|
+
this.greenDevAnchorsOverlay = greenDevAnchorsOverlay;
|
|
73
|
+
}
|
|
68
74
|
|
|
69
75
|
override reset(data: ResetData) {
|
|
70
76
|
super.reset(data);
|
|
71
77
|
this.gridLabelState.gridLayerCounter = 0;
|
|
72
78
|
this.gridLabels.innerHTML = '';
|
|
79
|
+
this.greenDevAnchorsOverlay?.reset(data);
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
renderGridMarkup() {
|
|
@@ -129,6 +136,13 @@ export class PersistentOverlay extends Overlay {
|
|
|
129
136
|
this.context.restore();
|
|
130
137
|
}
|
|
131
138
|
|
|
139
|
+
drawGreenDevFloatyAnchors(highlights: GreenDevAnchorsHighlight[]) {
|
|
140
|
+
if (this.greenDevAnchorsOverlay && !this.greenDevAnchorsOverlay.installed) {
|
|
141
|
+
this.greenDevAnchorsOverlay.install();
|
|
142
|
+
}
|
|
143
|
+
this.greenDevAnchorsOverlay?.drawGreenDevAnchors(highlights);
|
|
144
|
+
}
|
|
145
|
+
|
|
132
146
|
drawIsolatedElementHighlight(highlight: IsolatedElementHighlight) {
|
|
133
147
|
if (!this.dragHandler) {
|
|
134
148
|
this.dragHandler = new DragResizeHandler(this.document, makeDraggableDelegate(this));
|
package/package.json
CHANGED