Closed
Bug 289250
Opened 21 years ago
Closed 20 years ago
FrameTraversal broken
Categories
(Core :: Layout, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: dougt, Assigned: roc)
References
Details
Attachments
(2 files, 1 obsolete file)
131.73 KB,
text/plain
|
Details | |
2.58 KB,
patch
|
bzbarsky
:
review+
asa
:
approval1.8b2-
shaver
:
approval1.8b3+
|
Details | Diff | Splinter Review |
I think resent changes to layout broken the following code. I am not sure if
this code is buggy and needs to be rewritten, or a regression occured. Please
advise:
GIVEN A |nsPresContext|:
nsCOMPtr<nsIDocument> doc = content->GetDocument();
if (!doc) return nsnull;
// the only case where there could be more shells in printpreview
nsIPresShell *shell = doc->GetShellAt(0);
if (!shell) return nsnull;
nsPresContext *presContext = shell->GetPresContext();
The following code yields an enumerator with very few (~3) frames in it. Before
recent changes to layout, this enumerator would be full of frame (frames for the
entire presContext).
nsresult createFrameTraversal(PRUint32 type, /* IS ALWAYS FOCUS */
nsPresContext* presContext,
nsIBidirectionalEnumerator** outTraversal)
{
nsresult result;
if (!presContext)
return NS_ERROR_FAILURE;
nsIPresShell* presShell = presContext->PresShell();
if (!presShell)
return NS_ERROR_FAILURE;
nsIFrame* frame = nsnull;
#ifdef OLDER_LAYOUT
presShell->GetRootFrame(&frame);
#else
frame = presShell->GetRootFrame();
#endif
if (!frame)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result));
if (NS_FAILED(result))
return result;
result = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
type,
presContext,
frame);
if (NS_FAILED(result))
return result;
NS_IF_ADDREF(*outTraversal = frameTraversal);
return NS_OK;
}
Thanks for looking into this.
Reporter | ||
Comment 1•21 years ago
|
||
forgive the OLDER_LAYOUT define. it isn't set in our case.
![]() |
||
Comment 2•21 years ago
|
||
Hmm... The frame traversal code for FOCUS doesn't really look at scrollframes
(unlike EXTENSIVE and LEAF).... roc, any idea what could be up here? Somehow
the frame iterator is clearly getting confused by the changes to the root frame
setup...
Reporter | ||
Comment 3•21 years ago
|
||
updating my tree back to 2005-03-20 08:00:00 fixes the problem.
Assignee | ||
Comment 4•21 years ago
|
||
The problem is that we reordered the scrollframe children so that scrollbars
are first, followed by the canvas frame. The frames look like this:
== viewport
== scrollframe
== scrollbar
== scrollbar
== canvas
== block and rest of document
So what happens in focus frame traversal is, we return the viewport frame, then
we return the scrollframe, then we return the scrollbars, then the
sibling/parent traversal loop sees IsRootFrame is true and thinks it's done.
The problem is that we should only be checking IsRootFrame after we've moved up
to the parent. A couple of the other methods have similar problems, although
they already have the necessary check after GetParent() too. This patch fixes
them all.
Doug, please test this patch and let me know if it works for you...
Assignee | ||
Updated•21 years ago
|
Assignee: dougt → roc
Status: NEW → ASSIGNED
Reporter | ||
Comment 5•21 years ago
|
||
roc, that didn't work. :-(
Assignee | ||
Comment 6•21 years ago
|
||
Can you be more specific?
After you get the root frame, you could add a statement
frame->List(frame->GetPresContext(), stdout, 0);
to dump the frame tree, and then add some other printfs to print the frame
pointers you get from the iterator (e.g., iter->CurrentItem(&f); printf("got
frame %x\n", f); ). That output would help to debug this...
Reporter | ||
Comment 7•21 years ago
|
||
requesting blocking status.
working on getting roc debugging data.
Flags: blocking1.8b2?
Reporter | ||
Comment 8•21 years ago
|
||
roc, this is the log per your request.
The page used to test this was, for reference, was
http://www.google.com/firefox?client=firefox-a&rls=org.mozilla:en-US:official
Assignee | ||
Comment 9•21 years ago
|
||
Attachment #179897 -
Attachment is obsolete: true
Reporter | ||
Comment 10•21 years ago
|
||
roc, that patch works for me. i will continue testing to see if anything is
still broken. Great work.
Reporter | ||
Updated•20 years ago
|
Attachment #181466 -
Flags: review?(bzbarsky)
Attachment #181466 -
Flags: approval1.8b2?
![]() |
||
Comment 11•20 years ago
|
||
So what's that patch actually doing, and why?
Assignee | ||
Comment 12•20 years ago
|
||
The frame traversal used to stop whenever it reached a frame matching
IsRootFrame (e.g., the canvas frame, which is a child of the viewport's
scrollframe). Now it only stops when we reach that frame when we back up from a
child frame to its parent.
What this means is that if you start a frame traversal at the root (viewport)
frame, you will see all frames. If you start a frame traversal from inside the
canvas frame, it will not enumerate the canvas frame or anything outside it (the
iewport frame, the viewport scrollframe, or the viewport scrollframe's
scrollbars and scrollcorner). Basically it's the same behaviour as before we
regressed except that if you initiate a frame traversal at the root, you now see
the viewport scrollframe's scrollbars and scrollcorner, but you didn't before.
![]() |
||
Comment 13•20 years ago
|
||
Comment on attachment 181466 [details] [diff] [review]
potential fix #2
>Index: layout/base/nsFrameTraversal.cpp
nsLeafIterator::Prev doesn't seem to have an IsRootFrame() check. Should it?
> nsFocusIterator::Next()
>+ if (IsRootFrame(result)) {
>+ result = 0;
>+ break;
Do you need the break? Won't that happen automatically?
> nsFocusIterator::Prev()
That method needs to do an IsRootFrame() check too, no?
Same for nsVisualIterator::Prev.
r=bzbarsky as a regression fix, but this only "unregresses" us to a broken
state, as far as I can tell -- going back and forward don't do quite the same
thing....
Attachment #181466 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 14•20 years ago
|
||
(In reply to comment #13)
> > nsFocusIterator::Next()
>
> >+ if (IsRootFrame(result)) {
> >+ result = 0;
> >+ break;
>
> Do you need the break? Won't that happen automatically?
It will. We could remove the break.
> > nsFocusIterator::Prev()
>
> That method needs to do an IsRootFrame() check too, no?
>
> Same for nsVisualIterator::Prev.
>
> r=bzbarsky as a regression fix, but this only "unregresses" us to a broken
> state, as far as I can tell -- going back and forward don't do quite the same
> thing....
Using IsRootFrame instead of != nsnull used to have the effect of stopping
enumeration without returnng the viewport scrollbars. I have no idea why that
might have been important.
Prev didn't need IsRootFrame because the scrollbars were after all the body
frames, so starting at a body frame wouldn't see the scrollbars anyway. Now,
because the viewport scrollbars come before the body frames, Prev will be seeing
them, and so is Next (and without the patch, if you start iterating at the
viewport frame, that's all you see). Again, I have no idea if this is a problem
for any frame traversal user.
Replacing all the IsRootFrame checks with null checks would make Next and Prev
symmetric and the only change would be that you always see the viewport
scrollbars. It seems to me that that's the simplest and least surprising thing
to do. Should we do that?
Reporter | ||
Comment 15•20 years ago
|
||
patch 2 worked for me. i can test out any other patch you produce.
![]() |
||
Comment 16•20 years ago
|
||
That makes some sense to me, but I also don't know what frame traversal users
that could break... Tabbing has me particularly worried.
Assignee | ||
Comment 17•20 years ago
|
||
I think we can push this out to b3.
Flags: blocking1.8b2? → blocking1.8b2-
Reporter | ||
Comment 18•20 years ago
|
||
disappointing, but understandable. lets try for 1.8b3
Flags: blocking1.8b3?
Comment 19•20 years ago
|
||
Comment on attachment 181466 [details] [diff] [review]
potential fix #2
moving request out to b3 for consideration after b2 ships.
Attachment #181466 -
Flags: approval1.8b3?
Attachment #181466 -
Flags: approval1.8b2?
Attachment #181466 -
Flags: approval1.8b2-
Comment 20•20 years ago
|
||
Comment on attachment 181466 [details] [diff] [review]
potential fix #2
a=shaver
Attachment #181466 -
Flags: approval1.8b3? → approval1.8b3+
Reporter | ||
Comment 21•20 years ago
|
||
Checking in nsFrameTraversal.cpp;
/cvsroot/mozilla/layout/base/nsFrameTraversal.cpp,v <-- nsFrameTraversal.cpp
new revision: 3.45; previous revision: 3.44
done
Fix checked in.
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Updated•20 years ago
|
Flags: blocking1.8b3?
You need to log in
before you can comment on or make changes to this bug.
Description
•