chrome-devtools-frontend 1.0.1019389 → 1.0.1020422
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.
- package/config/gni/devtools_grd_files.gni +2 -0
- package/front_end/core/i18n/locales/en-US.json +0 -3
- package/front_end/core/i18n/locales/en-XL.json +0 -3
- package/front_end/core/sdk/CSSMatchedStyles.ts +1 -1
- package/front_end/core/sdk/CSSModel.ts +22 -0
- package/front_end/core/sdk/CSSQuery.ts +2 -1
- package/front_end/core/sdk/CSSRule.ts +4 -0
- package/front_end/core/sdk/CSSScope.ts +30 -0
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/models/bindings/BreakpointManager.ts +22 -14
- package/front_end/panels/elements/ComputedStyleWidget.ts +2 -0
- package/front_end/panels/elements/ElementsTreeOutline.ts +3 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +25 -0
- package/front_end/panels/elements/computedStyleSidebarPane.css +4 -0
- package/front_end/panels/lighthouse/LighthousePanel.ts +2 -0
- package/front_end/panels/lighthouse/LighthouseStartView.ts +1 -0
- package/front_end/panels/network/RequestHeadersView.ts +1 -36
- package/front_end/panels/network/requestHeadersTree.css +1 -9
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspector.ts +23 -1
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.ts +18 -1
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewerUtils.ts +8 -0
- package/front_end/ui/components/linear_memory_inspector/linearMemoryViewer.css +4 -0
- package/front_end/ui/components/linear_memory_inspector/linear_memory_inspector.ts +2 -0
- package/front_end/ui/components/panel_feedback/PreviewToggle.ts +1 -8
- package/front_end/ui/components/panel_feedback/previewToggle.css +1 -7
- package/package.json +1 -1
@@ -605,6 +605,7 @@ grd_files_debug_sources = [
|
|
605
605
|
"front_end/core/sdk/CSSPropertyParser.js",
|
606
606
|
"front_end/core/sdk/CSSQuery.js",
|
607
607
|
"front_end/core/sdk/CSSRule.js",
|
608
|
+
"front_end/core/sdk/CSSScope.js",
|
608
609
|
"front_end/core/sdk/CSSStyleDeclaration.js",
|
609
610
|
"front_end/core/sdk/CSSStyleSheetHeader.js",
|
610
611
|
"front_end/core/sdk/CSSSupports.js",
|
@@ -1461,6 +1462,7 @@ grd_files_debug_sources = [
|
|
1461
1462
|
"front_end/ui/components/linear_memory_inspector/LinearMemoryNavigator.js",
|
1462
1463
|
"front_end/ui/components/linear_memory_inspector/LinearMemoryValueInterpreter.js",
|
1463
1464
|
"front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.js",
|
1465
|
+
"front_end/ui/components/linear_memory_inspector/LinearMemoryViewerUtils.js",
|
1464
1466
|
"front_end/ui/components/linear_memory_inspector/ValueInterpreterDisplay.js",
|
1465
1467
|
"front_end/ui/components/linear_memory_inspector/ValueInterpreterDisplayUtils.js",
|
1466
1468
|
"front_end/ui/components/linear_memory_inspector/ValueInterpreterSettings.js",
|
@@ -7511,9 +7511,6 @@
|
|
7511
7511
|
"panels/network/RequestHeadersView.ts | provisionalHeadersAreShownS": {
|
7512
7512
|
"message": "Provisional headers are shown. Disable cache to see full headers."
|
7513
7513
|
},
|
7514
|
-
"panels/network/RequestHeadersView.ts | recordedAttribution": {
|
7515
|
-
"message": "Recorded attribution with trigger-data: {PH1}"
|
7516
|
-
},
|
7517
7514
|
"panels/network/RequestHeadersView.ts | referrerPolicy": {
|
7518
7515
|
"message": "Referrer Policy"
|
7519
7516
|
},
|
@@ -7511,9 +7511,6 @@
|
|
7511
7511
|
"panels/network/RequestHeadersView.ts | provisionalHeadersAreShownS": {
|
7512
7512
|
"message": "P̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê śĥóŵń. D̂íŝáb̂ĺê ćâćĥé t̂ó ŝéê f́ûĺl̂ h́êád̂ér̂ś."
|
7513
7513
|
},
|
7514
|
-
"panels/network/RequestHeadersView.ts | recordedAttribution": {
|
7515
|
-
"message": "R̂éĉór̂d́êd́ ât́t̂ŕîb́ût́îón̂ ẃît́ĥ trigger-data: {PH1}"
|
7516
|
-
},
|
7517
7514
|
"panels/network/RequestHeadersView.ts | referrerPolicy": {
|
7518
7515
|
"message": "R̂éf̂ér̂ŕêŕ P̂ól̂íĉý"
|
7519
7516
|
},
|
@@ -491,7 +491,7 @@ export class CSSMatchedStyles {
|
|
491
491
|
return true;
|
492
492
|
}
|
493
493
|
const parentRule = style.parentRule as CSSStyleRule;
|
494
|
-
const queries = [...parentRule.media, ...parentRule.containerQueries, ...parentRule.supports];
|
494
|
+
const queries = [...parentRule.media, ...parentRule.containerQueries, ...parentRule.supports, ...parentRule.scopes];
|
495
495
|
for (const query of queries) {
|
496
496
|
if (!query.active()) {
|
497
497
|
return false;
|
@@ -461,6 +461,28 @@ export class CSSModel extends SDKModel<EventTypes> {
|
|
461
461
|
}
|
462
462
|
}
|
463
463
|
|
464
|
+
async setScopeText(
|
465
|
+
styleSheetId: Protocol.CSS.StyleSheetId, range: TextUtils.TextRange.TextRange,
|
466
|
+
newScopeText: string): Promise<boolean> {
|
467
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
|
468
|
+
|
469
|
+
try {
|
470
|
+
await this.ensureOriginalStyleSheetText(styleSheetId);
|
471
|
+
const {scope} = await this.agent.invoke_setScopeText({styleSheetId, range, text: newScopeText});
|
472
|
+
|
473
|
+
if (!scope) {
|
474
|
+
return false;
|
475
|
+
}
|
476
|
+
this.#domModel.markUndoableState();
|
477
|
+
const edit = new Edit(styleSheetId, range, newScopeText, scope);
|
478
|
+
this.fireStyleSheetChanged(styleSheetId, edit);
|
479
|
+
return true;
|
480
|
+
} catch (e) {
|
481
|
+
console.error(e);
|
482
|
+
return false;
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
464
486
|
async addRule(styleSheetId: Protocol.CSS.StyleSheetId, ruleText: string, ruleLocation: TextUtils.TextRange.TextRange):
|
465
487
|
Promise<CSSStyleRule|null> {
|
466
488
|
try {
|
@@ -9,7 +9,8 @@ import type {CSSModel, Edit} from './CSSModel.js';
|
|
9
9
|
import {CSSLocation} from './CSSModel.js';
|
10
10
|
import type {CSSStyleSheetHeader} from './CSSStyleSheetHeader.js';
|
11
11
|
|
12
|
-
type CSSQueryPayload =
|
12
|
+
type CSSQueryPayload =
|
13
|
+
Protocol.CSS.CSSMedia|Protocol.CSS.CSSContainerQuery|Protocol.CSS.CSSSupports|Protocol.CSS.CSSScope;
|
13
14
|
|
14
15
|
export abstract class CSSQuery {
|
15
16
|
text = '';
|
@@ -9,6 +9,7 @@ import * as Platform from '../platform/platform.js';
|
|
9
9
|
import {CSSContainerQuery} from './CSSContainerQuery.js';
|
10
10
|
import {CSSLayer} from './CSSLayer.js';
|
11
11
|
import {CSSMedia} from './CSSMedia.js';
|
12
|
+
import {CSSScope} from './CSSScope.js';
|
12
13
|
import {CSSSupports} from './CSSSupports.js';
|
13
14
|
|
14
15
|
import type {CSSModel, Edit} from './CSSModel.js';
|
@@ -103,6 +104,7 @@ export class CSSStyleRule extends CSSRule {
|
|
103
104
|
media: CSSMedia[];
|
104
105
|
containerQueries: CSSContainerQuery[];
|
105
106
|
supports: CSSSupports[];
|
107
|
+
scopes: CSSScope[];
|
106
108
|
layers: CSSLayer[];
|
107
109
|
wasUsed: boolean;
|
108
110
|
constructor(cssModel: CSSModel, payload: Protocol.CSS.CSSRule, wasUsed?: boolean) {
|
@@ -113,6 +115,7 @@ export class CSSStyleRule extends CSSRule {
|
|
113
115
|
this.containerQueries = payload.containerQueries ?
|
114
116
|
CSSContainerQuery.parseContainerQueriesPayload(cssModel, payload.containerQueries) :
|
115
117
|
[];
|
118
|
+
this.scopes = payload.scopes ? CSSScope.parseScopesPayload(cssModel, payload.scopes) : [];
|
116
119
|
this.supports = payload.supports ? CSSSupports.parseSupportsPayload(cssModel, payload.supports) : [];
|
117
120
|
this.layers = payload.layers ? CSSLayer.parseLayerPayload(cssModel, payload.layers) : [];
|
118
121
|
this.wasUsed = wasUsed || false;
|
@@ -200,6 +203,7 @@ export class CSSStyleRule extends CSSRule {
|
|
200
203
|
}
|
201
204
|
this.media.forEach(media => media.rebase(edit));
|
202
205
|
this.containerQueries.forEach(cq => cq.rebase(edit));
|
206
|
+
this.scopes.forEach(scope => scope.rebase(edit));
|
203
207
|
this.supports.forEach(supports => supports.rebase(edit));
|
204
208
|
|
205
209
|
super.rebase(edit);
|
@@ -0,0 +1,30 @@
|
|
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
|
+
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
6
|
+
import type * as Protocol from '../../generated/protocol.js';
|
7
|
+
|
8
|
+
import type {CSSModel} from './CSSModel.js';
|
9
|
+
import {CSSQuery} from './CSSQuery.js';
|
10
|
+
|
11
|
+
export class CSSScope extends CSSQuery {
|
12
|
+
static parseScopesPayload(cssModel: CSSModel, payload: Protocol.CSS.CSSScope[]): CSSScope[] {
|
13
|
+
return payload.map(scope => new CSSScope(cssModel, scope));
|
14
|
+
}
|
15
|
+
|
16
|
+
constructor(cssModel: CSSModel, payload: Protocol.CSS.CSSScope) {
|
17
|
+
super(cssModel);
|
18
|
+
this.reinitialize(payload);
|
19
|
+
}
|
20
|
+
|
21
|
+
reinitialize(payload: Protocol.CSS.CSSScope): void {
|
22
|
+
this.text = payload.text;
|
23
|
+
this.range = payload.range ? TextUtils.TextRange.TextRange.fromObject(payload.range) : null;
|
24
|
+
this.styleSheetId = payload.styleSheetId;
|
25
|
+
}
|
26
|
+
|
27
|
+
active(): boolean {
|
28
|
+
return true;
|
29
|
+
}
|
30
|
+
}
|
@@ -33,6 +33,7 @@ import * as CSSProperty from './CSSProperty.js';
|
|
33
33
|
import * as CSSPropertyParser from './CSSPropertyParser.js';
|
34
34
|
import * as CSSQuery from './CSSQuery.js';
|
35
35
|
import * as CSSRule from './CSSRule.js';
|
36
|
+
import * as CSSScope from './CSSScope.js';
|
36
37
|
import * as CSSStyleDeclaration from './CSSStyleDeclaration.js';
|
37
38
|
import * as CSSStyleSheetHeader from './CSSStyleSheetHeader.js';
|
38
39
|
import * as CSSSupports from './CSSSupports.js';
|
@@ -103,6 +104,7 @@ export {
|
|
103
104
|
CSSPropertyParser,
|
104
105
|
CSSQuery,
|
105
106
|
CSSRule,
|
107
|
+
CSSScope,
|
106
108
|
CSSStyleDeclaration,
|
107
109
|
CSSStyleSheetHeader,
|
108
110
|
CSSSupports,
|
@@ -409,13 +409,18 @@ export type EventTypes = {
|
|
409
409
|
[Events.BreakpointRemoved]: BreakpointLocation,
|
410
410
|
};
|
411
411
|
|
412
|
-
const enum DebuggerUpdateResult {
|
412
|
+
export const enum DebuggerUpdateResult {
|
413
413
|
OK = 'OK',
|
414
|
-
|
414
|
+
ERROR_BREAKPOINT_CLASH = 'ERROR_BREAKPOINT_CLASH',
|
415
|
+
ERROR_BACKEND = 'ERROR_BACKEND',
|
416
|
+
|
415
417
|
// PENDING implies that the current update requires another re-run.
|
416
418
|
PENDING = 'PENDING',
|
417
419
|
}
|
418
420
|
|
421
|
+
export type ScheduleUpdateResult =
|
422
|
+
DebuggerUpdateResult.OK|DebuggerUpdateResult.ERROR_BACKEND|DebuggerUpdateResult.ERROR_BREAKPOINT_CLASH;
|
423
|
+
|
419
424
|
const enum ResolveLocationResult {
|
420
425
|
OK = 'OK',
|
421
426
|
ERROR = 'ERROR',
|
@@ -430,7 +435,7 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
430
435
|
uiSourceCodes: Set<Workspace.UISourceCode.UISourceCode>;
|
431
436
|
#conditionInternal!: string;
|
432
437
|
#enabledInternal!: boolean;
|
433
|
-
isRemoved
|
438
|
+
isRemoved = false;
|
434
439
|
currentState: Breakpoint.State|null;
|
435
440
|
readonly #modelBreakpoints: Map<SDK.DebuggerModel.DebuggerModel, ModelBreakpoint>;
|
436
441
|
|
@@ -629,6 +634,9 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
629
634
|
}
|
630
635
|
|
631
636
|
async remove(keepInStorage: boolean): Promise<void> {
|
637
|
+
if (this.getIsRemoved()) {
|
638
|
+
return;
|
639
|
+
}
|
632
640
|
this.isRemoved = true;
|
633
641
|
const removeFromStorage = !keepInStorage;
|
634
642
|
|
@@ -676,9 +684,11 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
676
684
|
}
|
677
685
|
|
678
686
|
async #updateModel(model: ModelBreakpoint): Promise<void> {
|
679
|
-
const
|
680
|
-
if (
|
681
|
-
await this.remove(
|
687
|
+
const result = await model.scheduleUpdateInDebugger();
|
688
|
+
if (result === DebuggerUpdateResult.ERROR_BACKEND) {
|
689
|
+
await this.remove(true /* keepInStorage */);
|
690
|
+
} else if (result === DebuggerUpdateResult.ERROR_BREAKPOINT_CLASH) {
|
691
|
+
await this.remove(false /* keepInStorage */);
|
682
692
|
}
|
683
693
|
}
|
684
694
|
}
|
@@ -722,11 +732,9 @@ export class ModelBreakpoint {
|
|
722
732
|
this.#liveLocations.disposeAll();
|
723
733
|
}
|
724
734
|
|
725
|
-
|
726
|
-
// Returns false, if an error occurred.
|
727
|
-
async scheduleUpdateInDebugger(): Promise<boolean> {
|
735
|
+
async scheduleUpdateInDebugger(): Promise<ScheduleUpdateResult> {
|
728
736
|
if (!this.#debuggerModel.debuggerEnabled()) {
|
729
|
-
return
|
737
|
+
return DebuggerUpdateResult.OK;
|
730
738
|
}
|
731
739
|
|
732
740
|
const release = await this.#updateMutex.acquire();
|
@@ -735,7 +743,7 @@ export class ModelBreakpoint {
|
|
735
743
|
result = await this.#updateInDebugger();
|
736
744
|
}
|
737
745
|
release();
|
738
|
-
return result
|
746
|
+
return result;
|
739
747
|
}
|
740
748
|
|
741
749
|
private scriptDiverged(): boolean {
|
@@ -849,7 +857,7 @@ export class ModelBreakpoint {
|
|
849
857
|
// Something went wrong: we expect to have a non-null state, but have not received any
|
850
858
|
// breakpointIds from the back-end.
|
851
859
|
if (!breakpointIds.length) {
|
852
|
-
return DebuggerUpdateResult.
|
860
|
+
return DebuggerUpdateResult.ERROR_BACKEND;
|
853
861
|
}
|
854
862
|
|
855
863
|
this.#breakpointIds = breakpointIds;
|
@@ -859,7 +867,7 @@ export class ModelBreakpoint {
|
|
859
867
|
|
860
868
|
// Breakpoint clash: the resolved location resolves to a different breakpoint, report an error.
|
861
869
|
if (resolvedResults.includes(ResolveLocationResult.ERROR)) {
|
862
|
-
return DebuggerUpdateResult.
|
870
|
+
return DebuggerUpdateResult.ERROR_BREAKPOINT_CLASH;
|
863
871
|
}
|
864
872
|
return DebuggerUpdateResult.OK;
|
865
873
|
}
|
@@ -917,7 +925,7 @@ export class ModelBreakpoint {
|
|
917
925
|
Promise<void> {
|
918
926
|
const result = await this.addResolvedLocation(location);
|
919
927
|
if (result === ResolveLocationResult.ERROR) {
|
920
|
-
await this.#breakpoint.remove(false);
|
928
|
+
await this.#breakpoint.remove(false /* keepInStorage */);
|
921
929
|
}
|
922
930
|
}
|
923
931
|
|
@@ -206,6 +206,8 @@ export class ComputedStyleWidget extends UI.ThrottledWidget.ThrottledWidget {
|
|
206
206
|
constructor() {
|
207
207
|
super(true);
|
208
208
|
|
209
|
+
this.contentElement.classList.add('styles-sidebar-computed-style-widget');
|
210
|
+
|
209
211
|
this.computedStyleModel = new ComputedStyleModel();
|
210
212
|
this.computedStyleModel.addEventListener(Events.ComputedStyleChanged, this.update, this);
|
211
213
|
|
@@ -555,7 +555,9 @@ export class ElementsTreeOutline extends
|
|
555
555
|
// items extend at least to the right edge of the outer <ol> container.
|
556
556
|
// In the no-word-wrap mode the outer <ol> may be wider than the tree container
|
557
557
|
// (and partially hidden), in which case we are left to use only its right boundary.
|
558
|
-
|
558
|
+
// We use .clientWidth to account for possible scrollbar, and subtract 6px
|
559
|
+
// for the width of the split widget (see splitWidget.css).
|
560
|
+
const x = scrollContainer.totalOffsetLeft() + scrollContainer.clientWidth - 6;
|
559
561
|
|
560
562
|
const y = event.pageY;
|
561
563
|
|
@@ -708,6 +708,7 @@ export class StylePropertiesSection {
|
|
708
708
|
protected createAtRuleLists(rule: SDK.CSSRule.CSSStyleRule): void {
|
709
709
|
this.createMediaList(rule.media);
|
710
710
|
this.createContainerQueryList(rule.containerQueries);
|
711
|
+
this.createScopesList(rule.scopes);
|
711
712
|
this.createSupportsList(rule.supports);
|
712
713
|
}
|
713
714
|
|
@@ -778,6 +779,28 @@ export class StylePropertiesSection {
|
|
778
779
|
}
|
779
780
|
}
|
780
781
|
|
782
|
+
protected createScopesList(scopesList: SDK.CSSScope.CSSScope[]): void {
|
783
|
+
for (let i = scopesList.length - 1; i >= 0; --i) {
|
784
|
+
const scope = scopesList[i];
|
785
|
+
if (!scope.text) {
|
786
|
+
continue;
|
787
|
+
}
|
788
|
+
|
789
|
+
let onQueryTextClick;
|
790
|
+
if (scope.styleSheetId) {
|
791
|
+
onQueryTextClick = this.handleQueryRuleClick.bind(this, scope);
|
792
|
+
}
|
793
|
+
|
794
|
+
const scopeElement = new ElementsComponents.CSSQuery.CSSQuery();
|
795
|
+
scopeElement.data = {
|
796
|
+
queryPrefix: '@scope',
|
797
|
+
queryText: scope.text,
|
798
|
+
onQueryTextClick,
|
799
|
+
};
|
800
|
+
this.queryListElement.append(scopeElement);
|
801
|
+
}
|
802
|
+
}
|
803
|
+
|
781
804
|
protected createSupportsList(supportsList: SDK.CSSSupports.CSSSupports[]): void {
|
782
805
|
for (let i = supportsList.length - 1; i >= 0; --i) {
|
783
806
|
const supports = supportsList[i];
|
@@ -1185,6 +1208,8 @@ export class StylePropertiesSection {
|
|
1185
1208
|
success = await cssModel.setContainerQueryText(query.styleSheetId, range, newContent);
|
1186
1209
|
} else if (query instanceof SDK.CSSSupports.CSSSupports) {
|
1187
1210
|
success = await cssModel.setSupportsText(query.styleSheetId, range, newContent);
|
1211
|
+
} else if (query instanceof SDK.CSSScope.CSSScope) {
|
1212
|
+
success = await cssModel.setScopeText(query.styleSheetId, range, newContent);
|
1188
1213
|
} else {
|
1189
1214
|
success = await cssModel.setMediaText(query.styleSheetId, range, newContent);
|
1190
1215
|
}
|
@@ -302,6 +302,8 @@ export class LighthousePanel extends UI.Panel.Panel {
|
|
302
302
|
}
|
303
303
|
|
304
304
|
const reportContainer = this.auditResultsElement.createChild('div', 'lh-vars lh-root lh-devtools');
|
305
|
+
// @ts-ignore Expose LHR on DOM for e2e tests
|
306
|
+
reportContainer._lighthouseResultForTesting = lighthouseResult;
|
305
307
|
|
306
308
|
const dom = new LighthouseReport.DOM(this.auditResultsElement.ownerDocument as Document, reportContainer);
|
307
309
|
const renderer = new LighthouseReportRenderer(dom) as LighthouseReport.ReportRenderer;
|
@@ -143,6 +143,7 @@ export class StartView extends UI.Widget.Widget {
|
|
143
143
|
const checkbox = new UI.Toolbar.ToolbarSettingCheckbox(preset.setting, preset.description());
|
144
144
|
const row = formElements.createChild('div', 'vbox lighthouse-launcher-row');
|
145
145
|
row.appendChild(checkbox.element);
|
146
|
+
checkbox.element.setAttribute('data-lh-category', preset.configID);
|
146
147
|
this.checkboxes.push({preset, checkbox});
|
147
148
|
if (mode && !preset.supportedModes.includes(mode)) {
|
148
149
|
checkbox.setEnabled(false);
|
@@ -195,13 +195,6 @@ const UIStrings = {
|
|
195
195
|
*/
|
196
196
|
toUseThisResourceFromADifferentOrigin:
|
197
197
|
'To use this resource from a different origin, the server may relax the cross-origin resource policy response header:',
|
198
|
-
/**
|
199
|
-
* @description Shown in the network panel for network requests that meet special criteria.
|
200
|
-
* 'Attribution' is a term used by the "Attribution Reporting API" and refers to an event, e.g.
|
201
|
-
* buying an item in an online store after an ad was clicked.
|
202
|
-
* @example {foo} PH1
|
203
|
-
*/
|
204
|
-
recordedAttribution: 'Recorded attribution with `trigger-data`: {PH1}',
|
205
198
|
/**
|
206
199
|
*@description Label for a link from the network panel's headers view to the file in which
|
207
200
|
* header overrides are defined in the sources panel.
|
@@ -322,22 +315,7 @@ export class RequestHeadersView extends UI.Widget.VBox {
|
|
322
315
|
private formatHeaderObject(header: BlockedReasonDetailDescriptor): DocumentFragment {
|
323
316
|
const fragment = document.createDocumentFragment();
|
324
317
|
if (header.headerNotSet) {
|
325
|
-
fragment.createChild('div', 'header-badge header-badge-
|
326
|
-
}
|
327
|
-
// Highlight successful Attribution Reporting API redirects. If the request was
|
328
|
-
// not canceled, then something went wrong.
|
329
|
-
if (header.name.toLowerCase() === 'location' && this.request.canceled) {
|
330
|
-
const url = new URL(header.value?.toString() || '', this.request.parsedURL.securityOrigin());
|
331
|
-
const triggerData = getTriggerDataFromAttributionRedirect(url);
|
332
|
-
if (triggerData) {
|
333
|
-
fragment.createChild('div', 'header-badge header-badge-success header-badge-text').textContent =
|
334
|
-
'Attribution Reporting API';
|
335
|
-
header.details = {
|
336
|
-
explanation: (): string => i18nString(UIStrings.recordedAttribution, {PH1: triggerData}),
|
337
|
-
examples: [],
|
338
|
-
link: null,
|
339
|
-
};
|
340
|
-
}
|
318
|
+
fragment.createChild('div', 'header-badge header-badge-text').textContent = 'not-set';
|
341
319
|
}
|
342
320
|
const colon = header.value ? ': ' : '';
|
343
321
|
fragment.createChild('div', 'header-name').textContent = header.name + colon;
|
@@ -817,19 +795,6 @@ export class Category extends UI.TreeOutline.TreeElement {
|
|
817
795
|
}
|
818
796
|
}
|
819
797
|
|
820
|
-
/**
|
821
|
-
* Returns the value for the `trigger-data` search parameter iff the provided
|
822
|
-
* url is a valid attribution redirect as specified by the Attribution
|
823
|
-
* Reporting API.
|
824
|
-
*/
|
825
|
-
function getTriggerDataFromAttributionRedirect(url: URL): string|null {
|
826
|
-
if (url.pathname === '/.well-known/attribution-reporting/trigger-attribution' &&
|
827
|
-
url.searchParams.has('trigger-data')) {
|
828
|
-
return url.searchParams.get('trigger-data');
|
829
|
-
}
|
830
|
-
return null;
|
831
|
-
}
|
832
|
-
|
833
798
|
interface BlockedReasonDetailDescriptor {
|
834
799
|
name: string;
|
835
800
|
value: Object|null;
|
@@ -112,21 +112,13 @@
|
|
112
112
|
.tree-outline .header-badge {
|
113
113
|
display: inline;
|
114
114
|
margin-right: 0.75em;
|
115
|
+
background-color: var(--override-error-background-color);
|
115
116
|
color: var(--override-error-text-color);
|
116
117
|
border-radius: 100vh;
|
117
118
|
padding-left: 6px;
|
118
119
|
padding-right: 6px;
|
119
120
|
}
|
120
121
|
|
121
|
-
.tree-outline .header-badge-error {
|
122
|
-
background-color: var(--override-error-background-color);
|
123
|
-
}
|
124
|
-
|
125
|
-
.tree-outline .header-badge-success {
|
126
|
-
background-color: var(--color-accent-green);
|
127
|
-
text-transform: uppercase;
|
128
|
-
}
|
129
|
-
|
130
122
|
.tree-outline .header-value {
|
131
123
|
display: inline;
|
132
124
|
margin-right: 1em;
|
@@ -27,6 +27,7 @@ import {
|
|
27
27
|
import {formatAddress, parseAddress} from './LinearMemoryInspectorUtils.js';
|
28
28
|
import type {JumpToPointerAddressEvent, ValueTypeModeChangedEvent} from './ValueInterpreterDisplay.js';
|
29
29
|
import {LinearMemoryViewer} from './LinearMemoryViewer.js';
|
30
|
+
import type {HighlightInfo} from './LinearMemoryViewerUtils.js';
|
30
31
|
|
31
32
|
import * as i18n from '../../../core/i18n/i18n.js';
|
32
33
|
const UIStrings = {
|
@@ -51,6 +52,7 @@ export interface LinearMemoryInspectorData {
|
|
51
52
|
valueTypes?: Set<ValueType>;
|
52
53
|
valueTypeModes?: Map<ValueType, ValueTypeMode>;
|
53
54
|
endianness?: Endianness;
|
55
|
+
highlightInfo?: HighlightInfo;
|
54
56
|
}
|
55
57
|
|
56
58
|
export type Settings = {
|
@@ -120,6 +122,10 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
120
122
|
#outerMemoryLength = 0;
|
121
123
|
|
122
124
|
#address = -1;
|
125
|
+
#highlightInfo: HighlightInfo = {
|
126
|
+
size: 0,
|
127
|
+
startAddress: 0,
|
128
|
+
};
|
123
129
|
|
124
130
|
#currentNavigatorMode = Mode.Submitted;
|
125
131
|
#currentNavigatorAddressLine = `${this.#address}`;
|
@@ -143,12 +149,23 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
143
149
|
throw new Error('Memory offset has to be greater or equal to zero.');
|
144
150
|
}
|
145
151
|
|
152
|
+
if (data.highlightInfo !== undefined) {
|
153
|
+
if (data.highlightInfo.size < 0) {
|
154
|
+
throw new Error('Object size has to be greater than or equal to zero');
|
155
|
+
}
|
156
|
+
if (data.highlightInfo.startAddress > data.memoryOffset + data.memory.length ||
|
157
|
+
data.highlightInfo.startAddress < 0) {
|
158
|
+
throw new Error('Object start address is out of bounds.');
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
146
162
|
this.#memory = data.memory;
|
147
163
|
this.#memoryOffset = data.memoryOffset;
|
148
164
|
this.#outerMemoryLength = data.outerMemoryLength;
|
149
165
|
this.#valueTypeModes = data.valueTypeModes || this.#valueTypeModes;
|
150
166
|
this.#valueTypes = data.valueTypes || this.#valueTypes;
|
151
167
|
this.#endianness = data.endianness || this.#endianness;
|
168
|
+
this.#highlightInfo = data.highlightInfo || this.#highlightInfo;
|
152
169
|
this.#setAddress(data.address);
|
153
170
|
this.#render();
|
154
171
|
}
|
@@ -179,7 +196,12 @@ export class LinearMemoryInspector extends HTMLElement {
|
|
179
196
|
@pagenavigation=${this.#navigatePage}
|
180
197
|
@historynavigation=${this.#navigateHistory}></${LinearMemoryNavigator.litTagName}>
|
181
198
|
<${LinearMemoryViewer.litTagName}
|
182
|
-
.data=${{
|
199
|
+
.data=${{
|
200
|
+
memory: this.#memory.slice(start - this.#memoryOffset,
|
201
|
+
end - this.#memoryOffset),
|
202
|
+
address: this.#address, memoryOffset: start,
|
203
|
+
focus: this.#currentNavigatorMode === Mode.Submitted,
|
204
|
+
highlightInfo: this.#highlightInfo } as LinearMemoryViewerData}
|
183
205
|
@byteselected=${this.#onByteSelected}
|
184
206
|
@resize=${this.#resize}>
|
185
207
|
</${LinearMemoryViewer.litTagName}>
|
@@ -4,6 +4,7 @@
|
|
4
4
|
import * as LitHtml from '../../lit-html/lit-html.js';
|
5
5
|
import * as ComponentHelpers from '../helpers/helpers.js';
|
6
6
|
|
7
|
+
import type {HighlightInfo} from './LinearMemoryViewerUtils.js';
|
7
8
|
import {toHexString} from './LinearMemoryInspectorUtils.js';
|
8
9
|
import linearMemoryViewerStyles from './linearMemoryViewer.css.js';
|
9
10
|
|
@@ -14,6 +15,7 @@ export interface LinearMemoryViewerData {
|
|
14
15
|
address: number;
|
15
16
|
memoryOffset: number;
|
16
17
|
focus: boolean;
|
18
|
+
highlightInfo?: HighlightInfo;
|
17
19
|
}
|
18
20
|
|
19
21
|
export class ByteSelectedEvent extends Event {
|
@@ -50,6 +52,10 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
50
52
|
#memory = new Uint8Array();
|
51
53
|
#address = 0;
|
52
54
|
#memoryOffset = 0;
|
55
|
+
#highlightInfo: HighlightInfo = {
|
56
|
+
size: 0,
|
57
|
+
startAddress: 0,
|
58
|
+
};
|
53
59
|
|
54
60
|
#numRows = 1;
|
55
61
|
#numBytesInRow = BYTE_GROUP_SIZE;
|
@@ -69,6 +75,7 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
69
75
|
|
70
76
|
this.#memory = data.memory;
|
71
77
|
this.#address = data.address;
|
78
|
+
this.#highlightInfo = data.highlightInfo || this.#highlightInfo;
|
72
79
|
this.#memoryOffset = data.memoryOffset;
|
73
80
|
this.#focusOnByte = data.focus;
|
74
81
|
this.#update();
|
@@ -230,18 +237,20 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
230
237
|
#renderByteValues(startIndex: number, endIndex: number): LitHtml.TemplateResult {
|
231
238
|
const cells = [];
|
232
239
|
for (let i = startIndex; i < endIndex; ++i) {
|
240
|
+
const actualIndex = i + this.#memoryOffset;
|
233
241
|
// Add margin after each group of bytes of size byteGroupSize.
|
234
242
|
const addMargin = i !== startIndex && (i - startIndex) % BYTE_GROUP_SIZE === 0;
|
235
243
|
const selected = i === this.#address - this.#memoryOffset;
|
244
|
+
const shouldBeHighlighted = this.#shouldBeHighlighted(actualIndex);
|
236
245
|
const classMap = {
|
237
246
|
'cell': true,
|
238
247
|
'byte-cell': true,
|
239
248
|
'byte-group-margin': addMargin,
|
240
249
|
selected,
|
250
|
+
'highlight-area': shouldBeHighlighted,
|
241
251
|
};
|
242
252
|
const isSelectableCell = i < this.#memory.length;
|
243
253
|
const byteValue = isSelectableCell ? html`${toHexString({number: this.#memory[i], pad: 2, prefix: false})}` : '';
|
244
|
-
const actualIndex = i + this.#memoryOffset;
|
245
254
|
const onSelectedByte = isSelectableCell ? this.#onSelectedByte.bind(this, actualIndex) : '';
|
246
255
|
cells.push(html`<span class=${LitHtml.Directives.classMap(classMap)} @click=${onSelectedByte}>${byteValue}</span>`);
|
247
256
|
}
|
@@ -251,10 +260,13 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
251
260
|
#renderCharacterValues(startIndex: number, endIndex: number): LitHtml.TemplateResult {
|
252
261
|
const cells = [];
|
253
262
|
for (let i = startIndex; i < endIndex; ++i) {
|
263
|
+
const actualIndex = i + this.#memoryOffset;
|
264
|
+
const shouldBeHighlighted = this.#shouldBeHighlighted(actualIndex);
|
254
265
|
const classMap = {
|
255
266
|
'cell': true,
|
256
267
|
'text-cell': true,
|
257
268
|
selected: this.#address - this.#memoryOffset === i,
|
269
|
+
'highlight-area': shouldBeHighlighted,
|
258
270
|
};
|
259
271
|
const isSelectableCell = i < this.#memory.length;
|
260
272
|
const value = isSelectableCell ? html`${this.#toAscii(this.#memory[i])}` : '';
|
@@ -274,6 +286,11 @@ export class LinearMemoryViewer extends HTMLElement {
|
|
274
286
|
#onSelectedByte(index: number): void {
|
275
287
|
this.dispatchEvent(new ByteSelectedEvent(index));
|
276
288
|
}
|
289
|
+
|
290
|
+
#shouldBeHighlighted(index: number): boolean {
|
291
|
+
return this.#highlightInfo.startAddress <= index
|
292
|
+
&& index < this.#highlightInfo.startAddress + this.#highlightInfo.size;
|
293
|
+
}
|
277
294
|
}
|
278
295
|
|
279
296
|
ComponentHelpers.CustomElements.defineComponent('devtools-linear-memory-inspector-viewer', LinearMemoryViewer);
|
@@ -9,6 +9,7 @@ import * as LinearMemoryInspectorUtils from './LinearMemoryInspectorUtils.js';
|
|
9
9
|
import * as LinearMemoryNavigator from './LinearMemoryNavigator.js';
|
10
10
|
import * as LinearMemoryValueInterpreter from './LinearMemoryValueInterpreter.js';
|
11
11
|
import * as LinearMemoryViewer from './LinearMemoryViewer.js';
|
12
|
+
import * as LinearMemoryViewerUtils from './LinearMemoryViewerUtils.js';
|
12
13
|
import * as ValueInterpreterDisplay from './ValueInterpreterDisplay.js';
|
13
14
|
import * as ValueInterpreterDisplayUtils from './ValueInterpreterDisplayUtils.js';
|
14
15
|
import * as ValueInterpreterSettings from './ValueInterpreterSettings.js';
|
@@ -21,6 +22,7 @@ export {
|
|
21
22
|
LinearMemoryNavigator,
|
22
23
|
LinearMemoryValueInterpreter,
|
23
24
|
LinearMemoryViewer,
|
25
|
+
LinearMemoryViewerUtils,
|
24
26
|
ValueInterpreterDisplay,
|
25
27
|
ValueInterpreterDisplayUtils,
|
26
28
|
ValueInterpreterSettings,
|
@@ -67,18 +67,11 @@ export class PreviewToggle extends HTMLElement {
|
|
67
67
|
|
68
68
|
#render(): void {
|
69
69
|
const checked = Root.Runtime.experiments.isEnabled(this.#experiment);
|
70
|
-
const hasLink = Boolean(this.#feedbackURL) || Boolean(this.#learnMoreURL);
|
71
|
-
|
72
|
-
const containerClasses = LitHtml.Directives.classMap({
|
73
|
-
'container': true,
|
74
|
-
'has-link': hasLink,
|
75
|
-
});
|
76
|
-
|
77
70
|
// Disabled until https://crbug.com/1079231 is fixed.
|
78
71
|
// clang-format off
|
79
72
|
render(
|
80
73
|
html`
|
81
|
-
<div class
|
74
|
+
<div class="container">
|
82
75
|
<div class="checkbox-line">
|
83
76
|
<label class="experiment-preview">
|
84
77
|
<input type="checkbox" ?checked=${checked} @change=${this.#checkboxChanged} aria-label=${this.#name}/>
|
@@ -33,16 +33,10 @@
|
|
33
33
|
padding: 4px;
|
34
34
|
}
|
35
35
|
|
36
|
-
.container.has-link {
|
37
|
-
/* For x-link outline not to paint over the helper text
|
38
|
-
we need to have 2 * <padding>px additional line height */
|
39
|
-
line-height: calc(1em + 8px);
|
40
|
-
}
|
41
|
-
|
42
36
|
.x-link {
|
43
37
|
color: var(--color-primary);
|
44
38
|
text-decoration-line: underline;
|
45
|
-
|
39
|
+
margin: 4px;
|
46
40
|
}
|
47
41
|
|
48
42
|
.feedback .x-link {
|
package/package.json
CHANGED