Bug 1342297 - Add support for <iframe useContentEventHandling=true>. r=smaug
MozReview-Commit-ID: APNwd2v17PG
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1705,16 +1705,23 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
nsCOMPtr<nsPIDOMWindowOuter> ourWindow = ourDocshell->GetWindow();
nsCOMPtr<nsPIDOMWindowOuter> otherWindow = otherDocshell->GetWindow();
nsCOMPtr<Element> ourFrameElement =
ourWindow->GetFrameElementInternal();
nsCOMPtr<Element> otherFrameElement =
otherWindow->GetFrameElementInternal();
+ NS_ENSURE_STATE(ourFrameElement->AttrValueIs(kNameSpaceID_None,
+ nsGkAtoms::useContentEventHandling,
+ nsGkAtoms::_true, eCaseMatters) ==
+ otherFrameElement->AttrValueIs(kNameSpaceID_None,
+ nsGkAtoms::useContentEventHandling,
+ nsGkAtoms::_true, eCaseMatters));
+
nsCOMPtr<EventTarget> ourChromeEventHandler =
do_QueryInterface(ourWindow->GetChromeEventHandler());
nsCOMPtr<EventTarget> otherChromeEventHandler =
do_QueryInterface(otherWindow->GetChromeEventHandler());
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
nsCOMPtr<EventTarget> otherEventTarget = otherWindow->GetParentTarget();
@@ -1823,20 +1830,25 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
ourParentItem->AddChild(otherDocshell);
otherParentItem->AddChild(ourDocshell);
// Restore the correct chrome event handlers.
ourDocshell->SetChromeEventHandler(otherChromeEventHandler);
otherDocshell->SetChromeEventHandler(ourChromeEventHandler);
// Restore the correct treeowners
// (and also chrome event handlers for content frames only).
+ bool wantsContentEventHandling =
+ ourType == nsIDocShellTreeItem::typeContent ||
+ !ourFrameElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::useContentEventHandling,
+ nsGkAtoms::_true, eCaseMatters);
+
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourDocshell, otherOwner,
- ourType == nsIDocShellTreeItem::typeContent ? otherChromeEventHandler.get() : nullptr);
+ wantsContentEventHandling ? otherChromeEventHandler.get() : nullptr);
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherDocshell, ourOwner,
- ourType == nsIDocShellTreeItem::typeContent ? ourChromeEventHandler.get() : nullptr);
+ wantsContentEventHandling ? ourChromeEventHandler.get() : nullptr);
// Switch the owner content before we start calling AddTreeItemToTreeOwner.
// Note that we rely on this to deal with setting mObservingOwnerContent to
// false and calling RemoveMutationObserver as needed.
SetOwnerContent(otherContent);
aOther->SetOwnerContent(ourContent);
AddTreeItemToTreeOwner(ourDocshell, otherOwner, otherParentType, nullptr);
@@ -2341,17 +2353,19 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ENSURE_STATE(parentTreeOwner);
mIsTopLevelContent =
AddTreeItemToTreeOwner(mDocShell, parentTreeOwner, parentType, docShell);
// Make sure all shells have links back to the content element
// in the nearest enclosing chrome shell.
nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
- if (parentType == nsIDocShellTreeItem::typeChrome) {
+ if (parentType == nsIDocShellTreeItem::typeChrome &&
+ !mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::useContentEventHandling,
+ nsGkAtoms::_true, eCaseMatters)) {
// Our parent shell is a chrome shell. It is therefore our nearest
// enclosing chrome shell.
chromeEventHandler = do_QueryInterface(mOwnerContent);
NS_ASSERTION(chromeEventHandler,
"This mContent should implement this.");
} else {
// Our parent shell is a content shell. Get the chrome event
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -1285,16 +1285,17 @@ GK_ATOM(ul, "ul")
GK_ATOM(underflow, "underflow")
GK_ATOM(undetermined, "undetermined")
GK_ATOM(unload, "unload")
GK_ATOM(unparsedEntityUri, "unparsed-entity-uri")
GK_ATOM(upperFirst, "upper-first")
GK_ATOM(uri, "uri")
GK_ATOM(use, "use")
GK_ATOM(useAttributeSets, "use-attribute-sets")
+GK_ATOM(useContentEventHandling, "useContentEventHandling")
GK_ATOM(usemap, "usemap")
GK_ATOM(user_scalable, "user-scalable")
GK_ATOM(userInput, "userInput")
GK_ATOM(validate, "validate")
GK_ATOM(valign, "valign")
GK_ATOM(value, "value")
GK_ATOM(values, "values")
GK_ATOM(valueOf, "value-of")
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3770,18 +3770,20 @@ nsGlobalWindow::PostHandleEvent(EventCha
// This is page load event since load events don't propagate to |window|.
// @see nsDocument::GetEventTargetParent.
mIsDocumentLoaded = true;
mTimeoutManager->OnDocumentLoaded();
nsCOMPtr<Element> element = GetOuterWindow()->GetFrameElementInternal();
nsIDocShell* docShell = GetDocShell();
- if (element && GetParentInternal() &&
- docShell && docShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
+ if (element && GetParentInternal() && docShell &&
+ (docShell->ItemType() != nsIDocShellTreeItem::typeChrome ||
+ element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::useContentEventHandling,
+ nsGkAtoms::_true, eCaseMatters))) {
// If we're not in chrome, or at a chrome boundary, fire the
// onload event for the frame element.
nsEventStatus status = nsEventStatus_eIgnore;
WidgetEvent event(aVisitor.mEvent->IsTrusted(), eLoad);
event.mFlags.mBubbles = false;
event.mFlags.mCancelable = false;