diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index c6c5a7c0db7..a2177bb11db 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2886,6 +2886,13 @@ nsDocShell::GetParent(nsIDocShellTreeItem ** aParent) return NS_OK; } +already_AddRefed +nsDocShell::GetParentDocshell() +{ + nsCOMPtr docshell = do_QueryInterface(GetAsSupports(mParent)); + return static_cast(docshell.forget().get()); +} + nsresult nsDocShell::SetDocLoaderParent(nsDocLoader * aParent) { @@ -12436,91 +12443,16 @@ nsDocShell::GetCanExecuteScripts(bool *aResult) NS_ENSURE_ARG_POINTER(aResult); *aResult = false; // disallow by default - nsCOMPtr docshell = this; - nsCOMPtr globalObjTreeItem = - do_QueryInterface(docshell); + nsRefPtr docshell = this; + do { + nsresult rv = docshell->GetAllowJavascript(aResult); + if (NS_FAILED(rv)) return rv; + if (!*aResult) { + return NS_OK; + } - if (globalObjTreeItem) - { - nsCOMPtr treeItem(globalObjTreeItem); - nsCOMPtr parentItem; - bool firstPass = true; - bool lookForParents = false; - - // Walk up the docshell tree to see if any containing docshell disallows scripts - do - { - nsresult rv = docshell->GetAllowJavascript(aResult); - if (NS_FAILED(rv)) return rv; - if (!*aResult) { - nsDocShell* realDocshell = static_cast(docshell.get()); - if (realDocshell->mContentViewer) { - nsIDocument* doc = realDocshell->mContentViewer->GetDocument(); - if (doc && doc->HasFlag(NODE_IS_EDITABLE) && - realDocshell->mEditorData) { - nsCOMPtr editSession; - realDocshell->mEditorData->GetEditingSession(getter_AddRefs(editSession)); - bool jsDisabled = false; - if (editSession && - NS_SUCCEEDED(rv = editSession->GetJsAndPluginsDisabled(&jsDisabled))) { - if (firstPass) { - if (jsDisabled) { - // We have a docshell which has been explicitly set - // to design mode, so we disallow scripts. - return NS_OK; - } - // The docshell was not explicitly set to design mode, - // so it must be so because a parent was explicitly - // set to design mode. We don't need to look at higher - // docshells. - *aResult = true; - break; - } else if (lookForParents && jsDisabled) { - // If a parent was explicitly set to design mode, - // we should allow script execution on the child. - *aResult = true; - break; - } - // If the child docshell allows scripting, and the - // parent is inside design mode, we don't need to look - // further. - *aResult = true; - return NS_OK; - } - NS_WARNING("The editing session does not work?"); - return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE; - } - if (firstPass) { - // Don't be too hard on docshells on the first pass. - // There may be a parent docshell which has been set - // to design mode, so look for it. - lookForParents = true; - } else { - // We have a docshell which disallows scripts - // and is not editable, so we shouldn't allow - // scripts at all. - return NS_OK; - } - } - } else if (lookForParents) { - // The parent docshell was not explicitly set to design - // mode, so js on the child docshell was disabled for - // another reason. Therefore, we need to disable js. - *aResult = false; - return NS_OK; - } - firstPass = false; - - treeItem->GetParent(getter_AddRefs(parentItem)); - treeItem.swap(parentItem); - docshell = do_QueryInterface(treeItem); -#ifdef DEBUG - if (treeItem && !docshell) { - NS_ERROR("cannot get a docshell from a treeItem!"); - } -#endif // DEBUG - } while (treeItem && docshell); - } + docshell = docshell->GetParentDocshell(); + } while (docshell); return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 5af0b08d754..588643b2081 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -643,6 +643,9 @@ protected: nsIChannel* GetCurrentDocChannel(); bool ShouldBlockLoadingForBackButton(); + + // Convenience method for getting our parent docshell. Can return null + already_AddRefed GetParentDocshell(); protected: // Override the parent setter from nsDocLoader virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader); diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 994f0178290..c6e629c1e6f 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -528,10 +528,7 @@ interface nsIDocShell : nsIDocShellTreeItem /** * Whether this docshell can execute scripts based on its hierarchy. * The rule of thumb here is that we disable js if this docshell or any - * of its parents disallow scripting, unless the only reason for js being - * disabled in this docshell is a parent docshell having a document that - * is in design mode. In that case, we explicitly allow scripting on the - * current docshell. + * of its parents disallow scripting. */ readonly attribute boolean canExecuteScripts; diff --git a/editor/composer/test/test_bug519928.html b/editor/composer/test/test_bug519928.html index 71d5288bedf..545ec4551f0 100644 --- a/editor/composer/test/test_bug519928.html +++ b/editor/composer/test/test_bug519928.html @@ -65,7 +65,7 @@ addLoadEvent(function() { expectJSAllowed(true, enterDesignMode, function() { expectJSAllowed(true, leaveDesignMode, function() { expectJSAllowed(false, disableJS, function() { - expectJSAllowed(true, enterDesignMode, function() { + expectJSAllowed(false, enterDesignMode, function() { expectJSAllowed(false, leaveDesignMode, function() { expectJSAllowed(true, enableJS, function() { testDocumentDisabledJS(); @@ -94,7 +94,7 @@ function testDocumentDisabledJS() { document.designMode = "off"; iframe.contentDocument.designMode = "off"; - // Javascriont enabled on the main iframe + // Javascript enabled on the main iframe enableJS(); var doc = iframe.contentDocument;