chrome-devtools-frontend 1.0.1030070 → 1.0.1031400
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 +3 -0
- package/config/gni/devtools_image_files.gni +2 -0
- package/docs/workflows.md +1 -1
- package/front_end/Images/src/file-sync_icon.svg +62 -0
- package/front_end/Images/src/file_icon.svg +52 -0
- package/front_end/Tests.js +0 -28
- package/front_end/core/host/UserMetrics.ts +2 -1
- package/front_end/core/i18n/locales/en-US.json +18 -9
- package/front_end/core/i18n/locales/en-XL.json +18 -9
- package/front_end/core/platform/string-utilities.ts +2 -5
- package/front_end/core/root/Runtime.ts +1 -0
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +0 -4
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +0 -4
- package/front_end/core/sdk/NetworkRequest.ts +0 -4
- package/front_end/core/sdk/Resource.ts +0 -5
- package/front_end/core/sdk/Script.ts +71 -76
- package/front_end/core/sdk/Target.ts +4 -0
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +4 -1
- package/front_end/entrypoints/main/MainImpl.ts +4 -0
- package/front_end/generated/InspectorBackendCommands.js +10 -8
- package/front_end/generated/protocol-mapping.d.ts +16 -2
- package/front_end/generated/protocol-proxy-api.d.ts +11 -1
- package/front_end/generated/protocol.ts +75 -1
- package/front_end/models/bindings/CompilerScriptMapping.ts +6 -3
- package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +1 -4
- package/front_end/models/bindings/IgnoreListManager.ts +10 -8
- package/front_end/models/bindings/ResourceMapping.ts +0 -4
- package/front_end/models/bindings/StylesSourceMapping.ts +0 -5
- package/front_end/models/extensions/ExtensionServer.ts +2 -3
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +8 -0
- package/front_end/models/issues_manager/DeprecationIssue.ts +5 -1
- package/front_end/models/issues_manager/descriptions/arTooManyConcurrentRequests.md +5 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -2
- package/front_end/models/persistence/NetworkPersistenceManager.ts +4 -6
- package/front_end/models/persistence/PersistenceActions.ts +5 -4
- package/front_end/models/text_utils/CodeMirrorUtils.ts +17 -4
- package/front_end/models/text_utils/ContentProvider.ts +0 -1
- package/front_end/models/text_utils/StaticContentProvider.ts +0 -4
- package/front_end/models/workspace/UISourceCode.ts +10 -5
- package/front_end/panels/application/components/StackTrace.ts +2 -2
- package/front_end/panels/elements/CSSRuleValidator.ts +382 -63
- package/front_end/panels/elements/CSSRuleValidatorHelper.ts +34 -0
- package/front_end/panels/elements/ElementsTreeOutline.ts +23 -7
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/TopLayerContainer.ts +17 -28
- package/front_end/panels/elements/components/CSSHintDetailsView.ts +23 -20
- package/front_end/panels/elements/components/cssHintDetailsView.css +8 -2
- package/front_end/panels/elements/stylesSectionTree.css +1 -1
- package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +12 -0
- package/front_end/panels/network/components/RequestHeadersView.css +41 -8
- package/front_end/panels/network/components/RequestHeadersView.ts +102 -12
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -0
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +7 -0
- package/front_end/panels/sources/NavigatorView.ts +22 -0
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -3
- package/front_end/third_party/codemirror.next/bundle.ts +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/json.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -2
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -2
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +1247 -116
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -2
- package/front_end/ui/components/data_grid/DataGrid.ts +15 -10
- package/front_end/ui/components/data_grid/DataGridController.ts +7 -0
- package/front_end/ui/components/docs/building-ui-documentation/StylingComponents.md +64 -0
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspector.ts +2 -3
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +97 -17
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorPane.ts +1 -1
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewerUtils.ts +4 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +9 -7
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +10 -11
- package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +49 -0
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +18 -17
- package/package.json +6 -5
@@ -54,12 +54,13 @@ export class ContextMenuProvider implements UI.ContextMenu.Provider {
|
|
54
54
|
if (contentProvider instanceof Workspace.UISourceCode.UISourceCode) {
|
55
55
|
(contentProvider as Workspace.UISourceCode.UISourceCode).commitWorkingCopy();
|
56
56
|
}
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
const content = await contentProvider.requestContent();
|
58
|
+
let decodedContent = content.content || '';
|
59
|
+
if (content.isEncoded) {
|
60
|
+
decodedContent = window.atob(decodedContent);
|
60
61
|
}
|
61
62
|
const url = contentProvider.contentURL();
|
62
|
-
void Workspace.FileManager.FileManager.instance().save(url,
|
63
|
+
void Workspace.FileManager.FileManager.instance().save(url, decodedContent, true);
|
63
64
|
Workspace.FileManager.FileManager.instance().close(url);
|
64
65
|
}
|
65
66
|
|
@@ -37,12 +37,25 @@ export function createCssTokenizer(): Tokenizer {
|
|
37
37
|
const stream = new CodeMirror.StringStream();
|
38
38
|
stream.string = line;
|
39
39
|
|
40
|
-
const
|
40
|
+
const state = streamParser.startState();
|
41
41
|
let lastPos = stream.pos;
|
42
42
|
while (!stream.eol()) {
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
stream.start = lastPos;
|
44
|
+
let tokenType = streamParser.token(stream, state);
|
45
|
+
/**
|
46
|
+
* We expect unknown properties (like `unknownProp: unknownPropVal`) to still be
|
47
|
+
* formatted correctly. However, `tokenType` for such properties are marked
|
48
|
+
* as `error` from CodeMirror side and the internal state of the parser becomes `maybeprop`.
|
49
|
+
*
|
50
|
+
* So, we handle that specific keyword to be marked as `property` even though it is
|
51
|
+
* not a known property. We do this because for our formatting purposes it doesn't matter
|
52
|
+
* whether a property is a known CSS property or not.
|
53
|
+
*/
|
54
|
+
if (tokenType === 'error' && state.state === 'maybeprop') {
|
55
|
+
tokenType = 'property';
|
56
|
+
}
|
57
|
+
const segment = stream.current();
|
58
|
+
callback(segment, tokenType);
|
46
59
|
lastPos = stream.pos;
|
47
60
|
}
|
48
61
|
}
|
@@ -34,7 +34,6 @@ import type * as Platform from '../../core/platform/platform.js';
|
|
34
34
|
export abstract class ContentProvider {
|
35
35
|
abstract contentURL(): Platform.DevToolsPath.UrlString;
|
36
36
|
abstract contentType(): Common.ResourceType.ResourceType;
|
37
|
-
abstract contentEncoded(): Promise<boolean>;
|
38
37
|
abstract requestContent(): Promise<DeferredContent>;
|
39
38
|
abstract searchInContent(query: string, caseSensitive: boolean, isRegex: boolean): Promise<SearchMatch[]>;
|
40
39
|
}
|
@@ -39,10 +39,6 @@ export class StaticContentProvider implements ContentProvider {
|
|
39
39
|
return this.contentTypeInternal;
|
40
40
|
}
|
41
41
|
|
42
|
-
contentEncoded(): Promise<boolean> {
|
43
|
-
return Promise.resolve(false);
|
44
|
-
}
|
45
|
-
|
46
42
|
requestContent(): Promise<DeferredContent> {
|
47
43
|
return this.lazyContent();
|
48
44
|
}
|
@@ -71,6 +71,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
71
71
|
private workingCopyGetter: (() => string)|null;
|
72
72
|
private disableEditInternal: boolean;
|
73
73
|
private contentEncodedInternal?: boolean;
|
74
|
+
private isKnownThirdPartyInternal: boolean;
|
74
75
|
|
75
76
|
constructor(project: Project, url: Platform.DevToolsPath.UrlString, contentType: Common.ResourceType.ResourceType) {
|
76
77
|
super();
|
@@ -108,6 +109,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
108
109
|
this.workingCopyInternal = null;
|
109
110
|
this.workingCopyGetter = null;
|
110
111
|
this.disableEditInternal = false;
|
112
|
+
this.isKnownThirdPartyInternal = false;
|
111
113
|
}
|
112
114
|
|
113
115
|
requestMetadata(): Promise<UISourceCodeMetadata|null> {
|
@@ -207,11 +209,6 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
207
209
|
return this.contentTypeInternal;
|
208
210
|
}
|
209
211
|
|
210
|
-
async contentEncoded(): Promise<boolean> {
|
211
|
-
await this.requestContent();
|
212
|
-
return this.contentEncodedInternal || false;
|
213
|
-
}
|
214
|
-
|
215
212
|
project(): Project {
|
216
213
|
return this.projectInternal;
|
217
214
|
}
|
@@ -401,6 +398,14 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
401
398
|
return this.workingCopyInternal !== null || this.workingCopyGetter !== null;
|
402
399
|
}
|
403
400
|
|
401
|
+
isKnownThirdParty(): boolean {
|
402
|
+
return this.isKnownThirdPartyInternal;
|
403
|
+
}
|
404
|
+
|
405
|
+
markKnownThirdParty(): void {
|
406
|
+
this.isKnownThirdPartyInternal = true;
|
407
|
+
}
|
408
|
+
|
404
409
|
extension(): string {
|
405
410
|
return Common.ParsedURL.ParsedURL.extractExtension(this.nameInternal);
|
406
411
|
}
|
@@ -155,7 +155,7 @@ export class StackTrace extends HTMLElement {
|
|
155
155
|
const expandableRows = [];
|
156
156
|
let hiddenCallFramesCount = 0;
|
157
157
|
for (const item of this.#stackTraceRows) {
|
158
|
-
if (this.#showHidden ||
|
158
|
+
if (this.#showHidden || !item.ignoreListHide) {
|
159
159
|
if ('functionName' in item) {
|
160
160
|
expandableRows.push(LitHtml.html`
|
161
161
|
<${StackTraceRow.litTagName} data-stack-trace-row .data=${{
|
@@ -168,7 +168,7 @@ export class StackTrace extends HTMLElement {
|
|
168
168
|
`);
|
169
169
|
}
|
170
170
|
}
|
171
|
-
if (!this.#showHidden && 'functionName' in item &&
|
171
|
+
if (!this.#showHidden && 'functionName' in item && item.ignoreListHide) {
|
172
172
|
hiddenCallFramesCount++;
|
173
173
|
}
|
174
174
|
}
|
@@ -4,44 +4,63 @@
|
|
4
4
|
|
5
5
|
import * as i18n from '../../core/i18n/i18n.js';
|
6
6
|
|
7
|
+
import {
|
8
|
+
buildStyledPropertyText,
|
9
|
+
buildStyledRuleText,
|
10
|
+
isFlexContainer,
|
11
|
+
isGridContainer,
|
12
|
+
isMulticolContainer,
|
13
|
+
} from './CSSRuleValidatorHelper.js';
|
14
|
+
|
7
15
|
const UIStrings = {
|
8
16
|
/**
|
9
|
-
*@description
|
17
|
+
*@description The type of the CSS rule validation message that is shown in the Style panel. "Deprecated property" means that the property in the declaration is deprecated and should not be used.
|
18
|
+
*/
|
19
|
+
deprecatedPropertyHintPrefix: 'Deprecated property',
|
20
|
+
/**
|
21
|
+
*@description The type of the CSS rule validation message that is shown in the Style panel. "Inactive property" means that a property declaration was valid syntactially but didn't have expected effect.
|
10
22
|
*/
|
11
|
-
|
23
|
+
inactivePropertyHintPrefix: 'Inactive property',
|
12
24
|
/**
|
13
|
-
*@description
|
25
|
+
*@description The message that is shown in the Style panel when the user hovers over a property that has not effect due to some other property.
|
26
|
+
*@example {flex-wrap: nowrap} REASON_PROPERTY_DECLARATION_CODE
|
27
|
+
*@example {align-content} AFFECTED_PROPERTY_DECLARATION_CODE
|
14
28
|
*/
|
15
|
-
|
29
|
+
ruleViolatedBySameElementRuleReason:
|
30
|
+
'This element has the {REASON_PROPERTY_DECLARATION_CODE} property and therefore, {AFFECTED_PROPERTY_DECLARATION_CODE} has no effect.',
|
16
31
|
/**
|
17
|
-
*@description
|
18
|
-
*@example {flex-wrap: nowrap}
|
19
|
-
*@example {align-content} AFFECTED_RULE_CODE
|
32
|
+
*@description The message that is shown in the Style panel when the user hovers over a property declaration that has not effect due to some other property.
|
33
|
+
*@example {flex-wrap: nowrap} REASON_PROPERTY_DECLARATION_CODE
|
20
34
|
*/
|
21
|
-
|
35
|
+
ruleViolatedBySameElementRuleFix:
|
36
|
+
'For this property to work, please remove or change the value of {REASON_PROPERTY_DECLARATION_CODE}.',
|
22
37
|
/**
|
23
|
-
*@description
|
24
|
-
*@example {
|
38
|
+
*@description The message that is shown in the Style panel when the user hovers over a property declaration that has not effect due to the current property value.
|
39
|
+
*@example {display: block} EXISTING_PROPERTY_DECLARATION
|
40
|
+
*@example {display: flex} TARGET_PROPERTY_DECLARATION
|
25
41
|
*/
|
26
|
-
|
42
|
+
ruleViolatedBySameElementRuleChangeSuggestion:
|
43
|
+
'For this property to work, please change the {EXISTING_PROPERTY_DECLARATION} rule to {TARGET_PROPERTY_DECLARATION}.',
|
27
44
|
/**
|
28
|
-
*@description
|
29
|
-
*@example {display: block}
|
30
|
-
*@example {flex}
|
45
|
+
*@description The message that is shown in the Style panel when the user hovers over a property declaration that has not effect due to properties of the parent element.
|
46
|
+
*@example {display: block} REASON_PROPERTY_DECLARATION_CODE
|
47
|
+
*@example {flex} AFFECTED_PROPERTY_DECLARATION_CODE
|
31
48
|
*/
|
32
|
-
ruleViolatedByParentElementRuleReason:
|
49
|
+
ruleViolatedByParentElementRuleReason:
|
50
|
+
'The parent element has the {REASON_PROPERTY_DECLARATION_CODE} property and therefore, this element\'s property {AFFECTED_PROPERTY_DECLARATION_CODE} has no effect.',
|
33
51
|
/**
|
34
|
-
*@description
|
52
|
+
*@description The message that is shown in the Style panel when the user hovers over a property declaration that has not effect due to the properties of the parent element.
|
35
53
|
*@example {display: block} EXISTING_PARENT_ELEMENT_RULE
|
36
54
|
*@example {display: flex} TARGET_PARENT_ELEMENT_RULE
|
37
55
|
*/
|
38
|
-
ruleViolatedByParentElementRuleFix:
|
39
|
-
|
56
|
+
ruleViolatedByParentElementRuleFix:
|
57
|
+
'Please change the parent element\'s property declaration from {EXISTING_PARENT_ELEMENT_RULE} to {TARGET_PARENT_ELEMENT_RULE} to fix this issue.',
|
58
|
+
};
|
40
59
|
const str_ = i18n.i18n.registerUIStrings('panels/elements/CSSRuleValidator.ts', UIStrings);
|
41
60
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
42
61
|
|
43
62
|
export const enum AuthoringHintType {
|
44
|
-
|
63
|
+
INACTIVE_PROPERTY = 'ruleValidation',
|
45
64
|
DEPRECATED_PROPERTY = 'deprecatedProperty',
|
46
65
|
}
|
47
66
|
|
@@ -49,19 +68,20 @@ export class AuthoringHint {
|
|
49
68
|
readonly #hintType: AuthoringHintType;
|
50
69
|
readonly #hintMessage: string;
|
51
70
|
readonly #possibleFixMessage: string|null;
|
52
|
-
readonly #
|
71
|
+
readonly #learnMoreLink: string|undefined;
|
53
72
|
|
54
|
-
constructor(
|
73
|
+
constructor(
|
74
|
+
hintType: AuthoringHintType, hintMessage: string, possibleFixMessage: string|null, learnMoreLink?: string) {
|
55
75
|
this.#hintType = hintType;
|
56
76
|
this.#hintMessage = hintMessage;
|
57
77
|
this.#possibleFixMessage = possibleFixMessage;
|
58
|
-
this.#
|
78
|
+
this.#learnMoreLink = learnMoreLink;
|
59
79
|
}
|
60
80
|
|
61
81
|
getHintPrefix(): string {
|
62
82
|
switch (this.#hintType) {
|
63
|
-
case AuthoringHintType.
|
64
|
-
return i18nString(UIStrings.
|
83
|
+
case AuthoringHintType.INACTIVE_PROPERTY:
|
84
|
+
return i18nString(UIStrings.inactivePropertyHintPrefix);
|
65
85
|
case AuthoringHintType.DEPRECATED_PROPERTY:
|
66
86
|
return i18nString(UIStrings.deprecatedPropertyHintPrefix);
|
67
87
|
}
|
@@ -75,8 +95,8 @@ export class AuthoringHint {
|
|
75
95
|
return this.#possibleFixMessage;
|
76
96
|
}
|
77
97
|
|
78
|
-
getLearnMoreLink(): string|
|
79
|
-
return this.#
|
98
|
+
getLearnMoreLink(): string|undefined {
|
99
|
+
return this.#learnMoreLink;
|
80
100
|
}
|
81
101
|
}
|
82
102
|
|
@@ -87,6 +107,9 @@ export abstract class CSSRuleValidator {
|
|
87
107
|
this.#affectedProperties = affectedProperties;
|
88
108
|
}
|
89
109
|
|
110
|
+
/**
|
111
|
+
* If `isRuleValid` returns false, it means there is a hint to be shown. The hint is retrieved by invoking `getAuthoringHint`.
|
112
|
+
*/
|
90
113
|
abstract isRuleValid(computedStyles: Map<String, String>|null, parentsComputedStyles?: Map<String, String>|null):
|
91
114
|
boolean;
|
92
115
|
|
@@ -94,7 +117,9 @@ export abstract class CSSRuleValidator {
|
|
94
117
|
return this.#affectedProperties;
|
95
118
|
}
|
96
119
|
|
97
|
-
abstract getAuthoringHint(
|
120
|
+
abstract getAuthoringHint(
|
121
|
+
propertyName: string, computedStyles: Map<String, String>|null,
|
122
|
+
parentComputedStyles: Map<String, String>|null): AuthoringHint;
|
98
123
|
}
|
99
124
|
|
100
125
|
export class AlignContentValidator extends CSSRuleValidator {
|
@@ -106,28 +131,25 @@ export class AlignContentValidator extends CSSRuleValidator {
|
|
106
131
|
if (computedStyles === null || computedStyles === undefined) {
|
107
132
|
return true;
|
108
133
|
}
|
109
|
-
|
110
|
-
if (display !== 'flex' && display !== 'inline-flex') {
|
134
|
+
if (!isFlexContainer(computedStyles)) {
|
111
135
|
return true;
|
112
136
|
}
|
113
137
|
return computedStyles.get('flex-wrap') !== 'nowrap';
|
114
138
|
}
|
115
139
|
|
116
140
|
getAuthoringHint(): AuthoringHint {
|
117
|
-
const
|
118
|
-
const
|
141
|
+
const reasonPropertyDeclaration = buildStyledPropertyText('flex-wrap');
|
142
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText('align-content');
|
119
143
|
|
120
144
|
return new AuthoringHint(
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
}),
|
130
|
-
true,
|
145
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
146
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
147
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
148
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
149
|
+
}),
|
150
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
151
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
152
|
+
}),
|
131
153
|
);
|
132
154
|
}
|
133
155
|
}
|
@@ -138,40 +160,337 @@ export class FlexItemValidator extends CSSRuleValidator {
|
|
138
160
|
}
|
139
161
|
|
140
162
|
isRuleValid(computedStyles: Map<String, String>|null, parentsComputedStyles: Map<String, String>|null): boolean {
|
141
|
-
if (
|
142
|
-
parentsComputedStyles === undefined) {
|
163
|
+
if (parentsComputedStyles === null) {
|
143
164
|
return true;
|
144
165
|
}
|
145
|
-
|
146
|
-
return parentDisplay === 'flex' || parentDisplay === 'inline-flex';
|
166
|
+
return isFlexContainer(parentsComputedStyles);
|
147
167
|
}
|
148
168
|
|
149
|
-
getAuthoringHint(
|
150
|
-
|
151
|
-
|
152
|
-
const
|
169
|
+
getAuthoringHint(
|
170
|
+
property: string, computedStyles: Map<String, String>|null,
|
171
|
+
parentsComputedStyles: Map<String, String>|null): AuthoringHint {
|
172
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', parentsComputedStyles?.get('display'));
|
173
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
174
|
+
const targeParentPropertyDeclaration = buildStyledRuleText('display', 'flex');
|
153
175
|
|
154
176
|
return new AuthoringHint(
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
}),
|
165
|
-
true,
|
177
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
178
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
|
179
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
180
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
181
|
+
}),
|
182
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
|
183
|
+
'EXISTING_PARENT_ELEMENT_RULE': reasonPropertyDeclaration,
|
184
|
+
'TARGET_PARENT_ELEMENT_RULE': targeParentPropertyDeclaration,
|
185
|
+
}),
|
166
186
|
);
|
167
187
|
}
|
168
188
|
}
|
169
189
|
|
170
|
-
|
171
|
-
|
190
|
+
export class FlexContainerValidator extends CSSRuleValidator {
|
191
|
+
constructor() {
|
192
|
+
super(['flex-direction', 'flex-flow', 'flex-wrap', 'justify-content']);
|
193
|
+
}
|
194
|
+
|
195
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
196
|
+
if (computedStyles === null) {
|
197
|
+
return true;
|
198
|
+
}
|
199
|
+
return isFlexContainer(computedStyles);
|
200
|
+
}
|
201
|
+
|
202
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
203
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', computedStyles?.get('display'));
|
204
|
+
const targetRuleCode = buildStyledRuleText('display', 'flex');
|
205
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
206
|
+
|
207
|
+
return new AuthoringHint(
|
208
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
209
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
210
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
211
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
212
|
+
}),
|
213
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
|
214
|
+
'EXISTING_PROPERTY_DECLARATION': reasonPropertyDeclaration,
|
215
|
+
'TARGET_PROPERTY_DECLARATION': targetRuleCode,
|
216
|
+
}),
|
217
|
+
);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
export class GridContainerValidator extends CSSRuleValidator {
|
222
|
+
constructor() {
|
223
|
+
super([
|
224
|
+
'grid',
|
225
|
+
'grid-auto-columns',
|
226
|
+
'grid-auto-flow',
|
227
|
+
'grid-auto-rows',
|
228
|
+
'grid-template',
|
229
|
+
'grid-template-areas',
|
230
|
+
'grid-template-columns',
|
231
|
+
'grid-template-rows',
|
232
|
+
]);
|
233
|
+
}
|
234
|
+
|
235
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
236
|
+
if (computedStyles === null) {
|
237
|
+
return true;
|
238
|
+
}
|
239
|
+
return isGridContainer(computedStyles);
|
240
|
+
}
|
241
|
+
|
242
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
243
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', computedStyles?.get('display'));
|
244
|
+
const targetRuleCode = buildStyledRuleText('display', 'grid');
|
245
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
246
|
+
|
247
|
+
return new AuthoringHint(
|
248
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
249
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
250
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
251
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
252
|
+
}),
|
253
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleChangeSuggestion, {
|
254
|
+
'EXISTING_PROPERTY_DECLARATION': reasonPropertyDeclaration,
|
255
|
+
'TARGET_PROPERTY_DECLARATION': targetRuleCode,
|
256
|
+
}),
|
257
|
+
);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
export class GridItemValidator extends CSSRuleValidator {
|
262
|
+
constructor() {
|
263
|
+
super([
|
264
|
+
'grid-area',
|
265
|
+
'grid-column',
|
266
|
+
'grid-row',
|
267
|
+
'grid-row-end',
|
268
|
+
'grid-row-start',
|
269
|
+
]);
|
270
|
+
}
|
271
|
+
|
272
|
+
isRuleValid(computedStyles: Map<String, String>|null, parentComputedStyles: Map<String, String>|null): boolean {
|
273
|
+
if (parentComputedStyles === null) {
|
274
|
+
return true;
|
275
|
+
}
|
276
|
+
return isGridContainer(parentComputedStyles);
|
277
|
+
}
|
278
|
+
|
279
|
+
getAuthoringHint(
|
280
|
+
property: string, computedStyles: Map<String, String>|null,
|
281
|
+
parentComputedStyles: Map<String, String>|null): AuthoringHint {
|
282
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', parentComputedStyles?.get('display'));
|
283
|
+
const targeParentPropertyDeclaration = buildStyledRuleText('display', 'grid');
|
284
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
285
|
+
|
286
|
+
return new AuthoringHint(
|
287
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
288
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleReason, {
|
289
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
290
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
291
|
+
}),
|
292
|
+
i18nString(UIStrings.ruleViolatedByParentElementRuleFix, {
|
293
|
+
'EXISTING_PARENT_ELEMENT_RULE': reasonPropertyDeclaration,
|
294
|
+
'TARGET_PARENT_ELEMENT_RULE': targeParentPropertyDeclaration,
|
295
|
+
}),
|
296
|
+
);
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
export class FlexGridValidator extends CSSRuleValidator {
|
301
|
+
constructor() {
|
302
|
+
super([
|
303
|
+
'order',
|
304
|
+
'align-content',
|
305
|
+
'align-items',
|
306
|
+
'align-self',
|
307
|
+
]);
|
308
|
+
}
|
172
309
|
|
310
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
311
|
+
if (computedStyles === null) {
|
312
|
+
return true;
|
313
|
+
}
|
314
|
+
return isFlexContainer(computedStyles) || isGridContainer(computedStyles);
|
315
|
+
}
|
316
|
+
|
317
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
318
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', computedStyles?.get('display'));
|
319
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
320
|
+
|
321
|
+
return new AuthoringHint(
|
322
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
323
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
324
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
325
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
326
|
+
}),
|
327
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
328
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
329
|
+
}),
|
330
|
+
);
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
export class MulticolFlexGridValidator extends CSSRuleValidator {
|
335
|
+
constructor() {
|
336
|
+
super([
|
337
|
+
'gap',
|
338
|
+
'column-gap',
|
339
|
+
'row-gap',
|
340
|
+
'grid-gap',
|
341
|
+
'grid-column-gap',
|
342
|
+
'grid-column-end',
|
343
|
+
'grid-row-gap',
|
344
|
+
]);
|
345
|
+
}
|
346
|
+
|
347
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
348
|
+
if (computedStyles === null) {
|
349
|
+
return true;
|
350
|
+
}
|
351
|
+
return isMulticolContainer(computedStyles) || isFlexContainer(computedStyles) || isGridContainer(computedStyles);
|
352
|
+
}
|
353
|
+
|
354
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
355
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', computedStyles?.get('display'));
|
356
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
357
|
+
|
358
|
+
return new AuthoringHint(
|
359
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
360
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
361
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
362
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
363
|
+
}),
|
364
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
365
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
366
|
+
}),
|
367
|
+
);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
|
371
|
+
export class PaddingValidator extends CSSRuleValidator {
|
372
|
+
constructor() {
|
373
|
+
super([
|
374
|
+
'padding',
|
375
|
+
'padding-top',
|
376
|
+
'padding-right',
|
377
|
+
'padding-bottom',
|
378
|
+
'padding-left',
|
379
|
+
]);
|
380
|
+
}
|
381
|
+
|
382
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
383
|
+
const display = computedStyles?.get('display');
|
384
|
+
if (display === null || display === undefined) {
|
385
|
+
return true;
|
386
|
+
}
|
387
|
+
return !['table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group',
|
388
|
+
'table-column']
|
389
|
+
.includes(display as string);
|
390
|
+
}
|
391
|
+
|
392
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
393
|
+
const reasonPropertyDeclaration = buildStyledRuleText('display', computedStyles?.get('display'));
|
394
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
395
|
+
|
396
|
+
return new AuthoringHint(
|
397
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
398
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
399
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
400
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
401
|
+
}),
|
402
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
403
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
404
|
+
}),
|
405
|
+
);
|
406
|
+
}
|
407
|
+
}
|
408
|
+
|
409
|
+
export class PositionValidator extends CSSRuleValidator {
|
410
|
+
constructor() {
|
411
|
+
super([
|
412
|
+
'top',
|
413
|
+
'right',
|
414
|
+
'bottom',
|
415
|
+
'left',
|
416
|
+
]);
|
417
|
+
}
|
418
|
+
|
419
|
+
isRuleValid(computedStyles: Map<String, String>|null): boolean {
|
420
|
+
const position = computedStyles?.get('position');
|
421
|
+
if (position === null || position === undefined) {
|
422
|
+
return true;
|
423
|
+
}
|
424
|
+
return position !== 'static';
|
425
|
+
}
|
426
|
+
|
427
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
428
|
+
const reasonPropertyDeclaration = buildStyledRuleText('position', computedStyles?.get('position'));
|
429
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
430
|
+
|
431
|
+
return new AuthoringHint(
|
432
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
433
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
434
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
435
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
436
|
+
}),
|
437
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
438
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
439
|
+
}),
|
440
|
+
);
|
441
|
+
}
|
442
|
+
}
|
443
|
+
|
444
|
+
export class ZIndexValidator extends CSSRuleValidator {
|
445
|
+
constructor() {
|
446
|
+
super([
|
447
|
+
'z-index',
|
448
|
+
]);
|
449
|
+
}
|
450
|
+
|
451
|
+
isRuleValid(computedStyles: Map<String, String>|null, parentComputedStyles: Map<String, String>|null): boolean {
|
452
|
+
const position = computedStyles?.get('position');
|
453
|
+
if (position === null || position === undefined) {
|
454
|
+
return true;
|
455
|
+
}
|
456
|
+
return ['absolute', 'relative', 'fixed', 'sticky'].includes(position as string) ||
|
457
|
+
isFlexContainer(parentComputedStyles);
|
458
|
+
}
|
459
|
+
|
460
|
+
getAuthoringHint(property: string, computedStyles: Map<String, String>|null): AuthoringHint {
|
461
|
+
const reasonPropertyDeclaration = buildStyledRuleText('position', computedStyles?.get('position'));
|
462
|
+
const affectedPropertyDeclarationCode = buildStyledPropertyText(property);
|
463
|
+
|
464
|
+
return new AuthoringHint(
|
465
|
+
AuthoringHintType.INACTIVE_PROPERTY,
|
466
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleReason, {
|
467
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
468
|
+
'AFFECTED_PROPERTY_DECLARATION_CODE': affectedPropertyDeclarationCode,
|
469
|
+
}),
|
470
|
+
i18nString(UIStrings.ruleViolatedBySameElementRuleFix, {
|
471
|
+
'REASON_PROPERTY_DECLARATION_CODE': reasonPropertyDeclaration,
|
472
|
+
}),
|
473
|
+
);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
const CSS_RULE_VALIDATORS = [
|
478
|
+
AlignContentValidator,
|
479
|
+
FlexItemValidator,
|
480
|
+
FlexContainerValidator,
|
481
|
+
GridContainerValidator,
|
482
|
+
GridItemValidator,
|
483
|
+
FlexGridValidator,
|
484
|
+
MulticolFlexGridValidator,
|
485
|
+
PaddingValidator,
|
486
|
+
PositionValidator,
|
487
|
+
ZIndexValidator,
|
488
|
+
];
|
489
|
+
|
490
|
+
const setupCSSRulesValidators = (): Map<String, CSSRuleValidator[]> => {
|
173
491
|
const validatorsMap = new Map<String, CSSRuleValidator[]>();
|
174
|
-
for (const
|
492
|
+
for (const validatorClass of CSS_RULE_VALIDATORS) {
|
493
|
+
const validator = new validatorClass();
|
175
494
|
const affectedProperties = validator.getAffectedProperties();
|
176
495
|
|
177
496
|
for (const affectedProperty of affectedProperties) {
|