devtools-tracing 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/generate.ts +32 -26
  2. package/index.ts +2 -1
  3. package/lib/extension-api/ExtensionAPI.d.ts +357 -0
  4. package/lib/front_end/models/bindings/CSSWorkspaceBinding.ts +318 -0
  5. package/lib/front_end/models/bindings/CompilerScriptMapping.ts +536 -0
  6. package/lib/front_end/models/bindings/ContentProviderBasedProject.ts +187 -0
  7. package/lib/front_end/models/bindings/DebuggerLanguagePlugins.ts +1197 -0
  8. package/lib/front_end/models/bindings/DebuggerWorkspaceBinding.ts +733 -0
  9. package/lib/front_end/models/bindings/DefaultScriptMapping.ts +141 -0
  10. package/lib/front_end/models/bindings/FileUtils.ts +228 -0
  11. package/lib/front_end/models/bindings/LiveLocation.ts +81 -0
  12. package/lib/front_end/models/bindings/NetworkProject.ts +157 -0
  13. package/lib/front_end/models/bindings/PresentationConsoleMessageHelper.ts +312 -0
  14. package/lib/front_end/models/bindings/ResourceMapping.ts +539 -0
  15. package/lib/front_end/models/bindings/ResourceScriptMapping.ts +491 -0
  16. package/lib/front_end/models/bindings/ResourceUtils.ts +103 -0
  17. package/lib/front_end/models/bindings/SASSSourceMapping.ts +222 -0
  18. package/lib/front_end/models/bindings/StylesSourceMapping.ts +316 -0
  19. package/lib/front_end/models/bindings/TempFile.ts +67 -0
  20. package/lib/front_end/models/bindings/bindings.ts +39 -0
  21. package/lib/front_end/models/source_map_scopes/NamesResolver.ts +765 -0
  22. package/lib/front_end/models/source_map_scopes/ScopeChainModel.ts +84 -0
  23. package/lib/front_end/models/source_map_scopes/source_map_scopes.ts +11 -0
  24. package/lib/front_end/models/stack_trace/StackTrace.ts +53 -0
  25. package/lib/front_end/models/stack_trace/StackTraceImpl.ts +85 -0
  26. package/lib/front_end/models/stack_trace/StackTraceModel.ts +128 -0
  27. package/lib/front_end/models/stack_trace/Trie.ts +163 -0
  28. package/lib/front_end/models/stack_trace/stack_trace.ts +9 -0
  29. package/lib/front_end/models/stack_trace/stack_trace_impl.ts +13 -0
  30. package/lib/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +240 -0
  31. package/lib/front_end/models/trace_source_maps_resolver/trace_source_maps_resolver.ts +5 -0
  32. package/lib/front_end/models/workspace/FileManager.ts +97 -0
  33. package/lib/front_end/models/workspace/IgnoreListManager.ts +628 -0
  34. package/lib/front_end/models/workspace/SearchConfig.ts +149 -0
  35. package/lib/front_end/models/workspace/UISourceCode.ts +698 -0
  36. package/lib/front_end/models/workspace/WorkspaceImpl.ts +339 -0
  37. package/lib/front_end/models/workspace/workspace.ts +17 -0
  38. package/lib/front_end/panels/timeline/TimelineUIUtils.ts +1029 -0
  39. package/lib/front_end/panels/timeline/extensions/ExtensionUI.ts +49 -0
  40. package/lib/front_end/panels/timeline/extensions/extensions.ts +9 -0
  41. package/lib/front_end/third_party/codemirror.next/LICENSE +21 -0
  42. package/lib/front_end/third_party/codemirror.next/README.chromium +30 -0
  43. package/lib/front_end/third_party/codemirror.next/bundle-tsconfig.json +24 -0
  44. package/lib/front_end/third_party/codemirror.next/bundle.ts +135 -0
  45. package/lib/front_end/third_party/codemirror.next/chunk/angular.js +2 -0
  46. package/lib/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -0
  47. package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js +2 -0
  48. package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -0
  49. package/lib/front_end/third_party/codemirror.next/chunk/cpp.js +2 -0
  50. package/lib/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -0
  51. package/lib/front_end/third_party/codemirror.next/chunk/css.js +2 -0
  52. package/lib/front_end/third_party/codemirror.next/chunk/html.js +4 -0
  53. package/lib/front_end/third_party/codemirror.next/chunk/java.js +2 -0
  54. package/lib/front_end/third_party/codemirror.next/chunk/java.js.map +1 -0
  55. package/lib/front_end/third_party/codemirror.next/chunk/javascript.js +2 -0
  56. package/lib/front_end/third_party/codemirror.next/chunk/legacy.js +2 -0
  57. package/lib/front_end/third_party/codemirror.next/chunk/legacy.js.map +1 -0
  58. package/lib/front_end/third_party/codemirror.next/chunk/less.js +2 -0
  59. package/lib/front_end/third_party/codemirror.next/chunk/less.js.map +1 -0
  60. package/lib/front_end/third_party/codemirror.next/chunk/markdown.js +2 -0
  61. package/lib/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -0
  62. package/lib/front_end/third_party/codemirror.next/chunk/php.js +2 -0
  63. package/lib/front_end/third_party/codemirror.next/chunk/php.js.map +1 -0
  64. package/lib/front_end/third_party/codemirror.next/chunk/python.js +2 -0
  65. package/lib/front_end/third_party/codemirror.next/chunk/python.js.map +1 -0
  66. package/lib/front_end/third_party/codemirror.next/chunk/sass.js +2 -0
  67. package/lib/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -0
  68. package/lib/front_end/third_party/codemirror.next/chunk/svelte.js +2 -0
  69. package/lib/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -0
  70. package/lib/front_end/third_party/codemirror.next/chunk/vue.js +2 -0
  71. package/lib/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -0
  72. package/lib/front_end/third_party/codemirror.next/chunk/wast.js +2 -0
  73. package/lib/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -0
  74. package/lib/front_end/third_party/codemirror.next/chunk/xml.js +2 -0
  75. package/lib/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -0
  76. package/lib/front_end/third_party/codemirror.next/codemirror.next.d.ts +8057 -0
  77. package/lib/front_end/third_party/codemirror.next/codemirror.next.js +2 -0
  78. package/lib/front_end/third_party/codemirror.next/codemirror.next.js.map +1 -0
  79. package/lib/front_end/third_party/codemirror.next/package.json +43 -0
  80. package/lib/front_end/third_party/codemirror.next/rebuild.sh +6 -0
  81. package/lib/front_end/third_party/codemirror.next/rollup.config.mjs +49 -0
  82. package/lib/front_end/third_party/source-map-scopes-codec/LICENSE +26 -0
  83. package/lib/front_end/third_party/source-map-scopes-codec/README.chromium +31 -0
  84. package/lib/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +33 -0
  85. package/lib/front_end/third_party/source-map-scopes-codec/package/LICENSE +26 -0
  86. package/lib/front_end/third_party/source-map-scopes-codec/package/README.md +64 -0
  87. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +62 -0
  88. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -0
  89. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +37 -0
  90. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +1 -0
  91. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +29 -0
  92. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -0
  93. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +8 -0
  94. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +1 -0
  95. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +6 -0
  96. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +1 -0
  97. package/lib/front_end/third_party/source-map-scopes-codec/package/deno.json +21 -0
  98. package/lib/front_end/third_party/source-map-scopes-codec/package/package.json +14 -0
  99. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +196 -0
  100. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -0
  101. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +262 -0
  102. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +235 -0
  103. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +1 -0
  104. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +359 -0
  105. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js +39 -0
  106. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +1 -0
  107. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +53 -0
  108. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +438 -0
  109. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -0
  110. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +539 -0
  111. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +23 -0
  112. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +1 -0
  113. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +35 -0
  114. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +257 -0
  115. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -0
  116. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +348 -0
  117. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js +8 -0
  118. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +1 -0
  119. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +20 -0
  120. package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes-tsconfig.json +8 -0
  121. package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes.d.ts +184 -0
  122. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js +9 -0
  123. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +1 -0
  124. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.ts +12 -0
  125. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +82 -0
  126. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +1 -0
  127. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +99 -0
  128. package/lib/front_end/third_party/source-map-scopes-codec/source-map-scopes-codec.ts +5 -0
  129. package/lib/front_end/ui/legacy/theme_support/ThemeSupport.ts +222 -0
  130. package/lib/front_end/ui/legacy/theme_support/theme_support.ts +5 -0
  131. package/package.json +5 -5
  132. package/patches/chrome-devtools-frontend+1.0.1533544.patch +1549 -20
@@ -0,0 +1,141 @@
1
+ // Copyright 2012 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../core/common/common.js';
6
+ import type * as Platform from '../../core/platform/platform.js';
7
+ import * as SDK from '../../core/sdk/sdk.js';
8
+ import type * as TextUtils from '../text_utils/text_utils.js';
9
+ import * as Workspace from '../workspace/workspace.js';
10
+
11
+ import {ContentProviderBasedProject} from './ContentProviderBasedProject.js';
12
+ import type {DebuggerSourceMapping, DebuggerWorkspaceBinding} from './DebuggerWorkspaceBinding.js';
13
+
14
+ export class DefaultScriptMapping implements DebuggerSourceMapping {
15
+ readonly #debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
16
+ readonly #project: ContentProviderBasedProject;
17
+ readonly #eventListeners: Common.EventTarget.EventDescriptor[];
18
+ readonly #uiSourceCodeToScript: Map<Workspace.UISourceCode.UISourceCode, SDK.Script.Script>;
19
+ readonly #scriptToUISourceCode: Map<SDK.Script.Script, Workspace.UISourceCode.UISourceCode>;
20
+
21
+ constructor(
22
+ debuggerModel: SDK.DebuggerModel.DebuggerModel, workspace: Workspace.Workspace.WorkspaceImpl,
23
+ debuggerWorkspaceBinding: DebuggerWorkspaceBinding) {
24
+ defaultScriptMappings.add(this);
25
+ this.#debuggerWorkspaceBinding = debuggerWorkspaceBinding;
26
+ this.#project = new ContentProviderBasedProject(
27
+ workspace, 'debugger:' + debuggerModel.target().id(), Workspace.Workspace.projectTypes.Debugger, '',
28
+ true /* isServiceProject */);
29
+ this.#eventListeners = [
30
+ debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this.globalObjectCleared, this),
31
+ debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this.parsedScriptSource, this),
32
+ debuggerModel.addEventListener(
33
+ SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this.discardedScriptSource, this),
34
+ ];
35
+ this.#uiSourceCodeToScript = new Map();
36
+ this.#scriptToUISourceCode = new Map();
37
+ }
38
+
39
+ static createV8ScriptURL(script: SDK.Script.Script): Platform.DevToolsPath.UrlString {
40
+ const name = Common.ParsedURL.ParsedURL.extractName(script.sourceURL);
41
+ const url = 'debugger:///VM' + script.scriptId + (name ? ' ' + name : '') as Platform.DevToolsPath.UrlString;
42
+ return url;
43
+ }
44
+
45
+ static scriptForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Script.Script|null {
46
+ for (const defaultScriptMapping of defaultScriptMappings) {
47
+ const script = defaultScriptMapping.#uiSourceCodeToScript.get(uiSourceCode);
48
+ if (script !== undefined) {
49
+ return script;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+
55
+ uiSourceCodeForScript(script: SDK.Script.Script): Workspace.UISourceCode.UISourceCode|null {
56
+ return this.#scriptToUISourceCode.get(script) ?? null;
57
+ }
58
+
59
+ rawLocationToUILocation(rawLocation: SDK.DebuggerModel.Location): Workspace.UISourceCode.UILocation|null {
60
+ const script = rawLocation.script();
61
+ if (!script) {
62
+ return null;
63
+ }
64
+ const uiSourceCode = this.#scriptToUISourceCode.get(script);
65
+ if (!uiSourceCode) {
66
+ return null;
67
+ }
68
+ const {lineNumber, columnNumber} = script.rawLocationToRelativeLocation(rawLocation);
69
+ return uiSourceCode.uiLocation(lineNumber, columnNumber);
70
+ }
71
+
72
+ uiLocationToRawLocations(
73
+ uiSourceCode: Workspace.UISourceCode.UISourceCode, lineNumber: number,
74
+ columnNumber?: number): SDK.DebuggerModel.Location[] {
75
+ const script = this.#uiSourceCodeToScript.get(uiSourceCode);
76
+ if (!script) {
77
+ return [];
78
+ }
79
+ ({lineNumber, columnNumber} = script.relativeLocationToRawLocation({lineNumber, columnNumber}));
80
+ return [script.debuggerModel.createRawLocation(script, lineNumber, columnNumber ?? 0)];
81
+ }
82
+
83
+ uiLocationRangeToRawLocationRanges(
84
+ uiSourceCode: Workspace.UISourceCode.UISourceCode,
85
+ {startLine, startColumn, endLine, endColumn}: TextUtils.TextRange.TextRange):
86
+ SDK.DebuggerModel.LocationRange[]|null {
87
+ const script = this.#uiSourceCodeToScript.get(uiSourceCode);
88
+ if (!script) {
89
+ return [];
90
+ }
91
+ ({lineNumber: startLine, columnNumber: startColumn} =
92
+ script.relativeLocationToRawLocation({lineNumber: startLine, columnNumber: startColumn}));
93
+ ({lineNumber: endLine, columnNumber: endColumn} =
94
+ script.relativeLocationToRawLocation({lineNumber: endLine, columnNumber: endColumn}));
95
+ const start = script.debuggerModel.createRawLocation(script, startLine, startColumn);
96
+ const end = script.debuggerModel.createRawLocation(script, endLine, endColumn);
97
+ return [{start, end}];
98
+ }
99
+
100
+ private parsedScriptSource(event: Common.EventTarget.EventTargetEvent<SDK.Script.Script>): void {
101
+ const script = event.data;
102
+ const url = DefaultScriptMapping.createV8ScriptURL(script);
103
+
104
+ const uiSourceCode = this.#project.createUISourceCode(url, Common.ResourceType.resourceTypes.Script);
105
+ if (script.isBreakpointCondition) {
106
+ uiSourceCode.markAsUnconditionallyIgnoreListed();
107
+ }
108
+ this.#uiSourceCodeToScript.set(uiSourceCode, script);
109
+ this.#scriptToUISourceCode.set(script, uiSourceCode);
110
+ this.#project.addUISourceCodeWithProvider(uiSourceCode, script, null, 'text/javascript');
111
+ void this.#debuggerWorkspaceBinding.updateLocations(script);
112
+ }
113
+
114
+ private discardedScriptSource(event: Common.EventTarget.EventTargetEvent<SDK.Script.Script>): void {
115
+ const script = event.data;
116
+ const uiSourceCode = this.#scriptToUISourceCode.get(script);
117
+ if (uiSourceCode === undefined) {
118
+ return;
119
+ }
120
+ this.#scriptToUISourceCode.delete(script);
121
+ this.#uiSourceCodeToScript.delete(uiSourceCode);
122
+ this.#project.removeUISourceCode(uiSourceCode.url());
123
+ }
124
+
125
+ private globalObjectCleared(): void {
126
+ this.#scriptToUISourceCode.clear();
127
+ this.#uiSourceCodeToScript.clear();
128
+ this.#project.reset();
129
+ }
130
+
131
+ dispose(): void {
132
+ defaultScriptMappings.delete(this);
133
+ Common.EventTarget.removeEventListeners(this.#eventListeners);
134
+ this.globalObjectCleared();
135
+ this.#project.dispose();
136
+ }
137
+ }
138
+
139
+ // TODO(bmeurer): Remove the static methods from DefaultScriptMapping
140
+ // and get rid of this global table.
141
+ const defaultScriptMappings = new Set<DefaultScriptMapping>();
@@ -0,0 +1,228 @@
1
+ // Copyright 2012 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../core/common/common.js';
6
+ import type * as Platform from '../../core/platform/platform.js';
7
+ import * as TextUtils from '../text_utils/text_utils.js';
8
+ import * as Workspace from '../workspace/workspace.js';
9
+
10
+ export interface ChunkedReader {
11
+ fileSize(): number;
12
+
13
+ loadedSize(): number;
14
+
15
+ fileName(): string;
16
+
17
+ cancel(): void;
18
+
19
+ error(): DOMError|null;
20
+ }
21
+
22
+ export class ChunkedFileReader implements ChunkedReader {
23
+ #file: File|null;
24
+ readonly #fileSize: number;
25
+ #loadedSize: number;
26
+ #streamReader: ReadableStreamDefaultReader<Uint8Array<ArrayBuffer>>|null;
27
+ readonly #chunkSize: number;
28
+ readonly #chunkTransferredCallback: ((arg0: ChunkedReader) => void)|undefined;
29
+ readonly #decoder: TextDecoder;
30
+ #isCanceled: boolean;
31
+ #error: DOMException|null;
32
+ #transferFinished!: (arg0: boolean) => void;
33
+ #output?: Common.StringOutputStream.OutputStream;
34
+ #reader?: FileReader|null;
35
+
36
+ constructor(file: File, chunkSize?: number, chunkTransferredCallback?: ((arg0: ChunkedReader) => void)) {
37
+ this.#file = file;
38
+ this.#fileSize = file.size;
39
+ this.#loadedSize = 0;
40
+ this.#chunkSize = (chunkSize) ? chunkSize : Number.MAX_VALUE;
41
+ this.#chunkTransferredCallback = chunkTransferredCallback;
42
+ this.#decoder = new TextDecoder();
43
+ this.#isCanceled = false;
44
+ this.#error = null;
45
+ this.#streamReader = null;
46
+ }
47
+
48
+ async read(output: Common.StringOutputStream.OutputStream): Promise<boolean> {
49
+ if (this.#chunkTransferredCallback) {
50
+ this.#chunkTransferredCallback(this);
51
+ }
52
+
53
+ if (this.#file?.type.endsWith('gzip')) {
54
+ const fileStream = this.#file.stream();
55
+ const stream = Common.Gzip.decompressStream(fileStream);
56
+ this.#streamReader = stream.getReader();
57
+ } else {
58
+ this.#reader = new FileReader();
59
+ this.#reader.onload = this.onChunkLoaded.bind(this);
60
+ this.#reader.onerror = this.onError.bind(this);
61
+ }
62
+
63
+ this.#output = output;
64
+ void this.loadChunk();
65
+
66
+ return await new Promise(resolve => {
67
+ this.#transferFinished = resolve;
68
+ });
69
+ }
70
+
71
+ cancel(): void {
72
+ this.#isCanceled = true;
73
+ }
74
+
75
+ loadedSize(): number {
76
+ return this.#loadedSize;
77
+ }
78
+
79
+ fileSize(): number {
80
+ return this.#fileSize;
81
+ }
82
+
83
+ fileName(): string {
84
+ if (!this.#file) {
85
+ return '';
86
+ }
87
+ return this.#file.name;
88
+ }
89
+
90
+ error(): DOMException|null {
91
+ return this.#error;
92
+ }
93
+
94
+ private onChunkLoaded(event: Event): void {
95
+ if (this.#isCanceled) {
96
+ return;
97
+ }
98
+
99
+ const eventTarget = (event.target as FileReader);
100
+ if (eventTarget.readyState !== FileReader.DONE) {
101
+ return;
102
+ }
103
+
104
+ if (!this.#reader) {
105
+ return;
106
+ }
107
+
108
+ const buffer = (this.#reader.result as ArrayBuffer);
109
+ this.#loadedSize += buffer.byteLength;
110
+ const endOfFile = this.#loadedSize === this.#fileSize;
111
+ void this.decodeChunkBuffer(buffer, endOfFile);
112
+ }
113
+
114
+ private async decodeChunkBuffer(buffer: ArrayBuffer, endOfFile: boolean): Promise<void> {
115
+ if (!this.#output) {
116
+ return;
117
+ }
118
+ const decodedString = this.#decoder.decode(buffer, {stream: !endOfFile});
119
+ await this.#output.write(decodedString, endOfFile);
120
+ if (this.#isCanceled) {
121
+ return;
122
+ }
123
+ if (this.#chunkTransferredCallback) {
124
+ this.#chunkTransferredCallback(this);
125
+ }
126
+
127
+ if (endOfFile) {
128
+ void this.finishRead();
129
+ return;
130
+ }
131
+ void this.loadChunk();
132
+ }
133
+
134
+ private async finishRead(): Promise<void> {
135
+ if (!this.#output) {
136
+ return;
137
+ }
138
+ this.#file = null;
139
+ this.#reader = null;
140
+ await this.#output.close();
141
+ this.#transferFinished(!this.#error);
142
+ }
143
+
144
+ private async loadChunk(): Promise<void> {
145
+ if (!this.#output || !this.#file) {
146
+ return;
147
+ }
148
+ if (this.#streamReader) {
149
+ const {value, done} = await this.#streamReader.read();
150
+ if (done || !value) {
151
+ // Write empty string to inform of file end
152
+ await this.#output.write('', true);
153
+ return await this.finishRead();
154
+ }
155
+ void this.decodeChunkBuffer(value.buffer, false);
156
+ }
157
+ if (this.#reader) {
158
+ const chunkStart = this.#loadedSize;
159
+ const chunkEnd = Math.min(this.#fileSize, chunkStart + this.#chunkSize);
160
+ const nextPart = this.#file.slice(chunkStart, chunkEnd);
161
+ this.#reader.readAsArrayBuffer(nextPart);
162
+ }
163
+ }
164
+
165
+ private onError(event: Event): void {
166
+ const eventTarget = (event.target as FileReader);
167
+ this.#error = eventTarget.error;
168
+ this.#transferFinished(false);
169
+ }
170
+ }
171
+
172
+ export class FileOutputStream implements Common.StringOutputStream.OutputStream {
173
+ #writeCallbacks: Array<() => void>;
174
+ #fileName!: Platform.DevToolsPath.RawPathString|Platform.DevToolsPath.UrlString;
175
+ #closed?: boolean;
176
+ constructor() {
177
+ this.#writeCallbacks = [];
178
+ }
179
+
180
+ async open(fileName: Platform.DevToolsPath.RawPathString|Platform.DevToolsPath.UrlString): Promise<boolean> {
181
+ this.#closed = false;
182
+ this.#writeCallbacks = [];
183
+ this.#fileName = fileName;
184
+ const saveResponse = await Workspace.FileManager.FileManager.instance().save(
185
+ this.#fileName, TextUtils.ContentData.EMPTY_TEXT_CONTENT_DATA, /* forceSaveAs=*/ true);
186
+ if (saveResponse) {
187
+ Workspace.FileManager.FileManager.instance().addEventListener(
188
+ Workspace.FileManager.Events.APPENDED_TO_URL, this.onAppendDone, this);
189
+ }
190
+ return Boolean(saveResponse);
191
+ }
192
+
193
+ write(data: string): Promise<void> {
194
+ return new Promise(resolve => {
195
+ this.#writeCallbacks.push(resolve);
196
+ Workspace.FileManager.FileManager.instance().append(this.#fileName, data);
197
+ });
198
+ }
199
+
200
+ async close(): Promise<void> {
201
+ this.#closed = true;
202
+ if (this.#writeCallbacks.length) {
203
+ return;
204
+ }
205
+ Workspace.FileManager.FileManager.instance().removeEventListener(
206
+ Workspace.FileManager.Events.APPENDED_TO_URL, this.onAppendDone, this);
207
+ Workspace.FileManager.FileManager.instance().close(this.#fileName);
208
+ }
209
+
210
+ private onAppendDone(event: Common.EventTarget.EventTargetEvent<string>): void {
211
+ if (event.data !== this.#fileName) {
212
+ return;
213
+ }
214
+ const writeCallback = this.#writeCallbacks.shift();
215
+ if (writeCallback) {
216
+ writeCallback();
217
+ }
218
+ if (this.#writeCallbacks.length) {
219
+ return;
220
+ }
221
+ if (!this.#closed) {
222
+ return;
223
+ }
224
+ Workspace.FileManager.FileManager.instance().removeEventListener(
225
+ Workspace.FileManager.Events.APPENDED_TO_URL, this.onAppendDone, this);
226
+ Workspace.FileManager.FileManager.instance().close(this.#fileName);
227
+ }
228
+ }
@@ -0,0 +1,81 @@
1
+ // Copyright 2014 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type * as Workspace from '../workspace/workspace.js';
6
+
7
+ export interface LiveLocation {
8
+ update(): Promise<void>;
9
+ uiLocation(): Promise<Workspace.UISourceCode.UILocation|null>;
10
+ dispose(): void;
11
+ isDisposed(): boolean;
12
+ }
13
+
14
+ export class LiveLocationWithPool implements LiveLocation {
15
+ #updateDelegate: ((arg0: LiveLocation) => Promise<void>)|null;
16
+ readonly #locationPool: LiveLocationPool;
17
+ #updatePromise: Promise<void>|null;
18
+
19
+ constructor(updateDelegate: (arg0: LiveLocation) => Promise<void>, locationPool: LiveLocationPool) {
20
+ this.#updateDelegate = updateDelegate;
21
+ this.#locationPool = locationPool;
22
+ this.#locationPool.add(this);
23
+
24
+ this.#updatePromise = null;
25
+ }
26
+
27
+ async update(): Promise<void> {
28
+ if (!this.#updateDelegate) {
29
+ return;
30
+ }
31
+ // The following is a basic scheduling algorithm, guaranteeing that
32
+ // {#updateDelegate} is always run atomically. That is, we always
33
+ // wait for an update to finish before we trigger the next run.
34
+ if (this.#updatePromise) {
35
+ await this.#updatePromise.then(() => this.update());
36
+ } else {
37
+ this.#updatePromise = this.#updateDelegate(this);
38
+ await this.#updatePromise;
39
+ this.#updatePromise = null;
40
+ }
41
+ }
42
+
43
+ async uiLocation(): Promise<Workspace.UISourceCode.UILocation|null> {
44
+ throw new Error('Not implemented');
45
+ }
46
+
47
+ dispose(): void {
48
+ this.#locationPool.delete(this);
49
+ this.#updateDelegate = null;
50
+ }
51
+
52
+ isDisposed(): boolean {
53
+ return !this.#locationPool.has(this);
54
+ }
55
+ }
56
+
57
+ export class LiveLocationPool {
58
+ readonly #locations: Set<LiveLocation>;
59
+
60
+ constructor() {
61
+ this.#locations = new Set();
62
+ }
63
+
64
+ add(location: LiveLocation): void {
65
+ this.#locations.add(location);
66
+ }
67
+
68
+ delete(location: LiveLocation): void {
69
+ this.#locations.delete(location);
70
+ }
71
+
72
+ has(location: LiveLocation): boolean {
73
+ return this.#locations.has(location);
74
+ }
75
+
76
+ disposeAll(): void {
77
+ for (const location of this.#locations) {
78
+ location.dispose();
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,157 @@
1
+ // Copyright 2012 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Common from '../../core/common/common.js';
6
+ import * as SDK from '../../core/sdk/sdk.js';
7
+ import type * as Protocol from '../../generated/protocol.js';
8
+ import type * as Workspace from '../workspace/workspace.js';
9
+
10
+ const uiSourceCodeToAttributionMap = new WeakMap<Workspace.UISourceCode.UISourceCode, Map<Protocol.Page.FrameId, {
11
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame,
12
+ count: number,
13
+ }>>();
14
+ const projectToTargetMap = new WeakMap<Workspace.Workspace.Project, SDK.Target.Target>();
15
+
16
+ let networkProjectManagerInstance: NetworkProjectManager;
17
+
18
+ export class NetworkProjectManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
19
+ private constructor() {
20
+ super();
21
+ }
22
+
23
+ static instance({forceNew}: {
24
+ forceNew: boolean,
25
+ } = {forceNew: false}): NetworkProjectManager {
26
+ if (!networkProjectManagerInstance || forceNew) {
27
+ networkProjectManagerInstance = new NetworkProjectManager();
28
+ }
29
+
30
+ return networkProjectManagerInstance;
31
+ }
32
+ }
33
+
34
+ export const enum Events {
35
+ FRAME_ATTRIBUTION_ADDED = 'FrameAttributionAdded',
36
+ FRAME_ATTRIBUTION_REMOVED = 'FrameAttributionRemoved',
37
+ }
38
+
39
+ export interface FrameAttributionEvent {
40
+ uiSourceCode: Workspace.UISourceCode.UISourceCode;
41
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame;
42
+ }
43
+
44
+ export interface EventTypes {
45
+ [Events.FRAME_ATTRIBUTION_ADDED]: FrameAttributionEvent;
46
+ [Events.FRAME_ATTRIBUTION_REMOVED]: FrameAttributionEvent;
47
+ }
48
+
49
+ export class NetworkProject {
50
+ static resolveFrame(uiSourceCode: Workspace.UISourceCode.UISourceCode, frameId: Protocol.Page.FrameId):
51
+ SDK.ResourceTreeModel.ResourceTreeFrame|null {
52
+ const target = NetworkProject.targetForUISourceCode(uiSourceCode);
53
+ const resourceTreeModel = target?.model(SDK.ResourceTreeModel.ResourceTreeModel);
54
+ return resourceTreeModel ? resourceTreeModel.frameForId(frameId) : null;
55
+ }
56
+
57
+ static setInitialFrameAttribution(uiSourceCode: Workspace.UISourceCode.UISourceCode, frameId: Protocol.Page.FrameId):
58
+ void {
59
+ if (!frameId) {
60
+ return;
61
+ }
62
+ const frame = NetworkProject.resolveFrame(uiSourceCode, frameId);
63
+ if (!frame) {
64
+ return;
65
+ }
66
+ const attribution = new Map<Protocol.Page.FrameId, {
67
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame,
68
+ count: number,
69
+ }>();
70
+ attribution.set(frameId, {frame, count: 1});
71
+ uiSourceCodeToAttributionMap.set(uiSourceCode, attribution);
72
+ }
73
+
74
+ static cloneInitialFrameAttribution(
75
+ fromUISourceCode: Workspace.UISourceCode.UISourceCode,
76
+ toUISourceCode: Workspace.UISourceCode.UISourceCode): void {
77
+ const fromAttribution = uiSourceCodeToAttributionMap.get(fromUISourceCode);
78
+ if (!fromAttribution) {
79
+ return;
80
+ }
81
+ const toAttribution = new Map<Protocol.Page.FrameId, {
82
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame,
83
+ count: number,
84
+ }>();
85
+ for (const frameId of fromAttribution.keys()) {
86
+ const value = fromAttribution.get(frameId);
87
+ if (typeof value !== 'undefined') {
88
+ toAttribution.set(frameId, {frame: value.frame, count: value.count});
89
+ }
90
+ }
91
+ uiSourceCodeToAttributionMap.set(toUISourceCode, toAttribution);
92
+ }
93
+
94
+ static addFrameAttribution(uiSourceCode: Workspace.UISourceCode.UISourceCode, frameId: Protocol.Page.FrameId): void {
95
+ const frame = NetworkProject.resolveFrame(uiSourceCode, frameId);
96
+ if (!frame) {
97
+ return;
98
+ }
99
+ const frameAttribution = uiSourceCodeToAttributionMap.get(uiSourceCode);
100
+ if (!frameAttribution) {
101
+ return;
102
+ }
103
+ const attributionInfo = frameAttribution.get(frameId) || {frame, count: 0};
104
+ attributionInfo.count += 1;
105
+ frameAttribution.set(frameId, attributionInfo);
106
+ if (attributionInfo.count !== 1) {
107
+ return;
108
+ }
109
+
110
+ const data = {uiSourceCode, frame};
111
+ NetworkProjectManager.instance().dispatchEventToListeners(Events.FRAME_ATTRIBUTION_ADDED, data);
112
+ }
113
+
114
+ static removeFrameAttribution(uiSourceCode: Workspace.UISourceCode.UISourceCode, frameId: Protocol.Page.FrameId):
115
+ void {
116
+ const frameAttribution = uiSourceCodeToAttributionMap.get(uiSourceCode);
117
+ if (!frameAttribution) {
118
+ return;
119
+ }
120
+ const attributionInfo = frameAttribution.get(frameId);
121
+ console.assert(Boolean(attributionInfo), 'Failed to remove frame attribution for url: ' + uiSourceCode.url());
122
+ if (!attributionInfo) {
123
+ return;
124
+ }
125
+ attributionInfo.count -= 1;
126
+ if (attributionInfo.count > 0) {
127
+ return;
128
+ }
129
+ frameAttribution.delete(frameId);
130
+ const data = {uiSourceCode, frame: attributionInfo.frame};
131
+ NetworkProjectManager.instance().dispatchEventToListeners(Events.FRAME_ATTRIBUTION_REMOVED, data);
132
+ }
133
+
134
+ static targetForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Target.Target|null {
135
+ return projectToTargetMap.get(uiSourceCode.project()) || null;
136
+ }
137
+
138
+ static setTargetForProject(project: Workspace.Workspace.Project, target: SDK.Target.Target): void {
139
+ projectToTargetMap.set(project, target);
140
+ }
141
+
142
+ static getTargetForProject(project: Workspace.Workspace.Project): SDK.Target.Target|null {
143
+ return projectToTargetMap.get(project) || null;
144
+ }
145
+
146
+ static framesForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
147
+ SDK.ResourceTreeModel.ResourceTreeFrame[] {
148
+ const target = NetworkProject.targetForUISourceCode(uiSourceCode);
149
+ const resourceTreeModel = target?.model(SDK.ResourceTreeModel.ResourceTreeModel);
150
+ const attribution = uiSourceCodeToAttributionMap.get(uiSourceCode);
151
+ if (!resourceTreeModel || !attribution) {
152
+ return [];
153
+ }
154
+ const frames = Array.from(attribution.keys()).map(frameId => resourceTreeModel.frameForId(frameId));
155
+ return frames.filter(frame => !!frame);
156
+ }
157
+ }