chrome-devtools-frontend 1.0.1593518 → 1.0.1595090

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 (111) hide show
  1. package/docs/contributing/settings-experiments-features.md +93 -98
  2. package/front_end/core/common/README.md +126 -0
  3. package/front_end/core/host/UserMetrics.ts +1 -2
  4. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  5. package/front_end/core/root/ExperimentNames.ts +0 -1
  6. package/front_end/core/sdk/CSSModel.ts +22 -0
  7. package/front_end/core/sdk/CSSNavigation.ts +33 -0
  8. package/front_end/core/sdk/CSSRule.ts +12 -2
  9. package/front_end/core/sdk/EmulationModel.ts +41 -1
  10. package/front_end/core/sdk/sdk-meta.ts +22 -18
  11. package/front_end/core/sdk/sdk.ts +2 -0
  12. package/front_end/design_system_tokens.css +538 -259
  13. package/front_end/entrypoints/main/MainImpl.ts +0 -6
  14. package/front_end/entrypoints/main/main-meta.ts +2 -2
  15. package/front_end/generated/InspectorBackendCommands.ts +6 -4
  16. package/front_end/generated/SupportedCSSProperties.js +12 -0
  17. package/front_end/generated/protocol-mapping.d.ts +7 -0
  18. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  19. package/front_end/generated/protocol.ts +47 -0
  20. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -0
  21. package/front_end/models/emulation/DeviceModeModel.ts +47 -0
  22. package/front_end/models/issues_manager/Issue.ts +1 -0
  23. package/front_end/models/issues_manager/IssueAggregator.ts +9 -9
  24. package/front_end/models/issues_manager/IssuesManager.ts +5 -5
  25. package/front_end/models/issues_manager/SelectivePermissionsInterventionIssue.ts +65 -0
  26. package/front_end/models/issues_manager/descriptions/selectivePermissionsIntervention.md +7 -0
  27. package/front_end/models/issues_manager/issues_manager.ts +2 -4
  28. package/front_end/models/javascript_metadata/NativeFunctions.js +48 -9
  29. package/front_end/models/lighthouse/lighthouse.ts +9 -0
  30. package/front_end/models/persistence/persistence-meta.ts +4 -4
  31. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +12 -1
  32. package/front_end/panels/ai_assistance/components/ChatInput.ts +37 -30
  33. package/front_end/panels/ai_assistance/components/ChatView.ts +4 -2
  34. package/front_end/panels/ai_assistance/components/chatInput.css +26 -1
  35. package/front_end/panels/application/StorageView.ts +8 -2
  36. package/front_end/panels/application/preloading/PreloadingView.ts +105 -7
  37. package/front_end/panels/application/preloading/preloadingView.css +4 -0
  38. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +3 -0
  39. package/front_end/panels/common/AiCodeGenerationTeaser.ts +3 -0
  40. package/front_end/panels/console/ConsoleView.ts +2 -2
  41. package/front_end/panels/console/console-meta.ts +18 -14
  42. package/front_end/panels/elements/ComputedStyleWidget.ts +12 -7
  43. package/front_end/panels/elements/ElementsPanel.ts +1 -1
  44. package/front_end/panels/elements/ElementsTreeOutline.ts +4 -6
  45. package/front_end/panels/elements/ImagePreviewPopover.ts +6 -9
  46. package/front_end/panels/elements/StylePropertiesSection.ts +30 -0
  47. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +1 -6
  48. package/front_end/panels/elements/StylesSidebarPane.ts +92 -7
  49. package/front_end/panels/elements/elements-meta.ts +12 -8
  50. package/front_end/panels/emulation/DeviceModeToolbar.ts +206 -66
  51. package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +120 -0
  52. package/front_end/panels/issues/HiddenIssuesRow.ts +1 -1
  53. package/front_end/panels/issues/IssueKindView.ts +2 -1
  54. package/front_end/panels/issues/IssueView.ts +4 -4
  55. package/front_end/panels/issues/IssuesPane.ts +8 -2
  56. package/front_end/panels/issues/issues.ts +2 -0
  57. package/front_end/panels/lighthouse/LighthouseController.ts +3 -3
  58. package/front_end/panels/lighthouse/LighthousePanel.ts +9 -5
  59. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +5 -5
  60. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +6 -7
  61. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +4 -3
  62. package/front_end/panels/lighthouse/LighthouseStartView.ts +99 -38
  63. package/front_end/panels/lighthouse/LighthouseTimespanView.ts +53 -14
  64. package/front_end/panels/lighthouse/RadioSetting.ts +33 -19
  65. package/front_end/panels/lighthouse/lighthouse.ts +2 -2
  66. package/front_end/panels/media/PlayerMessagesView.ts +62 -49
  67. package/front_end/panels/media/media.ts +2 -0
  68. package/front_end/panels/media/playerMessagesView.css +1 -1
  69. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +49 -24
  70. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +2 -2
  71. package/front_end/panels/sources/sources-meta.ts +8 -4
  72. package/front_end/panels/utils/utils.ts +11 -5
  73. package/front_end/third_party/chromium/README.chromium +1 -1
  74. package/front_end/third_party/lit/lib/async-directive.d.ts +465 -0
  75. package/front_end/third_party/lit/lib/async-directive.js +23 -0
  76. package/front_end/third_party/lit/lib/async-directive.js.map +1 -0
  77. package/front_end/third_party/lit/lib/decorators.d.ts +7 -1
  78. package/front_end/third_party/lit/lib/decorators.js +2 -2
  79. package/front_end/third_party/lit/lib/decorators.js.map +1 -1
  80. package/front_end/third_party/lit/lib/directive.js.map +1 -1
  81. package/front_end/third_party/lit/lib/directives.d.ts +27 -8
  82. package/front_end/third_party/lit/lib/directives.js +8 -8
  83. package/front_end/third_party/lit/lib/directives.js.map +1 -1
  84. package/front_end/third_party/lit/lib/lit.d.ts +15 -5
  85. package/front_end/third_party/lit/lib/lit.js +4 -4
  86. package/front_end/third_party/lit/lib/lit.js.map +1 -1
  87. package/front_end/third_party/lit/lib/static-html.js +2 -2
  88. package/front_end/third_party/lit/lib/static-html.js.map +1 -1
  89. package/front_end/third_party/lit/lit.ts +2 -1
  90. package/front_end/third_party/lit/rollup.config.mjs +1 -1
  91. package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
  92. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  93. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +1 -1
  94. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -1
  95. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +1 -1
  96. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +1 -1
  97. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -1
  98. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +2 -2
  99. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -0
  100. package/front_end/ui/legacy/SuggestBox.ts +4 -0
  101. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  102. package/front_end/ui/legacy/components/utils/ImagePreview.ts +27 -23
  103. package/front_end/ui/lit/lit.ts +1 -0
  104. package/front_end/ui/visual_logging/Debugging.ts +1 -1
  105. package/front_end/ui/visual_logging/KnownContextValues.ts +19 -0
  106. package/inspector_overlay/highlight_grid_common.ts +11 -8
  107. package/package.json +1 -1
  108. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +0 -78
  109. package/front_end/models/issues_manager/LowTextContrastIssue.ts +0 -63
  110. package/front_end/panels/issues/AffectedElementsWithLowContrastView.ts +0 -91
  111. /package/front_end/{panels → models}/lighthouse/LighthouseReporterTypes.ts +0 -0
@@ -25,6 +25,10 @@
25
25
  button.toolbar-has-dropdown {
26
26
  margin: var(--sys-size-2) 0;
27
27
  }
28
+
29
+ .toolbar-filter {
30
+ max-width: var(--sys-size-29);
31
+ }
28
32
  }
29
33
 
30
34
  devtools-split-view {
@@ -70,6 +70,9 @@ function getTooltipDisclaimerText(noLogging: boolean, panel: AiCodeCompletion.Ai
70
70
  return noLogging ?
71
71
  lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionNoLoggingInSources) :
72
72
  lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionInSources);
73
+ case AiCodeCompletion.AiCodeCompletion.ContextFlavor.STYLES:
74
+ // TODO(476101019): update with string for styles pane
75
+ return '';
73
76
  }
74
77
  }
75
78
 
@@ -147,6 +147,9 @@ function getTooltipDisclaimerText(noLogging: boolean, panel: AiCodeCompletion.Ai
147
147
  return noLogging ?
148
148
  lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeGenerationNoLoggingInSources) :
149
149
  lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeGenerationInSources);
150
+ case AiCodeCompletion.AiCodeCompletion.ContextFlavor.STYLES:
151
+ // TODO(476101019): update with string for styles pane
152
+ return '';
150
153
  }
151
154
  }
152
155
 
@@ -107,11 +107,11 @@ const UIStrings = {
107
107
  /**
108
108
  * @description Title of a setting under the Console category that can be invoked through the Command Menu
109
109
  */
110
- groupSimilarMessagesInConsole: 'Group similar messages in console',
110
+ groupSimilarMessagesInConsole: 'Group similar messages',
111
111
  /**
112
112
  * @description Title of a setting under the Console category that can be invoked through the Command Menu
113
113
  */
114
- showCorsErrorsInConsole: 'Show `CORS` errors in console',
114
+ showCorsErrorsInConsole: 'CORS errors in console',
115
115
  /**
116
116
  * @description Tooltip for the the console sidebar toggle in the Console panel. Command to
117
117
  * open/show the sidebar.
@@ -62,11 +62,11 @@ const UIStrings = {
62
62
  */
63
63
  timestamps: 'Timestamps',
64
64
  /**
65
- * @description Title of a setting under the Console category that can be invoked through the Command Menu
65
+ * @description Title of an option under the Console category that can be invoked through the Command Menu
66
66
  */
67
67
  showTimestamps: 'Show timestamps',
68
68
  /**
69
- * @description Title of a setting under the Console category that can be invoked through the Command Menu
69
+ * @description Title of an option under the Console category that can be invoked through the Command Menu
70
70
  */
71
71
  hideTimestamps: 'Hide timestamps',
72
72
  /**
@@ -88,19 +88,23 @@ const UIStrings = {
88
88
  /**
89
89
  * @description Title of a setting under the Console category that can be invoked through the Command Menu
90
90
  */
91
- groupSimilarMessagesInConsole: 'Group similar messages in console',
91
+ groupSimilarMessages: 'Group similar messages',
92
92
  /**
93
93
  * @description Title of a setting under the Console category that can be invoked through the Command Menu
94
94
  */
95
- doNotGroupSimilarMessagesIn: 'Do not group similar messages in console',
95
+ doNotGroupSimilarMessages: 'Don\'t group similar messages',
96
96
  /**
97
- * @description Title of a setting under the Console category that can be invoked through the Command Menu
97
+ * @description Title of a setting under the Console category in Settings
98
98
  */
99
- showCorsErrorsInConsole: 'Show `CORS` errors in console',
99
+ corsErrorsInConsole: 'CORS errors in console',
100
100
  /**
101
- * @description Title of a setting under the Console category that can be invoked through the Command Menu
101
+ * @description Title of an option under the Console category that can be invoked through the Command Menu
102
+ */
103
+ showCorsErrorsInConsole: 'Show CORS errors in console',
104
+ /**
105
+ * @description Title of an option under the Console category that can be invoked through the Command Menu
102
106
  */
103
- doNotShowCorsErrorsIn: 'Do not show `CORS` errors in console',
107
+ doNotShowCorsErrorsIn: 'Don\'t show CORS errors in console',
104
108
  /**
105
109
  * @description Title of a setting under the Console category in Settings
106
110
  */
@@ -137,7 +141,7 @@ const UIStrings = {
137
141
  * @description Title of a setting under the Console category in Settings that controls whether AI summaries should
138
142
  * be shown for console warnings/errors.
139
143
  */
140
- showConsoleInsightTeasers: 'Show AI summaries for console messages',
144
+ consoleInsightTeasers: 'AI summaries for console messages',
141
145
  } as const;
142
146
  const str_ = i18n.i18n.registerUIStrings('panels/console/console-meta.ts', UIStrings);
143
147
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
@@ -342,25 +346,25 @@ Common.Settings.registerSettingExtension({
342
346
  Common.Settings.registerSettingExtension({
343
347
  category: Common.Settings.SettingCategory.CONSOLE,
344
348
  storageType: Common.Settings.SettingStorageType.SYNCED,
345
- title: i18nLazyString(UIStrings.groupSimilarMessagesInConsole),
349
+ title: i18nLazyString(UIStrings.groupSimilarMessages),
346
350
  settingName: 'console-group-similar',
347
351
  settingType: Common.Settings.SettingType.BOOLEAN,
348
352
  defaultValue: true,
349
353
  options: [
350
354
  {
351
355
  value: true,
352
- title: i18nLazyString(UIStrings.groupSimilarMessagesInConsole),
356
+ title: i18nLazyString(UIStrings.groupSimilarMessages),
353
357
  },
354
358
  {
355
359
  value: false,
356
- title: i18nLazyString(UIStrings.doNotGroupSimilarMessagesIn),
360
+ title: i18nLazyString(UIStrings.doNotGroupSimilarMessages),
357
361
  },
358
362
  ],
359
363
  });
360
364
 
361
365
  Common.Settings.registerSettingExtension({
362
366
  category: Common.Settings.SettingCategory.CONSOLE,
363
- title: i18nLazyString(UIStrings.showCorsErrorsInConsole),
367
+ title: i18nLazyString(UIStrings.corsErrorsInConsole),
364
368
  settingName: 'console-shows-cors-errors',
365
369
  settingType: Common.Settings.SettingType.BOOLEAN,
366
370
  defaultValue: true,
@@ -436,7 +440,7 @@ Common.Settings.registerSettingExtension({
436
440
  Common.Settings.registerSettingExtension({
437
441
  category: Common.Settings.SettingCategory.CONSOLE,
438
442
  storageType: Common.Settings.SettingStorageType.SYNCED,
439
- title: i18nLazyString(UIStrings.showConsoleInsightTeasers),
443
+ title: i18nLazyString(UIStrings.consoleInsightTeasers),
440
444
  settingName: 'console-insight-teasers-enabled',
441
445
  settingType: Common.Settings.SettingType.BOOLEAN,
442
446
  defaultValue: true,
@@ -353,13 +353,18 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
353
353
 
354
354
  this.filterRegex = null;
355
355
  this.linkifier = new Components.Linkifier.Linkifier(maxLinkLength);
356
- this.imagePreviewPopover = new ImagePreviewPopover(this.contentElement, event => {
357
- const link = event.composedPath()[0];
358
- if (link instanceof Element) {
359
- return link;
360
- }
361
- return null;
362
- }, () => this.#computedStyleModel ? this.#computedStyleModel.node : null);
356
+ this.imagePreviewPopover = new ImagePreviewPopover(
357
+ this.contentElement,
358
+ event => {
359
+ const link = event.composedPath()[0];
360
+ if (link instanceof Element) {
361
+ return link;
362
+ }
363
+ return null;
364
+ },
365
+ async () => {
366
+ return await Components.ImagePreview.loadPrecomputedFeatures(this.#computedStyleModel?.node);
367
+ });
363
368
 
364
369
  this.#updateView({hasMatches: true});
365
370
  }
@@ -1556,7 +1556,7 @@ export class DOMNodeRevealer implements
1556
1556
  }
1557
1557
 
1558
1558
  if (resolvedNode) {
1559
- const opts: RevealAndSelectNodeOpts = {showPanel: true, focusNode: !omitFocus};
1559
+ const opts: RevealAndSelectNodeOpts = omitFocus ? {showPanel: false} : {showPanel: true, focusNode: true};
1560
1560
  const promise = resolvedNode instanceof SDK.DOMModel.AdoptedStyleSheet ?
1561
1561
  panel.revealAndSelectAdoptedStyleSheet(resolvedNode, opts) :
1562
1562
  panel.revealAndSelectNode(resolvedNode, opts);
@@ -43,6 +43,7 @@ import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
43
43
  import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
44
44
  import * as Highlighting from '../../ui/components/highlighting/highlighting.js';
45
45
  import * as IssueCounter from '../../ui/components/issue_counter/issue_counter.js';
46
+ import * as UIComponentUtils from '../../ui/legacy/components/utils/utils.js';
46
47
  import * as UI from '../../ui/legacy/legacy.js';
47
48
  import {html, nothing, render} from '../../ui/lit/lit.js';
48
49
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -555,18 +556,15 @@ export class ElementsTreeOutline extends
555
556
  }
556
557
  return link;
557
558
  },
558
- link => {
559
+ async link => {
559
560
  const listItem = UI.UIUtils.enclosingNodeOrSelfWithNodeName(link, 'li');
560
561
  if (!listItem) {
561
- return null;
562
+ return undefined;
562
563
  }
563
564
 
564
565
  const treeElement =
565
566
  (UI.TreeOutline.TreeElement.getTreeElementBylistItemNode(listItem) as ElementsTreeElement | undefined);
566
- if (!treeElement) {
567
- return null;
568
- }
569
- return treeElement.node();
567
+ return await UIComponentUtils.ImagePreview.loadPrecomputedFeatures(treeElement?.node());
570
568
  });
571
569
 
572
570
  this.updateRecords = new Map();
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import type * as Platform from '../../core/platform/platform.js';
6
- import type * as SDK from '../../core/sdk/sdk.js';
7
6
  import * as Components from '../../ui/legacy/components/utils/utils.js';
8
7
  import * as UI from '../../ui/legacy/legacy.js';
9
8
 
@@ -15,13 +14,15 @@ import * as UI from '../../ui/legacy/legacy.js';
15
14
  */
16
15
  export class ImagePreviewPopover {
17
16
  private readonly getLinkElement: (arg0: Event) => Element | null;
18
- private readonly getDOMNode: (arg0: Element) => SDK.DOMModel.DOMNode | null;
19
17
  private readonly popover: UI.PopoverHelper.PopoverHelper;
18
+
19
+ #getNodeFeatures: (link: Element) => Promise<Components.ImagePreview.PrecomputedFeatures|undefined>;
20
+
20
21
  constructor(
21
22
  container: HTMLElement, getLinkElement: (arg0: Event) => Element | null,
22
- getDOMNode: (arg0: Element) => SDK.DOMModel.DOMNode | null) {
23
+ getNodeFeatures: (arg0: Element) => Promise<Components.ImagePreview.PrecomputedFeatures|undefined>) {
23
24
  this.getLinkElement = getLinkElement;
24
- this.getDOMNode = getDOMNode;
25
+ this.#getNodeFeatures = getNodeFeatures;
25
26
  this.popover =
26
27
  new UI.PopoverHelper.PopoverHelper(container, this.handleRequest.bind(this), 'elements.image-preview');
27
28
  this.popover.setTimeout(0, 100);
@@ -39,11 +40,7 @@ export class ImagePreviewPopover {
39
40
  return {
40
41
  box: link.boxInWindow(),
41
42
  show: async (popover: UI.GlassPane.GlassPane) => {
42
- const node = this.getDOMNode((link));
43
- if (!node) {
44
- return false;
45
- }
46
- const precomputedFeatures = await Components.ImagePreview.ImagePreview.loadDimensionsForNode(node);
43
+ const precomputedFeatures = await this.#getNodeFeatures(link);
47
44
  const preview = await Components.ImagePreview.ImagePreview.build(href, true, {
48
45
  precomputedFeatures,
49
46
  align: Components.ImagePreview.Align.CENTER,
@@ -807,6 +807,7 @@ export class StylePropertiesSection {
807
807
  let scopeIndex = 0;
808
808
  let supportsIndex = 0;
809
809
  let nestingIndex = 0;
810
+ let navigationsIndex = 0;
810
811
  this.nestingLevel = 0;
811
812
  for (const ruleType of rule.ruleTypes) {
812
813
  let ancestorRuleElement;
@@ -829,6 +830,9 @@ export class StylePropertiesSection {
829
830
  case Protocol.CSS.CSSRuleType.StartingStyleRule:
830
831
  ancestorRuleElement = this.createStartingStyleElement();
831
832
  break;
833
+ case Protocol.CSS.CSSRuleType.NavigationRule:
834
+ ancestorRuleElement = this.createNavigationElement(rule.navigations[navigationsIndex++]);
835
+ break;
832
836
  }
833
837
  if (ancestorRuleElement) {
834
838
  this.#ancestorRuleListElement.prepend(ancestorRuleElement);
@@ -1007,6 +1011,27 @@ export class StylePropertiesSection {
1007
1011
  return supportsElement;
1008
1012
  }
1009
1013
 
1014
+ protected createNavigationElement(navigation: SDK.CSSNavigation.CSSNavigation): ElementsComponents.CSSQuery.CSSQuery
1015
+ |undefined {
1016
+ if (!navigation.text) {
1017
+ return;
1018
+ }
1019
+
1020
+ let onQueryTextClick;
1021
+ if (navigation.styleSheetId) {
1022
+ onQueryTextClick = this.handleQueryRuleClick.bind(this, navigation);
1023
+ }
1024
+
1025
+ const navigationElement = new ElementsComponents.CSSQuery.CSSQuery();
1026
+ navigationElement.data = {
1027
+ queryPrefix: '@navigation',
1028
+ queryText: navigation.text,
1029
+ onQueryTextClick,
1030
+ jslogContext: 'navigation',
1031
+ };
1032
+ return navigationElement;
1033
+ }
1034
+
1010
1035
  protected createNestingElement(nestingSelector?: string): HTMLElement|undefined {
1011
1036
  if (!nestingSelector) {
1012
1037
  return;
@@ -1419,6 +1444,8 @@ export class StylePropertiesSection {
1419
1444
  success = await cssModel.setSupportsText(query.styleSheetId, range, newContent);
1420
1445
  } else if (query instanceof SDK.CSSScope.CSSScope) {
1421
1446
  success = await cssModel.setScopeText(query.styleSheetId, range, newContent);
1447
+ } else if (query instanceof SDK.CSSNavigation.CSSNavigation) {
1448
+ success = await cssModel.setNavigationText(query.styleSheetId, range, newContent);
1422
1449
  } else {
1423
1450
  success = await cssModel.setMediaText(query.styleSheetId, range, newContent);
1424
1451
  }
@@ -1871,6 +1898,9 @@ export class FunctionRuleSection extends StylePropertiesSection {
1871
1898
  if ('supports' in condition) {
1872
1899
  return this.createSupportsElement(condition.supports);
1873
1900
  }
1901
+ if ('navigation' in condition) {
1902
+ return this.createNavigationElement(condition.navigation);
1903
+ }
1874
1904
  return;
1875
1905
  }
1876
1906
 
@@ -18,11 +18,6 @@ export class StylesAiCodeCompletionProvider {
18
18
 
19
19
  #boundOnUpdateAiCodeCompletionState = this.#updateAiCodeCompletionState.bind(this);
20
20
 
21
- #debouncedRequestAidaSuggestion =
22
- Common.Debouncer.debounce((prefix: string, suffix: string, cursorPositionAtRequest: number) => {
23
- void this.#requestAidaSuggestion(prefix, suffix, cursorPositionAtRequest);
24
- }, TextEditor.AiCodeCompletionProvider.AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS);
25
-
26
21
  private constructor(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig) {
27
22
  const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
28
23
  if (!AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionStylesEnabled(devtoolsLocale.locale)) {
@@ -113,7 +108,7 @@ export class StylesAiCodeCompletionProvider {
113
108
  prefix = prefix + text;
114
109
  const suffix = content.substring(propertyEndOffset);
115
110
  // TODO(b/476098133): Consider adjusting cursor position
116
- this.#debouncedRequestAidaSuggestion(prefix, suffix, cursorPosition);
111
+ await this.#requestAidaSuggestion(prefix, suffix, cursorPosition);
117
112
  }
118
113
 
119
114
  async #requestAidaSuggestion(prefix: string, suffix: string, cursorPositionAtRequest: number): Promise<void> {
@@ -42,9 +42,11 @@ import {assertNotNullOrUndefined} from '../../core/platform/platform.js';
42
42
  import * as Root from '../../core/root/root.js';
43
43
  import * as SDK from '../../core/sdk/sdk.js';
44
44
  import * as Protocol from '../../generated/protocol.js';
45
+ import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
45
46
  import * as Bindings from '../../models/bindings/bindings.js';
46
47
  import type * as ComputedStyle from '../../models/computed_style/computed_style.js';
47
48
  import * as TextUtils from '../../models/text_utils/text_utils.js';
49
+ import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
48
50
  import {createIcon, Icon} from '../../ui/kit/kit.js';
49
51
  import * as InlineEditor from '../../ui/legacy/components/inline_editor/inline_editor.js';
50
52
  import * as Components from '../../ui/legacy/components/utils/utils.js';
@@ -70,6 +72,7 @@ import {
70
72
  } from './StylePropertiesSection.js';
71
73
  import {StylePropertyHighlighter} from './StylePropertyHighlighter.js';
72
74
  import type {StylePropertyTreeElement} from './StylePropertyTreeElement.js';
75
+ import * as StylesAiCodeCompletionProvider from './StylesAiCodeCompletionProvider.js';
73
76
  import type {StylesContainer} from './StylesContainer.js';
74
77
  import stylesSidebarPaneStyles from './stylesSidebarPane.css.js';
75
78
  import {WebCustomData} from './WebCustomData.js';
@@ -233,13 +236,19 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
233
236
  this.contentElement.addEventListener('copy', this.clipboardCopy.bind(this));
234
237
 
235
238
  this.boundOnScroll = this.onScroll.bind(this);
236
- this.imagePreviewPopover = new ImagePreviewPopover(this.contentElement, event => {
237
- const link = event.composedPath()[0];
238
- if (link instanceof Element) {
239
- return link;
240
- }
241
- return null;
242
- }, () => this.node());
239
+ this.imagePreviewPopover = new ImagePreviewPopover(
240
+ this.contentElement,
241
+ event => {
242
+ const link = event.composedPath()[0];
243
+ if (link instanceof Element) {
244
+ return link;
245
+ }
246
+ return null;
247
+ },
248
+ async () => {
249
+ const features = await Components.ImagePreview.loadPrecomputedFeatures(this.node());
250
+ return features;
251
+ });
243
252
 
244
253
  UI.ViewManager.ViewManager.instance().addEventListener(UI.ViewManager.Events.VIEW_VISIBILITY_CHANGED, event => {
245
254
  if (event.data.revealedViewId === 'animations' || event.data.hiddenViewId === 'animations') {
@@ -1736,6 +1745,12 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
1736
1745
  private treeElement: StylePropertyTreeElement;
1737
1746
  private isEditingName: boolean;
1738
1747
  private readonly cssVariables: string[];
1748
+ aiCodeCompletionConfig?: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
1749
+ aiCodeCompletionProvider?: StylesAiCodeCompletionProvider.StylesAiCodeCompletionProvider;
1750
+
1751
+ #debouncedTriggerAiCodeCompletion = Common.Debouncer.debounce(() => {
1752
+ void this.triggerAiCodeCompletion();
1753
+ }, TextEditor.AiCodeCompletionProvider.AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS);
1739
1754
 
1740
1755
  constructor(treeElement: StylePropertyTreeElement, isEditingName: boolean, completions: string[] = []) {
1741
1756
  // Use the same callback both for applyItemCallback and acceptItemCallback.
@@ -1794,6 +1809,27 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
1794
1809
  }
1795
1810
  }
1796
1811
  }
1812
+
1813
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
1814
+ if (AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionStylesEnabled(devtoolsLocale.locale)) {
1815
+ this.aiCodeCompletionConfig = {
1816
+ completionContext: {},
1817
+ generationContext: {},
1818
+ onFeatureEnabled: () => {},
1819
+ onFeatureDisabled: () => {},
1820
+ onSuggestionAccepted: () => {},
1821
+ onRequestTriggered: () => {},
1822
+ onResponseReceived: () => {},
1823
+ panel: AiCodeCompletion.AiCodeCompletion.ContextFlavor.STYLES,
1824
+ getCompletionHint: this.getCompletionHint.bind(this),
1825
+ getCurrentText: () => {
1826
+ return this.text();
1827
+ },
1828
+ setAiAutoCompletion: () => {},
1829
+ };
1830
+ this.aiCodeCompletionProvider =
1831
+ StylesAiCodeCompletionProvider.StylesAiCodeCompletionProvider.createInstance(this.aiCodeCompletionConfig);
1832
+ }
1797
1833
  }
1798
1834
 
1799
1835
  override onKeyDown(event: Event): void {
@@ -1844,6 +1880,13 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
1844
1880
  return false;
1845
1881
  }
1846
1882
 
1883
+ override onInput(event: Event): void {
1884
+ super.onInput(event);
1885
+ if (this.aiCodeCompletionProvider) {
1886
+ this.#debouncedTriggerAiCodeCompletion();
1887
+ }
1888
+ }
1889
+
1847
1890
  private handleNameOrValueUpDown(event: Event): boolean {
1848
1891
  function finishHandler(this: CSSPropertyPrompt, _originalValue: string, _replacementString: string): void {
1849
1892
  // Synthesize property text disregarding any comments, custom whitespace etc.
@@ -2054,6 +2097,48 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2054
2097
  return subtitleElement;
2055
2098
  }
2056
2099
  }
2100
+
2101
+ private async triggerAiCodeCompletion(): Promise<void> {
2102
+ const selection = this.element().getComponentSelection();
2103
+ if (!this.aiCodeCompletionProvider || !selection || selection.rangeCount === 0) {
2104
+ return;
2105
+ }
2106
+ const range = selection.getRangeAt(0);
2107
+ const userInput = this.text();
2108
+ // Only trigger if caret is at end of text content
2109
+ if (range.endOffset < userInput.length) {
2110
+ return;
2111
+ }
2112
+ const cssModel = this.treeElement.stylesContainer().cssModel();
2113
+ if (!cssModel) {
2114
+ return;
2115
+ }
2116
+ await this.aiCodeCompletionProvider.triggerAiCodeCompletion(
2117
+ userInput, range.endOffset, this.isEditingName, this.treeElement.property, cssModel);
2118
+ }
2119
+
2120
+ /**
2121
+ * Extracts the remaining portion of the suggestion text that follows the
2122
+ * user's current input.
2123
+ */
2124
+ private getCompletionHint(): string|null {
2125
+ const topSuggestion = this.isSuggestBoxVisible() ? this.suggestBox?.completion() : null;
2126
+ const suggestionText = topSuggestion?.text;
2127
+ if (!suggestionText) {
2128
+ return null;
2129
+ }
2130
+ const userInput = this.text();
2131
+ let completionHint = suggestionText;
2132
+ // Iterate from the longest possible overlap down to the shortest
2133
+ for (let i = Math.min(userInput.length, suggestionText.length); i > 0; i--) {
2134
+ const overlapCandidate = suggestionText.substring(0, i);
2135
+ if (userInput.endsWith(overlapCandidate)) {
2136
+ completionHint = suggestionText.slice(i);
2137
+ break;
2138
+ }
2139
+ }
2140
+ return completionHint;
2141
+ }
2057
2142
  }
2058
2143
 
2059
2144
  export function unescapeCssString(input: string): string {
@@ -110,9 +110,13 @@ const UIStrings = {
110
110
  /**
111
111
  * @description Title of a setting under the Elements category. Whether to show/hide code comments in HTML.
112
112
  */
113
+ htmlComments: 'HTML comments',
114
+ /**
115
+ * @description Title of an option under the Elements category that can be invoked through the Command Menu
116
+ */
113
117
  showHtmlComments: 'Show `HTML` comments',
114
118
  /**
115
- * @description Title of a setting under the Elements category. Whether to show/hide code comments in HTML.
119
+ * @description Title of an option under the Elements category that can be invoked through the Command Menu
116
120
  */
117
121
  hideHtmlComments: 'Hide `HTML` comments',
118
122
  /**
@@ -126,12 +130,12 @@ const UIStrings = {
126
130
  * the inspect tooltip (an information pane that hovers next to selected DOM elements) has extra
127
131
  * detail.
128
132
  */
129
- showDetailedInspectTooltip: 'Show detailed inspect tooltip',
133
+ detailedInspectTooltip: 'Detailed inspect tooltip',
130
134
  /**
131
135
  * @description Title of a setting under the Elements category in Settings. Turns on a mode where
132
136
  * hovering over CSS properties in the Styles pane will display a popover with documentation.
133
137
  */
134
- showCSSDocumentationTooltip: 'Show CSS documentation tooltip',
138
+ CSSDocumentationTooltip: 'CSS documentation tooltip',
135
139
  /**
136
140
  * @description A context menu item (command) in the Elements panel that copy the styles of
137
141
  * the HTML element.
@@ -146,7 +150,7 @@ const UIStrings = {
146
150
  * @description Title of a setting under the Elements category. Whether to show/hide hide
147
151
  * the shadow DOM nodes of HTML elements that are built into the browser (e.g. the <input> element).
148
152
  */
149
- showUserAgentShadowDOM: 'Show user agent shadow `DOM`',
153
+ userAgentShadowDOM: 'User agent shadow `DOM`',
150
154
  /**
151
155
  * @description Command for showing the 'Computed' tool. Displays computed CSS styles in Elements sidebar.
152
156
  */
@@ -489,7 +493,7 @@ Common.Settings.registerSettingExtension({
489
493
  category: Common.Settings.SettingCategory.ELEMENTS,
490
494
  storageType: Common.Settings.SettingStorageType.SYNCED,
491
495
  order: 1,
492
- title: i18nLazyString(UIStrings.showUserAgentShadowDOM),
496
+ title: i18nLazyString(UIStrings.userAgentShadowDOM),
493
497
  settingName: 'show-ua-shadow-dom',
494
498
  settingType: Common.Settings.SettingType.BOOLEAN,
495
499
  defaultValue: false,
@@ -528,7 +532,7 @@ Common.Settings.registerSettingExtension({
528
532
  category: Common.Settings.SettingCategory.ELEMENTS,
529
533
  storageType: Common.Settings.SettingStorageType.SYNCED,
530
534
  order: 3,
531
- title: i18nLazyString(UIStrings.showHtmlComments),
535
+ title: i18nLazyString(UIStrings.htmlComments),
532
536
  settingName: 'show-html-comments',
533
537
  settingType: Common.Settings.SettingType.BOOLEAN,
534
538
  defaultValue: true,
@@ -558,7 +562,7 @@ Common.Settings.registerSettingExtension({
558
562
  category: Common.Settings.SettingCategory.ELEMENTS,
559
563
  storageType: Common.Settings.SettingStorageType.SYNCED,
560
564
  order: 5,
561
- title: i18nLazyString(UIStrings.showDetailedInspectTooltip),
565
+ title: i18nLazyString(UIStrings.detailedInspectTooltip),
562
566
  settingName: 'show-detailed-inspect-tooltip',
563
567
  settingType: Common.Settings.SettingType.BOOLEAN,
564
568
  defaultValue: true,
@@ -581,7 +585,7 @@ Common.Settings.registerSettingExtension({
581
585
  Common.Settings.registerSettingExtension({
582
586
  category: Common.Settings.SettingCategory.ELEMENTS,
583
587
  storageType: Common.Settings.SettingStorageType.SYNCED,
584
- title: i18nLazyString(UIStrings.showCSSDocumentationTooltip),
588
+ title: i18nLazyString(UIStrings.CSSDocumentationTooltip),
585
589
  settingName: 'show-css-property-documentation-on-hover',
586
590
  settingType: Common.Settings.SettingType.BOOLEAN,
587
591
  defaultValue: true,