chrome-devtools-frontend 1.0.958475 → 1.0.959105

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 (100) hide show
  1. package/AUTHORS +1 -0
  2. package/front_end/Images/generate-css-vars.js +12 -13
  3. package/front_end/core/i18n/locales/af.json +399 -354
  4. package/front_end/core/i18n/locales/am.json +399 -354
  5. package/front_end/core/i18n/locales/ar.json +399 -354
  6. package/front_end/core/i18n/locales/as.json +399 -354
  7. package/front_end/core/i18n/locales/az.json +399 -354
  8. package/front_end/core/i18n/locales/be.json +399 -354
  9. package/front_end/core/i18n/locales/bg.json +399 -354
  10. package/front_end/core/i18n/locales/bn.json +399 -354
  11. package/front_end/core/i18n/locales/bs.json +400 -355
  12. package/front_end/core/i18n/locales/ca.json +399 -354
  13. package/front_end/core/i18n/locales/cs.json +399 -354
  14. package/front_end/core/i18n/locales/cy.json +399 -354
  15. package/front_end/core/i18n/locales/da.json +399 -354
  16. package/front_end/core/i18n/locales/de.json +399 -354
  17. package/front_end/core/i18n/locales/el.json +399 -354
  18. package/front_end/core/i18n/locales/en-GB.json +420 -375
  19. package/front_end/core/i18n/locales/es-419.json +399 -354
  20. package/front_end/core/i18n/locales/es.json +399 -354
  21. package/front_end/core/i18n/locales/et.json +399 -354
  22. package/front_end/core/i18n/locales/eu.json +403 -358
  23. package/front_end/core/i18n/locales/fa.json +399 -354
  24. package/front_end/core/i18n/locales/fi.json +399 -354
  25. package/front_end/core/i18n/locales/fil.json +399 -354
  26. package/front_end/core/i18n/locales/fr-CA.json +399 -354
  27. package/front_end/core/i18n/locales/fr.json +399 -354
  28. package/front_end/core/i18n/locales/gl.json +399 -354
  29. package/front_end/core/i18n/locales/gu.json +399 -354
  30. package/front_end/core/i18n/locales/he.json +399 -354
  31. package/front_end/core/i18n/locales/hi.json +399 -354
  32. package/front_end/core/i18n/locales/hr.json +399 -354
  33. package/front_end/core/i18n/locales/hu.json +399 -354
  34. package/front_end/core/i18n/locales/hy.json +399 -354
  35. package/front_end/core/i18n/locales/id.json +399 -354
  36. package/front_end/core/i18n/locales/is.json +399 -354
  37. package/front_end/core/i18n/locales/it.json +399 -354
  38. package/front_end/core/i18n/locales/ja.json +399 -354
  39. package/front_end/core/i18n/locales/ka.json +399 -354
  40. package/front_end/core/i18n/locales/kk.json +400 -355
  41. package/front_end/core/i18n/locales/km.json +399 -354
  42. package/front_end/core/i18n/locales/kn.json +399 -354
  43. package/front_end/core/i18n/locales/ko.json +399 -354
  44. package/front_end/core/i18n/locales/ky.json +399 -354
  45. package/front_end/core/i18n/locales/lo.json +399 -354
  46. package/front_end/core/i18n/locales/lt.json +399 -354
  47. package/front_end/core/i18n/locales/lv.json +399 -354
  48. package/front_end/core/i18n/locales/mk.json +399 -354
  49. package/front_end/core/i18n/locales/ml.json +399 -354
  50. package/front_end/core/i18n/locales/mn.json +399 -354
  51. package/front_end/core/i18n/locales/mr.json +399 -354
  52. package/front_end/core/i18n/locales/ms.json +399 -354
  53. package/front_end/core/i18n/locales/my.json +399 -354
  54. package/front_end/core/i18n/locales/ne.json +399 -354
  55. package/front_end/core/i18n/locales/nl.json +399 -354
  56. package/front_end/core/i18n/locales/no.json +399 -354
  57. package/front_end/core/i18n/locales/or.json +399 -354
  58. package/front_end/core/i18n/locales/pa.json +410 -365
  59. package/front_end/core/i18n/locales/pl.json +399 -354
  60. package/front_end/core/i18n/locales/pt-PT.json +399 -354
  61. package/front_end/core/i18n/locales/pt.json +399 -354
  62. package/front_end/core/i18n/locales/ro.json +399 -354
  63. package/front_end/core/i18n/locales/ru.json +399 -354
  64. package/front_end/core/i18n/locales/si.json +399 -354
  65. package/front_end/core/i18n/locales/sk.json +399 -354
  66. package/front_end/core/i18n/locales/sl.json +399 -354
  67. package/front_end/core/i18n/locales/sq.json +399 -354
  68. package/front_end/core/i18n/locales/sr-Latn.json +399 -354
  69. package/front_end/core/i18n/locales/sr.json +399 -354
  70. package/front_end/core/i18n/locales/sv.json +399 -354
  71. package/front_end/core/i18n/locales/sw.json +399 -354
  72. package/front_end/core/i18n/locales/ta.json +405 -360
  73. package/front_end/core/i18n/locales/te.json +399 -354
  74. package/front_end/core/i18n/locales/th.json +399 -354
  75. package/front_end/core/i18n/locales/tr.json +399 -354
  76. package/front_end/core/i18n/locales/uk.json +399 -354
  77. package/front_end/core/i18n/locales/ur.json +399 -354
  78. package/front_end/core/i18n/locales/uz.json +399 -354
  79. package/front_end/core/i18n/locales/vi.json +399 -354
  80. package/front_end/core/i18n/locales/zh-HK.json +399 -354
  81. package/front_end/core/i18n/locales/zh-TW.json +399 -354
  82. package/front_end/core/i18n/locales/zh.json +399 -354
  83. package/front_end/core/i18n/locales/zu.json +399 -354
  84. package/front_end/core/platform/generate-dcheck.js +2 -2
  85. package/front_end/entrypoints/main/main-meta.ts +24 -24
  86. package/front_end/generated/SupportedCSSProperties.js +2 -2
  87. package/front_end/models/persistence/WorkspaceSettingsTab.ts +0 -1
  88. package/front_end/models/persistence/workspaceSettingsTab.css +3 -7
  89. package/front_end/panels/elements/ElementsPanel.ts +18 -14
  90. package/front_end/panels/elements/elementsPanel.css +6 -2
  91. package/front_end/panels/settings/settingsScreen.css +4 -3
  92. package/front_end/ui/legacy/filter.css +1 -0
  93. package/package.json +1 -1
  94. package/scripts/build/generate_css_js_files.js +8 -6
  95. package/scripts/build/generate_html_entrypoint.js +2 -1
  96. package/scripts/build/ninja/copy-file.js +2 -1
  97. package/scripts/build/ninja/copy-files.js +2 -1
  98. package/scripts/build/ninja/generate-declaration.js +2 -1
  99. package/scripts/build/ninja/node.gni +4 -1
  100. package/scripts/build/ninja/write-if-changed.js +27 -0
@@ -2,8 +2,8 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- const fs = require('fs');
6
5
  const path = require('path');
6
+ const {writeIfChanged} = require('../../../scripts/build/ninja/write-if-changed.js');
7
7
  const [, , targetGenDir] = process.argv;
8
8
 
9
9
  let functionImplementation = '';
@@ -16,6 +16,6 @@ if (process.argv.includes('--should-dcheck')) {
16
16
  `;
17
17
  }
18
18
 
19
- fs.writeFileSync(
19
+ writeIfChanged(
20
20
  path.join(targetGenDir, 'dcheck.js'),
21
21
  `export function DCHECK(condition, message = 'DCHECK') {${functionImplementation}}`);
@@ -672,6 +672,30 @@ Common.Settings.registerSettingExtension({
672
672
  ],
673
673
  });
674
674
 
675
+ // Not all locales that are supported should also be made available in the
676
+ // settings. Filter out pseudo locales e.g.
677
+ function filterLocalesForSettings(): string[] {
678
+ return i18n.i18n.getAllSupportedDevToolsLocales().filter(locale => locale !== 'en-XL');
679
+ }
680
+
681
+ Common.Settings.registerSettingExtension({
682
+ category: Common.Settings.SettingCategory.APPEARANCE,
683
+ storageType: Common.Settings.SettingStorageType.Synced,
684
+ settingName: 'language',
685
+ settingType: Common.Settings.SettingType.ENUM,
686
+ title: i18nLazyString(UIStrings.language),
687
+ defaultValue: 'en-US',
688
+ options: [
689
+ {
690
+ value: 'browserLanguage',
691
+ title: i18nLazyString(UIStrings.browserLanguage),
692
+ text: i18nLazyString(UIStrings.browserLanguage),
693
+ },
694
+ ...filterLocalesForSettings().map(locale => createOptionForLocale(locale)),
695
+ ],
696
+ reloadRequired: true,
697
+ });
698
+
675
699
  Common.Settings.registerSettingExtension({
676
700
  category: Common.Settings.SettingCategory.APPEARANCE,
677
701
  storageType: Common.Settings.SettingStorageType.Synced,
@@ -743,30 +767,6 @@ function createOptionForLocale(localeString: string): Common.Settings.SettingExt
743
767
  };
744
768
  }
745
769
 
746
- // Not all locales that are supported should also be made available in the
747
- // settings. Filter out pseudo locales e.g.
748
- function filterLocalesForSettings(): string[] {
749
- return i18n.i18n.getAllSupportedDevToolsLocales().filter(locale => locale !== 'en-XL');
750
- }
751
-
752
- Common.Settings.registerSettingExtension({
753
- category: Common.Settings.SettingCategory.APPEARANCE,
754
- storageType: Common.Settings.SettingStorageType.Synced,
755
- settingName: 'language',
756
- settingType: Common.Settings.SettingType.ENUM,
757
- title: i18nLazyString(UIStrings.language),
758
- defaultValue: 'en-US',
759
- options: [
760
- {
761
- value: 'browserLanguage',
762
- title: i18nLazyString(UIStrings.browserLanguage),
763
- text: i18nLazyString(UIStrings.browserLanguage),
764
- },
765
- ...filterLocalesForSettings().map(locale => createOptionForLocale(locale)),
766
- ],
767
- reloadRequired: true,
768
- });
769
-
770
770
  Common.Settings.registerSettingExtension({
771
771
  category: Common.Settings.SettingCategory.SYNC,
772
772
  // This name must be kept in sync with DevToolsSettings::kSyncDevToolsPreferencesFrontendName.
@@ -582,7 +582,7 @@ export const generatedProperties = [
582
582
  'name': 'mix-blend-mode',
583
583
  'keywords': [
584
584
  'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
585
- 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
585
+ 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'plus-lighter'
586
586
  ]
587
587
  },
588
588
  {'name': 'negative'},
@@ -1086,7 +1086,7 @@ export const generatedPropertyValues = {
1086
1086
  'mix-blend-mode': {
1087
1087
  'values': [
1088
1088
  'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
1089
- 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
1089
+ 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'plus-lighter'
1090
1090
  ]
1091
1091
  },
1092
1092
  'object-fit': {'values': ['fill', 'contain', 'cover', 'none', 'scale-down']},
@@ -106,7 +106,6 @@ export class WorkspaceSettingsTab extends UI.Widget.VBox {
106
106
  const inputElement = UI.UIUtils.createInput('', 'text');
107
107
  UI.ARIAUtils.bindLabelToControl(labelElement, inputElement);
108
108
  p.appendChild(inputElement);
109
- inputElement.style.width = '270px';
110
109
  const folderExcludeSetting = IsolatedFileSystemManager.instance().workspaceFolderExcludePatternSetting();
111
110
  const setValue =
112
111
  UI.UIUtils.bindInput(inputElement, folderExcludeSetting.set.bind(folderExcludeSetting), regexValidator, false);
@@ -32,11 +32,6 @@
32
32
  column-width: 308px;
33
33
  }
34
34
 
35
- .workspace-settings-tab .settings-tab label {
36
- padding-right: 4px;
37
- display: inline-flex;
38
- }
39
-
40
35
  .workspace-settings-tab .settings-container-wrapper {
41
36
  position: absolute;
42
37
  top: 31px;
@@ -57,12 +52,13 @@
57
52
  }
58
53
 
59
54
  .workspace-settings-tab p.folder-exclude-pattern {
60
- display: flex;
55
+ display: grid;
61
56
  align-items: center;
62
57
  }
63
58
 
64
59
  .workspace-settings-tab p.folder-exclude-pattern > input {
65
- flex: auto;
60
+ width: 80%;
61
+ margin-left: 10px;
66
62
  }
67
63
 
68
64
  .workspace-settings-tab .settings-tab .file-system-container {
@@ -167,7 +167,8 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
167
167
  UI.View.ViewLocationResolver {
168
168
  private splitWidget: UI.SplitWidget.SplitWidget;
169
169
  private readonly searchableViewInternal: UI.SearchableView.SearchableView;
170
- private contentElementInternal: HTMLDivElement;
170
+ private mainContainer: HTMLDivElement;
171
+ private domTreeContainer: HTMLDivElement;
171
172
  private splitMode: _splitMode|null;
172
173
  private readonly accessibilityTreeView: AccessibilityTreeView|undefined;
173
174
  private breadcrumbs: ElementsComponents.ElementsBreadcrumbs.ElementsBreadcrumbs;
@@ -211,24 +212,27 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
211
212
  this.searchableViewInternal.setPlaceholder(i18nString(UIStrings.findByStringSelectorOrXpath));
212
213
  const stackElement = this.searchableViewInternal.element;
213
214
 
214
- this.contentElementInternal = document.createElement('div');
215
+ this.mainContainer = document.createElement('div');
216
+ this.domTreeContainer = document.createElement('div');
215
217
  const crumbsContainer = document.createElement('div');
216
218
  if (Root.Runtime.experiments.isEnabled('fullAccessibilityTree')) {
217
219
  this.initializeFullAccessibilityTreeView();
218
220
  }
219
- stackElement.appendChild(this.contentElementInternal);
221
+ this.mainContainer.appendChild(this.domTreeContainer);
222
+ stackElement.appendChild(this.mainContainer);
220
223
  stackElement.appendChild(crumbsContainer);
221
224
 
222
- UI.ARIAUtils.markAsMain(this.contentElementInternal);
223
- UI.ARIAUtils.setAccessibleName(this.contentElementInternal, i18nString(UIStrings.domTreeExplorer));
225
+ UI.ARIAUtils.markAsMain(this.domTreeContainer);
226
+ UI.ARIAUtils.setAccessibleName(this.domTreeContainer, i18nString(UIStrings.domTreeExplorer));
224
227
 
225
228
  this.splitWidget.setMainWidget(this.searchableViewInternal);
226
229
  this.splitMode = null;
227
230
 
228
- this.contentElementInternal.id = 'elements-content';
231
+ this.mainContainer.id = 'main-content';
232
+ this.domTreeContainer.id = 'elements-content';
229
233
  // FIXME: crbug.com/425984
230
234
  if (Common.Settings.Settings.instance().moduleSetting('domWordWrap').get()) {
231
- this.contentElementInternal.classList.add('elements-wrap');
235
+ this.domTreeContainer.classList.add('elements-wrap');
232
236
  }
233
237
  Common.Settings.Settings.instance()
234
238
  .moduleSetting('domWordWrap')
@@ -282,7 +286,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
282
286
  this.domTreeButton = createAccessibilityTreeToggleButton(true);
283
287
  this.domTreeButton.addEventListener('click', this.showDOMTree.bind(this));
284
288
 
285
- this.contentElementInternal.appendChild(this.accessibilityTreeButton);
289
+ this.mainContainer.appendChild(this.accessibilityTreeButton);
286
290
  }
287
291
 
288
292
  private showAccessibilityTree(): void {
@@ -433,12 +437,12 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
433
437
 
434
438
  for (const treeOutline of this.treeOutlines) {
435
439
  // Attach heavy component lazily
436
- if (treeOutline.element.parentElement !== this.contentElementInternal) {
440
+ if (treeOutline.element.parentElement !== this.domTreeContainer) {
437
441
  const header = this.treeOutlineHeaders.get(treeOutline);
438
442
  if (header) {
439
- this.contentElementInternal.appendChild(header);
443
+ this.domTreeContainer.appendChild(header);
440
444
  }
441
- this.contentElementInternal.appendChild(treeOutline.element);
445
+ this.domTreeContainer.appendChild(treeOutline.element);
442
446
  }
443
447
  }
444
448
 
@@ -469,10 +473,10 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
469
473
  for (const treeOutline of this.treeOutlines) {
470
474
  treeOutline.setVisible(false);
471
475
  // Detach heavy component on hide
472
- this.contentElementInternal.removeChild(treeOutline.element);
476
+ this.domTreeContainer.removeChild(treeOutline.element);
473
477
  const header = this.treeOutlineHeaders.get(treeOutline);
474
478
  if (header) {
475
- this.contentElementInternal.removeChild(header);
479
+ this.domTreeContainer.removeChild(header);
476
480
  }
477
481
  }
478
482
  super.willHide();
@@ -668,7 +672,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
668
672
  }
669
673
 
670
674
  private domWordWrapSettingChanged(event: Common.EventTarget.EventTargetEvent<boolean>): void {
671
- this.contentElementInternal.classList.toggle('elements-wrap', event.data);
675
+ this.domTreeContainer.classList.toggle('elements-wrap', event.data);
672
676
  for (const treeOutline of this.treeOutlines) {
673
677
  treeOutline.setWordWrap(event.data);
674
678
  }
@@ -27,11 +27,15 @@
27
27
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
  */
29
29
 
30
- #elements-content {
30
+ #main-content {
31
+ position: relative;
31
32
  flex: 1 1;
33
+ }
34
+
35
+ #elements-content {
32
36
  overflow: auto;
33
37
  padding: 2px 0 0;
34
- position: relative;
38
+ height: 100%;
35
39
  }
36
40
 
37
41
  .style-panes-wrapper {
@@ -80,9 +80,9 @@ fieldset {
80
80
  align-items: center;
81
81
  }
82
82
 
83
- .experiments-filter label {
83
+ label {
84
84
  padding-right: 8px;
85
- flex-shrink: 0;
85
+ padding-bottom: 8px;
86
86
  }
87
87
 
88
88
  .settings-tab p {
@@ -95,7 +95,7 @@ fieldset {
95
95
 
96
96
  .settings-select {
97
97
  align-items: center;
98
- display: flex;
98
+ display: grid;
99
99
  }
100
100
 
101
101
  .settings-experiments-warning-subsection-warning {
@@ -174,6 +174,7 @@ fieldset {
174
174
 
175
175
  .settings-tab select {
176
176
  margin-left: 10px;
177
+ width: 80%;
177
178
  }
178
179
 
179
180
  .settings-experiment {
@@ -65,6 +65,7 @@
65
65
  border-radius: 6px;
66
66
  overflow: hidden;
67
67
  cursor: pointer;
68
+ line-height: 1.2;
68
69
  }
69
70
 
70
71
  .filter-bitset-filter span:focus-visible {
package/package.json CHANGED
@@ -53,5 +53,5 @@
53
53
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
54
54
  "watch": "third_party/node/node.py --output scripts/watch_build.js"
55
55
  },
56
- "version": "1.0.958475"
56
+ "version": "1.0.959105"
57
57
  }
@@ -4,6 +4,7 @@
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
  const CleanCSS = require('clean-css');
7
+ const {writeIfChanged} = require('./ninja/write-if-changed.js');
7
8
  const [, , buildTimestamp, isDebugString, legacyString, targetName, srcDir, targetGenDir, files] = process.argv;
8
9
 
9
10
  const filenames = files.split(',');
@@ -34,21 +35,22 @@ export default styles;`;
34
35
  }
35
36
 
36
37
  const generatedFileName = `${fileName}${isLegacy ? '.legacy' : ''}.js`;
37
-
38
- fs.writeFileSync(
39
- path.join(targetGenDir, generatedFileName),
40
- `// Copyright ${new Date(Number(buildTimestamp) * 1000).getFullYear()} The Chromium Authors. All rights reserved.
38
+ const generatedFileLocation = path.join(targetGenDir, generatedFileName);
39
+ const newContents = `// Copyright ${
40
+ new Date(Number(buildTimestamp) * 1000).getUTCFullYear()} The Chromium Authors. All rights reserved.
41
41
  // Use of this source code is governed by a BSD-style license that can be
42
42
  // found in the LICENSE file.
43
43
  // IMPORTANT: this file is auto generated. Please do not edit this file.
44
44
  /* istanbul ignore file */
45
45
  ${exportStatement}
46
- `);
46
+ `;
47
+
48
+ writeIfChanged(generatedFileLocation, newContents);
47
49
 
48
50
  configFiles.push(`\"${generatedFileName}\"`);
49
51
  }
50
52
 
51
- fs.writeFileSync(path.join(targetGenDir, `${targetName}-tsconfig.json`), `{
53
+ writeIfChanged(path.join(targetGenDir, `${targetName}-tsconfig.json`), `{
52
54
  "compilerOptions": {
53
55
  "composite": true,
54
56
  "outDir": "."
@@ -5,6 +5,7 @@
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
  const {argv} = require('yargs');
8
+ const {writeIfChanged} = require('./ninja/write-if-changed.js');
8
9
 
9
10
  const {template} = argv;
10
11
 
@@ -32,5 +33,5 @@ const templateContent = fs.readFileSync(template, 'utf-8');
32
33
 
33
34
  for (const entrypoint of entrypoints) {
34
35
  const rewrittenTemplateContent = templateContent.replace(new RegExp('%ENTRYPOINT_NAME%', 'g'), entrypoint);
35
- fs.writeFileSync(path.join(outDirectory, `${entrypoint}.html`), rewrittenTemplateContent);
36
+ writeIfChanged(path.join(outDirectory, `${entrypoint}.html`), rewrittenTemplateContent);
36
37
  }
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const {writeIfChanged} = require('./write-if-changed.js');
6
7
  const [, , src, dest] = process.argv;
7
8
 
8
9
  const srcPath = path.join(process.cwd(), src);
@@ -23,7 +24,7 @@ if (fileExists(destPath)) {
23
24
  // Force a write to the target filesystem, since by default the ninja
24
25
  // toolchain will create a hardlink, which in turn reflects changes in
25
26
  // gen and resources/inspector back to //front_end.
26
- fs.writeFileSync(destPath, srcContents);
27
+ writeIfChanged(destPath, srcContents);
27
28
 
28
29
  /**
29
30
  * Case sensitive implementation of a file look up.
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const {writeIfChanged} = require('./write-if-changed.js');
6
7
  const [, , src, dest, files] = process.argv;
7
8
 
8
9
  for (const file of files.split(',')) {
@@ -24,7 +25,7 @@ for (const file of files.split(',')) {
24
25
  // Force a write to the target filesystem, since by default the ninja
25
26
  // toolchain will create a hardlink, which in turn reflects changes in
26
27
  // gen and resources/inspector back to //front_end.
27
- fs.writeFileSync(destPath, srcContents);
28
+ writeIfChanged(destPath, srcContents);
28
29
  }
29
30
 
30
31
  /**
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const {writeIfChanged} = require('./write-if-changed.js');
6
7
 
7
8
  const [, , outputDirectory, entrypointName] = process.argv;
8
9
 
@@ -13,4 +14,4 @@ const outputLocation = path.join(outputDirectory, `${rawFileName}.d.ts`);
13
14
  // We can't use copy here, as that would maintain the original file timestamps.
14
15
  // This can throw off Ninja, which verifies that timestamps of generated files
15
16
  // are the same as the timestamp it ran the action on.
16
- fs.writeFileSync(outputLocation, fs.readFileSync(inputLocation));
17
+ writeIfChanged(outputLocation, fs.readFileSync(inputLocation));
@@ -20,7 +20,10 @@ template("node_action") {
20
20
 
21
21
  _full_script_location = devtools_location_prepend + invoker.script
22
22
 
23
- inputs += [ _full_script_location ]
23
+ inputs += [
24
+ _full_script_location,
25
+ devtools_location_prepend + "scripts/build/ninja/write-if-changed.js",
26
+ ]
24
27
 
25
28
  args = [ rebase_path(_full_script_location, root_build_dir) ] + invoker.args
26
29
  }
@@ -0,0 +1,27 @@
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
+ const fs = require('fs');
6
+
7
+ /**
8
+ * Only write content to a file if the content is different that what it previously contained.
9
+ * The reason for only writing when necessary is that GN uses file timestamps to determine freshness.
10
+ * Therefore, if the file contents hasn't changed, but the timestamp has, GN thinks the file is new.
11
+ *
12
+ * Instead, we can only write when the content is changed, meaning we don't touch a file when it is
13
+ * unchanged. This would preserve the original file timestamps and hence GN can correctly conclude
14
+ * the file output hasn't changed.
15
+ *
16
+ * @param {string} generatedFileLocation Location to write to
17
+ * @param {string} newContents The contents to write (or noop if unchanged with previous content)
18
+ */
19
+ module.exports.writeIfChanged = (generatedFileLocation, newContents) => {
20
+ if (fs.existsSync(generatedFileLocation)) {
21
+ if (fs.readFileSync(generatedFileLocation, {encoding: 'utf8', flag: 'r'}) === newContents) {
22
+ return;
23
+ }
24
+ }
25
+
26
+ fs.writeFileSync(generatedFileLocation, newContents, {encoding: 'utf-8'});
27
+ };