chrome-devtools-frontend 1.0.1583146 → 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.
- package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
- package/front_end/core/host/InspectorFrontendHostStub.ts +2 -0
- package/front_end/core/root/Runtime.ts +12 -6
- package/front_end/core/sdk/CSSMatchedStyles.ts +3 -0
- package/front_end/core/sdk/CSSMetadata.ts +3 -0
- package/front_end/entrypoints/main/MainImpl.ts +1 -0
- package/front_end/generated/Deprecation.ts +21 -0
- package/front_end/generated/InspectorBackendCommands.ts +5 -3
- package/front_end/generated/SupportedCSSProperties.js +10 -4
- package/front_end/generated/protocol-mapping.d.ts +2 -1
- package/front_end/generated/protocol-proxy-api.d.ts +2 -1
- package/front_end/generated/protocol.ts +14 -0
- package/front_end/models/ai_assistance/AiConversation.ts +34 -2
- package/front_end/models/ai_assistance/BuiltInAi.ts +1 -2
- package/front_end/models/ai_assistance/agents/AiAgent.ts +3 -10
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +17 -9
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -24
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +12 -0
- package/front_end/models/ai_code_generation/AiCodeGeneration.ts +5 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +16 -8
- package/front_end/models/computed_style/ComputedStyleModel.ts +20 -15
- package/front_end/models/greendev/Prototypes.ts +1 -5
- package/front_end/models/issues_manager/CorsIssue.ts +2 -9
- package/front_end/models/issues_manager/descriptions/corsLocalNetworkAccessPermissionDenied.md +2 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +20 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +13 -36
- package/front_end/panels/ai_assistance/components/ChatInput.ts +73 -95
- package/front_end/panels/ai_assistance/components/ChatView.ts +13 -2
- package/front_end/panels/application/FrameDetailsView.ts +4 -9
- package/front_end/panels/common/AiCodeGenerationTeaser.ts +10 -0
- package/front_end/panels/console/ConsoleView.ts +1 -2
- package/front_end/panels/console/ConsoleViewMessage.ts +19 -12
- package/front_end/panels/elements/ComputedStyleWidget.ts +41 -21
- package/front_end/panels/elements/ElementsPanel.ts +18 -5
- package/front_end/panels/elements/ElementsTreeElement.ts +173 -169
- package/front_end/panels/elements/NodeStackTraceWidget.ts +3 -13
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +69 -0
- package/front_end/panels/elements/computedStyleWidget.css +1 -6
- package/front_end/panels/elements/elements.ts +3 -1
- package/front_end/panels/issues/AffectedResourcesView.ts +1 -2
- package/front_end/panels/network/NetworkDataGridNode.ts +0 -8
- package/front_end/panels/network/RequestConditionsDrawer.ts +138 -112
- package/front_end/panels/network/RequestInitiatorView.ts +2 -10
- package/front_end/panels/settings/SettingsScreen.ts +12 -4
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +6 -9
- package/front_end/panels/sources/CallStackSidebarPane.ts +4 -6
- package/front_end/panels/sources/DebuggerPlugin.ts +2 -1
- package/front_end/panels/sources/GoToLineQuickOpen.ts +0 -4
- package/front_end/panels/sources/OpenFileQuickOpen.ts +0 -4
- package/front_end/panels/sources/OutlineQuickOpen.ts +0 -4
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +3 -1
- package/front_end/panels/sources/sources-meta.ts +9 -6
- package/front_end/panels/timeline/TimelineFlameChartView.ts +0 -12
- package/front_end/panels/timeline/TimelinePanel.ts +35 -15
- package/front_end/panels/timeline/TimelineUIUtils.ts +2 -6
- package/front_end/panels/timeline/components/Sidebar.ts +21 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +1 -20
- package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +2 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js +5 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +8 -6
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +2 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js +5 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +4 -3
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/encoding.ts +5 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/linkifier/LinkifierImpl.ts +3 -0
- package/front_end/ui/components/linkifier/LinkifierUtils.ts +3 -0
- package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +29 -7
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +34 -18
- package/front_end/ui/legacy/InspectorView.ts +41 -15
- package/front_end/ui/legacy/UIUtils.ts +30 -6
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +4 -3
- package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -1
- package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +8 -2
- package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +8 -8
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +20 -150
- package/front_end/ui/legacy/components/utils/Linkifier.ts +120 -87
- package/front_end/ui/legacy/components/utils/jsUtils.css +0 -9
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/mcp/HostBindings.ts +3 -0
- package/package.json +1 -1
- package/front_end/models/issues_manager/descriptions/corsInsecurePrivateNetwork.md +0 -10
- package/front_end/models/issues_manager/descriptions/corsPreflightAllowPrivateNetworkError.md +0 -10
- package/front_end/models/issues_manager/descriptions/corsPrivateNetworkPermissionDenied.md +0 -10
- package/front_end/ui/legacy/Floaty.ts +0 -438
- package/front_end/ui/legacy/floaty.css +0 -77
|
@@ -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
|
|
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,8 @@ 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
|
+
const {animateOn} = UI.UIUtils;
|
|
76
77
|
|
|
77
78
|
const UIStrings = {
|
|
78
79
|
/**
|
|
@@ -465,6 +466,8 @@ export interface Decoration {
|
|
|
465
466
|
color: string;
|
|
466
467
|
}
|
|
467
468
|
|
|
469
|
+
const DOM_UPDATE_ANIMATION_CLASS_NAME = 'dom-update-highlight';
|
|
470
|
+
|
|
468
471
|
function handleAdornerKeydown(cb: (event: Event) => void): (event: KeyboardEvent) => void {
|
|
469
472
|
return (event: KeyboardEvent) => {
|
|
470
473
|
if (event.code === 'Enter' || event.code === 'Space') {
|
|
@@ -525,14 +528,6 @@ function renderTitle(
|
|
|
525
528
|
const result = convertUnicodeCharsToHTMLEntities(firstChild.nodeValue());
|
|
526
529
|
const textContent = Platform.StringUtilities.collapseWhitespace(result.text);
|
|
527
530
|
|
|
528
|
-
const highlightAnimation = (updateRecord?.hasChangedChildren() || updateRecord?.isCharDataModified()) ?
|
|
529
|
-
ref(el => {
|
|
530
|
-
if (el) {
|
|
531
|
-
UI.UIUtils.runCSSAnimationOnce(el, 'dom-update-highlight');
|
|
532
|
-
}
|
|
533
|
-
}) :
|
|
534
|
-
nothing;
|
|
535
|
-
|
|
536
531
|
const renderTextNode = ref(el => {
|
|
537
532
|
if (el) {
|
|
538
533
|
el.textContent = textContent;
|
|
@@ -541,8 +536,11 @@ function renderTitle(
|
|
|
541
536
|
});
|
|
542
537
|
|
|
543
538
|
return html`${openingTag}<span class="webkit-html-text-node" jslog=${
|
|
544
|
-
VisualLogging.value('text-node').track({change: true, dblclick: true})} ${
|
|
545
|
-
|
|
539
|
+
VisualLogging.value('text-node').track({change: true, dblclick: true})} ${
|
|
540
|
+
animateOn(
|
|
541
|
+
Boolean((updateRecord?.hasChangedChildren() || updateRecord?.isCharDataModified())),
|
|
542
|
+
DOM_UPDATE_ANIMATION_CLASS_NAME)} ${renderTextNode}></span>\u200B${
|
|
543
|
+
renderTag(node, tagName, true, expanded, false, updateRecord)}`;
|
|
546
544
|
}
|
|
547
545
|
|
|
548
546
|
if (isXMLMimeType || !ForbiddenClosingTagElements.has(tagName)) {
|
|
@@ -577,12 +575,6 @@ function renderTitle(
|
|
|
577
575
|
|
|
578
576
|
const result = convertUnicodeCharsToHTMLEntities(node.nodeValue());
|
|
579
577
|
const textContent = Platform.StringUtilities.collapseWhitespace(result.text);
|
|
580
|
-
const highlightAnimation = updateRecord?.isCharDataModified() ? ref(el => {
|
|
581
|
-
if (el) {
|
|
582
|
-
UI.UIUtils.runCSSAnimationOnce(el, 'dom-update-highlight');
|
|
583
|
-
}
|
|
584
|
-
}) :
|
|
585
|
-
nothing;
|
|
586
578
|
const renderTextNode = ref(el => {
|
|
587
579
|
if (el) {
|
|
588
580
|
el.textContent = textContent;
|
|
@@ -592,7 +584,8 @@ function renderTitle(
|
|
|
592
584
|
return html`"<span class="webkit-html-text-node" jslog=${VisualLogging.value('text-node').track({
|
|
593
585
|
change: true,
|
|
594
586
|
dblclick: true
|
|
595
|
-
})} ${
|
|
587
|
+
})} ${animateOn(Boolean(updateRecord?.isCharDataModified()), DOM_UPDATE_ANIMATION_CLASS_NAME)} ${
|
|
588
|
+
renderTextNode}></span>"`;
|
|
596
589
|
}
|
|
597
590
|
|
|
598
591
|
case Node.COMMENT_NODE: {
|
|
@@ -622,18 +615,12 @@ function renderTitle(
|
|
|
622
615
|
|
|
623
616
|
case Node.DOCUMENT_NODE: {
|
|
624
617
|
const text = (node as SDK.DOMModel.DOMDocument).documentURL;
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
showColumnNumber: false,
|
|
632
|
-
inlineFrameIndex: 0,
|
|
633
|
-
}));
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
return html`<span>#document (<span ${linkify}></span>)</span>`;
|
|
618
|
+
return html`<span>#document (<span>${Components.Linkifier.Linkifier.renderLinkifiedUrl(text, {
|
|
619
|
+
text,
|
|
620
|
+
preventClick: true,
|
|
621
|
+
showColumnNumber: false,
|
|
622
|
+
inlineFrameIndex: 0,
|
|
623
|
+
})}</span>)</span>`;
|
|
637
624
|
}
|
|
638
625
|
|
|
639
626
|
case Node.DOCUMENT_FRAGMENT_NODE: {
|
|
@@ -647,138 +634,138 @@ function renderTitle(
|
|
|
647
634
|
}
|
|
648
635
|
}
|
|
649
636
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
const value = attr.value || '';
|
|
655
|
-
const forceValue = isDiff;
|
|
656
|
-
const closingPunctuationRegex = /[\/;:\)\]\}]/g;
|
|
657
|
-
let highlightIndex = 0;
|
|
658
|
-
let highlightCount = 0;
|
|
659
|
-
let additionalHighlightOffset = 0;
|
|
637
|
+
const enum SrcsetTokenType {
|
|
638
|
+
LITERAL = 0,
|
|
639
|
+
LINK = 1
|
|
640
|
+
}
|
|
660
641
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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);
|
|
668
670
|
}
|
|
669
|
-
|
|
670
|
-
return match + '\u200B';
|
|
671
|
-
});
|
|
671
|
+
}
|
|
672
672
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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});
|
|
676
683
|
}
|
|
677
|
-
|
|
678
|
-
Highlighting.highlightRangesWithStyleClass(element, result.entityRanges, 'webkit-html-entity-value');
|
|
684
|
+
value = value.substring(url.length + descriptor.length);
|
|
679
685
|
}
|
|
686
|
+
return result;
|
|
687
|
+
}
|
|
680
688
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
if (el) {
|
|
689
|
-
UI.UIUtils.runCSSAnimationOnce(el, 'dom-update-highlight');
|
|
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;
|
|
690
696
|
}
|
|
691
|
-
})
|
|
692
|
-
|
|
697
|
+
})}`;
|
|
698
|
+
}
|
|
693
699
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
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;
|
|
697
713
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
function linkifyValue(value: string): Element {
|
|
702
|
-
const rewrittenHref = node ? node.resolveURL(value) : null;
|
|
703
|
-
if (rewrittenHref === null) {
|
|
704
|
-
const span = document.createElement('span');
|
|
705
|
-
setValueWithEntities(span, value);
|
|
706
|
-
return span;
|
|
707
|
-
}
|
|
708
|
-
value = value.replace(closingPunctuationRegex, '$&\u200B');
|
|
709
|
-
if (value.startsWith('data:')) {
|
|
710
|
-
value = Platform.StringUtilities.trimMiddle(value, 60);
|
|
711
|
-
}
|
|
712
|
-
const link = node && node.nodeName().toLowerCase() === 'a' ?
|
|
713
|
-
Link.create(rewrittenHref, value, undefined, 'image-url') :
|
|
714
|
-
Components.Linkifier.Linkifier.linkifyURL(rewrittenHref, {
|
|
715
|
-
text: value,
|
|
716
|
-
preventClick: true,
|
|
717
|
-
showColumnNumber: false,
|
|
718
|
-
inlineFrameIndex: 0,
|
|
719
|
-
});
|
|
720
|
-
return ImagePreviewPopover.setImageUrl(link, rewrittenHref);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
function linkifySrcset(value: string): DocumentFragment {
|
|
724
|
-
// Splitting normally on commas or spaces will break on valid srcsets "foo 1x,bar 2x" and "data:,foo 1x".
|
|
725
|
-
const fragment = document.createDocumentFragment();
|
|
726
|
-
let i = 0;
|
|
727
|
-
while (value.length) {
|
|
728
|
-
if (i++ > 0) {
|
|
729
|
-
UI.UIUtils.createTextChild(fragment, ' ');
|
|
730
|
-
}
|
|
731
|
-
value = value.trim();
|
|
732
|
-
let url = '';
|
|
733
|
-
let descriptor = '';
|
|
734
|
-
const indexOfSpace = value.search(/\s/);
|
|
735
|
-
if (indexOfSpace === -1) {
|
|
736
|
-
url = value;
|
|
737
|
-
} else if (indexOfSpace > 0 && value[indexOfSpace - 1] === ',') {
|
|
738
|
-
url = value.substring(0, indexOfSpace);
|
|
739
|
-
} else {
|
|
740
|
-
url = value.substring(0, indexOfSpace);
|
|
741
|
-
const indexOfComma = value.indexOf(',', indexOfSpace);
|
|
742
|
-
if (indexOfComma !== -1) {
|
|
743
|
-
descriptor = value.substring(indexOfSpace, indexOfComma + 1);
|
|
744
|
-
} else {
|
|
745
|
-
descriptor = value.substring(indexOfSpace);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
714
|
+
additionalHighlightOffset += 1;
|
|
715
|
+
return match + '\u200B';
|
|
716
|
+
});
|
|
748
717
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
+
}
|
|
725
|
+
|
|
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);
|
|
756
732
|
}
|
|
757
|
-
|
|
758
|
-
|
|
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);
|
|
759
744
|
}
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
return fragment;
|
|
745
|
+
})}>${Platform.StringUtilities.trimMiddle(value, 150)}</devtools-link>`;
|
|
763
746
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
valueElement.removeChildren();
|
|
772
|
-
if (nodeName && (name === 'src' || name === 'href') && value) {
|
|
773
|
-
valueElement.appendChild(linkifyValue(value));
|
|
774
|
-
} else if ((nodeName === 'img' || nodeName === 'source') && name === 'srcset') {
|
|
775
|
-
valueElement.appendChild(linkifySrcset(value));
|
|
776
|
-
} else if (nodeName === 'image' && (name === 'xlink:href' || name === 'href')) {
|
|
777
|
-
valueElement.appendChild(linkifySrcset(value));
|
|
778
|
-
} else {
|
|
779
|
-
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);
|
|
780
754
|
}
|
|
781
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
|
+
});
|
|
782
769
|
|
|
783
770
|
const relationRef =
|
|
784
771
|
(relation: Protocol.DOM.GetElementByRelationRequestRelation, tooltip: string): ReturnType<typeof ref> =>
|
|
@@ -831,11 +818,41 @@ function renderAttribute(
|
|
|
831
818
|
}
|
|
832
819
|
}
|
|
833
820
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
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
|
|
844
|
+
return html`<span class="webkit-html-attribute" jslog=${jslog}><span class="webkit-html-attribute-name"
|
|
845
|
+
${animateOn(Boolean(updateRecord?.isAttributeModified(name) && !hasText), DOM_UPDATE_ANIMATION_CLASS_NAME)} ${
|
|
846
|
+
relationRefDirective}>${name}</span>${
|
|
847
|
+
hasText ? html`=\u200B"<span class="webkit-html-attribute-value" ${
|
|
848
|
+
animateOn(
|
|
849
|
+
Boolean(updateRecord?.isAttributeModified(name) && hasText),
|
|
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>"` :
|
|
838
854
|
nothing}</span>`;
|
|
855
|
+
// clang-format on
|
|
839
856
|
}
|
|
840
857
|
|
|
841
858
|
function renderTag(
|
|
@@ -855,13 +872,6 @@ function renderTag(
|
|
|
855
872
|
hasUpdates = hasUpdates || (!expanded && updateRecord.hasChangedChildren());
|
|
856
873
|
}
|
|
857
874
|
|
|
858
|
-
const highlightAnimation = hasUpdates ? ref(el => {
|
|
859
|
-
if (el) {
|
|
860
|
-
UI.UIUtils.runCSSAnimationOnce(el, 'dom-update-highlight');
|
|
861
|
-
}
|
|
862
|
-
}) :
|
|
863
|
-
nothing;
|
|
864
|
-
|
|
865
875
|
// We are taking full text content of the tag, including attributes and children, to set the aria label.
|
|
866
876
|
// FIXME: we should compute the aria label ourselves if it is event needed.
|
|
867
877
|
const setAriaLabel = ref(el => {
|
|
@@ -876,7 +886,8 @@ function renderTag(
|
|
|
876
886
|
|
|
877
887
|
return html`<span
|
|
878
888
|
class=${Lit.Directives.classMap(classMap)} ${setAriaLabel}
|
|
879
|
-
><<span class=${tagNameClass} jslog=${jslog || nothing} ${
|
|
889
|
+
><<span class=${tagNameClass} jslog=${jslog || nothing} ${
|
|
890
|
+
animateOn(hasUpdates, DOM_UPDATE_ANIMATION_CLASS_NAME)}>${tagString}</span>${
|
|
880
891
|
attributes.map(attr => html` ${renderAttribute(attr, updateRecord, false, node)}`)}></span>\u200B`;
|
|
881
892
|
}
|
|
882
893
|
|
|
@@ -1189,7 +1200,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1189
1200
|
|
|
1190
1201
|
static animateOnDOMUpdate(treeElement: ElementsTreeElement): void {
|
|
1191
1202
|
const tagName = treeElement.listItemElement.querySelector('.webkit-html-tag-name');
|
|
1192
|
-
UI.UIUtils.runCSSAnimationOnce(tagName || treeElement.listItemElement,
|
|
1203
|
+
UI.UIUtils.runCSSAnimationOnce(tagName || treeElement.listItemElement, DOM_UPDATE_ANIMATION_CLASS_NAME);
|
|
1193
1204
|
}
|
|
1194
1205
|
|
|
1195
1206
|
static visibleShadowRoots(node: SDK.DOMModel.DOMNode): SDK.DOMModel.DOMNode[] {
|
|
@@ -1420,7 +1431,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1420
1431
|
}
|
|
1421
1432
|
}
|
|
1422
1433
|
}
|
|
1423
|
-
UI.UIUtils.runCSSAnimationOnce(animationElement,
|
|
1434
|
+
UI.UIUtils.runCSSAnimationOnce(animationElement, DOM_UPDATE_ANIMATION_CLASS_NAME);
|
|
1424
1435
|
}
|
|
1425
1436
|
|
|
1426
1437
|
isClosingTag(): boolean {
|
|
@@ -1726,13 +1737,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1726
1737
|
if (this.editing) {
|
|
1727
1738
|
return false;
|
|
1728
1739
|
}
|
|
1729
|
-
const handledByFloaty = UI.Floaty.onFloatyClick({
|
|
1730
|
-
type: UI.Floaty.FloatyContextTypes.ELEMENT_NODE_ID,
|
|
1731
|
-
data: {nodeId: this.nodeInternal.id},
|
|
1732
|
-
});
|
|
1733
|
-
if (handledByFloaty) {
|
|
1734
|
-
return false;
|
|
1735
|
-
}
|
|
1736
1740
|
return super.select(omitFocus, selectedByUser);
|
|
1737
1741
|
}
|
|
1738
1742
|
|
|
@@ -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 {
|
|
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, {
|
|
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(MaxLengthForLinks);
|
|
49
46
|
readonly #view: View;
|
|
50
47
|
|
|
51
48
|
constructor(view = DEFAULT_VIEW) {
|
|
@@ -73,13 +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
|
-
|
|
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
|
}
|
|
84
|
-
|
|
85
|
-
export const MaxLengthForLinks = 40;
|
|
@@ -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,
|
|
@@ -253,8 +253,7 @@ export abstract class AffectedResourcesView extends UI.TreeOutline.TreeElement {
|
|
|
253
253
|
const sourceCodeLocation = document.createElement('td');
|
|
254
254
|
sourceCodeLocation.classList.add('affected-source-location');
|
|
255
255
|
if (sourceLocation) {
|
|
256
|
-
const
|
|
257
|
-
const linkifier = new Components.Linkifier.Linkifier(maxLengthForDisplayedURLs);
|
|
256
|
+
const linkifier = new Components.Linkifier.Linkifier(UI.UIUtils.MaxLengthForDisplayedURLsInConsole);
|
|
258
257
|
const sourceAnchor = linkifier.linkifyScriptLocation(
|
|
259
258
|
target || null, sourceLocation.scriptId || null, sourceLocation.url as Platform.DevToolsPath.UrlString,
|
|
260
259
|
sourceLocation.lineNumber, {columnNumber: sourceLocation.columnNumber, inlineFrameIndex: 0});
|
|
@@ -1185,14 +1185,6 @@ export class NetworkRequestNode extends NetworkNode {
|
|
|
1185
1185
|
}
|
|
1186
1186
|
|
|
1187
1187
|
override select(suppressSelectedEvent?: boolean): void {
|
|
1188
|
-
const id = this.request()?.requestId();
|
|
1189
|
-
if (id) {
|
|
1190
|
-
const floatyHandled =
|
|
1191
|
-
UI.Floaty.onFloatyClick({type: UI.Floaty.FloatyContextTypes.NETWORK_REQUEST, data: {requestId: id}});
|
|
1192
|
-
if (floatyHandled) {
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
1188
|
super.select(suppressSelectedEvent);
|
|
1197
1189
|
this.parentView().dispatchEventToListeners(Events.RequestSelected, this.requestInternal);
|
|
1198
1190
|
}
|