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.nodeHref = form.nodeHref;
|
||||
this.disabled = form.disabled;
|
||||
this.constructed = form.constructed;
|
||||
this.title = form.title;
|
||||
this.system = form.system;
|
||||
this.styleSheetIndex = form.styleSheetIndex;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class StyleSheetWatcher {
|
|||
resourceId,
|
||||
resourceType: STYLESHEET,
|
||||
disabled: styleSheet.disabled,
|
||||
constructed: styleSheet.constructed,
|
||||
fileName,
|
||||
href: styleSheet.href,
|
||||
isNew: isCreatedByDevTools,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -48,4 +48,6 @@ interface StyleSheet {
|
|||
readonly attribute DOMString sourceURL;
|
||||
[ChromeOnly, Pure]
|
||||
readonly attribute Document? associatedDocument;
|
||||
[ChromeOnly, Pure, BinaryName="isConstructed"]
|
||||
readonly attribute boolean constructed;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue