Bug 1553012 - Make PresShell::ScrollFrameRectIntoView work in fission world. r=mattwoodrow,nika,tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D36136

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Hiroyuki Ikezoe 2019-07-09 05:34:27 +00:00
Родитель 57de429e1f
Коммит 8aa17d97ef
13 изменённых файлов: 153 добавлений и 8 удалений

Просмотреть файл

@ -13,8 +13,10 @@
#include "nsFocusManager.h"
#include "nsFrameLoader.h"
#include "nsFrameLoaderOwner.h"
#include "nsQueryObject.h"
#include "nsIDocShellTreeOwner.h"
#include "nsQueryObject.h"
#include "nsSubDocumentFrame.h"
#include "nsView.h"
using namespace mozilla::ipc;
@ -159,6 +161,38 @@ mozilla::ipc::IPCResult BrowserBridgeChild::RecvFireFrameLoadEvent(
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserBridgeChild::RecvScrollRectIntoView(
const nsRect& aRect, const ScrollAxis& aVertical,
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel) {
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
if (!owner) {
return IPC_OK();
}
nsIFrame* frame = owner->GetPrimaryFrame();
if (!frame) {
return IPC_OK();
}
nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(frame);
if (!subdocumentFrame) {
return IPC_OK();
}
nsPoint extraOffset = subdocumentFrame->GetExtraOffset();
int32_t parentAPD = frame->PresContext()->AppUnitsPerDevPixel();
nsRect rect =
aRect.ScaleToOtherAppUnitsRoundOut(aAppUnitsPerDevPixel, parentAPD);
rect += extraOffset;
RefPtr<PresShell> presShell = frame->PresShell();
presShell->ScrollFrameRectIntoView(frame, rect, aVertical, aHorizontal,
aScrollFlags);
return IPC_OK();
}
void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
mIPCOpen = false;
}

Просмотреть файл

@ -85,6 +85,12 @@ class BrowserBridgeChild : public PBrowserBridgeChild {
mozilla::ipc::IPCResult RecvFireFrameLoadEvent(bool aIsTrusted);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvScrollRectIntoView(
const nsRect& aRect, const ScrollAxis& aVertical,
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:

Просмотреть файл

@ -3797,6 +3797,20 @@ mozilla::ipc::IPCResult BrowserParent::RecvFireFrameLoadEvent(bool aIsTrusted) {
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvScrollRectIntoView(
const nsRect& aRect, const ScrollAxis& aVertical,
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel) {
BrowserBridgeParent* bridge = GetBrowserBridgeParent();
if (!bridge || !bridge->CanSend()) {
return IPC_OK();
}
Unused << bridge->SendScrollRectIntoView(aRect, aVertical, aHorizontal,
aScrollFlags, aAppUnitsPerDevPixel);
return IPC_OK();
}
NS_IMETHODIMP
FakeChannel::OnAuthAvailable(nsISupports* aContext,
nsIAuthInformation* aAuthInfo) {

Просмотреть файл

@ -447,6 +447,11 @@ class BrowserParent final : public PBrowserParent,
mozilla::ipc::IPCResult RecvDispatchKeyboardEvent(
const mozilla::WidgetKeyboardEvent& aEvent);
mozilla::ipc::IPCResult RecvScrollRectIntoView(
const nsRect& aRect, const ScrollAxis& aVertical,
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel);
PColorPickerParent* AllocPColorPickerParent(const nsString& aTitle,
const nsString& aInitialColor);

Просмотреть файл

@ -89,6 +89,8 @@ using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
using mozilla::dom::EffectsInfo from "mozilla/dom/TabMessageUtils.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
using mozilla::ScrollAxis from "mozilla/PresShellForwards.h";
using mozilla::ScrollFlags from "mozilla/PresShellForwards.h";
namespace mozilla {
namespace dom {
@ -693,6 +695,10 @@ parent:
*/
async FireFrameLoadEvent(bool aIsTrusted);
async ScrollRectIntoView(nsRect aRect, ScrollAxis aVertical,
ScrollAxis aHorizontal, ScrollFlags aScrollFlags,
int32_t aAppUnitsPerDevPixel);
child:
/**
* Notify the remote browser that it has been Show()n on this

Просмотреть файл

@ -16,6 +16,9 @@ using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
using mozilla::WidgetMouseEvent from "ipc/nsGUIEventIPC.h";
using mozilla::a11y::IDispatchHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::dom::EffectsInfo from "mozilla/dom/TabMessageUtils.h";
using mozilla::ScrollAxis from "mozilla/PresShellForwards.h";
using mozilla::ScrollFlags from "mozilla/PresShellForwards.h";
using struct nsRect from "nsRect.h";
namespace mozilla {
namespace dom {
@ -56,6 +59,10 @@ child:
*/
async FireFrameLoadEvent(bool aIsTrusted);
async ScrollRectIntoView(nsRect aRect, ScrollAxis aVertical,
ScrollAxis aHorizontal, ScrollFlags aScrollFlags,
int32_t aAppUnitsPerDevPixel);
parent:
// Destroy the remote web browser due to the nsFrameLoader going away.
async __delete__();

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/dom/EffectsInfo.h"
#include "mozilla/layers/LayersMessageUtils.h"
#include "ipc/IPCMessageUtils.h"
#include "X11UndefineNone.h"
namespace mozilla {
namespace dom {
@ -94,6 +95,48 @@ struct ParamTraits<mozilla::dom::EffectsInfo> {
}
};
template <>
struct ParamTraits<mozilla::WhenToScroll>
: public ContiguousEnumSerializerInclusive<
mozilla::WhenToScroll, mozilla::WhenToScroll::Always,
mozilla::WhenToScroll::IfNotFullyVisible> {};
template <>
struct ParamTraits<mozilla::ScrollFlags>
: public BitFlagsEnumSerializer<mozilla::ScrollFlags,
mozilla::ScrollFlags::ALL_BITS> {};
template <>
struct ParamTraits<mozilla::ScrollAxis> {
typedef mozilla::ScrollAxis paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mWhereToScroll);
WriteParam(aMsg, aParam.mWhenToScroll);
WriteParam(aMsg, aParam.mOnlyIfPerceivedScrollableDirection);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (!ReadParam(aMsg, aIter, &aResult->mWhereToScroll)) {
return false;
}
if (!ReadParam(aMsg, aIter, &aResult->mWhenToScroll)) {
return false;
}
// We can't set mOnlyIfPerceivedScrollableDirection directly since it's
// a bitfield.
bool value;
if (!ReadParam(aMsg, aIter, &value)) {
return false;
}
aResult->mOnlyIfPerceivedScrollableDirection = value;
return true;
}
};
} // namespace IPC
#endif // TABMESSAGE_UTILS_H

Просмотреть файл

@ -3616,12 +3616,20 @@ bool PresShell::ScrollFrameRectIntoView(nsIFrame* aFrame, const nsRect& aRect,
}
if (!parent && !(aScrollFlags & ScrollFlags::ScrollNoParentFrames)) {
nsPoint extraOffset(0, 0);
int32_t APD = container->PresContext()->AppUnitsPerDevPixel();
parent = nsLayoutUtils::GetCrossDocParentFrame(container, &extraOffset);
if (parent) {
int32_t APD = container->PresContext()->AppUnitsPerDevPixel();
int32_t parentAPD = parent->PresContext()->AppUnitsPerDevPixel();
rect = rect.ScaleToOtherAppUnitsRoundOut(APD, parentAPD);
rect += extraOffset;
} else {
nsCOMPtr<nsIDocShell> docShell =
container->PresContext()->GetDocShell();
if (BrowserChild* browserChild = BrowserChild::GetFrom(docShell)) {
// Defer to the parent document if this is an out-of-process iframe.
Unused << browserChild->SendScrollRectIntoView(
rect, aVertical, aHorizontal, aScrollFlags, APD);
}
}
}
container = parent;

Просмотреть файл

@ -151,6 +151,7 @@ enum class ScrollFlags {
IgnoreMarginAndPadding = 1 << 6,
// ScrollOverflowHidden | ScrollNoParentFrames
AnchorScrollFlags = (1 << 1) | (1 << 2),
ALL_BITS = (1 << 7) - 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ScrollFlags)

Просмотреть файл

@ -1600,17 +1600,31 @@ nsIFrame* nsLayoutUtils::GetFloatFromPlaceholder(nsIFrame* aFrame) {
nsIFrame* nsLayoutUtils::GetCrossDocParentFrame(const nsIFrame* aFrame,
nsPoint* aExtraOffset) {
nsIFrame* p = aFrame->GetParent();
if (p) return p;
if (p) {
return p;
}
nsView* v = aFrame->GetView();
if (!v) return nullptr;
if (!v) {
return nullptr;
}
v = v->GetParent(); // anonymous inner view
if (!v) return nullptr;
if (aExtraOffset) {
*aExtraOffset += v->GetPosition();
if (!v) {
return nullptr;
}
v = v->GetParent(); // subdocumentframe's view
return v ? v->GetFrame() : nullptr;
if (!v) {
return nullptr;
}
p = v->GetFrame();
if (p && aExtraOffset) {
nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(p);
MOZ_ASSERT(subdocumentFrame);
*aExtraOffset += subdocumentFrame->GetExtraOffset();
}
return p;
}
// static

Просмотреть файл

@ -92,6 +92,7 @@ with Files('nsVideoFrame.*'):
BUG_COMPONENT = ('Core', 'Audio/Video')
EXPORTS += [
'nsAtomicContainerFrame.h',
'nsCanvasFrame.h',
'nsContainerFrame.h',
'nsDirection.h',

Просмотреть файл

@ -1285,6 +1285,11 @@ nsView* nsSubDocumentFrame::EnsureInnerView() {
return mInnerView;
}
nsPoint nsSubDocumentFrame::GetExtraOffset() const {
MOZ_ASSERT(mInnerView);
return mInnerView->GetPosition();
}
nsIFrame* nsSubDocumentFrame::ObtainIntrinsicSizeFrame() {
if (StyleDisplay()->IsContainSize()) {
// Intrinsic size of 'contain:size' replaced elements is 0,0. So, don't use

Просмотреть файл

@ -96,6 +96,7 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
nsresult BeginSwapDocShells(nsIFrame* aOther);
void EndSwapDocShells(nsIFrame* aOther);
nsView* EnsureInnerView();
nsPoint GetExtraOffset() const;
nsIFrame* GetSubdocumentRootFrame();
enum { IGNORE_PAINT_SUPPRESSION = 0x1 };
mozilla::PresShell* GetSubdocumentPresShellForPainting(uint32_t aFlags);