Closed Bug 4577 Opened 26 years ago Closed 25 years ago

incremental reflow problems in table + area frames

Categories

(Core :: Layout: Tables, defect, P1)

x86
Windows NT
defect

Tracking

()

VERIFIED FIXED

People

(Reporter: buster, Assigned: karnaze)

References

()

Details

(you won't be able to reproduce this bug until I check in today (4/6/99) as soon as the tree opens...) run viewer, load test case, edit mode select from 'b' to 'e' make bold (ctrl-b) get the assertion shown below. continuing past the assertion gives incorrect layout, some of the document is missing even though it is in the content model. This bug has me somewhat blocked on implementing editor features. I can work around it for now, but soon it could be a major blocker for table editing. test case: <html> <head><title></title></head> <body> <TABLE> <TR> <TD><B>abc <TD><B>123 <TD><B>def </body> </html> stack: nsAreaFrame::Reflow(nsAreaFrame * const 0x013c9cb4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 458 + 35 bytes nsContainerFrame::ReflowChild(nsIFrame * 0x013c9cb0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsTableCellFrame::Reflow(nsTableCellFrame * const 0x013c96e4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 505 nsContainerFrame::ReflowChild(nsIFrame * 0x013c96e0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsTableRowFrame::IR_TargetIsChild(nsTableRowFrame * const 0x013c8560, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, RowReflowState & {...}, unsigned int & 0, nsIFrame * 0x013c96e0) line 1290 + 34 bytes nsTableRowFrame::IncrementalReflow(nsTableRowFrame * const 0x013c8560, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, RowReflowState & {...}, unsigned int & 0) line 982 + 35 bytes nsTableRowFrame::Reflow(nsTableRowFrame * const 0x013c8564, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 1433 + 35 bytes nsContainerFrame::ReflowChild(nsIFrame * 0x013c8560, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsTableRowGroupFrame::IR_TargetIsChild(nsTableRowGroupFrame * const 0x013c8ca0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, RowGroupReflowState & {...}, unsigned int & 0, nsIFrame * 0x013c8560) line 1340 + 34 bytes nsTableRowGroupFrame::IncrementalReflow(nsTableRowGroupFrame * const 0x013c8ca0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, RowGroupReflowState & {...}, unsigned int & 0) line 1047 + 35 bytes nsTableRowGroupFrame::Reflow(nsTableRowGroupFrame * const 0x013c8ca4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 947 + 35 bytes nsContainerFrame::ReflowChild(nsIFrame * 0x013c8ca0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsTableFrame::IR_TargetIsChild(nsTableFrame * const 0x013c49a0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, InnerTableReflowState & {...}, unsigned int & 0, nsIFrame * 0x013c8ca0) line 3491 + 34 bytes nsTableFrame::IncrementalReflow(nsTableFrame * const 0x013c49a0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 3085 + 35 bytes nsTableFrame::Reflow(nsTableFrame * const 0x013c49a4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 2430 + 35 bytes nsContainerFrame::ReflowChild(nsIFrame * 0x013c49a0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsTableOuterFrame::IR_InnerTableReflow(nsTableOuterFrame * const 0x013c46d0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, OuterTableReflowState & {...}, unsigned int & 0) line 552 + 34 bytes nsTableOuterFrame::IR_TargetIsInnerTableFrame(nsTableOuterFrame * const 0x013c46d0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, OuterTableReflowState & {...}, unsigned int & 0) line 344 + 31 bytes nsTableOuterFrame::IR_TargetIsChild(nsTableOuterFrame * const 0x013c46d0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, OuterTableReflowState & {...}, unsigned int & 0, nsIFrame * 0x013c49a0) line 316 + 31 bytes nsTableOuterFrame::IncrementalReflow(nsTableOuterFrame * const 0x013c46d0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, OuterTableReflowState & {...}, unsigned int & 0) line 301 + 35 bytes nsTableOuterFrame::Reflow(nsTableOuterFrame * const 0x013c46d4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 949 + 35 bytes nsBlockReflowContext::ReflowBlock(nsIFrame * 0x013c46d0, const nsRect & {x=0 y=0 width=8940 height=1073741824}, int 0, int 0, int 1, nsMargin & {top=0 right=0 bottom=0 left=0}, unsigned int & 0) line 225 + 42 bytes nsBlockFrame::ReflowBlockFrame(nsBlockReflowState & {...}, nsLineBox * 0x013cef20, int * 0x0012a650) line 2527 + 56 bytes nsBlockFrame::ReflowLine(nsBlockReflowState & {...}, nsLineBox * 0x013cef20, int * 0x0012a650) line 1961 + 20 bytes nsBlockFrame::ReflowDirtyLines(nsBlockReflowState & {...}) line 1769 + 20 bytes nsBlockFrame::Reflow(nsBlockFrame * const 0x013bb794, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 5) line 1206 + 18 bytes nsBlockReflowContext::ReflowBlock(nsIFrame * 0x013bb790, const nsRect & {x=0 y=0 width=9180 height=1073741824}, int 1, int 0, int 1, nsMargin & {top=0 right=0 bottom=0 left=0}, unsigned int & 5) line 225 + 42 bytes nsBlockFrame::ReflowBlockFrame(nsBlockReflowState & {...}, nsLineBox * 0x013bbf00, int * 0x0012c914) line 2527 + 56 bytes nsBlockFrame::ReflowLine(nsBlockReflowState & {...}, nsLineBox * 0x013bbf00, int * 0x0012c914) line 1961 + 20 bytes nsBlockFrame::ReflowDirtyLines(nsBlockReflowState & {...}) line 1769 + 20 bytes nsBlockFrame::Reflow(nsBlockFrame * const 0x013bbba4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 1206 + 18 bytes nsAreaFrame::Reflow(nsAreaFrame * const 0x013bbba4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 509 + 28 bytes nsContainerFrame::ReflowChild(nsIFrame * 0x013bbba0, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes RootFrame::Reflow(RootFrame * const 0x013b9b24, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 237 nsContainerFrame::ReflowChild(nsIFrame * 0x013b9b20, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes nsScrollFrame::Reflow(nsScrollFrame * const 0x013b6f14, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 394 nsContainerFrame::ReflowChild(nsIFrame * 0x013b6f10, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 388 + 28 bytes ViewportFrame::Reflow(ViewportFrame * const 0x0144b7b4, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0) line 434 nsHTMLReflowCommand::Dispatch(nsHTMLReflowCommand * const 0x01445260, nsIPresContext & {...}, nsHTMLReflowMetrics & {...}, const nsSize & {width=9180 height=4470}, nsIRenderingContext & {...}) line 169 PresShell::ProcessReflowCommands(PresShell * const 0x01442510) line 1238 PresShell::ExitReflowLock(PresShell * const 0x01442510) line 665 PresShell::ContentAppended(PresShell * const 0x01442518, nsIDocument * 0x01403220, nsIContent * 0x013bdf40, int 1) line 1717 nsDocument::ContentAppended(nsDocument * const 0x01403220, nsIContent * 0x013bdf40, int 1) line 1459 nsHTMLDocument::ContentAppended(nsHTMLDocument * const 0x01403220, nsIContent * 0x013bdf40, int 1) line 632 nsGenericHTMLContainerElement::AppendChildTo(nsIContent * 0x013bd12c, int 1) line 2631 nsGenericHTMLContainerElement::InsertBefore(nsIDOMNode * 0x013bd120, nsIDOMNode * 0x00000000, nsIDOMNode * * 0x0012f1d0) line 2315 + 14 bytes nsHTMLTableCellElement::InsertBefore(nsHTMLTableCellElement * const 0x013bdf34, nsIDOMNode * 0x013bd120, nsIDOMNode * 0x00000000, nsIDOMNode * * 0x0012f1d0) line 61 + 26 bytes InsertElementTxn::Do(InsertElementTxn * const 0x01445830) line 83 + 71 bytes nsTransactionItem::Do() line 102 + 18 bytes nsTransactionManager::BeginTransaction(nsITransaction * 0x01445830) line 552 + 11 bytes nsTransactionManager::Do(nsITransaction * 0x01445830) line 92 + 15 bytes nsEditor::Do(nsEditor * const 0x0144b300, nsITransaction * 0x01445830) line 696 + 29 bytes nsEditor::InsertNode(nsEditor * const 0x0144b300, nsIDOMNode * 0x013bd120, nsIDOMNode * 0x013bdf34, int 1) line 977 + 16 bytes nsTextEditor::RemoveTextPropertiesForNode(nsTextEditor * const 0x0144b300, nsIDOMNode * 0x013bd120, nsIDOMNode * 0x013bdfa0, int 1, int 8, nsIAtom * 0x0144b410 {"B"}) line 1536 + 37 bytes nsTextEditor::RemoveTextPropertiesForNodeWithDifferentParents(nsTextEditor * const 0x0144b300, nsIDOMRange * 0x013bc920, nsIDOMNode * 0x013bd120, int 1, nsIDOMNode * 0x013c4de0, int 2, nsIDOMNode * 0x013bdec0, nsIAtom * 0x0144b410 {"B"}) line 1671 + 40 bytes nsTextEditor::RemoveTextProperty(nsTextEditor * const 0x0144b320, nsIAtom * 0x0144b410 {"B"}) line 618 + 67 bytes nsHTMLEditor::RemoveTextProperty(nsHTMLEditor * const 0x0144b320, nsIAtom * 0x0144b410 {"B"}) line 124 nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent * 0x01442ee0, int & 1) line 364 nsTextEditorKeyListener::KeyDown(nsIDOMEvent * 0x01442ee0) line 136 nsEventListenerManager::HandleEvent(nsIPresContext & {...}, nsEvent * 0x0012fac8, nsIDOMEvent * * 0x0012f830, unsigned int 3, nsEventStatus & nsEventStatus_eIgnore) line 667 + 17 bytes nsDocument::HandleDOMEvent(nsDocument * const 0x01403220, nsIPresContext & {...}, nsEvent * 0x0012fac8, nsIDOMEvent * * 0x0012f830, unsigned int 1, nsEventStatus & nsEventStatus_eIgnore) line 2183 nsHTMLHtmlElement::HandleDOMEvent(nsHTMLHtmlElement * const 0x0140991c, nsIPresContext & {...}, nsEvent * 0x0012fac8, nsIDOMEvent * * 0x00000000, unsigned int 1, nsEventStatus & nsEventStatus_eIgnore) line 173 + 41 bytes PresShell::HandleEvent(PresShell * const 0x01442514, nsIView * 0x013b9bd0, nsGUIEvent * 0x0012fac8, nsEventStatus & nsEventStatus_eIgnore) line 2056 + 34 bytes nsView::HandleEvent(nsView * const 0x013b9bd0, nsGUIEvent * 0x0012fac8, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 825 nsView::HandleEvent(nsView * const 0x013b7120, nsGUIEvent * 0x0012fac8, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 808 nsView::HandleEvent(nsView * const 0x013b7850, nsGUIEvent * 0x0012fac8, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 808 nsScrollingView::HandleEvent(nsScrollingView * const 0x013b7850, nsGUIEvent * 0x0012fac8, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 840 nsView::HandleEvent(nsView * const 0x0143e450, nsGUIEvent * 0x0012fac8, unsigned int 28, nsEventStatus & nsEventStatus_eIgnore) line 808 nsViewManager::DispatchEvent(nsViewManager * const 0x0143e120, nsGUIEvent * 0x0012fac8, nsEventStatus & nsEventStatus_eIgnore) line 1712 HandleEvent(nsGUIEvent * 0x0012fac8) line 64 nsWindow::DispatchEvent(nsWindow * const 0x013b8470, nsGUIEvent * 0x0012fac8, nsEventStatus & nsEventStatus_eIgnore) line 416 + 10 bytes nsWindow::DispatchWindowEvent(nsGUIEvent * 0x0012fac8) line 432 nsWindow::OnKey(unsigned int 133, unsigned int 66, unsigned int 1, unsigned int 48) line 1380 + 24 bytes
Priority: P3 → P2
assigning a preliminary priority.
Assignee: troy → buster
Steve, this bug isn't of much use to me, because I need to build with the editor, and there's selection involved and presumably structural modifications (most likely that's what it bold causes). Each of these steps are outside of layout's control and could be causing a problem in itself A simple example of using JavaScript to perform an incremental content update would be preferable
Assignee: buster → troy
I understand that there are a few different systems involved, but I don't think your request is entirely reasonable, or even desireable. 1. Building the editor is painless. It's built by default now anyway, and on a decent machine takes about 2 minutes. 2. I expect there to be more than one bug uncovered by the editor's manipulation of content (this certainly isn't the first.) I don't think it is reasonable for us to have to recode editor logic in javascript for each of these. The editor is a legit client of the DOM and by extension the content model. Any content manipulation allowed by the DOM has to result in consistent content and frame trees. 3. Even if we did recode in javascript, there's no guarantee that the behavior would be the same. In some cases, it might be possible to construct automated test cases in javascript. To the extent that such test cases already exist (unit tests, regression tests, etc., I'd be happy to help the authors verify they've covered usage similar to that of the editor. 4. If you really suspect selection is involved in the problem, you should work with those coding selection, primarily mjudge. Selection's primary effect is on display of text frames, so I'd be surprised if it were involved in this case. I'm open to suggestions about how to help remove this variable from the equation. back to you...
Assignee: troy → buster
Component: Layout → HTMLTables
So, here's the problem. Note: you could have just as easily figured this out... The assert in nsAreaFrame indicates there's a problem, but it's not the problem. The assert is to make sure that there's a "next" frame in the reflow chain. > NS_ASSERTION(nsnull != nextFrame, "next frame in reflow command is null."); The fact that "nextFrame" is NULL indicates the reflow dispatching is screwed up. It turns out that the problem is in nsTableCellFrame's Reflow() function. The reflow type is "FrameAppended", and the table cell code only handles "StyleChanged". All other reflow types are unhandled amd we fall through and pass the reflow command along. This is what causes the problem. Assigning the bug back to you, because you implemented the table incremental reflow code
Steve, after thinking about it some more the real problem is that the FrameAppended reflow command is targeted at the table cell frame instead of the area-frame child frame. The best way to fix that is to change the ContentAppended() frame construction code to properly pass the reflow command to the area-frame. An acceptable short-term alternative is to change the table cell frame code to re-target the reflow command at the area-frame, and leave it for Chris to fix properly. If you do that, then leave an XXX in the code
Assignee: buster → karnaze
the workaround of re-targeting the incremental reflow has been checked in. It's up to Troy or Chris to fix the incremental reflow targeting for real now. Assigning to Chris. Removed Kipp and V from the cc list. Added troy.
Status: NEW → ASSIGNED
Priority: P2 → P1
Target Milestone: M5
Assignee: karnaze → buster
Status: ASSIGNED → NEW
Steve, I'm getting the following assertion on a 4/22 WinNT debug build in trying your test case. This is after your temporary fix to nsTableCellFrame. Also, I was able to select b thru the end of the line, but not b thru e. Please reassign back to me when its not asserting. This bug is related to 5126. NTDLL! 77f76148() nsDebug::PreCondition(char * 0x006eabec, char * 0x006eac28, char * 0x006eac38, int 383) line 120 + 13 bytes nsCOMPtr<nsIContent>::operator->() line 383 + 34 bytes nsContentIterator::NextNode(nsCOMPtr<nsIContent> * 0x017d9b38) line 458 + 21 bytes nsContentIterator::Next(nsContentIterator * const 0x017d9b30) line 565 nsTextEditor::GetTextProperty(nsTextEditor * const 0x017ce4e0, nsIAtom * 0x017ce5f0 {"B"}, const nsString * 0x00000000 {???}, const nsString * 0x00000000 {???}, int & 1, int & 1, int & 1) line 524 nsHTMLEditor::GetTextProperty(nsHTMLEditor * const 0x017ce4e0, nsIAtom * 0x017ce5f0 {"B"}, const nsString * 0x00000000 {???}, const nsString * 0x00000000 {???}, int & 1, int & 1, int & 1) line 138 nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent * 0x017d9950, int & 1) line 388 nsTextEditorKeyListener::KeyDown(nsIDOMEvent * 0x017d9950) line 168 nsEventListenerManager::HandleEvent(nsIPresContext & {...}, nsEvent * 0x0012fd5c, nsIDOMEvent * * 0x0012f9c4, unsigned int 3, nsEventStatus & nsEventStatus_eIgnore) line 667 + 17 bytes nsDocument::HandleDOMEvent(nsDocument * const 0x019f8460, nsIPresContext & {...}, nsEvent * 0x0012fd5c, nsIDOMEvent * * 0x0012f9c4, unsigned int 1, nsEventStatus & nsEventStatus_eIgnore) line 2185 nsHTMLHtmlElement::HandleDOMEvent(nsHTMLHtmlElement * const 0x01a1ac3c, nsIPresContext & {...}, nsEvent * 0x0012fd5c, nsIDOMEvent * * 0x00000000, unsigned int 1, nsEventStatus & nsEventStatus_eIgnore) line 175 + 41 bytes PresShell::HandleEvent(PresShell * const 0x017bc3f4, nsIView * 0x017c4310, nsGUIEvent * 0x0012fd5c, nsEventStatus & nsEventStatus_eIgnore) line 2012 + 34 bytes nsView::HandleEvent(nsView * const 0x017c4310, nsGUIEvent * 0x0012fd5c, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 827 nsView::HandleEvent(nsView * const 0x017bfb00, nsGUIEvent * 0x0012fd5c, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 810 nsView::HandleEvent(nsView * const 0x017bfa30, nsGUIEvent * 0x0012fd5c, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 810 nsScrollingView::HandleEvent(nsScrollingView * const 0x017bfa30, nsGUIEvent * 0x0012fd5c, unsigned int 8, nsEventStatus & nsEventStatus_eIgnore) line 865 nsView::HandleEvent(nsView * const 0x017bbbd0, nsGUIEvent * 0x0012fd5c, unsigned int 28, nsEventStatus & nsEventStatus_eIgnore) line 810 nsViewManager::DispatchEvent(nsViewManager * const 0x017ba720, nsGUIEvent * 0x0012fd5c, nsEventStatus & nsEventStatus_eIgnore) line 1718 HandleEvent(nsGUIEvent * 0x0012fd5c) line 67 nsWindow::DispatchEvent(nsWindow * const 0x017bfbd4, nsGUIEvent * 0x0012fd5c, nsEventStatus & nsEventStatus_eIgnore) line 414 + 10 bytes nsWindow::DispatchWindowEvent(nsGUIEvent * 0x0012fd5c) line 435 nsWindow::OnKey(unsigned int 133, int 0, char 2, unsigned int 66, unsigned int 1, unsigned int 48) line 1399 + 21 bytes nsWindow::ProcessMessage(unsigned int 258, unsigned int 2, long 3145729, long * 0x0012fef4) line 1935 + 63 bytes nsWindow::WindowProc(void * 0x00130594, unsigned int 258, unsigned int 2, long 3145729) line 478 + 27 bytes USER32! 77e71250()
Assignee: buster → jfrancis
joe, since I'm vacation can you look at this. If you don't get to it by Monday, just assign it back to me.
Assignee: jfrancis → buster
bouncing back to steve - i've been making bugs, not fixing them!
Assignee: buster → karnaze
Target Milestone: M5 → M6
set to M6, assigned to karnaze. Chris, you'll just do the Right Thing in the frame construction code to dispatch the incremental reflow command correctly, right?
the assertion Chris said was blocking him no longer happens.
Status: NEW → ASSIGNED
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Fixed with latest checkin.
Status: RESOLVED → VERIFIED
Fixed in 5/17 BUILD.
You need to log in before you can comment on or make changes to this bug.