Bug 950427. Don't descend into subdocuments at all in elementFromPoint. r=mats

This commit is contained in:
Robert O'Callahan 2013-12-18 18:37:24 +13:00
parent fd98185e20
commit 9454d623f6
7 changed files with 37 additions and 37 deletions

View File

@ -3131,6 +3131,20 @@ nsIDocument::ElementFromPoint(float aX, float aY)
return ElementFromPointHelper(aX, aY, false, true);
}
static nsIContent*
GetNonanonymousContent(nsIFrame* aFrame)
{
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
nsIContent* content = f->GetContent();
if (content && !content->IsInAnonymousSubtree()) {
return content;
}
}
return nullptr;
}
Element*
nsDocument::ElementFromPointHelper(float aX, float aY,
bool aIgnoreRootScrollFrame,
@ -3162,13 +3176,14 @@ nsDocument::ElementFromPointHelper(float aX, float aY,
}
nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
(aIgnoreRootScrollFrame ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
if (!ptFrame) {
return nullptr;
}
nsIContent* elem = GetContentInThisDocument(ptFrame);
nsIContent* elem = GetNonanonymousContent(ptFrame);
NS_ASSERTION(!elem || elem->OwnerDoc() == this, "Wrong document");
if (elem && !elem->IsElement()) {
elem = elem->GetParent();
}
@ -3217,14 +3232,15 @@ nsDocument::NodesFromRectHelper(float aX, float aY,
nsAutoTArray<nsIFrame*,8> outFrames;
nsLayoutUtils::GetFramesForArea(rootFrame, rect, outFrames,
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
(aIgnoreRootScrollFrame ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
// Used to filter out repeated elements in sequence.
nsIContent* lastAdded = nullptr;
for (uint32_t i = 0; i < outFrames.Length(); i++) {
nsIContent* node = GetContentInThisDocument(outFrames[i]);
nsIContent* node = GetNonanonymousContent(outFrames[i]);
NS_ASSERTION(!node || node->OwnerDoc() == this, "Wrong document");
if (node && !node->IsElement() && !node->IsNodeOfType(nsINode::eTEXT)) {
// We have a node that isn't an element or a text node,
@ -8068,27 +8084,6 @@ nsDocument::DoUnblockOnload()
}
}
nsIContent*
nsDocument::GetContentInThisDocument(nsIFrame* aFrame) const
{
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
nsIContent* content = f->GetContent();
if (!content || content->IsInAnonymousSubtree())
continue;
if (content->OwnerDoc() == this) {
return content;
}
// We must be in a subdocument so jump directly to the root frame.
// GetParentOrPlaceholderForCrossDoc gets called immediately to jump up to
// the containing document.
f = f->PresContext()->GetPresShell()->GetRootFrame();
}
return nullptr;
}
void
nsDocument::DispatchPageTransition(EventTarget* aDispatchTarget,
const nsAString& aType,

View File

@ -1310,16 +1310,6 @@ private:
mCSPWebConsoleErrorQueue.Flush(this);
}
/**
* Find the (non-anonymous) content in this document for aFrame. It will
* be aFrame's content node if that content is in this document and not
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
* element containing the subdocument containing aFrame, and/or find the
* nearest non-anonymous ancestor in this document.
* Returns null if there is no such element.
*/
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
// Just like EnableStyleSheetsForSet, but doesn't check whether
// aSheetSet is null and allows the caller to control whether to set
// aSheetSet as the preferred set in the CSSLoader.

View File

@ -486,6 +486,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mHadToIgnoreSuppression(false),
mIsAtRootOfPseudoStackingContext(false),
mIncludeAllOutOfFlows(false),
mDescendIntoSubdocuments(true),
mSelectedFramesOnly(false),
mAccurateVisibleRegions(false),
mAllowMergingAndFlattening(true),

View File

@ -283,6 +283,11 @@ public:
*/
void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
/**
* Call this to prevent descending into subdocuments.
*/
void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
/**
* Returns true if merging and flattening of display lists should be
@ -647,6 +652,7 @@ private:
bool mHadToIgnoreSuppression;
bool mIsAtRootOfPseudoStackingContext;
bool mIncludeAllOutOfFlows;
bool mDescendIntoSubdocuments;
bool mSelectedFramesOnly;
bool mAccurateVisibleRegions;
bool mAllowMergingAndFlattening;

View File

@ -2090,6 +2090,9 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
builder.SetIgnoreScrollFrame(rootScrollFrame);
}
}
if (aFlags & IGNORE_CROSS_DOC) {
builder.SetDescendIntoSubdocuments(false);
}
builder.EnterPresShell(aFrame, target);
aFrame->BuildDisplayListForStackingContext(&builder, target, &list);

View File

@ -607,7 +607,11 @@ public:
* When set, clipping due to the root scroll frame (and any other viewport-
* related clipping) is ignored.
*/
IGNORE_ROOT_SCROLL_FRAME = 0x02
IGNORE_ROOT_SCROLL_FRAME = 0x02,
/**
* When set, return only content in the same document as aFrame.
*/
IGNORE_CROSS_DOC = 0x04
};
/**

View File

@ -288,8 +288,9 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplayBorderBackgroundOutline(aBuilder, aLists);
}
if (!mInnerView)
if (!mInnerView || !aBuilder->GetDescendIntoSubdocuments()) {
return;
}
nsFrameLoader* frameLoader = FrameLoader();
if (frameLoader) {