Closed Bug 1247455 Opened 9 years ago Closed 9 years ago

Add a .removeCSS method to complement .insertCSS

Categories

(WebExtensions :: Untriaged, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED
mozilla49

People

(Reporter: natalieg, Assigned: claas)

References

Details

(Keywords: dev-doc-complete, Whiteboard: [discussion][berlin][good first bug] triaged)

Attachments

(1 file, 2 obsolete files)

There should be a way to remove stylesheets that are added with chrome.tabs.insertCSS. That way a WebExtension like Stylish can add and remove its own stylesheets without interfering with, or interference from, the website. A chrome.tabs.removeCSS method would do nicely, or else a new optional 'remove' property, defaulting to false, in the 'details' argument passed to .insertCSS. It would also be useful to insert a User or User Agent sheet this way instead of an Author sheet. Some elements simply can't be styled except by a UA sheet. This could be specified with a new optional 'origin' property, defaulting to Author, in the 'details' argument. Finally, it would be great if, in addition to or instead of these changes, the stylesheet service could be exposed as an additional, global .insertCSS method, grafted to chrome.windows or maybe chrome.runtime. This would permit Stylish, for example, to continue life as a WebExtension without losing its ability to style scrollbars and browser chrome.
Whiteboard: [discussion] triaged
Whiteboard: [discussion] triaged → [discussion][berlin] triaged
Whiteboard: [discussion][berlin] triaged → [discussion][berlin][good first bug] triaged
I have started to work on this bug at the 3rd Open Mozilla Night in Berlin and will share my results within the next days.
Assignee: nobody → mozilla
I am new here, want to start with something. I am good with SQL, and logic. I have some experience in C/C++, and Java. Help me with what should I do.
It took a bit longer due to personal reasons, but here are my results from the 3rd Open Mozilla Night based on how "insertCSS" works: - The entry point is the path |/browser/components/extensions| (found by search for "insertCSS" in DXR). - The `insertCSS` method is documented in |schemas/tabs.json|. - The implementation can be found in |ext-tabs.js| where it delegates to an existing `_execute` method which sends an 'Extension:Execute' message to the context. - Note: This context is the `ExtensionContext` (see |/toolkit/components/extensions/ExtensionContent.jsm|). - The context receives the message in `receiveMessage`, forwards it to `handleExtensionExecute` which delegates to `DocumentManager#executeScript` (in same file). - Note: For the sake of completeness, these messages are managed by the `MessageChannel` (see |/toolkit/components/extensions/MessageChannel.jsm|), but this is not essential for this bug. - Note: The 'Extension:Execute' message type seems to have been first implemented for the `executeScript` method only and then been reused for `insertCSS`. - The `executeScript` method creates an instance of `Script` (which, as of now, can represent JavaScript or CSS content to be added) and adds it to the context (see `addScript`) which calls `execute` which invokes `tryInject` on the script. - The `Script#tryInject` method makes use of `nsIDOMWindowUtils#loadSheetUsingURIString` for adding the CSS (see |dom/interfaces/base/nsIDOMWindowUtils.idl|). - Note: Inline CSS is converted to a data URI. - Note: There seems to be a bug in the CSS section of `Script#tryInject`, because the `deferred` promise is resolved within the for-loop (so upon the first CSS insertion). Hence, the solution for this bug involves: - ExtensionContext.jsm: Extend `Script` to support the removal of CSS (e.g. a new boolean option 'removeCss' which defaults to false and controls whether `tryInject` would call `removeSheetUsingURIString` rather than `loadSheetUsingURIString`). - ext-tabs.js: Add `removeCSS` method and extend `_execute` to set `removeCss` option when called by this new method. - tabs.json: Add `removeCSS` documentation. I will submit a first patch these days.
Attached patch 1247455.patch (obsolete) — Splinter Review
The patch contains the following changes: - ext-tabs.js: Add removeCSS method. - tabs.json: Add removeCSS schema. - browser_ext_tabs_removeCSS.js: Add test case. - ExtensionContent.jsm: Handle removeCSS (and reduce code duplication).
Attachment #8740680 - Flags: review?(kmaglione+bmo)
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Comment on attachment 8740680 [details] [diff] [review] 1247455.patch Review of attachment 8740680 [details] [diff] [review]: ----------------------------------------------------------------- Looks good. Thanks! Just a couple of nits to fix and it will be ready to land. ::: browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js @@ +109,5 @@ > + // Make sure that we're not holding on to references to closed message > + // managers. > + is(MessageChannel.messageManagers.size, messageManagersSize, "Message manager count"); > + is(MessageChannel.responseManagers.size, responseManagersSize, "Response manager count"); > + is(MessageChannel.pendingResponses.size, 0, "Pending response count"); These checks aren't really necessary here. We just need to have them in in one test. ::: toolkit/components/extensions/ExtensionContent.jsm @@ +202,5 @@ > if (shouldRun("document_start")) { > let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor) > .getInterface(Ci.nsIDOMWindowUtils); > + // We can insertCSS and removeCSS. > + let method = this.remove_css ? winUtils.removeSheetUsingURIString : winUtils.loadSheetUsingURIString; Can we move this to just before the `for` loop that calls the method? @@ +205,5 @@ > + // We can insertCSS and removeCSS. > + let method = this.remove_css ? winUtils.removeSheetUsingURIString : winUtils.loadSheetUsingURIString; > + > + // We can handle CSS urls (css) and CSS code (cssCode). > + let urls = []; Can we name this something like `cssUrls` so it's a bit clearer what it does?
Attachment #8740680 - Flags: review?(kmaglione+bmo) → review+
Attached patch 1247455-v2.patch (obsolete) — Splinter Review
The patch contains the changes from the previous patch plus the following changes: - browser_ext_tabs_removeCSS.js: Remove unnecessary checks. - ExtensionContent.jsm: Move method determination to where it is needed. - ExtensionContent.jsm: Rename `urls` array to `cssUrls`. PS: Thank you for the review.
Attachment #8740680 - Attachment is obsolete: true
Attachment #8741547 - Flags: review?(kmaglione+bmo)
Comment on attachment 8741547 [details] [diff] [review] 1247455-v2.patch Review of attachment 8741547 [details] [diff] [review]: ----------------------------------------------------------------- ::: browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js @@ +5,5 @@ > +add_task(function* testExecuteScript() { > + let {MessageChannel} = Cu.import("resource://gre/modules/MessageChannel.jsm", {}); > + > + let messageManagersSize = MessageChannel.messageManagers.size; > + let responseManagersSize = MessageChannel.responseManagers.size; These variables and the MessageChannel import also need to be removed, now. ESLint won't accept the unused variables.
Attachment #8741547 - Flags: review?(kmaglione+bmo) → review+
Comment on attachment 8742158 [details] [diff] [review] Add a .removeCSS method to complement .insertCSS The patch contains the changes from the previous patch plus the following changes: - browser_ext_tabs_removeCSS.js: Remove unnecessary import/variables. I ran `./mach eslint browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js` without errors.
Attachment #8742158 - Flags: review?(kmaglione+bmo)
Attachment #8741547 - Attachment is obsolete: true
Comment on attachment 8742158 [details] [diff] [review] Add a .removeCSS method to complement .insertCSS Review of attachment 8742158 [details] [diff] [review]: ----------------------------------------------------------------- Thanks!
Attachment #8742158 - Flags: review?(kmaglione+bmo) → review+
If you're ready for this to land, please add the checkin-needed keyword
Keywords: dev-doc-needed
Thanks, Kris! Successfully checked that the patch still works, therefore I'm adding the keyword now.
Keywords: checkin-needed
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla49
I've documented tabs.removeCSS() here: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/removeCSS I've updated tabs.insertCSS to refer to it: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/insertCSS I've updated the main tabs page to include a mention of the function: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs I've updated the compatibility data JSON with this PR: https://github.com/mdn/browser-compat-data/pull/24. I've added a note to Firefox 49 for developers. Once the PR is accepted and deployed, this should be done. Needinfo wbamberg about that.
Flags: needinfo?(wbamberg)
Flags: needinfo?(wbamberg)
Does the 'details.code' parameter need a warning? In `tabs.removeCSS` it simply identifies a stylesheet applied with `tabs.insertCSS` - it isn't evaluated as a stylesheet. In `tabs.insertCSS` it _is_ evaluated as a stylesheet in the context of a browser page, but is there really an XSS issue here? The page linked in the warning doesn't mention one. If it can indeed be done, then the XSS page should elaborate so that extension writers can know how to avoid it. Similarly, `tabs.removeCSS` won't inject the `details.file` stylesheet but only uses the URL to identify a stylesheet already applied by `insertCSS`.
(In reply to Nancy Grossman from comment #17) > Does the 'details.code' parameter need a warning? In `tabs.removeCSS` it > simply identifies a stylesheet applied with `tabs.insertCSS` - it isn't > evaluated as a stylesheet. In `tabs.insertCSS` it _is_ evaluated as a > stylesheet in the context of a browser page, but is there really an XSS > issue here? The page linked in the warning doesn't mention one. If it can > indeed be done, then the XSS page should elaborate so that extension writers > can know how to avoid it. > > Similarly, `tabs.removeCSS` won't inject the `details.file` stylesheet but > only uses the URL to identify a stylesheet already applied by `insertCSS`. Yes, agreed. I've updated the page, would you mind taking a look and seeing if it's better now? https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/removeCSS I've also drafted a simple example: https://github.com/mdn/webextensions-examples/pull/85
Flags: needinfo?(umbecono)
That's very good. The warnings are gone, and the examples are clear and well-ordered. Thank you. It may seem like a minor change to you, but the documentation is always so good here that when I see a warning like that I have to follow it up, even when I'm 99% sure of what I'll find. No doubt others do too.
Flags: needinfo?(umbecono)
Product: Toolkit → WebExtensions
See Also: → 1497729
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: