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,222 @@
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 Protocol from '../../generated/protocol.js';
9
+ import * as TextUtils from '../text_utils/text_utils.js';
10
+ import * as Workspace from '../workspace/workspace.js';
11
+
12
+ import {ContentProviderBasedProject} from './ContentProviderBasedProject.js';
13
+ import {CSSWorkspaceBinding, type SourceMapping} from './CSSWorkspaceBinding.js';
14
+ import {NetworkProject} from './NetworkProject.js';
15
+
16
+ export class SASSSourceMapping implements SourceMapping {
17
+ readonly #sourceMapManager: SDK.SourceMapManager.SourceMapManager<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>;
18
+ readonly #project: ContentProviderBasedProject;
19
+ readonly #eventListeners: Common.EventTarget.EventDescriptor[];
20
+ readonly #bindings: Map<string, Binding>;
21
+
22
+ constructor(
23
+ target: SDK.Target.Target,
24
+ sourceMapManager: SDK.SourceMapManager.SourceMapManager<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>,
25
+ workspace: Workspace.Workspace.WorkspaceImpl) {
26
+ this.#sourceMapManager = sourceMapManager;
27
+ this.#project = new ContentProviderBasedProject(
28
+ workspace, 'cssSourceMaps:' + target.id(), Workspace.Workspace.projectTypes.Network, '',
29
+ false /* isServiceProject */);
30
+ NetworkProject.setTargetForProject(this.#project, target);
31
+
32
+ this.#bindings = new Map();
33
+
34
+ this.#eventListeners = [
35
+ this.#sourceMapManager.addEventListener(
36
+ SDK.SourceMapManager.Events.SourceMapAttached, this.sourceMapAttached, this),
37
+ this.#sourceMapManager.addEventListener(
38
+ SDK.SourceMapManager.Events.SourceMapDetached, this.sourceMapDetached, this),
39
+ ];
40
+ }
41
+
42
+ private sourceMapAttachedForTest(_sourceMap: SDK.SourceMap.SourceMap|null): void {
43
+ }
44
+
45
+ private async sourceMapAttached(
46
+ event: Common.EventTarget
47
+ .EventTargetEvent<{client: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader, sourceMap: SDK.SourceMap.SourceMap}>):
48
+ Promise<void> {
49
+ const header = event.data.client;
50
+ const sourceMap = event.data.sourceMap;
51
+ const project = this.#project;
52
+ const bindings = this.#bindings;
53
+ for (const sourceURL of sourceMap.sourceURLs()) {
54
+ let binding = bindings.get(sourceURL);
55
+ if (!binding) {
56
+ binding = new Binding(project, sourceURL, header.createPageResourceLoadInitiator());
57
+ bindings.set(sourceURL, binding);
58
+ }
59
+ binding.addSourceMap(sourceMap, header.frameId);
60
+ }
61
+ await CSSWorkspaceBinding.instance().updateLocations(header);
62
+ this.sourceMapAttachedForTest(sourceMap);
63
+ }
64
+
65
+ private async sourceMapDetached(
66
+ event: Common.EventTarget
67
+ .EventTargetEvent<{client: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader, sourceMap: SDK.SourceMap.SourceMap}>):
68
+ Promise<void> {
69
+ const header = event.data.client;
70
+ const sourceMap = event.data.sourceMap;
71
+ const bindings = this.#bindings;
72
+ for (const sourceURL of sourceMap.sourceURLs()) {
73
+ const binding = bindings.get(sourceURL);
74
+ if (binding) {
75
+ binding.removeSourceMap(sourceMap, header.frameId);
76
+ if (!binding.getUiSourceCode()) {
77
+ bindings.delete(sourceURL);
78
+ }
79
+ }
80
+ }
81
+ await CSSWorkspaceBinding.instance().updateLocations(header);
82
+ }
83
+
84
+ rawLocationToUILocation(rawLocation: SDK.CSSModel.CSSLocation): Workspace.UISourceCode.UILocation|null {
85
+ const header = rawLocation.header();
86
+ if (!header) {
87
+ return null;
88
+ }
89
+ const sourceMap = this.#sourceMapManager.sourceMapForClient(header);
90
+ if (!sourceMap) {
91
+ return null;
92
+ }
93
+ let {lineNumber, columnNumber} = rawLocation;
94
+ // If the source map maps the origin (line:0, column:0) but the CSS header is inline (in a HTML doc),
95
+ // then adjust the line and column numbers.
96
+ if (sourceMap.mapsOrigin() && header.isInline) {
97
+ lineNumber -= header.startLine;
98
+ if (lineNumber === 0) {
99
+ columnNumber -= header.startColumn;
100
+ }
101
+ }
102
+ const entry = sourceMap.findEntry(lineNumber, columnNumber);
103
+ if (!entry?.sourceURL) {
104
+ return null;
105
+ }
106
+ const uiSourceCode = this.#project.uiSourceCodeForURL(entry.sourceURL);
107
+ if (!uiSourceCode) {
108
+ return null;
109
+ }
110
+ return uiSourceCode.uiLocation(entry.sourceLineNumber, entry.sourceColumnNumber);
111
+ }
112
+
113
+ uiLocationToRawLocations(uiLocation: Workspace.UISourceCode.UILocation): SDK.CSSModel.CSSLocation[] {
114
+ // TODO(crbug.com/1153123): Revisit the `#columnNumber || 0` and also preserve `undefined` for source maps?
115
+ const {uiSourceCode, lineNumber, columnNumber = 0} = uiLocation;
116
+ const binding = uiSourceCodeToBinding.get(uiSourceCode);
117
+ if (!binding) {
118
+ return [];
119
+ }
120
+ const locations: SDK.CSSModel.CSSLocation[] = [];
121
+ for (const sourceMap of binding.getReferringSourceMaps()) {
122
+ const entries = sourceMap.findReverseEntries(uiSourceCode.url(), lineNumber, columnNumber);
123
+ const header = this.#sourceMapManager.clientForSourceMap(sourceMap);
124
+ if (header) {
125
+ locations.push(
126
+ ...entries.map(entry => new SDK.CSSModel.CSSLocation(header, entry.lineNumber, entry.columnNumber)));
127
+ }
128
+ }
129
+ return locations;
130
+ }
131
+
132
+ static uiSourceOrigin(uiSourceCode: Workspace.UISourceCode.UISourceCode): Platform.DevToolsPath.UrlString[] {
133
+ const binding = uiSourceCodeToBinding.get(uiSourceCode);
134
+ if (binding) {
135
+ return binding.getReferringSourceMaps().map(sourceMap => sourceMap.compiledURL());
136
+ }
137
+ return [];
138
+ }
139
+
140
+ dispose(): void {
141
+ Common.EventTarget.removeEventListeners(this.#eventListeners);
142
+ this.#project.dispose();
143
+ }
144
+ }
145
+
146
+ const uiSourceCodeToBinding = new WeakMap<Workspace.UISourceCode.UISourceCode, Binding>();
147
+
148
+ class Binding {
149
+ readonly #project: ContentProviderBasedProject;
150
+ readonly #url: Platform.DevToolsPath.UrlString;
151
+ readonly #initiator: SDK.PageResourceLoader.PageResourceLoadInitiator;
152
+ referringSourceMaps: SDK.SourceMap.SourceMap[];
153
+ uiSourceCode: Workspace.UISourceCode.UISourceCode|null;
154
+
155
+ constructor(
156
+ project: ContentProviderBasedProject, url: Platform.DevToolsPath.UrlString,
157
+ initiator: SDK.PageResourceLoader.PageResourceLoadInitiator) {
158
+ this.#project = project;
159
+ this.#url = url;
160
+ this.#initiator = initiator;
161
+
162
+ this.referringSourceMaps = [];
163
+ this.uiSourceCode = null;
164
+ }
165
+
166
+ private recreateUISourceCodeIfNeeded(frameId: Protocol.Page.FrameId): void {
167
+ const sourceMap = this.referringSourceMaps[this.referringSourceMaps.length - 1];
168
+
169
+ const contentType = Common.ResourceType.resourceTypes.SourceMapStyleSheet;
170
+ const embeddedContent = sourceMap.embeddedContentByURL(this.#url);
171
+ const contentProvider = embeddedContent !== null ?
172
+ TextUtils.StaticContentProvider.StaticContentProvider.fromString(this.#url, contentType, embeddedContent) :
173
+ new SDK.CompilerSourceMappingContentProvider.CompilerSourceMappingContentProvider(
174
+ this.#url, contentType, this.#initiator);
175
+ const newUISourceCode = this.#project.createUISourceCode(this.#url, contentType);
176
+ uiSourceCodeToBinding.set(newUISourceCode, this);
177
+ const mimeType = Common.ResourceType.ResourceType.mimeFromURL(this.#url) || contentType.canonicalMimeType();
178
+ const metadata = typeof embeddedContent === 'string' ?
179
+ new Workspace.UISourceCode.UISourceCodeMetadata(null, embeddedContent.length) :
180
+ null;
181
+
182
+ if (this.uiSourceCode) {
183
+ NetworkProject.cloneInitialFrameAttribution(this.uiSourceCode, newUISourceCode);
184
+ this.#project.removeUISourceCode(this.uiSourceCode.url());
185
+ } else {
186
+ NetworkProject.setInitialFrameAttribution(newUISourceCode, frameId);
187
+ }
188
+ this.uiSourceCode = newUISourceCode;
189
+ this.#project.addUISourceCodeWithProvider(this.uiSourceCode, contentProvider, metadata, mimeType);
190
+ }
191
+
192
+ addSourceMap(sourceMap: SDK.SourceMap.SourceMap, frameId: Protocol.Page.FrameId): void {
193
+ if (this.uiSourceCode) {
194
+ NetworkProject.addFrameAttribution(this.uiSourceCode, frameId);
195
+ }
196
+ this.referringSourceMaps.push(sourceMap);
197
+ this.recreateUISourceCodeIfNeeded(frameId);
198
+ }
199
+
200
+ removeSourceMap(sourceMap: SDK.SourceMap.SourceMap, frameId: Protocol.Page.FrameId): void {
201
+ const uiSourceCode = (this.uiSourceCode as Workspace.UISourceCode.UISourceCode);
202
+ NetworkProject.removeFrameAttribution(uiSourceCode, frameId);
203
+ const lastIndex = this.referringSourceMaps.lastIndexOf(sourceMap);
204
+ if (lastIndex !== -1) {
205
+ this.referringSourceMaps.splice(lastIndex, 1);
206
+ }
207
+ if (!this.referringSourceMaps.length) {
208
+ this.#project.removeUISourceCode(uiSourceCode.url());
209
+ this.uiSourceCode = null;
210
+ } else {
211
+ this.recreateUISourceCodeIfNeeded(frameId);
212
+ }
213
+ }
214
+
215
+ getReferringSourceMaps(): SDK.SourceMap.SourceMap[] {
216
+ return this.referringSourceMaps;
217
+ }
218
+
219
+ getUiSourceCode(): Workspace.UISourceCode.UISourceCode|null {
220
+ return this.uiSourceCode;
221
+ }
222
+ }
@@ -0,0 +1,316 @@
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 * 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 {SourceMapping} from './CSSWorkspaceBinding.js';
13
+ import {NetworkProject} from './NetworkProject.js';
14
+ import {metadataForURL} from './ResourceUtils.js';
15
+
16
+ const uiSourceCodeToStyleMap = new WeakMap<Workspace.UISourceCode.UISourceCode, StyleFile>();
17
+
18
+ export class StylesSourceMapping implements SourceMapping {
19
+ #cssModel: SDK.CSSModel.CSSModel;
20
+ #project: ContentProviderBasedProject;
21
+ readonly #styleFiles = new Map<string, StyleFile>();
22
+ readonly #eventListeners: Common.EventTarget.EventDescriptor[];
23
+
24
+ constructor(cssModel: SDK.CSSModel.CSSModel, workspace: Workspace.Workspace.WorkspaceImpl) {
25
+ this.#cssModel = cssModel;
26
+ const target = this.#cssModel.target();
27
+ this.#project = new ContentProviderBasedProject(
28
+ workspace, 'css:' + target.id(), Workspace.Workspace.projectTypes.Network, '', false /* isServiceProject */);
29
+ NetworkProject.setTargetForProject(this.#project, target);
30
+
31
+ this.#eventListeners = [
32
+ this.#cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this.styleSheetAdded, this),
33
+ this.#cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this.styleSheetRemoved, this),
34
+ this.#cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this.styleSheetChanged, this),
35
+ ];
36
+ }
37
+
38
+ addSourceMap(sourceUrl: Platform.DevToolsPath.UrlString, sourceMapUrl: Platform.DevToolsPath.UrlString): void {
39
+ this.#styleFiles.get(sourceUrl)?.addSourceMap(sourceUrl, sourceMapUrl);
40
+ }
41
+
42
+ rawLocationToUILocation(rawLocation: SDK.CSSModel.CSSLocation): Workspace.UISourceCode.UILocation|null {
43
+ const header = rawLocation.header();
44
+ if (!header || !this.acceptsHeader(header)) {
45
+ return null;
46
+ }
47
+ const styleFile = this.#styleFiles.get(header.resourceURL());
48
+ if (!styleFile) {
49
+ return null;
50
+ }
51
+ let lineNumber = rawLocation.lineNumber;
52
+ let columnNumber: undefined|number = rawLocation.columnNumber;
53
+ if (header.isInline && header.hasSourceURL) {
54
+ lineNumber -= header.lineNumberInSource(0);
55
+ const headerColumnNumber = header.columnNumberInSource(lineNumber, 0);
56
+ if (typeof headerColumnNumber === 'undefined') {
57
+ columnNumber = headerColumnNumber;
58
+ } else {
59
+ columnNumber -= headerColumnNumber;
60
+ }
61
+ }
62
+ return styleFile.getUiSourceCode().uiLocation(lineNumber, columnNumber);
63
+ }
64
+
65
+ uiLocationToRawLocations(uiLocation: Workspace.UISourceCode.UILocation): SDK.CSSModel.CSSLocation[] {
66
+ const styleFile = uiSourceCodeToStyleMap.get(uiLocation.uiSourceCode);
67
+ if (!styleFile) {
68
+ return [];
69
+ }
70
+ const rawLocations = [];
71
+ for (const header of styleFile.getHeaders()) {
72
+ let lineNumber = uiLocation.lineNumber;
73
+ let columnNumber = uiLocation.columnNumber;
74
+ if (header.isInline && header.hasSourceURL) {
75
+ // TODO(crbug.com/1153123): Revisit the `#columnNumber || 0` and also preserve `undefined` for source maps?
76
+ columnNumber = header.columnNumberInSource(lineNumber, uiLocation.columnNumber || 0);
77
+ lineNumber = header.lineNumberInSource(lineNumber);
78
+ }
79
+ rawLocations.push(new SDK.CSSModel.CSSLocation(header, lineNumber, columnNumber));
80
+ }
81
+ return rawLocations;
82
+ }
83
+
84
+ private acceptsHeader(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader): boolean {
85
+ if (header.isConstructedByNew()) {
86
+ return false;
87
+ }
88
+ if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector') {
89
+ return false;
90
+ }
91
+ if (!header.resourceURL()) {
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+
97
+ private styleSheetAdded(event: Common.EventTarget.EventTargetEvent<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>):
98
+ void {
99
+ const header = event.data;
100
+ if (!this.acceptsHeader(header)) {
101
+ return;
102
+ }
103
+
104
+ const url = header.resourceURL();
105
+ let styleFile = this.#styleFiles.get(url);
106
+ if (!styleFile) {
107
+ styleFile = new StyleFile(this.#cssModel, this.#project, header);
108
+ this.#styleFiles.set(url, styleFile);
109
+ } else {
110
+ styleFile.addHeader(header);
111
+ }
112
+ }
113
+
114
+ private styleSheetRemoved(event: Common.EventTarget.EventTargetEvent<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>):
115
+ void {
116
+ const header = event.data;
117
+ if (!this.acceptsHeader(header)) {
118
+ return;
119
+ }
120
+ const url = header.resourceURL();
121
+ const styleFile = this.#styleFiles.get(url);
122
+ if (styleFile) {
123
+ if (styleFile.getHeaders().size === 1) {
124
+ styleFile.dispose();
125
+ this.#styleFiles.delete(url);
126
+ } else {
127
+ styleFile.removeHeader(header);
128
+ }
129
+ }
130
+ }
131
+
132
+ private styleSheetChanged(event: Common.EventTarget.EventTargetEvent<SDK.CSSModel.StyleSheetChangedEvent>): void {
133
+ const header = this.#cssModel.styleSheetHeaderForId(event.data.styleSheetId);
134
+ if (!header || !this.acceptsHeader(header)) {
135
+ return;
136
+ }
137
+ const styleFile = this.#styleFiles.get(header.resourceURL());
138
+ if (styleFile) {
139
+ styleFile.styleSheetChanged(header);
140
+ }
141
+ }
142
+
143
+ dispose(): void {
144
+ for (const styleFile of this.#styleFiles.values()) {
145
+ styleFile.dispose();
146
+ }
147
+ this.#styleFiles.clear();
148
+ Common.EventTarget.removeEventListeners(this.#eventListeners);
149
+ this.#project.removeProject();
150
+ }
151
+ }
152
+
153
+ export class StyleFile implements TextUtils.ContentProvider.ContentProvider {
154
+ readonly #cssModel: SDK.CSSModel.CSSModel;
155
+ readonly #project: ContentProviderBasedProject;
156
+ headers: Set<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader>;
157
+ uiSourceCode: Workspace.UISourceCode.UISourceCode;
158
+ readonly #eventListeners: Common.EventTarget.EventDescriptor[];
159
+ readonly #throttler = new Common.Throttler.Throttler(200);
160
+ #terminated = false;
161
+ #isAddingRevision?: boolean;
162
+ #isUpdatingHeaders?: boolean;
163
+
164
+ constructor(
165
+ cssModel: SDK.CSSModel.CSSModel, project: ContentProviderBasedProject,
166
+ header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader) {
167
+ this.#cssModel = cssModel;
168
+ this.#project = project;
169
+ this.headers = new Set([header]);
170
+
171
+ const target = cssModel.target();
172
+
173
+ const url = header.resourceURL();
174
+ const metadata = metadataForURL(target, header.frameId, url);
175
+
176
+ this.uiSourceCode = this.#project.createUISourceCode(url, header.contentType());
177
+ uiSourceCodeToStyleMap.set(this.uiSourceCode, this);
178
+ NetworkProject.setInitialFrameAttribution(this.uiSourceCode, header.frameId);
179
+ this.#project.addUISourceCodeWithProvider(this.uiSourceCode, this, metadata, 'text/css');
180
+
181
+ this.#eventListeners = [
182
+ this.uiSourceCode.addEventListener(
183
+ Workspace.UISourceCode.Events.WorkingCopyChanged, this.workingCopyChanged, this),
184
+ this.uiSourceCode.addEventListener(
185
+ Workspace.UISourceCode.Events.WorkingCopyCommitted, this.workingCopyCommitted, this),
186
+ ];
187
+ }
188
+
189
+ addHeader(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader): void {
190
+ this.headers.add(header);
191
+ NetworkProject.addFrameAttribution(this.uiSourceCode, header.frameId);
192
+ }
193
+
194
+ removeHeader(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader): void {
195
+ this.headers.delete(header);
196
+ NetworkProject.removeFrameAttribution(this.uiSourceCode, header.frameId);
197
+ }
198
+
199
+ styleSheetChanged(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader): void {
200
+ console.assert(this.headers.has(header));
201
+ if (this.#isUpdatingHeaders || !this.headers.has(header)) {
202
+ return;
203
+ }
204
+ const mirrorContentBound = this.mirrorContent.bind(this, header, true /* majorChange */);
205
+ void this.#throttler.schedule(mirrorContentBound, Common.Throttler.Scheduling.DEFAULT);
206
+ }
207
+
208
+ private workingCopyCommitted(): void {
209
+ if (this.#isAddingRevision) {
210
+ return;
211
+ }
212
+ const mirrorContentBound = this.mirrorContent.bind(this, this.uiSourceCode, true /* majorChange */);
213
+ void this.#throttler.schedule(mirrorContentBound, Common.Throttler.Scheduling.AS_SOON_AS_POSSIBLE);
214
+ }
215
+
216
+ private workingCopyChanged(): void {
217
+ if (this.#isAddingRevision) {
218
+ return;
219
+ }
220
+ const mirrorContentBound = this.mirrorContent.bind(this, this.uiSourceCode, false /* majorChange */);
221
+ void this.#throttler.schedule(mirrorContentBound, Common.Throttler.Scheduling.DEFAULT);
222
+ }
223
+
224
+ private async mirrorContent(fromProvider: TextUtils.ContentProvider.ContentProvider, majorChange: boolean):
225
+ Promise<void> {
226
+ if (this.#terminated) {
227
+ this.styleFileSyncedForTest();
228
+ return;
229
+ }
230
+
231
+ let newContent: string|null = null;
232
+ if (fromProvider === this.uiSourceCode) {
233
+ newContent = this.uiSourceCode.workingCopy();
234
+ } else {
235
+ newContent = TextUtils.ContentData.ContentData.textOr(await fromProvider.requestContentData(), null);
236
+ }
237
+
238
+ if (newContent === null || this.#terminated) {
239
+ this.styleFileSyncedForTest();
240
+ return;
241
+ }
242
+
243
+ if (fromProvider !== this.uiSourceCode) {
244
+ this.#isAddingRevision = true;
245
+ this.uiSourceCode.setWorkingCopy(newContent);
246
+ this.#isAddingRevision = false;
247
+ }
248
+
249
+ this.#isUpdatingHeaders = true;
250
+ const promises = [];
251
+ for (const header of this.headers) {
252
+ if (header === fromProvider) {
253
+ continue;
254
+ }
255
+ promises.push(this.#cssModel.setStyleSheetText(header.id, newContent, majorChange));
256
+ }
257
+ // ------ ASYNC ------
258
+ await Promise.all(promises);
259
+ this.#isUpdatingHeaders = false;
260
+ this.styleFileSyncedForTest();
261
+ }
262
+
263
+ private styleFileSyncedForTest(): void {
264
+ }
265
+
266
+ dispose(): void {
267
+ if (this.#terminated) {
268
+ return;
269
+ }
270
+ this.#terminated = true;
271
+ this.#project.removeUISourceCode(this.uiSourceCode.url());
272
+ Common.EventTarget.removeEventListeners(this.#eventListeners);
273
+ }
274
+
275
+ contentURL(): Platform.DevToolsPath.UrlString {
276
+ console.assert(this.headers.size > 0);
277
+ return this.#firstHeader().originalContentProvider().contentURL();
278
+ }
279
+
280
+ contentType(): Common.ResourceType.ResourceType {
281
+ console.assert(this.headers.size > 0);
282
+ return this.#firstHeader().originalContentProvider().contentType();
283
+ }
284
+
285
+ requestContentData(): Promise<TextUtils.ContentData.ContentDataOrError> {
286
+ console.assert(this.headers.size > 0);
287
+ return this.#firstHeader().originalContentProvider().requestContentData();
288
+ }
289
+
290
+ searchInContent(query: string, caseSensitive: boolean, isRegex: boolean):
291
+ Promise<TextUtils.ContentProvider.SearchMatch[]> {
292
+ console.assert(this.headers.size > 0);
293
+ return this.#firstHeader().originalContentProvider().searchInContent(query, caseSensitive, isRegex);
294
+ }
295
+
296
+ #firstHeader(): SDK.CSSStyleSheetHeader.CSSStyleSheetHeader {
297
+ console.assert(this.headers.size > 0);
298
+ return this.headers.values().next().value as SDK.CSSStyleSheetHeader.CSSStyleSheetHeader;
299
+ }
300
+
301
+ getHeaders(): Set<SDK.CSSStyleSheetHeader.CSSStyleSheetHeader> {
302
+ return this.headers;
303
+ }
304
+
305
+ getUiSourceCode(): Workspace.UISourceCode.UISourceCode {
306
+ return this.uiSourceCode;
307
+ }
308
+
309
+ addSourceMap(sourceUrl: Platform.DevToolsPath.UrlString, sourceMapUrl: Platform.DevToolsPath.UrlString): void {
310
+ const sourceMapManager = this.#cssModel.sourceMapManager();
311
+ this.headers.forEach(header => {
312
+ sourceMapManager.detachSourceMap(header);
313
+ sourceMapManager.attachSourceMap(header, sourceUrl, sourceMapUrl);
314
+ });
315
+ }
316
+ }
@@ -0,0 +1,67 @@
1
+ // Copyright 2013 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
+
7
+ import {ChunkedFileReader, type ChunkedReader} from './FileUtils.js';
8
+
9
+ export class TempFile {
10
+ #lastBlob: Blob|null;
11
+ constructor() {
12
+ this.#lastBlob = null;
13
+ }
14
+
15
+ write(pieces: Array<string|Blob>): void {
16
+ if (this.#lastBlob) {
17
+ pieces.unshift(this.#lastBlob);
18
+ }
19
+ this.#lastBlob = new Blob(pieces, {type: 'text/plain'});
20
+ }
21
+
22
+ read(): Promise<string|null> {
23
+ return this.readRange();
24
+ }
25
+
26
+ size(): number {
27
+ return this.#lastBlob ? this.#lastBlob.size : 0;
28
+ }
29
+
30
+ async readRange(startOffset?: number, endOffset?: number): Promise<string|null> {
31
+ if (!this.#lastBlob) {
32
+ Common.Console.Console.instance().error('Attempt to read a temp file that was never written');
33
+ return '';
34
+ }
35
+ const blob = typeof startOffset === 'number' || typeof endOffset === 'number' ?
36
+ this.#lastBlob.slice((startOffset as number), (endOffset as number)) :
37
+ this.#lastBlob;
38
+
39
+ const reader = new FileReader();
40
+ try {
41
+ await new Promise((resolve, reject) => {
42
+ reader.onloadend = resolve;
43
+ reader.onerror = reject;
44
+ reader.readAsText(blob);
45
+ });
46
+ } catch (error) {
47
+ Common.Console.Console.instance().error('Failed to read from temp file: ' + error.message);
48
+ }
49
+
50
+ return reader.result as string | null;
51
+ }
52
+
53
+ async copyToOutputStream(
54
+ outputStream: Common.StringOutputStream.OutputStream,
55
+ progress?: ((arg0: ChunkedReader) => void)): Promise<DOMError|null> {
56
+ if (!this.#lastBlob) {
57
+ void outputStream.close();
58
+ return null;
59
+ }
60
+ const reader = new ChunkedFileReader((this.#lastBlob as File), 10 * 1000 * 1000, progress);
61
+ return await reader.read(outputStream).then(success => success ? null : reader.error());
62
+ }
63
+
64
+ remove(): void {
65
+ this.#lastBlob = null;
66
+ }
67
+ }
@@ -0,0 +1,39 @@
1
+ // Copyright 2019 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 CompilerScriptMapping from './CompilerScriptMapping.js';
6
+ import * as ContentProviderBasedProject from './ContentProviderBasedProject.js';
7
+ import * as CSSWorkspaceBinding from './CSSWorkspaceBinding.js';
8
+ import * as DebuggerLanguagePlugins from './DebuggerLanguagePlugins.js';
9
+ import * as DebuggerWorkspaceBinding from './DebuggerWorkspaceBinding.js';
10
+ import * as DefaultScriptMapping from './DefaultScriptMapping.js';
11
+ import * as FileUtils from './FileUtils.js';
12
+ import * as LiveLocation from './LiveLocation.js';
13
+ import * as NetworkProject from './NetworkProject.js';
14
+ import * as PresentationConsoleMessageHelper from './PresentationConsoleMessageHelper.js';
15
+ import * as ResourceMapping from './ResourceMapping.js';
16
+ import * as ResourceScriptMapping from './ResourceScriptMapping.js';
17
+ import * as ResourceUtils from './ResourceUtils.js';
18
+ import * as SASSSourceMapping from './SASSSourceMapping.js';
19
+ import * as StylesSourceMapping from './StylesSourceMapping.js';
20
+ import * as TempFile from './TempFile.js';
21
+
22
+ export {
23
+ CompilerScriptMapping,
24
+ ContentProviderBasedProject,
25
+ CSSWorkspaceBinding,
26
+ DebuggerLanguagePlugins,
27
+ DebuggerWorkspaceBinding,
28
+ DefaultScriptMapping,
29
+ FileUtils,
30
+ LiveLocation,
31
+ NetworkProject,
32
+ PresentationConsoleMessageHelper,
33
+ ResourceMapping,
34
+ ResourceScriptMapping,
35
+ ResourceUtils,
36
+ SASSSourceMapping,
37
+ StylesSourceMapping,
38
+ TempFile,
39
+ };