author | Robert O'Callahan <robert@ocallahan.org> |
Wed, 18 Dec 2013 18:37:24 +1300 | |
changeset 161157 | cdbe5779c72800086f40480b6ac6893497ca9ff8 |
parent 161156 | d0ae017eae17a279c1f776aee638e0f643f5af71 |
child 161158 | fc0610680d3b2ed01d84998f12a8fe631178d78e |
push id | 25869 |
push user | kwierso@gmail.com |
push date | Thu, 19 Dec 2013 04:49:41 +0000 |
treeherder | mozilla-central@7d120481a6ae [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mats |
bugs | 950427 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -3157,17 +3157,17 @@ nsDocument::ElementFromPointHelper(float nsIFrame *rootFrame = ps->GetRootFrame(); // XUL docs, unlike HTML, have no frame tree until everything's done loading if (!rootFrame) { return nullptr; // return null to premature XUL callers as a reminder to wait } 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); if (elem && !elem->IsElement()) { elem = elem->GetParent(); @@ -3212,17 +3212,17 @@ nsDocument::NodesFromRectHelper(float aX nsIFrame *rootFrame = ps->GetRootFrame(); // XUL docs, unlike HTML, have no frame tree until everything's done loading if (!rootFrame) return NS_OK; // return nothing to premature XUL callers as a reminder to wait 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]); @@ -9454,17 +9454,17 @@ nsIDocument::CaretPositionFromPoint(floa nsIFrame *rootFrame = ps->GetRootFrame(); // XUL docs, unlike HTML, have no frame tree until everything's done loading if (!rootFrame) { return nullptr; } nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, - nsLayoutUtils::IGNORE_PAINT_SUPPRESSION); + nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC); if (!ptFrame) { return nullptr; } // GetContentOffsetsFromPoint requires frame-relative coordinates, so we need // to adjust to frame-relative coordinates before we can perform this call. // It should also not take into account the padding of the frame. nsPoint adjustedPoint = pt - ptFrame->GetOffsetTo(rootFrame);
--- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -481,16 +481,17 @@ nsDisplayListBuilder::nsDisplayListBuild mCachedOffset(0, 0), mGlassDisplayItem(nullptr), mMode(aMode), mBuildCaret(aBuildCaret), mIgnoreSuppression(false), mHadToIgnoreSuppression(false), mIsAtRootOfPseudoStackingContext(false), mIncludeAllOutOfFlows(false), + mDescendIntoSubdocuments(true), mSelectedFramesOnly(false), mAccurateVisibleRegions(false), mAllowMergingAndFlattening(true), mWillComputePluginGeometry(false), mInTransform(false), mSyncDecodeImages(false), mIsPaintingToWindow(false), mIsCompositingCheap(false),
--- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -278,16 +278,21 @@ public: * document when building the display list. */ bool GetHadToIgnorePaintSuppression() { return mHadToIgnoreSuppression; } /** * Call this if we're doing normal painting to the window. */ 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 * performed while computing visibility. */ bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; } void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; } @@ -642,16 +647,17 @@ private: nsDisplayItem* mGlassDisplayItem; nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy; Mode mMode; bool mBuildCaret; bool mIgnoreSuppression; bool mHadToIgnoreSuppression; bool mIsAtRootOfPseudoStackingContext; bool mIncludeAllOutOfFlows; + bool mDescendIntoSubdocuments; bool mSelectedFramesOnly; bool mAccurateVisibleRegions; bool mAllowMergingAndFlattening; bool mWillComputePluginGeometry; // True when we're building a display list that's directly or indirectly // under an nsDisplayTransform bool mInTransform; bool mSyncDecodeImages;
--- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2085,16 +2085,19 @@ nsLayoutUtils::GetFramesForArea(nsIFrame if (aFlags & IGNORE_ROOT_SCROLL_FRAME) { nsIFrame* rootScrollFrame = aFrame->PresContext()->PresShell()->GetRootScrollFrame(); if (rootScrollFrame) { builder.SetIgnoreScrollFrame(rootScrollFrame); } } + if (aFlags & IGNORE_CROSS_DOC) { + builder.SetDescendIntoSubdocuments(false); + } builder.EnterPresShell(aFrame, target); aFrame->BuildDisplayListForStackingContext(&builder, target, &list); builder.LeavePresShell(aFrame, target); #ifdef MOZ_DUMP_PAINTING if (gDumpEventList) { fprintf_stderr(stderr, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
--- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -602,17 +602,21 @@ public: * When set, paint suppression is ignored, so we'll return non-root page * elements even if paint suppression is stopping them from painting. */ IGNORE_PAINT_SUPPRESSION = 0x01, /** * 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 }; /** * Given aFrame, the root frame of a stacking context, find its descendant * frame under the point aPt that receives a mouse event at that location, * or nullptr if there is no such frame. * @param aPt the point, relative to the frame origin * @param aFlags some combination of FrameForPointFlags
--- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -237,19 +237,16 @@ nsSubDocumentFrame::GetSubdocumentSize() return nsIntSize(presContext->AppUnitsToDevPixels(docSizeAppUnits.width), presContext->AppUnitsToDevPixels(docSizeAppUnits.height)); } } bool nsSubDocumentFrame::PassPointerEventsToChildren() { - if (StyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) { - return true; - } // Limit use of mozpasspointerevents to documents with embedded:apps/chrome // permission, because this could be used by the parent document to discover // which parts of the subdocument are transparent to events (if subdocument // uses pointer-events:none on its root element, which is admittedly // unlikely) if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozpasspointerevents)) { if (PresContext()->IsChrome()) { return true; @@ -272,29 +269,39 @@ nsSubDocumentFrame::PassPointerEventsToC void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) return; - // If mozpasspointerevents is set, then we should allow subdocument content - // to handle events even if we're pointer-events:none. - if (aBuilder->IsForEventDelivery() && !PassPointerEventsToChildren()) - return; - // If we are pointer-events:none then we don't need to HitTest background - if (!aBuilder->IsForEventDelivery() || - StyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) { + bool pointerEventsNone = StyleVisibility()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE; + if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) { DisplayBorderBackgroundOutline(aBuilder, aLists); } - if (!mInnerView) + bool passPointerEventsToChildren = false; + if (aBuilder->IsForEventDelivery()) { + passPointerEventsToChildren = PassPointerEventsToChildren(); + // If mozpasspointerevents is set, then we should allow subdocument content + // to handle events even if we're pointer-events:none. + if (pointerEventsNone && !passPointerEventsToChildren) { + return; + } + } + + // If we're passing pointer events to children then we have to descend into + // subdocuments no matter what, to determine which parts are transparent for + // elementFromPoint. + if (!mInnerView || + (!aBuilder->GetDescendIntoSubdocuments() && !passPointerEventsToChildren)) { return; + } nsFrameLoader* frameLoader = FrameLoader(); if (frameLoader) { RenderFrameParent* rfp = frameLoader->GetCurrentRemoteFrame(); if (rfp) { rfp->BuildDisplayList(aBuilder, this, aDirtyRect, aLists); return; }