Created attachment 252209 [details]
Loading this testcase triggers the following assertion about 50% of the time:
###!!! ASSERTION: should only be called for text frames: 'Not Reached', file /Users/admin/trunk/mozilla/layout/generic/nsFrame.cpp, line 3273
nsFrame::CharacterDataChanged is what doesn't want to be called.
So... I can't seem to reproduce this. I assume you're using a build in which bug 367243 is fixed?
If so, what's the concrete frame class when the unwanted CharacterDataChanged is called?
Yes, I'm using a build in which bug 367243 is fixed.
(gdb) f 3
#3 0x084c686c in nsFrame::CharacterDataChanged (this=0x2f2518c, aPresContext=0x268147d0, aChild=0x2681d240, aAppend=0) at /Users/admin/trunk/mozilla/layout/generic/nsFrame.cpp:3273
3273 NS_NOTREACHED("should only be called for text frames");
(gdb) whats this
0x8ec6ee0 <_ZTV18nsFirstLetterFrame+8>: 0x84c3530 <_ZN7nsFrame14QueryInterfaceERK4nsIDPPv>
Created attachment 252260 [details]
stack trace for the assertion
Created attachment 252262 [details]
Testcase that's guaranteed to assert
This is sort of a combination of bug 230611 and bug 362901...
So I was wondering.... Should we be setting the _block_ as mContent on the nsFirstLetterFrame? That way it wouldn't end up as the primary frame for the text content.
That's probably a good idea. But maybe we need a better story for how we assign and find frames when we create a stack of frames for an element ... like maybe GetPrimaryFrameFor should take a parameter that controls which frame in a set we should return. E.g. possible values
-- "outermost" (the frame whose parent is associated with a different element)
-- "innermost" (the frame whose children are associated with different elements)
-- "styleholder" (the frame whose style context has the style for the element)
-- "replaced" (the special frame that implements the functionality of a replaced element)
hmm, any others?
Created attachment 253847 [details] [diff] [review]
This fixes this bug and bug 368451. The frame constructor changes are really enough to fix this bug. The nsContainerFrame changes fix bug 368451. The rest are assertions that I added as I was working on this to make sure that I didn't end up with textnodes in unexpected places, etc.
That fix doesn't change our GetPrimaryFor logic, by the way.
I do think it would be nice to have a better way to get the various frames mapping to a content node... Unfortunately, I'm not sure that there is always a unique "innermost" frame (e.g. comboboxes have a display frame and the dropdown), and so forth. We should spin that off into a separate bug.
Comment on attachment 253847 [details] [diff] [review]
roc, do you think you can review this instead?
We should document this decision somewhere.
We have an invariant right now that if frame F is an ancestor of frame G, then F->mContent is an ancestor of (or equal to) G->mContent. (Well, I can't think of any counterexamples.) This breaks that. I don't know how scared we should be about that.
The other option, I guess, is to change the code in nsCSSFrameConstructor to check the frame type and get the first child as needed. Then we'll need to fix bug 368451 in some other way (probably by doing that thing with anonymous content I've suggested before where we reframe its closest non-anonymous ancestor).
Yet another option, I suppose, is to give the first-letter the content which is the parent of the textnode. That should preserve the invariant in question while fixing this bug and bug 368451, I think.
The last suggestion sounds the best to me.
Created attachment 256756 [details] [diff] [review]
With that change
This patch uses the parent of the text for the first-letter content.
The change to CharacterDataChange deserves some mention. I made it because I was getting assertions about nodes not being unbound properly on the bug 368451 testcase. The reason was that the quote text ended up getting reinserted, so ended up outside the :after wrapper. The dynamic-1 test tests that. The dynamic-2 test tests bug 368451 comment 2. The dynamic-3 tests test the testcase in this bug's comment 5, basically.
With this patch all the attached tests pass, and I get no asserts on the testcases in this bug or bug 368451.
Jesse, do you think we want this on branches? If so, I'll work on a patch for that...
Only if this assertion bothers you, or if you think bug 368451 is likely to be a security hole rather than just a sorta-leak.
Hmm... probably better to not do it for now, since neither of those seems _that_ bad...
Thought this does seem to block bug 362901, I think...
This one doesn't look like a blocker, but we may approve a branch patch if other bugs down the chain turn out to be blockers.
Fixed for 18.104.22.168 by checkin for bug 362901.
quote-1d/b.html and dynamic-3b.html now pass on all platforms: