Bug 1635784 - Part 1: IsRemoteTarget should take fission OOP iframe into account; r=smaug

And add IsTopLevelRemoteTarget for the original usage.

Differential Revision: https://phabricator.services.mozilla.com/D79441
This commit is contained in:
Edgar Chen 2020-06-18 20:38:34 +00:00
Родитель 7ecb7ebe35
Коммит 4d53288bec
9 изменённых файлов: 27 добавлений и 18 удалений

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

@ -386,7 +386,8 @@ nsINode* FocusManager::FocusedDOMNode() const {
// residing in chrome process because it means an element in content process // residing in chrome process because it means an element in content process
// keeps the focus. // keeps the focus.
if (focusedElm) { if (focusedElm) {
if (EventStateManager::IsRemoteTarget(focusedElm)) { // XXXedgar, do we need to return null if focus is in fission OOP iframe?
if (EventStateManager::IsTopLevelRemoteTarget(focusedElm)) {
return nullptr; return nullptr;
} }
return focusedElm; return focusedElm;

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

@ -6105,8 +6105,7 @@ bool nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent) {
// If the subdocument lives in another process, the frame is // If the subdocument lives in another process, the frame is
// tabbable. // tabbable.
if (EventStateManager::IsRemoteTarget(aContent) || if (EventStateManager::IsRemoteTarget(aContent)) {
BrowserBridgeChild::GetFrom(aContent)) {
return true; return true;
} }

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

@ -735,7 +735,7 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// back to this process. So, only when this process receives a reply // back to this process. So, only when this process receives a reply
// eKeyPress event in BrowserParent, we should handle accesskey in this // eKeyPress event in BrowserParent, we should handle accesskey in this
// process. // process.
if (IsRemoteTarget(GetFocusedContent())) { if (IsTopLevelRemoteTarget(GetFocusedContent())) {
// However, if there is no accesskey target for the key combination, // However, if there is no accesskey target for the key combination,
// we don't need to wait reply from the remote process. Otherwise, // we don't need to wait reply from the remote process. Otherwise,
// Mark the event as waiting reply from remote process and stop // Mark the event as waiting reply from remote process and stop
@ -789,7 +789,7 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// because PresShell needs to check if it's marked as so before // because PresShell needs to check if it's marked as so before
// dispatching events into the DOM tree. // dispatching events into the DOM tree.
if (aEvent->IsWaitingReplyFromRemoteProcess() && if (aEvent->IsWaitingReplyFromRemoteProcess() &&
!aEvent->PropagationStopped() && !IsRemoteTarget(content)) { !aEvent->PropagationStopped() && !IsTopLevelRemoteTarget(content)) {
aEvent->ResetWaitingReplyFromRemoteProcessState(); aEvent->ResetWaitingReplyFromRemoteProcessState();
} }
} break; } break;
@ -1390,6 +1390,10 @@ void EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent,
} }
bool EventStateManager::IsRemoteTarget(nsIContent* target) { bool EventStateManager::IsRemoteTarget(nsIContent* target) {
return BrowserParent::GetFrom(target) || BrowserBridgeChild::GetFrom(target);
}
bool EventStateManager::IsTopLevelRemoteTarget(nsIContent* target) {
return !!BrowserParent::GetFrom(target); return !!BrowserParent::GetFrom(target);
} }
@ -1469,8 +1473,8 @@ bool EventStateManager::HandleCrossProcessEvent(WidgetEvent* aEvent,
void EventStateManager::CreateClickHoldTimer(nsPresContext* inPresContext, void EventStateManager::CreateClickHoldTimer(nsPresContext* inPresContext,
nsIFrame* inDownFrame, nsIFrame* inDownFrame,
WidgetGUIEvent* inMouseDownEvent) { WidgetGUIEvent* inMouseDownEvent) {
if (!inMouseDownEvent->IsTrusted() || IsRemoteTarget(mGestureDownContent) || if (!inMouseDownEvent->IsTrusted() ||
sIsPointerLocked) { IsTopLevelRemoteTarget(mGestureDownContent) || sIsPointerLocked) {
return; return;
} }
@ -2881,7 +2885,7 @@ void EventStateManager::DecideGestureEvent(WidgetGestureNotifyEvent* aEvent,
// e10s - mark remote content as pannable. This is a work around since // e10s - mark remote content as pannable. This is a work around since
// we don't have access to remote frame scroll info here. Apz data may // we don't have access to remote frame scroll info here. Apz data may
// assist is solving this. // assist is solving this.
if (current && IsRemoteTarget(current->GetContent())) { if (current && IsTopLevelRemoteTarget(current->GetContent())) {
panDirection = WidgetGestureNotifyEvent::ePanBoth; panDirection = WidgetGestureNotifyEvent::ePanBoth;
// We don't know when we reach bounds, so just disable feedback for now. // We don't know when we reach bounds, so just disable feedback for now.
displayPanFeedback = false; displayPanFeedback = false;
@ -3885,7 +3889,9 @@ void EventStateManager::UpdateCursor(nsPresContext* aPresContext,
WidgetEvent* aEvent, WidgetEvent* aEvent,
nsIFrame* aTargetFrame, nsIFrame* aTargetFrame,
nsEventStatus* aStatus) { nsEventStatus* aStatus) {
if (aTargetFrame && IsRemoteTarget(aTargetFrame->GetContent())) { // XXXedgar, we should not allow to update cursor if the mouse is over a
// fission OOP iframe.
if (aTargetFrame && IsTopLevelRemoteTarget(aTargetFrame->GetContent())) {
return; return;
} }
@ -4210,7 +4216,7 @@ nsIFrame* EventStateManager::DispatchMouseOrPointerEvent(
// If we are entering/leaving remote content, dispatch a mouse enter/exit // If we are entering/leaving remote content, dispatch a mouse enter/exit
// event to the remote frame. // event to the remote frame.
if (IsRemoteTarget(targetContent)) { if (IsTopLevelRemoteTarget(targetContent)) {
if (aMessage == eMouseOut) { if (aMessage == eMouseOut) {
// For remote content, send a "top-level" widget mouse exit event. // For remote content, send a "top-level" widget mouse exit event.
UniquePtr<WidgetMouseEvent> remoteEvent = UniquePtr<WidgetMouseEvent> remoteEvent =
@ -4709,7 +4715,8 @@ void EventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
nsIContent* target = sLastDragOverFrame nsIContent* target = sLastDragOverFrame
? sLastDragOverFrame.GetFrame()->GetContent() ? sLastDragOverFrame.GetFrame()->GetContent()
: nullptr; : nullptr;
if (IsRemoteTarget(target)) { // XXXedgar, look like we need to consider fission OOP iframe, too.
if (IsTopLevelRemoteTarget(target)) {
// Dragging something and moving from web content to chrome only // Dragging something and moving from web content to chrome only
// fires dragexit and dragleave to xul:browser. We have to forward // fires dragexit and dragleave to xul:browser. We have to forward
// dragexit to sLastDragOverFrame when its content is a remote // dragexit to sLastDragOverFrame when its content is a remote

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

@ -268,7 +268,9 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
// Sets the fullscreen event state on aElement to aIsFullscreen. // Sets the fullscreen event state on aElement to aIsFullscreen.
static void SetFullscreenState(dom::Element* aElement, bool aIsFullscreen); static void SetFullscreenState(dom::Element* aElement, bool aIsFullscreen);
static bool IsRemoteTarget(nsIContent* aTarget); static bool IsRemoteTarget(nsIContent* target);
static bool IsTopLevelRemoteTarget(nsIContent* aTarget);
// Returns the kind of APZ action the given WidgetWheelEvent will perform. // Returns the kind of APZ action the given WidgetWheelEvent will perform.
static Maybe<layers::APZWheelAction> APZWheelActionFor( static Maybe<layers::APZWheelAction> APZWheelActionFor(

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

@ -375,8 +375,7 @@ nsresult IMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
nsresult IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext, nsresult IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
nsIContent* aContent, nsIContent* aContent,
InputContextAction aAction) { InputContextAction aAction) {
bool remoteHasFocus = bool remoteHasFocus = EventStateManager::IsRemoteTarget(aContent);
BrowserParent::GetFrom(aContent) || BrowserBridgeChild::GetFrom(aContent);
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Info,
("OnChangeFocusInternal(aPresContext=0x%p (available: %s), " ("OnChangeFocusInternal(aPresContext=0x%p (available: %s), "

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

@ -367,7 +367,7 @@ bool nsXULElement::IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) {
// or if it's a remote target, since the remote target must handle // or if it's a remote target, since the remote target must handle
// the focus. // the focus.
if (aWithMouse && IsNonList(mNodeInfo) && if (aWithMouse && IsNonList(mNodeInfo) &&
!EventStateManager::IsRemoteTarget(this)) { !EventStateManager::IsTopLevelRemoteTarget(this)) {
return false; return false;
} }
#endif #endif

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

@ -109,7 +109,7 @@ nsresult nsXULPopupListener::HandleEvent(Event* aEvent) {
{ {
EventTarget* originalTarget = mouseEvent->GetOriginalTarget(); EventTarget* originalTarget = mouseEvent->GetOriginalTarget();
nsCOMPtr<nsIContent> content = do_QueryInterface(originalTarget); nsCOMPtr<nsIContent> content = do_QueryInterface(originalTarget);
if (content && EventStateManager::IsRemoteTarget(content)) { if (content && EventStateManager::IsTopLevelRemoteTarget(content)) {
return NS_OK; return NS_OK;
} }
} }

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

@ -7691,8 +7691,9 @@ nsIFrame* PresShell::EventHandler::ComputeRootFrameToHandleEventWithPopup(
// If a remote browser is currently capturing input break out if we // If a remote browser is currently capturing input break out if we
// detect a chrome generated popup. // detect a chrome generated popup.
// XXXedgar, do we need to check fission OOP iframe?
if (aCapturingContent && if (aCapturingContent &&
EventStateManager::IsRemoteTarget(aCapturingContent)) { EventStateManager::IsTopLevelRemoteTarget(aCapturingContent)) {
*aIsCapturingContentIgnored = true; *aIsCapturingContentIgnored = true;
} }

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

@ -428,7 +428,7 @@ bool WidgetEvent::WillBeSentToRemoteProcess() const {
} }
nsCOMPtr<nsIContent> originalTarget = do_QueryInterface(mOriginalTarget); nsCOMPtr<nsIContent> originalTarget = do_QueryInterface(mOriginalTarget);
return EventStateManager::IsRemoteTarget(originalTarget); return EventStateManager::IsTopLevelRemoteTarget(originalTarget);
} }
bool WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const { bool WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const {