devtools-tracing 1.0.0 → 1.1.0
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/README.md +4 -0
- package/generate.ts +32 -26
- package/index.ts +2 -1
- package/lib/extension-api/ExtensionAPI.d.ts +357 -0
- package/lib/front_end/models/bindings/CSSWorkspaceBinding.ts +318 -0
- package/lib/front_end/models/bindings/CompilerScriptMapping.ts +536 -0
- package/lib/front_end/models/bindings/ContentProviderBasedProject.ts +187 -0
- package/lib/front_end/models/bindings/DebuggerLanguagePlugins.ts +1197 -0
- package/lib/front_end/models/bindings/DebuggerWorkspaceBinding.ts +733 -0
- package/lib/front_end/models/bindings/DefaultScriptMapping.ts +141 -0
- package/lib/front_end/models/bindings/FileUtils.ts +228 -0
- package/lib/front_end/models/bindings/LiveLocation.ts +81 -0
- package/lib/front_end/models/bindings/NetworkProject.ts +157 -0
- package/lib/front_end/models/bindings/PresentationConsoleMessageHelper.ts +312 -0
- package/lib/front_end/models/bindings/ResourceMapping.ts +539 -0
- package/lib/front_end/models/bindings/ResourceScriptMapping.ts +491 -0
- package/lib/front_end/models/bindings/ResourceUtils.ts +103 -0
- package/lib/front_end/models/bindings/SASSSourceMapping.ts +222 -0
- package/lib/front_end/models/bindings/StylesSourceMapping.ts +316 -0
- package/lib/front_end/models/bindings/TempFile.ts +67 -0
- package/lib/front_end/models/bindings/bindings.ts +39 -0
- package/lib/front_end/models/source_map_scopes/NamesResolver.ts +765 -0
- package/lib/front_end/models/source_map_scopes/ScopeChainModel.ts +84 -0
- package/lib/front_end/models/source_map_scopes/source_map_scopes.ts +11 -0
- package/lib/front_end/models/stack_trace/StackTrace.ts +53 -0
- package/lib/front_end/models/stack_trace/StackTraceImpl.ts +85 -0
- package/lib/front_end/models/stack_trace/StackTraceModel.ts +128 -0
- package/lib/front_end/models/stack_trace/Trie.ts +163 -0
- package/lib/front_end/models/stack_trace/stack_trace.ts +9 -0
- package/lib/front_end/models/stack_trace/stack_trace_impl.ts +13 -0
- package/lib/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +240 -0
- package/lib/front_end/models/trace_source_maps_resolver/trace_source_maps_resolver.ts +5 -0
- package/lib/front_end/models/workspace/FileManager.ts +97 -0
- package/lib/front_end/models/workspace/IgnoreListManager.ts +628 -0
- package/lib/front_end/models/workspace/SearchConfig.ts +149 -0
- package/lib/front_end/models/workspace/UISourceCode.ts +698 -0
- package/lib/front_end/models/workspace/WorkspaceImpl.ts +339 -0
- package/lib/front_end/models/workspace/workspace.ts +17 -0
- package/lib/front_end/panels/timeline/TimelineUIUtils.ts +1029 -0
- package/lib/front_end/panels/timeline/extensions/ExtensionUI.ts +49 -0
- package/lib/front_end/panels/timeline/extensions/extensions.ts +9 -0
- package/lib/front_end/third_party/codemirror.next/LICENSE +21 -0
- package/lib/front_end/third_party/codemirror.next/README.chromium +30 -0
- package/lib/front_end/third_party/codemirror.next/bundle-tsconfig.json +24 -0
- package/lib/front_end/third_party/codemirror.next/bundle.ts +135 -0
- package/lib/front_end/third_party/codemirror.next/chunk/angular.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/cpp.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/css.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/html.js +4 -0
- package/lib/front_end/third_party/codemirror.next/chunk/java.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/java.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/javascript.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/legacy.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/legacy.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/less.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/less.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/markdown.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/php.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/php.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/python.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/python.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/sass.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/svelte.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/vue.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/wast.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/chunk/xml.js +2 -0
- package/lib/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/codemirror.next.d.ts +8057 -0
- package/lib/front_end/third_party/codemirror.next/codemirror.next.js +2 -0
- package/lib/front_end/third_party/codemirror.next/codemirror.next.js.map +1 -0
- package/lib/front_end/third_party/codemirror.next/package.json +43 -0
- package/lib/front_end/third_party/codemirror.next/rebuild.sh +6 -0
- package/lib/front_end/third_party/codemirror.next/rollup.config.mjs +49 -0
- package/lib/front_end/third_party/source-map-scopes-codec/LICENSE +26 -0
- package/lib/front_end/third_party/source-map-scopes-codec/README.chromium +31 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +33 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/LICENSE +26 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/README.md +64 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +62 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +37 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +29 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +8 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +6 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/deno.json +21 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/package.json +14 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +196 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +262 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +235 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +359 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js +39 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +53 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +438 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +539 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +23 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +35 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +257 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +348 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js +8 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +20 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes-tsconfig.json +8 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes.d.ts +184 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js +9 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.ts +12 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +82 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +1 -0
- package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +99 -0
- package/lib/front_end/third_party/source-map-scopes-codec/source-map-scopes-codec.ts +5 -0
- package/lib/front_end/ui/legacy/theme_support/ThemeSupport.ts +222 -0
- package/lib/front_end/ui/legacy/theme_support/theme_support.ts +5 -0
- package/package.json +11 -5
- package/patches/chrome-devtools-frontend+1.0.1533544.patch +1549 -20
|
@@ -47,21 +47,951 @@ index 62c5773..ff07f89 100644
|
|
|
47
47
|
const unrecognizedEntity = {
|
|
48
48
|
name: rootDomain,
|
|
49
49
|
diff --git a/node_modules/chrome-devtools-frontend/front_end/panels/timeline/TimelineUIUtils.ts b/node_modules/chrome-devtools-frontend/front_end/panels/timeline/TimelineUIUtils.ts
|
|
50
|
-
index 4fe7b92..
|
|
50
|
+
index 4fe7b92..9e9664b 100644
|
|
51
51
|
--- a/node_modules/chrome-devtools-frontend/front_end/panels/timeline/TimelineUIUtils.ts
|
|
52
52
|
+++ b/node_modules/chrome-devtools-frontend/front_end/panels/timeline/TimelineUIUtils.ts
|
|
53
|
-
@@ -
|
|
54
|
-
import * as
|
|
55
|
-
|
|
56
|
-
import
|
|
53
|
+
@@ -38,32 +38,12 @@ import * as Common from '../../core/common/common.js';
|
|
54
|
+
import * as i18n from '../../core/i18n/i18n.js';
|
|
55
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
56
|
+
import * as Root from '../../core/root/root.js';
|
|
57
|
+
-import * as SDK from '../../core/sdk/sdk.js';
|
|
58
|
+
import type * as Protocol from '../../generated/protocol.js';
|
|
59
|
+
-import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
60
|
+
import * as Trace from '../../models/trace/trace.js';
|
|
61
|
+
import * as SourceMapsResolver from '../../models/trace_source_maps_resolver/trace_source_maps_resolver.js';
|
|
62
|
+
-import * as TraceBounds from '../../services/trace_bounds/trace_bounds.js';
|
|
63
|
+
-import * as Tracing from '../../services/tracing/tracing.js';
|
|
64
|
+
-import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
|
|
65
|
+
-// eslint-disable-next-line @devtools/es-modules-import
|
|
66
|
+
-import codeHighlighterStyles from '../../ui/components/code_highlighter/codeHighlighter.css.js';
|
|
57
67
|
-import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
-// eslint-disable-next-line @devtools/es-modules-import
|
|
69
|
+
-import imagePreviewStyles from '../../ui/legacy/components/utils/imagePreview.css.js';
|
|
70
|
+
-import * as LegacyComponents from '../../ui/legacy/components/utils/utils.js';
|
|
71
|
+
-import * as UI from '../../ui/legacy/legacy.js';
|
|
72
|
+
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
|
73
|
+
|
|
74
|
+
-import {getDurationString} from './AppenderUtils.js';
|
|
75
|
+
-import * as TimelineComponents from './components/components.js';
|
|
76
|
+
import * as Extensions from './extensions/extensions.js';
|
|
77
|
+
-import {ModificationsManager} from './ModificationsManager.js';
|
|
78
|
+
-import {targetForEvent} from './TargetForEvent.js';
|
|
79
|
+
-import * as ThirdPartyTreeView from './ThirdPartyTreeView.js';
|
|
80
|
+
-import {TimelinePanel} from './TimelinePanel.js';
|
|
81
|
+
-import {selectionFromEvent} from './TimelineSelection.js';
|
|
82
|
+
-import * as Utils from './utils/utils.js';
|
|
83
|
+
|
|
84
|
+
const UIStrings = {
|
|
85
|
+
/**
|
|
86
|
+
@@ -487,17 +467,6 @@ let eventDispatchDesciptors: EventDispatchTypeDescriptor[];
|
|
87
|
+
|
|
88
|
+
let colorGenerator: Common.Color.Generator;
|
|
89
|
+
|
|
90
|
+
-interface LinkifyLocationOptions {
|
|
91
|
+
- scriptId: Protocol.Runtime.ScriptId|null;
|
|
92
|
+
- url: string;
|
|
93
|
+
- lineNumber: number;
|
|
94
|
+
- target: SDK.Target.Target|null;
|
|
95
|
+
- linkifier: LegacyComponents.Linkifier.Linkifier;
|
|
96
|
+
- isFreshOrEnhanced?: boolean;
|
|
97
|
+
- columnNumber?: number;
|
|
98
|
+
- omitOrigin?: boolean;
|
|
99
|
+
-}
|
|
100
|
+
-
|
|
101
|
+
type TimeRangeCategoryStats = Record<string, number>;
|
|
64
102
|
|
|
103
|
+
const {SamplesIntegrator} = Trace.Helpers.SamplesIntegrator;
|
|
104
|
+
@@ -517,9 +486,6 @@ export class TimelineUIUtils {
|
|
105
|
+
static frameDisplayName(frame: Protocol.Runtime.CallFrame): string {
|
|
106
|
+
const maybeResolvedData = SourceMapsResolver.SourceMapsResolver.resolvedCodeLocationForCallFrame(frame);
|
|
107
|
+
const functionName = maybeResolvedData?.name || frame.functionName;
|
|
108
|
+
- if (!SamplesIntegrator.isNativeRuntimeFrame(frame)) {
|
|
109
|
+
- return UI.UIUtils.beautifyFunctionName(functionName);
|
|
110
|
+
- }
|
|
111
|
+
const nativeGroup = SamplesIntegrator.nativeGroup(functionName);
|
|
112
|
+
switch (nativeGroup) {
|
|
113
|
+
case SamplesIntegrator.NativeGroups.COMPILE:
|
|
114
|
+
@@ -654,894 +620,6 @@ export class TimelineUIUtils {
|
|
115
|
+
return frame.scriptId !== '0' && !(frame.url?.startsWith('native '));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
- static async buildDetailsNodeForTraceEvent(
|
|
119
|
+
- event: Trace.Types.Events.Event, target: SDK.Target.Target|null, linkifier: LegacyComponents.Linkifier.Linkifier,
|
|
120
|
+
- isFreshOrEnhanced = false, parsedTrace: Trace.TraceModel.ParsedTrace): Promise<Node|null> {
|
|
121
|
+
- let details: HTMLElement|HTMLSpanElement|(Element | null)|Text|null = null;
|
|
122
|
+
- let detailsText;
|
|
123
|
+
- // TODO(40287735): update this code with type-safe data checks.
|
|
124
|
+
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
- const unsafeEventArgs = event.args as Record<string, any>;
|
|
126
|
+
- // TODO(40287735): update this code with type-safe data checks.
|
|
127
|
+
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
+
- const unsafeEventData = event.args?.data as Record<string, any>;
|
|
129
|
+
-
|
|
130
|
+
- switch (event.name) {
|
|
131
|
+
- case Trace.Types.Events.Name.PAINT_IMAGE:
|
|
132
|
+
- case Trace.Types.Events.Name.DECODE_IMAGE:
|
|
133
|
+
- case Trace.Types.Events.Name.DECODE_LAZY_PIXEL_REF:
|
|
134
|
+
- case Trace.Types.Events.Name.XHR_READY_STATE_CHANGED:
|
|
135
|
+
- case Trace.Types.Events.Name.XHR_LOAD:
|
|
136
|
+
- case Trace.Types.Events.Name.RESOURCE_WILL_SEND_REQUEST:
|
|
137
|
+
- case Trace.Types.Events.Name.RESOURCE_SEND_REQUEST:
|
|
138
|
+
- case Trace.Types.Events.Name.RESOURCE_RECEIVE_DATA:
|
|
139
|
+
- case Trace.Types.Events.Name.RESOURCE_RECEIVE_RESPONSE:
|
|
140
|
+
- case Trace.Types.Events.Name.RESOURCE_FINISH: {
|
|
141
|
+
- const url = Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data);
|
|
142
|
+
- if (url) {
|
|
143
|
+
- const options = {
|
|
144
|
+
- tabStop: true,
|
|
145
|
+
- showColumnNumber: false,
|
|
146
|
+
- inlineFrameIndex: 0,
|
|
147
|
+
- };
|
|
148
|
+
- details = LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options);
|
|
149
|
+
- }
|
|
150
|
+
- break;
|
|
151
|
+
- }
|
|
152
|
+
-
|
|
153
|
+
- case Trace.Types.Events.Name.FUNCTION_CALL: {
|
|
154
|
+
- details = document.createElement('span');
|
|
155
|
+
-
|
|
156
|
+
- // FunctionCall events have an args.data that could be a CallFrame, if all the details are present, so we check for that.
|
|
157
|
+
- const callFrame = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(event)?.at(0);
|
|
158
|
+
- if (Trace.Types.Events.isFunctionCall(event) && callFrame) {
|
|
159
|
+
- UI.UIUtils.createTextChild(
|
|
160
|
+
- details,
|
|
161
|
+
- TimelineUIUtils.frameDisplayName(
|
|
162
|
+
- {...callFrame, scriptId: String(callFrame.scriptId) as Protocol.Runtime.ScriptId}));
|
|
163
|
+
- }
|
|
164
|
+
- const location = this.linkifyLocation({
|
|
165
|
+
- scriptId: unsafeEventData['scriptId'],
|
|
166
|
+
- url: unsafeEventData['url'],
|
|
167
|
+
- lineNumber: callFrame?.lineNumber || 0,
|
|
168
|
+
- columnNumber: callFrame?.columnNumber,
|
|
169
|
+
- target,
|
|
170
|
+
- isFreshOrEnhanced,
|
|
171
|
+
- linkifier,
|
|
172
|
+
- omitOrigin: true,
|
|
173
|
+
- });
|
|
174
|
+
- if (location) {
|
|
175
|
+
- UI.UIUtils.createTextChild(details, ' @ ');
|
|
176
|
+
- details.appendChild(location);
|
|
177
|
+
- }
|
|
178
|
+
- break;
|
|
179
|
+
- }
|
|
180
|
+
-
|
|
181
|
+
- case Trace.Types.Events.Name.COMPILE_MODULE:
|
|
182
|
+
- case Trace.Types.Events.Name.CACHE_MODULE: {
|
|
183
|
+
- details = this.linkifyLocation({
|
|
184
|
+
- scriptId: null,
|
|
185
|
+
- url: unsafeEventArgs['fileName'],
|
|
186
|
+
- lineNumber: 0,
|
|
187
|
+
- columnNumber: 0,
|
|
188
|
+
- target,
|
|
189
|
+
- isFreshOrEnhanced,
|
|
190
|
+
- linkifier,
|
|
191
|
+
- });
|
|
192
|
+
- break;
|
|
193
|
+
- }
|
|
194
|
+
-
|
|
195
|
+
- case Trace.Types.Events.Name.COMPILE_SCRIPT:
|
|
196
|
+
- case Trace.Types.Events.Name.CACHE_SCRIPT:
|
|
197
|
+
- case Trace.Types.Events.Name.EVALUATE_SCRIPT: {
|
|
198
|
+
- const url = unsafeEventData['url'];
|
|
199
|
+
- if (url) {
|
|
200
|
+
- const {lineNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
|
|
201
|
+
- details = this.linkifyLocation({
|
|
202
|
+
- scriptId: null,
|
|
203
|
+
- url,
|
|
204
|
+
- lineNumber: lineNumber || 0,
|
|
205
|
+
- columnNumber: 0,
|
|
206
|
+
- target,
|
|
207
|
+
- isFreshOrEnhanced,
|
|
208
|
+
- linkifier,
|
|
209
|
+
- omitOrigin: true,
|
|
210
|
+
- });
|
|
211
|
+
- }
|
|
212
|
+
- break;
|
|
213
|
+
- }
|
|
214
|
+
-
|
|
215
|
+
- case Trace.Types.Events.Name.BACKGROUND_DESERIALIZE:
|
|
216
|
+
- case Trace.Types.Events.Name.STREAMING_COMPILE_SCRIPT: {
|
|
217
|
+
- const url = unsafeEventData['url'];
|
|
218
|
+
- if (url) {
|
|
219
|
+
- details = this.linkifyLocation({
|
|
220
|
+
- scriptId: null,
|
|
221
|
+
- url,
|
|
222
|
+
- lineNumber: 0,
|
|
223
|
+
- columnNumber: 0,
|
|
224
|
+
- target,
|
|
225
|
+
- isFreshOrEnhanced,
|
|
226
|
+
- linkifier,
|
|
227
|
+
- omitOrigin: true,
|
|
228
|
+
- });
|
|
229
|
+
- }
|
|
230
|
+
- break;
|
|
231
|
+
- }
|
|
232
|
+
-
|
|
233
|
+
- default: {
|
|
234
|
+
- /**
|
|
235
|
+
- * Some events have a stack trace which is extracted by default at @see TimelineUIUtils.generateCauses
|
|
236
|
+
- * thus, we prevent extracting the stack trace again here.
|
|
237
|
+
- */
|
|
238
|
+
- if (Trace.Helpers.Trace.eventHasCategory(event, Trace.Types.Events.Categories.Console) ||
|
|
239
|
+
- Trace.Types.Events.isUserTiming(event) || Trace.Types.Extensions.isSyntheticExtensionEntry(event) ||
|
|
240
|
+
- Trace.Types.Events.isProfileCall(event)) {
|
|
241
|
+
- detailsText = null;
|
|
242
|
+
- } else {
|
|
243
|
+
- details = this.linkifyTopCallFrame(event, target, linkifier, isFreshOrEnhanced) ?? null;
|
|
244
|
+
- }
|
|
245
|
+
- break;
|
|
246
|
+
- }
|
|
247
|
+
- }
|
|
248
|
+
-
|
|
249
|
+
- if (!details && detailsText) {
|
|
250
|
+
- details = document.createTextNode(detailsText);
|
|
251
|
+
- }
|
|
252
|
+
- return details;
|
|
253
|
+
- }
|
|
254
|
+
-
|
|
255
|
+
- static linkifyLocation(linkifyOptions: LinkifyLocationOptions): Element|null {
|
|
256
|
+
- const {scriptId, url, lineNumber, columnNumber, isFreshOrEnhanced, linkifier, target, omitOrigin} = linkifyOptions;
|
|
257
|
+
- const options = {
|
|
258
|
+
- lineNumber,
|
|
259
|
+
- columnNumber,
|
|
260
|
+
- showColumnNumber: true,
|
|
261
|
+
- inlineFrameIndex: 0,
|
|
262
|
+
- className: 'timeline-details',
|
|
263
|
+
- tabStop: true,
|
|
264
|
+
- omitOrigin,
|
|
265
|
+
- };
|
|
266
|
+
- if (isFreshOrEnhanced) {
|
|
267
|
+
- return linkifier.linkifyScriptLocation(
|
|
268
|
+
- target, scriptId, url as Platform.DevToolsPath.UrlString, lineNumber, options);
|
|
269
|
+
- }
|
|
270
|
+
- return LegacyComponents.Linkifier.Linkifier.linkifyURL(url as Platform.DevToolsPath.UrlString, options);
|
|
271
|
+
- }
|
|
272
|
+
-
|
|
273
|
+
- static linkifyTopCallFrame(
|
|
274
|
+
- event: Trace.Types.Events.Event, target: SDK.Target.Target|null, linkifier: LegacyComponents.Linkifier.Linkifier,
|
|
275
|
+
- isFreshOrEnhanced = false): Element|null {
|
|
276
|
+
- let frame = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(event)?.[0];
|
|
277
|
+
- if (Trace.Types.Events.isProfileCall(event)) {
|
|
278
|
+
- frame = event.callFrame;
|
|
279
|
+
- }
|
|
280
|
+
- if (!frame) {
|
|
281
|
+
- return null;
|
|
282
|
+
- }
|
|
283
|
+
- const options = {
|
|
284
|
+
- className: 'timeline-details',
|
|
285
|
+
- tabStop: true,
|
|
286
|
+
- inlineFrameIndex: 0,
|
|
287
|
+
- showColumnNumber: true,
|
|
288
|
+
- columnNumber: frame.columnNumber,
|
|
289
|
+
- lineNumber: frame.lineNumber,
|
|
290
|
+
- };
|
|
291
|
+
- if (isFreshOrEnhanced) {
|
|
292
|
+
- return linkifier.maybeLinkifyConsoleCallFrame(target, frame, {showColumnNumber: true, inlineFrameIndex: 0});
|
|
293
|
+
- }
|
|
294
|
+
- return LegacyComponents.Linkifier.Linkifier.linkifyURL(frame.url as Platform.DevToolsPath.UrlString, options);
|
|
295
|
+
- }
|
|
296
|
+
-
|
|
297
|
+
- static buildDetailsNodeForMarkerEvents(event: Trace.Types.Events.MarkerEvent): HTMLElement {
|
|
298
|
+
- let link = 'https://web.dev/user-centric-performance-metrics/';
|
|
299
|
+
- let name = 'page performance metrics';
|
|
300
|
+
- switch (event.name) {
|
|
301
|
+
- case Trace.Types.Events.Name.MARK_LCP_CANDIDATE:
|
|
302
|
+
- link = 'https://web.dev/lcp/';
|
|
303
|
+
- name = 'largest contentful paint';
|
|
304
|
+
- break;
|
|
305
|
+
- case Trace.Types.Events.Name.MARK_FCP:
|
|
306
|
+
- link = 'https://web.dev/first-contentful-paint/';
|
|
307
|
+
- name = 'first contentful paint';
|
|
308
|
+
- break;
|
|
309
|
+
- default:
|
|
310
|
+
- break;
|
|
311
|
+
- }
|
|
312
|
+
-
|
|
313
|
+
- const html = UI.Fragment.html`<div>${
|
|
314
|
+
- UI.XLink.XLink.create(
|
|
315
|
+
- link, i18nString(UIStrings.learnMore), undefined, undefined, 'learn-more')} about ${name}.</div>`;
|
|
316
|
+
- return html as HTMLElement;
|
|
317
|
+
- }
|
|
318
|
+
-
|
|
319
|
+
- static buildConsumeCacheDetails(
|
|
320
|
+
- eventData: {
|
|
321
|
+
- consumedCacheSize?: number,
|
|
322
|
+
- cacheRejected?: boolean,
|
|
323
|
+
- cacheKind?: string,
|
|
324
|
+
- },
|
|
325
|
+
- contentHelper: TimelineDetailsContentHelper): void {
|
|
326
|
+
- if (typeof eventData.consumedCacheSize === 'number') {
|
|
327
|
+
- contentHelper.appendTextRow(
|
|
328
|
+
- i18nString(UIStrings.compilationCacheStatus), i18nString(UIStrings.scriptLoadedFromCache));
|
|
329
|
+
- contentHelper.appendTextRow(
|
|
330
|
+
- i18nString(UIStrings.compilationCacheSize), i18n.ByteUtilities.bytesToString(eventData.consumedCacheSize));
|
|
331
|
+
- const cacheKind = eventData.cacheKind;
|
|
332
|
+
- if (cacheKind) {
|
|
333
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.compilationCacheKind), cacheKind);
|
|
334
|
+
- }
|
|
335
|
+
- } else if ('cacheRejected' in eventData && eventData['cacheRejected']) {
|
|
336
|
+
- // Version mismatch or similar.
|
|
337
|
+
- contentHelper.appendTextRow(
|
|
338
|
+
- i18nString(UIStrings.compilationCacheStatus), i18nString(UIStrings.failedToLoadScriptFromCache));
|
|
339
|
+
- } else {
|
|
340
|
+
- contentHelper.appendTextRow(
|
|
341
|
+
- i18nString(UIStrings.compilationCacheStatus), i18nString(UIStrings.scriptNotEligibleToBeLoadedFromCache));
|
|
342
|
+
- }
|
|
343
|
+
- }
|
|
344
|
+
-
|
|
345
|
+
- static maybeCreateLinkElement(url: string): Element|null {
|
|
346
|
+
- const parsedURL = new Common.ParsedURL.ParsedURL(url);
|
|
347
|
+
- if (!parsedURL.scheme) {
|
|
348
|
+
- return null;
|
|
349
|
+
- }
|
|
350
|
+
-
|
|
351
|
+
- const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(url);
|
|
352
|
+
- if (!splitResult) {
|
|
353
|
+
- return null;
|
|
354
|
+
- }
|
|
355
|
+
- const {url: rawURL, lineNumber, columnNumber} = splitResult;
|
|
356
|
+
-
|
|
357
|
+
- const options = {
|
|
358
|
+
- lineNumber,
|
|
359
|
+
- columnNumber,
|
|
360
|
+
- showColumnNumber: true,
|
|
361
|
+
- omitOrigin: true,
|
|
362
|
+
- };
|
|
363
|
+
-
|
|
364
|
+
- return LegacyComponents.Linkifier.Linkifier.linkifyURL(rawURL as Platform.DevToolsPath.UrlString, options);
|
|
365
|
+
- }
|
|
366
|
+
-
|
|
367
|
+
- /**
|
|
368
|
+
- * Takes an input string and parses it to look for links. It does this by
|
|
369
|
+
- * looking for URLs in the input string. The returned fragment will contain
|
|
370
|
+
- * the same string but with any links wrapped in clickable links. The text
|
|
371
|
+
- * of the link is the URL, so the visible string to the user is unchanged.
|
|
372
|
+
- */
|
|
373
|
+
- static parseStringForLinks(rawString: string): DocumentFragment {
|
|
374
|
+
- const results = TextUtils.TextUtils.Utils.splitStringByRegexes(rawString, [URL_REGEX]);
|
|
375
|
+
- const nodes = results.map(result => {
|
|
376
|
+
- if (result.regexIndex === -1) {
|
|
377
|
+
- return result.value;
|
|
378
|
+
- }
|
|
379
|
+
- return TimelineUIUtils.maybeCreateLinkElement(result.value) ?? result.value;
|
|
380
|
+
- });
|
|
381
|
+
-
|
|
382
|
+
- const frag = document.createDocumentFragment();
|
|
383
|
+
- frag.append(...nodes);
|
|
384
|
+
- return frag;
|
|
385
|
+
- }
|
|
386
|
+
-
|
|
387
|
+
- static async buildTraceEventDetails(
|
|
388
|
+
- parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
389
|
+
- event: Trace.Types.Events.Event,
|
|
390
|
+
- linkifier: LegacyComponents.Linkifier.Linkifier,
|
|
391
|
+
- canShowPieChart: boolean,
|
|
392
|
+
- entityMapper: Trace.EntityMapper.EntityMapper|null,
|
|
393
|
+
- ): Promise<DocumentFragment> {
|
|
394
|
+
- const maybeTarget = targetForEvent(parsedTrace, event);
|
|
395
|
+
- const {duration} = Trace.Helpers.Timing.eventTimingsMicroSeconds(event);
|
|
396
|
+
- const selfTime = getEventSelfTime(event, parsedTrace);
|
|
397
|
+
- const relatedNodesMap = await Utils.EntryNodes.relatedDOMNodesForEvent(
|
|
398
|
+
- parsedTrace,
|
|
399
|
+
- event,
|
|
400
|
+
- );
|
|
401
|
+
- let entityAppended = false;
|
|
402
|
+
-
|
|
403
|
+
- if (maybeTarget) {
|
|
404
|
+
- // @ts-expect-error TODO(crbug.com/1011811): Remove symbol usage.
|
|
405
|
+
- if (typeof event[previewElementSymbol] === 'undefined') {
|
|
406
|
+
- let previewElement: (Element|null)|null = null;
|
|
407
|
+
- const url = Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data);
|
|
408
|
+
- if (url) {
|
|
409
|
+
- previewElement = await LegacyComponents.ImagePreview.ImagePreview.build(url, false, {
|
|
410
|
+
- imageAltText: LegacyComponents.ImagePreview.ImagePreview.defaultAltTextForImageURL(url),
|
|
411
|
+
- precomputedFeatures: undefined,
|
|
412
|
+
- align: LegacyComponents.ImagePreview.Align.START,
|
|
413
|
+
- });
|
|
414
|
+
- } else if (Trace.Types.Events.isPaint(event)) {
|
|
415
|
+
- previewElement = await TimelineUIUtils.buildPicturePreviewContent(parsedTrace, event, maybeTarget);
|
|
416
|
+
- }
|
|
417
|
+
- // @ts-expect-error TODO(crbug.com/1011811): Remove symbol usage.
|
|
418
|
+
- event[previewElementSymbol] = previewElement;
|
|
419
|
+
- }
|
|
420
|
+
- }
|
|
421
|
+
-
|
|
422
|
+
- // This message may vary per event.name;
|
|
423
|
+
- let relatedNodeLabel;
|
|
424
|
+
-
|
|
425
|
+
- const contentHelper = new TimelineDetailsContentHelper(targetForEvent(parsedTrace, event), linkifier);
|
|
426
|
+
-
|
|
427
|
+
- const defaultColorForEvent = this.eventColor(event);
|
|
428
|
+
- const isMarker = parsedTrace && isMarkerEvent(parsedTrace, event);
|
|
429
|
+
- const color = isMarker ? TimelineUIUtils.markerStyleForEvent(event).color : defaultColorForEvent;
|
|
430
|
+
-
|
|
431
|
+
- contentHelper.addSection(TimelineUIUtils.eventTitle(event), color, event);
|
|
432
|
+
-
|
|
433
|
+
- // TODO: as part of the removal of the old engine, produce a typesafe way
|
|
434
|
+
- // to look up args and data for events.
|
|
435
|
+
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
436
|
+
- const unsafeEventArgs = event.args as Record<string, any>;
|
|
437
|
+
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
438
|
+
- const unsafeEventData = event.args?.data as Record<string, any>;
|
|
439
|
+
- const initiator = parsedTrace.data.Initiators.eventToInitiator.get(event) ?? null;
|
|
440
|
+
- const initiatorFor = parsedTrace.data.Initiators.initiatorToEvents.get(event) ?? null;
|
|
441
|
+
-
|
|
442
|
+
- let url: Platform.DevToolsPath.UrlString|null = null;
|
|
443
|
+
-
|
|
444
|
+
- if (parsedTrace) {
|
|
445
|
+
- const warnings = TimelineComponents.DetailsView.buildWarningElementsForEvent(event, parsedTrace);
|
|
446
|
+
- for (const warning of warnings) {
|
|
447
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.warning), warning, true);
|
|
448
|
+
- }
|
|
449
|
+
- }
|
|
450
|
+
-
|
|
451
|
+
- // Add timestamp to user timings, including custom extensibility markers
|
|
452
|
+
- if (Trace.Helpers.Trace.eventHasCategory(event, Trace.Types.Events.Categories.UserTiming) ||
|
|
453
|
+
- Trace.Types.Extensions.isSyntheticExtensionEntry(event)) {
|
|
454
|
+
- const adjustedEventTimeStamp = timeStampForEventAdjustedForClosestNavigationIfPossible(
|
|
455
|
+
- event,
|
|
456
|
+
- parsedTrace,
|
|
457
|
+
- );
|
|
458
|
+
- contentHelper.appendTextRow(
|
|
459
|
+
- i18nString(UIStrings.timestamp), i18n.TimeUtilities.preciseMillisToString(adjustedEventTimeStamp, 1));
|
|
460
|
+
- }
|
|
461
|
+
-
|
|
462
|
+
- // Only show total time and self time for events with non-zero durations.
|
|
463
|
+
- if (duration !== 0 && !Number.isNaN(duration)) {
|
|
464
|
+
- const timeStr = getDurationString(duration, selfTime);
|
|
465
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.duration), timeStr);
|
|
466
|
+
- }
|
|
467
|
+
-
|
|
468
|
+
- if (Trace.Types.Events.isPerformanceMark(event) && event.args.data?.detail) {
|
|
469
|
+
- const detailContainer = TimelineUIUtils.renderObjectJson(JSON.parse(event.args.data?.detail));
|
|
470
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.details), detailContainer);
|
|
471
|
+
- }
|
|
472
|
+
- if (Trace.Types.Events.isSyntheticUserTiming(event) && event.args?.data?.beginEvent.args.detail) {
|
|
473
|
+
- const detailContainer = TimelineUIUtils.renderObjectJson(JSON.parse(event.args?.data?.beginEvent.args.detail));
|
|
474
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.details), detailContainer);
|
|
475
|
+
- }
|
|
476
|
+
-
|
|
477
|
+
- if (parsedTrace.data.Meta.traceIsGeneric) {
|
|
478
|
+
- TimelineUIUtils.renderEventJson(event, contentHelper);
|
|
479
|
+
- return contentHelper.fragment;
|
|
480
|
+
- }
|
|
481
|
+
-
|
|
482
|
+
- if (Trace.Types.Events.isV8Compile(event)) {
|
|
483
|
+
- url = event.args.data?.url as Platform.DevToolsPath.UrlString;
|
|
484
|
+
- if (url) {
|
|
485
|
+
- const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
|
|
486
|
+
- contentHelper.appendLocationRow(
|
|
487
|
+
- i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
|
|
488
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
|
|
489
|
+
- if (originWithEntity) {
|
|
490
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
491
|
+
- }
|
|
492
|
+
- entityAppended = true;
|
|
493
|
+
- }
|
|
494
|
+
- const isEager = Boolean(event.args.data?.eager);
|
|
495
|
+
- if (isEager) {
|
|
496
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.eagerCompile), true);
|
|
497
|
+
- }
|
|
498
|
+
-
|
|
499
|
+
- const isStreamed = Boolean(event.args.data?.streamed);
|
|
500
|
+
- contentHelper.appendTextRow(
|
|
501
|
+
- i18nString(UIStrings.streamed),
|
|
502
|
+
- isStreamed + (isStreamed ? '' : `: ${event.args.data?.notStreamedReason || ''}`));
|
|
503
|
+
- if (event.args.data) {
|
|
504
|
+
- TimelineUIUtils.buildConsumeCacheDetails(event.args.data, contentHelper);
|
|
505
|
+
- }
|
|
506
|
+
- }
|
|
507
|
+
-
|
|
508
|
+
- if (Trace.Types.Extensions.isSyntheticExtensionEntry(event)) {
|
|
509
|
+
- // isSyntheticExtensionEntries can be any of: perf.measure, perf.mark or console.timeStamp.
|
|
510
|
+
- const userDetail = structuredClone(event.userDetail) as Record<string, Trace.Types.Extensions.JsonValue>;
|
|
511
|
+
- if (userDetail && Object.keys(userDetail).length) {
|
|
512
|
+
- // E.g. console.timeStamp(name, start, end, track, trackGroup, color,
|
|
513
|
+
- // {url: 'foo-extension://node/1', description: 'Node'});
|
|
514
|
+
- const hasExclusiveLink = typeof userDetail === 'object' && typeof userDetail.url === 'string' &&
|
|
515
|
+
- typeof userDetail.description === 'string';
|
|
516
|
+
- if (hasExclusiveLink && Boolean(Root.Runtime.hostConfig.devToolsDeepLinksViaExtensibilityApi?.enabled)) {
|
|
517
|
+
- const linkElement = this.maybeCreateLinkElement(String(userDetail.url));
|
|
518
|
+
- if (linkElement) {
|
|
519
|
+
- contentHelper.appendElementRow(String(userDetail.description), linkElement);
|
|
520
|
+
- // Now remove so we don't render them in renderObjectJson.
|
|
521
|
+
- delete userDetail.url;
|
|
522
|
+
- delete userDetail.description;
|
|
523
|
+
- }
|
|
524
|
+
- }
|
|
525
|
+
- if (Object.keys(userDetail).length) {
|
|
526
|
+
- // E.g., performance.measure(name, {detail: {important: 42, devtools: {}}})
|
|
527
|
+
- const detailContainer = TimelineUIUtils.renderObjectJson(userDetail);
|
|
528
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.details), detailContainer);
|
|
529
|
+
- }
|
|
530
|
+
- }
|
|
531
|
+
-
|
|
532
|
+
- // E.g. performance.measure(name, {detail: {devtools: {properties: ['Key', 'Value']}}})
|
|
533
|
+
- if (event.devtoolsObj.properties) {
|
|
534
|
+
- for (const [key, value] of event.devtoolsObj.properties || []) {
|
|
535
|
+
- const renderedValue = typeof value === 'string' ? TimelineUIUtils.parseStringForLinks(value) :
|
|
536
|
+
- TimelineUIUtils.renderObjectJson(value);
|
|
537
|
+
- contentHelper.appendElementRow(key, renderedValue);
|
|
538
|
+
- }
|
|
539
|
+
- }
|
|
540
|
+
- }
|
|
541
|
+
-
|
|
542
|
+
- const isFreshOrEnhanced =
|
|
543
|
+
- Boolean(parsedTrace && Tracing.FreshRecording.Tracker.instance().recordingIsFreshOrEnhanced(parsedTrace));
|
|
544
|
+
-
|
|
545
|
+
- switch (event.name) {
|
|
546
|
+
- case Trace.Types.Events.Name.GC:
|
|
547
|
+
- case Trace.Types.Events.Name.MAJOR_GC:
|
|
548
|
+
- case Trace.Types.Events.Name.MINOR_GC: {
|
|
549
|
+
- const delta = unsafeEventArgs['usedHeapSizeBefore'] - unsafeEventArgs['usedHeapSizeAfter'];
|
|
550
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.collected), i18n.ByteUtilities.bytesToString(delta));
|
|
551
|
+
- break;
|
|
552
|
+
- }
|
|
553
|
+
-
|
|
554
|
+
- case Trace.Types.Events.Name.PROFILE_CALL: {
|
|
555
|
+
- const profileCall = event as Trace.Types.Events.SyntheticProfileCall;
|
|
556
|
+
- const resolvedURL = SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(parsedTrace, profileCall);
|
|
557
|
+
- if (!resolvedURL) {
|
|
558
|
+
- break;
|
|
559
|
+
- }
|
|
560
|
+
- const callFrame = profileCall.callFrame;
|
|
561
|
+
- // Render the URL with its location content.
|
|
562
|
+
- contentHelper.appendLocationRow(
|
|
563
|
+
- i18nString(UIStrings.source), resolvedURL, callFrame.lineNumber || 0, callFrame.columnNumber, undefined,
|
|
564
|
+
- true);
|
|
565
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, profileCall);
|
|
566
|
+
- if (originWithEntity) {
|
|
567
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
568
|
+
- }
|
|
569
|
+
- entityAppended = true;
|
|
570
|
+
- break;
|
|
571
|
+
- }
|
|
572
|
+
- case Trace.Types.Events.Name.FUNCTION_CALL: {
|
|
573
|
+
- const detailsNode = await TimelineUIUtils.buildDetailsNodeForTraceEvent(
|
|
574
|
+
- event, targetForEvent(parsedTrace, event), linkifier, isFreshOrEnhanced, parsedTrace);
|
|
575
|
+
- if (detailsNode) {
|
|
576
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.function), detailsNode);
|
|
577
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
|
|
578
|
+
- if (originWithEntity) {
|
|
579
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
580
|
+
- }
|
|
581
|
+
- entityAppended = true;
|
|
582
|
+
- }
|
|
583
|
+
- break;
|
|
584
|
+
- }
|
|
585
|
+
-
|
|
586
|
+
- case Trace.Types.Events.Name.TIMER_FIRE:
|
|
587
|
+
- case Trace.Types.Events.Name.TIMER_INSTALL:
|
|
588
|
+
- case Trace.Types.Events.Name.TIMER_REMOVE: {
|
|
589
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.timerId), unsafeEventData.timerId);
|
|
590
|
+
-
|
|
591
|
+
- if (event.name === Trace.Types.Events.Name.TIMER_INSTALL) {
|
|
592
|
+
- contentHelper.appendTextRow(
|
|
593
|
+
- i18nString(UIStrings.timeout), i18n.TimeUtilities.millisToString(unsafeEventData['timeout']));
|
|
594
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.repeats), !unsafeEventData['singleShot']);
|
|
595
|
+
- }
|
|
596
|
+
- break;
|
|
597
|
+
- }
|
|
598
|
+
-
|
|
599
|
+
- case Trace.Types.Events.Name.SCHEDULE_POST_TASK_CALLBACK:
|
|
600
|
+
- case Trace.Types.Events.Name.RUN_POST_TASK_CALLBACK: {
|
|
601
|
+
- contentHelper.appendTextRow(
|
|
602
|
+
- i18nString(UIStrings.delay), i18n.TimeUtilities.millisToString(unsafeEventData['delay']));
|
|
603
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.priority), unsafeEventData['priority']);
|
|
604
|
+
- break;
|
|
605
|
+
- }
|
|
606
|
+
-
|
|
607
|
+
- case Trace.Types.Events.Name.FIRE_ANIMATION_FRAME: {
|
|
608
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.callbackId), unsafeEventData['id']);
|
|
609
|
+
- break;
|
|
610
|
+
- }
|
|
611
|
+
-
|
|
612
|
+
- case Trace.Types.Events.Name.COMPILE_MODULE: {
|
|
613
|
+
- contentHelper.appendLocationRow(i18nString(UIStrings.module), unsafeEventArgs['fileName'], 0);
|
|
614
|
+
- break;
|
|
615
|
+
- }
|
|
616
|
+
- case Trace.Types.Events.Name.COMPILE_SCRIPT: {
|
|
617
|
+
- // This case is handled above
|
|
618
|
+
- break;
|
|
619
|
+
- }
|
|
620
|
+
-
|
|
621
|
+
- case Trace.Types.Events.Name.CACHE_MODULE: {
|
|
622
|
+
- url = unsafeEventData && unsafeEventData['url'] as Platform.DevToolsPath.UrlString;
|
|
623
|
+
- contentHelper.appendTextRow(
|
|
624
|
+
- i18nString(UIStrings.compilationCacheSize),
|
|
625
|
+
- i18n.ByteUtilities.bytesToString(unsafeEventData['producedCacheSize']));
|
|
626
|
+
- break;
|
|
627
|
+
- }
|
|
628
|
+
-
|
|
629
|
+
- case Trace.Types.Events.Name.CACHE_SCRIPT: {
|
|
630
|
+
- url = unsafeEventData && unsafeEventData['url'] as Platform.DevToolsPath.UrlString;
|
|
631
|
+
- if (url) {
|
|
632
|
+
- const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
|
|
633
|
+
- contentHelper.appendLocationRow(
|
|
634
|
+
- i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
|
|
635
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
|
|
636
|
+
- if (originWithEntity) {
|
|
637
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
638
|
+
- }
|
|
639
|
+
- entityAppended = true;
|
|
640
|
+
- }
|
|
641
|
+
- contentHelper.appendTextRow(
|
|
642
|
+
- i18nString(UIStrings.compilationCacheSize),
|
|
643
|
+
- i18n.ByteUtilities.bytesToString(unsafeEventData['producedCacheSize']));
|
|
644
|
+
- break;
|
|
645
|
+
- }
|
|
646
|
+
-
|
|
647
|
+
- case Trace.Types.Events.Name.EVALUATE_SCRIPT: {
|
|
648
|
+
- url = unsafeEventData && unsafeEventData['url'] as Platform.DevToolsPath.UrlString;
|
|
649
|
+
- if (url) {
|
|
650
|
+
- const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
|
|
651
|
+
- contentHelper.appendLocationRow(
|
|
652
|
+
- i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
|
|
653
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
|
|
654
|
+
- if (originWithEntity) {
|
|
655
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
656
|
+
- }
|
|
657
|
+
- entityAppended = true;
|
|
658
|
+
- }
|
|
659
|
+
- break;
|
|
660
|
+
- }
|
|
661
|
+
-
|
|
662
|
+
- case Trace.Types.Events.Name.WASM_STREAM_FROM_RESPONSE_CALLBACK:
|
|
663
|
+
- case Trace.Types.Events.Name.WASM_COMPILED_MODULE:
|
|
664
|
+
- case Trace.Types.Events.Name.WASM_CACHED_MODULE:
|
|
665
|
+
- case Trace.Types.Events.Name.WASM_MODULE_CACHE_HIT:
|
|
666
|
+
- case Trace.Types.Events.Name.WASM_MODULE_CACHE_INVALID: {
|
|
667
|
+
- if (unsafeEventData) {
|
|
668
|
+
- url = unsafeEventArgs['url'] as Platform.DevToolsPath.UrlString;
|
|
669
|
+
- if (url) {
|
|
670
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.url), url);
|
|
671
|
+
- }
|
|
672
|
+
- const producedCachedSize = unsafeEventArgs['producedCachedSize'];
|
|
673
|
+
- if (producedCachedSize) {
|
|
674
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.producedCacheSize), producedCachedSize);
|
|
675
|
+
- }
|
|
676
|
+
- const consumedCachedSize = unsafeEventArgs['consumedCachedSize'];
|
|
677
|
+
- if (consumedCachedSize) {
|
|
678
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.consumedCacheSize), consumedCachedSize);
|
|
679
|
+
- }
|
|
680
|
+
- }
|
|
681
|
+
- break;
|
|
682
|
+
- }
|
|
683
|
+
-
|
|
684
|
+
- case Trace.Types.Events.Name.PAINT:
|
|
685
|
+
- case Trace.Types.Events.Name.PAINT_SETUP:
|
|
686
|
+
- case Trace.Types.Events.Name.RASTERIZE:
|
|
687
|
+
- case Trace.Types.Events.Name.SCROLL_LAYER: {
|
|
688
|
+
- relatedNodeLabel = i18nString(UIStrings.layerRoot);
|
|
689
|
+
- break;
|
|
690
|
+
- }
|
|
691
|
+
-
|
|
692
|
+
- case Trace.Types.Events.Name.PAINT_IMAGE:
|
|
693
|
+
- case Trace.Types.Events.Name.DECODE_LAZY_PIXEL_REF:
|
|
694
|
+
- case Trace.Types.Events.Name.DECODE_IMAGE:
|
|
695
|
+
- case Trace.Types.Events.Name.DRAW_LAZY_PIXEL_REF: {
|
|
696
|
+
- relatedNodeLabel = i18nString(UIStrings.ownerElement);
|
|
697
|
+
- url = Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data);
|
|
698
|
+
- if (url) {
|
|
699
|
+
- const options = {
|
|
700
|
+
- tabStop: true,
|
|
701
|
+
- showColumnNumber: false,
|
|
702
|
+
- inlineFrameIndex: 0,
|
|
703
|
+
- };
|
|
704
|
+
- contentHelper.appendElementRow(
|
|
705
|
+
- i18nString(UIStrings.imageUrl), LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options));
|
|
706
|
+
- }
|
|
707
|
+
- break;
|
|
708
|
+
- }
|
|
709
|
+
-
|
|
710
|
+
- case Trace.Types.Events.Name.PARSE_AUTHOR_STYLE_SHEET: {
|
|
711
|
+
- url = unsafeEventData['styleSheetUrl'] as Platform.DevToolsPath.UrlString;
|
|
712
|
+
- if (url) {
|
|
713
|
+
- const options = {
|
|
714
|
+
- tabStop: true,
|
|
715
|
+
- showColumnNumber: false,
|
|
716
|
+
- inlineFrameIndex: 0,
|
|
717
|
+
- };
|
|
718
|
+
- contentHelper.appendElementRow(
|
|
719
|
+
- i18nString(UIStrings.stylesheetUrl), LegacyComponents.Linkifier.Linkifier.linkifyURL(url, options));
|
|
720
|
+
- }
|
|
721
|
+
- break;
|
|
722
|
+
- }
|
|
723
|
+
-
|
|
724
|
+
- case Trace.Types.Events.Name.RECALC_STYLE: {
|
|
725
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.elementsAffected), unsafeEventArgs['elementCount']);
|
|
726
|
+
-
|
|
727
|
+
- const selectorStatsSetting =
|
|
728
|
+
- Common.Settings.Settings.instance().createSetting('timeline-capture-selector-stats', false);
|
|
729
|
+
- if (!selectorStatsSetting.get()) {
|
|
730
|
+
- const note = document.createElement('span');
|
|
731
|
+
- note.textContent = i18nString(UIStrings.sSelectorStatsInfo, {PH1: selectorStatsSetting.title()});
|
|
732
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.selectorStatsTitle), note);
|
|
733
|
+
- }
|
|
734
|
+
-
|
|
735
|
+
- break;
|
|
736
|
+
- }
|
|
737
|
+
-
|
|
738
|
+
- case Trace.Types.Events.Name.LAYOUT: {
|
|
739
|
+
- const beginData = unsafeEventArgs['beginData'];
|
|
740
|
+
- contentHelper.appendTextRow(
|
|
741
|
+
- i18nString(UIStrings.nodesThatNeedLayout),
|
|
742
|
+
- i18nString(UIStrings.sOfS, {PH1: beginData['dirtyObjects'], PH2: beginData['totalObjects']}));
|
|
743
|
+
- relatedNodeLabel = i18nString(UIStrings.layoutRoot);
|
|
744
|
+
- break;
|
|
745
|
+
- }
|
|
746
|
+
-
|
|
747
|
+
- case Trace.Types.Events.Name.CONSOLE_TIME: {
|
|
748
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.message), event.name);
|
|
749
|
+
- break;
|
|
750
|
+
- }
|
|
751
|
+
-
|
|
752
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_CREATE:
|
|
753
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_SEND_HANDSHAKE_REQUEST:
|
|
754
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_RECEIVE_HANDSHAKE_REQUEST:
|
|
755
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_SEND:
|
|
756
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_RECEIVE:
|
|
757
|
+
- case Trace.Types.Events.Name.WEB_SOCKET_DESTROY: {
|
|
758
|
+
- if (Trace.Types.Events.isWebSocketTraceEvent(event)) {
|
|
759
|
+
- const rows = TimelineComponents.DetailsView.buildRowsForWebSocketEvent(event, parsedTrace);
|
|
760
|
+
- for (const {key, value} of rows) {
|
|
761
|
+
- contentHelper.appendTextRow(key, value);
|
|
762
|
+
- }
|
|
763
|
+
- }
|
|
764
|
+
- break;
|
|
765
|
+
- }
|
|
766
|
+
-
|
|
767
|
+
- case Trace.Types.Events.Name.EMBEDDER_CALLBACK: {
|
|
768
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.callbackFunction), unsafeEventData['callbackName']);
|
|
769
|
+
- break;
|
|
770
|
+
- }
|
|
771
|
+
-
|
|
772
|
+
- case Trace.Types.Events.Name.ANIMATION: {
|
|
773
|
+
- if (!Trace.Types.Events.isSyntheticAnimation(event)) {
|
|
774
|
+
- break;
|
|
775
|
+
- }
|
|
776
|
+
- const {displayName, nodeName} = event.args.data.beginEvent.args.data;
|
|
777
|
+
- displayName && contentHelper.appendTextRow(i18nString(UIStrings.animating), displayName);
|
|
778
|
+
- // If relatedNodes is empty (maybe saved trace), then print the text description of the DOM node.
|
|
779
|
+
- if (!relatedNodesMap?.size && nodeName) {
|
|
780
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.relatedNode), nodeName);
|
|
781
|
+
- }
|
|
782
|
+
-
|
|
783
|
+
- const CLSInsight = Trace.Insights.Models.CLSCulprits;
|
|
784
|
+
- const failures = CLSInsight.getNonCompositedFailure(event);
|
|
785
|
+
- if (!failures.length) {
|
|
786
|
+
- break;
|
|
787
|
+
- }
|
|
788
|
+
-
|
|
789
|
+
- const failureReasons = new Set(failures.map(f => f.failureReasons).flat().filter(Boolean));
|
|
790
|
+
- const unsupportedProperties =
|
|
791
|
+
- new Set(failures.map(f => f.unsupportedProperties).flat().filter(Boolean)) as Set<string>;
|
|
792
|
+
-
|
|
793
|
+
- // The failureReasons can be empty when Blink added a new failure reason that is
|
|
794
|
+
- // not supported by DevTools yet
|
|
795
|
+
- if (failureReasons.size === 0) {
|
|
796
|
+
- contentHelper.appendElementRow(
|
|
797
|
+
- i18nString(UIStrings.compositingFailed), i18nString(UIStrings.compositingFailedUnknownReason), true);
|
|
798
|
+
- } else {
|
|
799
|
+
- for (const reason of failureReasons) {
|
|
800
|
+
- let str;
|
|
801
|
+
- switch (reason) {
|
|
802
|
+
- case CLSInsight.AnimationFailureReasons.ACCELERATED_ANIMATIONS_DISABLED:
|
|
803
|
+
- str = i18nString(UIStrings.compositingFailedAcceleratedAnimationsDisabled);
|
|
804
|
+
- break;
|
|
805
|
+
- case CLSInsight.AnimationFailureReasons.EFFECT_SUPPRESSED_BY_DEVTOOLS:
|
|
806
|
+
- str = i18nString(UIStrings.compositingFailedEffectSuppressedByDevtools);
|
|
807
|
+
- break;
|
|
808
|
+
- case CLSInsight.AnimationFailureReasons.INVALID_ANIMATION_OR_EFFECT:
|
|
809
|
+
- str = i18nString(UIStrings.compositingFailedInvalidAnimationOrEffect);
|
|
810
|
+
- break;
|
|
811
|
+
- case CLSInsight.AnimationFailureReasons.EFFECT_HAS_UNSUPPORTED_TIMING_PARAMS:
|
|
812
|
+
- str = i18nString(UIStrings.compositingFailedEffectHasUnsupportedTimingParams);
|
|
813
|
+
- break;
|
|
814
|
+
- case CLSInsight.AnimationFailureReasons.EFFECT_HAS_NON_REPLACE_COMPOSITE_MODE:
|
|
815
|
+
- str = i18nString(UIStrings.compositingFailedEffectHasNonReplaceCompositeMode);
|
|
816
|
+
- break;
|
|
817
|
+
- case CLSInsight.AnimationFailureReasons.TARGET_HAS_INVALID_COMPOSITING_STATE:
|
|
818
|
+
- str = i18nString(UIStrings.compositingFailedTargetHasInvalidCompositingState);
|
|
819
|
+
- break;
|
|
820
|
+
- case CLSInsight.AnimationFailureReasons.TARGET_HAS_INCOMPATIBLE_ANIMATIONS:
|
|
821
|
+
- str = i18nString(UIStrings.compositingFailedTargetHasIncompatibleAnimations);
|
|
822
|
+
- break;
|
|
823
|
+
- case CLSInsight.AnimationFailureReasons.TARGET_HAS_CSS_OFFSET:
|
|
824
|
+
- str = i18nString(UIStrings.compositingFailedTargetHasCSSOffset);
|
|
825
|
+
- break;
|
|
826
|
+
- case CLSInsight.AnimationFailureReasons.ANIMATION_AFFECTS_NON_CSS_PROPERTIES:
|
|
827
|
+
- str = i18nString(UIStrings.compositingFailedAnimationAffectsNonCSSProperties);
|
|
828
|
+
- break;
|
|
829
|
+
- case CLSInsight.AnimationFailureReasons.TRANSFORM_RELATED_PROPERTY_CANNOT_BE_ACCELERATED_ON_TARGET:
|
|
830
|
+
- str = i18nString(UIStrings.compositingFailedTransformRelatedPropertyCannotBeAcceleratedOnTarget);
|
|
831
|
+
- break;
|
|
832
|
+
- case CLSInsight.AnimationFailureReasons.TRANSFROM_BOX_SIZE_DEPENDENT:
|
|
833
|
+
- str = i18nString(UIStrings.compositingFailedTransformDependsBoxSize);
|
|
834
|
+
- break;
|
|
835
|
+
- case CLSInsight.AnimationFailureReasons.FILTER_RELATED_PROPERTY_MAY_MOVE_PIXELS:
|
|
836
|
+
- str = i18nString(UIStrings.compositingFailedFilterRelatedPropertyMayMovePixels);
|
|
837
|
+
- break;
|
|
838
|
+
- case CLSInsight.AnimationFailureReasons.UNSUPPORTED_CSS_PROPERTY:
|
|
839
|
+
- str = i18nString(UIStrings.compositingFailedUnsupportedCSSProperty, {
|
|
840
|
+
- propertyCount: unsupportedProperties.size,
|
|
841
|
+
- properties: new Intl.ListFormat(undefined, {style: 'short', type: 'conjunction'})
|
|
842
|
+
- .format(unsupportedProperties),
|
|
843
|
+
- });
|
|
844
|
+
- break;
|
|
845
|
+
- case CLSInsight.AnimationFailureReasons.MIXED_KEYFRAME_VALUE_TYPES:
|
|
846
|
+
- str = i18nString(UIStrings.compositingFailedMixedKeyframeValueTypes);
|
|
847
|
+
- break;
|
|
848
|
+
- case CLSInsight.AnimationFailureReasons.TIMELINE_SOURCE_HAS_INVALID_COMPOSITING_STATE:
|
|
849
|
+
- str = i18nString(UIStrings.compositingFailedTimelineSourceHasInvalidCompositingState);
|
|
850
|
+
- break;
|
|
851
|
+
- case CLSInsight.AnimationFailureReasons.ANIMATION_HAS_NO_VISIBLE_CHANGE:
|
|
852
|
+
- str = i18nString(UIStrings.compositingFailedAnimationHasNoVisibleChange);
|
|
853
|
+
- break;
|
|
854
|
+
- case CLSInsight.AnimationFailureReasons.AFFECTS_IMPORTANT_PROPERTY:
|
|
855
|
+
- str = i18nString(UIStrings.compositingFailedAffectsImportantProperty);
|
|
856
|
+
- break;
|
|
857
|
+
- case CLSInsight.AnimationFailureReasons.SVG_TARGET_HAS_INDEPENDENT_TRANSFORM_PROPERTY:
|
|
858
|
+
- str = i18nString(UIStrings.compositingFailedSVGTargetHasIndependentTransformProperty);
|
|
859
|
+
- break;
|
|
860
|
+
- default:
|
|
861
|
+
- // We should never actually end up here, as adding a new AnimationFailureReason
|
|
862
|
+
- // should also require adding a UIString that describes it
|
|
863
|
+
- str = i18nString(UIStrings.compositingFailedUnknownReason);
|
|
864
|
+
- break;
|
|
865
|
+
- }
|
|
866
|
+
- str && contentHelper.appendElementRow(i18nString(UIStrings.compositingFailed), str, true);
|
|
867
|
+
- }
|
|
868
|
+
- }
|
|
869
|
+
-
|
|
870
|
+
- break;
|
|
871
|
+
- }
|
|
872
|
+
-
|
|
873
|
+
- case Trace.Types.Events.Name.PARSE_HTML: {
|
|
874
|
+
- const beginData = unsafeEventArgs['beginData'];
|
|
875
|
+
- const startLine = beginData['startLine'] - 1;
|
|
876
|
+
- const endLine = unsafeEventArgs['endData'] ? unsafeEventArgs['endData']['endLine'] - 1 : undefined;
|
|
877
|
+
- url = beginData['url'];
|
|
878
|
+
- if (url) {
|
|
879
|
+
- contentHelper.appendLocationRange(i18nString(UIStrings.range), url, startLine, endLine);
|
|
880
|
+
- }
|
|
881
|
+
- break;
|
|
882
|
+
- }
|
|
883
|
+
-
|
|
884
|
+
- // @ts-expect-error Fall-through intended.
|
|
885
|
+
- case Trace.Types.Events.Name.FIRE_IDLE_CALLBACK: {
|
|
886
|
+
- contentHelper.appendTextRow(
|
|
887
|
+
- i18nString(UIStrings.allottedTime),
|
|
888
|
+
- i18n.TimeUtilities.millisToString(unsafeEventData['allottedMilliseconds']));
|
|
889
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.invokedByTimeout), unsafeEventData['timedOut']);
|
|
890
|
+
- }
|
|
891
|
+
-
|
|
892
|
+
- case Trace.Types.Events.Name.REQUEST_IDLE_CALLBACK:
|
|
893
|
+
- case Trace.Types.Events.Name.CANCEL_IDLE_CALLBACK: {
|
|
894
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.callbackId), unsafeEventData['id']);
|
|
895
|
+
-
|
|
896
|
+
- if (Trace.Types.Events.isRequestIdleCallback(event)) {
|
|
897
|
+
- contentHelper.appendTextRow(
|
|
898
|
+
- i18nString(UIStrings.requestIdleCallbackTimeout),
|
|
899
|
+
- i18n.TimeUtilities.preciseMillisToString(event.args.data.timeout));
|
|
900
|
+
- }
|
|
901
|
+
- break;
|
|
902
|
+
- }
|
|
903
|
+
-
|
|
904
|
+
- case Trace.Types.Events.Name.EVENT_DISPATCH: {
|
|
905
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.type), unsafeEventData['type']);
|
|
906
|
+
- break;
|
|
907
|
+
- }
|
|
908
|
+
-
|
|
909
|
+
- // @ts-expect-error Fall-through intended.
|
|
910
|
+
- case Trace.Types.Events.Name.MARK_LCP_CANDIDATE: {
|
|
911
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.type), String(unsafeEventData['type']));
|
|
912
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.size), String(unsafeEventData['size']));
|
|
913
|
+
- }
|
|
914
|
+
-
|
|
915
|
+
- case Trace.Types.Events.Name.MARK_FIRST_PAINT:
|
|
916
|
+
- case Trace.Types.Events.Name.MARK_FCP:
|
|
917
|
+
- case Trace.Types.Events.Name.MARK_LOAD:
|
|
918
|
+
- case Trace.Types.Events.Name.MARK_DOM_CONTENT: {
|
|
919
|
+
- const adjustedEventTimeStamp = timeStampForEventAdjustedForClosestNavigationIfPossible(
|
|
920
|
+
- event,
|
|
921
|
+
- parsedTrace,
|
|
922
|
+
- );
|
|
923
|
+
-
|
|
924
|
+
- contentHelper.appendTextRow(
|
|
925
|
+
- i18nString(UIStrings.timestamp), i18n.TimeUtilities.preciseMillisToString(adjustedEventTimeStamp, 1));
|
|
926
|
+
-
|
|
927
|
+
- if (Trace.Types.Events.isMarkerEvent(event)) {
|
|
928
|
+
- contentHelper.appendElementRow(
|
|
929
|
+
- i18nString(UIStrings.details), TimelineUIUtils.buildDetailsNodeForMarkerEvents(event));
|
|
930
|
+
- }
|
|
931
|
+
-
|
|
932
|
+
- break;
|
|
933
|
+
- }
|
|
934
|
+
-
|
|
935
|
+
- case Trace.Types.Events.Name.EVENT_TIMING: {
|
|
936
|
+
- const detailsNode = await TimelineUIUtils.buildDetailsNodeForTraceEvent(
|
|
937
|
+
- event, targetForEvent(parsedTrace, event), linkifier, isFreshOrEnhanced, parsedTrace);
|
|
938
|
+
- if (detailsNode) {
|
|
939
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.details), detailsNode);
|
|
940
|
+
- }
|
|
941
|
+
- if (Trace.Types.Events.isSyntheticInteraction(event)) {
|
|
942
|
+
- const inputDelay = i18n.TimeUtilities.formatMicroSecondsAsMillisFixed(event.inputDelay);
|
|
943
|
+
- const mainThreadTime = i18n.TimeUtilities.formatMicroSecondsAsMillisFixed(event.mainThreadHandling);
|
|
944
|
+
- const presentationDelay = i18n.TimeUtilities.formatMicroSecondsAsMillisFixed(event.presentationDelay);
|
|
945
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.interactionID), event.interactionId);
|
|
946
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.inputDelay), inputDelay);
|
|
947
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.processingDuration), mainThreadTime);
|
|
948
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.presentationDelay), presentationDelay);
|
|
949
|
+
- }
|
|
950
|
+
- break;
|
|
951
|
+
- }
|
|
952
|
+
-
|
|
953
|
+
- default: {
|
|
954
|
+
- const detailsNode = await TimelineUIUtils.buildDetailsNodeForTraceEvent(
|
|
955
|
+
- event, targetForEvent(parsedTrace, event), linkifier, isFreshOrEnhanced, parsedTrace);
|
|
956
|
+
- if (detailsNode) {
|
|
957
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.details), detailsNode);
|
|
958
|
+
- }
|
|
959
|
+
- break;
|
|
960
|
+
- }
|
|
961
|
+
- }
|
|
962
|
+
- const relatedNodes = relatedNodesMap?.values() || [];
|
|
963
|
+
- for (const relatedNode of relatedNodes) {
|
|
964
|
+
- if (relatedNode) {
|
|
965
|
+
- const nodeSpan = await Common.Linkifier.Linkifier.linkify(relatedNode);
|
|
966
|
+
- contentHelper.appendElementRow(relatedNodeLabel || i18nString(UIStrings.relatedNode), nodeSpan);
|
|
967
|
+
- }
|
|
968
|
+
- }
|
|
969
|
+
-
|
|
970
|
+
- // @ts-expect-error TODO(crbug.com/1011811): Remove symbol usage.
|
|
971
|
+
- if (event[previewElementSymbol]) {
|
|
972
|
+
- contentHelper.addSection(i18nString(UIStrings.preview));
|
|
973
|
+
- // @ts-expect-error TODO(crbug.com/1011811): Remove symbol usage.
|
|
974
|
+
- contentHelper.appendElementRow('', event[previewElementSymbol]);
|
|
975
|
+
- }
|
|
976
|
+
-
|
|
977
|
+
- if (!entityAppended) {
|
|
978
|
+
- const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
|
|
979
|
+
- if (originWithEntity) {
|
|
980
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
|
|
981
|
+
- }
|
|
982
|
+
- }
|
|
983
|
+
-
|
|
984
|
+
- const hasStackTrace = Boolean(Trace.Helpers.Trace.getStackTraceTopCallFrameInEventPayload(event));
|
|
985
|
+
- if (Trace.Types.Events.isUserTiming(event) || Trace.Types.Extensions.isSyntheticExtensionEntry(event) ||
|
|
986
|
+
- Trace.Types.Events.isProfileCall(event) || initiator || initiatorFor || hasStackTrace ||
|
|
987
|
+
- parsedTrace?.data.Invalidations.invalidationsForEvent.get(event)) {
|
|
988
|
+
- await TimelineUIUtils.generateCauses(event, contentHelper, parsedTrace);
|
|
989
|
+
- }
|
|
990
|
+
-
|
|
991
|
+
- if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE)) {
|
|
992
|
+
- TimelineUIUtils.renderEventJson(event, contentHelper);
|
|
993
|
+
- }
|
|
994
|
+
-
|
|
65
995
|
- const stats: TimeRangeCategoryStats = {};
|
|
66
996
|
- const showPieChart = canShowPieChart && TimelineUIUtils.aggregatedStatsForTraceEvent(stats, parsedTrace, event);
|
|
67
997
|
- if (showPieChart) {
|
|
@@ -70,10 +1000,346 @@ index 4fe7b92..573e0d3 100644
|
|
|
70
1000
|
- contentHelper.appendElementRow('', pieChart);
|
|
71
1001
|
- }
|
|
72
1002
|
-
|
|
73
|
-
|
|
1003
|
+
- return contentHelper.fragment;
|
|
1004
|
+
- }
|
|
1005
|
+
-
|
|
1006
|
+
static statsForTimeRange(
|
|
1007
|
+
events: Trace.Types.Events.Event[], startTime: Trace.Types.Timing.Milli,
|
|
1008
|
+
endTime: Trace.Types.Timing.Milli): TimeRangeCategoryStats {
|
|
1009
|
+
@@ -1660,264 +738,6 @@ export class TimelineUIUtils {
|
|
1010
|
+
}
|
|
74
1011
|
}
|
|
75
1012
|
|
|
76
|
-
|
|
1013
|
+
- private static renderEventJson(event: Trace.Types.Events.Event, contentHelper: TimelineDetailsContentHelper): void {
|
|
1014
|
+
- contentHelper.addSection(i18nString(UIStrings.traceEvent));
|
|
1015
|
+
-
|
|
1016
|
+
- const eventWithArgsFirst = {
|
|
1017
|
+
- ...{args: event.args},
|
|
1018
|
+
- ...event,
|
|
1019
|
+
- };
|
|
1020
|
+
- const highlightContainer = TimelineUIUtils.renderObjectJson(eventWithArgsFirst);
|
|
1021
|
+
- contentHelper.appendElementRow('', highlightContainer);
|
|
1022
|
+
- }
|
|
1023
|
+
-
|
|
1024
|
+
- private static renderObjectJson(obj: Object|Trace.Types.Extensions.JsonValue): HTMLDivElement {
|
|
1025
|
+
- const indentLength = Common.Settings.Settings.instance().moduleSetting('text-editor-indent').get().length;
|
|
1026
|
+
- // Elide if the data is huge. Then remove the initial new-line for a denser UI
|
|
1027
|
+
- const eventStr = JSON.stringify(obj, null, indentLength).slice(0, 10_000).replace(/{\n /, '{ ');
|
|
1028
|
+
-
|
|
1029
|
+
- // Use CodeHighlighter for syntax highlighting.
|
|
1030
|
+
- const highlightContainer = document.createElement('div');
|
|
1031
|
+
- const shadowRoot = UI.UIUtils.createShadowRootWithCoreStyles(highlightContainer, {cssFile: codeHighlighterStyles});
|
|
1032
|
+
- const elem = shadowRoot.createChild('div');
|
|
1033
|
+
- elem.classList.add('monospace', 'source-code');
|
|
1034
|
+
- elem.textContent = eventStr;
|
|
1035
|
+
- // Highlighting is done async (shrug), but we'll return the container immediately.
|
|
1036
|
+
- void CodeHighlighter.CodeHighlighter.highlightNode(elem, 'text/javascript').then(() => {
|
|
1037
|
+
- /**
|
|
1038
|
+
- * Linkify any URLs within the text nodes.
|
|
1039
|
+
- * Use a TreeWalker to find all our text nodes
|
|
1040
|
+
- **/
|
|
1041
|
+
- function* iterateTreeWalker(walker: TreeWalker): IterableIterator<Node> {
|
|
1042
|
+
- while (walker.nextNode()) {
|
|
1043
|
+
- yield walker.currentNode;
|
|
1044
|
+
- }
|
|
1045
|
+
- }
|
|
1046
|
+
- const walker = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT);
|
|
1047
|
+
- // Gather all the nodes first, then we'll potentially replace them.
|
|
1048
|
+
- for (const node of Array.from(iterateTreeWalker(walker))) {
|
|
1049
|
+
- const frag = TimelineUIUtils.parseStringForLinks(node.textContent || '');
|
|
1050
|
+
- node.parentNode?.replaceChild(frag, node);
|
|
1051
|
+
- }
|
|
1052
|
+
- });
|
|
1053
|
+
-
|
|
1054
|
+
- return highlightContainer;
|
|
1055
|
+
- }
|
|
1056
|
+
-
|
|
1057
|
+
- static stackTraceFromCallFrames(callFrames: Protocol.Runtime.CallFrame[]|Trace.Types.Events.CallFrame[]):
|
|
1058
|
+
- Protocol.Runtime.StackTrace {
|
|
1059
|
+
- return {callFrames} as Protocol.Runtime.StackTrace;
|
|
1060
|
+
- }
|
|
1061
|
+
-
|
|
1062
|
+
- static async generateCauses(
|
|
1063
|
+
- event: Trace.Types.Events.Event, contentHelper: TimelineDetailsContentHelper,
|
|
1064
|
+
- parsedTrace: Trace.TraceModel.ParsedTrace): Promise<void> {
|
|
1065
|
+
- const {startTime} = Trace.Helpers.Timing.eventTimingsMilliSeconds(event);
|
|
1066
|
+
- let initiatorStackLabel = i18nString(UIStrings.initiatorStackTrace);
|
|
1067
|
+
- let stackLabel = i18nString(UIStrings.functionStack);
|
|
1068
|
+
- const stackTraceForEvent = Trace.Extras.StackTraceForEvent.get(event, parsedTrace.data);
|
|
1069
|
+
- if (stackTraceForEvent?.callFrames.length || stackTraceForEvent?.description || stackTraceForEvent?.parent) {
|
|
1070
|
+
- contentHelper.addSection(i18nString(UIStrings.functionStack));
|
|
1071
|
+
- contentHelper.createChildStackTraceElement(stackTraceForEvent);
|
|
1072
|
+
- // TODO(andoli): also build stack trace component for other events
|
|
1073
|
+
- // that have a stack trace using the StackTraceForEvent helper.
|
|
1074
|
+
- } else {
|
|
1075
|
+
- const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(event);
|
|
1076
|
+
- if (stackTrace?.length) {
|
|
1077
|
+
- contentHelper.addSection(stackLabel);
|
|
1078
|
+
- contentHelper.createChildStackTraceElement(TimelineUIUtils.stackTraceFromCallFrames(stackTrace));
|
|
1079
|
+
- }
|
|
1080
|
+
- }
|
|
1081
|
+
- switch (event.name) {
|
|
1082
|
+
- case Trace.Types.Events.Name.TIMER_FIRE:
|
|
1083
|
+
- initiatorStackLabel = i18nString(UIStrings.timerInstalled);
|
|
1084
|
+
- break;
|
|
1085
|
+
- case Trace.Types.Events.Name.FIRE_ANIMATION_FRAME:
|
|
1086
|
+
- initiatorStackLabel = i18nString(UIStrings.animationFrameRequested);
|
|
1087
|
+
- break;
|
|
1088
|
+
- case Trace.Types.Events.Name.FIRE_IDLE_CALLBACK:
|
|
1089
|
+
- initiatorStackLabel = i18nString(UIStrings.idleCallbackRequested);
|
|
1090
|
+
- break;
|
|
1091
|
+
- case Trace.Types.Events.Name.RECALC_STYLE:
|
|
1092
|
+
- initiatorStackLabel = i18nString(UIStrings.firstInvalidated);
|
|
1093
|
+
- stackLabel = i18nString(UIStrings.recalculationForced);
|
|
1094
|
+
- break;
|
|
1095
|
+
- case Trace.Types.Events.Name.LAYOUT:
|
|
1096
|
+
- initiatorStackLabel = i18nString(UIStrings.firstLayoutInvalidation);
|
|
1097
|
+
- stackLabel = i18nString(UIStrings.layoutForced);
|
|
1098
|
+
- break;
|
|
1099
|
+
- }
|
|
1100
|
+
-
|
|
1101
|
+
- const initiator = parsedTrace.data.Initiators.eventToInitiator.get(event);
|
|
1102
|
+
- const initiatorFor = parsedTrace.data.Initiators.initiatorToEvents.get(event);
|
|
1103
|
+
- const invalidations = parsedTrace.data.Invalidations.invalidationsForEvent.get(event);
|
|
1104
|
+
-
|
|
1105
|
+
- if (initiator) {
|
|
1106
|
+
- // If we have an initiator for the event, we can show its stack trace, a link to reveal the initiator,
|
|
1107
|
+
- // and the time since the initiator (Pending For).
|
|
1108
|
+
- const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(initiator);
|
|
1109
|
+
- if (stackTrace) {
|
|
1110
|
+
- contentHelper.addSection(initiatorStackLabel);
|
|
1111
|
+
- contentHelper.createChildStackTraceElement(TimelineUIUtils.stackTraceFromCallFrames(stackTrace.map(frame => {
|
|
1112
|
+
- return {
|
|
1113
|
+
- ...frame,
|
|
1114
|
+
- scriptId: String(frame.scriptId) as Protocol.Runtime.ScriptId,
|
|
1115
|
+
- };
|
|
1116
|
+
- })));
|
|
1117
|
+
- }
|
|
1118
|
+
-
|
|
1119
|
+
- const link = this.createEntryLink(initiator);
|
|
1120
|
+
- contentHelper.appendElementRow(i18nString(UIStrings.initiatedBy), link);
|
|
1121
|
+
-
|
|
1122
|
+
- const {startTime: initiatorStartTime} = Trace.Helpers.Timing.eventTimingsMilliSeconds(initiator);
|
|
1123
|
+
- const delay = startTime - initiatorStartTime;
|
|
1124
|
+
- contentHelper.appendTextRow(i18nString(UIStrings.pendingFor), i18n.TimeUtilities.preciseMillisToString(delay, 1));
|
|
1125
|
+
- }
|
|
1126
|
+
-
|
|
1127
|
+
- if (initiatorFor) {
|
|
1128
|
+
- // If the event is an initiator for some entries, add links to reveal them.
|
|
1129
|
+
- const links = document.createElement('div');
|
|
1130
|
+
- initiatorFor.map((initiator, i) => {
|
|
1131
|
+
- links.appendChild(this.createEntryLink(initiator));
|
|
1132
|
+
- // Add space between each link if it's not last
|
|
1133
|
+
- if (i < initiatorFor.length - 1) {
|
|
1134
|
+
- links.append(' ');
|
|
1135
|
+
- }
|
|
1136
|
+
- });
|
|
1137
|
+
- contentHelper.appendElementRow(UIStrings.initiatorFor, links);
|
|
1138
|
+
- }
|
|
1139
|
+
-
|
|
1140
|
+
- if (invalidations?.length) {
|
|
1141
|
+
- const totalInvalidations = parsedTrace.data.Invalidations.invalidationCountForEvent.get(event) ??
|
|
1142
|
+
- 0; // Won't be 0, but saves us dealing with undefined.
|
|
1143
|
+
- contentHelper.addSection(i18nString(UIStrings.invalidations, {PH1: totalInvalidations}));
|
|
1144
|
+
- await TimelineUIUtils.generateInvalidationsList(invalidations, contentHelper);
|
|
1145
|
+
- }
|
|
1146
|
+
- }
|
|
1147
|
+
-
|
|
1148
|
+
- private static createEntryLink(entry: Trace.Types.Events.Event): HTMLElement {
|
|
1149
|
+
- const link = document.createElement('span');
|
|
1150
|
+
-
|
|
1151
|
+
- const traceBoundsState = TraceBounds.TraceBounds.BoundsManager.instance().state();
|
|
1152
|
+
-
|
|
1153
|
+
- if (!traceBoundsState) {
|
|
1154
|
+
- console.error('Tried to link to an entry without any traceBoundsState. This should never happen.');
|
|
1155
|
+
- return link;
|
|
1156
|
+
- }
|
|
1157
|
+
-
|
|
1158
|
+
- // Check is the entry is outside of the current breadcrumb. If it is, don't create a link to navigate to it because there is no way to navigate outside breadcrumb without removing it. Instead, just display the name and "outside breadcrumb" text
|
|
1159
|
+
- // Consider entry outside breadcrumb only if it is fully outside. If a part of it is visible, we can still select it.
|
|
1160
|
+
- const isEntryOutsideBreadcrumb = traceBoundsState.micro.minimapTraceBounds.min > entry.ts + (entry.dur || 0) ||
|
|
1161
|
+
- traceBoundsState.micro.minimapTraceBounds.max < entry.ts;
|
|
1162
|
+
-
|
|
1163
|
+
- // Check if it is in the hidden array
|
|
1164
|
+
- const isEntryHidden = ModificationsManager.activeManager()?.getEntriesFilter().entryIsInvisible(entry);
|
|
1165
|
+
-
|
|
1166
|
+
- if (!isEntryOutsideBreadcrumb) {
|
|
1167
|
+
- link.classList.add('timeline-link');
|
|
1168
|
+
- UI.ARIAUtils.markAsLink(link);
|
|
1169
|
+
- link.tabIndex = 0;
|
|
1170
|
+
- link.addEventListener('click', () => {
|
|
1171
|
+
- TimelinePanel.instance().select(selectionFromEvent(entry));
|
|
1172
|
+
- });
|
|
1173
|
+
-
|
|
1174
|
+
- link.addEventListener('keydown', event => {
|
|
1175
|
+
- if (event.key === Platform.KeyboardUtilities.ENTER_KEY) {
|
|
1176
|
+
- TimelinePanel.instance().select(selectionFromEvent(entry));
|
|
1177
|
+
- event.consume(true);
|
|
1178
|
+
- }
|
|
1179
|
+
- });
|
|
1180
|
+
- }
|
|
1181
|
+
-
|
|
1182
|
+
- if (isEntryHidden) {
|
|
1183
|
+
- link.textContent = this.eventTitle(entry) + ' ' + i18nString(UIStrings.entryIsHidden);
|
|
1184
|
+
- } else if (isEntryOutsideBreadcrumb) {
|
|
1185
|
+
- link.textContent = this.eventTitle(entry) + ' ' + i18nString(UIStrings.outsideBreadcrumbRange);
|
|
1186
|
+
- } else {
|
|
1187
|
+
- link.textContent = this.eventTitle(entry);
|
|
1188
|
+
- }
|
|
1189
|
+
-
|
|
1190
|
+
- return link;
|
|
1191
|
+
- }
|
|
1192
|
+
-
|
|
1193
|
+
- private static async generateInvalidationsList(
|
|
1194
|
+
- invalidations: Trace.Types.Events.InvalidationTrackingEvent[],
|
|
1195
|
+
- contentHelper: TimelineDetailsContentHelper): Promise<void> {
|
|
1196
|
+
- const {groupedByReason, backendNodeIds} = TimelineComponents.DetailsView.generateInvalidationsList(invalidations);
|
|
1197
|
+
-
|
|
1198
|
+
- let relatedNodesMap: Map<number, SDK.DOMModel.DOMNode|null>|null = null;
|
|
1199
|
+
- const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
1200
|
+
- const domModel = target?.model(SDK.DOMModel.DOMModel);
|
|
1201
|
+
- if (domModel) {
|
|
1202
|
+
- relatedNodesMap = await domModel.pushNodesByBackendIdsToFrontend(backendNodeIds);
|
|
1203
|
+
- }
|
|
1204
|
+
-
|
|
1205
|
+
- Object.keys(groupedByReason).forEach(reason => {
|
|
1206
|
+
- TimelineUIUtils.generateInvalidationsForReason(reason, groupedByReason[reason], relatedNodesMap, contentHelper);
|
|
1207
|
+
- });
|
|
1208
|
+
- }
|
|
1209
|
+
-
|
|
1210
|
+
- private static generateInvalidationsForReason(
|
|
1211
|
+
- reason: string, invalidations: Trace.Types.Events.InvalidationTrackingEvent[],
|
|
1212
|
+
- relatedNodesMap: Map<number, SDK.DOMModel.DOMNode|null>|null, contentHelper: TimelineDetailsContentHelper): void {
|
|
1213
|
+
- function createLinkForInvalidationNode(invalidation: Trace.Types.Events.InvalidationTrackingEvent):
|
|
1214
|
+
- HTMLSpanElement {
|
|
1215
|
+
- const node = (invalidation.args.data.nodeId && relatedNodesMap) ?
|
|
1216
|
+
- relatedNodesMap.get(invalidation.args.data.nodeId) :
|
|
1217
|
+
- null;
|
|
1218
|
+
- if (node) {
|
|
1219
|
+
- const nodeSpan = document.createElement('span');
|
|
1220
|
+
- void Common.Linkifier.Linkifier.linkify(node).then(link => nodeSpan.appendChild(link));
|
|
1221
|
+
- return nodeSpan;
|
|
1222
|
+
- }
|
|
1223
|
+
- if (invalidation.args.data.nodeName) {
|
|
1224
|
+
- const nodeSpan = document.createElement('span');
|
|
1225
|
+
- nodeSpan.textContent = invalidation.args.data.nodeName;
|
|
1226
|
+
- return nodeSpan;
|
|
1227
|
+
- }
|
|
1228
|
+
- const nodeSpan = document.createElement('span');
|
|
1229
|
+
- UI.UIUtils.createTextChild(nodeSpan, i18nString(UIStrings.UnknownNode));
|
|
1230
|
+
- return nodeSpan;
|
|
1231
|
+
- }
|
|
1232
|
+
-
|
|
1233
|
+
- const generatedItems = new Set<string>();
|
|
1234
|
+
-
|
|
1235
|
+
- for (const invalidation of invalidations) {
|
|
1236
|
+
- const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(invalidation);
|
|
1237
|
+
- let scriptLink: HTMLElement|null = null;
|
|
1238
|
+
- const callFrame = stackTrace?.at(0);
|
|
1239
|
+
- if (callFrame) {
|
|
1240
|
+
- scriptLink = contentHelper.linkifier()?.maybeLinkifyScriptLocation(
|
|
1241
|
+
- SDK.TargetManager.TargetManager.instance().rootTarget(),
|
|
1242
|
+
- callFrame.scriptId as Protocol.Runtime.ScriptId,
|
|
1243
|
+
- callFrame.url as Platform.DevToolsPath.UrlString,
|
|
1244
|
+
- callFrame.lineNumber,
|
|
1245
|
+
- ) ||
|
|
1246
|
+
- null;
|
|
1247
|
+
- }
|
|
1248
|
+
-
|
|
1249
|
+
- const niceNodeLink = createLinkForInvalidationNode(invalidation);
|
|
1250
|
+
-
|
|
1251
|
+
- const text = scriptLink ?
|
|
1252
|
+
- i18n.i18n.getFormatLocalizedString(
|
|
1253
|
+
- str_, UIStrings.invalidationWithCallFrame, {PH1: niceNodeLink, PH2: scriptLink}) as HTMLElement :
|
|
1254
|
+
- niceNodeLink;
|
|
1255
|
+
-
|
|
1256
|
+
- // Sometimes we can get different Invalidation events which cause
|
|
1257
|
+
- // the same text for the same element for the same reason to be
|
|
1258
|
+
- // generated. Rather than show the user duplicates, if we have
|
|
1259
|
+
- // generated text that looks identical to this before, we will
|
|
1260
|
+
- // bail.
|
|
1261
|
+
- const generatedText: string = (typeof text === 'string' ? text : text.innerText);
|
|
1262
|
+
- if (generatedItems.has(generatedText)) {
|
|
1263
|
+
- continue;
|
|
1264
|
+
- }
|
|
1265
|
+
-
|
|
1266
|
+
- generatedItems.add(generatedText);
|
|
1267
|
+
- contentHelper.appendElementRow(reason, text);
|
|
1268
|
+
- }
|
|
1269
|
+
- }
|
|
1270
|
+
-
|
|
1271
|
+
/** Populates the passed object then returns true/false if it makes sense to show the pie chart */
|
|
1272
|
+
private static aggregatedStatsForTraceEvent(
|
|
1273
|
+
total: TimeRangeCategoryStats, parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
1274
|
+
@@ -1970,67 +790,12 @@ export class TimelineUIUtils {
|
|
1275
|
+
return true;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
- static async buildPicturePreviewContent(
|
|
1279
|
+
- parsedTrace: Trace.TraceModel.ParsedTrace, event: Trace.Types.Events.Paint,
|
|
1280
|
+
- target: SDK.Target.Target): Promise<Element|null> {
|
|
1281
|
+
- const snapshotEvent = parsedTrace.data.LayerTree.paintsToSnapshots.get(event);
|
|
1282
|
+
- if (!snapshotEvent) {
|
|
1283
|
+
- return null;
|
|
1284
|
+
- }
|
|
1285
|
+
-
|
|
1286
|
+
- const paintProfilerModel = target.model(SDK.PaintProfiler.PaintProfilerModel);
|
|
1287
|
+
- if (!paintProfilerModel) {
|
|
1288
|
+
- return null;
|
|
1289
|
+
- }
|
|
1290
|
+
- const snapshot = await paintProfilerModel.loadSnapshot(snapshotEvent.args.snapshot.skp64);
|
|
1291
|
+
- if (!snapshot) {
|
|
1292
|
+
- return null;
|
|
1293
|
+
- }
|
|
1294
|
+
-
|
|
1295
|
+
- const snapshotWithRect = {
|
|
1296
|
+
- snapshot,
|
|
1297
|
+
- rect: snapshotEvent.args.snapshot.params?.layer_rect,
|
|
1298
|
+
- };
|
|
1299
|
+
-
|
|
1300
|
+
- if (!snapshotWithRect) {
|
|
1301
|
+
- return null;
|
|
1302
|
+
- }
|
|
1303
|
+
- const imageURLPromise = snapshotWithRect.snapshot.replay();
|
|
1304
|
+
- snapshotWithRect.snapshot.release();
|
|
1305
|
+
- const imageURL = await imageURLPromise as Platform.DevToolsPath.UrlString;
|
|
1306
|
+
- if (!imageURL) {
|
|
1307
|
+
- return null;
|
|
1308
|
+
- }
|
|
1309
|
+
- const stylesContainer = document.createElement('div');
|
|
1310
|
+
- const shadowRoot = stylesContainer.attachShadow({mode: 'open'});
|
|
1311
|
+
- shadowRoot.createChild('style').textContent = imagePreviewStyles;
|
|
1312
|
+
- const container = shadowRoot.createChild('div');
|
|
1313
|
+
- container.classList.add('image-preview-container', 'vbox', 'link');
|
|
1314
|
+
- const img = container.createChild('img');
|
|
1315
|
+
- img.src = imageURL;
|
|
1316
|
+
- img.alt = LegacyComponents.ImagePreview.ImagePreview.defaultAltTextForImageURL(imageURL);
|
|
1317
|
+
- const paintProfilerButton = container.createChild('a');
|
|
1318
|
+
- paintProfilerButton.textContent = i18nString(UIStrings.paintProfiler);
|
|
1319
|
+
- UI.ARIAUtils.markAsLink(container);
|
|
1320
|
+
- container.tabIndex = 0;
|
|
1321
|
+
- container.addEventListener('click', () => TimelinePanel.instance().select(selectionFromEvent(event)), false);
|
|
1322
|
+
- container.addEventListener('keydown', keyEvent => {
|
|
1323
|
+
- if (keyEvent.key === Platform.KeyboardUtilities.ENTER_KEY) {
|
|
1324
|
+
- TimelinePanel.instance().select(selectionFromEvent(event));
|
|
1325
|
+
- keyEvent.consume(true);
|
|
1326
|
+
- }
|
|
1327
|
+
- });
|
|
1328
|
+
- return stylesContainer;
|
|
1329
|
+
- }
|
|
1330
|
+
-
|
|
1331
|
+
static createEventDivider(event: Trace.Types.Events.Event, zeroTime: number): HTMLDivElement {
|
|
1332
|
+
const eventDivider = document.createElement('div');
|
|
1333
|
+
eventDivider.classList.add('resources-event-divider');
|
|
1334
|
+
const {startTime: eventStartTime} = Trace.Helpers.Timing.eventTimingsMilliSeconds(event);
|
|
1335
|
+
|
|
1336
|
+
const startTime = i18n.TimeUtilities.millisToString(eventStartTime - zeroTime);
|
|
1337
|
+
- UI.Tooltip.Tooltip.install(
|
|
1338
|
+
- eventDivider, i18nString(UIStrings.sAtS, {PH1: TimelineUIUtils.eventTitle(event), PH2: startTime}));
|
|
1339
|
+
const style = TimelineUIUtils.markerStyleForEvent(event);
|
|
1340
|
+
if (style.tall) {
|
|
1341
|
+
eventDivider.style.backgroundColor = style.color;
|
|
1342
|
+
@@ -2048,157 +813,6 @@ export class TimelineUIUtils {
|
|
77
1343
|
return Trace.Styles.getCategoryStyles();
|
|
78
1344
|
}
|
|
79
1345
|
|
|
@@ -150,13 +1416,59 @@ index 4fe7b92..573e0d3 100644
|
|
|
150
1416
|
-
|
|
151
1417
|
- return element;
|
|
152
1418
|
- }
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
1419
|
+
- // Generates a Summary component given a aggregated stats for categories.
|
|
1420
|
+
- static generateSummaryDetails(
|
|
1421
|
+
- aggregatedStats: Record<string, number>, rangeStart: number, rangeEnd: number,
|
|
1422
|
+
- selectedEvents: Trace.Types.Events.Event[],
|
|
1423
|
+
- thirdPartyTree: ThirdPartyTreeView.ThirdPartyTreeViewWidget): Element {
|
|
1424
|
+
- const element = document.createElement('div');
|
|
1425
|
+
- element.classList.add('timeline-details-range-summary', 'hbox');
|
|
1426
|
+
-
|
|
1427
|
+
- // First, the category bar chart.
|
|
1428
|
+
- let total = 0;
|
|
1429
|
+
- let categories: TimelineComponents.TimelineSummary.CategoryData[] = [];
|
|
1430
|
+
- // Calculate total of all categories.
|
|
1431
|
+
- for (const categoryName in aggregatedStats) {
|
|
1432
|
+
- total += aggregatedStats[categoryName];
|
|
1433
|
+
- }
|
|
1434
|
+
-
|
|
1435
|
+
- // Get stats values from categories.
|
|
1436
|
+
- for (const categoryName in Trace.Styles.getCategoryStyles()) {
|
|
1437
|
+
- const category = Trace.Styles.getCategoryStyles()[categoryName as keyof Trace.Styles.CategoryPalette];
|
|
1438
|
+
- if (category.name === Trace.Styles.EventCategory.IDLE) {
|
|
1439
|
+
- continue;
|
|
1440
|
+
- }
|
|
1441
|
+
- const value = aggregatedStats[category.name];
|
|
1442
|
+
- if (!value) {
|
|
1443
|
+
- continue;
|
|
1444
|
+
- }
|
|
1445
|
+
- const title = category.title;
|
|
1446
|
+
- const color = category.getCSSValue();
|
|
1447
|
+
- categories.push({value, color, title});
|
|
1448
|
+
- }
|
|
1449
|
+
-
|
|
1450
|
+
- // Keeps the most useful categories on top.
|
|
1451
|
+
- categories = categories.sort((a, b) => b.value - a.value);
|
|
1452
|
+
- const start = Trace.Types.Timing.Milli(rangeStart);
|
|
1453
|
+
- const end = Trace.Types.Timing.Milli(rangeEnd);
|
|
1454
|
+
- const categorySummaryTable = new TimelineComponents.TimelineSummary.CategorySummary();
|
|
1455
|
+
- categorySummaryTable.data = {
|
|
1456
|
+
- rangeStart: start,
|
|
1457
|
+
- rangeEnd: end,
|
|
1458
|
+
- total,
|
|
1459
|
+
- categories,
|
|
1460
|
+
- selectedEvents,
|
|
1461
|
+
- };
|
|
1462
|
+
- element.append(categorySummaryTable);
|
|
1463
|
+
- // Add the 3p datagrid
|
|
1464
|
+
- const treeView = new ThirdPartyTreeView.ThirdPartyTreeElement();
|
|
1465
|
+
- treeView.treeView = thirdPartyTree;
|
|
1466
|
+
- UI.ARIAUtils.setLabel(treeView, i18nString(UIStrings.thirdPartyTable));
|
|
1467
|
+
- element.append(treeView);
|
|
1468
|
+
-
|
|
1469
|
+
- return element;
|
|
1470
|
+
- }
|
|
1471
|
+
-
|
|
160
1472
|
- static generateDetailsContentForFrame(
|
|
161
1473
|
- frame: Trace.Types.Events.LegacyTimelineFrame, filmStrip: Trace.Extras.FilmStrip.Data|null,
|
|
162
1474
|
- filmStripFrame: Trace.Extras.FilmStrip.Frame|null): DocumentFragment {
|
|
@@ -185,3 +1497,220 @@ index 4fe7b92..573e0d3 100644
|
|
|
185
1497
|
static frameDuration(frame: Trace.Types.Events.LegacyTimelineFrame): Element {
|
|
186
1498
|
const offsetMilli = Trace.Helpers.Timing.microToMilli(frame.startTimeOffset);
|
|
187
1499
|
const durationMilli = Trace.Helpers.Timing.microToMilli(Trace.Types.Timing.Micro(frame.endTime - frame.startTime));
|
|
1500
|
+
@@ -2318,27 +932,6 @@ export class TimelineUIUtils {
|
|
1501
|
+
return Common.ParsedURL.schemeIs(url, 'about:') ? `"${Platform.StringUtilities.trimMiddle(frame.name, trimAt)}"` :
|
|
1502
|
+
frame.url.slice(0, trimAt);
|
|
1503
|
+
}
|
|
1504
|
+
-
|
|
1505
|
+
- static getOriginWithEntity(
|
|
1506
|
+
- entityMapper: Trace.EntityMapper.EntityMapper|null, parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
1507
|
+
- event: Trace.Types.Events.Event): string|null {
|
|
1508
|
+
- const resolvedURL = SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(parsedTrace, event);
|
|
1509
|
+
- if (!resolvedURL) {
|
|
1510
|
+
- return null;
|
|
1511
|
+
- }
|
|
1512
|
+
- const parsedUrl = URL.parse(resolvedURL);
|
|
1513
|
+
- if (!parsedUrl) {
|
|
1514
|
+
- return null;
|
|
1515
|
+
- }
|
|
1516
|
+
-
|
|
1517
|
+
- const entity = entityMapper?.entityForEvent(event) ?? null;
|
|
1518
|
+
- if (!entity) {
|
|
1519
|
+
- return null;
|
|
1520
|
+
- }
|
|
1521
|
+
-
|
|
1522
|
+
- const originWithEntity = Utils.Helpers.formatOriginWithEntity(parsedUrl, entity, true);
|
|
1523
|
+
- return originWithEntity;
|
|
1524
|
+
- }
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
export const aggregatedStatsKey = Symbol('aggregatedStats');
|
|
1528
|
+
@@ -2357,147 +950,6 @@ export class EventDispatchTypeDescriptor {
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
-export class TimelineDetailsContentHelper {
|
|
1533
|
+
- fragment: DocumentFragment;
|
|
1534
|
+
- #linkifier: LegacyComponents.Linkifier.Linkifier|null;
|
|
1535
|
+
- private target: SDK.Target.Target|null;
|
|
1536
|
+
- element: HTMLDivElement;
|
|
1537
|
+
- private tableElement: HTMLElement;
|
|
1538
|
+
-
|
|
1539
|
+
- constructor(target: SDK.Target.Target|null, linkifier: LegacyComponents.Linkifier.Linkifier|null) {
|
|
1540
|
+
- this.fragment = document.createDocumentFragment();
|
|
1541
|
+
-
|
|
1542
|
+
- this.#linkifier = linkifier;
|
|
1543
|
+
- this.target = target;
|
|
1544
|
+
-
|
|
1545
|
+
- this.element = document.createElement('div');
|
|
1546
|
+
- this.element.classList.add('timeline-details-view-block');
|
|
1547
|
+
- this.tableElement = this.element.createChild('div', 'vbox timeline-details-chip-body');
|
|
1548
|
+
- this.fragment.appendChild(this.element);
|
|
1549
|
+
- }
|
|
1550
|
+
-
|
|
1551
|
+
- addSection(title: string, swatchColor?: string, event?: Trace.Types.Events.Event): void {
|
|
1552
|
+
- if (!this.tableElement.hasChildNodes()) {
|
|
1553
|
+
- this.element.removeChildren();
|
|
1554
|
+
- } else {
|
|
1555
|
+
- this.element = document.createElement('div');
|
|
1556
|
+
- this.element.classList.add('timeline-details-view-block');
|
|
1557
|
+
- this.fragment.appendChild(this.element);
|
|
1558
|
+
- }
|
|
1559
|
+
-
|
|
1560
|
+
- if (title) {
|
|
1561
|
+
- const titleElement = this.element.createChild('div', 'timeline-details-chip-title');
|
|
1562
|
+
- if (swatchColor) {
|
|
1563
|
+
- titleElement.createChild('div').style.backgroundColor = swatchColor;
|
|
1564
|
+
- }
|
|
1565
|
+
-
|
|
1566
|
+
- const textChild = titleElement.createChild('span');
|
|
1567
|
+
- textChild.textContent = title;
|
|
1568
|
+
-
|
|
1569
|
+
- if (event) {
|
|
1570
|
+
- textChild.classList.add('timeline-details-chip-title-reveal-entry');
|
|
1571
|
+
- textChild.addEventListener('click', function() {
|
|
1572
|
+
- TimelinePanel.instance().zoomEvent(event);
|
|
1573
|
+
- });
|
|
1574
|
+
- }
|
|
1575
|
+
- }
|
|
1576
|
+
-
|
|
1577
|
+
- this.tableElement = this.element.createChild('div', 'vbox timeline-details-chip-body');
|
|
1578
|
+
- this.fragment.appendChild(this.element);
|
|
1579
|
+
- }
|
|
1580
|
+
-
|
|
1581
|
+
- linkifier(): LegacyComponents.Linkifier.Linkifier|null {
|
|
1582
|
+
- return this.#linkifier;
|
|
1583
|
+
- }
|
|
1584
|
+
-
|
|
1585
|
+
- appendTextRow(title: string, value: string|number|boolean): void {
|
|
1586
|
+
- const rowElement = this.tableElement.createChild('div', 'timeline-details-view-row');
|
|
1587
|
+
- rowElement.createChild('div', 'timeline-details-view-row-title').textContent = title;
|
|
1588
|
+
- rowElement.createChild('div', 'timeline-details-view-row-value').textContent = value.toString();
|
|
1589
|
+
- }
|
|
1590
|
+
-
|
|
1591
|
+
- appendElementRow(title: string, content: string|Node, isWarning?: boolean, isStacked?: boolean): void {
|
|
1592
|
+
- const rowElement = this.tableElement.createChild('div', 'timeline-details-view-row');
|
|
1593
|
+
- rowElement.setAttribute('data-row-title', title);
|
|
1594
|
+
- if (isWarning) {
|
|
1595
|
+
- rowElement.classList.add('timeline-details-warning');
|
|
1596
|
+
- }
|
|
1597
|
+
- if (isStacked) {
|
|
1598
|
+
- rowElement.classList.add('timeline-details-stack-values');
|
|
1599
|
+
- }
|
|
1600
|
+
- const titleElement = rowElement.createChild('div', 'timeline-details-view-row-title');
|
|
1601
|
+
- titleElement.textContent = title;
|
|
1602
|
+
- const valueElement = rowElement.createChild('div', 'timeline-details-view-row-value');
|
|
1603
|
+
- if (content instanceof Node) {
|
|
1604
|
+
- valueElement.appendChild(content);
|
|
1605
|
+
- } else {
|
|
1606
|
+
- UI.UIUtils.createTextChild(valueElement, content || '');
|
|
1607
|
+
- }
|
|
1608
|
+
- }
|
|
1609
|
+
-
|
|
1610
|
+
- appendLocationRow(
|
|
1611
|
+
- title: string, url: string, startLine: number, startColumn?: number, text?: string, omitOrigin?: boolean): void {
|
|
1612
|
+
- if (!this.#linkifier) {
|
|
1613
|
+
- return;
|
|
1614
|
+
- }
|
|
1615
|
+
-
|
|
1616
|
+
- const options = {
|
|
1617
|
+
- tabStop: true,
|
|
1618
|
+
- columnNumber: startColumn,
|
|
1619
|
+
- showColumnNumber: true,
|
|
1620
|
+
- inlineFrameIndex: 0,
|
|
1621
|
+
- text,
|
|
1622
|
+
- omitOrigin,
|
|
1623
|
+
- };
|
|
1624
|
+
- const link = this.#linkifier.maybeLinkifyScriptLocation(
|
|
1625
|
+
- this.target, null, url as Platform.DevToolsPath.UrlString, startLine, options);
|
|
1626
|
+
- if (!link) {
|
|
1627
|
+
- return;
|
|
1628
|
+
- }
|
|
1629
|
+
- this.appendElementRow(title, link);
|
|
1630
|
+
- }
|
|
1631
|
+
-
|
|
1632
|
+
- appendLocationRange(title: string, url: Platform.DevToolsPath.UrlString, startLine: number, endLine?: number): void {
|
|
1633
|
+
- if (!this.#linkifier || !this.target) {
|
|
1634
|
+
- return;
|
|
1635
|
+
- }
|
|
1636
|
+
- const locationContent = document.createElement('span');
|
|
1637
|
+
- const link = this.#linkifier.maybeLinkifyScriptLocation(
|
|
1638
|
+
- this.target, null, url, startLine, {tabStop: true, inlineFrameIndex: 0});
|
|
1639
|
+
- if (!link) {
|
|
1640
|
+
- return;
|
|
1641
|
+
- }
|
|
1642
|
+
- locationContent.appendChild(link);
|
|
1643
|
+
- UI.UIUtils.createTextChild(
|
|
1644
|
+
- locationContent, Platform.StringUtilities.sprintf(' [%s…%s]', startLine + 1, (endLine || 0) + 1 || ''));
|
|
1645
|
+
- this.appendElementRow(title, locationContent);
|
|
1646
|
+
- }
|
|
1647
|
+
-
|
|
1648
|
+
- createChildStackTraceElement(stackTrace: Protocol.Runtime.StackTrace): void {
|
|
1649
|
+
- if (!this.#linkifier) {
|
|
1650
|
+
- return;
|
|
1651
|
+
- }
|
|
1652
|
+
- const resolvedStackTrace: Protocol.Runtime.StackTrace = structuredClone(stackTrace);
|
|
1653
|
+
- let currentResolvedStackTrace: Protocol.Runtime.StackTrace|undefined = resolvedStackTrace;
|
|
1654
|
+
- while (currentResolvedStackTrace) {
|
|
1655
|
+
- currentResolvedStackTrace.callFrames = currentResolvedStackTrace.callFrames.map(
|
|
1656
|
+
- callFrame => ({
|
|
1657
|
+
- ...callFrame,
|
|
1658
|
+
- functionName: SourceMapsResolver.SourceMapsResolver.resolvedCodeLocationForCallFrame(callFrame)?.name ||
|
|
1659
|
+
- callFrame.functionName,
|
|
1660
|
+
- }));
|
|
1661
|
+
- currentResolvedStackTrace = currentResolvedStackTrace.parent;
|
|
1662
|
+
- }
|
|
1663
|
+
- const stackTraceElement =
|
|
1664
|
+
- this.tableElement.createChild('div', 'timeline-details-view-row timeline-details-stack-values');
|
|
1665
|
+
- const callFrameContents = new LegacyComponents.JSPresentationUtils.StackTracePreviewContent(
|
|
1666
|
+
- undefined, this.target ?? undefined, this.#linkifier,
|
|
1667
|
+
- {stackTrace: resolvedStackTrace, tabStops: true, showColumnNumber: true});
|
|
1668
|
+
- callFrameContents.markAsRoot();
|
|
1669
|
+
- callFrameContents.show(stackTraceElement);
|
|
1670
|
+
- }
|
|
1671
|
+
-}
|
|
1672
|
+
-
|
|
1673
|
+
export const categoryBreakdownCacheSymbol = Symbol('categoryBreakdownCache');
|
|
1674
|
+
export interface TimelineMarkerStyle {
|
|
1675
|
+
title: string;
|
|
1676
|
+
diff --git a/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/Linkifier.ts b/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/Linkifier.ts
|
|
1677
|
+
index 7d19eae..e073846 100644
|
|
1678
|
+
--- a/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/Linkifier.ts
|
|
1679
|
+
+++ b/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/Linkifier.ts
|
|
1680
|
+
@@ -16,7 +16,6 @@ import * as TextUtils from '../../../../models/text_utils/text_utils.js';
|
|
1681
|
+
import type * as Trace from '../../../../models/trace/trace.js';
|
|
1682
|
+
import * as Workspace from '../../../../models/workspace/workspace.js';
|
|
1683
|
+
import type * as IconButton from '../../../components/icon_button/icon_button.js';
|
|
1684
|
+
-import * as VisualLogging from '../../../visual_logging/visual_logging.js';
|
|
1685
|
+
import * as UI from '../../legacy.js';
|
|
1686
|
+
|
|
1687
|
+
const UIStrings = {
|
|
1688
|
+
@@ -601,7 +600,6 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
1689
|
+
// @ts-expect-error
|
|
1690
|
+
link.href = href;
|
|
1691
|
+
}
|
|
1692
|
+
- link.setAttribute('jslog', `${VisualLogging.link(jslogContext).track({click: true})}`);
|
|
1693
|
+
|
|
1694
|
+
if (text instanceof HTMLElement) {
|
|
1695
|
+
link.appendChild(text);
|
|
1696
|
+
diff --git a/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/utils.ts b/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/utils.ts
|
|
1697
|
+
index 2f98cde..cb95b85 100644
|
|
1698
|
+
--- a/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/utils.ts
|
|
1699
|
+
+++ b/node_modules/chrome-devtools-frontend/front_end/ui/legacy/components/utils/utils.ts
|
|
1700
|
+
@@ -2,16 +2,8 @@
|
|
1701
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
1702
|
+
// found in the LICENSE file.
|
|
1703
|
+
|
|
1704
|
+
-import * as ImagePreview from './ImagePreview.js';
|
|
1705
|
+
-import * as JSPresentationUtils from './JSPresentationUtils.js';
|
|
1706
|
+
import * as Linkifier from './Linkifier.js';
|
|
1707
|
+
-import * as Reload from './Reload.js';
|
|
1708
|
+
-import * as TargetDetachedDialog from './TargetDetachedDialog.js';
|
|
1709
|
+
|
|
1710
|
+
export {
|
|
1711
|
+
- ImagePreview,
|
|
1712
|
+
- JSPresentationUtils,
|
|
1713
|
+
Linkifier,
|
|
1714
|
+
- Reload,
|
|
1715
|
+
- TargetDetachedDialog,
|
|
1716
|
+
};
|