mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
Bug 1581008: Add inactive CSS message for properties that are impossible to override. r=pbro,fluent-reviewers,flod
Depends on D45624 Differential Revision: https://phabricator.services.mozilla.com/D45625 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b591abf5e0
commit
fa5347f328
@ -33,6 +33,8 @@ inactive-css-property-because-of-display = <strong>{ $property }</strong> has no
|
|||||||
|
|
||||||
inactive-css-not-display-block-on-floated = The <strong>display</strong> value has been changed by the engine to <strong>block</strong> because the element is <strong>floated<strong>.
|
inactive-css-not-display-block-on-floated = The <strong>display</strong> value has been changed by the engine to <strong>block</strong> because the element is <strong>floated<strong>.
|
||||||
|
|
||||||
|
inactive-css-property-is-impossible-to-override-in-visited = It’s impossible to override <strong>{ $property }</strong> due to <strong>:visited</strong> restriction.
|
||||||
|
|
||||||
## In the Rule View when a CSS property cannot be successfully applied we display
|
## In the Rule View when a CSS property cannot be successfully applied we display
|
||||||
## an icon. When this icon is hovered this message is displayed to explain how
|
## an icon. When this icon is hovered this message is displayed to explain how
|
||||||
## the problem can be solved.
|
## the problem can be solved.
|
||||||
|
@ -79,13 +79,13 @@ class InactiveCssTooltipHelper {
|
|||||||
*/
|
*/
|
||||||
getTemplate(data, tooltip) {
|
getTemplate(data, tooltip) {
|
||||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
const { fixId, msgId, numFixProps, property, display } = data;
|
const { fixId, msgId, numFixProps, property, display, learnMoreURL } = data;
|
||||||
const { doc } = tooltip;
|
const { doc } = tooltip;
|
||||||
|
|
||||||
|
const documentURL =
|
||||||
|
learnMoreURL || `https://developer.mozilla.org/docs/Web/CSS/${property}`;
|
||||||
this._currentTooltip = tooltip;
|
this._currentTooltip = tooltip;
|
||||||
this._currentUrl =
|
this._currentUrl = `${documentURL}?utm_source=devtools&utm_medium=inspector-inactive-css`;
|
||||||
`https://developer.mozilla.org/docs/Web/CSS/${property}` +
|
|
||||||
`?utm_source=devtools&utm_medium=inspector-inactive-css`;
|
|
||||||
|
|
||||||
const templateNode = doc.createElementNS(XHTML_NS, "template");
|
const templateNode = doc.createElementNS(XHTML_NS, "template");
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ const {
|
|||||||
getBindingElementAndPseudo,
|
getBindingElementAndPseudo,
|
||||||
getCSSStyleRules,
|
getCSSStyleRules,
|
||||||
l10n,
|
l10n,
|
||||||
|
hasVisitedState,
|
||||||
isAgentStylesheet,
|
isAgentStylesheet,
|
||||||
isAuthorStylesheet,
|
isAuthorStylesheet,
|
||||||
isUserStylesheet,
|
isUserStylesheet,
|
||||||
@ -724,6 +725,11 @@ CssLogic.href = function(sheet) {
|
|||||||
return href;
|
return href;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given node has visited state.
|
||||||
|
*/
|
||||||
|
CssLogic.hasVisitedState = hasVisitedState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A safe way to access cached bits of information about a stylesheet.
|
* A safe way to access cached bits of information about a stylesheet.
|
||||||
*
|
*
|
||||||
|
@ -101,8 +101,6 @@ const BOLD_FONT_WEIGHT = 700;
|
|||||||
// Offset (in px) to avoid cutting off text edges of italic fonts.
|
// Offset (in px) to avoid cutting off text edges of italic fonts.
|
||||||
const FONT_PREVIEW_OFFSET = 4;
|
const FONT_PREVIEW_OFFSET = 4;
|
||||||
|
|
||||||
const NS_EVENT_STATE_VISITED = 1 << 24;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PageStyle actor lets the client look at the styles on a page, as
|
* The PageStyle actor lets the client look at the styles on a page, as
|
||||||
* they are applied to a given node.
|
* they are applied to a given node.
|
||||||
@ -725,7 +723,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||||||
const domRules = InspectorUtils.getCSSStyleRules(
|
const domRules = InspectorUtils.getCSSStyleRules(
|
||||||
node,
|
node,
|
||||||
pseudo,
|
pseudo,
|
||||||
_hasVisitedState(node)
|
CssLogic.hasVisitedState(node)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!domRules) {
|
if (!domRules) {
|
||||||
@ -843,7 +841,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||||||
const { bindingElement, pseudo } = CssLogic.getBindingElementAndPseudo(
|
const { bindingElement, pseudo } = CssLogic.getBindingElementAndPseudo(
|
||||||
element
|
element
|
||||||
);
|
);
|
||||||
const relevantLinkVisited = _hasVisitedState(bindingElement);
|
const relevantLinkVisited = CssLogic.hasVisitedState(bindingElement);
|
||||||
entry.matchedSelectors = [];
|
entry.matchedSelectors = [];
|
||||||
|
|
||||||
for (let i = 0; i < selectors.length; i++) {
|
for (let i = 0; i < selectors.length; i++) {
|
||||||
@ -2249,10 +2247,3 @@ function getTextAtLineColumn(text, line, column) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.getTextAtLineColumn = getTextAtLineColumn;
|
exports.getTextAtLineColumn = getTextAtLineColumn;
|
||||||
|
|
||||||
function _hasVisitedState(node) {
|
|
||||||
return (
|
|
||||||
!!(InspectorUtils.getContentState(node) & NS_EVENT_STATE_VISITED) ||
|
|
||||||
InspectorUtils.hasPseudoClassLock(node, ":visited")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -5,12 +5,33 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const Services = require("Services");
|
const Services = require("Services");
|
||||||
|
const InspectorUtils = require("InspectorUtils");
|
||||||
|
|
||||||
|
loader.lazyRequireGetter(
|
||||||
|
this,
|
||||||
|
"CssLogic",
|
||||||
|
"devtools/server/actors/inspector/css-logic",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
const INACTIVE_CSS_ENABLED = Services.prefs.getBoolPref(
|
const INACTIVE_CSS_ENABLED = Services.prefs.getBoolPref(
|
||||||
"devtools.inspector.inactive.css.enabled",
|
"devtools.inspector.inactive.css.enabled",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const VISITED_MDN_LINK = "https://developer.mozilla.org/docs/Web/CSS/:visited";
|
||||||
|
const VISITED_INVALID_PROPERTIES = allCssPropertiesExcept([
|
||||||
|
"color",
|
||||||
|
"background-color",
|
||||||
|
"border-color",
|
||||||
|
"border-bottom-color",
|
||||||
|
"border-left-color",
|
||||||
|
"border-right-color",
|
||||||
|
"border-top-color",
|
||||||
|
"column-rule-color",
|
||||||
|
"outline-color",
|
||||||
|
]);
|
||||||
|
|
||||||
class InactivePropertyHelper {
|
class InactivePropertyHelper {
|
||||||
/**
|
/**
|
||||||
* A list of rules for when CSS properties have no effect.
|
* A list of rules for when CSS properties have no effect.
|
||||||
@ -195,6 +216,15 @@ class InactivePropertyHelper {
|
|||||||
msgId: "inactive-css-not-display-block-on-floated",
|
msgId: "inactive-css-not-display-block-on-floated",
|
||||||
numFixProps: 2,
|
numFixProps: 2,
|
||||||
},
|
},
|
||||||
|
// The property is impossible to override due to :visited restriction.
|
||||||
|
{
|
||||||
|
invalidProperties: VISITED_INVALID_PROPERTIES,
|
||||||
|
when: () => this.isVisitedRule(),
|
||||||
|
fixId: "learn-more",
|
||||||
|
msgId: "inactive-css-property-is-impossible-to-override-in-visited",
|
||||||
|
numFixProps: 1,
|
||||||
|
learnMoreURL: VISITED_MDN_LINK,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,6 +269,9 @@ class InactivePropertyHelper {
|
|||||||
* The number of properties we suggest in the fixId string.
|
* The number of properties we suggest in the fixId string.
|
||||||
* @return {String} object.property
|
* @return {String} object.property
|
||||||
* The inactive property name.
|
* The inactive property name.
|
||||||
|
* @return {String} object.learnMoreURL
|
||||||
|
* An optional link if we need to open an other link than
|
||||||
|
* the default MDN property one.
|
||||||
* @return {Boolean} object.used
|
* @return {Boolean} object.used
|
||||||
* true if the property is used.
|
* true if the property is used.
|
||||||
*/
|
*/
|
||||||
@ -253,6 +286,7 @@ class InactivePropertyHelper {
|
|||||||
let fixId = "";
|
let fixId = "";
|
||||||
let msgId = "";
|
let msgId = "";
|
||||||
let numFixProps = 0;
|
let numFixProps = 0;
|
||||||
|
let learnMoreURL = null;
|
||||||
let used = true;
|
let used = true;
|
||||||
|
|
||||||
this.VALIDATORS.some(validator => {
|
this.VALIDATORS.some(validator => {
|
||||||
@ -260,9 +294,7 @@ class InactivePropertyHelper {
|
|||||||
let isRuleConcerned = false;
|
let isRuleConcerned = false;
|
||||||
|
|
||||||
if (validator.invalidProperties) {
|
if (validator.invalidProperties) {
|
||||||
isRuleConcerned =
|
isRuleConcerned = validator.invalidProperties.includes(property);
|
||||||
validator.invalidProperties === "*" ||
|
|
||||||
validator.invalidProperties.includes(property);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRuleConcerned) {
|
if (!isRuleConcerned) {
|
||||||
@ -277,6 +309,7 @@ class InactivePropertyHelper {
|
|||||||
fixId = validator.fixId;
|
fixId = validator.fixId;
|
||||||
msgId = validator.msgId;
|
msgId = validator.msgId;
|
||||||
numFixProps = validator.numFixProps;
|
numFixProps = validator.numFixProps;
|
||||||
|
learnMoreURL = validator.learnMoreURL;
|
||||||
used = false;
|
used = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -300,6 +333,7 @@ class InactivePropertyHelper {
|
|||||||
msgId,
|
msgId,
|
||||||
numFixProps,
|
numFixProps,
|
||||||
property,
|
property,
|
||||||
|
learnMoreURL,
|
||||||
used,
|
used,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -627,6 +661,39 @@ class InactivePropertyHelper {
|
|||||||
return !!this.getParentGridElement(this.node);
|
return !!this.getParentGridElement(this.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isVisitedRule() {
|
||||||
|
if (!CssLogic.hasVisitedState(this.node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectors = CssLogic.getSelectors(this.cssRule);
|
||||||
|
if (!selectors.some(s => s.endsWith(":visited"))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { bindingElement, pseudo } = CssLogic.getBindingElementAndPseudo(
|
||||||
|
this.node
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let i = 0; i < selectors.length; i++) {
|
||||||
|
if (
|
||||||
|
!selectors[i].endsWith(":visited") &&
|
||||||
|
InspectorUtils.selectorMatchesElement(
|
||||||
|
bindingElement,
|
||||||
|
this.cssRule,
|
||||||
|
i,
|
||||||
|
pseudo,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// Match non :visited selector.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
getParentGridElement(node) {
|
getParentGridElement(node) {
|
||||||
// The documentElement can't be a grid item, only a container, so bail out.
|
// The documentElement can't be a grid item, only a container, so bail out.
|
||||||
if (node.flattenedTreeParentNode === node.ownerDocument) {
|
if (node.flattenedTreeParentNode === node.ownerDocument) {
|
||||||
@ -672,3 +739,23 @@ class InactivePropertyHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.inactivePropertyHelper = new InactivePropertyHelper();
|
exports.inactivePropertyHelper = new InactivePropertyHelper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all CSS property names except given properties.
|
||||||
|
*
|
||||||
|
* @param {Array} - propertiesToIgnore
|
||||||
|
* Array of property ignored.
|
||||||
|
* @return {Array}
|
||||||
|
* Array of all CSS property name except propertiesToIgnore.
|
||||||
|
*/
|
||||||
|
function allCssPropertiesExcept(propertiesToIgnore) {
|
||||||
|
const properties = new Set(
|
||||||
|
InspectorUtils.getCSSPropertyNames({ includeAliases: true })
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const name of propertiesToIgnore) {
|
||||||
|
properties.delete(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...properties];
|
||||||
|
}
|
||||||
|
@ -553,3 +553,20 @@ function getCSSStyleRules(node) {
|
|||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
exports.getCSSStyleRules = getCSSStyleRules;
|
exports.getCSSStyleRules = getCSSStyleRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given node has visited state.
|
||||||
|
*/
|
||||||
|
function hasVisitedState(node) {
|
||||||
|
if (!node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NS_EVENT_STATE_VISITED = 1 << 24;
|
||||||
|
|
||||||
|
return (
|
||||||
|
!!(InspectorUtils.getContentState(node) & NS_EVENT_STATE_VISITED) ||
|
||||||
|
InspectorUtils.hasPseudoClassLock(node, ":visited")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
exports.hasVisitedState = hasVisitedState;
|
||||||
|
Loading…
Reference in New Issue
Block a user