Closed Bug 96455 Opened 23 years ago Closed 23 years ago

hr has duplicate lineboxes in frame tree

Categories

(Core :: DOM: Editor, defect, P3)

defect

Tracking

()

VERIFIED FIXED
mozilla0.9.7

People

(Reporter: TucsonTester2, Assigned: kinmoz)

References

Details

(Whiteboard: [EDITORBASE] fixed on trunk)

Attachments

(5 files, 3 obsolete files)

From Bugzilla Helper: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1) BuildID: 20010726 Horizontal Line indention and outdention gives you a line that is not selectable. Also by choosing add number list it creats an additional line with no number, Reproducible: Always Steps to Reproduce: 1. Open new composer page 2. Click on insert and choose Horizontal Line 3. Click on indent 4. Click on horizontal Line and then click on outdent 5. The line can no longer be selected 6. Click on add number list Actual Results: There was two horizontal lines. One of them could not be deleted and the other was in numberlist format with no number in front of it Expected Results: Allowed the Horizontal line to be selected and deleted To choose outdent the Horizontal line must be selected again
I see this in my Mac debug build from today; reassign to kin I see this on my console: frame: Inline(hr)(0) (0x1a0bd580) style: 0x1a0bd550 :after {} Wrong parent style context style: 0x1a0bd428 {} should be using: style: 0x1bde02e4 {}
Assignee: brade → kin
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Windows NT → All
Hardware: PC → All
Attached file Minimal Test Case (deleted) —
Changing summary from "Horizontal Line indention and outdention gives you a line that is not selectable" to "hr has duplicate lineboxes in frame tree" Unless I'm misreading the frame dump in viewer, it looks like layout generates 2 lines for each HR in the content tree, which causes problems in the editor whenever we remove and re-insert the hr into the content tree. (See JS Test Case for an example) Turns out the Minimal Test Case I attatched above, isn't so minimal. You can see the duplication in the frame tree with a simple doc: <html><body><hr></body></html> attinasi/waterson, do either of you have a bug like this on your plate already? I'll attatch another test case that allows you to insert and remove the same hr in the content tree. If you do that a couple of times, you'll see a lot of duplication in the frame tree ... as if frames aren't getting destroyed like they should be, even when their associated content is removed from the tree.
Status: NEW → ASSIGNED
Priority: -- → P3
Summary: Horizontal Line indention and outdention gives you a line that is not selectable → hr has duplicate lineboxes in frame tree
Target Milestone: --- → mozilla0.9.5
Attached file Test case that allows hr insertion/deletion. (obsolete) (deleted) —
Blocks: 99517
Eegad - what a mess! Yes, I see this, of course in Quirks mode only. In Quirks Mode we treat HR as inline and use generated content to make it 'seem' like a block. I wonder if this problem exists with other generated content as well... I'll try to test that out. I also wonder if that hack that buster put in so long ago to make HR act like this in Quirks mode was worth it. If I remember correctly, it was to allow HR to resize between floated elements.
So, If I create a document like: <html> <head> <style> span { -moz-box-sizing: border-box; margin: 0 0.1% 0 0.1%; /* Mmm! Hack-on-a-hack for bug 81776 */ } span:before { white-space: pre; content: "\A"; } span:after { white-space: pre; content: "\A"; } </style> </head> <body> One Line <span>*</span> Next Line </body> </html> to emulate what we do with HR on a SPAN, I see the same problem with the multiple line frames: line 02962110: count=2 [0x2038] {0,0,848,285} < Text(0)@0299AC74[0,10,T] next=0299AD40 {0,0,840,285} < "\nOne Line\n" > Inline(span)(1)@0299AD40 next=02962244 next-in-flow=02962244 < Inline(span)(1)@0299AE04 {0,225,0,0} [state=0000004c] < Text(-1)@0299AE70[0,1,T] {0,-225,0,285} [state=00000044] < "\n" > > > > line 0296227C: count=1 state=inline,clean,NOT Impacted,< Inline(span)(1)@02962244 next=029620D0 prev-in-flow=0299AD40 < Text(0)@0299AEE4[0,1,T] next=02962024 {0,0,120,285} < "*" > Inline(span)(1)@02962024 {120,225,0,0} [state=0000004c] < Text(-1)@02962090[0,1,T] {0,-225,0,285} [state=00000044] < "\n" > > > > line 02962308: count=1 state=inline,clean,NOT < Text(2)@029620D0[0,11,T] {0,570,900,285} [state=71000034] < "\nNext Line\n" > > Looking at this, I think it is correct. The HR (or SPAN in this case) have generated content for the :before and :after style rules. So the extra lines need to be there, and the extra frames in those lines have to be attributed to the HR (or SPAN) tags. The problem of not removing them when the HR is deleted though is a real bug. I bet that the problem of removing elements with generated content is more general, not just restricted to HR elements (just a guess).
Attachment #48456 - Attachment is obsolete: true
--> 0.9.6
Target Milestone: mozilla0.9.5 → mozilla0.9.6
Whiteboard: [EDITORBASE]
Marc was correct, the problem is not limited to HR. I just attatched a test case that uses an image with :before and :after content that we can use to see that the generated content frames aren't being removed. It's important to note that things are deleted properly in Marc's test case using the span, because it is splittable, so in that case the generated content frames are in-flow as continuous frames for the span, and nsBlockFrame::DoRemoveFrame() removes all continuing frames for content that is removed. The problem with inline-non-splittable elements is that their generated content frames are siblings (not continuous frames), so when we remove the content node from the tree, only the primary frame for that content node is removed. There doesn't seem to be any notion of generated content inside nsBlockFrame, so rather than introduce it, I decided to try and fix the problem in nsCSSFrameConstructor.cpp, which is the same place that makes the generated content a sibling of the primary frame. I'll attatch the diff I used to fix the bug. The one thing I didn't like about this approach was that in order to get the previous sibling for a frame, I had to go up to the parent and walk it's child list till I got to the previous sibling, which might be a performance problem on large flat pages. I could try the approach of modifying nsBlockFrame::DoRemoveFrame() so that it handles this situation, but I might have to complicate the loop logic there because the generated content could be on different lines than the primary frame etc. Should I try that route? nsCSSFrameConstructor.cpp coming up.
--> mozilla0.9.7
Target Milestone: mozilla0.9.6 → mozilla0.9.7
Looks fine to me, modulo stylistic vandalism (put the open braces on the same line as the if/else/while, etc.) HasPseudoStyle could just be a file-static (no need to add it to the class). Also, why not just: return (pseudoStyle != nsnull); instead of creating a temporary, blah blah blah. There isn't a better way to find the previous frame. Oh well. You don't check |rv| after calling RemoveGeneratedContentSiblings: why even bother assigning it to a temporary, then? (Why not make RemoveGeneratedContentSiblings a |void| function.) And I guess this could just be file-static, too (no need to add to the class).
*** Bug 96453 has been marked as a duplicate of this bug. ***
kin, in case it wasn't clear, attachment 56089 [details] is okay by me module some stylistic nits. Fix those, and sr=waterson.
Attached patch Patch Rev 1.1 (With waterson's suggestions) (obsolete) (deleted) — Splinter Review
I just attatched a new patch incorporating all of waterson's suggestions. Can I get an r= from attinasi or dbaron and an sr= from waterson? Btw, this should fix waterson's bug 71979, but while using some of the test cases in that bug, I think I ran across another bug where calling GetPrimaryFrameFor() is returning the :before pseudo content frame for BR content instead of the nsBRFrame for the BR. This results in only the :before frame being removed leaving the nsBRFrame and any :after frame associated with it in the frame tree.
Attachment #56098 - Attachment is obsolete: true
Whiteboard: [EDITORBASE] → [EDITORBASE] FIX IN HAND, need r=
Comment on attachment 57271 [details] [diff] [review] Patch Rev 1.1 (With waterson's suggestions) Marking sr=waterson per his comments above. :-)
Attachment #57271 - Flags: superreview+
Looks good!
Comment on attachment 57271 [details] [diff] [review] Patch Rev 1.1 (With waterson's suggestions) These changes look good - r=attinasi I wonder if + if (!aPresContext || !aPresShell || !aFrameManager || !aFrame) + return; could just be an assertion though...
Attachment #57271 - Flags: review+
I changed: + if (!aPresContext || !aPresShell || !aFrameManager || !aFrame) + return; to: + NS_ASSERTION(aPresContext && aPresShell && aFrameManager && aFrame, "Null arg pointer!"); in my local tree.
Whiteboard: [EDITORBASE] FIX IN HAND, need r= → [EDITORBASE] FIX IN HAND, ready for checkin
No release needed for styleContext? Also, possible leak of styleContext in the case where |if content && !content->IsContentOfType(nsIContent::eELEMENT) && styleContext| is true. Better to split this pattern (or nsCOMPtr<>). + nsCOMPtr<nsIContent> content; + nsIStyleContext *styleContext = nsnull; + + aFrame->GetContent(getter_AddRefs(content)); + aFrame->GetStyleContext(&styleContext); + + if (!content || !content->IsContentOfType(nsIContent::eELEMENT) || !styleContext) + return NS_OK;
Attached patch Patch Rev 1.2 (deleted) — Splinter Review
Crap! Good catch rbs. I just attached Rev 1.2 that contains the assertion attinasi wanted, and uses a COMPtr for the styleContext. If there are no other objections, I'll check this in as soon as soon as I can catch an open tree.
Attachment #57271 - Attachment is obsolete: true
I am wondering if there could be several before/after frames? Is that possible? e.g. tag:before { content: "foo"; content: "bar"; }
I tried that when I first came up with the fix, but it didn't seem like you could. The last content: you specified was what showed up on the screen and in the frame tree.
Patch Rev 1.2 checked into trunk: mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp revision 1.655
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Whiteboard: [EDITORBASE] FIX IN HAND, ready for checkin → [EDITORBASE] fixed on trunk
Verified on build 2001111503.
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: