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
	
	 Emilio Cobos Álvarez
						Emilio Cobos Álvarez