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:
Emilio Cobos Álvarez 2022-05-19 22:32:28 +00:00
parent 32257d0c50
commit 05a8fc5ff9
11 changed files with 94 additions and 19 deletions

View file

@ -42,6 +42,7 @@ class StyleSheetFront extends FrontClassWithSpec(styleSheetSpec) {
this.href = form.href;
this.nodeHref = form.nodeHref;
this.disabled = form.disabled;
this.constructed = form.constructed;
this.title = form.title;
this.system = form.system;
this.styleSheetIndex = form.styleSheetIndex;

View file

@ -320,14 +320,18 @@ RuleEditor.prototype = {
* The original position object (url/line/column) or null.
*/
_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;
if (originalLocation) {
displayURL = originalLocation.url;
line = originalLocation.line;
}
let sourceTextContent = CssLogic.shortSource({ href: displayURL });
let sourceTextContent = CssLogic.shortSource({
constructed,
href: displayURL,
});
let title = displayURL ? displayURL : sourceTextContent;
if (line > 0) {
sourceTextContent += ":" + line;
@ -347,8 +351,7 @@ RuleEditor.prototype = {
".ruleview-rule-source-label"
);
const title = this.rule.title;
const sourceHref =
this.rule.sheet && this.rule.sheet.href ? this.rule.sheet.href : title;
const sourceHref = this.rule.sheet?.href || title;
const uaLabel = STYLE_INSPECTOR_L10N.getStr("rule.userAgentStyles");
sourceLabel.textContent = uaLabel + " " + title;

View file

@ -198,13 +198,15 @@ StyleSheetEditor.prototype = {
}
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;
return getString("inlineStyleSheet", index);
}
if (!this._friendlyName) {
const sheetURI = this.styleSheet.href;
this._friendlyName = shortSource({ href: sheetURI });
this._friendlyName = shortSource(this.styleSheet);
try {
this._friendlyName = decodeURI(this._friendlyName);
} catch (ex) {

View file

@ -69,6 +69,7 @@ class StyleSheetWatcher {
resourceId,
resourceType: STYLESHEET,
disabled: styleSheet.disabled,
constructed: styleSheet.constructed,
fileName,
href: styleSheet.href,
isNew: isCreatedByDevTools,

View file

@ -375,6 +375,7 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
href: this.href,
nodeHref: docHref,
disabled: this.rawSheet.disabled,
constructed: this.rawSheet.constructed,
title: this.rawSheet.title,
system: CssLogic.isAgentStylesheet(this.rawSheet),
styleSheetIndex: this.styleSheetIndex,

View file

@ -649,7 +649,9 @@ class StyleSheetsManager extends EventEmitter {
if (ownerNode.nodeType == ownerNode.DOCUMENT_NODE) {
return ownerNode.location.href;
} else if (ownerNode.ownerDocument?.location) {
}
if (ownerNode.ownerDocument?.location) {
return ownerNode.ownerDocument.location.href;
}

View file

@ -17,6 +17,7 @@ const EXISTING_RESOURCES = [
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
isNew: false,
disabled: false,
constructed: false,
ruleCount: 1,
mediaRules: [],
},
@ -28,6 +29,17 @@ const EXISTING_RESOURCES = [
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
isNew: false,
disabled: false,
constructed: false,
ruleCount: 1,
mediaRules: [],
},
{
styleText: "",
href: null,
nodeHref: null,
isNew: false,
disabled: false,
constructed: true,
ruleCount: 1,
mediaRules: [],
},
@ -38,6 +50,7 @@ const EXISTING_RESOURCES = [
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
isNew: false,
disabled: false,
constructed: false,
ruleCount: 1,
mediaRules: [],
},
@ -49,12 +62,13 @@ const EXISTING_RESOURCES = [
"https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html",
isNew: false,
disabled: false,
constructed: false,
ruleCount: 1,
mediaRules: [],
},
];
const ADDITIONAL_RESOURCE = {
const ADDITIONAL_INLINE_RESOURCE = {
styleText:
"@media all { body { color: red; } } @media print { body { color: cyan; } } body { font-size: 10px; }",
href: null,
@ -62,6 +76,7 @@ const ADDITIONAL_RESOURCE = {
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
isNew: false,
disabled: false,
constructed: false,
ruleCount: 3,
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 = {
styleText: "body { font-size: 10px; }",
href: null,
@ -88,6 +114,7 @@ const ADDITIONAL_FROM_ACTOR_RESOURCE = {
"https://example.com/browser/devtools/shared/commands/resource/tests/style_document.html",
isNew: true,
disabled: false,
constructed: false,
ruleCount: 1,
mediaRules: [],
};
@ -130,7 +157,7 @@ async function testResourceAvailableFeature() {
info("Check whether ResourceCommand gets additonal stylesheet");
await ContentTask.spawn(
tab.linkedBrowser,
ADDITIONAL_RESOURCE.styleText,
ADDITIONAL_INLINE_RESOURCE.styleText,
text => {
const document = content.document;
const stylesheet = document.createElement("style");
@ -143,11 +170,29 @@ async function testResourceAvailableFeature() {
);
await assertResource(
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(
"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(
"stylesheets"
@ -156,7 +201,7 @@ async function testResourceAvailableFeature() {
ADDITIONAL_FROM_ACTOR_RESOURCE.styleText
);
await waitUntil(
() => availableResources.length === EXISTING_RESOURCES.length + 2
() => availableResources.length === EXISTING_RESOURCES.length + 3
);
await assertResource(
availableResources[availableResources.length - 1],
@ -399,7 +444,10 @@ async function testNestedResourceUpdateFeature() {
function findMatchingExpectedResource(resource) {
return EXISTING_RESOURCES.find(
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.isNew, expected.isNew, "isNew 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");
assertMediaRules(resource.mediaRules, expected.mediaRules);
}

View file

@ -8,7 +8,13 @@
<style>
body { color: lime; }
</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>
<body>
<iframe src="https://example.org/browser/devtools/shared/commands/resource/tests/style_iframe.html"></iframe>

View file

@ -130,11 +130,16 @@ exports.isAgentStylesheet = function(sheet) {
* @param {CSSStyleSheet} sheet the DOM object for the style sheet.
*/
exports.shortSource = function(sheet) {
// Use a string like "inline" if there is no source href
if (!sheet || !sheet.href) {
if (!sheet) {
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.
const dataUrl = sheet.href.trim().match(/^data:.*?,((?:.|\r|\n)*)$/);
if (dataUrl) {

View file

@ -19,11 +19,14 @@ rule.status.BEST=Best Match
rule.status.MATCHED=Matched
rule.status.PARENT_MATCH=Parent Match
# LOCALIZATION NOTE (rule.sourceElement, rule.sourceInline): For each
# style property the panel shows the rules which hold that specific property.
# LOCALIZATION NOTE (rule.sourceElement, rule.sourceInline,
# 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
# 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.sourceConstructed=constructed
rule.sourceElement=element
# LOCALIZATION NOTE (rule.inheritedFrom): Shown for CSS rules

View file

@ -48,4 +48,6 @@ interface StyleSheet {
readonly attribute DOMString sourceURL;
[ChromeOnly, Pure]
readonly attribute Document? associatedDocument;
[ChromeOnly, Pure, BinaryName="isConstructed"]
readonly attribute boolean constructed;
};