2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsPopupSetFrame.h"
|
2007-10-06 06:53:05 -07:00
|
|
|
#include "nsGkAtoms.h"
|
|
|
|
#include "nsCOMPtr.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsPresContext.h"
|
|
|
|
#include "nsStyleContext.h"
|
|
|
|
#include "nsBoxLayoutState.h"
|
|
|
|
#include "nsIScrollableFrame.h"
|
|
|
|
#include "nsIRootBox.h"
|
2010-02-09 08:05:19 -08:00
|
|
|
#include "nsMenuPopupFrame.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsIFrame*
|
|
|
|
NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|
|
|
{
|
|
|
|
return new (aPresShell) nsPopupSetFrame (aPresShell, aContext);
|
|
|
|
}
|
|
|
|
|
2009-09-12 09:49:24 -07:00
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPopupSetFrame::Init(nsIContent* aContent,
|
|
|
|
nsIFrame* aParent,
|
|
|
|
nsIFrame* aPrevInFlow)
|
|
|
|
{
|
|
|
|
nsresult rv = nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
|
|
|
|
|
2008-12-16 16:30:31 -08:00
|
|
|
// Normally the root box is our grandparent, but in case of wrapping
|
|
|
|
// it can be our great-grandparent.
|
|
|
|
nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
|
|
|
|
if (rootBox) {
|
2007-03-22 10:30:00 -07:00
|
|
|
rootBox->SetPopupSetFrame(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-10-06 06:53:05 -07:00
|
|
|
nsIAtom*
|
|
|
|
nsPopupSetFrame::GetType() const
|
|
|
|
{
|
|
|
|
return nsGkAtoms::popupSetFrame;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
2011-08-24 13:54:30 -07:00
|
|
|
nsPopupSetFrame::AppendFrames(ChildListID aListID,
|
2009-07-30 10:23:32 -07:00
|
|
|
nsFrameList& aFrameList)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-08-24 13:54:30 -07:00
|
|
|
if (aListID == kPopupList) {
|
2010-02-09 08:05:19 -08:00
|
|
|
AddPopupFrameList(aFrameList);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-08-24 13:54:30 -07:00
|
|
|
return nsBoxFrame::AppendFrames(aListID, aFrameList);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-08-24 13:54:30 -07:00
|
|
|
nsPopupSetFrame::RemoveFrame(ChildListID aListID,
|
2007-03-22 10:30:00 -07:00
|
|
|
nsIFrame* aOldFrame)
|
|
|
|
{
|
2011-08-24 13:54:30 -07:00
|
|
|
if (aListID == kPopupList) {
|
2010-02-09 08:05:19 -08:00
|
|
|
RemovePopupFrame(aOldFrame);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-08-24 13:54:30 -07:00
|
|
|
return nsBoxFrame::RemoveFrame(aListID, aOldFrame);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-08-24 13:54:30 -07:00
|
|
|
nsPopupSetFrame::InsertFrames(ChildListID aListID,
|
2007-03-22 10:30:00 -07:00
|
|
|
nsIFrame* aPrevFrame,
|
2009-07-30 10:23:32 -07:00
|
|
|
nsFrameList& aFrameList)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-08-24 13:54:30 -07:00
|
|
|
if (aListID == kPopupList) {
|
2010-02-09 08:05:19 -08:00
|
|
|
AddPopupFrameList(aFrameList);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-08-24 13:54:30 -07:00
|
|
|
return nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2011-08-24 13:54:30 -07:00
|
|
|
nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
|
2009-07-28 05:53:20 -07:00
|
|
|
nsFrameList& aChildList)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-08-24 13:54:30 -07:00
|
|
|
if (aListID == kPopupList) {
|
2010-02-09 08:05:19 -08:00
|
|
|
// XXXmats this asserts because we don't implement
|
2011-08-24 13:54:30 -07:00
|
|
|
// GetChildList(kPopupList) so nsCSSFrameConstructor
|
2010-02-09 08:05:19 -08:00
|
|
|
// believes it's empty and calls us multiple times.
|
|
|
|
//NS_ASSERTION(mPopupList.IsEmpty(),
|
|
|
|
// "SetInitialChildList on non-empty child list");
|
|
|
|
AddPopupFrameList(aChildList);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-08-24 13:54:30 -07:00
|
|
|
return nsBoxFrame::SetInitialChildList(aListID, aChildList);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-12-23 21:21:15 -08:00
|
|
|
nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-02-09 08:05:19 -08:00
|
|
|
mPopupList.DestroyFramesFrom(aDestructRoot);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-12-16 16:30:31 -08:00
|
|
|
// Normally the root box is our grandparent, but in case of wrapping
|
|
|
|
// it can be our great-grandparent.
|
|
|
|
nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
|
|
|
|
if (rootBox) {
|
2012-07-30 07:20:58 -07:00
|
|
|
rootBox->SetPopupSetFrame(nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2009-12-23 21:21:15 -08:00
|
|
|
nsBoxFrame::DestroyFrom(aDestructRoot);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPopupSetFrame::DoLayout(nsBoxLayoutState& aState)
|
|
|
|
{
|
|
|
|
// lay us out
|
|
|
|
nsresult rv = nsBoxFrame::DoLayout(aState);
|
|
|
|
|
|
|
|
// lay out all of our currently open popups.
|
2010-02-09 08:05:19 -08:00
|
|
|
for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
|
|
|
|
nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
|
2012-07-30 07:20:58 -07:00
|
|
|
popupChild->LayoutPopup(aState, nullptr, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-02-09 08:05:19 -08:00
|
|
|
void
|
2007-03-22 10:30:00 -07:00
|
|
|
nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup)
|
|
|
|
{
|
2010-02-09 08:05:19 -08:00
|
|
|
NS_PRECONDITION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
|
|
|
|
aPopup->GetType() == nsGkAtoms::menuPopupFrame,
|
|
|
|
"removing wrong type of frame in popupset's ::popupList");
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-02-09 08:05:19 -08:00
|
|
|
mPopupList.DestroyFrame(aPopup);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2010-02-09 08:05:19 -08:00
|
|
|
void
|
2009-07-28 05:53:20 -07:00
|
|
|
nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-02-09 08:05:19 -08:00
|
|
|
#ifdef DEBUG
|
|
|
|
for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
|
|
|
|
NS_ASSERTION((e.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
|
|
|
|
e.get()->GetType() == nsGkAtoms::menuPopupFrame,
|
|
|
|
"adding wrong type of frame in popupset's ::popupList");
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2010-02-09 08:05:19 -08:00
|
|
|
#endif
|
2012-07-30 07:20:58 -07:00
|
|
|
mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-10-06 06:53:05 -07:00
|
|
|
|
2007-10-23 17:02:26 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
NS_IMETHODIMP
|
2012-09-19 07:36:35 -07:00
|
|
|
nsPopupSetFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
|
2007-10-06 06:53:05 -07:00
|
|
|
{
|
2007-10-23 17:02:26 -07:00
|
|
|
IndentBy(out, aIndent);
|
|
|
|
ListTag(out);
|
|
|
|
#ifdef DEBUG_waterson
|
|
|
|
fprintf(out, " [parent=%p]", static_cast<void*>(mParent));
|
|
|
|
#endif
|
|
|
|
if (HasView()) {
|
|
|
|
fprintf(out, " [view=%p]", static_cast<void*>(GetView()));
|
|
|
|
}
|
2009-09-18 04:09:36 -07:00
|
|
|
if (GetNextSibling()) {
|
|
|
|
fprintf(out, " next=%p", static_cast<void*>(GetNextSibling()));
|
2007-10-23 17:02:26 -07:00
|
|
|
}
|
2012-07-30 07:20:58 -07:00
|
|
|
if (nullptr != GetPrevContinuation()) {
|
2007-10-23 17:02:26 -07:00
|
|
|
fprintf(out, " prev-continuation=%p", static_cast<void*>(GetPrevContinuation()));
|
|
|
|
}
|
2012-07-30 07:20:58 -07:00
|
|
|
if (nullptr != GetNextContinuation()) {
|
2007-10-23 17:02:26 -07:00
|
|
|
fprintf(out, " next-continuation=%p", static_cast<void*>(GetNextContinuation()));
|
|
|
|
}
|
|
|
|
fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height);
|
|
|
|
if (0 != mState) {
|
2011-12-19 19:46:39 -08:00
|
|
|
fprintf(out, " [state=%016llx]", (unsigned long long)mState);
|
2007-10-23 17:02:26 -07:00
|
|
|
}
|
|
|
|
fprintf(out, " [content=%p]", static_cast<void*>(mContent));
|
|
|
|
nsPopupSetFrame* f = const_cast<nsPopupSetFrame*>(this);
|
2010-10-06 21:25:47 -07:00
|
|
|
if (f->HasOverflowAreas()) {
|
|
|
|
nsRect overflowArea = f->GetVisualOverflowRect();
|
|
|
|
fprintf(out, " [vis-overflow=%d,%d,%d,%d]",
|
|
|
|
overflowArea.x, overflowArea.y,
|
|
|
|
overflowArea.width, overflowArea.height);
|
|
|
|
overflowArea = f->GetScrollableOverflowRect();
|
|
|
|
fprintf(out, " [scr-overflow=%d,%d,%d,%d]",
|
|
|
|
overflowArea.x, overflowArea.y,
|
2008-02-19 23:08:55 -08:00
|
|
|
overflowArea.width, overflowArea.height);
|
2007-10-23 17:02:26 -07:00
|
|
|
}
|
|
|
|
fprintf(out, " [sc=%p]", static_cast<void*>(mStyleContext));
|
2009-10-29 14:17:56 -07:00
|
|
|
nsIAtom* pseudoTag = mStyleContext->GetPseudo();
|
2007-10-23 17:02:26 -07:00
|
|
|
if (pseudoTag) {
|
|
|
|
nsAutoString atomString;
|
|
|
|
pseudoTag->ToString(atomString);
|
|
|
|
fprintf(out, " pst=%s",
|
|
|
|
NS_LossyConvertUTF16toASCII(atomString).get());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Output the children
|
2011-09-28 23:19:26 -07:00
|
|
|
bool outputOneList = false;
|
2011-08-24 13:54:29 -07:00
|
|
|
ChildListIterator lists(this);
|
|
|
|
for (; !lists.IsDone(); lists.Next()) {
|
|
|
|
if (outputOneList) {
|
2007-10-23 17:02:26 -07:00
|
|
|
IndentBy(out, aIndent);
|
|
|
|
}
|
2011-10-17 07:59:28 -07:00
|
|
|
outputOneList = true;
|
2011-08-24 13:54:29 -07:00
|
|
|
fprintf(out, "%s<\n", mozilla::layout::ChildListName(lists.CurrentID()));
|
|
|
|
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
|
|
|
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
|
|
|
nsIFrame* kid = childFrames.get();
|
|
|
|
// Verify the child frame's parent frame pointer is correct
|
|
|
|
NS_ASSERTION(kid->GetParent() == this, "bad parent frame pointer");
|
|
|
|
|
|
|
|
// Have the child frame list
|
2012-09-19 07:36:35 -07:00
|
|
|
kid->List(out, aIndent + 1, aFlags);
|
2011-08-24 13:54:29 -07:00
|
|
|
}
|
|
|
|
IndentBy(out, aIndent);
|
|
|
|
fputs(">\n", out);
|
|
|
|
}
|
2007-10-23 17:02:26 -07:00
|
|
|
|
|
|
|
// XXXmats the above is copy-pasted from nsContainerFrame::List which is lame,
|
|
|
|
// clean this up after bug 399111 is implemented.
|
|
|
|
|
2010-02-09 08:05:19 -08:00
|
|
|
if (!mPopupList.IsEmpty()) {
|
2007-10-23 17:02:26 -07:00
|
|
|
fputs("<\n", out);
|
|
|
|
++aIndent;
|
|
|
|
IndentBy(out, aIndent);
|
2011-08-24 13:54:29 -07:00
|
|
|
fputs(mozilla::layout::ChildListName(kPopupList), out);
|
2007-10-23 17:02:26 -07:00
|
|
|
fputs(" for ", out);
|
|
|
|
ListTag(out);
|
|
|
|
fputs(" <\n", out);
|
|
|
|
++aIndent;
|
2010-02-09 08:05:19 -08:00
|
|
|
for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
|
2012-09-19 07:36:35 -07:00
|
|
|
e.get()->List(out, aIndent, aFlags);
|
2007-10-23 17:02:26 -07:00
|
|
|
}
|
|
|
|
--aIndent;
|
|
|
|
IndentBy(out, aIndent);
|
|
|
|
fputs(">\n", out);
|
|
|
|
--aIndent;
|
|
|
|
IndentBy(out, aIndent);
|
|
|
|
fputs(">\n", out);
|
2011-10-17 07:59:28 -07:00
|
|
|
outputOneList = true;
|
2007-10-23 17:02:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!outputOneList) {
|
|
|
|
fputs("<>\n", out);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2007-10-06 06:53:05 -07:00
|
|
|
}
|
2007-10-23 17:02:26 -07:00
|
|
|
#endif
|