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.
Files changed (133) hide show
  1. package/README.md +4 -0
  2. package/generate.ts +32 -26
  3. package/index.ts +2 -1
  4. package/lib/extension-api/ExtensionAPI.d.ts +357 -0
  5. package/lib/front_end/models/bindings/CSSWorkspaceBinding.ts +318 -0
  6. package/lib/front_end/models/bindings/CompilerScriptMapping.ts +536 -0
  7. package/lib/front_end/models/bindings/ContentProviderBasedProject.ts +187 -0
  8. package/lib/front_end/models/bindings/DebuggerLanguagePlugins.ts +1197 -0
  9. package/lib/front_end/models/bindings/DebuggerWorkspaceBinding.ts +733 -0
  10. package/lib/front_end/models/bindings/DefaultScriptMapping.ts +141 -0
  11. package/lib/front_end/models/bindings/FileUtils.ts +228 -0
  12. package/lib/front_end/models/bindings/LiveLocation.ts +81 -0
  13. package/lib/front_end/models/bindings/NetworkProject.ts +157 -0
  14. package/lib/front_end/models/bindings/PresentationConsoleMessageHelper.ts +312 -0
  15. package/lib/front_end/models/bindings/ResourceMapping.ts +539 -0
  16. package/lib/front_end/models/bindings/ResourceScriptMapping.ts +491 -0
  17. package/lib/front_end/models/bindings/ResourceUtils.ts +103 -0
  18. package/lib/front_end/models/bindings/SASSSourceMapping.ts +222 -0
  19. package/lib/front_end/models/bindings/StylesSourceMapping.ts +316 -0
  20. package/lib/front_end/models/bindings/TempFile.ts +67 -0
  21. package/lib/front_end/models/bindings/bindings.ts +39 -0
  22. package/lib/front_end/models/source_map_scopes/NamesResolver.ts +765 -0
  23. package/lib/front_end/models/source_map_scopes/ScopeChainModel.ts +84 -0
  24. package/lib/front_end/models/source_map_scopes/source_map_scopes.ts +11 -0
  25. package/lib/front_end/models/stack_trace/StackTrace.ts +53 -0
  26. package/lib/front_end/models/stack_trace/StackTraceImpl.ts +85 -0
  27. package/lib/front_end/models/stack_trace/StackTraceModel.ts +128 -0
  28. package/lib/front_end/models/stack_trace/Trie.ts +163 -0
  29. package/lib/front_end/models/stack_trace/stack_trace.ts +9 -0
  30. package/lib/front_end/models/stack_trace/stack_trace_impl.ts +13 -0
  31. package/lib/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +240 -0
  32. package/lib/front_end/models/trace_source_maps_resolver/trace_source_maps_resolver.ts +5 -0
  33. package/lib/front_end/models/workspace/FileManager.ts +97 -0
  34. package/lib/front_end/models/workspace/IgnoreListManager.ts +628 -0
  35. package/lib/front_end/models/workspace/SearchConfig.ts +149 -0
  36. package/lib/front_end/models/workspace/UISourceCode.ts +698 -0
  37. package/lib/front_end/models/workspace/WorkspaceImpl.ts +339 -0
  38. package/lib/front_end/models/workspace/workspace.ts +17 -0
  39. package/lib/front_end/panels/timeline/TimelineUIUtils.ts +1029 -0
  40. package/lib/front_end/panels/timeline/extensions/ExtensionUI.ts +49 -0
  41. package/lib/front_end/panels/timeline/extensions/extensions.ts +9 -0
  42. package/lib/front_end/third_party/codemirror.next/LICENSE +21 -0
  43. package/lib/front_end/third_party/codemirror.next/README.chromium +30 -0
  44. package/lib/front_end/third_party/codemirror.next/bundle-tsconfig.json +24 -0
  45. package/lib/front_end/third_party/codemirror.next/bundle.ts +135 -0
  46. package/lib/front_end/third_party/codemirror.next/chunk/angular.js +2 -0
  47. package/lib/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -0
  48. package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js +2 -0
  49. package/lib/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -0
  50. package/lib/front_end/third_party/codemirror.next/chunk/cpp.js +2 -0
  51. package/lib/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -0
  52. package/lib/front_end/third_party/codemirror.next/chunk/css.js +2 -0
  53. package/lib/front_end/third_party/codemirror.next/chunk/html.js +4 -0
  54. package/lib/front_end/third_party/codemirror.next/chunk/java.js +2 -0
  55. package/lib/front_end/third_party/codemirror.next/chunk/java.js.map +1 -0
  56. package/lib/front_end/third_party/codemirror.next/chunk/javascript.js +2 -0
  57. package/lib/front_end/third_party/codemirror.next/chunk/legacy.js +2 -0
  58. package/lib/front_end/third_party/codemirror.next/chunk/legacy.js.map +1 -0
  59. package/lib/front_end/third_party/codemirror.next/chunk/less.js +2 -0
  60. package/lib/front_end/third_party/codemirror.next/chunk/less.js.map +1 -0
  61. package/lib/front_end/third_party/codemirror.next/chunk/markdown.js +2 -0
  62. package/lib/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -0
  63. package/lib/front_end/third_party/codemirror.next/chunk/php.js +2 -0
  64. package/lib/front_end/third_party/codemirror.next/chunk/php.js.map +1 -0
  65. package/lib/front_end/third_party/codemirror.next/chunk/python.js +2 -0
  66. package/lib/front_end/third_party/codemirror.next/chunk/python.js.map +1 -0
  67. package/lib/front_end/third_party/codemirror.next/chunk/sass.js +2 -0
  68. package/lib/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -0
  69. package/lib/front_end/third_party/codemirror.next/chunk/svelte.js +2 -0
  70. package/lib/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -0
  71. package/lib/front_end/third_party/codemirror.next/chunk/vue.js +2 -0
  72. package/lib/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -0
  73. package/lib/front_end/third_party/codemirror.next/chunk/wast.js +2 -0
  74. package/lib/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -0
  75. package/lib/front_end/third_party/codemirror.next/chunk/xml.js +2 -0
  76. package/lib/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -0
  77. package/lib/front_end/third_party/codemirror.next/codemirror.next.d.ts +8057 -0
  78. package/lib/front_end/third_party/codemirror.next/codemirror.next.js +2 -0
  79. package/lib/front_end/third_party/codemirror.next/codemirror.next.js.map +1 -0
  80. package/lib/front_end/third_party/codemirror.next/package.json +43 -0
  81. package/lib/front_end/third_party/codemirror.next/rebuild.sh +6 -0
  82. package/lib/front_end/third_party/codemirror.next/rollup.config.mjs +49 -0
  83. package/lib/front_end/third_party/source-map-scopes-codec/LICENSE +26 -0
  84. package/lib/front_end/third_party/source-map-scopes-codec/README.chromium +31 -0
  85. package/lib/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +33 -0
  86. package/lib/front_end/third_party/source-map-scopes-codec/package/LICENSE +26 -0
  87. package/lib/front_end/third_party/source-map-scopes-codec/package/README.md +64 -0
  88. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +62 -0
  89. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -0
  90. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +37 -0
  91. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +1 -0
  92. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +29 -0
  93. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -0
  94. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +8 -0
  95. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +1 -0
  96. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +6 -0
  97. package/lib/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +1 -0
  98. package/lib/front_end/third_party/source-map-scopes-codec/package/deno.json +21 -0
  99. package/lib/front_end/third_party/source-map-scopes-codec/package/package.json +14 -0
  100. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +196 -0
  101. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -0
  102. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +262 -0
  103. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +235 -0
  104. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +1 -0
  105. package/lib/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +359 -0
  106. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js +39 -0
  107. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +1 -0
  108. package/lib/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +53 -0
  109. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +438 -0
  110. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -0
  111. package/lib/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +539 -0
  112. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +23 -0
  113. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +1 -0
  114. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +35 -0
  115. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +257 -0
  116. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -0
  117. package/lib/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +348 -0
  118. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js +8 -0
  119. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +1 -0
  120. package/lib/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +20 -0
  121. package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes-tsconfig.json +8 -0
  122. package/lib/front_end/third_party/source-map-scopes-codec/package/src/scopes.d.ts +184 -0
  123. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js +9 -0
  124. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +1 -0
  125. package/lib/front_end/third_party/source-map-scopes-codec/package/src/util.ts +12 -0
  126. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +82 -0
  127. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +1 -0
  128. package/lib/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +99 -0
  129. package/lib/front_end/third_party/source-map-scopes-codec/source-map-scopes-codec.ts +5 -0
  130. package/lib/front_end/ui/legacy/theme_support/ThemeSupport.ts +222 -0
  131. package/lib/front_end/ui/legacy/theme_support/theme_support.ts +5 -0
  132. package/package.json +11 -5
  133. package/patches/chrome-devtools-frontend+1.0.1533544.patch +1549 -20
@@ -0,0 +1,184 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ /**
6
+ * The decoded scopes information found in a source map.
7
+ */
8
+ export interface ScopeInfo {
9
+ /**
10
+ * The length of {@linkcode scopes} must match the length of "sources" in the source map JSON. Each entry describes the scope tree of the corresponding source file.
11
+ */
12
+ scopes: (OriginalScope | null)[];
13
+
14
+ /**
15
+ * The range tree of the generated bundle. Multiple top-level ranges are allowed but must not overlap source position wise.
16
+ */
17
+ ranges: GeneratedRange[];
18
+ }
19
+
20
+ /**
21
+ * A scope in the authored source.
22
+ */
23
+ export interface OriginalScope {
24
+ /** The beginning of this scope (inclusive). */
25
+ start: Position;
26
+
27
+ /** The end of this scope (exclusive) */
28
+ end: Position;
29
+
30
+ /**
31
+ * The name of this scope. For function scopes this is the function name.
32
+ *
33
+ * Constructors may put the class name here.
34
+ */
35
+ name?: string;
36
+
37
+ /**
38
+ * JavaScript-like languages are encouraged to use 'Global', 'Class', 'Function' and 'Block'.
39
+ *
40
+ * The "kind" is only used in debuggers as a label for scope UI views, but does not have any
41
+ * semantic significance.
42
+ */
43
+ kind?: string;
44
+
45
+ /**
46
+ * Whether this scope is something that can be called and results in stack frame (e.g. functions, methods, etc.).
47
+ */
48
+ isStackFrame: boolean;
49
+
50
+ /**
51
+ * All variable names that this scope declares.
52
+ */
53
+ variables: string[];
54
+
55
+ /**
56
+ * The child scopes. When manually building scopes, {@linkcode children} must be sorted, not
57
+ * overlap each other and be contained within [start, end).
58
+ */
59
+ children: OriginalScope[];
60
+
61
+ /** The parent scope or `undefined` for top-level scopes. */
62
+ parent?: OriginalScope;
63
+ }
64
+
65
+ /**
66
+ * A range (can be a scope) in the generated JavaScript/WASM.
67
+ *
68
+ * The name "range" was chosen deliberately as a GeneratedRange does not necessarily
69
+ * correspond to a lexical JavaScript scope. E.g. inlining, or concatenating multiple
70
+ * bundles can result in generated ranges that are not lexical scopes.
71
+ */
72
+ export interface GeneratedRange {
73
+ /** The beginning of this range (inclusive) */
74
+ start: Position;
75
+
76
+ /** The end of this range (exclusive) */
77
+ end: Position;
78
+
79
+ /**
80
+ * The corresponding scope in the authored source.
81
+ */
82
+ originalScope?: OriginalScope;
83
+
84
+ /**
85
+ * Whether this generated range is an actual JavaScript/WASM function in the generated code.
86
+ */
87
+ isStackFrame: boolean;
88
+
89
+ /**
90
+ * Whether calls to this generated range should be hidden from stack traces even if
91
+ * this range has an `originalScope`.
92
+ */
93
+ isHidden: boolean;
94
+
95
+ /**
96
+ * If this `GeneratedRange` is the result of inlining `originalScope`, then `callSite`
97
+ * refers to where `originalScope` was called in the original ("authored") code.
98
+ *
99
+ * If this field is present than `originalScope` is present as well and `isStackFrame` is `false`.
100
+ */
101
+ callSite?: OriginalPosition;
102
+
103
+ /**
104
+ * Expressions that compute the values of the variables of this OriginalScope. The length
105
+ * of `values` matches the length of `originalScope.variables`.
106
+ */
107
+ values: Binding[];
108
+
109
+ /**
110
+ * The child ranges. When manually building ranges, {@linkcode children} must be sorted,
111
+ * not overlap each other and be contained within [start, end).
112
+ */
113
+ children: GeneratedRange[];
114
+
115
+ /** The parent range or `undefined` for top-level ranges. */
116
+ parent?: GeneratedRange;
117
+ }
118
+
119
+ /**
120
+ * For each variable, this can either be:
121
+ *
122
+ * 1) A single expression (valid for a full `GeneratedRange`).
123
+ *
124
+ * 2) `null` if this variable is unavailable in the whole range. This can
125
+ * happen e.g. when the variable was optimized out and can't be recomputed.
126
+ *
127
+ * 3) A list of `SubRangeBinding`s. Used when computing the value requires different
128
+ * expressions throughout the `GeneratedRange` or if the variable is unavailable in
129
+ * parts of the `GeneratedRange`.
130
+ *
131
+ * Note: The decoder produces `SubRangeBindings` where the "from" of the first `SubRangeBinding`
132
+ * and the "to" of the last `SubRangeBinding` are equal to the `GeneratedRange`s "start" and "end"
133
+ * position respectively.
134
+ */
135
+ export type Binding = string | null | SubRangeBinding[];
136
+
137
+ export interface SubRangeBinding {
138
+ value?: string;
139
+ from: Position;
140
+ to: Position;
141
+ }
142
+
143
+ /**
144
+ * A position with 0-based line and column numbers.
145
+ *
146
+ * A {@linkcode Position} object by itself does not imply a position in original source
147
+ * or generated code. It is used in both and normally it is clear from context.
148
+ */
149
+ export interface Position {
150
+ line: number;
151
+ column: number;
152
+ }
153
+
154
+ /**
155
+ * A position with 0-based line and column numbers in a specific original source file.
156
+ */
157
+ export interface OriginalPosition extends Position {
158
+ /** The 0-based index into "sources" in the source map. Or into {@linkcode ScopeInfo.scopes}. */
159
+ sourceIndex: number;
160
+ }
161
+
162
+ /**
163
+ * A standard source map, or index source map as per https://tc39.es/ecma426.
164
+ */
165
+ export type SourceMap = SourceMapJson | IndexSourceMapJson;
166
+
167
+ /**
168
+ * A standard index source map json object as per https://tc39.es/ecma426.
169
+ */
170
+ export interface IndexSourceMapJson {
171
+ version: 3;
172
+ sections: Array<{ offset: Position; map: SourceMapJson }>;
173
+ }
174
+
175
+ /**
176
+ * A standard source map json object as per https://tc39.es/ecma426.
177
+ */
178
+ export interface SourceMapJson {
179
+ version: 3;
180
+ sources: (string | null)[];
181
+ mappings: string;
182
+ names?: string[];
183
+ scopes?: string;
184
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ /**
5
+ * @returns A negative number iff `a` precedes `b`, 0 iff `a` and `b` are equal and a positive number iff `b` precedes `a`.
6
+ */ export function comparePositions(a, b) {
7
+ return a.line - b.line || a.column - b.column;
8
+ }
9
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sources":["./util.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B;;CAEC,GACD,OAAO,SAAS,iBAAiB,CAAW,EAAE,CAAW;EACvD,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,MAAM,GAAG,EAAE,MAAM;AAC/C"}
@@ -0,0 +1,12 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
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 { Position } from "./scopes.d.ts";
6
+
7
+ /**
8
+ * @returns A negative number iff `a` precedes `b`, 0 iff `a` and `b` are equal and a positive number iff `b` precedes `a`.
9
+ */
10
+ export function comparePositions(a: Position, b: Position): number {
11
+ return a.line - b.line || a.column - b.column;
12
+ }
@@ -0,0 +1,82 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ /**
5
+ * @fileoverview
6
+ *
7
+ * VLQ implementation taken mostly verbatim from Chrome DevTools itself.
8
+ */ const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9
+ const BASE64_CODES = new Uint8Array(123);
10
+ for(let index = 0; index < BASE64_CHARS.length; ++index){
11
+ BASE64_CODES[BASE64_CHARS.charCodeAt(index)] = index;
12
+ }
13
+ const VLQ_BASE_SHIFT = 5;
14
+ const VLQ_BASE_MASK = (1 << 5) - 1;
15
+ const VLQ_CONTINUATION_MASK = 1 << 5;
16
+ export function encodeSigned(n) {
17
+ // Set the sign bit as the least significant bit.
18
+ n = n >= 0 ? 2 * n : 1 - 2 * n;
19
+ return encodeUnsigned(n);
20
+ }
21
+ export function encodeUnsigned(n) {
22
+ // Encode into a base64 run.
23
+ let result = "";
24
+ while(true){
25
+ // Extract the lowest 5 bits and remove them from the number.
26
+ const digit = n & 0x1f;
27
+ n >>>= 5;
28
+ // Is there anything more left to encode?
29
+ if (n === 0) {
30
+ // We are done encoding, finish the run.
31
+ result += BASE64_CHARS[digit];
32
+ break;
33
+ } else {
34
+ // There is still more encode, so add the digit and the continuation bit.
35
+ result += BASE64_CHARS[0x20 + digit];
36
+ }
37
+ }
38
+ return result;
39
+ }
40
+ export class TokenIterator {
41
+ #string;
42
+ #position;
43
+ constructor(string){
44
+ this.#string = string;
45
+ this.#position = 0;
46
+ }
47
+ nextChar() {
48
+ return this.#string.charAt(this.#position++);
49
+ }
50
+ /** Returns the unicode value of the next character and advances the iterator */ nextCharCode() {
51
+ return this.#string.charCodeAt(this.#position++);
52
+ }
53
+ peek() {
54
+ return this.#string.charAt(this.#position);
55
+ }
56
+ hasNext() {
57
+ return this.#position < this.#string.length;
58
+ }
59
+ nextSignedVLQ() {
60
+ let result = this.nextUnsignedVLQ();
61
+ // Fix the sign.
62
+ const negative = result & 1;
63
+ result >>>= 1;
64
+ return negative ? -result : result;
65
+ }
66
+ nextUnsignedVLQ() {
67
+ let result = 0;
68
+ let shift = 0;
69
+ let digit = 0;
70
+ do {
71
+ const charCode = this.nextCharCode();
72
+ digit = BASE64_CODES[charCode];
73
+ result += (digit & VLQ_BASE_MASK) << shift;
74
+ shift += VLQ_BASE_SHIFT;
75
+ }while (digit & VLQ_CONTINUATION_MASK)
76
+ return result;
77
+ }
78
+ currentChar() {
79
+ return this.#string.charAt(this.#position - 1);
80
+ }
81
+ }
82
+ //# sourceMappingURL=vlq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vlq.js","sources":["./vlq.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B;;;;CAIC,GAED,MAAM,eACJ;AACF,MAAM,eAAe,IAAI,WAAW;AACpC,IAAK,IAAI,QAAQ,GAAG,QAAQ,aAAa,MAAM,EAAE,EAAE,MAAO;EACxD,YAAY,CAAC,aAAa,UAAU,CAAC,OAAO,GAAG;AACjD;AAEA,MAAM,iBAAiB;AACvB,MAAM,gBAAgB,CAAC,KAAK,CAAC,IAAI;AACjC,MAAM,wBAAwB,KAAK;AAEnC,OAAO,SAAS,aAAa,CAAS;EACpC,iDAAiD;EACjD,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI;EAC7B,OAAO,eAAe;AACxB;AAEA,OAAO,SAAS,eAAe,CAAS;EACtC,4BAA4B;EAC5B,IAAI,SAAS;EACb,MAAO,KAAM;IACX,6DAA6D;IAC7D,MAAM,QAAQ,IAAI;IAClB,OAAO;IACP,yCAAyC;IACzC,IAAI,MAAM,GAAG;MACX,wCAAwC;MACxC,UAAU,YAAY,CAAC,MAAM;MAC7B;IACF,OAAO;MACL,yEAAyE;MACzE,UAAU,YAAY,CAAC,OAAO,MAAM;IACtC;EACF;EACA,OAAO;AACT;AAEA,OAAO,MAAM;EACF,CAAA,MAAO,CAAS;EACzB,CAAA,QAAS,CAAS;EAElB,YAAY,MAAc,CAAE;IAC1B,IAAI,CAAC,CAAA,MAAO,GAAG;IACf,IAAI,CAAC,CAAA,QAAS,GAAG;EACnB;EAEA,WAAmB;IACjB,OAAO,IAAI,CAAC,CAAA,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,QAAS;EAC3C;EAEA,+EAA+E,GAC/E,eAAuB;IACrB,OAAO,IAAI,CAAC,CAAA,MAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA,QAAS;EAC/C;EAEA,OAAe;IACb,OAAO,IAAI,CAAC,CAAA,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,QAAS;EAC3C;EAEA,UAAmB;IACjB,OAAO,IAAI,CAAC,CAAA,QAAS,GAAG,IAAI,CAAC,CAAA,MAAO,CAAC,MAAM;EAC7C;EAEA,gBAAwB;IACtB,IAAI,SAAS,IAAI,CAAC,eAAe;IAEjC,gBAAgB;IAChB,MAAM,WAAW,SAAS;IAC1B,YAAY;IACZ,OAAO,WAAW,CAAC,SAAS;EAC9B;EAEA,kBAA0B;IACxB,IAAI,SAAS;IACb,IAAI,QAAQ;IACZ,IAAI,QAAQ;IACZ,GAAG;MACD,MAAM,WAAW,IAAI,CAAC,YAAY;MAClC,QAAQ,YAAY,CAAC,SAAS;MAC9B,UAAU,CAAC,QAAQ,aAAa,KAAK;MACrC,SAAS;IACX,QAAS,QAAQ,sBAAuB;IACxC,OAAO;EACT;EAEA,cAAsB;IACpB,OAAO,IAAI,CAAC,CAAA,MAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,QAAS,GAAG;EAC9C;AACF"}
@@ -0,0 +1,99 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ /**
6
+ * @fileoverview
7
+ *
8
+ * VLQ implementation taken mostly verbatim from Chrome DevTools itself.
9
+ */
10
+
11
+ const BASE64_CHARS =
12
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13
+ const BASE64_CODES = new Uint8Array(123);
14
+ for (let index = 0; index < BASE64_CHARS.length; ++index) {
15
+ BASE64_CODES[BASE64_CHARS.charCodeAt(index)] = index;
16
+ }
17
+
18
+ const VLQ_BASE_SHIFT = 5;
19
+ const VLQ_BASE_MASK = (1 << 5) - 1;
20
+ const VLQ_CONTINUATION_MASK = 1 << 5;
21
+
22
+ export function encodeSigned(n: number): string {
23
+ // Set the sign bit as the least significant bit.
24
+ n = n >= 0 ? 2 * n : 1 - 2 * n;
25
+ return encodeUnsigned(n);
26
+ }
27
+
28
+ export function encodeUnsigned(n: number): string {
29
+ // Encode into a base64 run.
30
+ let result = "";
31
+ while (true) {
32
+ // Extract the lowest 5 bits and remove them from the number.
33
+ const digit = n & 0x1f;
34
+ n >>>= 5;
35
+ // Is there anything more left to encode?
36
+ if (n === 0) {
37
+ // We are done encoding, finish the run.
38
+ result += BASE64_CHARS[digit];
39
+ break;
40
+ } else {
41
+ // There is still more encode, so add the digit and the continuation bit.
42
+ result += BASE64_CHARS[0x20 + digit];
43
+ }
44
+ }
45
+ return result;
46
+ }
47
+
48
+ export class TokenIterator {
49
+ readonly #string: string;
50
+ #position: number;
51
+
52
+ constructor(string: string) {
53
+ this.#string = string;
54
+ this.#position = 0;
55
+ }
56
+
57
+ nextChar(): string {
58
+ return this.#string.charAt(this.#position++);
59
+ }
60
+
61
+ /** Returns the unicode value of the next character and advances the iterator */
62
+ nextCharCode(): number {
63
+ return this.#string.charCodeAt(this.#position++);
64
+ }
65
+
66
+ peek(): string {
67
+ return this.#string.charAt(this.#position);
68
+ }
69
+
70
+ hasNext(): boolean {
71
+ return this.#position < this.#string.length;
72
+ }
73
+
74
+ nextSignedVLQ(): number {
75
+ let result = this.nextUnsignedVLQ();
76
+
77
+ // Fix the sign.
78
+ const negative = result & 1;
79
+ result >>>= 1;
80
+ return negative ? -result : result;
81
+ }
82
+
83
+ nextUnsignedVLQ(): number {
84
+ let result = 0;
85
+ let shift = 0;
86
+ let digit = 0;
87
+ do {
88
+ const charCode = this.nextCharCode();
89
+ digit = BASE64_CODES[charCode];
90
+ result += (digit & VLQ_BASE_MASK) << shift;
91
+ shift += VLQ_BASE_SHIFT;
92
+ } while (digit & VLQ_CONTINUATION_MASK);
93
+ return result;
94
+ }
95
+
96
+ currentChar(): string {
97
+ return this.#string.charAt(this.#position - 1);
98
+ }
99
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright 2025 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ export * from './package/src/mod.js';
@@ -0,0 +1,222 @@
1
+ // Copyright 2021 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
+ /* eslint-disable @devtools/no-imperative-dom-api */
5
+
6
+ /*
7
+ * Copyright (C) 2011 Google Inc. All rights reserved.
8
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
9
+ * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
10
+ * Copyright (C) 2009 Joseph Pecoraro
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * 1. Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ * 2. Redistributions in binary form must reproduce the above copyright
19
+ * notice, this list of conditions and the following disclaimer in the
20
+ * documentation and/or other materials provided with the distribution.
21
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
22
+ * its contributors may be used to endorse or promote products derived
23
+ * from this software without specific prior written permission.
24
+ *
25
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
26
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
29
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+ */
36
+
37
+ import * as Common from '../../../core/common/common.js';
38
+ import * as Host from '../../../core/host/host.js';
39
+ import * as Root from '../../../core/root/root.js';
40
+
41
+ let themeSupportInstance: ThemeSupport;
42
+
43
+ const themeValueByTargetByName = new Map<Element|null, Map<string, string>>();
44
+
45
+ export class ThemeSupport extends EventTarget {
46
+ #themeName = 'default';
47
+ private computedStyleOfHTML = Common.Lazy.lazy(() => window.getComputedStyle(document.documentElement));
48
+
49
+ readonly #documentsToTheme = new Set<Document>([document]);
50
+
51
+ readonly #darkThemeMediaQuery: MediaQueryList;
52
+ readonly #highContrastMediaQuery: MediaQueryList;
53
+ readonly #onThemeChangeListener = (): void => this.#applyTheme();
54
+ readonly #onHostThemeChangeListener = (): void => this.fetchColorsAndApplyHostTheme();
55
+
56
+ private constructor(private setting: Common.Settings.Setting<string>) {
57
+ super();
58
+
59
+ // When the theme changes we instantiate a new theme support and reapply.
60
+ // Equally if the user has set to match the system and the OS preference changes
61
+ // we perform the same change.
62
+ this.#darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
63
+ this.#highContrastMediaQuery = window.matchMedia('(forced-colors: active)');
64
+ this.#darkThemeMediaQuery.addEventListener('change', this.#onThemeChangeListener);
65
+ this.#highContrastMediaQuery.addEventListener('change', this.#onThemeChangeListener);
66
+ setting.addChangeListener(this.#onThemeChangeListener);
67
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
68
+ Host.InspectorFrontendHostAPI.Events.ColorThemeChanged, this.#onHostThemeChangeListener);
69
+ }
70
+
71
+ #dispose(): void {
72
+ this.#darkThemeMediaQuery.removeEventListener('change', this.#onThemeChangeListener);
73
+ this.#highContrastMediaQuery.removeEventListener('change', this.#onThemeChangeListener);
74
+ this.setting.removeChangeListener(this.#onThemeChangeListener);
75
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
76
+ Host.InspectorFrontendHostAPI.Events.ColorThemeChanged, this.#onHostThemeChangeListener);
77
+ }
78
+
79
+ static hasInstance(): boolean {
80
+ return typeof themeSupportInstance !== 'undefined';
81
+ }
82
+
83
+ static instance(opts: {
84
+ forceNew: boolean|null,
85
+ setting: Common.Settings.Setting<string>|null,
86
+ } = {forceNew: null, setting: null}): ThemeSupport {
87
+ const {forceNew, setting} = opts;
88
+ if (!themeSupportInstance || forceNew) {
89
+ if (!setting) {
90
+ throw new Error(`Unable to create theme support: setting must be provided: ${new Error().stack}`);
91
+ }
92
+
93
+ if (themeSupportInstance) {
94
+ themeSupportInstance.#dispose();
95
+ }
96
+ themeSupportInstance = new ThemeSupport(setting);
97
+ }
98
+
99
+ return themeSupportInstance;
100
+ }
101
+
102
+ /**
103
+ * Adds additional `Document` instances that should be themed besides the default
104
+ * `window.document` in which this ThemeSupport instance was created.
105
+ */
106
+ addDocumentToTheme(document: Document): void {
107
+ this.#documentsToTheme.add(document);
108
+ this.#fetchColorsAndApplyHostTheme(document);
109
+ }
110
+
111
+ getComputedValue(propertyName: string, target: Element|null = null): string {
112
+ // Since we might query the same property name from various targets we need to support
113
+ // per-target caching of computed values. Here we attempt to locate the particular computed
114
+ // value cache for the target element. If no target was specified we use the default computed root,
115
+ // which belongs to the documentElement.
116
+ let themeValueByName = themeValueByTargetByName.get(target);
117
+ if (!themeValueByName) {
118
+ themeValueByName = new Map<string, string>();
119
+ themeValueByTargetByName.set(target, themeValueByName);
120
+ }
121
+
122
+ // Since theme changes trigger a reload, we can avoid repeatedly looking up color values
123
+ // dynamically. Instead we can look up the first time and cache them for future use,
124
+ // knowing that the cache will be invalidated by virtue of a reload when the theme changes.
125
+ let themeValue = themeValueByName.get(propertyName);
126
+ if (!themeValue) {
127
+ const styleDeclaration = target ? window.getComputedStyle(target) : this.computedStyleOfHTML();
128
+ if (typeof styleDeclaration === 'symbol') {
129
+ throw new Error(`Computed value for property (${propertyName}) could not be found on documentElement.`);
130
+ }
131
+ themeValue = styleDeclaration.getPropertyValue(propertyName).trim();
132
+
133
+ // If we receive back an empty value (nothing has been set) we don't store it for the future.
134
+ // This means that subsequent requests will continue to query the styles in case the value
135
+ // has been set.
136
+ if (themeValue) {
137
+ themeValueByName.set(propertyName, themeValue);
138
+ }
139
+ }
140
+
141
+ return themeValue;
142
+ }
143
+
144
+ themeName(): string {
145
+ return this.#themeName;
146
+ }
147
+
148
+ #applyTheme(): void {
149
+ for (const document of this.#documentsToTheme) {
150
+ this.#applyThemeToDocument(document);
151
+ }
152
+ }
153
+
154
+ #applyThemeToDocument(document: Document): void {
155
+ const isForcedColorsMode = window.matchMedia('(forced-colors: active)').matches;
156
+ const systemPreferredTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default';
157
+
158
+ const useSystemPreferred = this.setting.get() === 'systemPreferred' || isForcedColorsMode;
159
+ this.#themeName = useSystemPreferred ? systemPreferredTheme : this.setting.get();
160
+ document.documentElement.classList.toggle('theme-with-dark-background', this.#themeName === 'dark');
161
+
162
+ const useChromeTheme = Common.Settings.moduleSetting('chrome-theme-colors').get();
163
+ const isIncognito = Root.Runtime.hostConfig.isOffTheRecord === true;
164
+ // Baseline is the name of Chrome's default color theme and there are two of these: default and grayscale.
165
+ // The collective name for the rest of the color themes is dynamic.
166
+ // In the baseline themes Chrome uses custom values for surface colors, whereas for dynamic themes these are color-mixed.
167
+ // To match Chrome we need to know if any of the baseline themes is currently active and assign specific values to surface colors.
168
+ if (isIncognito) {
169
+ document.documentElement.classList.toggle('baseline-grayscale', true);
170
+ } else if (useChromeTheme) {
171
+ const selectedTheme = getComputedStyle(document.body).getPropertyValue('--user-color-source');
172
+ document.documentElement.classList.toggle('baseline-default', selectedTheme === 'baseline-default');
173
+ document.documentElement.classList.toggle('baseline-grayscale', selectedTheme === 'baseline-grayscale');
174
+ } else {
175
+ document.documentElement.classList.toggle('baseline-grayscale', true);
176
+ }
177
+
178
+ // In the event the theme changes we need to clear caches and notify subscribers.
179
+ themeValueByTargetByName.clear();
180
+ this.dispatchEvent(new ThemeChangeEvent());
181
+ }
182
+
183
+ static clearThemeCache(): void {
184
+ themeValueByTargetByName.clear();
185
+ }
186
+
187
+ fetchColorsAndApplyHostTheme(): void {
188
+ for (const document of this.#documentsToTheme) {
189
+ this.#fetchColorsAndApplyHostTheme(document);
190
+ }
191
+ }
192
+
193
+ #fetchColorsAndApplyHostTheme(document: Document): void {
194
+ const useChromeTheme = Common.Settings.moduleSetting('chrome-theme-colors').get();
195
+ if (Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode() || !useChromeTheme) {
196
+ this.#applyThemeToDocument(document);
197
+ return;
198
+ }
199
+
200
+ const oldColorsCssLink = document.querySelector('link[href*=\'//theme/colors.css\']');
201
+ const newColorsCssLink = document.createElement('link');
202
+ newColorsCssLink.setAttribute(
203
+ 'href', `devtools://theme/colors.css?sets=ui,chrome&version=${(new Date()).getTime().toString()}`);
204
+ newColorsCssLink.setAttribute('rel', 'stylesheet');
205
+ newColorsCssLink.setAttribute('type', 'text/css');
206
+ newColorsCssLink.onload = () => {
207
+ if (oldColorsCssLink) {
208
+ oldColorsCssLink.remove();
209
+ }
210
+ this.#applyThemeToDocument(document);
211
+ };
212
+ document.body.appendChild(newColorsCssLink);
213
+ }
214
+ }
215
+
216
+ export class ThemeChangeEvent extends Event {
217
+ static readonly eventName = 'themechange';
218
+
219
+ constructor() {
220
+ super(ThemeChangeEvent.eventName, {bubbles: true, composed: true});
221
+ }
222
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright 2020 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
+ export * from './ThemeSupport.js';
package/package.json CHANGED
@@ -1,15 +1,21 @@
1
1
  {
2
2
  "name": "devtools-tracing",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Utilities for working with trace files",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "start": "tsx index.ts",
8
- "test": "echo \"Error: no test specified\" && exit 1",
9
- "postinstall": "patch-package"
8
+ "postinstall": "patch-package",
9
+ "generate": "tsx generate.ts",
10
+ "example:inp": "tsx examples/inp.ts",
11
+ "example:stats": "tsx examples/stats.ts"
10
12
  },
11
- "author": "",
12
- "license": "ISC",
13
+ "author": "Samuel Maddock <sam@samuelmaddock.com>",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+ssh://git@github.com/samuelmaddock/devtools-tracing.git"
17
+ },
18
+ "license": "BSD-3-Clause",
13
19
  "devDependencies": {
14
20
  "@typescript-eslint/typescript-estree": "^8.46.2",
15
21
  "chrome-devtools-frontend": "^1.0.1533544",