chrome-devtools-frontend 1.0.933401 → 1.0.934332

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 (26) hide show
  1. package/config/gni/devtools_grd_files.gni +3 -0
  2. package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -1
  3. package/front_end/core/i18n/locales/en-US.json +21 -0
  4. package/front_end/core/i18n/locales/en-XL.json +21 -0
  5. package/front_end/core/platform/string-utilities.ts +3 -3
  6. package/front_end/core/sdk/ChildTargetManager.ts +2 -2
  7. package/front_end/core/sdk/DOMModel.ts +5 -9
  8. package/front_end/panels/animation/animationTimeline.css +5 -5
  9. package/front_end/panels/application/BackForwardCacheView.ts +50 -19
  10. package/front_end/panels/application/backForwardCacheView.css +4 -0
  11. package/front_end/panels/console/ConsoleContextSelector.ts +1 -1
  12. package/front_end/panels/console/ConsoleViewMessage.ts +8 -3
  13. package/front_end/panels/elements/components/adornerSettingsPane.css +4 -0
  14. package/front_end/panels/help/releaseNote.css +2 -2
  15. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +0 -5
  16. package/front_end/panels/sensors/sensors.css +1 -1
  17. package/front_end/panels/settings/SettingsScreen.ts +31 -8
  18. package/front_end/panels/settings/components/SyncSection.ts +118 -0
  19. package/front_end/panels/settings/components/components.ts +9 -0
  20. package/front_end/panels/settings/components/syncSection.css +59 -0
  21. package/front_end/panels/settings/keybindsSettingsTab.css +1 -1
  22. package/front_end/ui/components/settings/SettingCheckbox.ts +9 -2
  23. package/front_end/ui/legacy/tabbedPane.css +1 -1
  24. package/front_end/ui/legacy/themeColors.css +4 -0
  25. package/front_end/ui/legacy/toolbar.css +18 -4
  26. package/package.json +1 -1
@@ -430,6 +430,7 @@ grd_files_release_sources = [
430
430
  "front_end/panels/security/security_module.js",
431
431
  "front_end/panels/sensors/sensors-meta.js",
432
432
  "front_end/panels/sensors/sensors.js",
433
+ "front_end/panels/settings/components/components.js",
433
434
  "front_end/panels/settings/emulation/components/components.js",
434
435
  "front_end/panels/settings/emulation/emulation-meta.js",
435
436
  "front_end/panels/settings/emulation/emulation.js",
@@ -1186,6 +1187,8 @@ grd_files_debug_sources = [
1186
1187
  "front_end/panels/settings/FrameworkIgnoreListSettingsTab.js",
1187
1188
  "front_end/panels/settings/KeybindsSettingsTab.js",
1188
1189
  "front_end/panels/settings/SettingsScreen.js",
1190
+ "front_end/panels/settings/components/SyncSection.js",
1191
+ "front_end/panels/settings/components/syncSection.css.js",
1189
1192
  "front_end/panels/settings/emulation/DevicesSettingsTab.js",
1190
1193
  "front_end/panels/settings/emulation/components/UserAgentClientHintsForm.js",
1191
1194
  "front_end/panels/settings/emulation/components/userAgentClientHintsForm.css.js",
@@ -330,7 +330,7 @@ export interface SyncInformation {
330
330
  /** Whether Chrome Sync is enabled and active */
331
331
  isSyncActive: boolean;
332
332
  /** Whether syncing of Chrome Settings is enabled via Chrome Sync is enabled */
333
- arePreferencesSynced: boolean;
333
+ arePreferencesSynced?: boolean;
334
334
  /** The email of the account used for syncing */
335
335
  accountEmail?: string;
336
336
  /** The image of the account used for syncing. Its a base64 encoded PNG */
@@ -2678,6 +2678,9 @@
2678
2678
  "panels/application/BackForwardCacheView.ts | circumstantial": {
2679
2679
  "message": "Not Actionable"
2680
2680
  },
2681
+ "panels/application/BackForwardCacheView.ts | circumstantialExplanation": {
2682
+ "message": "These reasons are not actionable i.e. caching was prevented by something outside of the direct control of the page."
2683
+ },
2681
2684
  "panels/application/BackForwardCacheView.ts | lastMainFrameNavigation": {
2682
2685
  "message": "Last Main Frame Navigation"
2683
2686
  },
@@ -2690,12 +2693,18 @@
2690
2693
  "panels/application/BackForwardCacheView.ts | pageSupportNeeded": {
2691
2694
  "message": "Actionable"
2692
2695
  },
2696
+ "panels/application/BackForwardCacheView.ts | pageSupportNeededExplanation": {
2697
+ "message": "These reasons are actionable i.e. they can be cleaned up to make the page eligible for back-forward cache."
2698
+ },
2693
2699
  "panels/application/BackForwardCacheView.ts | restoredFromBFCache": {
2694
2700
  "message": "Restored from back-forward cache"
2695
2701
  },
2696
2702
  "panels/application/BackForwardCacheView.ts | supportPending": {
2697
2703
  "message": "Pending Support"
2698
2704
  },
2705
+ "panels/application/BackForwardCacheView.ts | supportPendingExplanation": {
2706
+ "message": "Chrome support for these reasons is pending i.e. they will not prevent the page from being eligible for back-forward cache in a future version of Chrome."
2707
+ },
2699
2708
  "panels/application/BackForwardCacheView.ts | unavailable": {
2700
2709
  "message": "unavailable"
2701
2710
  },
@@ -8756,6 +8765,18 @@
8756
8765
  "panels/sensors/SensorsView.ts | timezoneId": {
8757
8766
  "message": "Timezone ID"
8758
8767
  },
8768
+ "panels/settings/components/SyncSection.ts | preferencesSyncDisabled": {
8769
+ "message": "To turn this setting on, you must first enable settings sync in Chrome."
8770
+ },
8771
+ "panels/settings/components/SyncSection.ts | settings": {
8772
+ "message": "Go to Settings"
8773
+ },
8774
+ "panels/settings/components/SyncSection.ts | signedIn": {
8775
+ "message": "Signed into Chrome as:"
8776
+ },
8777
+ "panels/settings/components/SyncSection.ts | syncDisabled": {
8778
+ "message": "To turn this setting on, you must enable Chrome sync."
8779
+ },
8759
8780
  "panels/settings/emulation/components/UserAgentClientHintsForm.ts | addBrand": {
8760
8781
  "message": "Add Brand"
8761
8782
  },
@@ -2678,6 +2678,9 @@
2678
2678
  "panels/application/BackForwardCacheView.ts | circumstantial": {
2679
2679
  "message": "N̂ót̂ Áĉt́îón̂áb̂ĺê"
2680
2680
  },
2681
+ "panels/application/BackForwardCacheView.ts | circumstantialExplanation": {
2682
+ "message": "T̂h́êśê ŕêáŝón̂ś âŕê ńôt́ âćt̂íôńâb́l̂é î.é. ĉáĉh́îńĝ ẃâś p̂ŕêv́êńt̂éd̂ b́ŷ śôḿêt́ĥín̂ǵ ôút̂śîd́ê óf̂ t́ĥé d̂ír̂éĉt́ ĉón̂t́r̂ól̂ óf̂ t́ĥé p̂áĝé."
2683
+ },
2681
2684
  "panels/application/BackForwardCacheView.ts | lastMainFrameNavigation": {
2682
2685
  "message": "L̂áŝt́ M̂áîń F̂ŕâḿê Ńâv́îǵât́îón̂"
2683
2686
  },
@@ -2690,12 +2693,18 @@
2690
2693
  "panels/application/BackForwardCacheView.ts | pageSupportNeeded": {
2691
2694
  "message": "Âćt̂íôńâb́l̂é"
2692
2695
  },
2696
+ "panels/application/BackForwardCacheView.ts | pageSupportNeededExplanation": {
2697
+ "message": "T̂h́êśê ŕêáŝón̂ś âŕê áĉt́îón̂áb̂ĺê í.ê. t́ĥéŷ ćâń b̂é ĉĺêán̂éd̂ úp̂ t́ô ḿâḱê t́ĥé p̂áĝé êĺîǵîb́l̂é f̂ór̂ b́âćk̂-f́ôŕŵár̂d́ ĉáĉh́ê."
2698
+ },
2693
2699
  "panels/application/BackForwardCacheView.ts | restoredFromBFCache": {
2694
2700
  "message": "R̂éŝt́ôŕêd́ f̂ŕôḿ b̂áĉḱ-f̂ór̂ẃâŕd̂ ćâćĥé"
2695
2701
  },
2696
2702
  "panels/application/BackForwardCacheView.ts | supportPending": {
2697
2703
  "message": "P̂én̂d́îńĝ Śûṕp̂ór̂t́"
2698
2704
  },
2705
+ "panels/application/BackForwardCacheView.ts | supportPendingExplanation": {
2706
+ "message": "Ĉh́r̂óm̂é ŝúp̂ṕôŕt̂ f́ôŕ t̂h́êśê ŕêáŝón̂ś îś p̂én̂d́îńĝ í.ê. t́ĥéŷ ẃîĺl̂ ńôt́ p̂ŕêv́êńt̂ t́ĥé p̂áĝé f̂ŕôḿ b̂éîńĝ él̂íĝíb̂ĺê f́ôŕ b̂áĉḱ-f̂ór̂ẃâŕd̂ ćâćĥé îń â f́ût́ûŕê v́êŕŝíôń ôf́ Ĉh́r̂óm̂é."
2707
+ },
2699
2708
  "panels/application/BackForwardCacheView.ts | unavailable": {
2700
2709
  "message": "ûńâv́âíl̂áb̂ĺê"
2701
2710
  },
@@ -8756,6 +8765,18 @@
8756
8765
  "panels/sensors/SensorsView.ts | timezoneId": {
8757
8766
  "message": "T̂ím̂éẑón̂é ÎD́"
8758
8767
  },
8768
+ "panels/settings/components/SyncSection.ts | preferencesSyncDisabled": {
8769
+ "message": "T̂ó t̂úr̂ń t̂h́îś ŝét̂t́îńĝ ón̂, ýôú m̂úŝt́ f̂ír̂śt̂ én̂áb̂ĺê śêt́t̂ín̂ǵŝ śŷńĉ ín̂ Ćĥŕôḿê."
8770
+ },
8771
+ "panels/settings/components/SyncSection.ts | settings": {
8772
+ "message": "Ĝó t̂ó Ŝét̂t́îńĝś"
8773
+ },
8774
+ "panels/settings/components/SyncSection.ts | signedIn": {
8775
+ "message": "Ŝíĝńêd́ îńt̂ó Ĉh́r̂óm̂é âś:"
8776
+ },
8777
+ "panels/settings/components/SyncSection.ts | syncDisabled": {
8778
+ "message": "T̂ó t̂úr̂ń t̂h́îś ŝét̂t́îńĝ ón̂, ýôú m̂úŝt́ êńâb́l̂é Ĉh́r̂óm̂é ŝýn̂ć."
8779
+ },
8759
8780
  "panels/settings/emulation/components/UserAgentClientHintsForm.ts | addBrand": {
8760
8781
  "message": "Âd́d̂ B́r̂án̂d́"
8761
8782
  },
@@ -240,9 +240,9 @@ const escapedReplacements = new Map([
240
240
  ['\v', '\\v'],
241
241
  ['\'', '\\\''],
242
242
  ['\\', '\\\\'],
243
- ['<!--', '<\\!--'],
244
- ['<script', '<\\script'],
245
- ['</script', '<\\/script'],
243
+ ['<!--', '\\x3C!--'],
244
+ ['<script', '\\x3Cscript'],
245
+ ['</script', '\\x3C/script'],
246
246
  ]);
247
247
 
248
248
  export const formatAsJSLiteral = (content: string): string => {
@@ -118,14 +118,14 @@ export class ChildTargetManager extends SDKModel<EventTypes> implements Protocol
118
118
  let targetName = '';
119
119
  if (targetInfo.type === 'worker' && targetInfo.title && targetInfo.title !== targetInfo.url) {
120
120
  targetName = targetInfo.title;
121
- } else if (targetInfo.type !== 'iframe') {
121
+ } else if (targetInfo.type !== 'iframe' && targetInfo.type !== 'webview') {
122
122
  const parsedURL = Common.ParsedURL.ParsedURL.fromString(targetInfo.url);
123
123
  targetName =
124
124
  parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + (++ChildTargetManager.lastAnonymousTargetId);
125
125
  }
126
126
 
127
127
  let type = Type.Browser;
128
- if (targetInfo.type === 'iframe') {
128
+ if (targetInfo.type === 'iframe' || targetInfo.type === 'webview') {
129
129
  type = Type.Frame;
130
130
  }
131
131
  // TODO(lfg): ensure proper capabilities for child pages (e.g. portals).
@@ -159,14 +159,14 @@ export class DOMNode {
159
159
  this.childrenInternal = [];
160
160
  }
161
161
 
162
+ const frameOwnerTags = ['IFRAME', 'PORTAL', 'EMBED', 'OBJECT'];
162
163
  if (payload.contentDocument) {
163
164
  this.contentDocumentInternal = new DOMDocument(this.#domModelInternal, payload.contentDocument);
164
165
  this.contentDocumentInternal.parentNode = this;
165
166
  this.childrenInternal = [];
166
- } else if ((payload.nodeName === 'IFRAME' || payload.nodeName === 'PORTAL') && payload.frameId) {
167
+ } else if (payload.frameId && frameOwnerTags.includes(payload.nodeName)) {
167
168
  // At this point we know we are in an OOPIF, otherwise #payload.contentDocument would have been set.
168
- this.childDocumentPromiseForTesting =
169
- this.createChildDocumentPromiseForTesting(payload.frameId, this.#domModelInternal.target());
169
+ this.childDocumentPromiseForTesting = this.requestChildDocument(payload.frameId, this.#domModelInternal.target());
170
170
  this.childrenInternal = [];
171
171
  }
172
172
 
@@ -205,14 +205,10 @@ export class DOMNode {
205
205
  }
206
206
  }
207
207
 
208
- private async createChildDocumentPromiseForTesting(frameId: Protocol.Page.FrameId, notInTarget: Target):
209
- Promise<DOMDocument|null> {
208
+ private async requestChildDocument(frameId: Protocol.Page.FrameId, notInTarget: Target): Promise<DOMDocument|null> {
210
209
  const frame = await FrameManager.instance().getOrWaitForFrame(frameId, notInTarget);
211
210
  const childModel = frame.resourceTreeModel()?.target().model(DOMModel);
212
- if (childModel) {
213
- return childModel.requestDocument();
214
- }
215
- return null;
211
+ return childModel?.requestDocument() || null;
216
212
  }
217
213
 
218
214
  isAdFrameNode(): boolean {
@@ -399,12 +399,12 @@ text.animation-timeline-grid-label {
399
399
  }
400
400
 
401
401
  .animation-playback-rate-button {
402
- border: 1px solid var(--color-details-hairline);
402
+ border: 1px solid var(--color-button-secondary-border);
403
403
  color: var(--color-text-primary);
404
404
  display: inline-block;
405
405
  margin-right: -1px;
406
406
  padding: 1px 4px;
407
- background: var(--color-background);
407
+ background-color: transparent;
408
408
  flex: 1 0 auto;
409
409
  text-align: center;
410
410
  cursor: pointer;
@@ -419,9 +419,9 @@ text.animation-timeline-grid-label {
419
419
  }
420
420
 
421
421
  .animation-playback-rate-button.selected {
422
- color: var(--legacy-selection-fg-color);
423
- background-color: var(--legacy-selection-bg-color);
424
- border-color: var(--legacy-selection-bg-color);
422
+ color: var(--color-button-primary-text);
423
+ background-color: var(--color-primary);
424
+ border-color: var(--color-primary);
425
425
  z-index: 1;
426
426
  }
427
427
 
@@ -9,6 +9,7 @@ import * as LitHtml from '../../ui/lit-html/lit-html.js';
9
9
  import * as ReportView from '../../ui/components/report_view/report_view.js';
10
10
  import * as UI from '../../ui/legacy/legacy.js';
11
11
  import * as Protocol from '../../generated/protocol.js';
12
+ import * as IconButton from '../../ui/components/icon_button/icon_button.js';
12
13
 
13
14
  import {NotRestoredReasonDescription} from './BackForwardCacheStrings.js';
14
15
  import backForwardCacheViewStyles from './backForwardCacheView.css.js';
@@ -53,21 +54,41 @@ const UIStrings = {
53
54
  */
54
55
  restoredFromBFCache: 'Restored from back-forward cache',
55
56
  /**
56
- * @description Category text for the reasons which need to be cleaned up on the websites in
57
- * order to make the page eligible for the back-forward cache.
57
+ * @description Label for a list of reasons which prevent the page from being eligible for
58
+ * back-forward cache. These reasons are actionable i.e. they can be cleaned up to make the
59
+ * page eligible for back-forward cache.
58
60
  */
59
61
  pageSupportNeeded: 'Actionable',
60
62
  /**
61
- * @description Category text for the reasons which are circumstantial and cannot be addressed
62
- * by developers.
63
+ * @description Explanation for actionable items which prevent the page from being eligible
64
+ * for back-forward cache.
65
+ */
66
+ pageSupportNeededExplanation:
67
+ 'These reasons are actionable i.e. they can be cleaned up to make the page eligible for back-forward cache.',
68
+ /**
69
+ * @description Label for a list of reasons which prevent the page from being eligible for
70
+ * back-forward cache. These reasons are circumstantial / not actionable i.e. they cannot be
71
+ * cleaned up by developers to make the page eligible for back-forward cache.
63
72
  */
64
73
  circumstantial: 'Not Actionable',
65
74
  /**
66
- * @description Explanation text appended to a reason why the usage of the back-forward cache
67
- * is not possible, if in a future version of Chrome this reason will not prevent the usage
68
- * of the back-forward cache anymore.
75
+ * @description Explanation for circumstantial/non-actionable items which prevent the page from being eligible
76
+ * for back-forward cache.
77
+ */
78
+ circumstantialExplanation:
79
+ 'These reasons are not actionable i.e. caching was prevented by something outside of the direct control of the page.',
80
+ /**
81
+ * @description Label for a list of reasons which prevent the page from being eligible for
82
+ * back-forward cache. These reasons are pending support by chrome i.e. in a future version
83
+ * of chrome they will not prevent back-forward cache usage anymore.
69
84
  */
70
85
  supportPending: 'Pending Support',
86
+ /**
87
+ * @description Explanation for 'pending support' items which prevent the page from being eligible
88
+ * for back-forward cache.
89
+ */
90
+ supportPendingExplanation:
91
+ 'Chrome support for these reasons is pending i.e. they will not prevent the page from being eligible for back-forward cache in a future version of Chrome.',
71
92
  };
72
93
  const str_ = i18n.i18n.registerUIStrings('panels/application/BackForwardCacheView.ts', UIStrings);
73
94
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -160,25 +181,35 @@ export class BackForwardCacheView extends UI.ThrottledWidget.ThrottledWidget {
160
181
  // Disabled until https://crbug.com/1079231 is fixed.
161
182
  // clang-format off
162
183
  return LitHtml.html`
163
- ${this.renderExplanations(UIStrings.pageSupportNeeded, pageSupportNeeded)}
164
- ${this.renderExplanations(UIStrings.supportPending, supportPending)}
165
- ${this.renderExplanations(UIStrings.circumstantial, circumstantial)}
184
+ ${this.renderExplanations(i18nString(UIStrings.pageSupportNeeded), i18nString(UIStrings.pageSupportNeededExplanation), pageSupportNeeded)}
185
+ ${this.renderExplanations(i18nString(UIStrings.supportPending), i18nString(UIStrings.supportPendingExplanation), supportPending)}
186
+ ${this.renderExplanations(i18nString(UIStrings.circumstantial), i18nString(UIStrings.circumstantialExplanation), circumstantial)}
166
187
  `;
167
188
  // clang-format on
168
189
  }
169
190
 
170
- private renderExplanations(category: string, explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[]):
171
- LitHtml.TemplateResult {
191
+ private renderExplanations(
192
+ category: Platform.UIString.LocalizedString, explainerText: Platform.UIString.LocalizedString,
193
+ explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[]): LitHtml.TemplateResult {
194
+ // Disabled until https://crbug.com/1079231 is fixed.
195
+ // clang-format off
172
196
  return LitHtml.html`
173
- ${
174
- explanations.length > 0 ? LitHtml.html`
175
- <${ReportView.ReportView.ReportKey.litTagName}>${category}</${ReportView.ReportView.ReportKey.litTagName}>
176
- <${ReportView.ReportView.ReportValue.litTagName}>
197
+ ${explanations.length > 0 ? LitHtml.html`
198
+ <${ReportView.ReportView.ReportKey.litTagName}>
199
+ ${category}
200
+ <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
201
+ iconName: 'help_outline',
202
+ color: 'var(--color-text-secondary)',
203
+ width: '16px',
204
+ height: '16px',
205
+ } as IconButton.Icon.IconData} title=${explainerText}></${IconButton.Icon.Icon.litTagName}>
206
+ </${ReportView.ReportView.ReportKey.litTagName}>
207
+ <${ReportView.ReportView.ReportValue.litTagName}>
177
208
  <ul class='not-restored-reason-list'>${explanations.map(explanation => this.renderReason(explanation))}</ul>
178
- </${ReportView.ReportView.ReportValue.litTagName}>
179
- ` :
180
- LitHtml.nothing}
209
+ </${ReportView.ReportView.ReportValue.litTagName}>
210
+ ` : LitHtml.nothing}
181
211
  `;
212
+ // clang-format on
182
213
  }
183
214
 
184
215
  private renderReason(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation): LitHtml.TemplateResult {
@@ -8,3 +8,7 @@
8
8
  list-style-type: none;
9
9
  padding-inline-start: 0;
10
10
  }
11
+
12
+ .inline-icon {
13
+ vertical-align: sub;
14
+ }
@@ -254,7 +254,7 @@ export class ConsoleContextSelector implements SDK.TargetManager.SDKModelObserve
254
254
  }
255
255
 
256
256
  itemSelected(item: SDK.RuntimeModel.ExecutionContext|null): void {
257
- this.toolbarItemInternal.element.classList.toggle('warning', !this.isTopContext(item) && this.hasTopContext());
257
+ this.toolbarItemInternal.element.classList.toggle('highlight', !this.isTopContext(item) && this.hasTopContext());
258
258
  const title = item ? i18nString(UIStrings.javascriptContextS, {PH1: this.titleFor(item)}) :
259
259
  i18nString(UIStrings.javascriptContextNotSelected);
260
260
  this.toolbarItemInternal.setTitle(title);
@@ -1650,9 +1650,14 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1650
1650
  const suffix = `${line.substring(link.positionRight)}${newline}`;
1651
1651
 
1652
1652
  formattedLine.appendChild(this.linkifyStringAsFragment(prefix));
1653
- const scriptLocationLink = this.linkifier.linkifyScriptLocation(
1654
- debuggerModel.target(), null, link.url, link.lineNumber,
1655
- {columnNumber: link.columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
1653
+ const scriptLocationLink =
1654
+ this.linkifier.linkifyScriptLocation(debuggerModel.target(), null, link.url, link.lineNumber, {
1655
+ columnNumber: link.columnNumber,
1656
+ className: undefined,
1657
+ tabStop: undefined,
1658
+ inlineFrameIndex: 0,
1659
+ showColumnNumber: true,
1660
+ });
1656
1661
  scriptLocationLink.tabIndex = -1;
1657
1662
  this.selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
1658
1663
  formattedLine.appendChild(scriptLocationLink);
@@ -65,3 +65,7 @@
65
65
  .close::after {
66
66
  transform: rotate(-45deg);
67
67
  }
68
+
69
+ :host-context(.-theme-with-dark-background) input[type="checkbox"] {
70
+ filter: invert(80%);
71
+ }
@@ -45,7 +45,7 @@
45
45
  }
46
46
 
47
47
  .release-note-container .release-note-link {
48
- border: 1px solid var(--color-details-hairline);
48
+ border: 1px solid var(--color-details-hairline-light);
49
49
  padding-left: 8px;
50
50
  padding-right: 8px;
51
51
  margin-bottom: 4px;
@@ -53,7 +53,7 @@
53
53
  }
54
54
 
55
55
  .release-note-container .release-note-link:hover {
56
- box-shadow: 0 0 0 1px var(--box-shadow-outline-color) inset;
56
+ border-color: var(--color-details-hairline);
57
57
  }
58
58
 
59
59
  .release-note-title,
@@ -51,11 +51,6 @@ export class LighthouseReportRenderer extends LighthouseReport.ReportRenderer {
51
51
  if (!container) {
52
52
  return;
53
53
  }
54
- const disclaimerEl = container.querySelector('.lh-metrics__disclaimer');
55
- // If it was a PWA-only run, we'd have a trace but no perf category to add the button to
56
- if (!disclaimerEl) {
57
- return;
58
- }
59
54
 
60
55
  const defaultPassTrace = artifacts.traces.defaultPass;
61
56
  const text = simulated ? i18nString(UIStrings.viewOriginalTrace) : i18nString(UIStrings.viewTrace);
@@ -293,7 +293,7 @@ fieldset.device-orientation-override-section {
293
293
  }
294
294
 
295
295
  button.text-button {
296
- margin: 0 10px;
296
+ margin: 4px 0 0 10px;
297
297
  }
298
298
 
299
299
  @media (forced-colors: active) {
@@ -35,6 +35,7 @@ import * as Root from '../../core/root/root.js';
35
35
  import * as IconButton from '../../ui/components/icon_button/icon_button.js';
36
36
  import * as Components from '../../ui/legacy/components/utils/utils.js';
37
37
  import * as UI from '../../ui/legacy/legacy.js';
38
+ import * as PanelComponents from './components/components.js';
38
39
 
39
40
  import settingsScreenStyles from './settingsScreen.css.js';
40
41
 
@@ -260,6 +261,8 @@ class SettingsTab extends UI.Widget.VBox {
260
261
  let genericSettingsTabInstance: GenericSettingsTab;
261
262
 
262
263
  export class GenericSettingsTab extends SettingsTab {
264
+ private readonly syncSection: PanelComponents.SyncSection.SyncSection = new PanelComponents.SyncSection.SyncSection();
265
+
263
266
  constructor() {
264
267
  super(i18nString(UIStrings.preferences), 'preferences-tab-content');
265
268
 
@@ -301,13 +304,7 @@ export class GenericSettingsTab extends SettingsTab {
301
304
  for (const sectionCategory of explicitSectionOrder) {
302
305
  const settingsForSection = preRegisteredSettings.filter(
303
306
  setting => setting.category === sectionCategory && GenericSettingsTab.isSettingVisible(setting));
304
-
305
- // Always create the EXTENSIONS section and append the link handling control.
306
- if (sectionCategory === Common.Settings.SettingCategory.EXTENSIONS) {
307
- this.createExtensionSection(settingsForSection);
308
- } else if (settingsForSection.length > 0) {
309
- this.createSectionElement(sectionCategory, settingsForSection);
310
- }
307
+ this.createSectionElement(sectionCategory, settingsForSection);
311
308
  }
312
309
 
313
310
  this.appendSection().appendChild(
@@ -335,17 +332,43 @@ export class GenericSettingsTab extends SettingsTab {
335
332
  return Boolean(title && setting.category);
336
333
  }
337
334
 
335
+ override wasShown(): void {
336
+ super.wasShown();
337
+ this.updateSyncSection();
338
+ }
339
+
340
+ private updateSyncSection(): void {
341
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.getSyncInformation(syncInfo => {
342
+ this.syncSection.data = {
343
+ syncInfo,
344
+ syncSetting: Common.Settings.moduleSetting('sync_preferences') as Common.Settings.Setting<boolean>,
345
+ };
346
+ });
347
+ }
348
+
338
349
  private createExtensionSection(settings: Common.Settings.SettingRegistration[]): void {
339
350
  const sectionName = Common.Settings.SettingCategory.EXTENSIONS;
340
351
  const settingUI = Components.Linkifier.LinkHandlerSettingUI.instance() as UI.SettingsUI.SettingUI;
341
352
  const element = settingUI.settingElement();
342
353
  if (element) {
343
- const sectionElement = this.createSectionElement(sectionName, settings);
354
+ const sectionElement = this.createStandardSectionElement(sectionName, settings);
344
355
  sectionElement.appendChild(element);
345
356
  }
346
357
  }
347
358
 
348
359
  private createSectionElement(
360
+ category: Common.Settings.SettingCategory, settings: Common.Settings.SettingRegistration[]): void {
361
+ // Always create the EXTENSIONS section and append the link handling control.
362
+ if (category === Common.Settings.SettingCategory.EXTENSIONS) {
363
+ this.createExtensionSection(settings);
364
+ } else if (category === Common.Settings.SettingCategory.SYNC && settings.length > 0) {
365
+ this.containerElement.appendChild(this.syncSection);
366
+ } else if (settings.length > 0) {
367
+ this.createStandardSectionElement(category, settings);
368
+ }
369
+ }
370
+
371
+ private createStandardSectionElement(
349
372
  category: Common.Settings.SettingCategory, settings: Common.Settings.SettingRegistration[]): Element {
350
373
  const uiSectionName = Common.Settings.getLocalizedSettingsCategory(category);
351
374
  const sectionElement = this.appendSection(uiSectionName);
@@ -0,0 +1,118 @@
1
+ // Copyright 2021 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 * as Common from '../../../core/common/common.js';
6
+ import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
7
+ import type * as Host from '../../../core/host/host.js';
8
+ import * as i18n from '../../../core/i18n/i18n.js';
9
+ import * as LitHtml from '../../../ui/lit-html/lit-html.js';
10
+ import * as Settings from '../../../ui/components/settings/settings.js';
11
+
12
+ import syncSectionStyles from './syncSection.css.js';
13
+
14
+ const UIStrings = {
15
+ /**
16
+ * @description Text shown to the user in the Settings UI. 'This setting' refers
17
+ * to a checkbox that is disabled.
18
+ */
19
+ syncDisabled: 'To turn this setting on, you must enable Chrome sync.',
20
+ /**
21
+ * @description Text shown to the user in the Settings UI. 'This setting' refers
22
+ * to a checkbox that is disabled.
23
+ */
24
+ preferencesSyncDisabled: 'To turn this setting on, you must first enable settings sync in Chrome.',
25
+ /**
26
+ * @description Label for a link that take the user to the "Sync" section of the
27
+ * chrome settings. The link is shown in the DevTools Settings UI.
28
+ */
29
+ settings: 'Go to Settings',
30
+ /**
31
+ * @description Label for the account email address. Shown in the DevTools Settings UI in
32
+ * front of the email address currently used for Chrome Sync.
33
+ */
34
+ signedIn: 'Signed into Chrome as:',
35
+ };
36
+ const str_ = i18n.i18n.registerUIStrings('panels/settings/components/SyncSection.ts', UIStrings);
37
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
38
+
39
+ export interface SyncSectionData {
40
+ syncInfo: Host.InspectorFrontendHostAPI.SyncInformation;
41
+ syncSetting: Common.Settings.Setting<boolean>;
42
+ }
43
+
44
+ export class SyncSection extends HTMLElement {
45
+ static readonly litTagName = LitHtml.literal`devtools-sync-section`;
46
+ private readonly shadow = this.attachShadow({mode: 'open'});
47
+
48
+ private syncInfo: Host.InspectorFrontendHostAPI.SyncInformation = {isSyncActive: false};
49
+ private syncSetting?: Common.Settings.Setting<boolean>;
50
+
51
+ private boundRender = this.render.bind(this);
52
+
53
+ connectedCallback(): void {
54
+ this.shadow.adoptedStyleSheets = [syncSectionStyles];
55
+ }
56
+
57
+ set data(data: SyncSectionData) {
58
+ this.syncInfo = data.syncInfo;
59
+ this.syncSetting = data.syncSetting;
60
+ ComponentHelpers.ScheduledRender.scheduleRender(this, this.boundRender);
61
+ }
62
+
63
+ private render(): void {
64
+ if (!this.syncSetting) {
65
+ throw new Error('SyncSection not properly initialized');
66
+ }
67
+
68
+ const checkboxDisabled = !this.syncInfo.isSyncActive || !this.syncInfo.arePreferencesSynced;
69
+ // Disabled until https://crbug.com/1079231 is fixed.
70
+ // clang-format off
71
+ LitHtml.render(LitHtml.html`
72
+ <fieldset>
73
+ <legend>${Common.Settings.getLocalizedSettingsCategory(Common.Settings.SettingCategory.SYNC)}</legend>
74
+ ${renderAccountInfoOrWarning(this.syncInfo)}
75
+ <${Settings.SettingCheckbox.SettingCheckbox.litTagName} .data=${
76
+ {setting: this.syncSetting, disabled: checkboxDisabled} as Settings.SettingCheckbox.SettingCheckboxData}>
77
+ </${Settings.SettingCheckbox.SettingCheckbox.litTagName}>
78
+ </fieldset>
79
+ `, this.shadow, {host: this});
80
+ // clang-format on
81
+ }
82
+ }
83
+
84
+ function renderAccountInfoOrWarning(syncInfo: Host.InspectorFrontendHostAPI.SyncInformation): LitHtml.TemplateResult {
85
+ if (!syncInfo.isSyncActive) {
86
+ return LitHtml.html`
87
+ <span class="warning">
88
+ ${i18nString(UIStrings.syncDisabled)} <x-link href="chrome://settings/syncSetup" class="link">${
89
+ i18nString(UIStrings.settings)}</x-link>
90
+ </span>`;
91
+ }
92
+ if (!syncInfo.arePreferencesSynced) {
93
+ // Disabled until https://crbug.com/1079231 is fixed.
94
+ // clang-format off
95
+ return LitHtml.html`
96
+ <span class="warning">
97
+ ${i18nString(UIStrings.preferencesSyncDisabled)} <x-link href="chrome://settings/syncSetup/advanced" class="link">${
98
+ i18nString(UIStrings.settings)}</x-link>
99
+ </span>`;
100
+ // clang-format on
101
+ }
102
+ return LitHtml.html`
103
+ <div class="account-info">
104
+ <img src="data:image/png;base64, ${syncInfo.accountImage}" alt="Account avatar" />
105
+ <div class="account-email">
106
+ <span>${i18nString(UIStrings.signedIn)}</span>
107
+ <span>${syncInfo.accountEmail}</span>
108
+ </div>
109
+ </div>`;
110
+ }
111
+
112
+ ComponentHelpers.CustomElements.defineComponent('devtools-sync-section', SyncSection);
113
+
114
+ declare global {
115
+ interface HTMLElementTagNameMap {
116
+ 'devtools-sync-section': SyncSection;
117
+ }
118
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright 2021 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 * as SyncSection from './SyncSection.js';
6
+
7
+ export {
8
+ SyncSection,
9
+ };
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Copyright (c) 2021 The Chromium Authors. All rights reserved.
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ :host {
8
+ break-inside: avoid;
9
+ display: block;
10
+ padding-bottom: 9px;
11
+ width: 288px;
12
+ }
13
+
14
+ fieldset {
15
+ border: 0;
16
+ margin-left: 20px;
17
+ padding: 0;
18
+ }
19
+
20
+ legend {
21
+ color: var(--color-text-secondary);
22
+ font-size: 120%;
23
+ margin-left: -20px;
24
+ padding: 0;
25
+ text-align: left;
26
+ }
27
+
28
+ .link {
29
+ color: var(--color-link);
30
+ text-decoration: underline;
31
+ cursor: pointer;
32
+ padding: 2px 0; /* adjust focus ring size */
33
+ }
34
+
35
+ img {
36
+ background-size: 32px 32px;
37
+ border: 0;
38
+ border-radius: 50%;
39
+ display: block;
40
+ height: 32px;
41
+ width: 32px;
42
+ }
43
+
44
+ .warning {
45
+ display: block;
46
+ margin-top: 12px;
47
+ }
48
+
49
+ .account-info {
50
+ display: flex;
51
+ align-items: center;
52
+ margin-top: 12px;
53
+ }
54
+
55
+ .account-email {
56
+ display: flex;
57
+ flex-direction: column;
58
+ margin-left: 8px;
59
+ }
@@ -42,7 +42,7 @@ h1 {
42
42
  min-height: 30px;
43
43
  display: grid;
44
44
  grid-template-rows: repeat(auto-fit, 30px);
45
- grid-template-columns: 1fr 30px 1fr 30px 30px;
45
+ grid-template-columns: 1fr 30px 2fr 30px 30px;
46
46
  flex: auto 1 1;
47
47
  }
48
48
 
@@ -10,6 +10,11 @@ import settingCheckboxStyles from './settingCheckbox.css.js';
10
10
 
11
11
  export interface SettingCheckboxData {
12
12
  setting: Common.Settings.Setting<boolean>;
13
+ /**
14
+ * If set to true, the checkbox is disabled and not clickable by the user.
15
+ * The checkbox will still reflect the current value of the setting (i.e. checked/unchecked).
16
+ */
17
+ disabled?: boolean;
13
18
  }
14
19
 
15
20
  /**
@@ -20,6 +25,7 @@ export class SettingCheckbox extends HTMLElement {
20
25
  private readonly shadow = this.attachShadow({mode: 'open'});
21
26
 
22
27
  private setting?: Common.Settings.Setting<boolean>;
28
+ private disabled: boolean = false;
23
29
  private changeListenerDescriptor?: Common.EventTarget.EventDescriptor;
24
30
 
25
31
  connectedCallback(): void {
@@ -32,6 +38,7 @@ export class SettingCheckbox extends HTMLElement {
32
38
  }
33
39
 
34
40
  this.setting = data.setting;
41
+ this.disabled = Boolean(data.disabled);
35
42
 
36
43
  this.changeListenerDescriptor = this.setting.addChangeListener(() => {
37
44
  this.render();
@@ -48,8 +55,8 @@ export class SettingCheckbox extends HTMLElement {
48
55
  LitHtml.html`
49
56
  <p>
50
57
  <label>
51
- <input type="checkbox" ?checked=${this.setting.get()} @change="${this.checkboxChanged}" aria-label="${
52
- this.setting.title()}" /> ${this.setting.title()}
58
+ <input type="checkbox" ?checked=${this.setting.get()} ?disabled=${this.disabled} @change="${
59
+ this.checkboxChanged}" aria-label="${this.setting.title()}" /> ${this.setting.title()}
53
60
  </label>
54
61
  </p>`,
55
62
  this.shadow, {host: this});
@@ -163,7 +163,7 @@
163
163
  }
164
164
 
165
165
  .-theme-with-dark-background .tabbed-pane-header-tab.selected,
166
- :host-context(.-theme-with-dark-background) .tabbed-pane-header-tab.selected:focus {
166
+ :host-context(.-theme-with-dark-background) .tabbed-pane-header-tab.selected:focus-visible {
167
167
  background-color: var(--color-background-elevation-0);
168
168
  }
169
169
  /* stylelint-enable no-descending-specificity */
@@ -120,8 +120,10 @@
120
120
  --color-button-outline-focus: rgb(26 115 232 / 50%);
121
121
  --color-button-primary-background-hovering: rgb(77 134 225 / 100%);
122
122
  --color-button-primary-background-pressed: rgb(88 132 205);
123
+ --color-button-primary-text: rgb(255 255 255);
123
124
  --color-button-secondary-background-hovering: rgb(26 115 232 / 10%);
124
125
  --color-button-secondary-background-pressed: rgb(26 92 178 / 25%);
126
+ --color-button-secondary-border: rgb(218 220 224);
125
127
 
126
128
  /* Colors for file icons */
127
129
  --color-ic-file-document: rgb(39 116 240);
@@ -239,8 +241,10 @@
239
241
  --color-button-outline-focus: rgb(138 180 248 / 80%);
240
242
  --color-button-primary-background-hovering: rgb(174 203 250 / 100%);
241
243
  --color-button-primary-background-pressed: rgb(210 227 252 / 100%);
244
+ --color-button-primary-text: rgb(0 0 0);
242
245
  --color-button-secondary-background-hovering: rgb(138 180 248 / 15%);
243
246
  --color-button-secondary-background-pressed: rgb(138 180 248 / 23%);
247
+ --color-button-secondary-border: rgb(60 61 65);
244
248
 
245
249
  /* Colors for file icons */
246
250
  --color-ic-file-document: rgb(39 116 240);
@@ -7,8 +7,6 @@
7
7
  :host {
8
8
  flex: none;
9
9
  padding: 0 2px;
10
-
11
- --override-toolbar-warning-red: rgb(238 68 47 / 7%);
12
10
  }
13
11
 
14
12
  .toolbar-shadow {
@@ -406,8 +404,24 @@ input[is=history-input]:not(:placeholder-shown) {
406
404
  box-shadow: var(--legacy-focus-ring-active-shadow);
407
405
  }
408
406
 
409
- .toolbar-item.warning {
410
- background: var(--override-toolbar-warning-red);
407
+ .toolbar-item.highlight::before {
408
+ content: "";
409
+ position: absolute;
410
+ top: 2px;
411
+ left: 2px;
412
+ right: 2px;
413
+ bottom: 2px;
414
+ border-radius: 2px;
415
+ background: var(--color-primary);
416
+ z-index: -1;
417
+ }
418
+
419
+ .toolbar-item.highlight {
420
+ color: var(--color-button-primary-text);
421
+ }
422
+
423
+ .toolbar-item.highlight > .icon-mask {
424
+ background: var(--color-button-primary-text);
411
425
  }
412
426
 
413
427
  devtools-icon.leading-issue-icon {
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.933401"
58
+ "version": "1.0.934332"
59
59
  }