chrome-devtools-frontend 1.0.1010831 → 1.0.1011873

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.
@@ -544,6 +544,7 @@ grd_files_debug_sources = [
544
544
  "front_end/core/common/JavaScriptMetaData.js",
545
545
  "front_end/core/common/Lazy.js",
546
546
  "front_end/core/common/Linkifier.js",
547
+ "front_end/core/common/Mutex.js",
547
548
  "front_end/core/common/Object.js",
548
549
  "front_end/core/common/ParsedURL.js",
549
550
  "front_end/core/common/Progress.js",
package/docs/workflows.md CHANGED
@@ -59,7 +59,7 @@ This works with Chromium 79 or later.
59
59
  **(Requires `brew install coreutils` on Mac.)**
60
60
 
61
61
  ```bash
62
- <path-to-chrome>/chrome --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end)
62
+ <path-to-devtools-frontend>/third_party/chrome/chrome-<platform>/chrome --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end)
63
63
  ```
64
64
 
65
65
  Note that `$(realpath out/Default/gen/front_end)` expands to the absolute path to build artifacts for DevTools frontend.
@@ -79,7 +79,7 @@ Serve the content of `out/Default/gen/front_end` on a web server, e.g. via `pyth
79
79
  Then point to that web server when starting Chromium, for example:
80
80
 
81
81
  ```bash
82
- <path-to-chrome>/chrome --custom-devtools-frontend=http://localhost:8000/
82
+ <path-to-devtools-frontend>/third_party/chrome/chrome-<platform>/chrome --custom-devtools-frontend=http://localhost:8000/
83
83
  ```
84
84
 
85
85
  Open DevTools via F12 on Windows/Linux or Cmd+Option+I on Mac.
@@ -91,7 +91,7 @@ Serve the content of `out/Default/gen/front_end` on a web server, e.g. via `pyth
91
91
  Then point to that web server when starting Chromium, for example:
92
92
 
93
93
  ```bash
94
- <path-to-chrome>/chrome --custom-devtools-frontend=http://localhost:8000/ --remote-debugging-port=9222
94
+ <path-to-devtools-frontend>/third_party/chrome/chrome-<platform>/chrome --custom-devtools-frontend=http://localhost:8000/ --remote-debugging-port=9222
95
95
  ```
96
96
 
97
97
  In a regular Chrome tab, go to the URL `http://localhost:9222#custom=true`. It lists URLs that can be copied to new Chrome tabs to inspect individual debug targets.
@@ -0,0 +1,42 @@
1
+ // Copyright 2022 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
+ type ReleaseFn = () => void;
6
+
7
+ /**
8
+ * Use Mutex class to coordinate local concurrent operations.
9
+ * Once `acquire` promise resolves, you hold the lock and must
10
+ * call `release` function returned by `acquire` to release the
11
+ * lock. Failing to `release` the lock may lead to deadlocks.
12
+ */
13
+ export class Mutex {
14
+ #locked = false;
15
+ #acquiringQueue: Array<(release: ReleaseFn) => void> = [];
16
+
17
+ acquire(): Promise<ReleaseFn> {
18
+ let resolver = (_release: ReleaseFn): void => {};
19
+ const promise = new Promise<ReleaseFn>((resolve): void => {
20
+ resolver = resolve;
21
+ });
22
+ this.#acquiringQueue.push(resolver);
23
+ this.#processAcquiringQueue();
24
+ return promise;
25
+ }
26
+
27
+ #processAcquiringQueue(): void {
28
+ if (this.#locked) {
29
+ return;
30
+ }
31
+ const nextAquirePromise = this.#acquiringQueue.shift();
32
+ if (nextAquirePromise) {
33
+ this.#locked = true;
34
+ nextAquirePromise(this.#release.bind(this));
35
+ }
36
+ }
37
+
38
+ #release(): void {
39
+ this.#locked = false;
40
+ this.#processAcquiringQueue();
41
+ }
42
+ }
@@ -14,6 +14,7 @@ import * as EventTarget from './EventTarget.js';
14
14
  import * as JavaScriptMetaData from './JavaScriptMetaData.js';
15
15
  import * as Lazy from './Lazy.js';
16
16
  import * as Linkifier from './Linkifier.js';
17
+ import * as Mutex from './Mutex.js';
17
18
  import * as ObjectWrapper from './Object.js';
18
19
  import * as ParsedURL from './ParsedURL.js';
19
20
  import * as Progress from './Progress.js';
@@ -58,6 +59,7 @@ export {
58
59
  JavaScriptMetaData,
59
60
  Lazy,
60
61
  Linkifier,
62
+ Mutex,
61
63
  ObjectWrapper,
62
64
  ParsedURL,
63
65
  Progress,
@@ -315,7 +315,7 @@ export class CSSMatchedStyles {
315
315
  for (let i = 0; i < pseudoPayload.length; ++i) {
316
316
  const entryPayload = pseudoPayload[i];
317
317
  // PseudoElement nodes are not created unless "content" css property is set.
318
- const pseudoElement = this.#nodeInternal.pseudoElements().get(entryPayload.pseudoType) || null;
318
+ const pseudoElement = this.#nodeInternal.pseudoElements().get(entryPayload.pseudoType)?.at(-1) || null;
319
319
  const pseudoStyles = [];
320
320
  const rules = entryPayload.matches || [];
321
321
 
@@ -69,7 +69,7 @@ export class DOMNode {
69
69
  #xmlVersion!: string|undefined;
70
70
  #isSVGNodeInternal!: boolean;
71
71
  #creationStackTraceInternal: Promise<Protocol.Runtime.StackTrace|null>|null;
72
- pseudoElementsInternal: Map<string, DOMNode>;
72
+ #pseudoElements: Map<string, DOMNode[]>;
73
73
  #distributedNodesInternal: DOMNodeShortcut[];
74
74
  assignedSlot: DOMNodeShortcut|null;
75
75
  readonly shadowRootsInternal: DOMNode[];
@@ -100,7 +100,7 @@ export class DOMNode {
100
100
  this.#agent = this.#domModelInternal.getAgent();
101
101
  this.index = undefined;
102
102
  this.#creationStackTraceInternal = null;
103
- this.pseudoElementsInternal = new Map();
103
+ this.#pseudoElements = new Map();
104
104
  this.#distributedNodesInternal = [];
105
105
  this.assignedSlot = null;
106
106
  this.shadowRootsInternal = [];
@@ -319,32 +319,33 @@ export class DOMNode {
319
319
  }
320
320
 
321
321
  hasPseudoElements(): boolean {
322
- return this.pseudoElementsInternal.size > 0;
322
+ return this.#pseudoElements.size > 0;
323
323
  }
324
324
 
325
- pseudoElements(): Map<string, DOMNode> {
326
- return this.pseudoElementsInternal;
325
+ pseudoElements(): Map<string, DOMNode[]> {
326
+ return this.#pseudoElements;
327
327
  }
328
328
 
329
- beforePseudoElement(): DOMNode|null {
330
- if (!this.pseudoElementsInternal) {
331
- return null;
332
- }
333
- return this.pseudoElementsInternal.get(DOMNode.PseudoElementNames.Before) || null;
329
+ beforePseudoElement(): DOMNode|undefined {
330
+ return this.#pseudoElements.get(DOMNode.PseudoElementNames.Before)?.at(-1);
334
331
  }
335
332
 
336
- afterPseudoElement(): DOMNode|null {
337
- if (!this.pseudoElementsInternal) {
338
- return null;
339
- }
340
- return this.pseudoElementsInternal.get(DOMNode.PseudoElementNames.After) || null;
333
+ afterPseudoElement(): DOMNode|undefined {
334
+ return this.#pseudoElements.get(DOMNode.PseudoElementNames.After)?.at(-1);
341
335
  }
342
336
 
343
- markerPseudoElement(): DOMNode|null {
344
- if (!this.pseudoElementsInternal) {
345
- return null;
346
- }
347
- return this.pseudoElementsInternal.get(DOMNode.PseudoElementNames.Marker) || null;
337
+ markerPseudoElement(): DOMNode|undefined {
338
+ return this.#pseudoElements.get(DOMNode.PseudoElementNames.Marker)?.at(-1);
339
+ }
340
+
341
+ pageTransitionPseudoElements(): DOMNode[] {
342
+ return [
343
+ ...this.#pseudoElements.get(DOMNode.PseudoElementNames.PageTransition) || [],
344
+ ...this.#pseudoElements.get(DOMNode.PseudoElementNames.PageTransitionContainer) || [],
345
+ ...this.#pseudoElements.get(DOMNode.PseudoElementNames.PageTransitionImageWrapper) || [],
346
+ ...this.#pseudoElements.get(DOMNode.PseudoElementNames.PageTransitionOutgoingImage) || [],
347
+ ...this.#pseudoElements.get(DOMNode.PseudoElementNames.PageTransitionIncomingImage) || [],
348
+ ];
348
349
  }
349
350
 
350
351
  hasAssignedSlot(): boolean {
@@ -632,7 +633,12 @@ export class DOMNode {
632
633
  removeChild(node: DOMNode): void {
633
634
  const pseudoType = node.pseudoType();
634
635
  if (pseudoType) {
635
- this.pseudoElementsInternal.delete(pseudoType);
636
+ const updatedPseudoElements = this.#pseudoElements.get(pseudoType)?.filter(element => element !== node);
637
+ if (updatedPseudoElements && updatedPseudoElements.length > 0) {
638
+ this.#pseudoElements.set(pseudoType, updatedPseudoElements);
639
+ } else {
640
+ this.#pseudoElements.delete(pseudoType);
641
+ }
636
642
  } else {
637
643
  const shadowRootIndex = this.shadowRootsInternal.indexOf(node);
638
644
  if (shadowRootIndex !== -1) {
@@ -678,7 +684,12 @@ export class DOMNode {
678
684
  if (!pseudoType) {
679
685
  throw new Error('DOMNode.pseudoType() is expected to be defined.');
680
686
  }
681
- this.pseudoElementsInternal.set(pseudoType, node);
687
+ const currentPseudoElements = this.#pseudoElements.get(pseudoType);
688
+ if (currentPseudoElements) {
689
+ currentPseudoElements.push(node);
690
+ } else {
691
+ this.#pseudoElements.set(pseudoType, [node]);
692
+ }
682
693
  }
683
694
  }
684
695
 
@@ -960,6 +971,11 @@ export namespace DOMNode {
960
971
  Before = 'before',
961
972
  After = 'after',
962
973
  Marker = 'marker',
974
+ PageTransition = 'page-transition',
975
+ PageTransitionContainer = 'page-transition-container',
976
+ PageTransitionImageWrapper = 'page-transition-image-wrapper',
977
+ PageTransitionOutgoingImage = 'page-transition-outgoing-image',
978
+ PageTransitionIncomingImage = 'page-transition-incoming-image',
963
979
  }
964
980
 
965
981
  // TODO(crbug.com/1167717): Make this a const enum again
@@ -1375,11 +1391,15 @@ export class DOMModel extends SDKModel<EventTypes> {
1375
1391
  if (!pseudoType) {
1376
1392
  throw new Error('DOMModel._pseudoElementAdded expects pseudoType to be defined.');
1377
1393
  }
1378
- const previousPseudoType = parent.pseudoElements().get(pseudoType);
1379
- if (previousPseudoType) {
1380
- throw new Error('DOMModel._pseudoElementAdded expects parent to not already have this pseudo type added.');
1394
+ const currentPseudoElements = parent.pseudoElements().get(pseudoType);
1395
+ if (currentPseudoElements) {
1396
+ Platform.DCHECK(
1397
+ () => pseudoType.startsWith('page-transition'),
1398
+ 'DOMModel.pseudoElementAdded expects parent to not already have this pseudo type added; only page-transition* pseudo elements can coexist under the same parent.');
1399
+ currentPseudoElements.push(node);
1400
+ } else {
1401
+ parent.pseudoElements().set(pseudoType, [node]);
1381
1402
  }
1382
- parent.pseudoElements().set(pseudoType, node);
1383
1403
  this.dispatchEventToListeners(Events.NodeInserted, node);
1384
1404
  this.scheduleMutationEvent(node);
1385
1405
  }
@@ -1420,7 +1440,9 @@ export class DOMModel extends SDKModel<EventTypes> {
1420
1440
  }
1421
1441
  const pseudoElements = node.pseudoElements();
1422
1442
  for (const value of pseudoElements.values()) {
1423
- this.unbind(value);
1443
+ for (const pseudoElement of value) {
1444
+ this.unbind(pseudoElement);
1445
+ }
1424
1446
  }
1425
1447
  const templateContent = node.templateContent();
1426
1448
  if (templateContent) {
@@ -64,7 +64,7 @@ ElementsTestRunner.findNode = async function(matchFunction, callback) {
64
64
  }
65
65
 
66
66
  const pseudoElementsMap = node.pseudoElements();
67
- const pseudoElements = pseudoElementsMap ? [...pseudoElementsMap.values()] : [];
67
+ const pseudoElements = pseudoElementsMap ? [...pseudoElementsMap.values()].flat() : [];
68
68
  const children = (node.children() || []).concat(node.shadowRoots()).concat(pseudoElements);
69
69
  if (node.templateContent()) {
70
70
  children.push(node.templateContent());
@@ -133,7 +133,7 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
133
133
  }
134
134
 
135
135
  const debuggerModel = script.debuggerModel;
136
- const uiSourceCode = await this.getUpdatedUISourceCode(script);
136
+ const uiSourceCode = await this.getUISourceCodeWithUpdatedBreakpointInfo(script);
137
137
  if (this.#hasBreakpointsForUrl(script.sourceURL)) {
138
138
  await this.#restoreBreakpointsForUrl(uiSourceCode);
139
139
  }
@@ -165,7 +165,8 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
165
165
  }
166
166
  }
167
167
 
168
- async getUpdatedUISourceCode(script: SDK.Script.Script): Promise<Workspace.UISourceCode.UISourceCode> {
168
+ async getUISourceCodeWithUpdatedBreakpointInfo(script: SDK.Script.Script):
169
+ Promise<Workspace.UISourceCode.UISourceCode> {
169
170
  const isSnippet = script.sourceURL.startsWith('snippet://');
170
171
  const projectType = isSnippet ? Workspace.Workspace.projectTypes.Network : undefined;
171
172
 
@@ -8,6 +8,7 @@ import * as Platform from '../../core/platform/platform.js';
8
8
  import * as Root from '../../core/root/root.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
10
  import * as Protocol from '../../generated/protocol.js';
11
+ import * as Bindings from '../bindings/bindings.js';
11
12
  import * as Workspace from '../workspace/workspace.js';
12
13
 
13
14
  import type {FileSystem} from './FileSystemWorkspaceBinding.js';
@@ -35,6 +36,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
35
36
  private enabled: boolean;
36
37
  private eventDescriptors: Common.EventTarget.EventDescriptor[];
37
38
  #headerOverridesMap: Map<Platform.DevToolsPath.EncodedPathString, HeaderOverrideWithRegex[]> = new Map();
39
+ readonly #sourceCodeToBindProcessMutex = new WeakMap<Workspace.UISourceCode.UISourceCode, Common.Mutex.Mutex>();
38
40
 
39
41
  private constructor(workspace: Workspace.Workspace.WorkspaceImpl) {
40
42
  super();
@@ -66,6 +68,8 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
66
68
  });
67
69
 
68
70
  PersistenceImpl.instance().addNetworkInterceptor(this.canHandleNetworkUISourceCode.bind(this));
71
+ Bindings.BreakpointManager.BreakpointManager.instance().addUpdateBindingsCallback(
72
+ this.networkUISourceCodeAdded.bind(this));
69
73
 
70
74
  this.eventDescriptors = [];
71
75
  void this.enabledChanged();
@@ -301,24 +305,63 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
301
305
  return path;
302
306
  }
303
307
 
304
- private async unbind(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
308
+ async #unbind(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
305
309
  const binding = this.bindings.get(uiSourceCode);
306
310
  if (binding) {
307
- this.bindings.delete(binding.network);
308
- this.bindings.delete(binding.fileSystem);
309
- await PersistenceImpl.instance().removeBinding(binding);
311
+ const mutex = this.#getOrCreateMutex(binding.network);
312
+ const release = await mutex.acquire();
313
+ await this.#innerUnbind(binding);
314
+ release();
310
315
  }
311
316
  }
312
317
 
313
- private async bind(
318
+ async #unbindUnguarded(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
319
+ const binding = this.bindings.get(uiSourceCode);
320
+ if (binding) {
321
+ await this.#innerUnbind(binding);
322
+ }
323
+ }
324
+
325
+ #innerUnbind(binding: PersistenceBinding): Promise<void> {
326
+ this.bindings.delete(binding.network);
327
+ this.bindings.delete(binding.fileSystem);
328
+ return PersistenceImpl.instance().removeBinding(binding);
329
+ }
330
+
331
+ async #bind(
314
332
  networkUISourceCode: Workspace.UISourceCode.UISourceCode,
315
333
  fileSystemUISourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
316
- if (this.bindings.has(networkUISourceCode)) {
317
- await this.unbind(networkUISourceCode);
334
+ const mutex = this.#getOrCreateMutex(networkUISourceCode);
335
+ const release = await mutex.acquire();
336
+ try {
337
+ const existingBinding = this.bindings.get(networkUISourceCode);
338
+ if (existingBinding) {
339
+ const {network, fileSystem} = existingBinding;
340
+ if (networkUISourceCode === network && fileSystemUISourceCode === fileSystem) {
341
+ return;
342
+ }
343
+ }
344
+
345
+ await this.#unbindUnguarded(networkUISourceCode);
346
+ await this.#unbindUnguarded(fileSystemUISourceCode);
347
+ await this.#innerAddBinding(networkUISourceCode, fileSystemUISourceCode);
348
+ } finally {
349
+ release();
318
350
  }
319
- if (this.bindings.has(fileSystemUISourceCode)) {
320
- await this.unbind(fileSystemUISourceCode);
351
+ }
352
+
353
+ #getOrCreateMutex(networkUISourceCode: Workspace.UISourceCode.UISourceCode): Common.Mutex.Mutex {
354
+ let mutex = this.#sourceCodeToBindProcessMutex.get(networkUISourceCode);
355
+ if (!mutex) {
356
+ mutex = new Common.Mutex.Mutex();
357
+ this.#sourceCodeToBindProcessMutex.set(networkUISourceCode, mutex);
321
358
  }
359
+ return mutex;
360
+ }
361
+
362
+ async #innerAddBinding(
363
+ networkUISourceCode: Workspace.UISourceCode.UISourceCode,
364
+ fileSystemUISourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
322
365
  const binding = new PersistenceBinding(networkUISourceCode, fileSystemUISourceCode);
323
366
  this.bindings.set(networkUISourceCode, binding);
324
367
  this.bindings.set(fileSystemUISourceCode, binding);
@@ -394,7 +437,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
394
437
  const project = this.projectInternal as FileSystem;
395
438
  const fileSystemUISourceCode = project.uiSourceCodeForURL(this.fileUrlFromNetworkUrl(url));
396
439
  if (fileSystemUISourceCode) {
397
- await this.bind(uiSourceCode, fileSystemUISourceCode);
440
+ await this.#bind(uiSourceCode, fileSystemUISourceCode);
398
441
  }
399
442
  }
400
443
 
@@ -408,7 +451,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
408
451
  const networkUISourceCode =
409
452
  this.networkUISourceCodeForEncodedPath.get(Common.ParsedURL.ParsedURL.join(relativePath, '/'));
410
453
  if (networkUISourceCode) {
411
- await this.bind(networkUISourceCode, uiSourceCode);
454
+ await this.#bind(networkUISourceCode, uiSourceCode);
412
455
  }
413
456
  }
414
457
 
@@ -521,7 +564,8 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
521
564
 
522
565
  private async networkUISourceCodeRemoved(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
523
566
  if (uiSourceCode.project().type() === Workspace.Workspace.projectTypes.Network) {
524
- await this.unbind(uiSourceCode);
567
+ await this.#unbind(uiSourceCode);
568
+ this.#sourceCodeToBindProcessMutex.delete(uiSourceCode);
525
569
  this.networkUISourceCodeForEncodedPath.delete(this.encodedPathFromUrl(uiSourceCode.url()));
526
570
  }
527
571
  }
@@ -532,7 +576,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
532
576
  }
533
577
  this.updateInterceptionPatterns();
534
578
  this.originalResponseContentPromises.delete(uiSourceCode);
535
- await this.unbind(uiSourceCode);
579
+ await this.#unbind(uiSourceCode);
536
580
  }
537
581
 
538
582
  async setProject(project: Workspace.Workspace.Project|null): Promise<void> {
@@ -1218,6 +1218,8 @@ export class ElementsTreeOutline extends
1218
1218
  visibleChildren.push(templateContent);
1219
1219
  }
1220
1220
 
1221
+ visibleChildren.push(...node.pageTransitionPseudoElements());
1222
+
1221
1223
  const markerPseudoElement = node.markerPseudoElement();
1222
1224
  if (markerPseudoElement) {
1223
1225
  visibleChildren.push(markerPseudoElement);
@@ -110,8 +110,14 @@ export class FilteredUISourceCodeListProvider extends QuickOpen.FilteredListWidg
110
110
  multiplier = 5;
111
111
  }
112
112
 
113
+ let contentTypeBonus = 0;
114
+ if (uiSourceCode.contentType().isFromSourceMap()) {
115
+ contentTypeBonus = 100;
116
+ // Maybe also have a bonus for being a script?
117
+ }
118
+
113
119
  const fullDisplayName = uiSourceCode.fullDisplayName();
114
- return score + multiplier * this.scorer.calculateScore(fullDisplayName, null);
120
+ return score + multiplier * (contentTypeBonus + this.scorer.calculateScore(fullDisplayName, null));
115
121
  }
116
122
 
117
123
  renderItem(itemIndex: number, query: string, titleElement: Element, subtitleElement: Element): void {
@@ -454,6 +454,9 @@ export class WebauthnPaneImpl extends UI.Widget.VBox implements
454
454
 
455
455
  #removeAuthenticatorSections(): void {
456
456
  this.#authenticatorsView.innerHTML = '';
457
+ for (const dataGrid of this.#dataGrids.values()) {
458
+ dataGrid.asWidget().detach();
459
+ }
457
460
  this.#dataGrids.clear();
458
461
  }
459
462
 
@@ -788,7 +791,11 @@ export class WebauthnPaneImpl extends UI.Widget.VBox implements
788
791
  child.remove();
789
792
  }
790
793
  }
791
- this.#dataGrids.delete(authenticatorId);
794
+ const dataGrid = this.#dataGrids.get(authenticatorId);
795
+ if (dataGrid) {
796
+ dataGrid.asWidget().detach();
797
+ this.#dataGrids.delete(authenticatorId);
798
+ }
792
799
 
793
800
  if (this.#model) {
794
801
  void this.#model.removeAuthenticator(authenticatorId);
@@ -25,7 +25,7 @@
25
25
  bottom: 0;
26
26
  left: 0;
27
27
  right: 0;
28
- overflow: overlay;
28
+ overflow: scroll;
29
29
  transform: translateZ(0);
30
30
  background-color: var(--color-background);
31
31
  }
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1010831"
58
+ "version": "1.0.1011873"
59
59
  }