chrome-devtools-frontend 1.0.1589336 → 1.0.1590494

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 (44) hide show
  1. package/front_end/core/common/Settings.ts +30 -1
  2. package/front_end/generated/Deprecation.ts +7 -0
  3. package/front_end/generated/InspectorBackendCommands.ts +9 -3
  4. package/front_end/generated/protocol-mapping.d.ts +9 -0
  5. package/front_end/generated/protocol-proxy-api.d.ts +7 -0
  6. package/front_end/generated/protocol.ts +98 -0
  7. package/front_end/models/javascript_metadata/NativeFunctions.js +48 -0
  8. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +140 -32
  9. package/front_end/panels/ai_assistance/README.md +71 -0
  10. package/front_end/panels/ai_assistance/aiAssistancePanel.css +5 -0
  11. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  12. package/front_end/panels/ai_assistance/components/ChatMessage.ts +110 -7
  13. package/front_end/panels/ai_assistance/components/ChatView.ts +10 -0
  14. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +208 -0
  15. package/front_end/panels/ai_assistance/components/chatMessage.css +2 -2
  16. package/front_end/panels/ai_assistance/components/walkthroughView.css +121 -0
  17. package/front_end/panels/application/DeviceBoundSessionsView.ts +64 -2
  18. package/front_end/panels/console/ConsoleView.ts +8 -8
  19. package/front_end/panels/console/console-meta.ts +10 -6
  20. package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +14 -14
  21. package/front_end/panels/elements/ComputedStyleWidget.ts +27 -22
  22. package/front_end/panels/elements/ElementsTreeElement.ts +56 -2
  23. package/front_end/panels/elements/ElementsTreeOutline.ts +2 -0
  24. package/front_end/panels/elements/StyleEditorWidget.ts +12 -12
  25. package/front_end/panels/elements/StylePropertiesSection.ts +65 -64
  26. package/front_end/panels/elements/StylePropertyTreeElement.ts +138 -135
  27. package/front_end/panels/elements/StylesContainer.ts +57 -0
  28. package/front_end/panels/elements/StylesSidebarPane.ts +2 -1
  29. package/front_end/panels/layer_viewer/Layers3DView.ts +2 -2
  30. package/front_end/panels/network/RequestInitiatorView.ts +3 -2
  31. package/front_end/panels/timeline/timeline-meta.ts +4 -4
  32. package/front_end/panels/whats_new/ReleaseNoteText.ts +10 -16
  33. package/front_end/panels/whats_new/resources/WNDT.md +6 -6
  34. package/front_end/third_party/chromium/README.chromium +1 -1
  35. package/front_end/ui/components/markdown_view/MarkdownView.ts +5 -6
  36. package/front_end/ui/components/markdown_view/markdownView.css +6 -0
  37. package/front_end/ui/components/markdown_view/markdown_view.ts +0 -2
  38. package/front_end/ui/legacy/Treeoutline.ts +58 -10
  39. package/front_end/ui/legacy/Widget.ts +11 -1
  40. package/front_end/ui/legacy/inspectorCommon.css +2 -0
  41. package/front_end/ui/visual_logging/KnownContextValues.ts +11 -1
  42. package/package.json +1 -1
  43. package/front_end/ui/components/markdown_view/MarkdownLink.ts +0 -53
  44. package/front_end/ui/components/markdown_view/markdownLink.css +0 -11
@@ -93,21 +93,6 @@ const UIStrings = {
93
93
  const str_ = i18n.i18n.registerUIStrings('panels/elements/ComputedStyleWidget.ts', UIStrings);
94
94
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
95
95
 
96
- /**
97
- * Rendering a property's name and value is expensive, and each time we do it
98
- * it generates a new HTML element. If we call this directly from our Lit
99
- * components, we will generate a brand new DOM element on each single render.
100
- * This is very expensive and unnecessary - for the majority of re-renders a
101
- * property's name and value does not change. So we cache the rest of rendering
102
- * the name and value in a map, where the key used is a combination of the
103
- * property's name and value. This ensures that we only re-generate this element
104
- * if the node itself changes.
105
- * The resulting Element nodes are inserted into the ComputedStyleProperty
106
- * component via <slot>s, ensuring that Lit doesn't directly render/re-render
107
- * the element.
108
- */
109
- const propertyContentsCache = new Map<string, {name: Element, value: Element}>();
110
-
111
96
  function matchProperty(name: string, value: string): SDK.CSSPropertyParser.BottomUpTreeMatching|null {
112
97
  return SDK.CSSPropertyParser.matchDeclaration(name, value, [
113
98
  new SDK.CSSPropertyParserMatchers.ColorMatcher(), new SDK.CSSPropertyParserMatchers.URLMatcher(),
@@ -116,9 +101,10 @@ function matchProperty(name: string, value: string): SDK.CSSPropertyParser.Botto
116
101
  }
117
102
 
118
103
  function renderPropertyContents(
119
- node: SDK.DOMModel.DOMNode, propertyName: string, propertyValue: string): {name: Element, value: Element} {
104
+ node: SDK.DOMModel.DOMNode, cache: Map<string, {name: Element, value: Element}>, propertyName: string,
105
+ propertyValue: string): {name: Element, value: Element} {
120
106
  const cacheKey = propertyName + ':' + propertyValue;
121
- const valueFromCache = propertyContentsCache.get(cacheKey);
107
+ const valueFromCache = cache.get(cacheKey);
122
108
  if (valueFromCache) {
123
109
  return valueFromCache;
124
110
  }
@@ -130,7 +116,7 @@ function renderPropertyContents(
130
116
  [new ColorRenderer(), new URLRenderer(null, node), new StringRenderer()])
131
117
  .valueElement;
132
118
  value.slot = 'value';
133
- propertyContentsCache.set(cacheKey, {name, value});
119
+ cache.set(cacheKey, {name, value});
134
120
  return {name, value};
135
121
  }
136
122
 
@@ -139,10 +125,11 @@ function renderPropertyContents(
139
125
  * to ensure nothing expensive runs here, or if it does it is safely cached.
140
126
  **/
141
127
  const createPropertyElement =
142
- (node: SDK.DOMModel.DOMNode, propertyName: string, propertyValue: string, traceable: boolean, inherited: boolean,
128
+ (node: SDK.DOMModel.DOMNode, cache: Map<string, {name: Element, value: Element}>, propertyName: string,
129
+ propertyValue: string, traceable: boolean, inherited: boolean,
143
130
  activeProperty: SDK.CSSProperty.CSSProperty|undefined,
144
131
  onContextMenu: ((event: Event) => void)): Lit.TemplateResult => {
145
- const {name, value} = renderPropertyContents(node, propertyName, propertyValue);
132
+ const {name, value} = renderPropertyContents(node, cache, propertyName, propertyValue);
146
133
  // clang-format off
147
134
  return html`<devtools-computed-style-property
148
135
  .traceable=${traceable}
@@ -315,6 +302,24 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
315
302
  private filterRegex: RegExp|null;
316
303
  private readonly linkifier: Components.Linkifier.Linkifier;
317
304
  private readonly imagePreviewPopover: ImagePreviewPopover;
305
+ /**
306
+ * Rendering a property's name and value is expensive, and each time we do it
307
+ * it generates a new HTML element. If we call this directly from our Lit
308
+ * components, we will generate a brand new DOM element on each single render.
309
+ * This is very expensive and unnecessary - for the majority of re-renders a
310
+ * property's name and value does not change. So we cache the rest of rendering
311
+ * the name and value in a map, where the key used is a combination of the
312
+ * property's name and value. This ensures that we only re-generate this element
313
+ * if the node itself changes.
314
+ * The resulting Element nodes are inserted into the ComputedStyleProperty
315
+ * component via <slot>s, ensuring that Lit doesn't directly render/re-render
316
+ * the element.
317
+ * We have to store this cache per widget because it is possible to have
318
+ * multiple widgets for the same NodeId showing at once. In that case, if we
319
+ * reuse the same element from the cache, only one of the widgets will be
320
+ * populated, because an HTML node cannot be in two locations at once.
321
+ */
322
+ #propertyElementsCache = new Map<string, {name: Element, value: Element}>();
318
323
 
319
324
  #computedStylesTree = new TreeOutline.TreeOutline.TreeOutline<ComputedStyleData>();
320
325
  #treeData?: TreeOutline.TreeOutline.TreeOutlineData<ComputedStyleData>;
@@ -559,8 +564,8 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
559
564
  const activeProperty = trace?.find(
560
565
  property => matchedStyles.propertyState(property) === SDK.CSSMatchedStyles.PropertyState.ACTIVE);
561
566
  const propertyElement = createPropertyElement(
562
- domNode, data.propertyName, data.propertyValue, propertyTraces.has(data.propertyName), data.inherited,
563
- activeProperty, event => {
567
+ domNode, this.#propertyElementsCache, data.propertyName, data.propertyValue,
568
+ propertyTraces.has(data.propertyName), data.inherited, activeProperty, event => {
564
569
  if (activeProperty) {
565
570
  this.handleContextMenuEvent(matchedStyles, activeProperty, event);
566
571
  }
@@ -113,6 +113,10 @@ const UIStrings = {
113
113
  * @description A context menu item in the Elements Tree Element of the Elements panel
114
114
  */
115
115
  editAsHtml: 'Edit as HTML',
116
+ /**
117
+ * @description A context menu item in the Elements Tree Element of the Elements panel
118
+ */
119
+ editData: 'Edit data',
116
120
  /**
117
121
  * @description Text to cut an element, cut should be used as a verb
118
122
  */
@@ -628,6 +632,18 @@ function renderTitle(
628
632
  Platform.StringUtilities.collapseWhitespace(node.nodeNameInCorrectCase())}</span>`;
629
633
  }
630
634
 
635
+ case Node.PROCESSING_INSTRUCTION_NODE: {
636
+ const nodeValue = node.nodeValue();
637
+ const maybeSpace = nodeValue ? ' ' : '';
638
+ return html`<span class="webkit-html-processing-instruction">&lt;?<span
639
+ class="webkit-html-tag-name" jslog=${VisualLogging.value('tag-name').track({change: true, dblclick: true})}>${
640
+ node.nodeName()}</span>${maybeSpace}<span class="webkit-html-processing-instruction-value" jslog=${
641
+ VisualLogging.value('processing-instruction-value').track({
642
+ change: true,
643
+ dblclick: true,
644
+ })}>${nodeValue}</span>?&gt;</span>`;
645
+ }
646
+
631
647
  default: {
632
648
  return html`${Platform.StringUtilities.collapseWhitespace(node.nodeNameInCorrectCase())}`;
633
649
  }
@@ -1785,11 +1801,13 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1785
1801
  return false;
1786
1802
  }
1787
1803
 
1788
- if (this.nodeInternal.nodeType() !== Node.ELEMENT_NODE && this.nodeInternal.nodeType() !== Node.TEXT_NODE) {
1804
+ if (this.nodeInternal.nodeType() !== Node.ELEMENT_NODE && this.nodeInternal.nodeType() !== Node.TEXT_NODE &&
1805
+ this.nodeInternal.nodeType() !== Node.PROCESSING_INSTRUCTION_NODE) {
1789
1806
  return false;
1790
1807
  }
1791
1808
 
1792
- const textNode = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-text-node');
1809
+ const textNode = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-text-node') ??
1810
+ eventTarget.enclosingNodeOrSelfWithClass('webkit-html-processing-instruction-value');
1793
1811
  if (textNode) {
1794
1812
  return this.startEditingTextNode(textNode);
1795
1813
  }
@@ -2127,6 +2145,24 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2127
2145
  }
2128
2146
  }
2129
2147
 
2148
+ async populateProcessingElementContextMenu(contextMenu: UI.ContextMenu.ContextMenu): Promise<void> {
2149
+ const treeOutline = this.treeOutline;
2150
+ if (!treeOutline) {
2151
+ return;
2152
+ }
2153
+
2154
+ contextMenu.editSection().appendItem(
2155
+ i18nString(UIStrings.editData), this.startEditingProcessingInstructionValue.bind(this),
2156
+ {jslogContext: 'elements.edit-data'});
2157
+ contextMenu.editSection().appendItem(
2158
+ i18nString(UIStrings.duplicateElement), treeOutline.duplicateNode.bind(treeOutline, this.nodeInternal), {
2159
+ disabled: (this.nodeInternal.isInShadowTree()),
2160
+ jslogContext: 'elements.duplicate-element',
2161
+ });
2162
+ contextMenu.editSection().appendItem(
2163
+ i18nString(UIStrings.deleteElement), this.remove.bind(this), {jslogContext: 'delete-element'});
2164
+ }
2165
+
2130
2166
  private startEditing(): boolean|undefined {
2131
2167
  if (!this.treeOutline || this.treeOutline.selectedDOMNode() !== this.nodeInternal) {
2132
2168
  return;
@@ -2151,6 +2187,19 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2151
2187
  }
2152
2188
  }
2153
2189
 
2190
+ if (this.nodeInternal.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2191
+ return this.startEditingProcessingInstructionValue();
2192
+ }
2193
+
2194
+ return;
2195
+ }
2196
+
2197
+ private startEditingProcessingInstructionValue(): boolean|undefined {
2198
+ const processingInstructionValue =
2199
+ this.listItemElement.getElementsByClassName('webkit-html-processing-instruction-value')[0];
2200
+ if (processingInstructionValue) {
2201
+ return this.startEditingTextNode(processingInstructionValue);
2202
+ }
2154
2203
  return;
2155
2204
  }
2156
2205
 
@@ -2586,6 +2635,11 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2586
2635
  }
2587
2636
 
2588
2637
  function moveToNextAttributeIfNeeded(this: ElementsTreeElement): void {
2638
+ if (this.nodeInternal.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2639
+ this.startEditingProcessingInstructionValue();
2640
+ return;
2641
+ }
2642
+
2589
2643
  if (moveDirection !== 'forward') {
2590
2644
  this.addNewAttribute();
2591
2645
  return;
@@ -1332,6 +1332,8 @@ export class ElementsTreeOutline extends
1332
1332
  await treeElement.populateNodeContextMenu(contextMenu);
1333
1333
  } else if (isPseudoElement) {
1334
1334
  treeElement.populatePseudoElementContextMenu(contextMenu);
1335
+ } else if (treeElement.node().nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
1336
+ await treeElement.populateProcessingElementContextMenu(contextMenu);
1335
1337
  }
1336
1338
 
1337
1339
  ElementsPanel.instance().populateAdornerSettingsContextMenu(contextMenu);
@@ -9,7 +9,7 @@ import * as UI from '../../ui/legacy/legacy.js';
9
9
  import type * as ElementsComponents from './components/components.js';
10
10
  import type {StylePropertiesSection} from './StylePropertiesSection.js';
11
11
  import {StylePropertyTreeElement} from './StylePropertyTreeElement.js';
12
- import type {StylesSidebarPane} from './StylesSidebarPane.js';
12
+ import type {StylesContainer} from './StylesContainer.js';
13
13
 
14
14
  type PropertySelectedEvent = ElementsComponents.StylePropertyEditor.PropertySelectedEvent;
15
15
  type PropertyDeselectedEvent = ElementsComponents.StylePropertyEditor.PropertyDeselectedEvent;
@@ -29,7 +29,7 @@ interface Editor extends HTMLElement {
29
29
  */
30
30
  export class StyleEditorWidget extends UI.Widget.VBox {
31
31
  private editor?: Editor;
32
- private pane?: StylesSidebarPane;
32
+ private stylesContainer?: StylesContainer;
33
33
  private section?: StylePropertiesSection;
34
34
  private editorContainer: HTMLElement;
35
35
 
@@ -69,8 +69,8 @@ export class StyleEditorWidget extends UI.Widget.VBox {
69
69
  await this.render();
70
70
  }
71
71
 
72
- bindContext(pane: StylesSidebarPane, section: StylePropertiesSection): void {
73
- this.pane = pane;
72
+ bindContext(stylesContainer: StylesContainer, section: StylePropertiesSection): void {
73
+ this.stylesContainer = stylesContainer;
74
74
  this.section = section;
75
75
  this.editor?.addEventListener('propertyselected', this.onPropertySelected);
76
76
  this.editor?.addEventListener('propertydeselected', this.onPropertyDeselected);
@@ -85,7 +85,7 @@ export class StyleEditorWidget extends UI.Widget.VBox {
85
85
  }
86
86
 
87
87
  unbindContext(): void {
88
- this.pane = undefined;
88
+ this.stylesContainer = undefined;
89
89
  this.section = undefined;
90
90
  this.editor?.removeEventListener('propertyselected', this.onPropertySelected);
91
91
  this.editor?.removeEventListener('propertydeselected', this.onPropertyDeselected);
@@ -98,7 +98,7 @@ export class StyleEditorWidget extends UI.Widget.VBox {
98
98
  this.editor.data = {
99
99
  authoredProperties: this.section ? getAuthoredStyles(this.section, this.editor.getEditableProperties()) :
100
100
  new Map(),
101
- computedProperties: this.pane ? await fetchComputedStyles(this.pane) : new Map(),
101
+ computedProperties: this.stylesContainer ? await fetchComputedStyles(this.stylesContainer) : new Map(),
102
102
  };
103
103
  }
104
104
 
@@ -118,19 +118,19 @@ export class StyleEditorWidget extends UI.Widget.VBox {
118
118
  }
119
119
 
120
120
  static createTriggerButton(
121
- pane: StylesSidebarPane, section: StylePropertiesSection, editorClass: {new(): Editor}, buttonTitle: string,
122
- triggerKey: string): HTMLElement {
121
+ stylesContainer: StylesContainer, section: StylePropertiesSection, editorClass: {new(): Editor},
122
+ buttonTitle: string, triggerKey: string): HTMLElement {
123
123
  const triggerButton = createIcon('flex-wrap', 'styles-pane-button');
124
124
  triggerButton.title = buttonTitle;
125
125
  triggerButton.role = 'button';
126
126
 
127
127
  triggerButton.onclick = async event => {
128
128
  event.stopPropagation();
129
- const popoverHelper = pane.swatchPopoverHelper();
129
+ const popoverHelper = stylesContainer.swatchPopoverHelper();
130
130
  const widget = StyleEditorWidget.instance();
131
131
  widget.element.classList.toggle('with-padding', true);
132
132
  widget.setEditor(editorClass);
133
- widget.bindContext(pane, section);
133
+ widget.bindContext(stylesContainer, section);
134
134
  widget.setTriggerKey(triggerKey);
135
135
  await widget.render();
136
136
  widget.focus();
@@ -168,8 +168,8 @@ function ensureTreeElementForProperty(section: StylePropertiesSection, propertyN
168
168
  return newTarget;
169
169
  }
170
170
 
171
- async function fetchComputedStyles(pane: StylesSidebarPane): Promise<Map<string, string>> {
172
- const computedStyleModel = pane.computedStyleModel();
171
+ async function fetchComputedStyles(stylesContainer: StylesContainer): Promise<Map<string, string>> {
172
+ const computedStyleModel = stylesContainer.computedStyleModel();
173
173
  const style = await computedStyleModel.fetchComputedStyle();
174
174
  return style ? style.computedStyle : new Map();
175
175
  }