Closed Bug 1132020 Opened 9 years ago Closed 9 years ago

CSS rules not displayed for ::before pseudo-element after content changes

Categories

(DevTools :: Inspector, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 1208544

People

(Reporter: pbro, Unassigned)

References

Details

STR:
- Open http://jsbin.com/kacemifazi/3/
- Open the inspector (tested in latest fx-team)
- Select the ::before pseudo-element in the div.test element
- Observe that the rule-view sidebar shows the right rule:
.test::before {
    content: "test";
}
- Now change the content value to something else
- Select the div.test element
- Now select again the ::before pseudo-element

Expected: the rule-view sidebar still contains the CSS rule that applies to the pseudo-element
Actual: the rule-view is now empty (apart from the message "No element selected").

The following JS error appears in the console:

Error: findCssSelector received element not inside document
Stack trace:
CssLogic_findCssSelector@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/styleinspector/css-logic.js:925:1
exports.NodeActor<.getUniqueSelector<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/actors/inspector.js:570:12
actorProto/</handler@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/protocol.js:1006:19
DSC_onPacket@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/main.js:1450:15
LocalDebuggerTransport.prototype.send/<@resource://gre/modules/devtools/dbg-client.jsm -> resource://gre/modules/devtools/transport/transport.js:545:11
makeInfallible/<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/DevToolsUtils.js:82:14
makeInfallible/<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/DevToolsUtils.js:82:14
 protocol.js:900
"Protocol error (unknownError): Error: findCssSelector received element not inside document" protocol.js:20
"Protocol error (unknownError): Error: findCssSelector received element not inside document" inspector-panel.js:439
Same with dev-edition (37).

What I suspect is that changing the content property actually re-creates a new pseudo-element altogether, and since we don't have mutation events for those, the inspector has basically no knowledge of the new node and probably still shows the old version in the markup-view.

If we can't fix this properly before we have some sort of mutation event listener for pseudo-elements, maybe we still want to handle the use case in a nicer way somehow, at least avoiding the error. Maybe there's a way that we can detect that a pseudo-element has changed, after the fact, and then force a refresh of the parent node in the markup-view.
This is surely caused by the lack of mutation observers for pseudo elements (bug 1034110).

> If we can't fix this properly before we have some sort of mutation event
> listener for pseudo-elements, maybe we still want to handle the use case in
> a nicer way somehow, at least avoiding the error. Maybe there's a way that
> we can detect that a pseudo-element has changed, after the fact, and then
> force a refresh of the parent node in the markup-view.

At one point I was trying to create a fake mutation event on the server by guessing when a pseudo element changed (see https://bugzilla.mozilla.org/show_bug.cgi?id=1034110#c1).  This was more of an experiment and not a usable solution, but the idea that we could handle this relatively easy case and send a childList mutation to the frontend could work.  I forget exactly what would happen if we send that mutation while one of the children is selected though.
Depends on: 1034110
Interestingly, you can continue to edit other properties of the pseudo element after changing the content, as long as you don't reselect it.  The childList mutation idea may or may not allow this to continue working.

If the only error is within findCssSelector, we could try try/catching it and see if that allows you to at least edit the rules still.  The breadcrumbs would be incorrect, but it would be a better failure scenario.
Depends on: 1208544
I've seen this in action too and to be frank it's enough of a dev issue that I'd consider switching back to Chrome and its devtools because it doesn't have this bug.

It's not just the ::before selector; I see it with ::after too. Once you make a change like adding "display: none" to the element, if you de-select the element in the DOM explorer then re-select it, all its CSS styles are gone in the inspector (as are other psuedo elements) and only a reload restores them.
(In reply to matt from comment #4)
> I've seen this in action too and to be frank it's enough of a dev issue that
> I'd consider switching back to Chrome and its devtools because it doesn't
> have this bug.
> 
> It's not just the ::before selector; I see it with ::after too. Once you
> make a change like adding "display: none" to the element, if you de-select
> the element in the DOM explorer then re-select it, all its CSS styles are
> gone in the inspector (as are other psuedo elements) and only a reload
> restores them.

This should be handled now as a result of Bug 1208544, and the fix will be shipping in Dev Edition next week.  The ::before/::after will disappear once it's display:none (that's just how the platform works - the pseudo elements actually are destroyed in that case), but will reappear once it's visible again.  Here's a test page where you can click 'toggle all styles' to add/remove pseudo elements: https://bgrins.github.io/devtools-demos/inspector/pseudo.html
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → DUPLICATE
Awesome, thanks Brian!
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.