mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Backed out 2 changesets (bug 1306054) for l10n issues.
Backed out changeset 88fb590040c4 (bug 1306054) Backed out changeset 4369c5635972 (bug 1306054)
This commit is contained in:
parent
13ff287a49
commit
f88dffff7e
@ -4,7 +4,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
const Rule = require("devtools/client/inspector/rules/models/rule");
|
||||
const UserProperties = require("devtools/client/inspector/rules/models/user-properties");
|
||||
@ -16,8 +15,6 @@ loader.lazyRequireGetter(this, "parseNamedDeclarations", "devtools/shared/css/pa
|
||||
loader.lazyRequireGetter(this, "parseSingleValue", "devtools/shared/css/parsing-utils", true);
|
||||
loader.lazyRequireGetter(this, "isCssVariable", "devtools/shared/fronts/css-properties", true);
|
||||
|
||||
const PREF_INACTIVE_CSS_ENABLED = "devtools.inspector.inactive.css.enabled";
|
||||
|
||||
/**
|
||||
* ElementStyle is responsible for the following:
|
||||
* Keeps track of which properties are overridden.
|
||||
@ -68,13 +65,6 @@ class ElementStyle {
|
||||
}
|
||||
}
|
||||
|
||||
get unusedCssEnabled() {
|
||||
if (!this._unusedCssEnabled) {
|
||||
this._unusedCssEnabled = Services.prefs.getBoolPref(PREF_INACTIVE_CSS_ENABLED);
|
||||
}
|
||||
return this._unusedCssEnabled;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.destroyed) {
|
||||
return;
|
||||
@ -135,7 +125,7 @@ class ElementStyle {
|
||||
}
|
||||
|
||||
// Mark overridden computed styles.
|
||||
this.onRuleUpdated();
|
||||
this.markOverriddenAll();
|
||||
|
||||
this._sortRulesForPseudoElement();
|
||||
|
||||
@ -252,28 +242,26 @@ class ElementStyle {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls updateDeclarations with all supported pseudo elements
|
||||
* Calls markOverridden with all supported pseudo elements
|
||||
*/
|
||||
onRuleUpdated() {
|
||||
markOverriddenAll() {
|
||||
this.variables.clear();
|
||||
this.updateDeclarations();
|
||||
this.markOverridden();
|
||||
|
||||
for (const pseudo of this.cssProperties.pseudoElements) {
|
||||
this.updateDeclarations(pseudo);
|
||||
this.markOverridden(pseudo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the declarations for a given pseudo element with an overridden flag if
|
||||
* an earlier property overrides it and update the editor to show it in the
|
||||
* UI. If there is any inactive CSS we also update the editors state to show
|
||||
* the inactive CSS icon.
|
||||
* Mark the properties listed in this.rules for a given pseudo element
|
||||
* with an overridden flag if an earlier property overrides it.
|
||||
*
|
||||
* @param {String} pseudo
|
||||
* Which pseudo element to flag as overridden.
|
||||
* Empty string or undefined will default to no pseudo element.
|
||||
*/
|
||||
updateDeclarations(pseudo = "") {
|
||||
markOverridden(pseudo = "") {
|
||||
// Gather all the text properties applied by these rules, ordered
|
||||
// from more- to less-specific. Text properties from keyframes rule are
|
||||
// excluded from being marked as overridden since a number of criteria such
|
||||
@ -357,22 +345,16 @@ class ElementStyle {
|
||||
}
|
||||
}
|
||||
|
||||
// For each TextProperty, mark it overridden if all of its computed
|
||||
// properties are marked overridden. Update the text property's associated
|
||||
// editor, if any. This will clear the _overriddenDirty state on all
|
||||
// computed properties. For each editor we also show or hide the inactive
|
||||
// CSS icon as needed.
|
||||
// For each TextProperty, mark it overridden if all of its
|
||||
// computed properties are marked overridden. Update the text
|
||||
// property's associated editor, if any. This will clear the
|
||||
// _overriddenDirty state on all computed properties.
|
||||
for (const textProp of textProps) {
|
||||
// _updatePropertyOverridden will return true if the
|
||||
// overridden state has changed for the text property.
|
||||
if (this._updatePropertyOverridden(textProp)) {
|
||||
textProp.updateEditor();
|
||||
}
|
||||
|
||||
// For each editor show or hide the inactive CSS icon as needed.
|
||||
if (textProp.editor && this.unusedCssEnabled) {
|
||||
textProp.editor.updatePropertyState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,9 +581,8 @@ class ElementStyle {
|
||||
// the same relative position.
|
||||
this.rules.splice(newIndex === -1 ? oldIndex : newIndex, 0, newRule);
|
||||
|
||||
// Recompute, mark and update the UI for any properties that are
|
||||
// overridden or contain inactive CSS according to the new list of rules.
|
||||
this.onRuleUpdated();
|
||||
// Mark any properties that are overridden according to the new list of rules.
|
||||
this.markOverriddenAll();
|
||||
|
||||
// In order to keep the new rule in place of the old in the rules view, we need
|
||||
// to remove the rule again if the rule was inserted to its new index according
|
||||
@ -613,6 +594,7 @@ class ElementStyle {
|
||||
this.rules.splice(newIndex, 1);
|
||||
this.rules.splice(oldIndex, 0, newRule);
|
||||
}
|
||||
|
||||
this._changed();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -308,7 +308,7 @@ class Rule {
|
||||
* in the element style's store.
|
||||
*/
|
||||
_applyPropertiesNoAuthored(modifications) {
|
||||
this.elementStyle.onRuleUpdated();
|
||||
this.elementStyle.markOverriddenAll();
|
||||
|
||||
const disabledProps = [];
|
||||
|
||||
@ -419,7 +419,7 @@ class Rule {
|
||||
}
|
||||
return this._applyPropertiesNoAuthored(modifications);
|
||||
}).then(() => {
|
||||
this.elementStyle.onRuleUpdated();
|
||||
this.elementStyle.markOverriddenAll();
|
||||
|
||||
if (resultPromise === this._applyingModifications) {
|
||||
this._applyingModifications = null;
|
||||
|
@ -232,19 +232,6 @@ class TextProperty {
|
||||
return this.rule.domRule.declarations[selfIndex].isValid;
|
||||
}
|
||||
|
||||
isUsed() {
|
||||
const selfIndex = this.rule.textProps.indexOf(this);
|
||||
const declarations = this.rule.domRule.declarations;
|
||||
|
||||
// StyleRuleActor's declarations may have a isUsed flag (if the server is the right
|
||||
// version). Just return true if the information is missing.
|
||||
if (!declarations || !declarations[selfIndex] || !declarations[selfIndex].isUsed) {
|
||||
return { used: true };
|
||||
}
|
||||
|
||||
return declarations[selfIndex].isUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the name of this property.
|
||||
*
|
||||
|
@ -195,8 +195,6 @@ skip-if = (os == "win" && debug) # bug 963492: win.
|
||||
[browser_rules_highlight-element-rule.js]
|
||||
[browser_rules_highlight-property.js]
|
||||
[browser_rules_highlight-used-fonts.js]
|
||||
[browser_rules_inactive_css_flexbox.js]
|
||||
[browser_rules_inactive_css_grid.js]
|
||||
[browser_rules_inherited-properties_01.js]
|
||||
[browser_rules_inherited-properties_02.js]
|
||||
[browser_rules_inherited-properties_03.js]
|
||||
|
@ -1,170 +0,0 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test inactive flex properties.
|
||||
|
||||
const TEST_URI = `
|
||||
<head>
|
||||
<style>
|
||||
#container {
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
border: 1px solid #000;
|
||||
align-content: space-between;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.flex-item {
|
||||
flex-basis: auto;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#self-aligned {
|
||||
align-self: stretch;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>browser_rules_inactive_css_flexbox.js</h1>
|
||||
<div id="container" style="display:flex">
|
||||
<div class="flex-item item-1" style="order:1">1</div>
|
||||
<div class="flex-item item-2" style="order:2">2</div>
|
||||
<div class="flex-item item-3" style="order:3">3</div>
|
||||
</div>
|
||||
<div id="self-aligned"></div>
|
||||
</body>`;
|
||||
|
||||
const BEFORE = [
|
||||
{
|
||||
selector: "#self-aligned",
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.or.flex.item",
|
||||
declaration: {
|
||||
"align-self": "stretch",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
selector: ".item-2",
|
||||
activeDeclarations: [
|
||||
{
|
||||
declarations: {
|
||||
"order": "2",
|
||||
},
|
||||
ruleIndex: 0,
|
||||
},
|
||||
{
|
||||
declarations: {
|
||||
"flex-basis": "auto",
|
||||
"flex-grow": "1",
|
||||
"flex-shrink": "1",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.container",
|
||||
declaration: {
|
||||
"flex-direction": "row",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
selector: "#container",
|
||||
activeDeclarations: [
|
||||
{
|
||||
declarations: {
|
||||
"display": "flex",
|
||||
},
|
||||
ruleIndex: 0,
|
||||
},
|
||||
{
|
||||
declarations: {
|
||||
width: "200px",
|
||||
height: "100px",
|
||||
border: "1px solid #000",
|
||||
"align-content": "space-between",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.item",
|
||||
declaration: {
|
||||
"order": "1",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
waitFor: "inspector-updated",
|
||||
},
|
||||
];
|
||||
|
||||
const AFTER = [
|
||||
{
|
||||
selector: ".item-2",
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.item",
|
||||
declaration: {
|
||||
"order": "2",
|
||||
},
|
||||
ruleIndex: 0,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.item",
|
||||
declaration: {
|
||||
"flex-basis": "auto",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.item",
|
||||
declaration: {
|
||||
"flex-grow": "1",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.item",
|
||||
declaration: {
|
||||
"flex-shrink": "1",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.container",
|
||||
declaration: {
|
||||
"flex-direction": "row",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const {inspector, view} = await openRuleView();
|
||||
|
||||
await runInactiveCSSTests(view, inspector, BEFORE);
|
||||
|
||||
// Toggle `display:flex` to disabled.
|
||||
await toggleDeclaration(inspector, view, 0, {
|
||||
display: "flex",
|
||||
});
|
||||
await view.once("ruleview-refreshed");
|
||||
await runInactiveCSSTests(view, inspector, AFTER);
|
||||
});
|
@ -1,170 +0,0 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test inactive grid properties.
|
||||
|
||||
const TEST_URI = `
|
||||
<head>
|
||||
<style>
|
||||
#container {
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
border: 1px solid #000;
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.item-1 {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: auto;
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
#self-aligned {
|
||||
align-self: stretch;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>browser_rules_inactive_css_grid.js</h1>
|
||||
<div id="container" style="display:grid">
|
||||
<div class="grid-item item-1">1</div>
|
||||
<div class="grid-item item-2">2</div>
|
||||
<div class="grid-item item-3">3</div>
|
||||
<div class="grid-item item-4">4</div>
|
||||
</div>
|
||||
<div id="self-aligned"></div>
|
||||
</body>`;
|
||||
|
||||
const BEFORE = [
|
||||
{
|
||||
selector: "#self-aligned",
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.or.flex.item",
|
||||
declaration: {
|
||||
"align-self": "stretch",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
selector: ".item-1",
|
||||
activeDeclarations: [
|
||||
{
|
||||
declarations: {
|
||||
"grid-column-start": "1",
|
||||
"grid-column-end": "3",
|
||||
"grid-row-start": "1",
|
||||
"grid-row-end": "auto",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.flex.container",
|
||||
declaration: {
|
||||
"flex-direction": "row",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
selector: "#container",
|
||||
activeDeclarations: [
|
||||
{
|
||||
declarations: {
|
||||
display: "grid",
|
||||
},
|
||||
ruleIndex: 0,
|
||||
},
|
||||
{
|
||||
declarations: {
|
||||
width: "200px",
|
||||
height: "100px",
|
||||
border: "1px solid #000",
|
||||
"column-gap": "10px",
|
||||
"row-gap": "10px",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.or.flex.item",
|
||||
declaration: {
|
||||
"align-self": "start",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
waitFor: "inspector-updated",
|
||||
},
|
||||
];
|
||||
|
||||
const AFTER = [
|
||||
{
|
||||
activeDeclarations: [
|
||||
{
|
||||
declarations: {
|
||||
display: "grid",
|
||||
},
|
||||
ruleIndex: 0,
|
||||
},
|
||||
{
|
||||
declarations: {
|
||||
width: "200px",
|
||||
height: "100px",
|
||||
border: "1px solid #000",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
inactiveDeclarations: [
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.container",
|
||||
declaration: {
|
||||
"column-gap": "10px",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.container",
|
||||
declaration: {
|
||||
"row-gap": "10px",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
{
|
||||
l10n: "rule.inactive.css.not.grid.or.flex.item",
|
||||
declaration: {
|
||||
"align-self": "start",
|
||||
},
|
||||
ruleIndex: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const {inspector, view} = await openRuleView();
|
||||
|
||||
await runInactiveCSSTests(view, inspector, BEFORE);
|
||||
|
||||
// Toggle `display:grid` to disabled.
|
||||
await toggleDeclaration(inspector, view, 0, {
|
||||
display: "grid",
|
||||
});
|
||||
await view.once("ruleview-refreshed");
|
||||
await runInactiveCSSTests(view, inspector, AFTER);
|
||||
});
|
@ -568,7 +568,7 @@ async function toggleClassPanelCheckBox(view, name) {
|
||||
|
||||
/**
|
||||
* Verify the content of the class-panel.
|
||||
* @param {CssRuleView} view The rule-view instance
|
||||
* @param {CssRuleView} view The rule-view isntance
|
||||
* @param {Array} classes The list of expected classes. Each item in this array is an
|
||||
* object with the following properties: {name: {String}, state: {Boolean}}
|
||||
*/
|
||||
@ -606,204 +606,3 @@ async function openEyedropper(view, swatch) {
|
||||
dropperButton.click();
|
||||
await onOpened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of declarations for a rule index.
|
||||
*
|
||||
* @param {ruleView} view
|
||||
* The rule-view instance.
|
||||
* @param {Number} ruleIndex
|
||||
* The index we expect the rule to have in the rule-view.
|
||||
*
|
||||
* @returns A map containing stringified property declarations e.g.
|
||||
* [
|
||||
* {
|
||||
* "color:red":
|
||||
* {
|
||||
* propertyName: "color",
|
||||
* propertyValue: "red",
|
||||
* warnings: "This won't work",
|
||||
* used: true,
|
||||
* }
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
*/
|
||||
function getPropertiesForRuleIndex(view, ruleIndex) {
|
||||
const declaration = new Map();
|
||||
const ruleEditor = getRuleViewRuleEditor(view, ruleIndex);
|
||||
|
||||
for (const currProp of ruleEditor.rule.textProps) {
|
||||
const icon = currProp.editor.unusedState;
|
||||
|
||||
declaration.set(`${currProp.name}:${currProp.value}`, {
|
||||
propertyName: currProp.name,
|
||||
propertyValue: currProp.value,
|
||||
warnings: icon.title ? icon.title.split("\n") : [],
|
||||
used: !currProp.editor.element.classList.contains("unused"),
|
||||
});
|
||||
}
|
||||
|
||||
return declaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a declaration disabled or enabled.
|
||||
*
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox.
|
||||
* @param {ruleView} view
|
||||
* The rule-view instance
|
||||
* @param {Number} ruleIndex
|
||||
* The index of the CSS rule where we can find the declaration to be
|
||||
* toggled.
|
||||
* @param {Object} declaration
|
||||
* An object representing the declaration e.g. { color: "red" }.
|
||||
*/
|
||||
async function toggleDeclaration(inspector, view, ruleIndex, declaration) {
|
||||
const ruleEditor = getRuleViewRuleEditor(view, ruleIndex);
|
||||
const [[ name, value ]] = Object.entries(declaration);
|
||||
|
||||
let textProp = null;
|
||||
for (const currProp of ruleEditor.rule.textProps) {
|
||||
if (currProp.name === name && currProp.value === value) {
|
||||
textProp = currProp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const dec = `${name}:${value}`;
|
||||
ok(textProp, `Declaration "${dec}" found`);
|
||||
|
||||
const newStatus = textProp.enabled ? "disabled" : "enabled";
|
||||
info(`Toggling declaration "${dec}" of rule ${ruleIndex} to ${newStatus}`);
|
||||
|
||||
await togglePropStatus(view, textProp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a declaration is marked inactive and that it has the expected
|
||||
* warning.
|
||||
*
|
||||
* @param {ruleView} view
|
||||
* The rule-view instance.
|
||||
* @param {Number} ruleIndex
|
||||
* The index we expect the rule to have in the rule-view.
|
||||
* @param {Object} declaration
|
||||
* An object representing the declaration e.g. { color: "red" }.
|
||||
* @param {String} warningL10nString
|
||||
* l10n string representing an expected warning.
|
||||
*/
|
||||
function checkDeclarationIsInactive(view, ruleIndex, declaration, warningL10nString) {
|
||||
const declarations = getPropertiesForRuleIndex(view, ruleIndex);
|
||||
const [[ name, value ]] = Object.entries(declaration);
|
||||
const dec = `${name}:${value}`;
|
||||
const { used, warnings } = declarations.get(dec);
|
||||
|
||||
ok(!used, `"${dec}" is inactive`);
|
||||
is(warnings.length, 1, `"${dec}" has a warning`);
|
||||
|
||||
const warning = INSPECTOR_L10N.getFormatStr(warningL10nString, name);
|
||||
is(warnings[0], warning, `The warning on "${dec}" is correct`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a declaration is marked active.
|
||||
*
|
||||
* @param {ruleView} view
|
||||
* The rule-view instance.
|
||||
* @param {Number} ruleIndex
|
||||
* The index we expect the rule to have in the rule-view.
|
||||
* @param {Object} declaration
|
||||
* An object representing the declaration e.g. { color: "red" }.
|
||||
*/
|
||||
function checkDeclarationIsActive(view, ruleIndex, declaration) {
|
||||
const declarations = getPropertiesForRuleIndex(view, ruleIndex);
|
||||
const [[ name, value ]] = Object.entries(declaration);
|
||||
const dec = `${name}:${value}`;
|
||||
const { used, warnings } = declarations.get(dec);
|
||||
|
||||
ok(used, `${dec} is active`);
|
||||
is(warnings.length, 0, `${dec} has no warnings`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inactive CSS test runner.
|
||||
*
|
||||
* @param {ruleView} view
|
||||
* The rule-view instance.
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox.
|
||||
* @param {Array} tests
|
||||
* An array of test object for this method to consume e.g.
|
||||
* [
|
||||
* {
|
||||
* selector: "#flex-item",
|
||||
* activeDeclarations: [
|
||||
* {
|
||||
* declarations: {
|
||||
* "order": "2",
|
||||
* },
|
||||
* ruleIndex: 0,
|
||||
* },
|
||||
* {
|
||||
* declarations: {
|
||||
* "flex-basis": "auto",
|
||||
* "flex-grow": "1",
|
||||
* "flex-shrink": "1",
|
||||
* },
|
||||
* ruleIndex: 1,
|
||||
* },
|
||||
* ],
|
||||
* inactiveDeclarations: [
|
||||
* {
|
||||
* l10n: "rule.inactive.css.not.flex.container",
|
||||
* declaration: {
|
||||
* "flex-direction": "row",
|
||||
* },
|
||||
* ruleIndex: 1,
|
||||
* },
|
||||
* ],
|
||||
* waitFor: "markupmutation",
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
*/
|
||||
async function runInactiveCSSTests(view, inspector, tests) {
|
||||
for (const test of tests) {
|
||||
let event = null;
|
||||
|
||||
if (test.waitFor) {
|
||||
event = inspector.once(test.waitFor);
|
||||
}
|
||||
|
||||
if (test.selector) {
|
||||
await selectNode(test.selector, inspector);
|
||||
}
|
||||
|
||||
if (test.waitFor) {
|
||||
await event;
|
||||
}
|
||||
|
||||
if (test.activeDeclarations) {
|
||||
// Check whether declarations are marked as used.
|
||||
for (const activeDeclarations of test.activeDeclarations) {
|
||||
for (const [name, value] of Object.entries(activeDeclarations.declarations)) {
|
||||
checkDeclarationIsActive(view, activeDeclarations.ruleIndex, {
|
||||
[name]: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (test.inactiveDeclarations) {
|
||||
for (const inactiveDeclaration of test.inactiveDeclarations) {
|
||||
// Check that declaration is unused and has a warning.
|
||||
checkDeclarationIsInactive(view,
|
||||
inactiveDeclaration.ruleIndex,
|
||||
inactiveDeclaration.declaration,
|
||||
inactiveDeclaration.l10n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ RuleEditor.prototype = {
|
||||
rules.splice(oldIndex, 1);
|
||||
rules.splice(newRuleIndex, 0, newRule);
|
||||
elementStyle._changed();
|
||||
elementStyle.onRuleUpdated();
|
||||
elementStyle.markOverriddenAll();
|
||||
|
||||
// We install the new editor in place of the old -- you might
|
||||
// think we would replicate the list-modification logic above,
|
||||
|
@ -182,11 +182,6 @@ TextPropertyEditor.prototype = {
|
||||
title: l10n("rule.warning.title"),
|
||||
});
|
||||
|
||||
this.unusedState = createChild(this.container, "div", {
|
||||
class: "ruleview-unused-warning",
|
||||
hidden: "",
|
||||
});
|
||||
|
||||
// Filter button that filters for the current property name and is
|
||||
// displayed when the property is overridden by another rule.
|
||||
this.filterProperty = createChild(this.container, "div", {
|
||||
@ -601,8 +596,8 @@ TextPropertyEditor.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the visibility of the enable checkbox, the warning indicator, the used
|
||||
* indicator and the filter property, as well as the overridden state of the property.
|
||||
* Update the visibility of the enable checkbox, the warning indicator and
|
||||
* the filter property, as well as the overridden state of the property.
|
||||
*/
|
||||
updatePropertyState: function() {
|
||||
if (this.prop.enabled) {
|
||||
@ -633,17 +628,6 @@ TextPropertyEditor.prototype = {
|
||||
} else {
|
||||
this.element.classList.remove("ruleview-overridden");
|
||||
}
|
||||
|
||||
const { used, reasons } = this.prop.isUsed();
|
||||
|
||||
if (this.editing || this.prop.overridden || !this.prop.enabled || used) {
|
||||
this.element.classList.remove("unused");
|
||||
this.unusedState.hidden = true;
|
||||
} else {
|
||||
this.element.classList.add("unused");
|
||||
this.unusedState.title = reasons.join("\n");
|
||||
this.unusedState.hidden = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -775,20 +775,20 @@ async function assertTooltipShownOnHover(tooltip, target) {
|
||||
* @return a promise that resolves with the tooltip object
|
||||
*/
|
||||
async function assertShowPreviewTooltip(view, target) {
|
||||
const name = "previewTooltip";
|
||||
|
||||
// Get the tooltip. If it does not exist one will be created.
|
||||
const tooltip = view.tooltips.getTooltip(name);
|
||||
ok(tooltip, `Tooltip '${name}' has been instantiated`);
|
||||
|
||||
const shown = tooltip.once("shown");
|
||||
const mouseEvent = new target.ownerDocument.defaultView.MouseEvent("mousemove", {
|
||||
bubbles: true,
|
||||
});
|
||||
target.dispatchEvent(mouseEvent);
|
||||
|
||||
info("Waiting for tooltip to be shown");
|
||||
await shown;
|
||||
const name = "previewTooltip";
|
||||
ok(view.tooltips._instances.has(name),
|
||||
`Tooltip '${name}' has been instantiated`);
|
||||
const tooltip = view.tooltips.getTooltip(name);
|
||||
|
||||
if (!tooltip.isVisible()) {
|
||||
info("Waiting for tooltip to be shown");
|
||||
await tooltip.once("shown");
|
||||
}
|
||||
|
||||
ok(tooltip.isVisible(), `The tooltip '${name}' is visible`);
|
||||
|
||||
|
@ -97,7 +97,6 @@ devtools.jar:
|
||||
skin/breadcrumbs.css (themes/breadcrumbs.css)
|
||||
skin/chart.css (themes/chart.css)
|
||||
skin/widgets.css (themes/widgets.css)
|
||||
skin/images/alerticon-unused.svg (themes/images/alerticon-unused.svg)
|
||||
skin/rules.css (themes/rules.css)
|
||||
skin/images/command-paintflashing.svg (themes/images/command-paintflashing.svg)
|
||||
skin/images/command-screenshot.svg (themes/images/command-screenshot.svg)
|
||||
|
@ -488,33 +488,3 @@ markupView.scrollableBadge.tooltip=This element has scrollable overflow.
|
||||
# LOCALIZATION NOTE (rulePreviewTooltip.noAssociatedRule): This is the text displayed inside
|
||||
# the RulePreviewTooltip when a rule cannot be found for a CSS property declaration.
|
||||
rulePreviewTooltip.noAssociatedRule=No associated rule
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.flex.container): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.flex.container=“%S” has no effect on this element since it’s not a flex container (try adding “display:flex” or “display:inline-flex”)
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.flex.item): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.flex.item=“%S” has no effect on this element since it’s not a flex item (try adding “display:flex” or “display:inline-flex” to the item’s parent)
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.grid.container): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.grid.container=“%S” has no effect on this element since it’s not a grid container (try adding “display:grid” or “display:inline-grid”)
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.grid.item): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.grid.item=“%S” has no effect on this element since it’s not a grid item (try adding “display:grid” or “display:inline-grid” to the item’s parent)
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.grid.or.flex.item): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.grid.or.flex.item=“%S” has no effect on this element since it’s not a grid or flex item (try adding “display:grid”, “display:flex”, “display:inline-grid” or “display:inline-flex” to the item’s parent)
|
||||
|
||||
# LOCALIZATION NOTE (rule.inactive.css.not.grid.or.flex.container): These properties
|
||||
# contain the text displayed inside the Rule View’s Inactive CSS Tooltip when a
|
||||
# property is not active. %S will be replaced with a property name.
|
||||
rule.inactive.css.not.grid.or.flex.container=“%S” has no effect on this element since it’s neither a flex container nor a grid container (try adding “display:grid” or “display:flex”)
|
||||
|
@ -50,12 +50,6 @@ pref("devtools.inspector.showUserAgentStyles", false);
|
||||
pref("devtools.inspector.showAllAnonymousContent", false);
|
||||
// Show user agent shadow roots
|
||||
pref("devtools.inspector.showUserAgentShadowRoots", false);
|
||||
// Enable Inactive CSS detection
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("devtools.inspector.inactive.css.enabled", true);
|
||||
#else
|
||||
pref("devtools.inspector.inactive.css.enabled", false);
|
||||
#endif
|
||||
// Enable the new Rules View
|
||||
pref("devtools.inspector.new-rulesview.enabled", false);
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16">
|
||||
<path stroke="context-stroke" fill="none" d="M15.5 8.5C15.5 12.36 12.36 15.5 8.5 15.5C4.63 15.5 1.5 12.36 1.5 8.5C1.5 4.64 4.63 1.5 8.5 1.5C12.36 1.5 15.5 4.64 15.5 8.5Z"/>
|
||||
<path fill="context-fill" d="M8.98 7.47C9.52 7.47 9.96 7.91 9.96 8.45C9.96 9.42 9.96 11.33 9.96 12.29C9.96 12.83 9.52 13.27 8.98 13.27C8.59 13.27 8.4 13.27 8.01 13.27C7.47 13.27 7.03 12.83 7.03 12.29C7.03 11.33 7.03 9.42 7.03 8.45C7.03 7.91 7.47 7.47 8.01 7.47C8.4 7.47 8.59 7.47 8.98 7.47Z"/>
|
||||
<path fill="context-fill" d="M9.96 5.36C9.96 6.16 9.3 6.81 8.49 6.81C7.69 6.81 7.03 6.16 7.03 5.36C7.03 4.57 7.69 3.92 8.49 3.92C9.3 3.92 9.96 4.57 9.96 5.36Z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 938 B |
@ -7,7 +7,6 @@
|
||||
--rule-highlight-background-color: var(--theme-highlight-yellow);
|
||||
--rule-header-background-color: var(--theme-toolbar-background);
|
||||
--rule-pseudo-class-text-color: var(--yellow-70) ;
|
||||
|
||||
/* This should be --yellow-50 but since we need an opacity of 0.4, we hard-code the
|
||||
resulting color here for now. */
|
||||
--rule-property-highlight-background-color: #FFF697;
|
||||
@ -17,7 +16,6 @@
|
||||
--rule-highlight-background-color: #521C76;
|
||||
--rule-header-background-color: #222225;
|
||||
--rule-pseudo-class-text-color: var(--yellow-50);
|
||||
|
||||
/* This should be --yellow-50 but since we need an opacity of 0.3, we hard-code the
|
||||
resulting color here for now. */
|
||||
--rule-property-highlight-background-color: #605913;
|
||||
@ -31,7 +29,6 @@
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* Override the min-width from .inspector-tabpanel, as the rule panel can support small
|
||||
widths */
|
||||
min-width: 100px;
|
||||
@ -50,7 +47,7 @@
|
||||
}
|
||||
|
||||
#ruleview-toolbar > .devtools-searchbox:first-child {
|
||||
padding-inline-start: 0;
|
||||
padding-inline-start: 0px;
|
||||
}
|
||||
|
||||
#ruleview-command-toolbar {
|
||||
@ -194,8 +191,6 @@
|
||||
.ruleview-overridden-items[hidden],
|
||||
.ruleview-overridden-rule-filter[hidden],
|
||||
.ruleview-warning[hidden],
|
||||
.ruleview-unused-warning[hidden],
|
||||
.ruleview-used[hidden],
|
||||
.ruleview-overridden .ruleview-grid {
|
||||
display: none;
|
||||
}
|
||||
@ -264,7 +259,7 @@
|
||||
}
|
||||
|
||||
.ruleview-rule-pseudo-element {
|
||||
padding-left: 20px;
|
||||
padding-left:20px;
|
||||
border-left: solid 10px;
|
||||
}
|
||||
|
||||
@ -322,11 +317,6 @@
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.ruleview-property.unused .ruleview-namecontainer,
|
||||
.ruleview-property.unused .ruleview-propertyvaluecontainer {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.ruleview-overridden-rule-filter {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
@ -369,8 +359,7 @@
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.ruleview-warning,
|
||||
.ruleview-unused-warning {
|
||||
.ruleview-warning {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
@ -381,19 +370,6 @@
|
||||
fill: var(--yellow-60);
|
||||
}
|
||||
|
||||
.ruleview-unused-warning {
|
||||
background-image: url(chrome://devtools/skin/images/alerticon-unused.svg);
|
||||
background-color: var(--theme-sidebar-background);
|
||||
-moz-context-properties: fill, stroke;
|
||||
fill: var(--theme-icon-dimmed-color);
|
||||
stroke: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.ruleview-unused-warning:hover {
|
||||
fill: var(--theme-icon-color);
|
||||
stroke: var(--theme-icon-color);
|
||||
}
|
||||
|
||||
.ruleview-rule:not(:hover) .ruleview-enableproperty {
|
||||
visibility: hidden;
|
||||
}
|
||||
@ -442,11 +418,11 @@
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
border: 0 solid var(--theme-text-color-alt);
|
||||
border: 0px solid var(--theme-text-color-alt);
|
||||
}
|
||||
|
||||
.ruleview-overridden-item::before {
|
||||
top: 0;
|
||||
top: 0px;
|
||||
left: -15px;
|
||||
height: 0.8em;
|
||||
width: 10px;
|
||||
@ -479,7 +455,6 @@
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
|
||||
/* align the swatch with its value */
|
||||
margin-top: -1px;
|
||||
margin-inline-end: 5px;
|
||||
|
@ -21,8 +21,6 @@ loader.lazyRequireGetter(this, "getDefinedGeometryProperties",
|
||||
"devtools/server/actors/highlighters/geometry-editor", true);
|
||||
loader.lazyRequireGetter(this, "isCssPropertyKnown",
|
||||
"devtools/server/actors/css-properties", true);
|
||||
loader.lazyRequireGetter(this, "inactivePropertyHelper",
|
||||
"devtools/server/actors/utils/inactive-property-helper", true);
|
||||
loader.lazyRequireGetter(this, "parseNamedDeclarations",
|
||||
"devtools/shared/css/parsing-utils", true);
|
||||
loader.lazyRequireGetter(this, "prettifyCSS",
|
||||
@ -1285,8 +1283,6 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
|
||||
? form.authoredText
|
||||
: form.cssText;
|
||||
const declarations = parseNamedDeclarations(isCssPropertyKnown, cssText, true);
|
||||
const el = this.pageStyle.cssLogic.viewedElement;
|
||||
const style = this.pageStyle.cssLogic.computedStyle;
|
||||
|
||||
// We need to grab CSS from the window, since calling supports() on the
|
||||
// one from the current global will fail due to not being an HTML global.
|
||||
@ -1295,8 +1291,6 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
|
||||
// Use the 1-arg CSS.supports() call so that we also accept !important
|
||||
// in the value.
|
||||
decl.isValid = CSS.supports(`${decl.name}:${decl.value}`);
|
||||
decl.isUsed = inactivePropertyHelper.isPropertyUsed(
|
||||
el, style, this.rawRule, decl.name);
|
||||
// Check property name. All valid CSS properties support "initial" as a value.
|
||||
decl.isNameValid = CSS.supports(decl.name, "initial");
|
||||
return decl;
|
||||
|
@ -1,366 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const PREF_UNUSED_CSS_ENABLED = "devtools.inspector.inactive.css.enabled";
|
||||
const INSPECTOR_L10N =
|
||||
new LocalizationHelper("devtools/client/locales/inspector.properties");
|
||||
|
||||
class InactivePropertyHelper {
|
||||
/**
|
||||
* A list of rules for when CSS properties have no effect.
|
||||
*
|
||||
* In certain situations, CSS properties do not have any effect. A common
|
||||
* example is trying to set a width on an inline element like a <span>.
|
||||
*
|
||||
* There are so many properties in CSS that it's difficult to remember which
|
||||
* ones do and don't apply in certain situations. Some are straight-forward
|
||||
* like `flex-wrap` only applying to an element that has `display:flex`.
|
||||
* Others are less trivial like setting something other than a color on a
|
||||
* `:visited` pseudo-class.
|
||||
*
|
||||
* This file contains "rules" in the form of objects with the following
|
||||
* properties:
|
||||
* {
|
||||
* invalidProperties (see note):
|
||||
* Array of CSS property names that are inactive if the rule matches.
|
||||
* validProperties (see note):
|
||||
* Array of CSS property names that are active if the rule matches.
|
||||
* when:
|
||||
* The rule itself, a JS function used to identify the conditions
|
||||
* indicating whether a property is valid or not.
|
||||
*
|
||||
* error:
|
||||
* A JS function that returns a custom error message explaining why the
|
||||
* property is inactive in this situation. This function takes a single
|
||||
* argument: the property name.
|
||||
* }
|
||||
*
|
||||
* NOTE: validProperties and invalidProperties are mutually exclusive.
|
||||
*
|
||||
* The main export is `isPropertyUsed()`, which can be used to check if a
|
||||
* property is used or not, and why.
|
||||
*/
|
||||
get VALIDATORS() {
|
||||
return [
|
||||
// Flex container property used on non-flex container.
|
||||
{
|
||||
invalidProperties: [
|
||||
"flex-direction",
|
||||
"flex-flow",
|
||||
"flex-wrap",
|
||||
],
|
||||
when: () => !this.flexContainer,
|
||||
error: property => msg("rule.inactive.css.not.flex.container", property),
|
||||
},
|
||||
// Flex item property used on non-flex item.
|
||||
{
|
||||
invalidProperties: [
|
||||
"flex",
|
||||
"flex-basis",
|
||||
"flex-grow",
|
||||
"flex-shrink",
|
||||
"order",
|
||||
],
|
||||
when: () => !this.flexItem,
|
||||
error: property => msg("rule.inactive.css.not.flex.item", property),
|
||||
},
|
||||
// Grid container property used on non-grid container.
|
||||
{
|
||||
invalidProperties: [
|
||||
"grid-auto-columns",
|
||||
"grid-auto-flow",
|
||||
"grid-auto-rows",
|
||||
"grid-template",
|
||||
"grid-gap",
|
||||
"row-gap",
|
||||
"column-gap",
|
||||
"justify-items",
|
||||
],
|
||||
when: () => !this.gridContainer,
|
||||
error: property => msg("rule.inactive.css.not.grid.container", property),
|
||||
},
|
||||
// Grid item property used on non-grid item.
|
||||
{
|
||||
invalidProperties: [
|
||||
"grid-area",
|
||||
"grid-column",
|
||||
"grid-column-end",
|
||||
"grid-column-start",
|
||||
"grid-row",
|
||||
"grid-row-end",
|
||||
"grid-row-start",
|
||||
"justify-self",
|
||||
],
|
||||
when: () => !this.gridItem,
|
||||
error: property => msg("rule.inactive.css.not.grid.item", property),
|
||||
},
|
||||
// Grid and flex item properties used on non-grid or non-flex item.
|
||||
{
|
||||
invalidProperties: [
|
||||
"align-self",
|
||||
],
|
||||
when: () => !this.gridItem && !this.flexItem,
|
||||
error: property => msg("rule.inactive.css.not.grid.or.flex.item", property),
|
||||
},
|
||||
// Grid and flex container properties used on non-grid or non-flex container.
|
||||
{
|
||||
invalidProperties: [
|
||||
"align-content",
|
||||
"align-items",
|
||||
"justify-content",
|
||||
],
|
||||
when: () => !this.gridContainer && !this.flexContainer,
|
||||
error: property => msg("rule.inactive.css.not.grid.or.flex.container", property),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get unusedCssEnabled() {
|
||||
if (!this._unusedCssEnabled) {
|
||||
this._unusedCssEnabled = Services.prefs.getBoolPref(PREF_UNUSED_CSS_ENABLED);
|
||||
}
|
||||
return this._unusedCssEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this CSS property having any effect on this element?
|
||||
*
|
||||
* @param {DOMNode} el
|
||||
* The DOM element.
|
||||
* @param {Style} elStyle
|
||||
* The computed style for this DOMNode.
|
||||
* @param {DOMRule} cssRule
|
||||
* The CSS rule the property is defined in.
|
||||
* @param {String} property
|
||||
* The CSS property name.
|
||||
*
|
||||
* @return {Object} object
|
||||
* @return {Boolean} object.used
|
||||
* true if the property is used.
|
||||
* @return {Array} object.reasons
|
||||
* A string array listing the reasons a property isn't used.
|
||||
*/
|
||||
isPropertyUsed(el, elStyle, cssRule, property) {
|
||||
if (!this.unusedCssEnabled) {
|
||||
return {used: true};
|
||||
}
|
||||
|
||||
const errors = [];
|
||||
|
||||
this.VALIDATORS.forEach(validator => {
|
||||
// First check if this rule cares about this property.
|
||||
let isRuleConcerned = false;
|
||||
|
||||
if (validator.invalidProperties) {
|
||||
isRuleConcerned = validator.invalidProperties === "*" ||
|
||||
validator.invalidProperties.includes(property);
|
||||
} else if (validator.validProperties) {
|
||||
isRuleConcerned = !validator.validProperties.includes(property);
|
||||
}
|
||||
|
||||
if (!isRuleConcerned) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.select(el, elStyle, cssRule, property);
|
||||
|
||||
// And then run the validator, gathering the error message if the
|
||||
// validator passes.
|
||||
if (validator.when()) {
|
||||
const error = validator.error(property);
|
||||
|
||||
if (typeof error === "string") {
|
||||
errors.push(validator.error(property));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
used: !errors.length,
|
||||
reasons: errors,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus on a node.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* Node to focus on.
|
||||
*/
|
||||
select(node, style, cssRule, property) {
|
||||
this._node = node;
|
||||
this._cssRule = cssRule;
|
||||
this._property = property;
|
||||
this._style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a public reference to node.
|
||||
*/
|
||||
get node() {
|
||||
return this._node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache and provide node's computed style.
|
||||
*/
|
||||
get style() {
|
||||
return this._style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current node's propName is set to one of the values passed in
|
||||
* the values array.
|
||||
*
|
||||
* @param {String} propName
|
||||
* Property name to check.
|
||||
* @param {Array} values
|
||||
* Values to compare against.
|
||||
*/
|
||||
checkStyle(propName, values) {
|
||||
return this.checkStyleForNode(this.node, propName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node's propName is set to one of the values passed in the values
|
||||
* array.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* The node to check.
|
||||
* @param {String} propName
|
||||
* Property name to check.
|
||||
* @param {Array} values
|
||||
* Values to compare against.
|
||||
*/
|
||||
checkStyleForNode(node, propName, values) {
|
||||
return values.some(value => this.style[propName] === value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current node is a flex container i.e. a node that has a style
|
||||
* of `display:flex` or `display:inline-flex`.
|
||||
*/
|
||||
get flexContainer() {
|
||||
return this.checkStyle("display", ["flex", "inline-flex"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current node is a flex item.
|
||||
*/
|
||||
get flexItem() {
|
||||
return this.isFlexItem(this.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current node is a grid container i.e. a node that has a style
|
||||
* of `display:grid` or `display:inline-grid`.
|
||||
*/
|
||||
get gridContainer() {
|
||||
return this.checkStyle("display", ["grid", "inline-grid"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current node is a grid item.
|
||||
*/
|
||||
get gridItem() {
|
||||
return this.isGridItem(this.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node is a flex item.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* The node to check.
|
||||
*/
|
||||
isFlexItem(node) {
|
||||
return !!node.parentFlexElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node is a flex container.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* The node to check.
|
||||
*/
|
||||
isFlexContainer(node) {
|
||||
return !!node.getAsFlexContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node is a grid container.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* The node to check.
|
||||
*/
|
||||
isGridContainer(node) {
|
||||
return !!node.getGridFragments().length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node is a grid item.
|
||||
*
|
||||
* @param {DOMNode} node
|
||||
* The node to check.
|
||||
*/
|
||||
isGridItem(node) {
|
||||
return !!this.getParentGridElement(this.node);
|
||||
}
|
||||
|
||||
getParentGridElement(node) {
|
||||
if (node.nodeType === node.ELEMENT_NODE) {
|
||||
const display = this.style.display;
|
||||
|
||||
if (!display || display === "none" || display === "contents") {
|
||||
// Doesn't generate a box, not a grid item.
|
||||
return null;
|
||||
}
|
||||
const position = this.style.position;
|
||||
if (position === "absolute" ||
|
||||
position === "fixed" ||
|
||||
this.style.cssFloat !== "none") {
|
||||
// Out of flow, not a grid item.
|
||||
return null;
|
||||
}
|
||||
} else if (node.nodeType !== node.TEXT_NODE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let p = node.flattenedTreeParentNode; p; p = p.flattenedTreeParentNode) {
|
||||
const style = node.ownerGlobal.getComputedStyle(p);
|
||||
const display = style.display;
|
||||
|
||||
if (display.includes("grid") && !!p.getGridFragments().length > 0) {
|
||||
// It's a grid item!
|
||||
return p;
|
||||
}
|
||||
if (display !== "contents") {
|
||||
return null; // Not a grid item, for sure.
|
||||
}
|
||||
// display: contents, walk to the parent
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that gets localized strings.
|
||||
*
|
||||
* @param {String} propName
|
||||
* The property name to use. This property name must exist in the
|
||||
* `inspector.properties` file).
|
||||
* @param {*} values
|
||||
* Values to be used as replacement strings.
|
||||
*/
|
||||
function msg(...args) {
|
||||
return INSPECTOR_L10N.getFormatStr(...args);
|
||||
}
|
||||
|
||||
exports.inactivePropertyHelper = new InactivePropertyHelper();
|
@ -13,7 +13,6 @@ DevToolsModules(
|
||||
'dbg-source.js',
|
||||
'event-breakpoints.js',
|
||||
'event-loop.js',
|
||||
'inactive-property-helper.js',
|
||||
'make-debugger.js',
|
||||
'shapes-utils.js',
|
||||
'stack.js',
|
||||
|
Loading…
Reference in New Issue
Block a user