chrome-devtools-frontend 1.0.1558690 → 1.0.1561080

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.
Files changed (167) hide show
  1. package/front_end/Images/src/container.svg +4 -0
  2. package/front_end/core/common/Gzip.ts +15 -0
  3. package/front_end/core/host/InspectorFrontendHostStub.ts +0 -3
  4. package/front_end/core/platform/ArrayUtilities.ts +13 -0
  5. package/front_end/core/root/Runtime.ts +0 -5
  6. package/front_end/core/sdk/CSSMetadata.ts +6 -6
  7. package/front_end/core/sdk/CSSModel.ts +2 -2
  8. package/front_end/core/sdk/DOMModel.ts +15 -3
  9. package/front_end/core/sdk/NetworkManager.ts +4 -0
  10. package/front_end/core/sdk/NetworkRequest.ts +9 -0
  11. package/front_end/core/sdk/OverlayModel.ts +20 -9
  12. package/front_end/entrypoints/main/MainImpl.ts +2 -1
  13. package/front_end/generated/InspectorBackendCommands.ts +6 -3
  14. package/front_end/generated/SupportedCSSProperties.js +64 -32
  15. package/front_end/generated/protocol-mapping.d.ts +16 -0
  16. package/front_end/generated/protocol-proxy-api.d.ts +12 -0
  17. package/front_end/generated/protocol.ts +38 -1
  18. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  19. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +11 -7
  20. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +23 -22
  21. package/front_end/models/badges/UserBadges.ts +48 -16
  22. package/front_end/models/greendev/Prototypes.ts +6 -1
  23. package/front_end/models/trace/LanternComputationData.ts +4 -3
  24. package/front_end/models/trace/Processor.ts +6 -5
  25. package/front_end/models/trace/Styles.ts +10 -1
  26. package/front_end/models/trace/extras/TraceTree.ts +1 -1
  27. package/front_end/models/trace/handlers/LargestImagePaintHandler.ts +2 -2
  28. package/front_end/models/trace/handlers/MetaHandler.ts +14 -0
  29. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +59 -34
  30. package/front_end/models/trace/helpers/Timing.ts +8 -1
  31. package/front_end/models/trace/insights/Common.ts +1 -1
  32. package/front_end/models/trace/insights/LCPBreakdown.ts +4 -4
  33. package/front_end/models/trace/insights/LCPDiscovery.ts +3 -3
  34. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  35. package/front_end/models/trace/insights/types.ts +1 -1
  36. package/front_end/models/trace/types/TraceEvents.ts +62 -10
  37. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -142
  38. package/front_end/panels/ai_assistance/PatchWidget.ts +90 -72
  39. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  40. package/front_end/panels/ai_assistance/components/ChatInput.ts +701 -0
  41. package/front_end/panels/ai_assistance/components/ChatView.ts +71 -1268
  42. package/front_end/panels/ai_assistance/components/UserActionRow.ts +514 -31
  43. package/front_end/panels/ai_assistance/components/chatInput.css +387 -0
  44. package/front_end/panels/ai_assistance/components/chatView.css +38 -599
  45. package/front_end/panels/ai_assistance/components/userActionRow.css +230 -0
  46. package/front_end/panels/autofill/AutofillView.ts +2 -2
  47. package/front_end/panels/changes/ChangesView.ts +15 -1
  48. package/front_end/panels/changes/changesView.css +6 -0
  49. package/front_end/panels/common/AiCodeGenerationTeaser.ts +48 -12
  50. package/front_end/panels/common/BadgeNotification.ts +44 -58
  51. package/front_end/panels/common/CopyChangesToPrompt.ts +233 -0
  52. package/front_end/panels/common/aiCodeGenerationTeaser.css +14 -0
  53. package/front_end/panels/common/common.ts +2 -1
  54. package/front_end/panels/console/consoleView.css +1 -1
  55. package/front_end/panels/elements/CSSRuleValidator.ts +38 -0
  56. package/front_end/panels/elements/ElementsTreeElement.ts +222 -377
  57. package/front_end/panels/elements/ElementsTreeOutline.ts +0 -23
  58. package/front_end/panels/elements/ShortcutTreeElement.ts +57 -50
  59. package/front_end/panels/elements/StylePropertiesSection.ts +1 -3
  60. package/front_end/panels/elements/StylesSidebarPane.ts +15 -4
  61. package/front_end/panels/elements/components/AdornerManager.ts +5 -149
  62. package/front_end/panels/issues/HiddenIssuesRow.ts +1 -2
  63. package/front_end/panels/issues/IssueKindView.ts +2 -4
  64. package/front_end/panels/issues/IssueView.ts +2 -4
  65. package/front_end/panels/network/NetworkDataGridNode.ts +65 -1
  66. package/front_end/panels/network/NetworkLogView.ts +2 -4
  67. package/front_end/panels/network/NetworkLogViewColumns.ts +9 -0
  68. package/front_end/panels/screencast/ScreencastApp.ts +1 -0
  69. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  70. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +14 -1
  71. package/front_end/panels/timeline/StatusDialog.ts +4 -3
  72. package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -4
  73. package/front_end/panels/timeline/TimelineController.ts +185 -3
  74. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +52 -25
  75. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +3 -16
  76. package/front_end/panels/timeline/TimelineFlameChartView.ts +65 -21
  77. package/front_end/panels/timeline/TimelinePanel.ts +86 -126
  78. package/front_end/panels/timeline/TimelineTreeView.ts +1 -0
  79. package/front_end/panels/timeline/TimelineUIUtils.ts +28 -2
  80. package/front_end/panels/timeline/TimingsTrackAppender.ts +3 -1
  81. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
  82. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -2
  83. package/front_end/panels/timeline/components/insights/RenderBlocking.ts +6 -4
  84. package/front_end/panels/timeline/components/insights/Table.ts +3 -3
  85. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +4 -0
  86. package/front_end/panels/timeline/timelinePanel.css +8 -1
  87. package/front_end/panels/timeline/utils/EntryNodes.ts +2 -1
  88. package/front_end/panels/whats_new/ReleaseNoteText.ts +15 -9
  89. package/front_end/panels/whats_new/resources/WNDT.md +6 -6
  90. package/front_end/third_party/chromium/README.chromium +1 -1
  91. package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
  92. package/front_end/third_party/lit/rebuild.sh +1 -1
  93. package/front_end/third_party/puppeteer/README.chromium +2 -2
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +2 -3
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +9 -0
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.d.ts +3 -0
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.js +9 -0
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPResponse.js.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts +3 -0
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js +10 -0
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +8 -4
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.d.ts +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.d.ts.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.js +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/injected.js.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  120. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +10 -1
  123. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +13 -7
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +2 -3
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +9 -0
  129. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.d.ts +3 -0
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.js +9 -0
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPResponse.js.map +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts +3 -0
  135. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js +10 -0
  137. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  139. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +8 -4
  140. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.d.ts +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.d.ts.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.js +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/injected.js.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/types.d.ts +10 -1
  151. package/front_end/third_party/puppeteer/package/package.json +3 -3
  152. package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -3
  153. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +13 -0
  154. package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +10 -0
  155. package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +15 -0
  156. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +9 -4
  157. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  158. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  159. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  160. package/front_end/ui/components/adorners/Adorner.ts +8 -68
  161. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +70 -28
  162. package/front_end/ui/legacy/SearchableView.ts +11 -5
  163. package/front_end/ui/legacy/SplitWidget.ts +1 -1
  164. package/front_end/ui/legacy/TabbedPane.ts +1 -1
  165. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +43 -9
  166. package/front_end/ui/visual_logging/KnownContextValues.ts +16 -0
  167. package/package.json +2 -1
@@ -33,6 +33,8 @@
33
33
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
  */
35
35
 
36
+ import '../../ui/components/adorners/adorners.js';
37
+
36
38
  import * as Common from '../../core/common/common.js';
37
39
  import * as Host from '../../core/host/host.js';
38
40
  import * as i18n from '../../core/i18n/i18n.js';
@@ -47,12 +49,12 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
47
49
  import * as Workspace from '../../models/workspace/workspace.js';
48
50
  import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
49
51
  import type {DirectiveResult} from '../../third_party/lit/lib/directive.js';
50
- import * as Adorners from '../../ui/components/adorners/adorners.js';
52
+ import type * as Adorners from '../../ui/components/adorners/adorners.js';
51
53
  import * as Buttons from '../../ui/components/buttons/buttons.js';
52
54
  import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
53
55
  import * as Highlighting from '../../ui/components/highlighting/highlighting.js';
54
56
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
55
- import {createIcon, Icon} from '../../ui/kit/kit.js';
57
+ import {Icon} from '../../ui/kit/kit.js';
56
58
  import * as Components from '../../ui/legacy/components/utils/utils.js';
57
59
  import * as UI from '../../ui/legacy/legacy.js';
58
60
  import * as Lit from '../../ui/lit/lit.js';
@@ -69,7 +71,7 @@ import {type ElementsTreeOutline, MappedCharToEntity} from './ElementsTreeOutlin
69
71
  import {ImagePreviewPopover} from './ImagePreviewPopover.js';
70
72
  import {getRegisteredDecorators, type MarkerDecorator, type MarkerDecoratorRegistration} from './MarkerDecorator.js';
71
73
 
72
- const {html, nothing, render, Directives: {ref, repeat}} = Lit;
74
+ const {html, nothing, render, Directives: {ref}} = Lit;
73
75
 
74
76
  const UIStrings = {
75
77
  /**
@@ -383,6 +385,7 @@ export interface ViewInput {
383
385
 
384
386
  showAdAdorner: boolean;
385
387
  showContainerAdorner: boolean;
388
+ containerType?: string;
386
389
  showFlexAdorner: boolean;
387
390
  showGridAdorner: boolean;
388
391
  showGridLanesAdorner: boolean;
@@ -392,20 +395,27 @@ export interface ViewInput {
392
395
  isSubgrid: boolean;
393
396
 
394
397
  showViewSourceAdorner: boolean;
395
- adorners?: Set<Adorners.Adorner.Adorner>;
398
+ showScrollAdorner: boolean;
399
+ showScrollSnapAdorner: boolean;
396
400
  nodeInfo?: DocumentFragment;
397
401
  topLayerIndex: number;
402
+ scrollSnapAdornerActive: boolean;
398
403
 
399
404
  onGutterClick: (e: Event) => void;
400
- onAdornerAdded: (adorner: Adorners.Adorner.Adorner) => void;
401
- onAdornerRemoved: (adorner: Adorners.Adorner.Adorner) => void;
402
405
  onContainerAdornerClick: (e: Event) => void;
403
406
  onFlexAdornerClick: (e: Event) => void;
404
407
  onGridAdornerClick: (e: Event) => void;
405
408
  onMediaAdornerClick: (e: Event) => void;
406
409
  onPopoverAdornerClick: (e: Event) => void;
410
+ onScrollSnapAdornerClick: (e: Event) => void;
407
411
  onTopLayerAdornerClick: (e: Event) => void;
408
412
  onViewSourceAdornerClick: () => void;
413
+ onSlotAdornerClick: (e: Event) => void;
414
+ showSlotAdorner: boolean;
415
+ slotName?: string;
416
+ showStartingStyleAdorner: boolean;
417
+ startingStyleAdornerActive: boolean;
418
+ onStartingStyleAdornerClick: (e: Event) => void;
409
419
  }
410
420
 
411
421
  export interface ViewOutput {
@@ -414,49 +424,39 @@ export interface ViewOutput {
414
424
  contentElement?: HTMLElement;
415
425
  }
416
426
 
417
- function adornerRef(input: ViewInput): DirectiveResult<typeof Lit.Directives.RefDirective> {
427
+ export function adornerRef(): DirectiveResult<typeof Lit.Directives.RefDirective> {
418
428
  let adorner: Adorners.Adorner.Adorner|undefined;
419
429
  return ref((el?: Element) => {
420
430
  if (adorner) {
421
- input.onAdornerRemoved(adorner);
431
+ ElementsPanel.instance().deregisterAdorner(adorner);
422
432
  }
423
433
  adorner = el as Adorners.Adorner.Adorner;
424
-
425
434
  if (adorner) {
426
435
  if (ElementsPanel.instance().isAdornerEnabled(adorner.name)) {
427
436
  adorner.show();
428
437
  } else {
429
438
  adorner.hide();
430
439
  }
431
- input.onAdornerAdded(adorner);
440
+ ElementsPanel.instance().registerAdorner(adorner);
432
441
  }
433
442
  });
434
443
  }
435
444
 
445
+ function handleAdornerKeydown(cb: (event: Event) => void): (event: KeyboardEvent) => void {
446
+ return (event: KeyboardEvent) => {
447
+ if (event.code === 'Enter' || event.code === 'Space') {
448
+ cb(event);
449
+ event.preventDefault();
450
+ event.stopPropagation();
451
+ }
452
+ };
453
+ }
454
+
436
455
  export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
437
- const adAdornerConfig =
438
- ElementsComponents.AdornerManager.getRegisteredAdorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD);
439
- const viewSourceAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
440
- ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE);
441
- const containerAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
442
- ElementsComponents.AdornerManager.RegisteredAdorners.CONTAINER);
443
- const flexAdornerConfig =
444
- ElementsComponents.AdornerManager.getRegisteredAdorner(ElementsComponents.AdornerManager.RegisteredAdorners.FLEX);
445
- const gridAdornerConfig =
446
- ElementsComponents.AdornerManager.getRegisteredAdorner(ElementsComponents.AdornerManager.RegisteredAdorners.GRID);
447
- const subgridAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
448
- ElementsComponents.AdornerManager.RegisteredAdorners.SUBGRID);
449
- const gridLanesAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
450
- ElementsComponents.AdornerManager.RegisteredAdorners.GRID_LANES);
451
- const mediaAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
452
- ElementsComponents.AdornerManager.RegisteredAdorners.MEDIA);
453
- const popoverAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
454
- ElementsComponents.AdornerManager.RegisteredAdorners.POPOVER);
455
- const topLayerAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
456
- ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER);
457
- const hasAdorners = input.adorners?.size || input.showAdAdorner || input.showContainerAdorner ||
458
- input.showFlexAdorner || input.showGridAdorner || input.showGridLanesAdorner || input.showMediaAdorner ||
459
- input.showPopoverAdorner || input.showTopLayerAdorner || input.showViewSourceAdorner;
456
+ const hasAdorners = input.showAdAdorner || input.showContainerAdorner || input.showFlexAdorner ||
457
+ input.showGridAdorner || input.showGridLanesAdorner || input.showMediaAdorner || input.showPopoverAdorner ||
458
+ input.showTopLayerAdorner || input.showViewSourceAdorner || input.showScrollAdorner ||
459
+ input.showScrollSnapAdorner || input.showSlotAdorner || input.showStartingStyleAdorner;
460
460
  // clang-format off
461
461
  render(html`
462
462
  <div ${ref(el => { output.contentElement = el as HTMLElement; })}>
@@ -468,113 +468,90 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
468
468
  ${hasAdorners ? html`<div class="adorner-container ${!hasAdorners ? 'hidden' : ''}">
469
469
  ${input.showAdAdorner ? html`<devtools-adorner
470
470
  aria-label=${i18nString(UIStrings.thisFrameWasIdentifiedAsAnAd)}
471
- .data=${{name: adAdornerConfig.name, jslogContext: adAdornerConfig.name}}
472
- ${adornerRef(input)}>
473
- <span>${adAdornerConfig.name}</span>
471
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.AD}
472
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD)}
473
+ ${adornerRef()}>
474
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.AD}</span>
474
475
  </devtools-adorner>` : nothing}
475
476
  ${input.showViewSourceAdorner ? html`<devtools-adorner
476
- .data=${{name: viewSourceAdornerConfig.name, jslogContext: viewSourceAdornerConfig.name}}
477
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE}
478
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE)}
477
479
  aria-label=${i18nString(UIStrings.viewSourceCode)}
478
480
  @click=${input.onViewSourceAdornerClick}
479
- ${adornerRef(input)}>
480
- <span>${viewSourceAdornerConfig.name}</span>
481
+ ${adornerRef()}>
482
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE}</span>
481
483
  </devtools-adorner>` : nothing}
482
484
  ${input.showContainerAdorner ? html`<devtools-adorner
483
485
  class=clickable
484
486
  role=button
485
487
  toggleable=true
486
488
  tabindex=0
487
- .data=${{name: containerAdornerConfig.name, jslogContext: containerAdornerConfig.name}}
488
- jslog=${VisualLogging.adorner(containerAdornerConfig.name).track({click: true})}
489
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.CONTAINER}
490
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.CONTAINER).track({click: true})}
489
491
  active=${input.containerAdornerActive}
490
492
  aria-label=${input.containerAdornerActive ? i18nString(UIStrings.enableContainer) : i18nString(UIStrings.disableContainer)}
491
493
  @click=${input.onContainerAdornerClick}
492
- @keydown=${(event: KeyboardEvent) => {
493
- if (event.code === 'Enter' || event.code === 'Space') {
494
- input.onContainerAdornerClick(event);
495
- event.stopPropagation();
496
- }
497
- }}
498
- ${adornerRef(input)}>
499
- <span>${containerAdornerConfig.name}</span>
494
+ @keydown=${handleAdornerKeydown(input.onContainerAdornerClick)}
495
+ ${adornerRef()}>
496
+ <span class="adorner-with-icon">
497
+ <devtools-icon name="container"></devtools-icon>
498
+ <span>${input.containerType}</span>
499
+ </span>
500
500
  </devtools-adorner>`: nothing}
501
501
  ${input.showFlexAdorner ? html`<devtools-adorner
502
502
  class=clickable
503
503
  role=button
504
504
  toggleable=true
505
505
  tabindex=0
506
- .data=${{name: flexAdornerConfig.name, jslogContext: flexAdornerConfig.name}}
507
- jslog=${VisualLogging.adorner(flexAdornerConfig.name).track({click: true})}
506
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.FLEX}
507
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.FLEX).track({click: true})}
508
508
  active=${input.flexAdornerActive}
509
509
  aria-label=${input.flexAdornerActive ? i18nString(UIStrings.disableFlexMode) : i18nString(UIStrings.enableFlexMode)}
510
510
  @click=${input.onFlexAdornerClick}
511
- @keydown=${(event: KeyboardEvent) => {
512
- if (event.code === 'Enter' || event.code === 'Space') {
513
- input.onFlexAdornerClick(event);
514
- event.stopPropagation();
515
- }
516
- }}
517
- ${adornerRef(input)}>
518
- <span>${flexAdornerConfig.name}</span>
511
+ @keydown=${handleAdornerKeydown(input.onFlexAdornerClick)}
512
+ ${adornerRef()}>
513
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.FLEX}</span>
519
514
  </devtools-adorner>`: nothing}
520
515
  ${input.showGridAdorner ? html`<devtools-adorner
521
516
  class=clickable
522
517
  role=button
523
518
  toggleable=true
524
519
  tabindex=0
525
- .data=${{
526
- name: input.isSubgrid ? subgridAdornerConfig.name : gridAdornerConfig.name,
527
- jslogContext: input.isSubgrid ? subgridAdornerConfig.name : gridAdornerConfig.name,
528
- }}
529
- jslog=${VisualLogging.adorner(input.isSubgrid ? subgridAdornerConfig.name : gridAdornerConfig.name).track({click: true})}
520
+ .name=${input.isSubgrid ? ElementsComponents.AdornerManager.RegisteredAdorners.SUBGRID : ElementsComponents.AdornerManager.RegisteredAdorners.GRID}
521
+ jslog=${VisualLogging.adorner(input.isSubgrid ? ElementsComponents.AdornerManager.RegisteredAdorners.SUBGRID : ElementsComponents.AdornerManager.RegisteredAdorners.GRID).track({click: true})}
530
522
  active=${input.gridAdornerActive}
531
523
  aria-label=${input.gridAdornerActive ? i18nString(UIStrings.disableGridMode) : i18nString(UIStrings.enableGridMode)}
532
524
  @click=${input.onGridAdornerClick}
533
- @keydown=${(event: KeyboardEvent) => {
534
- if (event.code === 'Enter' || event.code === 'Space') {
535
- input.onGridAdornerClick(event);
536
- event.stopPropagation();
537
- }
538
- }}
539
- ${adornerRef(input)}>
540
- <span>${input.isSubgrid ? subgridAdornerConfig.name : gridAdornerConfig.name}</span>
525
+ @keydown=${handleAdornerKeydown(input.onGridAdornerClick)}
526
+ ${adornerRef()}>
527
+ <span>${input.isSubgrid ? ElementsComponents.AdornerManager.RegisteredAdorners.SUBGRID : ElementsComponents.AdornerManager.RegisteredAdorners.GRID}</span>
541
528
  </devtools-adorner>`: nothing}
542
529
  ${input.showGridLanesAdorner ? html`<devtools-adorner
543
530
  class=clickable
544
531
  role=button
545
532
  toggleable=true
546
533
  tabindex=0
547
- .data=${{name: gridLanesAdornerConfig.name, jslogContext: gridLanesAdornerConfig.name}}
548
- jslog=${VisualLogging.adorner(gridLanesAdornerConfig.name).track({click: true})}
534
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.GRID_LANES}
535
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.GRID_LANES).track({click: true})}
549
536
  active=${input.gridAdornerActive}
550
537
  aria-label=${input.gridAdornerActive ? i18nString(UIStrings.disableGridLanesMode) : i18nString(UIStrings.enableGridLanesMode)}
551
538
  @click=${input.onGridAdornerClick}
552
- @keydown=${(event: KeyboardEvent) => {
553
- if (event.code === 'Enter' || event.code === 'Space') {
554
- input.onGridAdornerClick(event);
555
- event.stopPropagation();
556
- }
557
- }}
558
- ${adornerRef(input)}>
559
- <span>${gridLanesAdornerConfig.name}</span>
539
+ @keydown=${handleAdornerKeydown(input.onGridAdornerClick)}
540
+ ${adornerRef()}>
541
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.GRID_LANES}</span>
560
542
  </devtools-adorner>`: nothing}
561
543
  ${input.showMediaAdorner ? html`<devtools-adorner
562
544
  class=clickable
563
545
  role=button
564
546
  tabindex=0
565
- .data=${{name: mediaAdornerConfig.name, jslogContext: mediaAdornerConfig.name}}
566
- jslog=${VisualLogging.adorner(mediaAdornerConfig.name).track({click: true})}
547
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.MEDIA}
548
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.MEDIA).track({click: true})}
567
549
  aria-label=${i18nString(UIStrings.openMediaPanel)}
568
550
  @click=${input.onMediaAdornerClick}
569
- @keydown=${(event: KeyboardEvent) => {
570
- if (event.code === 'Enter' || event.code === 'Space') {
571
- input.onMediaAdornerClick(event);
572
- event.stopPropagation();
573
- }
574
- }}
575
- ${adornerRef(input)}>
551
+ @keydown=${handleAdornerKeydown(input.onMediaAdornerClick)}
552
+ ${adornerRef()}>
576
553
  <span class="adorner-with-icon">
577
- ${mediaAdornerConfig.name}<devtools-icon name="select-element"></devtools-icon>
554
+ ${ElementsComponents.AdornerManager.RegisteredAdorners.MEDIA}<devtools-icon name="select-element"></devtools-icon>
578
555
  </span>
579
556
  </devtools-adorner>`: nothing}
580
557
  ${input.showPopoverAdorner ? html`<devtools-adorner
@@ -582,42 +559,75 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
582
559
  role=button
583
560
  toggleable=true
584
561
  tabindex=0
585
- .data=${{name: popoverAdornerConfig.name, jslogContext: popoverAdornerConfig.name}}
586
- jslog=${VisualLogging.adorner(popoverAdornerConfig.name).track({click: true})}
562
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.POPOVER}
563
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.POPOVER).track({click: true})}
587
564
  active=${input.popoverAdornerActive}
588
565
  aria-label=${input.popoverAdornerActive ? i18nString(UIStrings.stopForceOpenPopover) : i18nString(UIStrings.forceOpenPopover)}
589
566
  @click=${input.onPopoverAdornerClick}
590
- @keydown=${(event: KeyboardEvent) => {
591
- if (event.code === 'Enter' || event.code === 'Space') {
592
- input.onPopoverAdornerClick(event);
593
- event.stopPropagation();
594
- }
595
- }}
596
- ${adornerRef(input)}>
597
- <span>${popoverAdornerConfig.name}</span>
567
+ @keydown=${handleAdornerKeydown(input.onPopoverAdornerClick)}
568
+ ${adornerRef()}>
569
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.POPOVER}</span>
598
570
  </devtools-adorner>`: nothing}
599
571
  ${input.showTopLayerAdorner ? html`<devtools-adorner
600
572
  class=clickable
601
573
  role=button
602
574
  tabindex=0
603
- .data=${{name: topLayerAdornerConfig.name, jslogContext: topLayerAdornerConfig.name}}
604
- jslog=${VisualLogging.adorner(topLayerAdornerConfig.name).track({click: true})}
575
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER}
576
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER).track({click: true})}
605
577
  aria-label=${i18nString(UIStrings.reveal)}
606
578
  @click=${input.onTopLayerAdornerClick}
607
- @keydown=${(event: KeyboardEvent) => {
608
- if (event.code === 'Enter' || event.code === 'Space') {
609
- input.onTopLayerAdornerClick(event);
610
- event.stopPropagation();
611
- }
612
- }}
613
- ${adornerRef(input)}>
579
+ @keydown=${handleAdornerKeydown(input.onTopLayerAdornerClick)}
580
+ ${adornerRef()}>
614
581
  <span class="adorner-with-icon">
615
582
  ${`top-layer (${input.topLayerIndex})`}<devtools-icon name="select-element"></devtools-icon>
616
583
  </span>
617
584
  </devtools-adorner>`: nothing}
618
- ${repeat(Array.from((input.adorners ?? new Set()).values()).sort(adornerComparator), adorner => {
619
- return adorner;
620
- })}
585
+ ${input.showStartingStyleAdorner ? html`<devtools-adorner
586
+ class="starting-style"
587
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.STARTING_STYLE}
588
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.STARTING_STYLE).track({click: true})}
589
+ active=${input.startingStyleAdornerActive}
590
+ toggleable=true
591
+ aria-label=${input.startingStyleAdornerActive ? i18nString(UIStrings.disableStartingStyle) : i18nString(UIStrings.enableStartingStyle)}
592
+ @click=${input.onStartingStyleAdornerClick}
593
+ @keydown=${handleAdornerKeydown(input.onStartingStyleAdornerClick)}
594
+ ${adornerRef()}>
595
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.STARTING_STYLE}</span>
596
+ </devtools-adorner>` : nothing}
597
+ ${input.showScrollAdorner ? html`<devtools-adorner
598
+ class="scroll"
599
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL}
600
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL).track({click: true})}
601
+ aria-label=${i18nString(UIStrings.elementHasScrollableOverflow)}
602
+ ${adornerRef()}>
603
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL}</span>
604
+ </devtools-adorner>` : nothing}
605
+ ${input.showSlotAdorner ? html`<devtools-adorner
606
+ class=clickable
607
+ role=button
608
+ tabindex=0
609
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.SLOT}
610
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.SLOT).track({click: true})}
611
+ @click=${input.onSlotAdornerClick}
612
+ @mousedown=${(e: Event) => e.stopPropagation()}
613
+ ${adornerRef()}>
614
+ <span class="adorner-with-icon">
615
+ <devtools-icon name="select-element"></devtools-icon>
616
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.SLOT}</span>
617
+ </span>
618
+ </devtools-adorner>`: nothing}
619
+ ${input.showScrollSnapAdorner ? html`<devtools-adorner
620
+ class="scroll-snap"
621
+ .name=${ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP}
622
+ jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP).track({click: true})}
623
+ active=${input.scrollSnapAdornerActive}
624
+ toggleable=true
625
+ aria-label=${input.scrollSnapAdornerActive ? i18nString(UIStrings.disableScrollSnap) : i18nString(UIStrings.enableScrollSnap)}
626
+ @click=${input.onScrollSnapAdornerClick}
627
+ @keydown=${handleAdornerKeydown(input.onScrollSnapAdornerClick)}
628
+ ${adornerRef()}>
629
+ <span>${ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP}</span>
630
+ </devtools-adorner>` : nothing}
621
631
  </div>`: nothing}
622
632
  </div>
623
633
  `, target);
@@ -651,12 +661,14 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
651
661
  readonly tagTypeContext: TagTypeContext;
652
662
 
653
663
  #adornersThrottler = new Common.Throttler.Throttler(100);
654
- #adorners = new Set<Adorners.Adorner.Adorner>();
655
664
  #nodeInfo?: DocumentFragment;
656
665
  #containerAdornerActive = false;
657
666
  #flexAdornerActive = false;
658
667
  #gridAdornerActive = false;
659
668
  #popoverAdornerActive = false;
669
+
670
+ #scrollSnapAdornerActive = false;
671
+ #startingStyleAdornerActive = false;
660
672
  #layout: SDK.CSSModel.LayoutProperties|null = null;
661
673
 
662
674
  constructor(node: SDK.DOMModel.DOMNode, isClosingTag?: boolean) {
@@ -687,10 +699,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
687
699
  tagType: TagType.OPENING,
688
700
  canAddAttributes: this.nodeInternal.nodeType() === Node.ELEMENT_NODE,
689
701
  };
690
- void this.updateStyleAdorners();
691
-
692
- void this.updateScrollAdorner();
693
-
694
702
  void this.#updateAdorners();
695
703
  }
696
704
  this.expandAllButtonElement = null;
@@ -711,34 +719,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
711
719
  if (this.nodeInternal.detached && !this.isClosingTag()) {
712
720
  this.listItemNode.setAttribute('title', 'Detached Tree Node');
713
721
  }
714
-
715
- node.domModel().overlayModel().addEventListener(
716
- SDK.OverlayModel.Events.PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED, event => {
717
- const {nodeId: eventNodeId, enabled} = event.data;
718
- if (eventNodeId !== node.id) {
719
- return;
720
- }
721
- this.#containerAdornerActive = enabled;
722
- this.performUpdate();
723
- });
724
- node.domModel().overlayModel().addEventListener(
725
- SDK.OverlayModel.Events.PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED, event => {
726
- const {nodeId: eventNodeId, enabled} = event.data;
727
- if (eventNodeId !== node.id) {
728
- return;
729
- }
730
- this.#flexAdornerActive = enabled;
731
- this.performUpdate();
732
- });
733
- node.domModel().overlayModel().addEventListener(
734
- SDK.OverlayModel.Events.PERSISTENT_GRID_OVERLAY_STATE_CHANGED, event => {
735
- const {nodeId: eventNodeId, enabled} = event.data;
736
- if (eventNodeId !== node.id) {
737
- return;
738
- }
739
- this.#gridAdornerActive = enabled;
740
- this.performUpdate();
741
- });
742
722
  }
743
723
 
744
724
  static animateOnDOMUpdate(treeElement: ElementsTreeElement): void {
@@ -794,17 +774,13 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
794
774
  }
795
775
  }
796
776
 
797
- get adorners(): Adorners.Adorner.Adorner[] {
798
- return Array.from(this.#adorners);
799
- }
800
-
801
777
  performUpdate(): void {
802
778
  DEFAULT_VIEW(
803
779
  {
804
780
  containerAdornerActive: this.#containerAdornerActive,
805
- adorners: !this.isClosingTag() ? this.#adorners : undefined,
806
781
  showAdAdorner: this.nodeInternal.isAdFrameNode(),
807
- showContainerAdorner: Boolean(this.#layout?.isContainer) && !this.isClosingTag(),
782
+ showContainerAdorner: Boolean(this.#layout?.containerType) && !this.isClosingTag(),
783
+ containerType: this.#layout?.containerType,
808
784
  showFlexAdorner: Boolean(this.#layout?.isFlex) && !this.isClosingTag(),
809
785
  flexAdornerActive: this.#flexAdornerActive,
810
786
  showGridAdorner: Boolean(this.#layout?.isGrid) && !this.isClosingTag(),
@@ -817,21 +793,33 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
817
793
  popoverAdornerActive: this.#popoverAdornerActive,
818
794
  isSubgrid: Boolean(this.#layout?.isSubgrid),
819
795
  showViewSourceAdorner: this.nodeInternal.isRootNode() && isOpeningTag(this.tagTypeContext),
796
+ showScrollAdorner: ((this.node().nodeName() === 'HTML' && this.node().ownerDocument?.isScrollable()) ||
797
+ (this.node().nodeName() !== '#document' && this.node().isScrollable())) &&
798
+ !this.isClosingTag(),
799
+ showScrollSnapAdorner: Boolean(this.#layout?.hasScroll) && !this.isClosingTag(),
800
+ scrollSnapAdornerActive: this.#scrollSnapAdornerActive,
801
+ showSlotAdorner: Boolean(this.nodeInternal.assignedSlot) && !this.isClosingTag(),
802
+ showStartingStyleAdorner: this.nodeInternal.affectedByStartingStyles() && !this.isClosingTag(),
803
+ startingStyleAdornerActive: this.#startingStyleAdornerActive,
820
804
  nodeInfo: this.#nodeInfo,
805
+ onStartingStyleAdornerClick: (event: Event) => this.#onStartingStyleAdornerClick(event),
806
+ onSlotAdornerClick: () => {
807
+ if (this.nodeInternal.assignedSlot) {
808
+ const deferredNode = this.nodeInternal.assignedSlot.deferredNode;
809
+ deferredNode.resolve(node => {
810
+ void Common.Revealer.reveal(node);
811
+ });
812
+ }
813
+ },
821
814
  topLayerIndex: this.node().topLayerIndex(),
822
815
  onViewSourceAdornerClick: this.revealHTMLInSources.bind(this),
823
816
  onGutterClick: this.showContextMenu.bind(this),
824
- onAdornerAdded: adorner => {
825
- ElementsPanel.instance().registerAdorner(adorner);
826
- },
827
- onAdornerRemoved: adorner => {
828
- ElementsPanel.instance().deregisterAdorner(adorner);
829
- },
830
817
  onContainerAdornerClick: (event: Event) => this.#onContainerAdornerClick(event),
831
818
  onFlexAdornerClick: (event: Event) => this.#onFlexAdornerClick(event),
832
819
  onGridAdornerClick: (event: Event) => this.#onGridAdornerClick(event),
833
820
  onMediaAdornerClick: (event: Event) => this.#onMediaAdornerClick(event),
834
821
  onPopoverAdornerClick: (event: Event) => this.#onPopoverAdornerClick(event),
822
+ onScrollSnapAdornerClick: (event: Event) => this.#onScrollSnapAdornerClick(event),
835
823
  onTopLayerAdornerClick: () => {
836
824
  if (!this.treeOutline) {
837
825
  return;
@@ -1054,25 +1042,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1054
1042
  this.#expandedChildrenLimit = expandedChildrenLimit;
1055
1043
  }
1056
1044
 
1057
- createSlotLink(nodeShortcut: SDK.DOMModel.DOMNodeShortcut|null): void {
1058
- if (!isOpeningTag(this.tagTypeContext)) {
1059
- return;
1060
- }
1061
- if (nodeShortcut) {
1062
- const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
1063
- ElementsComponents.AdornerManager.RegisteredAdorners.SLOT);
1064
- const adorner = this.adornSlot(config);
1065
- this.#adorners.add(adorner);
1066
- const deferredNode = nodeShortcut.deferredNode;
1067
- adorner.addEventListener('click', () => {
1068
- deferredNode.resolve(node => {
1069
- void Common.Revealer.reveal(node);
1070
- });
1071
- });
1072
- adorner.addEventListener('mousedown', e => e.consume(), false);
1073
- }
1074
- }
1075
-
1076
1045
  private createSelection(): void {
1077
1046
  const contentElement = this.contentElement;
1078
1047
  if (!contentElement) {
@@ -1124,6 +1093,19 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1124
1093
  if (this.treeOutline && !this.isClosingTag()) {
1125
1094
  this.treeOutline.treeElementByNode.set(this.nodeInternal, this);
1126
1095
  this.nodeInternal.addEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.performUpdate, this);
1096
+ this.nodeInternal.addEventListener(
1097
+ SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1098
+ this.nodeInternal.addEventListener(
1099
+ SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1100
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1101
+ this.nodeInternal.addEventListener(
1102
+ SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1103
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1104
+ this.nodeInternal.addEventListener(
1105
+ SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged, this);
1106
+ this.nodeInternal.addEventListener(
1107
+ SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED, this.#onPersistentScrollSnapOverlayStateChanged,
1108
+ this);
1127
1109
  }
1128
1110
  }
1129
1111
 
@@ -1135,6 +1117,58 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1135
1117
  this.treeOutline.treeElementByNode.delete(this.nodeInternal);
1136
1118
  }
1137
1119
  this.nodeInternal.removeEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.performUpdate, this);
1120
+ this.nodeInternal.removeEventListener(
1121
+ SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1122
+ this.nodeInternal.removeEventListener(
1123
+ SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1124
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1125
+ this.nodeInternal.removeEventListener(
1126
+ SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1127
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1128
+ this.nodeInternal.removeEventListener(
1129
+ SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged, this);
1130
+ this.nodeInternal.removeEventListener(
1131
+ SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED, this.#onPersistentScrollSnapOverlayStateChanged,
1132
+ this);
1133
+ }
1134
+
1135
+ #onScrollableFlagUpdated(): void {
1136
+ void this.#updateAdorners();
1137
+ }
1138
+
1139
+ #onPersistentContainerQueryOverlayStateChanged(event: Common.EventTarget.EventTargetEvent<{enabled: boolean}>): void {
1140
+ this.#containerAdornerActive = event.data.enabled;
1141
+ this.performUpdate();
1142
+ }
1143
+
1144
+ #onPersistentFlexContainerOverlayStateChanged(event: Common.EventTarget.EventTargetEvent<{enabled: boolean}>): void {
1145
+ this.#flexAdornerActive = event.data.enabled;
1146
+ this.performUpdate();
1147
+ }
1148
+
1149
+ #onPersistentGridOverlayStateChanged(event: Common.EventTarget.EventTargetEvent<{enabled: boolean}>): void {
1150
+ this.#gridAdornerActive = event.data.enabled;
1151
+ this.performUpdate();
1152
+ }
1153
+
1154
+ #onPersistentScrollSnapOverlayStateChanged(event: Common.EventTarget.EventTargetEvent<{enabled: boolean}>): void {
1155
+ this.#scrollSnapAdornerActive = event.data.enabled;
1156
+ this.performUpdate();
1157
+ }
1158
+
1159
+ #onScrollSnapAdornerClick(event: Event): void {
1160
+ event.stopPropagation();
1161
+ const node = this.node();
1162
+ const nodeId = node.id;
1163
+ if (!nodeId) {
1164
+ return;
1165
+ }
1166
+ const model = node.domModel().overlayModel();
1167
+ if (this.#scrollSnapAdornerActive) {
1168
+ model.hideScrollSnapInPersistentOverlay(nodeId);
1169
+ } else {
1170
+ model.highlightScrollSnapInPersistentOverlay(nodeId);
1171
+ }
1138
1172
  }
1139
1173
 
1140
1174
  override onattach(): void {
@@ -1492,7 +1526,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1492
1526
  ],
1493
1527
  },
1494
1528
  {
1495
- condition: (props: SDK.CSSModel.LayoutProperties|null): boolean => Boolean(props?.isContainer),
1529
+ condition: (props: SDK.CSSModel.LayoutProperties|null): boolean => Boolean(props?.containerType),
1496
1530
  items: [
1497
1531
  {
1498
1532
  label: i18nString(UIStrings.explainContainerQueries),
@@ -2851,69 +2885,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2851
2885
  });
2852
2886
  }
2853
2887
 
2854
- // TODO: add unit tests for adorner-related methods after component and TypeScript works are done
2855
- adorn({name}: {name: string}, content?: HTMLElement): Adorners.Adorner.Adorner {
2856
- let adornerContent = content;
2857
- if (!adornerContent) {
2858
- adornerContent = document.createElement('span');
2859
- adornerContent.textContent = name;
2860
- }
2861
- const adorner = new Adorners.Adorner.Adorner();
2862
- adorner.data = {
2863
- name,
2864
- content: adornerContent,
2865
- jslogContext: name,
2866
- };
2867
- if (isOpeningTag(this.tagTypeContext)) {
2868
- this.#adorners.add(adorner);
2869
- ElementsPanel.instance().registerAdorner(adorner);
2870
- this.updateAdorners();
2871
- }
2872
- return adorner;
2873
- }
2874
-
2875
- adornSlot({name}: {name: string}): Adorners.Adorner.Adorner {
2876
- const linkIcon = createIcon('select-element');
2877
- const slotText = document.createElement('span');
2878
- slotText.textContent = name;
2879
- const adornerContent = document.createElement('span');
2880
- adornerContent.append(linkIcon);
2881
- adornerContent.append(slotText);
2882
- adornerContent.classList.add('adorner-with-icon');
2883
- const adorner = new Adorners.Adorner.Adorner();
2884
- adorner.data = {
2885
- name,
2886
- content: adornerContent,
2887
- jslogContext: 'slot',
2888
- };
2889
- this.#adorners.add(adorner);
2890
- ElementsPanel.instance().registerAdorner(adorner);
2891
- this.updateAdorners();
2892
- return adorner;
2893
- }
2894
-
2895
- removeAdorner(adornerToRemove: Adorners.Adorner.Adorner): void {
2896
- ElementsPanel.instance().deregisterAdorner(adornerToRemove);
2897
- adornerToRemove.remove();
2898
- this.#adorners.delete(adornerToRemove);
2899
- this.updateAdorners();
2900
- }
2901
-
2902
- /**
2903
- * @param adornerType optional type of adorner to remove. If not provided, remove all adorners.
2904
- */
2905
- removeAdornersByType(adornerType?: ElementsComponents.AdornerManager.RegisteredAdorners): void {
2906
- if (!isOpeningTag(this.tagTypeContext)) {
2907
- return;
2908
- }
2909
-
2910
- for (const adorner of this.#adorners) {
2911
- if (adorner.name === adornerType || !adornerType) {
2912
- this.removeAdorner(adorner);
2913
- }
2914
- }
2915
- }
2916
-
2917
2888
  updateAdorners(): void {
2918
2889
  // TODO: remove adornersThrottler in favour of throttled updated (requestUpdate/performUpdate).
2919
2890
  void this.#adornersThrottler.schedule(this.#updateAdorners.bind(this));
@@ -2921,7 +2892,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2921
2892
 
2922
2893
  async #updateAdorners(): Promise<void> {
2923
2894
  if (this.isClosingTag()) {
2924
- this.performUpdate();
2925
2895
  return;
2926
2896
  }
2927
2897
  const node = this.node();
@@ -2935,41 +2905,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2935
2905
  this.performUpdate();
2936
2906
  }
2937
2907
 
2938
- // TODO: remove in favour of updateAdorners.
2939
- async updateStyleAdorners(): Promise<void> {
2940
- if (!isOpeningTag(this.tagTypeContext)) {
2941
- return;
2942
- }
2943
-
2944
- const node = this.node();
2945
- const nodeId = node.id;
2946
- if (node.nodeType() === Node.COMMENT_NODE || node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE ||
2947
- node.nodeType() === Node.TEXT_NODE || nodeId === undefined) {
2948
- return;
2949
- }
2950
- const layout = await node.domModel().cssModel().getLayoutPropertiesFromComputedStyle(nodeId);
2951
- // TODO: move this to the template.
2952
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.SUBGRID);
2953
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.GRID);
2954
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.GRID_LANES);
2955
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.FLEX);
2956
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP);
2957
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.MEDIA);
2958
- this.removeAdornersByType(ElementsComponents.AdornerManager.RegisteredAdorners.STARTING_STYLE);
2959
- if (layout) {
2960
- if (layout.hasScroll) {
2961
- this.pushScrollSnapAdorner();
2962
- }
2963
- }
2964
-
2965
- if (Root.Runtime.hostConfig.devToolsStartingStyleDebugging?.enabled) {
2966
- const affectedByStartingStyles = node.affectedByStartingStyles();
2967
- if (affectedByStartingStyles) {
2968
- this.pushStartingStyleAdorner();
2969
- }
2970
- }
2971
- }
2972
-
2973
2908
  async #onPopoverAdornerClick(event: Event): Promise<void> {
2974
2909
  event.stopPropagation();
2975
2910
  const node = this.node();
@@ -2985,102 +2920,21 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2985
2920
  this.performUpdate();
2986
2921
  }
2987
2922
 
2988
- pushScrollSnapAdorner(): void {
2989
- const node = this.node();
2990
- const nodeId = node.id;
2991
- if (!nodeId) {
2992
- return;
2993
- }
2994
- const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
2995
- ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP);
2996
- const adorner = this.adorn(config);
2997
- adorner.classList.add('scroll-snap');
2998
-
2999
- const onClick = ((() => {
3000
- const model = node.domModel().overlayModel();
3001
- if (adorner.isActive()) {
3002
- model.highlightScrollSnapInPersistentOverlay(nodeId);
3003
- } else {
3004
- model.hideScrollSnapInPersistentOverlay(nodeId);
3005
- }
3006
- }) as EventListener);
3007
-
3008
- adorner.addInteraction(onClick, {
3009
- isToggle: true,
3010
- shouldPropagateOnKeydown: false,
3011
- ariaLabelDefault: i18nString(UIStrings.enableScrollSnap),
3012
- ariaLabelActive: i18nString(UIStrings.disableScrollSnap),
3013
- });
3014
-
3015
- node.domModel().overlayModel().addEventListener(
3016
- SDK.OverlayModel.Events.PERSISTENT_SCROLL_SNAP_OVERLAY_STATE_CHANGED, event => {
3017
- const {nodeId: eventNodeId, enabled} = event.data;
3018
- if (eventNodeId !== nodeId) {
3019
- return;
3020
- }
3021
- adorner.toggle(enabled);
3022
- });
3023
-
3024
- this.#adorners.add(adorner);
3025
-
3026
- if (node.domModel().overlayModel().isHighlightedScrollSnapInPersistentOverlay(nodeId)) {
3027
- adorner.toggle(true);
3028
- }
3029
- }
3030
-
3031
- pushStartingStyleAdorner(): void {
2923
+ #onStartingStyleAdornerClick(event: Event): void {
2924
+ event.stopPropagation();
3032
2925
  const node = this.node();
3033
2926
  const nodeId = node.id;
3034
2927
  if (!nodeId) {
3035
2928
  return;
3036
2929
  }
3037
- const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
3038
- ElementsComponents.AdornerManager.RegisteredAdorners.STARTING_STYLE);
3039
- const adorner = this.adorn(config);
3040
- adorner.classList.add('starting-style');
3041
-
3042
- const onClick = ((() => {
3043
- const model = node.domModel().cssModel();
3044
- if (adorner.isActive()) {
3045
- model.forceStartingStyle(node, true);
3046
- } else {
3047
- model.forceStartingStyle(node, false);
3048
- }
3049
- }) as EventListener);
3050
-
3051
- adorner.addInteraction(onClick, {
3052
- isToggle: true,
3053
- shouldPropagateOnKeydown: false,
3054
- ariaLabelDefault: i18nString(UIStrings.enableStartingStyle),
3055
- ariaLabelActive: i18nString(UIStrings.disableStartingStyle),
3056
- });
3057
-
3058
- this.#adorners.add(adorner);
3059
- }
3060
-
3061
- updateScrollAdorner(): void {
3062
- if (!isOpeningTag(this.tagTypeContext)) {
3063
- return;
3064
- }
3065
- const scrollAdorner =
3066
- this.#adorners.values().find(x => x.name === ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL);
3067
- // Check if the node is scrollable, or if it's the <html> element and the document is scrollable
3068
- // because the top-level document (#document) doesn't have a corresponding tree element.
3069
- const needsAScrollAdorner = (this.node().nodeName() === 'HTML' && this.node().ownerDocument?.isScrollable()) ||
3070
- (this.node().nodeName() !== '#document' && this.node().isScrollable());
3071
- if (needsAScrollAdorner && !scrollAdorner) {
3072
- this.pushScrollAdorner();
3073
- } else if (!needsAScrollAdorner && scrollAdorner) {
3074
- this.removeAdorner(scrollAdorner);
2930
+ const model = node.domModel().cssModel();
2931
+ if (this.#startingStyleAdornerActive) {
2932
+ model.forceStartingStyle(node, false);
2933
+ } else {
2934
+ model.forceStartingStyle(node, true);
3075
2935
  }
3076
- }
3077
-
3078
- pushScrollAdorner(): void {
3079
- const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
3080
- ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL);
3081
- const adorner = this.adorn(config);
3082
- UI.Tooltip.Tooltip.install(adorner, i18nString(UIStrings.elementHasScrollableOverflow));
3083
- adorner.classList.add('scroll');
2936
+ this.#startingStyleAdornerActive = !this.#startingStyleAdornerActive;
2937
+ this.performUpdate();
3084
2938
  }
3085
2939
  }
3086
2940
 
@@ -3098,15 +2952,6 @@ export const ForbiddenClosingTagElements = new Set<string>([
3098
2952
  /** These tags we do not allow editing their tag name. **/
3099
2953
  export const EditTagBlocklist = new Set<string>(['html', 'head', 'body']);
3100
2954
 
3101
- export function adornerComparator(adornerA: Adorners.Adorner.Adorner, adornerB: Adorners.Adorner.Adorner): number {
3102
- const compareCategories =
3103
- ElementsComponents.AdornerManager.compareAdornerNamesByCategory(adornerB.name, adornerB.name);
3104
- if (compareCategories === 0) {
3105
- return adornerA.name.localeCompare(adornerB.name);
3106
- }
3107
- return compareCategories;
3108
- }
3109
-
3110
2955
  export function convertUnicodeCharsToHTMLEntities(text: string): {
3111
2956
  text: string,
3112
2957
  entityRanges: TextUtils.TextRange.SourceRange[],