зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
57de429e1f
Коммит
8aa17d97ef
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче