Closed Bug 56117 Opened 24 years ago Closed 23 years ago

[Patch-Dep] Text Nodes should not be matching any selectors (keep out of SelectorMatches?)

Categories

(Core :: CSS Parsing and Computation, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla0.9.6

People

(Reporter: attinasi, Assigned: dbaron)

References

Details

(Keywords: perf, testcase)

Attachments

(5 files)

From bug 53974: Text nodes are being passed into SelectorMatches. It is unclear if this should be prevented entirely, or if SelectorMatches needs to be smarter about how it handles text nodes. Some research needs to be done on this, and there is some good commentary in bug 53974. Some of the proposed new selectors for CSS3 may make it a requirement that the text nodes go into SelectorMatches (I'm thinking of the proposed :contains pseudo element, specifically). Currently, there is no need since no supported selectors match text nodes.
Accepting, moving to Future to investigate post-RTM.
Status: NEW → ASSIGNED
Target Milestone: --- → Future
Marc, Pierre: Could this help performance? Nominating nsbeta1 so that we at least consider this.
Keywords: nsbeta1, perf
QA Contact: chrisd → ian
I think we can actually prevent all rule matching on text nodes, which is a tad better than just short-circuiting SelectorMatches. My only concern is what happens later, when CSS3 selectors get implemented, so I'll comment the hell out of the change when I make it (assuming it provides significant benefit).
Target Milestone: Future → mozilla0.9
CSS3 won't match text nodes, ever, either. (:contains is a pseudo-class and matches elements not text nodes). Maybe far in the future text nodes might be matchable, but even then, I'd guess matching on a *part* of a text node would be much more likely to be what ends up being allowed.
I've attached a path that prevents text nodes from getting into rule matching, and asserts in SelectorMatches to make sure I caught them all. I tested this for a potential performance improvement, using a large text document (tinderbox full build log) and could not see more than a 5% performance improvement in style resolution, which could be just noise (used the Gecko Performance Test loading the log 10 times).
Patch is attached, needs review...
Keywords: patch
r=pierre
I suspect more performance win could be seen on pages that actually have many textnodes, e.g., pages with plenty <tag>'s and short texts in between.
Added testcase to kwds - it would be nice to have a testcase that showed some performance advantage (rbs?). I think that this should be landed anyway, hence the request for reviews, since it is also a correctness issue and it has not introduced any performance degradation in the common cases.
Keywords: testcase
Didn't we decide that doing QI() on XUL elements is fairly expensive? Do we know why we end up trying to match selectors on text nodes in the first place?
Yes, QI on an XUL element (for an interface that it does not support) is expensive. I could put in the hack I added before to pre-screen XUL elements and assume that a XULElement cannot be a text node - assuming that XUL elements are never text nodes too seems reasonable (CC'ing Hyatt to make sure). The reason we are trying to match selectors against text nodes, and the reason for this bug, is because ResolveStyleContextFor can be called by anyone, and they can pass in text nodes for aContent - in fact they do. Alternately we could make all 20 or so existing callers of ResolveStyleContextFor screen out text nodes but I thought that it was safest to do it in the rule matching code. Alternatively we could screen textnodes in nsPresContext::ResolveStyleContextFor and maybe even return an error from there... hmm, I hadn't thought of that. That would provide the benefit of publicizing the semantic that ResolveStyleContextFor is not to be called for text nodes, allowing clients to do their own optimizations, potentially. Thoughts on that?
Here is another way we end up trying to match selectors on text nodes: calls to nsCSSFrameConstructor::ContentStatesChanged end up calling nsStyleSetImpl::HasStateDependentStyle which does selector matching.
Gotcha. sr=waterson
Milestone shift --> Moz 0.8.1
Target Milestone: mozilla0.9 → mozilla0.8.1
looks good. r/sr=waterson
fine with me too, r=pierre
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Fix chececked in: nsCSSStyleSheet.cpp
The fix caused regressions - bug 71561 at least. It seems that text elements are being used by comboboxes, and that style is being resolved on them using the :-moz-display-comboboxcontrol-frame pseudo, so we really do have to allow them into selector matches (at least those particular text elements). I'll need a better way to screen out the text nodes that really should not be getting styled at all, ever. Backing out the change, so reopening this bug.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
There is at least one case (comboboxes) where text nodes need to be styled (and hence need to be getting into SelectorMatches). Of course, we could decide that comboboxes are wrong and fix them, or we could find a more targetted approach to identifying the text nodes that we actually want to keep out of SelectorMatches. Moving to Future for now since this is not critical and had very little if any performance benefits anyway.
Status: REOPENED → ASSIGNED
Target Milestone: mozilla0.8.1 → Future
The way comboboxes are styling text nodes seems wrong -- I wonder if they could do what that does by styling the OPTION element. It seems to me like a better long-term fix would be to fix comboboxes not to require styling of text nodes (i.e., not to depend on a style system bug) and then re-enable this fix.
The combo box problem will be fixed when ("when") we switch to XBL widgets. In the meantime, shouldn't the combo box be using a pseudo-*element*, instead?
David, Ian - thanks for confirming my feeling about how the combobox is using the text node (styled no less!). I'll get Rod involved in this conversation and see what his feelings are. David, you said it most plainly: by styling the text element, comboboxes are taking advantage of a bug in the style system that we want to fix. CC'ing rod (and emailing him some background data).
The combobox is NOT styling the text nodes in the options. It's styling the text node in the display area. In fact, it used the same style on the containing block and on the text node: // create the style context for the anonymous frame nsCOMPtr<nsIStyleContext> styleContext; rv = aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozDisplayComboboxControlFrame, mStyleContext, PR_FALSE, getter_AddRefs(styleContext)); if (NS_FAILED(rv)) { return rv; } if (!styleContext) { return NS_ERROR_NULL_POINTER; } // create a text frame and put it inside the block frame rv = NS_NewTextFrame(shell, &mTextFrame); if (NS_FAILED(rv)) { return rv; } if (!mTextFrame) { return NS_ERROR_NULL_POINTER; } nsCOMPtr<nsIStyleContext> textStyleContext; rv = aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozDisplayComboboxControlFrame, styleContext, PR_FALSE, getter_AddRefs(textStyleContext)); My guess is the text node is being styled because for some reason styling the parent block frame didn't do what it was suppose do. And since layout is so easy to understand, I am sure it was just laziness I didn't figure why :) So the point is, if we could figure out why the block isn't getting the right style applied, or we could at least understand why it isn't doing what I think it ought to be doing, we could take the style off the TextNode.
Rod, it looks like that code was added over a year ago, so maybe we should revisit it and see if it is still necessary. I'll open a new bug on it to keep this one from getting too off-track.
Opened bug 71717 for the ComboboxControlFrame issue - marking dependent.
Depends on: 71717
Matching milestone to the bug this depends on.
Target Milestone: Future → mozilla0.9
See related bug 74598 describing a possible further improvement to text node style context management.
Patch is attached, but waiting for dependency to be fixed.
Summary: Text Nodes should not be matching any selectors (keep out of SelectorMatches?) → [Patch-Dep] Text Nodes should not be matching any selectors (keep out of SelectorMatches?)
Matching milestone to dependent bug (it changed today to 0.9.1)
Target Milestone: mozilla0.9 → mozilla0.9.1
If we can get this fixed, I'd love to then look into the issue of eliminating style contexts from text frames all together (and just letting them use their parent's style context to draw). This would allow us to gain back some important time during reflow in addition to style resolution, since individual text frames obtain fonts (and call the ever-expensive GetMetricsFor).
Moving P2 and P3 bugs to 0.9.2
Target Milestone: mozilla0.9.1 → mozilla0.9.2
By mandate, moving non-crashers and non-dataloss bugs out.
Target Milestone: mozilla0.9.2 → mozilla1.0
Blocks: 83482
Blocks: 104166
Taking -- I want to try to get this in and fix the dependency (and then work on the issue hyatt mentioned).
Assignee: attinasi → dbaron
Status: ASSIGNED → NEW
Target Milestone: mozilla1.0 → mozilla0.9.7
I also attached a patch to bug 71717 that will allow this to be checked in.
Comment on attachment 55328 [details] [diff] [review] updated patch (also includes changes for bug 98128) r=pierre
Attachment #55328 - Flags: review+
sr=hyatt
OK, I started digging a bit more, and I found some interesting things: * most text nodes have their style contexts created using a pseudo-element (textNodePseudo), which is cheaper than creating them using the content node itself, since we don't have to match against universal rules. Apparently some comments and processing instructions can have style resolved on them as well, through pseudos as well (eek!). * there were a few that were actually passing the text node, and I fixed them not to pass the text node but to use the textPseudo like everwhere else. I'll attach a more compelete patch that turns the IsContentOfType checks in the style set / rule processor code into assertions and fixes up the callers. There's still a good bit more work we can do here...
(FWIW, the only time selectors *matched* text nodes was the case described in bug 71717.)
In the above patch I omitted the following change: Index: layout/html/document/src/forms.css =================================================================== RCS file: /cvsroot/mozilla/layout/html/document/src/forms.css,v retrieving revision 3.27 diff -u -d -r3.27 forms.css --- forms.css 2001/10/22 10:39:35 3.27 +++ forms.css 2001/10/27 04:56:27 @@ -217,7 +217,7 @@ textarea[disabled], option[disabled], select[disabled], -select[disabled] > :-moz-display-comboboxcontrol-frame { +select[disabled]:-moz-display-comboboxcontrol-frame { color: GrayText; cursor: default; }
Status: NEW → ASSIGNED
Target Milestone: mozilla0.9.7 → mozilla0.9.6
Comment on attachment 55350 [details] [diff] [review] more complete patch - prevent text nodes from being passed to style system sr=attinasi
Attachment #55350 - Flags: superreview+
Sorry, before spending more time looking at this one, I'm actually working on a better one that stops us doing any style resolution at all for non-elements (although we still create style contexts). I'll attach it shortly.
Comment on attachment 55604 [details] [diff] [review] more complete patch -- prevent any style resolution on non-elements, including using pseudos sr=attinasi
Attachment #55604 - Flags: superreview+
Comment on attachment 55604 [details] [diff] [review] more complete patch -- prevent any style resolution on non-elements, including using pseudos r=hyatt
Attachment #55604 - Flags: review+
Put // XXX indicating that the hack at the top of GetFirstLetterStyle in nsBlockFrame is temporary. Do the same with the ResolveStyleForNonElement declaration in the interface.
Checked in 2001-10-29 22:02/36 PDT.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago23 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: