forked from mirrors/gecko-dev
Bug 1769771 - Differentiate inline from constructed stylesheets in rule view. r=nchevobbe
I think this is worth it, but needs localization changes so splitting it out. Differential Revision: https://phabricator.services.mozilla.com/D146683
This commit is contained in:
parent
32257d0c50
commit
05a8fc5ff9
11 changed files with 94 additions and 19 deletions
|
|
@ -42,6 +42,7 @@ class StyleSheetFront extends FrontClassWithSpec(styleSheetSpec) {
|
||||||
this.href = form.href;
|
this.href = form.href;
|
||||||
this.nodeHref = form.nodeHref;
|
this.nodeHref = form.nodeHref;
|
||||||
this.disabled = form.disabled;
|
this.disabled = form.disabled;
|
||||||
|
this.constructed = form.constructed;
|
||||||
this.title = form.title;
|
this.title = form.title;
|
||||||
this.system = form.system;
|
this.system = form.system;
|
||||||
this.styleSheetIndex = form.styleSheetIndex;
|
this.styleSheetIndex = form.styleSheetIndex;
|
||||||
|
|
|
||||||
|
|
@ -320,14 +320,18 @@ RuleEditor.prototype = {
|
||||||
* The original position object (url/line/column) or null.
|
* The original position object (url/line/column) or null.
|
||||||
*/
|
*/
|
||||||
_updateLocation: function(originalLocation) {
|
_updateLocation: function(originalLocation) {
|
||||||
let displayURL = this.rule.sheet ? this.rule.sheet.href : null;
|
let displayURL = this.rule.sheet?.href;
|
||||||
|
const constructed = this.rule.sheet?.constructed;
|
||||||
let line = this.rule.ruleLine;
|
let line = this.rule.ruleLine;
|
||||||
if (originalLocation) {
|
if (originalLocation) {
|
||||||
displayURL = originalLocation.url;
|
displayURL = originalLocation.url;
|
||||||
line = originalLocation.line;
|
line = originalLocation.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sourceTextContent = CssLogic.shortSource({ href: displayURL });
|
let sourceTextContent = CssLogic.shortSource({
|
||||||
|
constructed,
|
||||||
|
href: displayURL,
|
||||||
|
});
|
||||||
let title = displayURL ? displayURL : sourceTextContent;
|
let title = displayURL ? displayURL : sourceTextContent;
|
||||||
if (line > 0) {
|
if (line > 0) {
|
||||||
sourceTextContent += ":" + line;
|
sourceTextContent += ":" + line;
|
||||||
|
|
@ -347,8 +351,7 @@ RuleEditor.prototype = {
|
||||||
".ruleview-rule-source-label"
|
".ruleview-rule-source-label"
|
||||||
);
|
);
|
||||||
const title = this.rule.title;
|
const title = this.rule.title;
|
||||||
const sourceHref =
|
const sourceHref = this.rule.sheet?.href || title;
|
||||||
this.rule.sheet && this.rule.sheet.href ? this.rule.sheet.href : title;
|
|
||||||
|
|
||||||
const uaLabel = STYLE_INSPECTOR_L10N.getStr("rule.userAgentStyles");
|
const uaLabel = STYLE_INSPECTOR_L10N.getStr("rule.userAgentStyles");
|
||||||
sourceLabel.textContent = uaLabel + " " + title;
|
sourceLabel.textContent = uaLabel + " " + title;
|
||||||
|
|
|
||||||
|
|
@ -198,13 +198,15 @@ StyleSheetEditor.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.styleSheet.href) {
|
if (!this.styleSheet.href) {
|
||||||
|
// TODO(bug 176993): Probably a different index + string for
|
||||||
|
// constructable stylesheets, they can't be meaningfully edited right now
|
||||||
|
// because we don't have their original text.
|
||||||
const index = this.styleSheetFriendlyIndex + 1 || 0;
|
const index = this.styleSheetFriendlyIndex + 1 || 0;
|
||||||
return getString("inlineStyleSheet", index);
|
return getString("inlineStyleSheet", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._friendlyName) {
|
if (!this._friendlyName) {
|
||||||
const sheetURI = this.styleSheet.href;
|
this._friendlyName = shortSource(this.styleSheet);
|
||||||
this._friendlyName = shortSource({ href: sheetURI });
|
|
||||||
try {
|
try {
|
||||||
this._friendlyName = decodeURI(this._friendlyName);
|
this._friendlyName = decodeURI(this._friendlyName);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ class StyleSheetWatcher {
|
||||||
resourceId,
|
resourceId,
|
||||||
resourceType: STYLESHEET,
|
resourceType: STYLESHEET,
|
||||||
disabled: styleSheet.disabled,
|
disabled: styleSheet.disabled,
|
||||||
|
constructed: styleSheet.constructed,
|
||||||
fileName,
|
fileName,
|
||||||
href: styleSheet.href,
|
href: styleSheet.href,
|
||||||
isNew: isCreatedByDevTools,
|
isNew: isCreatedByDevTools,
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,7 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
|
||||||
href: this.href,
|
href: this.href,
|
||||||
nodeHref: docHref,
|
nodeHref: docHref,
|
||||||
disabled: this.rawSheet.disabled,
|
disabled: this.rawSheet.disabled,
|
||||||
|
constructed: this.rawSheet.constructed,
|
||||||
title: this.rawSheet.title,
|
title: this.rawSheet.title,
|
||||||
system: CssLogic.isAgentStylesheet(this.rawSheet),
|
system: CssLogic.isAgentStylesheet(this.rawSheet),
|
||||||
styleSheetIndex: this.styleSheetIndex,
|
styleSheetIndex: this.styleSheetIndex,
|
||||||
|
|
|
||||||
|
|
@ -649,7 +649,9 @@ class StyleSheetsManager extends EventEmitter {
|
||||||
|
|
||||||
if (ownerNode.nodeType == ownerNode.DOCUMENT_NODE) {
|
if (ownerNode.nodeType == ownerNode.DOCUMENT_NODE) {
|
||||||
return ownerNode.location.href;
|
return ownerNode.location.href;
|
||||||
} else if (ownerNode.ownerDocument?.location) {
|
}
|
||||||
|
|
||||||
|
if (ownerNode.ownerDocument?.location) {
|
||||||
return ownerNode.ownerDocument.location.href;
|
return ownerNode.ownerDocument.location.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ const EXISTING_RESOURCES = [
|
||||||
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
||||||
isNew: false,
|
isNew: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
ruleCount: 1,
|
ruleCount: 1,
|
||||||
mediaRules: [],
|
mediaRules: [],
|
||||||
},
|
},
|
||||||
|
|
@ -28,6 +29,17 @@ const EXISTING_RESOURCES = [
|
||||||
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
||||||
isNew: false,
|
isNew: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
|
ruleCount: 1,
|
||||||
|
mediaRules: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
styleText: "",
|
||||||
|
href: null,
|
||||||
|
nodeHref: null,
|
||||||
|
isNew: false,
|
||||||
|
disabled: false,
|
||||||
|
constructed: true,
|
||||||
ruleCount: 1,
|
ruleCount: 1,
|
||||||
mediaRules: [],
|
mediaRules: [],
|
||||||
},
|
},
|
||||||
|
|
@ -38,6 +50,7 @@ const EXISTING_RESOURCES = [
|
||||||
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
|
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
|
||||||
isNew: false,
|
isNew: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
ruleCount: 1,
|
ruleCount: 1,
|
||||||
mediaRules: [],
|
mediaRules: [],
|
||||||
},
|
},
|
||||||
|
|
@ -49,12 +62,13 @@ const EXISTING_RESOURCES = [
|
||||||
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
|
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
|
||||||
isNew: false,
|
isNew: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
ruleCount: 1,
|
ruleCount: 1,
|
||||||
mediaRules: [],
|
mediaRules: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const ADDITIONAL_RESOURCE = {
|
const ADDITIONAL_INLINE_RESOURCE = {
|
||||||
styleText:
|
styleText:
|
||||||
"@media all { body { color: red; } } @media print { body { color: cyan; } } body { font-size: 10px; }",
|
"@media all { body { color: red; } } @media print { body { color: cyan; } } body { font-size: 10px; }",
|
||||||
href: null,
|
href: null,
|
||||||
|
|
@ -62,6 +76,7 @@ const ADDITIONAL_RESOURCE = {
|
||||||
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
||||||
isNew: false,
|
isNew: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
ruleCount: 3,
|
ruleCount: 3,
|
||||||
mediaRules: [
|
mediaRules: [
|
||||||
{
|
{
|
||||||
|
|
@ -81,6 +96,17 @@ const ADDITIONAL_RESOURCE = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ADDITIONAL_CONSTRUCTED_RESOURCE = {
|
||||||
|
styleText: "",
|
||||||
|
href: null,
|
||||||
|
nodeHref: null,
|
||||||
|
isNew: false,
|
||||||
|
disabled: false,
|
||||||
|
constructed: true,
|
||||||
|
ruleCount: 2,
|
||||||
|
mediaRules: [],
|
||||||
|
};
|
||||||
|
|
||||||
const ADDITIONAL_FROM_ACTOR_RESOURCE = {
|
const ADDITIONAL_FROM_ACTOR_RESOURCE = {
|
||||||
styleText: "body { font-size: 10px; }",
|
styleText: "body { font-size: 10px; }",
|
||||||
href: null,
|
href: null,
|
||||||
|
|
@ -88,6 +114,7 @@ const ADDITIONAL_FROM_ACTOR_RESOURCE = {
|
||||||
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
|
||||||
isNew: true,
|
isNew: true,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
constructed: false,
|
||||||
ruleCount: 1,
|
ruleCount: 1,
|
||||||
mediaRules: [],
|
mediaRules: [],
|
||||||
};
|
};
|
||||||
|
|
@ -130,7 +157,7 @@ async function testResourceAvailableFeature() {
|
||||||
info("Check whether ResourceCommand gets additonal stylesheet");
|
info("Check whether ResourceCommand gets additonal stylesheet");
|
||||||
await ContentTask.spawn(
|
await ContentTask.spawn(
|
||||||
tab.linkedBrowser,
|
tab.linkedBrowser,
|
||||||
ADDITIONAL_RESOURCE.styleText,
|
ADDITIONAL_INLINE_RESOURCE.styleText,
|
||||||
text => {
|
text => {
|
||||||
const document = content.document;
|
const document = content.document;
|
||||||
const stylesheet = document.createElement("style");
|
const stylesheet = document.createElement("style");
|
||||||
|
|
@ -143,11 +170,29 @@ async function testResourceAvailableFeature() {
|
||||||
);
|
);
|
||||||
await assertResource(
|
await assertResource(
|
||||||
availableResources[availableResources.length - 1],
|
availableResources[availableResources.length - 1],
|
||||||
ADDITIONAL_RESOURCE
|
ADDITIONAL_INLINE_RESOURCE
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Check whether ResourceCommand gets additonal constructed stylesheet");
|
||||||
|
await ContentTask.spawn(tab.linkedBrowser, null, () => {
|
||||||
|
const document = content.document;
|
||||||
|
const s = new content.CSSStyleSheet();
|
||||||
|
// We use the different number of rules to meaningfully differentiate
|
||||||
|
// between constructed stylesheets.
|
||||||
|
s.replaceSync("foo { color: red } bar { color: blue }");
|
||||||
|
// TODO(bug 1751346): wrappedJSObject should be unnecessary.
|
||||||
|
document.wrappedJSObject.adoptedStyleSheets.push(s);
|
||||||
|
});
|
||||||
|
await waitUntil(
|
||||||
|
() => availableResources.length === EXISTING_RESOURCES.length + 2
|
||||||
|
);
|
||||||
|
await assertResource(
|
||||||
|
availableResources[availableResources.length - 1],
|
||||||
|
ADDITIONAL_CONSTRUCTED_RESOURCE
|
||||||
);
|
);
|
||||||
|
|
||||||
info(
|
info(
|
||||||
"Check whether ResourceCommand gets additonal stylesheet which is added by DevTool"
|
"Check whether ResourceCommand gets additonal stylesheet which is added by DevTools"
|
||||||
);
|
);
|
||||||
const styleSheetsFront = await targetCommand.targetFront.getFront(
|
const styleSheetsFront = await targetCommand.targetFront.getFront(
|
||||||
"stylesheets"
|
"stylesheets"
|
||||||
|
|
@ -156,7 +201,7 @@ async function testResourceAvailableFeature() {
|
||||||
ADDITIONAL_FROM_ACTOR_RESOURCE.styleText
|
ADDITIONAL_FROM_ACTOR_RESOURCE.styleText
|
||||||
);
|
);
|
||||||
await waitUntil(
|
await waitUntil(
|
||||||
() => availableResources.length === EXISTING_RESOURCES.length + 2
|
() => availableResources.length === EXISTING_RESOURCES.length + 3
|
||||||
);
|
);
|
||||||
await assertResource(
|
await assertResource(
|
||||||
availableResources[availableResources.length - 1],
|
availableResources[availableResources.length - 1],
|
||||||
|
|
@ -399,7 +444,10 @@ async function testNestedResourceUpdateFeature() {
|
||||||
function findMatchingExpectedResource(resource) {
|
function findMatchingExpectedResource(resource) {
|
||||||
return EXISTING_RESOURCES.find(
|
return EXISTING_RESOURCES.find(
|
||||||
expected =>
|
expected =>
|
||||||
resource.href === expected.href && resource.nodeHref === expected.nodeHref
|
resource.href === expected.href &&
|
||||||
|
resource.nodeHref === expected.nodeHref &&
|
||||||
|
resource.ruleCount === expected.ruleCount &&
|
||||||
|
resource.constructed == expected.constructed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,6 +521,7 @@ async function assertResource(resource, expected) {
|
||||||
is(resource.nodeHref, expected.nodeHref, "nodeHref is correct");
|
is(resource.nodeHref, expected.nodeHref, "nodeHref is correct");
|
||||||
is(resource.isNew, expected.isNew, "isNew is correct");
|
is(resource.isNew, expected.isNew, "isNew is correct");
|
||||||
is(resource.disabled, expected.disabled, "disabled is correct");
|
is(resource.disabled, expected.disabled, "disabled is correct");
|
||||||
|
is(resource.constructed, expected.constructed, "constructed is correct");
|
||||||
is(resource.ruleCount, expected.ruleCount, "ruleCount is correct");
|
is(resource.ruleCount, expected.ruleCount, "ruleCount is correct");
|
||||||
assertMediaRules(resource.mediaRules, expected.mediaRules);
|
assertMediaRules(resource.mediaRules, expected.mediaRules);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,13 @@
|
||||||
<style>
|
<style>
|
||||||
body { color: lime; }
|
body { color: lime; }
|
||||||
</style>
|
</style>
|
||||||
<link href="style_document.css" rel="stylesheet" type="text/css"/>
|
<link href="style_document.css" rel="stylesheet">
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
const s = new CSSStyleSheet();
|
||||||
|
s.replaceSync("body { background-color: blue }");
|
||||||
|
document.adoptedStyleSheets.push(s);
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<iframe src="https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html"></iframe>
|
<iframe src="https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html"></iframe>
|
||||||
|
|
|
||||||
|
|
@ -130,11 +130,16 @@ exports.isAgentStylesheet = function(sheet) {
|
||||||
* @param {CSSStyleSheet} sheet the DOM object for the style sheet.
|
* @param {CSSStyleSheet} sheet the DOM object for the style sheet.
|
||||||
*/
|
*/
|
||||||
exports.shortSource = function(sheet) {
|
exports.shortSource = function(sheet) {
|
||||||
// Use a string like "inline" if there is no source href
|
if (!sheet) {
|
||||||
if (!sheet || !sheet.href) {
|
|
||||||
return exports.l10n("rule.sourceInline");
|
return exports.l10n("rule.sourceInline");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sheet.href) {
|
||||||
|
return exports.l10n(
|
||||||
|
sheet.constructed ? "rule.sourceConstructed" : "rule.sourceInline"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// If the sheet is a data URL, return a trimmed version of it.
|
// If the sheet is a data URL, return a trimmed version of it.
|
||||||
const dataUrl = sheet.href.trim().match(/^data:.*?,((?:.|\r|\n)*)$/);
|
const dataUrl = sheet.href.trim().match(/^data:.*?,((?:.|\r|\n)*)$/);
|
||||||
if (dataUrl) {
|
if (dataUrl) {
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,14 @@ rule.status.BEST=Best Match
|
||||||
rule.status.MATCHED=Matched
|
rule.status.MATCHED=Matched
|
||||||
rule.status.PARENT_MATCH=Parent Match
|
rule.status.PARENT_MATCH=Parent Match
|
||||||
|
|
||||||
# LOCALIZATION NOTE (rule.sourceElement, rule.sourceInline): For each
|
# LOCALIZATION NOTE (rule.sourceElement, rule.sourceInline,
|
||||||
# style property the panel shows the rules which hold that specific property.
|
# rule.sourceConstructed): For each style property the panel shows the rules
|
||||||
|
# which hold that specific property.
|
||||||
# For every rule, the rule source is also displayed: a rule can come from a
|
# For every rule, the rule source is also displayed: a rule can come from a
|
||||||
# file, from the same page (inline), or from the element itself (element).
|
# file, from the same page (inline), from a constructed style sheet
|
||||||
|
# (constructed), or from the element itself (element).
|
||||||
rule.sourceInline=inline
|
rule.sourceInline=inline
|
||||||
|
rule.sourceConstructed=constructed
|
||||||
rule.sourceElement=element
|
rule.sourceElement=element
|
||||||
|
|
||||||
# LOCALIZATION NOTE (rule.inheritedFrom): Shown for CSS rules
|
# LOCALIZATION NOTE (rule.inheritedFrom): Shown for CSS rules
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,6 @@ interface StyleSheet {
|
||||||
readonly attribute DOMString sourceURL;
|
readonly attribute DOMString sourceURL;
|
||||||
[ChromeOnly, Pure]
|
[ChromeOnly, Pure]
|
||||||
readonly attribute Document? associatedDocument;
|
readonly attribute Document? associatedDocument;
|
||||||
|
[ChromeOnly, Pure, BinaryName="isConstructed"]
|
||||||
|
readonly attribute boolean constructed;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue