chrome-devtools-frontend 1.0.1556696 → 1.0.1559913
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/Images/src/container.svg +4 -0
- package/front_end/core/common/Gzip.ts +15 -0
- package/front_end/core/common/Object.ts +5 -1
- package/front_end/core/host/ResourceLoader.ts +1 -1
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/sdk/CSSMetadata.ts +6 -6
- package/front_end/core/sdk/CSSModel.ts +2 -2
- package/front_end/core/sdk/DOMModel.ts +14 -3
- package/front_end/core/sdk/NetworkManager.ts +0 -7
- package/front_end/core/sdk/SourceMap.ts +16 -2
- package/front_end/core/sdk/SourceMapManager.ts +1 -1
- package/front_end/core/sdk/SourceMapScopesInfo.ts +11 -4
- package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +51 -8
- package/front_end/entrypoints/main/GlobalAiButton.ts +5 -1
- package/front_end/generated/Deprecation.ts +0 -7
- package/front_end/generated/InspectorBackendCommands.ts +5 -4
- package/front_end/generated/SupportedCSSProperties.js +64 -32
- package/front_end/generated/protocol-mapping.d.ts +9 -0
- package/front_end/generated/protocol-proxy-api.d.ts +7 -0
- package/front_end/generated/protocol.ts +23 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +11 -7
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +3 -3
- package/front_end/models/bindings/CompilerScriptMapping.ts +7 -6
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +4 -4
- package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
- package/front_end/models/stack_trace/StackTraceImpl.ts +5 -3
- package/front_end/models/stack_trace/StackTraceModel.ts +53 -40
- package/front_end/models/trace/EventsSerializer.ts +8 -2
- package/front_end/models/trace/LanternComputationData.ts +4 -3
- package/front_end/models/trace/Processor.ts +6 -5
- package/front_end/models/trace/Styles.ts +10 -1
- package/front_end/models/trace/handlers/LargestImagePaintHandler.ts +2 -2
- package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +2 -2
- package/front_end/models/trace/handlers/MetaHandler.ts +14 -0
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +54 -34
- package/front_end/models/trace/helpers/Timing.ts +8 -1
- package/front_end/models/trace/insights/Common.ts +1 -1
- package/front_end/models/trace/insights/LCPBreakdown.ts +4 -4
- package/front_end/models/trace/insights/LCPDiscovery.ts +3 -3
- package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
- package/front_end/models/trace/insights/types.ts +1 -1
- package/front_end/models/trace/types/TraceEvents.ts +62 -10
- package/front_end/panels/application/AppManifestView.ts +134 -223
- package/front_end/panels/application/CookieItemsView.ts +1 -0
- package/front_end/panels/application/SharedStorageTreeElement.ts +3 -0
- package/front_end/panels/application/appManifestView.css +1 -1
- package/front_end/panels/common/AiCodeGenerationTeaser.ts +48 -12
- package/front_end/panels/common/aiCodeGenerationTeaser.css +14 -0
- package/front_end/panels/common/common.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +4 -3
- package/front_end/panels/console/consoleView.css +1 -1
- package/front_end/panels/elements/CSSRuleValidator.ts +38 -0
- package/front_end/panels/elements/ElementsTreeElement.ts +108 -58
- package/front_end/panels/elements/ElementsTreeOutline.ts +0 -17
- package/front_end/panels/elements/ElementsTreeOutlineRenderer.ts +7 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +15 -4
- package/front_end/panels/elements/components/AdornerManager.ts +8 -0
- package/front_end/panels/emulation/DeviceModeToolbar.ts +3 -1
- package/front_end/panels/issues/AffectedResourcesView.ts +0 -1
- package/front_end/panels/lighthouse/LighthousePanel.ts +10 -0
- package/front_end/panels/lighthouse/lighthousePanel.css +46 -3
- package/front_end/panels/network/NetworkLogViewColumns.ts +9 -9
- package/front_end/panels/network/RequestCookiesView.ts +125 -141
- package/front_end/panels/network/components/RequestHeadersView.ts +2 -2
- package/front_end/panels/network/requestCookiesView.css +22 -20
- package/front_end/panels/recorder/components/RecordingView.ts +3 -3
- package/front_end/panels/recorder/components/StepView.ts +2 -1
- package/front_end/panels/settings/keybindsSettingsTab.css +4 -0
- package/front_end/panels/sources/CallStackSidebarPane.ts +7 -3
- package/front_end/panels/sources/DebuggerPausedMessage.ts +125 -90
- package/front_end/panels/sources/SourcesPanel.ts +10 -7
- package/front_end/panels/sources/debuggerPausedMessage.css +8 -0
- package/front_end/panels/timeline/StatusDialog.ts +4 -3
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +3 -16
- package/front_end/panels/timeline/TimelineFlameChartView.ts +64 -21
- package/front_end/panels/timeline/TimelinePanel.ts +71 -24
- package/front_end/panels/timeline/TimelineUIUtils.ts +28 -2
- package/front_end/panels/timeline/TimingsTrackAppender.ts +3 -1
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
- package/front_end/panels/timeline/components/insights/RenderBlocking.ts +6 -4
- package/front_end/panels/timeline/components/sidebarInsightsTab.css +2 -0
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +4 -0
- package/front_end/panels/timeline/timelinePanel.css +8 -1
- package/front_end/panels/timeline/utils/EntryNodes.ts +2 -1
- package/front_end/third_party/acorn/estree-legacy.d.ts +2 -0
- 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/api/Browser.d.ts +12 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +14 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js +6 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts +0 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +0 -20
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +10 -14
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
- 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 +14 -0
- 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/cdp/Browser.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +12 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js +22 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +9 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- 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.d.ts +26 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +72 -15
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +12 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +14 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js +6 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts +0 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +0 -20
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +11 -15
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
- 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 +14 -0
- 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/cdp/Browser.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +12 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js +22 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +9 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.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/lib/types.d.ts +26 -0
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +18 -0
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +16 -2
- package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +13 -0
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +0 -33
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +14 -28
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +19 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +19 -0
- package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +30 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +15 -6
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/icon_button/iconButton.css +3 -1
- package/front_end/ui/components/report_view/ReportView.ts +11 -2
- package/front_end/ui/components/report_view/report.css +16 -0
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +202 -32
- package/front_end/ui/components/text_editor/config.ts +6 -6
- package/front_end/ui/legacy/ContextMenu.ts +11 -2
- package/front_end/ui/legacy/SearchableView.ts +11 -5
- package/front_end/ui/legacy/SplitWidget.ts +1 -1
- package/front_end/ui/legacy/TextPrompt.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +4 -0
- package/front_end/ui/legacy/UIUtils.ts +0 -2
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +18 -3
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +3 -3
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +6 -0
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +43 -9
- package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
- package/package.json +1 -1
|
@@ -12,6 +12,13 @@ import * as UI from '../../../ui/legacy/legacy.js';
|
|
|
12
12
|
import * as VisualLogging from '../../visual_logging/visual_logging.js';
|
|
13
13
|
|
|
14
14
|
import {AiCodeCompletionTeaserPlaceholder} from './AiCodeCompletionTeaserPlaceholder.js';
|
|
15
|
+
import {
|
|
16
|
+
acceptAiAutoCompleteSuggestion,
|
|
17
|
+
aiAutoCompleteSuggestion,
|
|
18
|
+
aiAutoCompleteSuggestionState,
|
|
19
|
+
hasActiveAiSuggestion,
|
|
20
|
+
setAiAutoCompleteSuggestion,
|
|
21
|
+
} from './config.js';
|
|
15
22
|
import type {TextEditor} from './TextEditor.js';
|
|
16
23
|
|
|
17
24
|
export enum AiCodeGenerationTeaserMode {
|
|
@@ -28,30 +35,48 @@ const aiCodeGenerationTeaserModeState = CodeMirror.StateField.define<AiCodeGener
|
|
|
28
35
|
},
|
|
29
36
|
});
|
|
30
37
|
|
|
38
|
+
export interface AiCodeGenerationConfig {
|
|
39
|
+
generationContext: {
|
|
40
|
+
inferenceLanguage?: Host.AidaClient.AidaInferenceLanguage,
|
|
41
|
+
};
|
|
42
|
+
onSuggestionAccepted: () => void;
|
|
43
|
+
onRequestTriggered: () => void;
|
|
44
|
+
// TODO(b/445394511): Move exposing citations to onSuggestionAccepted
|
|
45
|
+
onResponseReceived: (citations: Host.AidaClient.Citation[]) => void;
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
export class AiCodeGenerationProvider {
|
|
32
49
|
#devtoolsLocale: string;
|
|
33
50
|
#aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
|
|
34
51
|
#generationTeaserCompartment = new CodeMirror.Compartment();
|
|
35
|
-
#generationTeaser: PanelCommon.AiCodeGenerationTeaser;
|
|
52
|
+
#generationTeaser: PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaser;
|
|
36
53
|
#editor?: TextEditor;
|
|
54
|
+
#aiCodeGenerationConfig: AiCodeGenerationConfig;
|
|
55
|
+
#aiCodeGeneration?: AiCodeGeneration.AiCodeGeneration.AiCodeGeneration;
|
|
37
56
|
|
|
57
|
+
#aidaClient: Host.AidaClient.AidaClient = new Host.AidaClient.AidaClient();
|
|
38
58
|
#boundOnUpdateAiCodeGenerationState = this.#updateAiCodeGenerationState.bind(this);
|
|
59
|
+
#controller = new AbortController();
|
|
39
60
|
|
|
40
|
-
private constructor() {
|
|
61
|
+
private constructor(aiCodeGenerationConfig: AiCodeGenerationConfig) {
|
|
41
62
|
this.#devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance().locale;
|
|
42
63
|
if (!AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(this.#devtoolsLocale)) {
|
|
43
64
|
throw new Error('AI code generation feature is not enabled.');
|
|
44
65
|
}
|
|
45
|
-
this.#generationTeaser = new PanelCommon.AiCodeGenerationTeaser();
|
|
66
|
+
this.#generationTeaser = new PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaser();
|
|
67
|
+
this.#aiCodeGenerationConfig = aiCodeGenerationConfig;
|
|
46
68
|
}
|
|
47
69
|
|
|
48
|
-
static createInstance(): AiCodeGenerationProvider {
|
|
49
|
-
return new AiCodeGenerationProvider();
|
|
70
|
+
static createInstance(aiCodeGenerationConfig: AiCodeGenerationConfig): AiCodeGenerationProvider {
|
|
71
|
+
return new AiCodeGenerationProvider(aiCodeGenerationConfig);
|
|
50
72
|
}
|
|
51
73
|
|
|
52
74
|
extension(): CodeMirror.Extension[] {
|
|
53
75
|
return [
|
|
54
|
-
CodeMirror.EditorView.updateListener.of(update => this
|
|
76
|
+
CodeMirror.EditorView.updateListener.of(update => this.#activateTeaser(update)),
|
|
77
|
+
CodeMirror.EditorView.updateListener.of(update => this.#abortGenerationDuringUpdate(update)),
|
|
78
|
+
aiAutoCompleteSuggestion,
|
|
79
|
+
aiAutoCompleteSuggestionState,
|
|
55
80
|
aiCodeGenerationTeaserModeState,
|
|
56
81
|
this.#generationTeaserCompartment.of([]),
|
|
57
82
|
CodeMirror.Prec.highest(CodeMirror.keymap.of(this.#editorKeymap())),
|
|
@@ -59,6 +84,7 @@ export class AiCodeGenerationProvider {
|
|
|
59
84
|
}
|
|
60
85
|
|
|
61
86
|
dispose(): void {
|
|
87
|
+
this.#controller.abort();
|
|
62
88
|
this.#cleanupAiCodeGeneration();
|
|
63
89
|
}
|
|
64
90
|
|
|
@@ -71,6 +97,10 @@ export class AiCodeGenerationProvider {
|
|
|
71
97
|
}
|
|
72
98
|
|
|
73
99
|
#setupAiCodeGeneration(): void {
|
|
100
|
+
if (this.#aiCodeGeneration) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.#aiCodeGeneration = new AiCodeGeneration.AiCodeGeneration.AiCodeGeneration({aidaClient: this.#aidaClient});
|
|
74
104
|
this.#editor?.dispatch({
|
|
75
105
|
effects:
|
|
76
106
|
[this.#generationTeaserCompartment.reconfigure([aiCodeGenerationTeaserExtension(this.#generationTeaser)])],
|
|
@@ -78,6 +108,10 @@ export class AiCodeGenerationProvider {
|
|
|
78
108
|
}
|
|
79
109
|
|
|
80
110
|
#cleanupAiCodeGeneration(): void {
|
|
111
|
+
if (!this.#aiCodeGeneration) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.#aiCodeGeneration = undefined;
|
|
81
115
|
this.#editor?.dispatch({
|
|
82
116
|
effects: [this.#generationTeaserCompartment.reconfigure([])],
|
|
83
117
|
});
|
|
@@ -99,23 +133,53 @@ export class AiCodeGenerationProvider {
|
|
|
99
133
|
{
|
|
100
134
|
key: 'Escape',
|
|
101
135
|
run: (): boolean => {
|
|
102
|
-
if (!this.#editor || !this.#
|
|
136
|
+
if (!this.#editor || !this.#aiCodeGeneration) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
if (hasActiveAiSuggestion(this.#editor.state)) {
|
|
140
|
+
this.#editor.dispatch({
|
|
141
|
+
effects: setAiAutoCompleteSuggestion.of(null),
|
|
142
|
+
});
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
const generationTeaserIsLoading = this.#generationTeaser.displayState ===
|
|
146
|
+
PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING;
|
|
147
|
+
if (this.#generationTeaser.isShowing() && generationTeaserIsLoading) {
|
|
148
|
+
this.#controller.abort();
|
|
149
|
+
this.#controller = new AbortController();
|
|
150
|
+
this.#dismissTeaser();
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
key: 'Tab',
|
|
158
|
+
run: (): boolean => {
|
|
159
|
+
if (!this.#aiCodeGeneration || !this.#editor || !hasActiveAiSuggestion(this.#editor.state)) {
|
|
103
160
|
return false;
|
|
104
161
|
}
|
|
105
|
-
this.#editor.
|
|
162
|
+
const {accepted, suggestion} = acceptAiAutoCompleteSuggestion(this.#editor.editor);
|
|
163
|
+
if (!accepted) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (suggestion?.rpcGlobalId) {
|
|
167
|
+
this.#aiCodeGeneration.registerUserAcceptance(suggestion.rpcGlobalId, suggestion.sampleId);
|
|
168
|
+
}
|
|
169
|
+
this.#aiCodeGenerationConfig?.onSuggestionAccepted();
|
|
106
170
|
return true;
|
|
107
171
|
},
|
|
108
172
|
},
|
|
109
173
|
{
|
|
110
174
|
any: (_view: unknown, event: KeyboardEvent) => {
|
|
111
|
-
if (!this.#editor || !this.#generationTeaser.isShowing()) {
|
|
175
|
+
if (!this.#editor || !this.#aiCodeGeneration || !this.#generationTeaser.isShowing()) {
|
|
112
176
|
return false;
|
|
113
177
|
}
|
|
114
178
|
if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event)) {
|
|
115
179
|
if (event.key === 'i') {
|
|
116
180
|
event.consume(true);
|
|
117
181
|
void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-generation.triggered');
|
|
118
|
-
this.#
|
|
182
|
+
void this.#triggerAiCodeGeneration({signal: this.#controller.signal});
|
|
119
183
|
return true;
|
|
120
184
|
}
|
|
121
185
|
}
|
|
@@ -125,7 +189,12 @@ export class AiCodeGenerationProvider {
|
|
|
125
189
|
];
|
|
126
190
|
}
|
|
127
191
|
|
|
128
|
-
|
|
192
|
+
#dismissTeaser(): void {
|
|
193
|
+
this.#generationTeaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.TRIGGER;
|
|
194
|
+
this.#editor?.dispatch({effects: setAiCodeGenerationTeaserMode.of(AiCodeGenerationTeaserMode.DISMISSED)});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#activateTeaser(update: CodeMirror.ViewUpdate): void {
|
|
129
198
|
const currentTeaserMode = update.state.field(aiCodeGenerationTeaserModeState);
|
|
130
199
|
if (currentTeaserMode === AiCodeGenerationTeaserMode.ACTIVE) {
|
|
131
200
|
return;
|
|
@@ -135,46 +204,147 @@ export class AiCodeGenerationProvider {
|
|
|
135
204
|
}
|
|
136
205
|
update.view.dispatch({effects: setAiCodeGenerationTeaserMode.of(AiCodeGenerationTeaserMode.ACTIVE)});
|
|
137
206
|
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Monitors editor changes to cancel an ongoing AI generation.
|
|
210
|
+
* We abort the request and dismiss the teaser if the user modifies the
|
|
211
|
+
* document or moves their cursor/selection. These actions indicate the user
|
|
212
|
+
* is no longer focused on the current generation point or has manually
|
|
213
|
+
* resumed editing, making the pending suggestion irrelevant.
|
|
214
|
+
*/
|
|
215
|
+
#abortGenerationDuringUpdate(update: CodeMirror.ViewUpdate): void {
|
|
216
|
+
if (!update.docChanged && update.state.selection.main.head === update.startState.selection.main.head) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const currentTeaserMode = update.state.field(aiCodeGenerationTeaserModeState);
|
|
220
|
+
const generationTeaserIsLoading = this.#generationTeaser.displayState ===
|
|
221
|
+
PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING;
|
|
222
|
+
// Generation should be in progress
|
|
223
|
+
if (currentTeaserMode === AiCodeGenerationTeaserMode.DISMISSED || !generationTeaserIsLoading) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.#controller.abort();
|
|
227
|
+
this.#controller = new AbortController();
|
|
228
|
+
this.#dismissTeaser();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async #triggerAiCodeGeneration(options?: {signal?: AbortSignal}): Promise<void> {
|
|
232
|
+
if (!this.#editor || !this.#aiCodeGeneration) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
this.#generationTeaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING;
|
|
237
|
+
const cursor = this.#editor.state.selection.main.head;
|
|
238
|
+
// TODO(b/445899453): Detect all types of comments
|
|
239
|
+
const query = this.#editor.state.doc.lineAt(cursor).text;
|
|
240
|
+
if (query.trim().length === 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const startTime = performance.now();
|
|
246
|
+
this.#aiCodeGenerationConfig?.onRequestTriggered();
|
|
247
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeGenerationRequestTriggered);
|
|
248
|
+
|
|
249
|
+
const generationResponse = await this.#aiCodeGeneration.generateCode(
|
|
250
|
+
query, AiCodeGeneration.AiCodeGeneration.basePreamble,
|
|
251
|
+
this.#aiCodeGenerationConfig?.generationContext.inferenceLanguage, options);
|
|
252
|
+
|
|
253
|
+
if (this.#generationTeaser) {
|
|
254
|
+
this.#dismissTeaser();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!generationResponse || generationResponse.samples.length === 0) {
|
|
258
|
+
this.#aiCodeGenerationConfig?.onResponseReceived([]);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const topSample = generationResponse.samples[0];
|
|
262
|
+
|
|
263
|
+
const shouldBlock = topSample.attributionMetadata?.attributionAction === Host.AidaClient.RecitationAction.BLOCK;
|
|
264
|
+
if (shouldBlock) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
this.#editor.dispatch({
|
|
269
|
+
effects: setAiAutoCompleteSuggestion.of({
|
|
270
|
+
text: '\n' + topSample.generationString,
|
|
271
|
+
from: cursor,
|
|
272
|
+
rpcGlobalId: generationResponse.metadata.rpcGlobalId,
|
|
273
|
+
sampleId: topSample.sampleId,
|
|
274
|
+
startTime,
|
|
275
|
+
onImpression: this.#aiCodeGeneration?.registerUserImpression.bind(this.#aiCodeGeneration),
|
|
276
|
+
})
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
AiCodeGeneration.debugLog('Suggestion dispatched to the editor', topSample.generationString);
|
|
280
|
+
const citations = topSample.attributionMetadata?.citations ?? [];
|
|
281
|
+
this.#aiCodeGenerationConfig?.onResponseReceived(citations);
|
|
282
|
+
} catch (e) {
|
|
283
|
+
AiCodeGeneration.debugLog('Error while fetching code generation suggestions from AIDA', e);
|
|
284
|
+
this.#aiCodeGenerationConfig?.onResponseReceived([]);
|
|
285
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeGenerationError);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (this.#generationTeaser) {
|
|
289
|
+
this.#dismissTeaser();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
138
292
|
}
|
|
139
293
|
|
|
140
|
-
|
|
141
|
-
|
|
294
|
+
function aiCodeGenerationTeaserExtension(teaser: PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaser):
|
|
295
|
+
CodeMirror.Extension {
|
|
142
296
|
return CodeMirror.ViewPlugin.fromClass(class {
|
|
143
|
-
#
|
|
297
|
+
#view: CodeMirror.EditorView;
|
|
144
298
|
|
|
145
|
-
constructor(
|
|
146
|
-
this.#
|
|
299
|
+
constructor(view: CodeMirror.EditorView) {
|
|
300
|
+
this.#view = view;
|
|
301
|
+
this.#updateTeaserState(view.state);
|
|
147
302
|
}
|
|
148
303
|
|
|
149
304
|
update(update: CodeMirror.ViewUpdate): void {
|
|
150
|
-
const currentTeaserMode = update.state.field(aiCodeGenerationTeaserModeState);
|
|
151
|
-
if (currentTeaserMode !== this.#teaserMode) {
|
|
152
|
-
this.#teaserMode = currentTeaserMode;
|
|
153
|
-
}
|
|
154
305
|
if (!update.docChanged && update.state.selection.main.head === update.startState.selection.main.head) {
|
|
155
306
|
return;
|
|
156
307
|
}
|
|
157
|
-
|
|
158
|
-
teaser.loading = false;
|
|
159
|
-
}
|
|
308
|
+
this.#updateTeaserState(update.state);
|
|
160
309
|
}
|
|
161
310
|
|
|
162
311
|
get decorations(): CodeMirror.DecorationSet {
|
|
163
|
-
|
|
312
|
+
const teaserMode = this.#view.state.field(aiCodeGenerationTeaserModeState);
|
|
313
|
+
if (teaserMode === AiCodeGenerationTeaserMode.DISMISSED) {
|
|
164
314
|
return CodeMirror.Decoration.none;
|
|
165
315
|
}
|
|
166
|
-
|
|
167
|
-
const
|
|
316
|
+
|
|
317
|
+
const cursorPosition = this.#view.state.selection.main.head;
|
|
318
|
+
const line = this.#view.state.doc.lineAt(cursorPosition);
|
|
319
|
+
|
|
320
|
+
const isEmptyLine = line.length === 0;
|
|
168
321
|
// TODO(b/445899453): Detect all types of comments
|
|
169
322
|
const isComment = line.text.startsWith('//');
|
|
170
323
|
const isCursorAtEndOfLine = cursorPosition >= line.to;
|
|
171
|
-
|
|
172
|
-
|
|
324
|
+
|
|
325
|
+
if ((isEmptyLine) || (isComment && isCursorAtEndOfLine)) {
|
|
326
|
+
return CodeMirror.Decoration.set([
|
|
327
|
+
CodeMirror.Decoration.widget({widget: new AiCodeCompletionTeaserPlaceholder(teaser), side: 1})
|
|
328
|
+
.range(cursorPosition),
|
|
329
|
+
]);
|
|
330
|
+
}
|
|
331
|
+
return CodeMirror.Decoration.none;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
#updateTeaserState(state: CodeMirror.EditorState): void {
|
|
335
|
+
// Only handle non loading states, as updates during generation are handled by
|
|
336
|
+
// #abortGenerationDuringUpdate in AiCodeGenerationProvider
|
|
337
|
+
if (teaser.displayState === PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const cursorPosition = state.selection.main.head;
|
|
341
|
+
const line = state.doc.lineAt(cursorPosition);
|
|
342
|
+
const isEmptyLine = line.length === 0;
|
|
343
|
+
if (isEmptyLine) {
|
|
344
|
+
teaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.DISCOVERY;
|
|
345
|
+
} else {
|
|
346
|
+
teaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.TRIGGER;
|
|
173
347
|
}
|
|
174
|
-
return CodeMirror.Decoration.set([
|
|
175
|
-
CodeMirror.Decoration.widget({widget: new AiCodeCompletionTeaserPlaceholder(teaser), side: 1})
|
|
176
|
-
.range(cursorPosition),
|
|
177
|
-
]);
|
|
178
348
|
}
|
|
179
349
|
}, {
|
|
180
350
|
decorations: v => v.decorations,
|
|
@@ -490,7 +490,7 @@ export interface ActiveSuggestion {
|
|
|
490
490
|
rpcGlobalId?: Host.AidaClient.RpcGlobalId;
|
|
491
491
|
startTime: number;
|
|
492
492
|
onImpression: (rpcGlobalId: Host.AidaClient.RpcGlobalId, latency: number, sampleId?: number) => void;
|
|
493
|
-
clearCachedRequest
|
|
493
|
+
clearCachedRequest?: () => void;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggestion|null>({
|
|
@@ -501,7 +501,7 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
|
|
|
501
501
|
if (effect.value) {
|
|
502
502
|
return effect.value;
|
|
503
503
|
}
|
|
504
|
-
value?.clearCachedRequest();
|
|
504
|
+
value?.clearCachedRequest?.();
|
|
505
505
|
return null;
|
|
506
506
|
}
|
|
507
507
|
}
|
|
@@ -514,14 +514,14 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
|
|
|
514
514
|
// between when the request was sent and the response was received.
|
|
515
515
|
// We check if the position is still valid before trying to map it.
|
|
516
516
|
if (value.from > tr.state.doc.length) {
|
|
517
|
-
value.clearCachedRequest();
|
|
517
|
+
value.clearCachedRequest?.();
|
|
518
518
|
return null;
|
|
519
519
|
}
|
|
520
520
|
|
|
521
521
|
// If deletion occurs, set to null. Otherwise, the mapping might fail if
|
|
522
522
|
// the position is inside the deleted range.
|
|
523
523
|
if (tr.docChanged && tr.state.doc.length < tr.startState.doc.length) {
|
|
524
|
-
value.clearCachedRequest();
|
|
524
|
+
value.clearCachedRequest?.();
|
|
525
525
|
return null;
|
|
526
526
|
}
|
|
527
527
|
|
|
@@ -530,7 +530,7 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
|
|
|
530
530
|
|
|
531
531
|
// If a change happened before the position from which suggestion was generated, set to null.
|
|
532
532
|
if (tr.docChanged && head < from) {
|
|
533
|
-
value.clearCachedRequest();
|
|
533
|
+
value.clearCachedRequest?.();
|
|
534
534
|
return null;
|
|
535
535
|
}
|
|
536
536
|
|
|
@@ -571,7 +571,7 @@ export function acceptAiAutoCompleteSuggestion(view: CM.EditorView):
|
|
|
571
571
|
userEvent: 'input.complete',
|
|
572
572
|
});
|
|
573
573
|
|
|
574
|
-
suggestion.clearCachedRequest();
|
|
574
|
+
suggestion.clearCachedRequest?.();
|
|
575
575
|
return {accepted: true, suggestion};
|
|
576
576
|
}
|
|
577
577
|
|
|
@@ -787,8 +787,17 @@ export class ContextMenu extends SubMenu {
|
|
|
787
787
|
|
|
788
788
|
const menuObject = this.buildMenuDescriptors();
|
|
789
789
|
const ownerDocument = (this.eventTarget as HTMLElement).ownerDocument;
|
|
790
|
-
|
|
791
|
-
|
|
790
|
+
|
|
791
|
+
let useSoftMenu = this.useSoftMenu || ContextMenu.useSoftMenu ||
|
|
792
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode();
|
|
793
|
+
|
|
794
|
+
// Allow force opening a Native menu when DevTools is under test.
|
|
795
|
+
// This allows opening DevTools on DevTools
|
|
796
|
+
if (!this.useSoftMenu && ContextMenu.useSoftMenu && this.event.altKey) {
|
|
797
|
+
useSoftMenu = false;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (useSoftMenu) {
|
|
792
801
|
this.softMenu = new SoftContextMenu(
|
|
793
802
|
(menuObject as SoftContextMenuDescriptor[]), this.itemSelected.bind(this), this.keepOpen, undefined,
|
|
794
803
|
this.onSoftMenuClosed, this.loggableParent);
|
|
@@ -150,6 +150,7 @@ export class SearchableView extends VBox {
|
|
|
150
150
|
private replaceToggleButton: ToolbarToggle;
|
|
151
151
|
private searchInputElement: HTMLInputElement;
|
|
152
152
|
private matchesElement: HTMLElement;
|
|
153
|
+
private matchesElementValue: HTMLElement;
|
|
153
154
|
private searchNavigationPrevElement: ToolbarButton;
|
|
154
155
|
private searchNavigationNextElement: ToolbarButton;
|
|
155
156
|
private readonly replaceInputElement: HTMLInputElement;
|
|
@@ -314,6 +315,9 @@ export class SearchableView extends VBox {
|
|
|
314
315
|
this.matchesElement.style.color = 'var(--sys-color-on-surface-subtle)';
|
|
315
316
|
this.matchesElement.style.padding = '0 var(--sys-size-3)';
|
|
316
317
|
this.matchesElement.classList.add('search-results-matches');
|
|
318
|
+
ARIAUtils.markAsPoliteLiveRegion(this.matchesElement, false);
|
|
319
|
+
this.matchesElementValue = this.matchesElement.createChild('span');
|
|
320
|
+
ARIAUtils.setHidden(this.matchesElementValue, true);
|
|
317
321
|
toolbar.appendToolbarItem(matchesText);
|
|
318
322
|
|
|
319
323
|
const cancelButtonElement = new Buttons.Button.Button();
|
|
@@ -455,7 +459,7 @@ export class SearchableView extends VBox {
|
|
|
455
459
|
resetSearch(): void {
|
|
456
460
|
this.clearSearch();
|
|
457
461
|
this.updateReplaceVisibility();
|
|
458
|
-
this.
|
|
462
|
+
this.matchesElementValue.textContent = '';
|
|
459
463
|
}
|
|
460
464
|
|
|
461
465
|
refreshSearch(): void {
|
|
@@ -504,15 +508,17 @@ export class SearchableView extends VBox {
|
|
|
504
508
|
|
|
505
509
|
private updateSearchMatchesCountAndCurrentMatchIndex(matches: number, currentMatchIndex: number): void {
|
|
506
510
|
if (!this.currentQuery) {
|
|
507
|
-
this.
|
|
511
|
+
this.matchesElementValue.textContent = '';
|
|
508
512
|
} else if (matches === 0 || currentMatchIndex >= 0) {
|
|
509
|
-
this.
|
|
513
|
+
this.matchesElementValue.textContent = i18nString(UIStrings.dOfD, {PH1: currentMatchIndex + 1, PH2: matches});
|
|
510
514
|
ARIAUtils.setLabel(
|
|
511
515
|
this.matchesElement, i18nString(UIStrings.accessibledOfD, {PH1: currentMatchIndex + 1, PH2: matches}));
|
|
512
516
|
} else if (matches === 1) {
|
|
513
|
-
this.
|
|
517
|
+
this.matchesElementValue.textContent = i18nString(UIStrings.matchString);
|
|
518
|
+
ARIAUtils.setLabel(this.matchesElement, i18nString(UIStrings.matchString));
|
|
514
519
|
} else {
|
|
515
|
-
this.
|
|
520
|
+
this.matchesElementValue.textContent = i18nString(UIStrings.dMatches, {PH1: matches});
|
|
521
|
+
ARIAUtils.setLabel(this.matchesElement, i18nString(UIStrings.dMatches, {PH1: matches}));
|
|
516
522
|
}
|
|
517
523
|
this.updateSearchNavigationButtonState(matches > 0);
|
|
518
524
|
}
|
|
@@ -327,7 +327,7 @@ export class TextPrompt extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
|
|
|
327
327
|
* or the |blurListener| parameter to register a "blur" event listener on the |element|
|
|
328
328
|
* (since the "blur" event does not bubble.)
|
|
329
329
|
*/
|
|
330
|
-
attachAndStartEditing(element: Element, blurListener
|
|
330
|
+
attachAndStartEditing(element: Element, blurListener?: (arg0: Event) => void): Element {
|
|
331
331
|
const proxyElement = this.#attach(element);
|
|
332
332
|
this.startEditing(blurListener);
|
|
333
333
|
return proxyElement;
|
|
@@ -1166,6 +1166,10 @@ export class ToolbarComboBox extends ToolbarItem<void, HTMLSelectElement> {
|
|
|
1166
1166
|
}
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
|
+
turnShrinkable(): void {
|
|
1170
|
+
this.element.classList.add('toolbar-has-dropdown-shrinkable');
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1169
1173
|
size(): number {
|
|
1170
1174
|
return this.element.childElementCount;
|
|
1171
1175
|
}
|
|
@@ -1295,8 +1295,6 @@ export class DevToolsIconLabel extends HTMLElement {
|
|
|
1295
1295
|
|
|
1296
1296
|
set data(data: IconData) {
|
|
1297
1297
|
this.#icon.data = data;
|
|
1298
|
-
// TODO(crbug.com/1427397): Clean this up. This was necessary so `DevToolsIconLabel` can use Lit icon
|
|
1299
|
-
// while being backwards-compatible with the legacy Icon while working for both small and large icons.
|
|
1300
1298
|
if (data.height === '14px') {
|
|
1301
1299
|
this.#icon.style.setProperty('margin-bottom', '-2px');
|
|
1302
1300
|
} else if (data.height === '20px') {
|
|
@@ -176,6 +176,12 @@ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined
|
|
|
176
176
|
|
|
177
177
|
const expiresSessionValue = i18nLazyString(UIStrings.session);
|
|
178
178
|
|
|
179
|
+
export interface CookiesTableData {
|
|
180
|
+
cookies: SDK.Cookie.Cookie[];
|
|
181
|
+
cookieToBlockedReasons?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.BlockedReason[]>;
|
|
182
|
+
cookieToExemptionReason?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.ExemptionReason>;
|
|
183
|
+
}
|
|
184
|
+
|
|
179
185
|
export class CookiesTable extends UI.Widget.VBox {
|
|
180
186
|
private saveCallback?: ((arg0: SDK.Cookie.Cookie, arg1: SDK.Cookie.Cookie|null) => Promise<boolean>);
|
|
181
187
|
private readonly refreshCallback?: (() => void);
|
|
@@ -190,15 +196,15 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
190
196
|
private readonly view: ViewFunction;
|
|
191
197
|
private selectedKey?: string;
|
|
192
198
|
private readonly editable: boolean;
|
|
193
|
-
private
|
|
199
|
+
private renderInline: boolean;
|
|
194
200
|
private readonly schemeBindingEnabled: boolean;
|
|
195
201
|
private readonly portBindingEnabled: boolean;
|
|
196
202
|
constructor(
|
|
197
|
-
renderInline?: boolean,
|
|
203
|
+
element?: HTMLElement, renderInline?: boolean,
|
|
198
204
|
saveCallback?: ((arg0: SDK.Cookie.Cookie, arg1: SDK.Cookie.Cookie|null) => Promise<boolean>),
|
|
199
205
|
refreshCallback?: (() => void), selectedCallback?: (() => void),
|
|
200
206
|
deleteCallback?: ((arg0: SDK.Cookie.Cookie, arg1: () => void) => void), view?: ViewFunction) {
|
|
201
|
-
super();
|
|
207
|
+
super(element);
|
|
202
208
|
if (!view) {
|
|
203
209
|
view = (input, _, target) => {
|
|
204
210
|
// clang-format off
|
|
@@ -325,6 +331,15 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
325
331
|
this.requestUpdate();
|
|
326
332
|
}
|
|
327
333
|
|
|
334
|
+
set cookiesData(data: CookiesTableData) {
|
|
335
|
+
this.setCookies(data.cookies, data.cookieToBlockedReasons, data.cookieToExemptionReason);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
set inline(value: boolean) {
|
|
339
|
+
this.renderInline = value;
|
|
340
|
+
this.requestUpdate();
|
|
341
|
+
}
|
|
342
|
+
|
|
328
343
|
setCookies(
|
|
329
344
|
cookies: SDK.Cookie.Cookie[],
|
|
330
345
|
cookieToBlockedReasons?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.BlockedReason[]>,
|
|
@@ -68,15 +68,15 @@ const UIStrings = {
|
|
|
68
68
|
/**
|
|
69
69
|
* @description A context menu item in the Data Grid of a data grid
|
|
70
70
|
*/
|
|
71
|
-
sortByString: 'Sort
|
|
71
|
+
sortByString: 'Sort by',
|
|
72
72
|
/**
|
|
73
73
|
* @description A context menu item in data grids to reset the columns to their default weight
|
|
74
74
|
*/
|
|
75
|
-
resetColumns: 'Reset
|
|
75
|
+
resetColumns: 'Reset columns',
|
|
76
76
|
/**
|
|
77
77
|
* @description A context menu item in data grids to list header options.
|
|
78
78
|
*/
|
|
79
|
-
headerOptions: 'Header
|
|
79
|
+
headerOptions: 'Header options',
|
|
80
80
|
/**
|
|
81
81
|
* @description Text to refresh the page
|
|
82
82
|
*/
|
|
@@ -1697,6 +1697,12 @@ export class Renderer implements UI.UIUtils.Renderer {
|
|
|
1697
1697
|
if (options?.expand) {
|
|
1698
1698
|
section.firstChild()?.expand();
|
|
1699
1699
|
}
|
|
1700
|
+
const dispatchDimensionChange = (): void => {
|
|
1701
|
+
section.element.dispatchEvent(new CustomEvent('dimensionschanged'));
|
|
1702
|
+
};
|
|
1703
|
+
section.addEventListener(UI.TreeOutline.Events.ElementAttached, dispatchDimensionChange);
|
|
1704
|
+
section.addEventListener(UI.TreeOutline.Events.ElementExpanded, dispatchDimensionChange);
|
|
1705
|
+
section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, dispatchDimensionChange);
|
|
1700
1706
|
return {
|
|
1701
1707
|
element: section.element,
|
|
1702
1708
|
forceSelect: section.forceSelect.bind(section),
|
|
@@ -1187,6 +1187,39 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
|
|
|
1187
1187
|
this.expandGroup(groupIndex, !this.rawTimelineData.groups[groupIndex].expanded /* setExpanded */);
|
|
1188
1188
|
}
|
|
1189
1189
|
|
|
1190
|
+
bulkExpandGroups(indexes: number[]): void {
|
|
1191
|
+
if (indexes.length === 0) {
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
if (!this.rawTimelineData) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
const groups = this.rawTimelineData.groups;
|
|
1199
|
+
if (!groups) {
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
let didUpdate = false;
|
|
1204
|
+
for (const index of indexes) {
|
|
1205
|
+
if (!this.isGroupCollapsible(index) || groups[index].expanded) {
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1208
|
+
didUpdate = true;
|
|
1209
|
+
groups[index].expanded = true;
|
|
1210
|
+
}
|
|
1211
|
+
if (didUpdate) {
|
|
1212
|
+
this.#updateAfterGroupExpansionChange();
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
#updateAfterGroupExpansionChange(): void {
|
|
1217
|
+
this.updateLevelPositions();
|
|
1218
|
+
this.updateHeight();
|
|
1219
|
+
this.draw();
|
|
1220
|
+
this.#notifyProviderOfConfigurationChange();
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1190
1223
|
private expandGroup(
|
|
1191
1224
|
groupIndex: number, setExpanded: boolean|undefined = true, propagatedExpand: boolean|undefined = false): void {
|
|
1192
1225
|
if (groupIndex < 0 || !this.isGroupCollapsible(groupIndex)) {
|
|
@@ -1203,12 +1236,10 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
|
|
|
1203
1236
|
}
|
|
1204
1237
|
|
|
1205
1238
|
const group = groups[groupIndex];
|
|
1206
|
-
group.expanded = setExpanded;
|
|
1207
|
-
|
|
1208
|
-
this.updateLevelPositions();
|
|
1209
1239
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1240
|
+
// If a group was expanded and is now being collapsed, and the selected
|
|
1241
|
+
// entry is within that group, then we have to deselect it.
|
|
1242
|
+
if (!setExpanded) {
|
|
1212
1243
|
const timelineData = this.timelineData();
|
|
1213
1244
|
if (timelineData) {
|
|
1214
1245
|
const level = timelineData.entryLevels[this.selectedEntryIndex];
|
|
@@ -1220,10 +1251,13 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
|
|
|
1220
1251
|
}
|
|
1221
1252
|
}
|
|
1222
1253
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1254
|
+
if (group.expanded === setExpanded) {
|
|
1255
|
+
// If the state isn't changing, early exit so we don't waste cycles
|
|
1256
|
+
// redrawing.
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1259
|
+
group.expanded = setExpanded;
|
|
1260
|
+
this.#updateAfterGroupExpansionChange();
|
|
1227
1261
|
|
|
1228
1262
|
this.scrollGroupIntoView(groupIndex);
|
|
1229
1263
|
// We only want to read expanded/collapsed state on user inputted expand/collapse
|