diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index a9f8130b510d..4656d175c910 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -97,6 +97,7 @@ class gfxContext; class nsIDOMEvent; class nsDisplayList; class nsDisplayListBuilder; +class nsPIDOMWindow; typedef short SelectionType; typedef PRUint64 nsFrameState; @@ -129,8 +130,8 @@ typedef struct CapturingContentInfo { } CapturingContentInfo; #define NS_IPRESSHELL_IID \ - { 0x7ae0e29f, 0x4d2e, 0x4acd, \ - { 0xb5, 0x74, 0xb6, 0x40, 0x8a, 0xca, 0xb8, 0x4d } } + { 0x6b32e1ca, 0xb295, 0x406d, \ + { 0xb2, 0x8b, 0x73, 0xda, 0xc3, 0x66, 0xc2, 0xa7 } } // Constants for ScrollContentIntoView() function #define NS_PRESSHELL_SCROLL_TOP 0 @@ -1002,6 +1003,11 @@ public: PRUint64 GetPaintCount() { return mPaintCount; } void IncrementPaintCount() { ++mPaintCount; } + /** + * Get the root DOM window of this presShell. + */ + virtual already_AddRefed GetRootWindow() = 0; + /** * Refresh observer management. */ diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 4f35b2f2de41..27ae8785a45c 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -808,6 +808,8 @@ public: nsIntPoint& aPoint, nsIntRect* aScreenRect); + virtual already_AddRefed GetRootWindow(); + //nsIViewObserver interface NS_IMETHOD Paint(nsIView* aDisplayRoot, @@ -1247,6 +1249,7 @@ protected: private: PRBool InZombieDocument(nsIContent *aContent); + already_AddRefed GetParentPresShell(); nsresult RetargetEventToParent(nsGUIEvent* aEvent, nsEventStatus* aEventStatus); @@ -6013,8 +6016,51 @@ PRBool PresShell::InZombieDocument(nsIContent *aContent) return !doc || !doc->GetWindow(); } -nsresult PresShell::RetargetEventToParent(nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +already_AddRefed +PresShell::GetRootWindow() +{ + nsCOMPtr window = + do_QueryInterface(mDocument->GetWindow()); + if (window) { + nsCOMPtr rootWindow = window->GetPrivateRoot(); + NS_ASSERTION(rootWindow, "nsPIDOMWindow::GetPrivateRoot() returns NULL"); + return rootWindow.forget(); + } + + // If we don't have DOM window, we're zombie, we should find the root window + // with our parent shell. + nsCOMPtr parent = GetParentPresShell(); + NS_ENSURE_TRUE(parent, nsnull); + return parent->GetRootWindow(); +} + +already_AddRefed +PresShell::GetParentPresShell() +{ + NS_ENSURE_TRUE(mPresContext, nsnull); + nsCOMPtr container = mPresContext->GetContainer(); + if (!container) { + container = do_QueryReferent(mForwardingContainer); + } + + // Now, find the parent pres shell and send the event there + nsCOMPtr treeItem = do_QueryInterface(container); + // Might have gone away, or never been around to start with + NS_ENSURE_TRUE(treeItem, nsnull); + + nsCOMPtr parentTreeItem; + treeItem->GetParent(getter_AddRefs(parentTreeItem)); + nsCOMPtr parentDocShell = do_QueryInterface(parentTreeItem); + NS_ENSURE_TRUE(parentDocShell && treeItem != parentTreeItem, nsnull); + + nsIPresShell* parentPresShell = nsnull; + parentDocShell->GetPresShell(&parentPresShell); + return parentPresShell; +} + +nsresult +PresShell::RetargetEventToParent(nsGUIEvent* aEvent, + nsEventStatus* aEventStatus) { // Send this events straight up to the parent pres shell. // We do this for keystroke events in zombie documents or if either a frame @@ -6022,28 +6068,8 @@ nsresult PresShell::RetargetEventToParent(nsGUIEvent* aEvent, // That way at least the UI key bindings can work. nsCOMPtr kungFuDeathGrip(this); - nsCOMPtr container = mPresContext->GetContainer(); - if (!container) - container = do_QueryReferent(mForwardingContainer); - - // Now, find the parent pres shell and send the event there - nsCOMPtr treeItem = - do_QueryInterface(container); - if (!treeItem) { - // Might have gone away, or never been around to start with - return NS_ERROR_FAILURE; - } - - nsCOMPtr parentTreeItem; - treeItem->GetParent(getter_AddRefs(parentTreeItem)); - nsCOMPtr parentDocShell = - do_QueryInterface(parentTreeItem); - if (!parentDocShell || treeItem == parentTreeItem) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr parentPresShell; - parentDocShell->GetPresShell(getter_AddRefs(parentPresShell)); + nsCOMPtr parentPresShell = GetParentPresShell(); + NS_ENSURE_TRUE(parentPresShell, NS_ERROR_FAILURE); nsCOMPtr parentViewObserver = do_QueryInterface(parentPresShell); if (!parentViewObserver) { @@ -6069,11 +6095,7 @@ PresShell::DisableNonTestMouseEvents(PRBool aDisable) already_AddRefed PresShell::GetFocusedDOMWindowInOurWindow() { - nsCOMPtr window = - do_QueryInterface(mDocument->GetWindow()); - NS_ENSURE_TRUE(window, nsnull); - - nsCOMPtr rootWindow = window->GetPrivateRoot(); + nsCOMPtr rootWindow = GetRootWindow(); NS_ENSURE_TRUE(rootWindow, nsnull); nsPIDOMWindow* focusedWindow; nsFocusManager::GetFocusedDescendant(rootWindow, PR_TRUE, &focusedWindow);