Closed Bug 187117 Opened 22 years ago Closed 22 years ago

[FIX]GetFirstInFlow/GetLastInFlow should live on nsIFrame

Categories

(Core :: Layout, defect, P1)

x86
Other
defect

Tracking

()

RESOLVED FIXED
mozilla1.3beta

People

(Reporter: bzbarsky, Assigned: bzbarsky)

Details

(Whiteboard: [whitebox])

Attachments

(1 file)

We have loops in all sorts of places to do what GetFirstInFlow/GetLastInFlow 
do...  I believe these should be virtual methods on nsIFrame, with the 
implementation in nsIFrame being just "return this;".  The nsSplittableFrame 
can override them as it does now.  And we can replace all those loops with the 
much faster code that nsSplittableFrame uses (or that nsIFrame will have) 
without having to resort to icky casts...

Thoughts?
I meant to take this....
.
Assignee: misc → bzbarsky
Priority: -- → P1
Target Milestone: --- → mozilla1.3beta
And yes, that will require virtual dispatch for this method.... I'm not sure 
how big of a hit that would be in the existing use cases....
Attachment #110747 - Flags: superreview?(dbaron)
Attachment #110747 - Flags: review?(roc+moz)
Summary: GetFirstInFlow/GetLastInFlow should live on nsIFrame → [FIX]GetFirstInFlow/GetLastInFlow should live on nsIFrame
Comment on attachment 110747 [details] [diff] [review]
something like this

sr=dbaron, although I'm surprised there aren't more places where you could use
this
Attachment #110747 - Flags: superreview?(dbaron) → superreview+
I was somewhat suprised too.  A lot of callers actually _do_ something to all
the in-flow frames, so have to iterate.  I basically looked at all places
calling GetNextInFlow/GetPrevInFlow and converted the ones that looked
convertable...

I've filed bug 187924 on making GetNextInFlow/GetPrevInFlow more usable; as I
work on that I may find more places where GetFirstInFlow/GetNextInFlow could be
used.... (but I doubt it).
Whiteboard: [whitebox]
why NS_IMETHOD_(nsIFrame*) instead of just nsIFrame*? There's no need to pretend
that nsIFrame is an XPCOM interface.
|NS_IMETHOD_(x)| is just |virtual x|, except on Windows, where it adds some
calling convention thing.  (|NS_IMETHOD| is equivalent to |NS_IMETHOD_(nsresult)|)
Oh, never mind.  I guess you just meant |virtual nsIFrame*|.
exactly.  I could certainly just make it |virtual nsIFrame*|, but I'm not sure
about the calling conventions business.  I'd be happier to de-COMify nsIFrame
all in one swoop.
Feel free to deCOMify nsIFrame, but in the meantime at least we don't need to
make it worse.
Comment on attachment 110747 [details] [diff] [review]
something like this

Since I'm a softie, I'll give the r= and let bz decide what the return type
should be.
Attachment #110747 - Flags: review?(roc+moz) → review+
Fix checked in.  I made it |virtual nsIFrame*|; comment 11 convinced me.  ;)
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
This check-in has added a warning on brad TBox:

+layout/html/base/src/nsTextFrame.cpp:969
+ `class nsContinuingTextFrame * firstInFlow' might be used uninitialized in
this function

See also bug 59652, bug 179819 and bug 59675 for more on the "uninitialized"
warnings.
That warning is completely bogus, if you just look at the code in question.  I
considered writing that in a different way when I wrote the code, but that is
simply the simplest and most straightforward way to write the code.

I suppose I could add a "= nsnull" to shut up the compiler, but I think it would
just obfuscate the code in this case....

If you see a good way to rewrite this code to avoid the idiocy of gcc, please
feel free to tell me.
I agree that it is bogus. Here are couple alternatives:

---
NS_IMETHODIMP_(nsIFrame*)
nsContinuingTextFrame::GetFirstInFlow() const
{
  nsContinuingTextFrame* firstInFlow = (nsContinuingTextFrame*)this;
  while (firstInFlow->mPrevInFlow)  {
    firstInFlow = (nsContinuingTextFrame*)firstInFlow->mPrevInFlow;
  }
  return firstInFlow;
}
---
NS_IMETHODIMP_(nsIFrame*)
nsContinuingTextFrame::GetFirstInFlow() const
{
  nsContinuingTextFrame* prevInFlow;
  nsContinuingTextFrame* firstInFlow = (nsContinuingTextFrame*)this;
  while ((prevInFlow = (nsContinuingTextFrame*)firstInFlow->mPrevInFlow))  {
    firstInFlow = prevInFlow;
  }
  return firstInFlow;
}
P.S. If you end up fixing it, can you also fix two other instances of the
(almost) same code:

layout/html/base/src/nsSplittableFrame.cpp:108
 `class nsSplittableFrame * firstInFlow' might be used uninitialized in this
function

layout/html/base/src/nsSplittableFrame.cpp:120
 `class nsSplittableFrame * lastInFlow' might be used uninitialized in this function

Thanks!
Product: Core → Core Graveyard
Component: Layout: Misc Code → Layout
Product: Core Graveyard → Core
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: