chrome-devtools-frontend 1.0.1585538 → 1.0.1585664

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.
@@ -4426,7 +4426,8 @@ export const generatedProperties = [
4426
4426
  "inherited": true,
4427
4427
  "keywords": [
4428
4428
  "none",
4429
- "auto"
4429
+ "auto",
4430
+ "all"
4430
4431
  ],
4431
4432
  "name": "text-decoration-skip-ink"
4432
4433
  },
@@ -6976,7 +6977,8 @@ export const generatedPropertyValues = {
6976
6977
  "text-decoration-skip-ink": {
6977
6978
  "values": [
6978
6979
  "none",
6979
- "auto"
6980
+ "auto",
6981
+ "all"
6980
6982
  ]
6981
6983
  },
6982
6984
  "text-decoration-style": {
@@ -346,6 +346,18 @@ export class AiCodeCompletion {
346
346
  }
347
347
  return Boolean(aidaAvailability.enabled && Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled);
348
348
  }
349
+
350
+ static isAiCodeCompletionStylesEnabled(locale: string): boolean {
351
+ if (!locale.startsWith('en-')) {
352
+ return false;
353
+ }
354
+ const aidaAvailability = Root.Runtime.hostConfig.aidaAvailability;
355
+ if (!aidaAvailability || aidaAvailability.blockedByGeo || aidaAvailability.blockedByAge ||
356
+ aidaAvailability.blockedByEnterprisePolicy) {
357
+ return false;
358
+ }
359
+ return Boolean(aidaAvailability.enabled && Root.Runtime.hostConfig.devToolsAiCodeCompletionStyles?.enabled);
360
+ }
349
361
  }
350
362
 
351
363
  export const enum ContextFlavor {
@@ -183,6 +183,19 @@ const DEFAULT_VIEW: View = (input, output, target) => {
183
183
  `, target);
184
184
  // clang-format on
185
185
  };
186
+
187
+ /**
188
+ * ChatView is a web component for historical reasons and generally should not
189
+ * exist because it barely has any presenter logic and it is definitely not
190
+ * re-usable as a custom element. Instead, the template from ChatView should be
191
+ * embdedded into the AiAssistancePanel (the sole host of chat interfaces) and
192
+ * the scroll handling logic should be implemented in view functions using refs
193
+ * or re-usable custom elements. Currently, the ChatView just combines the
194
+ * interfaces of ChatMessage and ChatInput presenters and passes most of the
195
+ * properties down to those presenters as-is.
196
+ *
197
+ * @deprecated
198
+ */
186
199
  export class ChatView extends HTMLElement {
187
200
  readonly #shadow = this.attachShadow({mode: 'open'});
188
201
  #scrollTop?: number;
@@ -272,7 +272,6 @@ interface FrameDetailsViewInput {
272
272
  frame: SDK.ResourceTreeModel.ResourceTreeFrame;
273
273
  target: SDK.Target.Target|null;
274
274
  creationStackTrace: StackTrace.StackTrace.StackTrace|null;
275
- creationTarget: SDK.Target.Target|null;
276
275
  adScriptAncestry: Protocol.Page.AdScriptAncestry|null;
277
276
  linkTargetDOMNode: SDK.DOMModel.DOMNode|null;
278
277
  permissionsPolicies: Protocol.Page.PermissionsPolicyFeatureState[]|null;
@@ -354,7 +353,7 @@ function renderDocumentSection(input: FrameDetailsViewInput): LitTemplate {
354
353
  ${maybeRenderUnreachableURL(input.frame?.unreachableUrl())}
355
354
  ${maybeRenderOrigin(input.frame?.securityOrigin)}
356
355
  ${renderOwnerElement(input.linkTargetDOMNode)}
357
- ${maybeRenderCreationStacktrace(input.creationStackTrace, input.creationTarget)}
356
+ ${maybeRenderCreationStacktrace(input.creationStackTrace)}
358
357
  ${maybeRenderAdStatus(input.frame?.adFrameType(), input.frame?.adFrameStatus())}
359
358
  ${maybeRenderCreatorAdScriptAncestry(input.frame?.adFrameType(), input.target, input.adScriptAncestry)}
360
359
  <devtools-report-divider></devtools-report-divider>`;
@@ -447,9 +446,8 @@ function renderOwnerElement(linkTargetDOMNode: SDK.DOMModel.DOMNode|null): LitTe
447
446
  return nothing;
448
447
  }
449
448
 
450
- function maybeRenderCreationStacktrace(
451
- stackTrace: StackTrace.StackTrace.StackTrace|null, target: SDK.Target.Target|null): LitTemplate {
452
- if (stackTrace && target) {
449
+ function maybeRenderCreationStacktrace(stackTrace: StackTrace.StackTrace.StackTrace|null): LitTemplate {
450
+ if (stackTrace) {
453
451
  // Disabled until https://crbug.com/1079231 is fixed.
454
452
  // clang-format off
455
453
  return html`
@@ -457,7 +455,7 @@ function maybeRenderCreationStacktrace(
457
455
  i18nString(UIStrings.creationStackTrace)}</devtools-report-key>
458
456
  <devtools-report-value jslog=${VisualLogging.section('frame-creation-stack-trace')}>
459
457
  <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(
460
- Components.JSPresentationUtils.StackTracePreviewContent, {target, stackTrace, options: {expandable: true}})}>
458
+ Components.JSPresentationUtils.StackTracePreviewContent, {stackTrace, options: {expandable: true}})}>
461
459
  </devtools-widget>
462
460
  </devtools-report-value>
463
461
  `;
@@ -844,7 +842,6 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
844
842
  #frame?: SDK.ResourceTreeModel.ResourceTreeFrame;
845
843
  #target: SDK.Target.Target|null = null;
846
844
  #creationStackTrace: StackTrace.StackTrace.StackTrace|null = null;
847
- #creationTarget: SDK.Target.Target|null = null;
848
845
  #securityIsolationInfo: Protocol.Network.SecurityIsolationStatus|null = null;
849
846
  #linkTargetDOMNode: SDK.DOMModel.DOMNode|null = null;
850
847
  #trials: Protocol.Page.OriginTrial[]|null = null;
@@ -869,7 +866,6 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
869
866
  });
870
867
  const {creationStackTrace: rawCreationStackTrace, creationStackTraceTarget: creationTarget} =
871
868
  frame.getCreationStackTraceData();
872
- this.#creationTarget = creationTarget;
873
869
  if (rawCreationStackTrace) {
874
870
  void Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
875
871
  .createStackTraceFromProtocolRuntime(rawCreationStackTrace, creationTarget)
@@ -924,7 +920,6 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
924
920
  frame,
925
921
  target: this.#target,
926
922
  creationStackTrace: this.#creationStackTrace,
927
- creationTarget: this.#creationTarget,
928
923
  protocolMonitorExperimentEnabled: this.#protocolMonitorExperimentEnabled,
929
924
  permissionsPolicies: this.#permissionsPolicies,
930
925
  adScriptAncestry: this.#adScriptAncestry,
@@ -705,8 +705,8 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
705
705
  const stackTraceElement = contentElement.createChild('div', 'hidden-stack-trace');
706
706
  const targetManager = SDK.TargetManager.TargetManager.instance();
707
707
  const stackTraceTarget = target ?? targetManager.primaryPageTarget() ?? targetManager.rootTarget();
708
- const stackTracePreview = new Components.JSPresentationUtils.StackTracePreviewContent(
709
- undefined, stackTraceTarget ?? undefined, this.linkifier, {widthConstrained: true});
708
+ const stackTracePreview = new Components.JSPresentationUtils.StackTracePreviewContent();
709
+ stackTracePreview.options = {widthConstrained: true};
710
710
  if (stackTraceTarget && stackTrace) {
711
711
  const selectableChildIndex = this.selectableChildren.length;
712
712
  void Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
@@ -54,7 +54,7 @@ import type * as Adorners from '../../ui/components/adorners/adorners.js';
54
54
  import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
55
55
  import * as Highlighting from '../../ui/components/highlighting/highlighting.js';
56
56
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
57
- import {Icon, Link} from '../../ui/kit/kit.js';
57
+ import {Icon} from '../../ui/kit/kit.js';
58
58
  import * as Components from '../../ui/legacy/components/utils/utils.js';
59
59
  import * as UI from '../../ui/legacy/legacy.js';
60
60
  import * as Lit from '../../ui/lit/lit.js';
@@ -72,7 +72,7 @@ import {type ElementsTreeOutline, MappedCharToEntity} from './ElementsTreeOutlin
72
72
  import {ImagePreviewPopover} from './ImagePreviewPopover.js';
73
73
  import {getRegisteredDecorators, type MarkerDecorator, type MarkerDecoratorRegistration} from './MarkerDecorator.js';
74
74
 
75
- const {html, nothing, render, Directives: {ref}} = Lit;
75
+ const {html, nothing, render, Directives: {ref, repeat}} = Lit;
76
76
  const {animateOn} = UI.UIUtils;
77
77
 
78
78
  const UIStrings = {
@@ -634,124 +634,138 @@ function renderTitle(
634
634
  }
635
635
  }
636
636
 
637
- function renderAttribute(
638
- attr: {name: string, value?: string}, updateRecord: Elements.ElementUpdateRecord.ElementUpdateRecord|null,
639
- isDiff: boolean, node: SDK.DOMModel.DOMNode): Lit.LitTemplate {
640
- const name = attr.name;
641
- const value = attr.value || '';
642
- const forceValue = isDiff;
643
- const closingPunctuationRegex = /[\/;:\)\]\}]/g;
644
- let highlightIndex = 0;
645
- let highlightCount = 0;
646
- let additionalHighlightOffset = 0;
637
+ const enum SrcsetTokenType {
638
+ LITERAL = 0,
639
+ LINK = 1
640
+ }
647
641
 
648
- function setValueWithEntities(element: Element, value: string): void {
649
- const result = convertUnicodeCharsToHTMLEntities(value);
650
- highlightCount = result.entityRanges.length;
651
- const newValue = result.text.replace(closingPunctuationRegex, (match, replaceOffset) => {
652
- while (highlightIndex < highlightCount && result.entityRanges[highlightIndex].offset < replaceOffset) {
653
- result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
654
- ++highlightIndex;
642
+ interface SrcsetToken {
643
+ type: SrcsetTokenType;
644
+ value: string;
645
+ }
646
+
647
+ // FIXME: find a home for this in SDK.
648
+ function parseSrcset(value: string): SrcsetToken[] {
649
+ const result: SrcsetToken[] = [];
650
+ let i = 0;
651
+ while (value.length) {
652
+ if (i++ > 0) {
653
+ result.push({value: ' ', type: SrcsetTokenType.LITERAL});
654
+ }
655
+ value = value.trim();
656
+ let url = '';
657
+ let descriptor = '';
658
+ const indexOfSpace = value.search(/\s/);
659
+ if (indexOfSpace === -1) {
660
+ url = value;
661
+ } else if (indexOfSpace > 0 && value[indexOfSpace - 1] === ',') {
662
+ url = value.substring(0, indexOfSpace);
663
+ } else {
664
+ url = value.substring(0, indexOfSpace);
665
+ const indexOfComma = value.indexOf(',', indexOfSpace);
666
+ if (indexOfComma !== -1) {
667
+ descriptor = value.substring(indexOfSpace, indexOfComma + 1);
668
+ } else {
669
+ descriptor = value.substring(indexOfSpace);
655
670
  }
656
- additionalHighlightOffset += 1;
657
- return match + '\u200B';
658
- });
671
+ }
659
672
 
660
- while (highlightIndex < highlightCount) {
661
- result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
662
- ++highlightIndex;
673
+ if (url) {
674
+ if (url.endsWith(',')) {
675
+ result.push({value: url.substring(0, url.length - 1), type: SrcsetTokenType.LINK});
676
+ result.push({type: SrcsetTokenType.LITERAL, value: ','});
677
+ } else {
678
+ result.push({value: url, type: SrcsetTokenType.LINK});
679
+ }
680
+ }
681
+ if (descriptor) {
682
+ result.push({type: SrcsetTokenType.LITERAL, value: descriptor});
663
683
  }
664
- element.setTextContentTruncatedIfNeeded(newValue);
665
- Highlighting.highlightRangesWithStyleClass(element, result.entityRanges, 'webkit-html-entity-value');
684
+ value = value.substring(url.length + descriptor.length);
666
685
  }
686
+ return result;
687
+ }
667
688
 
668
- const hasText = (forceValue || value.length > 0);
669
- const jslog = VisualLogging.value(name === 'style' ? 'style-attribute' : 'attribute').track({
670
- change: true,
671
- dblclick: true,
689
+ function renderLinkifiedSrcset(tokens: SrcsetToken[], node: SDK.DOMModel.DOMNode): Lit.TemplateResult {
690
+ return html`${repeat(tokens, token => {
691
+ switch (token.type) {
692
+ case SrcsetTokenType.LINK:
693
+ return renderLinkifiedValue(token.value, node);
694
+ case SrcsetTokenType.LITERAL:
695
+ return token.value;
696
+ }
697
+ })}`;
698
+ }
699
+
700
+ const closingPunctuationRegex = /[\/;:\)\]\}]/g;
701
+
702
+ // FIXME: this should be made declarative next.
703
+ function setValueWithEntities(element: Element, value: string): void {
704
+ let highlightIndex = 0;
705
+ let highlightCount = 0;
706
+ let additionalHighlightOffset = 0;
707
+ const result = convertUnicodeCharsToHTMLEntities(value);
708
+ highlightCount = result.entityRanges.length;
709
+ const newValue = result.text.replace(closingPunctuationRegex, (match, replaceOffset) => {
710
+ while (highlightIndex < highlightCount && result.entityRanges[highlightIndex].offset < replaceOffset) {
711
+ result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
712
+ ++highlightIndex;
713
+ }
714
+ additionalHighlightOffset += 1;
715
+ return match + '\u200B';
672
716
  });
673
717
 
674
- function linkifyValue(value: string): Element {
675
- const rewrittenHref = node ? node.resolveURL(value) : null;
676
- if (rewrittenHref === null) {
677
- const span = document.createElement('span');
678
- setValueWithEntities(span, value);
679
- return span;
680
- }
681
- value = value.replace(closingPunctuationRegex, '$&\u200B');
682
- if (value.startsWith('data:')) {
683
- value = Platform.StringUtilities.trimMiddle(value, 60);
684
- }
685
- const link = node && node.nodeName().toLowerCase() === 'a' ?
686
- Link.create(rewrittenHref, value, undefined, 'image-url') :
687
- Components.Linkifier.Linkifier.linkifyURL(rewrittenHref, {
688
- text: value,
689
- preventClick: true,
690
- showColumnNumber: false,
691
- inlineFrameIndex: 0,
692
- });
693
- return ImagePreviewPopover.setImageUrl(link, rewrittenHref);
694
- }
695
-
696
- function linkifySrcset(value: string): DocumentFragment {
697
- // Splitting normally on commas or spaces will break on valid srcsets "foo 1x,bar 2x" and "data:,foo 1x".
698
- const fragment = document.createDocumentFragment();
699
- let i = 0;
700
- while (value.length) {
701
- if (i++ > 0) {
702
- UI.UIUtils.createTextChild(fragment, ' ');
703
- }
704
- value = value.trim();
705
- let url = '';
706
- let descriptor = '';
707
- const indexOfSpace = value.search(/\s/);
708
- if (indexOfSpace === -1) {
709
- url = value;
710
- } else if (indexOfSpace > 0 && value[indexOfSpace - 1] === ',') {
711
- url = value.substring(0, indexOfSpace);
712
- } else {
713
- url = value.substring(0, indexOfSpace);
714
- const indexOfComma = value.indexOf(',', indexOfSpace);
715
- if (indexOfComma !== -1) {
716
- descriptor = value.substring(indexOfSpace, indexOfComma + 1);
717
- } else {
718
- descriptor = value.substring(indexOfSpace);
719
- }
720
- }
718
+ while (highlightIndex < highlightCount) {
719
+ result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
720
+ ++highlightIndex;
721
+ }
722
+ element.setTextContentTruncatedIfNeeded(newValue);
723
+ Highlighting.highlightRangesWithStyleClass(element, result.entityRanges, 'webkit-html-entity-value');
724
+ }
721
725
 
722
- if (url) {
723
- if (url.endsWith(',')) {
724
- fragment.appendChild(linkifyValue(url.substring(0, url.length - 1)));
725
- UI.UIUtils.createTextChild(fragment, ',');
726
- } else {
727
- fragment.appendChild(linkifyValue(url));
728
- }
726
+ function renderLinkifiedValue(value: string, node: SDK.DOMModel.DOMNode): Lit.TemplateResult {
727
+ const rewrittenHref = node ? node.resolveURL(value) : null;
728
+ if (rewrittenHref === null) {
729
+ return html`<span ${ref(el => {
730
+ if (el) {
731
+ setValueWithEntities(el, value);
729
732
  }
730
- if (descriptor) {
731
- UI.UIUtils.createTextChild(fragment, descriptor);
733
+ })}}></span>`;
734
+ }
735
+ value = value.replace(closingPunctuationRegex, '$&\u200B');
736
+ if (value.startsWith('data:')) {
737
+ value = Platform.StringUtilities.trimMiddle(value, 60);
738
+ }
739
+ const isAnchor = node && node.nodeName().toLowerCase() === 'a';
740
+ if (isAnchor) {
741
+ return html`<devtools-link class="devtools-link image-url" href=${rewrittenHref} ${ref(el => {
742
+ if (el) {
743
+ ImagePreviewPopover.setImageUrl(el, rewrittenHref);
732
744
  }
733
- value = value.substring(url.length + descriptor.length);
734
- }
735
- return fragment;
745
+ })}>${Platform.StringUtilities.trimMiddle(value, 150)}</devtools-link>`;
736
746
  }
737
-
738
- const nodeName = node ? node.nodeName().toLowerCase() : '';
739
- const setAttrValue = ref(el => {
740
- if (!el) {
741
- return;
742
- }
743
- const valueElement = el as HTMLElement;
744
- valueElement.removeChildren();
745
- if (nodeName && (name === 'src' || name === 'href') && value) {
746
- valueElement.appendChild(linkifyValue(value));
747
- } else if ((nodeName === 'img' || nodeName === 'source') && name === 'srcset') {
748
- valueElement.appendChild(linkifySrcset(value));
749
- } else if (nodeName === 'image' && (name === 'xlink:href' || name === 'href')) {
750
- valueElement.appendChild(linkifySrcset(value));
751
- } else {
752
- setValueWithEntities(valueElement, value);
747
+ return Components.Linkifier.Linkifier.renderLinkifiedUrl(rewrittenHref, {
748
+ text: value,
749
+ preventClick: true,
750
+ showColumnNumber: false,
751
+ inlineFrameIndex: 0,
752
+ onRef: link => {
753
+ ImagePreviewPopover.setImageUrl(link, rewrittenHref);
753
754
  }
754
755
  });
756
+ }
757
+
758
+ function renderAttribute(
759
+ attr: {name: string, value?: string}, updateRecord: Elements.ElementUpdateRecord.ElementUpdateRecord|null,
760
+ isDiff: boolean, node: SDK.DOMModel.DOMNode): Lit.LitTemplate {
761
+ const name = attr.name;
762
+ const value = attr.value || '';
763
+ const forceValue = isDiff;
764
+ const hasText = (forceValue || value.length > 0);
765
+ const jslog = VisualLogging.value(name === 'style' ? 'style-attribute' : 'attribute').track({
766
+ change: true,
767
+ dblclick: true,
768
+ });
755
769
 
756
770
  const relationRef =
757
771
  (relation: Protocol.DOM.GetElementByRelationRequestRelation, tooltip: string): ReturnType<typeof ref> =>
@@ -804,14 +818,41 @@ function renderAttribute(
804
818
  }
805
819
  }
806
820
 
821
+ const nodeName = node ? node.nodeName().toLowerCase() : '';
822
+ const enum ValueType {
823
+ UNKNOWN = 0,
824
+ SRC = 1,
825
+ SRCSET = 2,
826
+ }
827
+ let valueType = ValueType.UNKNOWN;
828
+ if (nodeName && (name === 'src' || name === 'href') && value) {
829
+ valueType = ValueType.SRC;
830
+ } else if ((nodeName === 'img' || nodeName === 'source') && name === 'srcset') {
831
+ valueType = ValueType.SRCSET;
832
+ } else if (nodeName === 'image' && (name === 'xlink:href' || name === 'href')) {
833
+ valueType = ValueType.SRCSET;
834
+ }
835
+
836
+ const withEntitiesRef = valueType === ValueType.UNKNOWN ? ref(el => {
837
+ if (el) {
838
+ setValueWithEntities(el, value);
839
+ }
840
+ }) :
841
+ nothing;
842
+
843
+ // clang-format off
807
844
  return html`<span class="webkit-html-attribute" jslog=${jslog}><span class="webkit-html-attribute-name"
808
845
  ${animateOn(Boolean(updateRecord?.isAttributeModified(name) && !hasText), DOM_UPDATE_ANIMATION_CLASS_NAME)} ${
809
846
  relationRefDirective}>${name}</span>${
810
847
  hasText ? html`=\u200B"<span class="webkit-html-attribute-value" ${
811
848
  animateOn(
812
849
  Boolean(updateRecord?.isAttributeModified(name) && hasText),
813
- DOM_UPDATE_ANIMATION_CLASS_NAME)} ${setAttrValue} ${valueRelationRefDirective}></span>"` :
850
+ DOM_UPDATE_ANIMATION_CLASS_NAME)} ${valueRelationRefDirective} ${withEntitiesRef}>
851
+ ${valueType === ValueType.SRC ? renderLinkifiedValue(value, node) : nothing}
852
+ ${valueType === ValueType.SRCSET ? renderLinkifiedSrcset(parseSrcset(value), node) : nothing}
853
+ </span>"` :
814
854
  nothing}</span>`;
855
+ // clang-format on
815
856
  }
816
857
 
817
858
  function renderTag(
@@ -22,22 +22,20 @@ const str_ = i18n.i18n.registerUIStrings('panels/elements/NodeStackTraceWidget.t
22
22
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
23
23
 
24
24
  interface ViewInput {
25
- target?: SDK.Target.Target;
26
- linkifier: Components.Linkifier.Linkifier;
27
25
  stackTrace?: StackTrace.StackTrace.StackTrace;
28
26
  }
29
27
 
30
28
  type View = (input: ViewInput, output: object, target: HTMLElement) => void;
31
29
 
32
30
  export const DEFAULT_VIEW: View = (input, _output, target) => {
33
- const {target: sdkTarget, linkifier, stackTrace} = input;
31
+ const {stackTrace} = input;
34
32
  // clang-format off
35
33
  render(html`
36
34
  <style>${nodeStackTraceWidgetStyles}</style>
37
35
  ${target && stackTrace ?
38
36
  html`<devtools-widget
39
37
  class="stack-trace"
40
- .widgetConfig=${UI.Widget.widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {target: sdkTarget, linkifier, stackTrace})}>
38
+ .widgetConfig=${UI.Widget.widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {stackTrace})}>
41
39
  </devtools-widget>` :
42
40
  html`<div class="gray-info-message">${i18nString(UIStrings.noStackTraceAvailable)}</div>`}`,
43
41
  target);
@@ -45,7 +43,6 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
45
43
  };
46
44
 
47
45
  export class NodeStackTraceWidget extends UI.Widget.VBox {
48
- readonly #linkifier = new Components.Linkifier.Linkifier(UI.UIUtils.MaxLengthForDisplayedURLsInConsole);
49
46
  readonly #view: View;
50
47
 
51
48
  constructor(view = DEFAULT_VIEW) {
@@ -73,11 +70,6 @@ export class NodeStackTraceWidget extends UI.Widget.VBox {
73
70
  await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().createStackTraceFromProtocolRuntime(
74
71
  runtimeStackTrace, target) :
75
72
  undefined;
76
- const input: ViewInput = {
77
- target,
78
- linkifier: this.#linkifier,
79
- stackTrace,
80
- };
81
- this.#view(input, {}, this.contentElement);
73
+ this.#view({stackTrace}, {}, this.contentElement);
82
74
  }
83
75
  }
@@ -0,0 +1,69 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../core/common/common.js';
6
+ import * as Host from '../../core/host/host.js';
7
+ import * as i18n from '../../core/i18n/i18n.js';
8
+ import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
9
+ import type * as TextEditor from '../../ui/components/text_editor/text_editor.js';
10
+
11
+ export class StylesAiCodeCompletionProvider {
12
+ #aidaClient: Host.AidaClient.AidaClient = new Host.AidaClient.AidaClient();
13
+ #aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
14
+ #aiCodeCompletion?: AiCodeCompletion.AiCodeCompletion.AiCodeCompletion;
15
+ #aiCodeCompletionConfig?: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
16
+
17
+ #boundOnUpdateAiCodeCompletionState = this.#updateAiCodeCompletionState.bind(this);
18
+
19
+ private constructor(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig) {
20
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
21
+ if (!AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionStylesEnabled(devtoolsLocale.locale)) {
22
+ throw new Error('AI code completion feature in Styles is not enabled.');
23
+ }
24
+ this.#aiCodeCompletionConfig = aiCodeCompletionConfig;
25
+ Host.AidaClient.HostConfigTracker.instance().addEventListener(
26
+ Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnUpdateAiCodeCompletionState);
27
+ this.#aiCodeCompletionSetting.addChangeListener(this.#boundOnUpdateAiCodeCompletionState);
28
+ void this.#updateAiCodeCompletionState();
29
+ }
30
+
31
+ static createInstance(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig):
32
+ StylesAiCodeCompletionProvider {
33
+ return new StylesAiCodeCompletionProvider(aiCodeCompletionConfig);
34
+ }
35
+
36
+ #setupAiCodeCompletion(): void {
37
+ if (!this.#aiCodeCompletionConfig) {
38
+ return;
39
+ }
40
+ if (this.#aiCodeCompletion) {
41
+ // early return as this means that code completion was previously setup
42
+ return;
43
+ }
44
+ this.#aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
45
+ {aidaClient: this.#aidaClient}, this.#aiCodeCompletionConfig.panel, undefined,
46
+ this.#aiCodeCompletionConfig.completionContext.stopSequences);
47
+ this.#aiCodeCompletionConfig.onFeatureEnabled();
48
+ }
49
+
50
+ #cleanupAiCodeCompletion(): void {
51
+ if (!this.#aiCodeCompletion) {
52
+ // early return as this means there is no code completion to clean up
53
+ return;
54
+ }
55
+ this.#aiCodeCompletion = undefined;
56
+ this.#aiCodeCompletionConfig?.onFeatureDisabled();
57
+ }
58
+
59
+ async #updateAiCodeCompletionState(): Promise<void> {
60
+ const aidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
61
+ const isAvailable = aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE;
62
+ const isEnabled = this.#aiCodeCompletionSetting.get();
63
+ if (isAvailable && isEnabled) {
64
+ this.#setupAiCodeCompletion();
65
+ } else {
66
+ this.#cleanupAiCodeCompletion();
67
+ }
68
+ }
69
+ }
@@ -4,7 +4,6 @@
4
4
 
5
5
  import './InspectElementModeController.js';
6
6
  import './ColorSwatchPopoverIcon.js';
7
-
8
7
  import './DOMPath.js';
9
8
  import './ElementsSidebarPane.js';
10
9
  import './ElementsTreeElement.js';
@@ -20,6 +19,7 @@ import './NodeStackTraceWidget.js';
20
19
  import './StylePropertiesSection.js';
21
20
  import './StylePropertyHighlighter.js';
22
21
  import './StylesSidebarPane.js';
22
+ import './StylesAiCodeCompletionProvider.js';
23
23
  import './StylePropertyTreeElement.js';
24
24
  import './ComputedStyleWidget.js';
25
25
  import './CSSRuleValidator.js';
@@ -59,6 +59,7 @@ import * as StylePropertiesSection from './StylePropertiesSection.js';
59
59
  import * as StylePropertyHighlighter from './StylePropertyHighlighter.js';
60
60
  import * as StylePropertyTreeElement from './StylePropertyTreeElement.js';
61
61
  import * as StylePropertyUtils from './StylePropertyUtils.js';
62
+ import * as StylesAiCodeCompletionProvider from './StylesAiCodeCompletionProvider.js';
62
63
  import * as StylesSidebarPane from './StylesSidebarPane.js';
63
64
  import * as TopLayerContainer from './TopLayerContainer.js';
64
65
  import * as WebCustomData from './WebCustomData.js';
@@ -94,6 +95,7 @@ export {
94
95
  StylePropertyHighlighter,
95
96
  StylePropertyTreeElement,
96
97
  StylePropertyUtils,
98
+ StylesAiCodeCompletionProvider,
97
99
  StylesSidebarPane,
98
100
  TopLayerContainer,
99
101
  WebCustomData,
@@ -39,8 +39,6 @@ export interface ViewInput {
39
39
  initiatorGraph: Logs.NetworkLog.InitiatorGraph;
40
40
  stackTrace: StackTrace.StackTrace.StackTrace|null;
41
41
  request: SDK.NetworkRequest.NetworkRequest;
42
- linkifier: Components.Linkifier.Linkifier;
43
- target?: SDK.Target.Target;
44
42
  }
45
43
 
46
44
  export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
@@ -68,8 +66,6 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
68
66
  <ul role="group">
69
67
  <li role="treeitem">
70
68
  <devtools-widget .widgetConfig=${widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {
71
- target: input.target,
72
- linkifier: input.linkifier,
73
69
  options: {tabStops: true},
74
70
  stackTrace: input.stackTrace,
75
71
  })}></devtools-widget>
@@ -165,7 +161,6 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
165
161
  type View = typeof DEFAULT_VIEW;
166
162
 
167
163
  export class RequestInitiatorView extends UI.Widget.VBox {
168
- private readonly linkifier: Components.Linkifier.Linkifier;
169
164
  private readonly request: SDK.NetworkRequest.NetworkRequest;
170
165
  #view: View;
171
166
 
@@ -173,7 +168,6 @@ export class RequestInitiatorView extends UI.Widget.VBox {
173
168
  super({jslog: `${VisualLogging.pane('initiator').track({resize: true})}`});
174
169
 
175
170
  this.element.classList.add('request-initiator-view');
176
- this.linkifier = new Components.Linkifier.Linkifier();
177
171
  this.request = request;
178
172
  this.#view = view;
179
173
  }
@@ -192,8 +186,8 @@ export class RequestInitiatorView extends UI.Widget.VBox {
192
186
  const networkManager = SDK.NetworkManager.NetworkManager.forRequest(request);
193
187
  const target = networkManager?.target() ?? targetManager.primaryPageTarget() ?? targetManager.rootTarget();
194
188
  let stackTrace: StackTrace.StackTrace.StackTrace|null = null;
195
- const preview = new Components.JSPresentationUtils.StackTracePreviewContent(
196
- undefined, target ?? undefined, linkifier, {tabStops: focusableLink});
189
+ const preview = new Components.JSPresentationUtils.StackTracePreviewContent();
190
+ preview.options = {tabStops: focusableLink};
197
191
  if (target) {
198
192
  stackTrace = await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
199
193
  .createStackTraceFromProtocolRuntime(initiator.stack, target);
@@ -219,8 +213,6 @@ export class RequestInitiatorView extends UI.Widget.VBox {
219
213
  initiatorGraph,
220
214
  stackTrace,
221
215
  request: this.request,
222
- linkifier: this.linkifier,
223
- target: target || undefined,
224
216
  };
225
217
 
226
218
  this.#view(viewInput, undefined, this.contentElement);
@@ -2498,10 +2498,6 @@ export class TimelineDetailsContentHelper {
2498
2498
  * contains any entries, and discards it if it's empty.
2499
2499
  */
2500
2500
  async createChildStackTraceElement(runtimeStackTrace: Protocol.Runtime.StackTrace): Promise<HTMLElement|null> {
2501
- if (!this.#linkifier) {
2502
- return null;
2503
- }
2504
-
2505
2501
  // Fallback to the main page/root target. Maybe the main page has a source map we need.
2506
2502
  // Worst case the stack is identity mapped.
2507
2503
  const targetManager = SDK.TargetManager.TargetManager.instance();
@@ -2513,8 +2509,8 @@ export class TimelineDetailsContentHelper {
2513
2509
  const stackTrace =
2514
2510
  await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().createStackTraceFromProtocolRuntime(
2515
2511
  runtimeStackTrace, target);
2516
- const callFrameContents = new LegacyComponents.JSPresentationUtils.StackTracePreviewContent(
2517
- undefined, target, this.#linkifier, {tabStops: true, showColumnNumber: true});
2512
+ const callFrameContents = new LegacyComponents.JSPresentationUtils.StackTracePreviewContent();
2513
+ callFrameContents.options = {tabStops: true, showColumnNumber: true};
2518
2514
  callFrameContents.stackTrace = stackTrace;
2519
2515
 
2520
2516
  await callFrameContents.updateComplete;
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: https://chromium.googlesource.com/chromium/src
3
3
  Version: N/A
4
- Revision: 1b64dcefe38cd6a1d49f95075bd448eae1c3cd57
4
+ Revision: ccc41bdd9ec5ebd001ba6ac080db5aa20d8b96a9
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE
@@ -34,17 +34,15 @@
34
34
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
35
  */
36
36
 
37
- import * as Common from '../../../../core/common/common.js';
38
37
  import * as i18n from '../../../../core/i18n/i18n.js';
39
38
  import * as SDK from '../../../../core/sdk/sdk.js';
40
- import type * as Protocol from '../../../../generated/protocol.js';
41
39
  import * as StackTrace from '../../../../models/stack_trace/stack_trace.js';
42
40
  import * as Workspace from '../../../../models/workspace/workspace.js';
43
41
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
44
42
  import * as UI from '../../legacy.js';
45
43
 
46
44
  import jsUtilsStyles from './jsUtils.css.js';
47
- import {Events as LinkifierEvents, Linkifier} from './Linkifier.js';
45
+ import {Linkifier} from './Linkifier.js';
48
46
 
49
47
  const UIStrings = {
50
48
  /**
@@ -63,10 +61,6 @@ const UIStrings = {
63
61
  * @description A link to rehide frames that are by default hidden.
64
62
  */
65
63
  showLess: 'Show less',
66
- /**
67
- * @description Text indicating that source url of a link is currently unknown
68
- */
69
- unknownSource: 'unknown',
70
64
  } as const;
71
65
  const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/utils/JSPresentationUtils.ts', UIStrings);
72
66
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -95,74 +89,8 @@ function populateContextMenu(link: Element, event: Event): void {
95
89
  void contextMenu.show();
96
90
  }
97
91
 
98
- // TODO(crbug.com/456517732): remove when all usages of runtimeStackTrace are migrated.
99
- function buildStackTraceRowsForLegacyRuntimeStackTrace(
100
- stackTrace: Protocol.Runtime.StackTrace,
101
- target: SDK.Target.Target|null,
102
- linkifier: Linkifier,
103
- tabStops: boolean|undefined,
104
- updateCallback?: (arg0: Array<StackTraceRegularRow|StackTraceAsyncRow>) => void,
105
- showColumnNumber?: boolean,
106
- ): Array<StackTraceRegularRow|StackTraceAsyncRow> {
107
- const stackTraceRows: Array<StackTraceRegularRow|StackTraceAsyncRow> = [];
108
-
109
- if (updateCallback) {
110
- const throttler = new Common.Throttler.Throttler(100);
111
- linkifier.addEventListener(LinkifierEvents.LIVE_LOCATION_UPDATED, () => {
112
- void throttler.schedule(async () => updateCallback(stackTraceRows));
113
- });
114
- }
115
-
116
- function buildStackTraceRowsHelper(
117
- stackTrace: Protocol.Runtime.StackTrace,
118
- previousCallFrames: Protocol.Runtime.CallFrame[]|undefined = undefined): void {
119
- let asyncRow: StackTraceAsyncRow|null = null;
120
- if (previousCallFrames) {
121
- asyncRow = {
122
- asyncDescription: UI.UIUtils.asyncStackTraceLabel(stackTrace.description, previousCallFrames),
123
- };
124
- stackTraceRows.push(asyncRow);
125
- }
126
- let previousStackFrameWasBreakpointCondition = false;
127
- for (const stackFrame of stackTrace.callFrames) {
128
- const functionName = UI.UIUtils.beautifyFunctionName(stackFrame.functionName);
129
- const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame, {
130
- showColumnNumber,
131
- tabStop: Boolean(tabStops),
132
- inlineFrameIndex: 0,
133
- revealBreakpoint: previousStackFrameWasBreakpointCondition,
134
- });
135
- if (link) {
136
- link.setAttribute('jslog', `${VisualLogging.link('stack-trace').track({click: true})}`);
137
- link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
138
-
139
- if (!link.textContent) {
140
- link.textContent = i18nString(UIStrings.unknownSource);
141
- }
142
- }
143
- stackTraceRows.push({functionName, link});
144
- previousStackFrameWasBreakpointCondition = [
145
- SDK.DebuggerModel.COND_BREAKPOINT_SOURCE_URL,
146
- SDK.DebuggerModel.LOGPOINT_SOURCE_URL,
147
- ].includes(stackFrame.url);
148
- }
149
- }
150
-
151
- buildStackTraceRowsHelper(stackTrace);
152
- let previousCallFrames = stackTrace.callFrames;
153
- for (let asyncStackTrace = stackTrace.parent; asyncStackTrace; asyncStackTrace = asyncStackTrace.parent) {
154
- if (asyncStackTrace.callFrames.length) {
155
- buildStackTraceRowsHelper(asyncStackTrace, previousCallFrames);
156
- }
157
- previousCallFrames = asyncStackTrace.callFrames;
158
- }
159
- return stackTraceRows;
160
- }
161
-
162
92
  function buildStackTraceRows(
163
93
  stackTrace: StackTrace.StackTrace.StackTrace,
164
- target: SDK.Target.Target|null,
165
- linkifier: Linkifier,
166
94
  tabStops: boolean|undefined,
167
95
  showColumnNumber?: boolean,
168
96
  ): Array<StackTraceRegularRow|StackTraceAsyncRow> {
@@ -214,9 +142,8 @@ function buildStackTraceRows(
214
142
 
215
143
  function renderStackTraceTable(
216
144
  container: Element, parent: Element, expandable: boolean,
217
- stackTraceRows: Array<StackTraceRegularRow|StackTraceAsyncRow>): HTMLElement[] {
145
+ stackTraceRows: Array<StackTraceRegularRow|StackTraceAsyncRow>): void {
218
146
  container.removeChildren();
219
- const links: HTMLElement[] = [];
220
147
 
221
148
  // The tableSection groups one or more synchronous call frames together.
222
149
  // Wherever there is an asynchronous call, a new section is created.
@@ -250,10 +177,7 @@ function renderStackTraceTable(
250
177
  } else {
251
178
  row.createChild('td', 'function-name').textContent = item.functionName;
252
179
  row.createChild('td').textContent = ' @ ';
253
- if (item.link) {
254
- row.createChild('td', 'link').appendChild(item.link);
255
- links.push(item.link);
256
- }
180
+ row.createChild('td', 'link').appendChild(item.link);
257
181
  }
258
182
  }
259
183
 
@@ -286,13 +210,9 @@ function renderStackTraceTable(
286
210
  // If we are in a popup, this will trigger a re-layout
287
211
  UI.GlassPane.GlassPane.containerMoved(container);
288
212
  }, false);
289
-
290
- return links;
291
213
  }
292
214
 
293
215
  export interface Options {
294
- // TODO(crbug.com/456517732): remove when all usages of runtimeStackTrace are migrated.
295
- runtimeStackTrace?: Protocol.Runtime.StackTrace;
296
216
  tabStops?: boolean;
297
217
  // Whether the width of stack trace preview
298
218
  // is constrained to its container or whether
@@ -304,7 +224,7 @@ export interface Options {
304
224
 
305
225
  interface StackTraceRegularRow {
306
226
  functionName: string;
307
- link: HTMLElement|null;
227
+ link: HTMLElement;
308
228
  }
309
229
 
310
230
  interface StackTraceAsyncRow {
@@ -313,92 +233,43 @@ interface StackTraceAsyncRow {
313
233
 
314
234
  export class StackTracePreviewContent extends UI.Widget.Widget {
315
235
  #stackTrace?: StackTrace.StackTrace.StackTrace;
316
- #target?: SDK.Target.Target;
317
- #linkifier?: Linkifier;
318
- #ownedLinkifier?: Linkifier;
319
- #options: Options;
320
- #links: HTMLElement[] = [];
236
+ #options: Options = {};
321
237
 
322
238
  readonly #table: HTMLElement;
323
- /**
324
- * Updated when we update to define if we have any rows for the StackTrace;
325
- * allowing the caller to know if this element is empty or not.
326
- */
327
- #hasRows = false;
328
239
 
329
- constructor(element?: HTMLElement, target?: SDK.Target.Target, linkifier?: Linkifier, options?: Options) {
330
- super(element, {useShadowDom: true});
331
-
332
- this.#target = target;
333
- this.#linkifier = linkifier;
334
- if (!this.#linkifier) {
335
- this.#ownedLinkifier = new Linkifier();
336
- this.#linkifier = this.#ownedLinkifier;
337
- }
338
- this.#options = options || {
339
- widthConstrained: false,
340
- };
341
-
342
- this.element.classList.add('monospace');
343
- this.element.classList.add('stack-preview-container');
344
- this.element.classList.toggle('width-constrained', this.#options.widthConstrained ?? false);
345
- this.element.style.display = 'inline-block';
240
+ constructor(element?: HTMLElement) {
241
+ super(element, {useShadowDom: true, classes: ['monospace', 'stack-preview-container']});
346
242
 
347
243
  UI.DOMUtilities.appendStyle(this.element.shadowRoot as ShadowRoot, jsUtilsStyles);
348
244
 
349
245
  this.#table = this.contentElement.createChild('table', 'stack-preview-container');
350
- this.#table.classList.toggle('width-constrained', this.#options.widthConstrained ?? false);
351
-
352
- this.performUpdate();
353
246
  }
354
247
 
355
248
  hasContent(): boolean {
356
- return this.#hasRows;
249
+ if (!this.#stackTrace) {
250
+ return false;
251
+ }
252
+ const {syncFragment, asyncFragments} = this.#stackTrace;
253
+ return syncFragment.frames.length > 0 || asyncFragments.some(f => f.frames.length > 0);
357
254
  }
358
255
 
359
256
  override performUpdate(): void {
360
- if (!this.#linkifier) {
257
+ if (!this.#stackTrace) {
361
258
  return;
362
259
  }
363
260
 
364
- const {runtimeStackTrace, tabStops} = this.#options;
365
-
366
- if (this.#stackTrace) {
367
- const stackTraceRows = buildStackTraceRows(
368
- this.#stackTrace, this.#target ?? null, this.#linkifier, tabStops, this.#options.showColumnNumber);
369
- this.#hasRows = stackTraceRows.length > 0;
370
- this.#links = renderStackTraceTable(this.#table, this.element, this.#options.expandable ?? false, stackTraceRows);
371
- return;
372
- }
373
-
374
- if (runtimeStackTrace) {
375
- // TODO(crbug.com/456517732): remove when all usages of runtimeStackTrace are migrated.
376
- const updateCallback =
377
- renderStackTraceTable.bind(null, this.#table, this.element, this.#options.expandable ?? false);
378
- const stackTraceRows = buildStackTraceRowsForLegacyRuntimeStackTrace(
379
- runtimeStackTrace ?? {callFrames: []}, this.#target ?? null, this.#linkifier, tabStops, updateCallback,
380
- this.#options.showColumnNumber);
381
- this.#hasRows = stackTraceRows.length > 0;
382
- this.#links = renderStackTraceTable(this.#table, this.element, this.#options.expandable ?? false, stackTraceRows);
383
- }
261
+ const stackTraceRows =
262
+ buildStackTraceRows(this.#stackTrace, this.#options.tabStops, this.#options.showColumnNumber);
263
+ renderStackTraceTable(this.#table, this.element, this.#options.expandable ?? false, stackTraceRows);
384
264
  }
385
265
 
386
266
  get linkElements(): readonly HTMLElement[] {
387
- return this.#links;
388
- }
389
-
390
- set target(target: SDK.Target.Target|undefined) {
391
- this.#target = target;
392
- this.requestUpdate();
393
- }
394
-
395
- set linkifier(linkifier: Linkifier) {
396
- this.#linkifier = linkifier;
397
- this.requestUpdate();
267
+ return [...this.contentElement.querySelectorAll<HTMLElement>('td.link > .devtools-link')];
398
268
  }
399
269
 
400
270
  set options(options: Options) {
401
271
  this.#options = options;
272
+ this.#table.classList.toggle('width-constrained', this.#options.widthConstrained ?? false);
402
273
  this.requestUpdate();
403
274
  }
404
275
 
@@ -410,8 +281,4 @@ export class StackTracePreviewContent extends UI.Widget.Widget {
410
281
  this.#stackTrace.addEventListener(StackTrace.StackTrace.Events.UPDATED, this.requestUpdate, this);
411
282
  this.requestUpdate();
412
283
  }
413
-
414
- override onDetach(): void {
415
- this.#ownedLinkifier?.dispose();
416
- }
417
284
  }
@@ -17,7 +17,7 @@ import * as TextUtils from '../../../../models/text_utils/text_utils.js';
17
17
  import type * as Trace from '../../../../models/trace/trace.js';
18
18
  import * as Workspace from '../../../../models/workspace/workspace.js';
19
19
  import * as UIHelpers from '../../../helpers/helpers.js';
20
- import {Directives, html, type LitTemplate, render} from '../../../lit/lit.js';
20
+ import {Directives, html, type LitTemplate, render, type TemplateResult} from '../../../lit/lit.js';
21
21
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
22
22
  import * as UI from '../../legacy.js';
23
23
 
@@ -562,7 +562,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
562
562
  info.icon = icon;
563
563
  }
564
564
 
565
- static renderLinkifiedUrl(url: Platform.DevToolsPath.UrlString, options?: LinkifyURLOptions): LitTemplate {
565
+ static renderLinkifiedUrl(url: Platform.DevToolsPath.UrlString, options?: LinkifyURLOptions): TemplateResult {
566
566
  options = options || {
567
567
  showColumnNumber: false,
568
568
  inlineFrameIndex: 0,
@@ -639,7 +639,8 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
639
639
  return link;
640
640
  }
641
641
 
642
- private static renderLink(text: string|HTMLElement, className: string, options: CreateLinkOptions = {}): LitTemplate {
642
+ private static renderLink(text: string|HTMLElement, className: string, options: CreateLinkOptions = {}):
643
+ TemplateResult {
643
644
  const {maxLength, title, href, preventClick, tabStop, bypassURLTrimming, jslogContext} = options;
644
645
  const classes: Record<string, boolean> = {
645
646
  'devtools-link': true,
@@ -666,6 +667,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
666
667
  if (!link) {
667
668
  return;
668
669
  }
670
+ options.onRef?.(link as HTMLElement);
669
671
  if (text instanceof HTMLElement) {
670
672
  link.appendChild(text);
671
673
  } else if (bypassURLTrimming) {
@@ -1153,6 +1155,7 @@ export interface LinkifyURLOptions {
1153
1155
  userMetric?: Host.UserMetrics.Action;
1154
1156
  jslogContext?: string;
1155
1157
  omitOrigin?: boolean;
1158
+ onRef?: (el: HTMLElement) => void;
1156
1159
  }
1157
1160
 
1158
1161
  export interface LinkifyOptions {
@@ -1183,6 +1186,7 @@ interface CreateLinkOptions {
1183
1186
  lineNumber?: number;
1184
1187
  columnNumber?: number;
1185
1188
  userMetric?: Host.UserMetrics.Action;
1189
+ onRef?: (el: HTMLElement) => void;
1186
1190
  }
1187
1191
 
1188
1192
  interface LinkDisplayOptions {
@@ -4,15 +4,6 @@
4
4
  * found in the LICENSE file.
5
5
  */
6
6
 
7
- :host {
8
- display: inline;
9
- }
10
-
11
- :host(.width-constrained) {
12
- display: inline-block;
13
- width: 100%;
14
- }
15
-
16
7
  .stack-preview-async-description {
17
8
  padding: 3px 0 1px;
18
9
  font-weight: bold;
package/package.json CHANGED
@@ -105,5 +105,5 @@
105
105
  "flat-cache": "6.1.12"
106
106
  }
107
107
  },
108
- "version": "1.0.1585538"
108
+ "version": "1.0.1585664"
109
109
  }