summaryrefslogtreecommitdiffstats
path: root/embedding/browser
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /embedding/browser
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'embedding/browser')
-rw-r--r--embedding/browser/build/moz.build14
-rw-r--r--embedding/browser/build/nsWebBrowserModule.cpp53
-rw-r--r--embedding/browser/moz.build57
-rw-r--r--embedding/browser/nsCTooltipTextProvider.h17
-rw-r--r--embedding/browser/nsCWebBrowser.idl34
-rw-r--r--embedding/browser/nsCommandHandler.cpp139
-rw-r--r--embedding/browser/nsCommandHandler.h35
-rw-r--r--embedding/browser/nsContextMenuInfo.cpp326
-rw-r--r--embedding/browser/nsContextMenuInfo.h54
-rw-r--r--embedding/browser/nsDocShellTreeOwner.cpp1674
-rw-r--r--embedding/browser/nsDocShellTreeOwner.h246
-rw-r--r--embedding/browser/nsEmbedStream.cpp101
-rw-r--r--embedding/browser/nsEmbedStream.h37
-rw-r--r--embedding/browser/nsICommandHandler.idl40
-rw-r--r--embedding/browser/nsIContextMenuListener.idl65
-rw-r--r--embedding/browser/nsIContextMenuListener2.idl121
-rw-r--r--embedding/browser/nsIEmbeddingSiteWindow.idl157
-rw-r--r--embedding/browser/nsIPrintPreviewNavigation.idl52
-rw-r--r--embedding/browser/nsIPrintingPromptService.idl165
-rw-r--r--embedding/browser/nsITooltipListener.idl44
-rw-r--r--embedding/browser/nsITooltipTextProvider.idl44
-rw-r--r--embedding/browser/nsIWebBrowser.idl163
-rw-r--r--embedding/browser/nsIWebBrowserChrome.idl147
-rw-r--r--embedding/browser/nsIWebBrowserChrome2.idl33
-rw-r--r--embedding/browser/nsIWebBrowserChrome3.idl61
-rw-r--r--embedding/browser/nsIWebBrowserChromeFocus.idl32
-rw-r--r--embedding/browser/nsIWebBrowserFocus.idl76
-rw-r--r--embedding/browser/nsIWebBrowserPrint.idl152
-rw-r--r--embedding/browser/nsIWebBrowserSetup.idl109
-rw-r--r--embedding/browser/nsIWebBrowserStream.idl56
-rw-r--r--embedding/browser/nsWebBrowser.cpp1952
-rw-r--r--embedding/browser/nsWebBrowser.h185
-rw-r--r--embedding/browser/nsWebBrowserContentPolicy.cpp108
-rw-r--r--embedding/browser/nsWebBrowserContentPolicy.h26
34 files changed, 6575 insertions, 0 deletions
diff --git a/embedding/browser/build/moz.build b/embedding/browser/build/moz.build
new file mode 100644
index 000000000..cdd0f5a76
--- /dev/null
+++ b/embedding/browser/build/moz.build
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ 'nsWebBrowserModule.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+LOCAL_INCLUDES += [
+ '..',
+]
diff --git a/embedding/browser/build/nsWebBrowserModule.cpp b/embedding/browser/build/nsWebBrowserModule.cpp
new file mode 100644
index 000000000..a061a2b43
--- /dev/null
+++ b/embedding/browser/build/nsWebBrowserModule.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ModuleUtils.h"
+#include "nsIServiceManager.h"
+#include "nsXPIDLString.h"
+
+#include "nsEmbedCID.h"
+
+#include "nsWebBrowser.h"
+#include "nsCommandHandler.h"
+#include "nsWebBrowserContentPolicy.h"
+
+// Factory Constructors
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowser)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowserContentPolicy)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsCommandHandler)
+
+NS_DEFINE_NAMED_CID(NS_WEBBROWSER_CID);
+NS_DEFINE_NAMED_CID(NS_COMMANDHANDLER_CID);
+NS_DEFINE_NAMED_CID(NS_WEBBROWSERCONTENTPOLICY_CID);
+
+static const mozilla::Module::CIDEntry kWebBrowserCIDs[] = {
+ { &kNS_WEBBROWSER_CID, false, nullptr, nsWebBrowserConstructor },
+ { &kNS_COMMANDHANDLER_CID, false, nullptr, nsCommandHandlerConstructor },
+ { &kNS_WEBBROWSERCONTENTPOLICY_CID, false, nullptr, nsWebBrowserContentPolicyConstructor },
+ { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kWebBrowserContracts[] = {
+ { NS_WEBBROWSER_CONTRACTID, &kNS_WEBBROWSER_CID },
+ { NS_COMMANDHANDLER_CONTRACTID, &kNS_COMMANDHANDLER_CID },
+ { NS_WEBBROWSERCONTENTPOLICY_CONTRACTID, &kNS_WEBBROWSERCONTENTPOLICY_CID },
+ { nullptr }
+};
+
+static const mozilla::Module::CategoryEntry kWebBrowserCategories[] = {
+ { "content-policy", NS_WEBBROWSERCONTENTPOLICY_CONTRACTID, NS_WEBBROWSERCONTENTPOLICY_CONTRACTID },
+ { nullptr }
+};
+
+static const mozilla::Module kWebBrowserModule = {
+ mozilla::Module::kVersion,
+ kWebBrowserCIDs,
+ kWebBrowserContracts,
+ kWebBrowserCategories
+};
+
+NSMODULE_DEFN(Browser_Embedding_Module) = &kWebBrowserModule;
diff --git a/embedding/browser/moz.build b/embedding/browser/moz.build
new file mode 100644
index 000000000..179a6b6c8
--- /dev/null
+++ b/embedding/browser/moz.build
@@ -0,0 +1,57 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ['build']
+
+XPIDL_SOURCES += [
+ 'nsCWebBrowser.idl',
+ 'nsICommandHandler.idl',
+ 'nsIContextMenuListener.idl',
+ 'nsIContextMenuListener2.idl',
+ 'nsIEmbeddingSiteWindow.idl',
+ 'nsITooltipListener.idl',
+ 'nsITooltipTextProvider.idl',
+ 'nsIWebBrowser.idl',
+ 'nsIWebBrowserChrome.idl',
+ 'nsIWebBrowserChrome2.idl',
+ 'nsIWebBrowserChrome3.idl',
+ 'nsIWebBrowserChromeFocus.idl',
+ 'nsIWebBrowserFocus.idl',
+ 'nsIWebBrowserSetup.idl',
+ 'nsIWebBrowserStream.idl',
+]
+
+if CONFIG['NS_PRINTING']:
+ XPIDL_SOURCES += [
+ 'nsIPrintingPromptService.idl',
+ 'nsIWebBrowserPrint.idl',
+ ]
+
+XPIDL_MODULE = 'webBrowser_core'
+
+EXPORTS += [
+ 'nsCTooltipTextProvider.h',
+]
+
+UNIFIED_SOURCES += [
+ 'nsCommandHandler.cpp',
+ 'nsContextMenuInfo.cpp',
+ 'nsDocShellTreeOwner.cpp',
+ 'nsEmbedStream.cpp',
+ 'nsWebBrowser.cpp',
+ 'nsWebBrowserContentPolicy.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+LOCAL_INCLUDES += [
+ '/docshell/base',
+ '/dom/base',
+ '/dom/svg',
+ '/layout/style',
+]
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
diff --git a/embedding/browser/nsCTooltipTextProvider.h b/embedding/browser/nsCTooltipTextProvider.h
new file mode 100644
index 000000000..95fb00432
--- /dev/null
+++ b/embedding/browser/nsCTooltipTextProvider.h
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NSCTOOLTIPTEXTPROVIDER_H
+#define NSCTOOLTIPTEXTPROVIDER_H
+
+#include "nsITooltipTextProvider.h"
+
+#define NS_TOOLTIPTEXTPROVIDER_CONTRACTID \
+ "@mozilla.org/embedcomp/tooltiptextprovider;1"
+#define NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID \
+ "@mozilla.org/embedcomp/default-tooltiptextprovider;1"
+
+#endif
diff --git a/embedding/browser/nsCWebBrowser.idl b/embedding/browser/nsCWebBrowser.idl
new file mode 100644
index 000000000..21927f7c7
--- /dev/null
+++ b/embedding/browser/nsCWebBrowser.idl
@@ -0,0 +1,34 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIWebBrowser.idl"
+#include "nsIBaseWindow.idl"
+#include "nsIScrollable.idl"
+#include "nsITextScroll.idl"
+
+/*
+nsCWebBrowser implements:
+-------------------------
+nsIWebBrowser
+nsIDocShellTreeItem
+nsIWebNavigation
+nsIWebProgress
+nsIBaseWindow
+nsIScrollable
+nsITextScroll
+nsIInterfaceRequestor
+
+
+Outwardly communicates with:
+----------------------------
+nsIWebBrowserChrome
+nsIBaseWindow
+nsIInterfaceRequestor
+*/
+
+%{ C++
+#include "nsEmbedCID.h"
+%}
diff --git a/embedding/browser/nsCommandHandler.cpp b/embedding/browser/nsCommandHandler.cpp
new file mode 100644
index 000000000..1e41e265a
--- /dev/null
+++ b/embedding/browser/nsCommandHandler.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCommandHandler.h"
+#include "nsWebBrowser.h"
+#include "nsDocShellTreeOwner.h"
+
+#include "nsMemory.h"
+#include "nsPIDOMWindow.h"
+
+nsCommandHandler::nsCommandHandler()
+ : mWindow(nullptr)
+{
+}
+
+nsCommandHandler::~nsCommandHandler()
+{
+}
+
+nsresult
+nsCommandHandler::GetCommandHandler(nsICommandHandler** aCommandHandler)
+{
+ NS_ENSURE_ARG_POINTER(aCommandHandler);
+
+ *aCommandHandler = nullptr;
+ if (!mWindow) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Get the document tree owner
+
+ nsCOMPtr<nsIDocShellTreeItem> docShellAsTreeItem =
+ do_QueryInterface(mWindow->GetDocShell());
+ nsIDocShellTreeOwner* treeOwner = nullptr;
+ docShellAsTreeItem->GetTreeOwner(&treeOwner);
+
+ // Make sure the tree owner is an an nsDocShellTreeOwner object
+ // by QI'ing for a hidden interface. If it doesn't have the interface
+ // then it's not safe to do the casting.
+
+ nsCOMPtr<nsICDocShellTreeOwner> realTreeOwner(do_QueryInterface(treeOwner));
+ if (realTreeOwner) {
+ nsDocShellTreeOwner* tree = static_cast<nsDocShellTreeOwner*>(treeOwner);
+ if (tree->mTreeOwner) {
+ nsresult rv;
+ rv = tree->mTreeOwner->QueryInterface(NS_GET_IID(nsICommandHandler),
+ (void**)aCommandHandler);
+ NS_RELEASE(treeOwner);
+ return rv;
+ }
+
+ NS_RELEASE(treeOwner);
+ }
+
+ *aCommandHandler = nullptr;
+
+ return NS_OK;
+}
+
+NS_IMPL_ADDREF(nsCommandHandler)
+NS_IMPL_RELEASE(nsCommandHandler)
+
+NS_INTERFACE_MAP_BEGIN(nsCommandHandler)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandHandler)
+ NS_INTERFACE_MAP_ENTRY(nsICommandHandlerInit)
+ NS_INTERFACE_MAP_ENTRY(nsICommandHandler)
+NS_INTERFACE_MAP_END
+
+///////////////////////////////////////////////////////////////////////////////
+// nsICommandHandlerInit implementation
+
+NS_IMETHODIMP
+nsCommandHandler::GetWindow(mozIDOMWindowProxy** aWindow)
+{
+ *aWindow = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCommandHandler::SetWindow(mozIDOMWindowProxy* aWindow)
+{
+ if (!aWindow) {
+ return NS_ERROR_FAILURE;
+ }
+ mWindow = nsPIDOMWindowOuter::From(aWindow);
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsICommandHandler implementation
+
+NS_IMETHODIMP
+nsCommandHandler::Exec(const char* aCommand, const char* aStatus,
+ char** aResult)
+{
+ NS_ENSURE_ARG_POINTER(aCommand);
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ nsCOMPtr<nsICommandHandler> commandHandler;
+ GetCommandHandler(getter_AddRefs(commandHandler));
+
+ // Call the client's command handler to deal with this command
+ if (commandHandler) {
+ *aResult = nullptr;
+ return commandHandler->Exec(aCommand, aStatus, aResult);
+ }
+
+ // Return an empty string
+ const char szEmpty[] = "";
+ *aResult = (char*)nsMemory::Clone(szEmpty, sizeof(szEmpty));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCommandHandler::Query(const char* aCommand, const char* aStatus,
+ char** aResult)
+{
+ NS_ENSURE_ARG_POINTER(aCommand);
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ nsCOMPtr<nsICommandHandler> commandHandler;
+ GetCommandHandler(getter_AddRefs(commandHandler));
+
+ // Call the client's command handler to deal with this command
+ if (commandHandler) {
+ *aResult = nullptr;
+ return commandHandler->Query(aCommand, aStatus, aResult);
+ }
+
+ // Return an empty string
+ const char szEmpty[] = "";
+ *aResult = (char*)nsMemory::Clone(szEmpty, sizeof(szEmpty));
+
+ return NS_OK;
+}
diff --git a/embedding/browser/nsCommandHandler.h b/embedding/browser/nsCommandHandler.h
new file mode 100644
index 000000000..3d229b9d6
--- /dev/null
+++ b/embedding/browser/nsCommandHandler.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NSCOMMANDHANDLER_H
+#define NSCOMMANDHANDLER_H
+
+#include "nsISupports.h"
+#include "nsICommandHandler.h"
+
+class nsPIDOMWindowOuter;
+
+class nsCommandHandler
+ : public nsICommandHandlerInit
+ , public nsICommandHandler
+{
+public:
+ nsCommandHandler();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICOMMANDHANDLERINIT
+ NS_DECL_NSICOMMANDHANDLER
+
+protected:
+ virtual ~nsCommandHandler();
+
+private:
+ nsresult GetCommandHandler(nsICommandHandler** aCommandHandler);
+
+ nsPIDOMWindowOuter* mWindow;
+};
+
+#endif
diff --git a/embedding/browser/nsContextMenuInfo.cpp b/embedding/browser/nsContextMenuInfo.cpp
new file mode 100644
index 000000000..5052dda65
--- /dev/null
+++ b/embedding/browser/nsContextMenuInfo.cpp
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsContextMenuInfo.h"
+
+#include "nsIImageLoadingContent.h"
+#include "imgLoader.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMHTMLDocument.h"
+#include "nsIDOMHTMLElement.h"
+#include "nsIDOMHTMLHtmlElement.h"
+#include "nsIDOMHTMLAnchorElement.h"
+#include "nsIDOMHTMLImageElement.h"
+#include "nsIDOMHTMLAreaElement.h"
+#include "nsIDOMHTMLLinkElement.h"
+#include "nsIDOMWindow.h"
+#include "nsICSSDeclaration.h"
+#include "nsIDOMCSSValue.h"
+#include "nsIDOMCSSPrimitiveValue.h"
+#include "nsNetUtil.h"
+#include "nsUnicharUtils.h"
+#include "nsIDocument.h"
+#include "nsIPrincipal.h"
+#include "nsIContentSecurityPolicy.h"
+#include "nsIContentPolicy.h"
+#include "imgRequestProxy.h"
+
+using mozilla::dom::Element;
+using mozilla::ErrorResult;
+
+NS_IMPL_ISUPPORTS(nsContextMenuInfo, nsIContextMenuInfo)
+
+nsContextMenuInfo::nsContextMenuInfo()
+{
+}
+
+nsContextMenuInfo::~nsContextMenuInfo()
+{
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetMouseEvent(nsIDOMEvent** aEvent)
+{
+ NS_ENSURE_ARG_POINTER(aEvent);
+ NS_IF_ADDREF(*aEvent = mMouseEvent);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetTargetNode(nsIDOMNode** aNode)
+{
+ NS_ENSURE_ARG_POINTER(aNode);
+ NS_IF_ADDREF(*aNode = mDOMNode);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
+{
+ NS_ENSURE_STATE(mAssociatedLink);
+ aHRef.Truncate(0);
+
+ nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
+ nsAutoString localName;
+ if (content) {
+ content->GetLocalName(localName);
+ }
+
+ nsCOMPtr<nsIDOMElement> linkContent;
+ ToLowerCase(localName);
+ if (localName.EqualsLiteral("a") ||
+ localName.EqualsLiteral("area") ||
+ localName.EqualsLiteral("link")) {
+ bool hasAttr;
+ content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
+ if (hasAttr) {
+ linkContent = content;
+ nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
+ if (anchor) {
+ anchor->GetHref(aHRef);
+ } else {
+ nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
+ if (area) {
+ area->GetHref(aHRef);
+ } else {
+ nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
+ if (link) {
+ link->GetHref(aHRef);
+ }
+ }
+ }
+ }
+ } else {
+ nsCOMPtr<nsIDOMNode> curr;
+ mAssociatedLink->GetParentNode(getter_AddRefs(curr));
+ while (curr) {
+ content = do_QueryInterface(curr);
+ if (!content) {
+ break;
+ }
+ content->GetLocalName(localName);
+ ToLowerCase(localName);
+ if (localName.EqualsLiteral("a")) {
+ bool hasAttr;
+ content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
+ if (hasAttr) {
+ linkContent = content;
+ nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(
+ do_QueryInterface(linkContent));
+ if (anchor) {
+ anchor->GetHref(aHRef);
+ }
+ } else {
+ linkContent = nullptr; // Links can't be nested.
+ }
+ break;
+ }
+
+ nsCOMPtr<nsIDOMNode> temp = curr;
+ temp->GetParentNode(getter_AddRefs(curr));
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetImageContainer(imgIContainer** aImageContainer)
+{
+ NS_ENSURE_ARG_POINTER(aImageContainer);
+ NS_ENSURE_STATE(mDOMNode);
+
+ nsCOMPtr<imgIRequest> request;
+ GetImageRequest(mDOMNode, getter_AddRefs(request));
+ if (request) {
+ return request->GetImage(aImageContainer);
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetImageSrc(nsIURI** aURI)
+{
+ NS_ENSURE_ARG_POINTER(aURI);
+ NS_ENSURE_STATE(mDOMNode);
+
+ nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
+ NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
+ return content->GetCurrentURI(aURI);
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetBackgroundImageContainer(imgIContainer** aImageContainer)
+{
+ NS_ENSURE_ARG_POINTER(aImageContainer);
+ NS_ENSURE_STATE(mDOMNode);
+
+ RefPtr<imgRequestProxy> request;
+ GetBackgroundImageRequest(mDOMNode, getter_AddRefs(request));
+ if (request) {
+ return request->GetImage(aImageContainer);
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsContextMenuInfo::GetBackgroundImageSrc(nsIURI** aURI)
+{
+ NS_ENSURE_ARG_POINTER(aURI);
+ NS_ENSURE_STATE(mDOMNode);
+
+ RefPtr<imgRequestProxy> request;
+ GetBackgroundImageRequest(mDOMNode, getter_AddRefs(request));
+ if (request) {
+ return request->GetURI(aURI);
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+nsresult
+nsContextMenuInfo::GetImageRequest(nsIDOMNode* aDOMNode, imgIRequest** aRequest)
+{
+ NS_ENSURE_ARG(aDOMNode);
+ NS_ENSURE_ARG_POINTER(aRequest);
+
+ // Get content
+ nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aDOMNode));
+ NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
+
+ return content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, aRequest);
+}
+
+bool
+nsContextMenuInfo::HasBackgroundImage(nsIDOMNode* aDOMNode)
+{
+ NS_ENSURE_TRUE(aDOMNode, false);
+
+ RefPtr<imgRequestProxy> request;
+ GetBackgroundImageRequest(aDOMNode, getter_AddRefs(request));
+
+ return (request != nullptr);
+}
+
+nsresult
+nsContextMenuInfo::GetBackgroundImageRequest(nsIDOMNode* aDOMNode,
+ imgRequestProxy** aRequest)
+{
+
+ NS_ENSURE_ARG(aDOMNode);
+ NS_ENSURE_ARG_POINTER(aRequest);
+
+ nsCOMPtr<nsIDOMNode> domNode = aDOMNode;
+
+ // special case for the <html> element: if it has no background-image
+ // we'll defer to <body>
+ nsCOMPtr<nsIDOMHTMLHtmlElement> htmlElement = do_QueryInterface(domNode);
+ if (htmlElement) {
+ nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(domNode);
+ nsAutoString nameSpace;
+ element->GetNamespaceURI(nameSpace);
+ if (nameSpace.IsEmpty()) {
+ nsresult rv = GetBackgroundImageRequestInternal(domNode, aRequest);
+ if (NS_SUCCEEDED(rv) && *aRequest) {
+ return NS_OK;
+ }
+
+ // no background-image found
+ nsCOMPtr<nsIDOMDocument> document;
+ domNode->GetOwnerDocument(getter_AddRefs(document));
+ nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(document));
+ NS_ENSURE_TRUE(htmlDocument, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIDOMHTMLElement> body;
+ htmlDocument->GetBody(getter_AddRefs(body));
+ domNode = do_QueryInterface(body);
+ NS_ENSURE_TRUE(domNode, NS_ERROR_FAILURE);
+ }
+ }
+ return GetBackgroundImageRequestInternal(domNode, aRequest);
+}
+
+nsresult
+nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode* aDOMNode,
+ imgRequestProxy** aRequest)
+{
+ NS_ENSURE_ARG_POINTER(aDOMNode);
+
+ nsCOMPtr<nsIDOMNode> domNode = aDOMNode;
+ nsCOMPtr<nsIDOMNode> parentNode;
+
+ nsCOMPtr<nsIDOMDocument> document;
+ domNode->GetOwnerDocument(getter_AddRefs(document));
+ NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
+
+ nsCOMPtr<mozIDOMWindowProxy> window;
+ document->GetDefaultView(getter_AddRefs(window));
+ NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+ auto* piWindow = nsPIDOMWindowOuter::From(window);
+ nsPIDOMWindowInner* innerWindow = piWindow->GetCurrentInnerWindow();
+ MOZ_ASSERT(innerWindow);
+
+ nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
+ nsAutoString bgStringValue;
+
+ nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
+ nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;
+
+ while (true) {
+ nsCOMPtr<Element> domElement(do_QueryInterface(domNode));
+ // bail for the parent node of the root element or null argument
+ if (!domElement) {
+ break;
+ }
+
+ ErrorResult dummy;
+ nsCOMPtr<nsICSSDeclaration> computedStyle =
+ innerWindow->GetComputedStyle(*domElement, EmptyString(), dummy);
+ dummy.SuppressException();
+ if (computedStyle) {
+ nsCOMPtr<nsIDOMCSSValue> cssValue;
+ computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-image"),
+ getter_AddRefs(cssValue));
+ primitiveValue = do_QueryInterface(cssValue);
+ if (primitiveValue) {
+ primitiveValue->GetStringValue(bgStringValue);
+ if (!bgStringValue.EqualsLiteral("none")) {
+ nsCOMPtr<nsIURI> bgUri;
+ NS_NewURI(getter_AddRefs(bgUri), bgStringValue);
+ NS_ENSURE_TRUE(bgUri, NS_ERROR_FAILURE);
+
+ imgLoader* il = imgLoader::NormalLoader();
+ NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
+
+ return il->LoadImage(bgUri, nullptr, nullptr,
+ doc->GetReferrerPolicy(), principal, nullptr,
+ nullptr, nullptr, nullptr, nsIRequest::LOAD_NORMAL,
+ nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
+ EmptyString(), aRequest);
+ }
+ }
+
+ // bail if we encounter non-transparent background-color
+ computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
+ getter_AddRefs(cssValue));
+ primitiveValue = do_QueryInterface(cssValue);
+ if (primitiveValue) {
+ primitiveValue->GetStringValue(bgStringValue);
+ if (!bgStringValue.EqualsLiteral("transparent")) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+ }
+
+ domNode->GetParentNode(getter_AddRefs(parentNode));
+ domNode = parentNode;
+ }
+
+ return NS_ERROR_FAILURE;
+}
diff --git a/embedding/browser/nsContextMenuInfo.h b/embedding/browser/nsContextMenuInfo.h
new file mode 100644
index 000000000..998045f97
--- /dev/null
+++ b/embedding/browser/nsContextMenuInfo.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsContextMenuInfo_h__
+#define nsContextMenuInfo_h__
+
+#include "nsCOMPtr.h"
+#include "nsIContextMenuListener2.h"
+#include "nsIDOMNode.h"
+#include "nsIDOMEvent.h"
+#include "imgIContainer.h"
+#include "imgIRequest.h"
+
+class ChromeContextMenuListener;
+class imgRequestProxy;
+
+// Helper class for implementors of nsIContextMenuListener2
+class nsContextMenuInfo : public nsIContextMenuInfo
+{
+ friend class ChromeContextMenuListener;
+
+public:
+ nsContextMenuInfo();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICONTEXTMENUINFO
+
+private:
+ virtual ~nsContextMenuInfo();
+
+ void SetMouseEvent(nsIDOMEvent* aEvent) { mMouseEvent = aEvent; }
+ void SetDOMNode(nsIDOMNode* aNode) { mDOMNode = aNode; }
+ void SetAssociatedLink(nsIDOMNode* aLink) { mAssociatedLink = aLink; }
+
+ nsresult GetImageRequest(nsIDOMNode* aDOMNode, imgIRequest** aRequest);
+
+ bool HasBackgroundImage(nsIDOMNode* aDOMNode);
+
+ nsresult GetBackgroundImageRequest(nsIDOMNode* aDOMNode,
+ imgRequestProxy** aRequest);
+
+ nsresult GetBackgroundImageRequestInternal(nsIDOMNode* aDOMNode,
+ imgRequestProxy** aRequest);
+
+private:
+ nsCOMPtr<nsIDOMEvent> mMouseEvent;
+ nsCOMPtr<nsIDOMNode> mDOMNode;
+ nsCOMPtr<nsIDOMNode> mAssociatedLink;
+};
+
+#endif // nsContextMenuInfo_h__
diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp
new file mode 100644
index 000000000..73397cc8b
--- /dev/null
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -0,0 +1,1674 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Local Includes
+#include "nsDocShellTreeOwner.h"
+#include "nsWebBrowser.h"
+
+// Helper Classes
+#include "nsStyleCoord.h"
+#include "nsSize.h"
+#include "mozilla/ReflowInput.h"
+#include "nsIServiceManager.h"
+#include "nsComponentManagerUtils.h"
+#include "nsXPIDLString.h"
+#include "nsIAtom.h"
+#include "nsReadableUtils.h"
+#include "nsUnicharUtils.h"
+#include "nsISimpleEnumerator.h"
+#include "mozilla/LookAndFeel.h"
+
+// Interfaces needed to be included
+#include "nsPresContext.h"
+#include "nsIContextMenuListener.h"
+#include "nsIContextMenuListener2.h"
+#include "nsITooltipListener.h"
+#include "nsIDOMNode.h"
+#include "nsIDOMNodeList.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMDocumentType.h"
+#include "nsIDOMElement.h"
+#include "Link.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/SVGTitleElement.h"
+#include "nsIDOMEvent.h"
+#include "nsIDOMFileList.h"
+#include "nsIDOMMouseEvent.h"
+#include "nsIFormControl.h"
+#include "nsIDOMHTMLInputElement.h"
+#include "nsIDOMHTMLTextAreaElement.h"
+#include "nsIDOMHTMLHtmlElement.h"
+#include "nsIDOMHTMLAppletElement.h"
+#include "nsIDOMHTMLObjectElement.h"
+#include "nsIDOMHTMLEmbedElement.h"
+#include "nsIDOMHTMLDocument.h"
+#include "nsIImageLoadingContent.h"
+#include "nsIWebNavigation.h"
+#include "nsIDOMHTMLElement.h"
+#include "nsIPresShell.h"
+#include "nsIStringBundle.h"
+#include "nsPIDOMWindow.h"
+#include "nsPIWindowRoot.h"
+#include "nsIDOMWindowCollection.h"
+#include "nsIWindowWatcher.h"
+#include "nsPIWindowWatcher.h"
+#include "nsIPrompt.h"
+#include "nsITabParent.h"
+#include "nsITabChild.h"
+#include "nsRect.h"
+#include "nsIWebBrowserChromeFocus.h"
+#include "nsIContent.h"
+#include "imgIContainer.h"
+#include "nsContextMenuInfo.h"
+#include "nsPresContext.h"
+#include "nsViewManager.h"
+#include "nsView.h"
+#include "nsIDOMDragEvent.h"
+#include "nsIConstraintValidation.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/EventListenerManager.h"
+#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/File.h" // for input type=file
+#include "mozilla/dom/FileList.h" // for input type=file
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// A helper routine that navigates the tricky path from a |nsWebBrowser| to
+// a |EventTarget| via the window root and chrome event handler.
+static nsresult
+GetDOMEventTarget(nsWebBrowser* aInBrowser, EventTarget** aTarget)
+{
+ if (!aInBrowser) {
+ return NS_ERROR_INVALID_POINTER;
+ }
+
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ aInBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (!domWindow) {
+ return NS_ERROR_FAILURE;
+ }
+
+ auto* outerWindow = nsPIDOMWindowOuter::From(domWindow);
+ nsPIDOMWindowOuter* rootWindow = outerWindow->GetPrivateRoot();
+ NS_ENSURE_TRUE(rootWindow, NS_ERROR_FAILURE);
+ nsCOMPtr<EventTarget> target = rootWindow->GetChromeEventHandler();
+ NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
+ target.forget(aTarget);
+
+ return NS_OK;
+}
+
+nsDocShellTreeOwner::nsDocShellTreeOwner()
+ : mWebBrowser(nullptr)
+ , mTreeOwner(nullptr)
+ , mPrimaryContentShell(nullptr)
+ , mWebBrowserChrome(nullptr)
+ , mOwnerWin(nullptr)
+ , mOwnerRequestor(nullptr)
+{
+}
+
+nsDocShellTreeOwner::~nsDocShellTreeOwner()
+{
+ RemoveChromeListeners();
+}
+
+NS_IMPL_ADDREF(nsDocShellTreeOwner)
+NS_IMPL_RELEASE(nsDocShellTreeOwner)
+
+NS_INTERFACE_MAP_BEGIN(nsDocShellTreeOwner)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
+ NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
+ NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+ NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
+ NS_INTERFACE_MAP_ENTRY(nsICDocShellTreeOwner)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+NS_INTERFACE_MAP_END
+
+//*****************************************************************************
+// nsDocShellTreeOwner::nsIInterfaceRequestor
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetInterface(const nsIID& aIID, void** aSink)
+{
+ NS_ENSURE_ARG_POINTER(aSink);
+
+ if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) {
+ return NS_OK;
+ }
+
+ if (aIID.Equals(NS_GET_IID(nsIWebBrowserChromeFocus))) {
+ if (mWebBrowserChromeWeak != nullptr) {
+ return mWebBrowserChromeWeak->QueryReferent(aIID, aSink);
+ }
+ return mOwnerWin->QueryInterface(aIID, aSink);
+ }
+
+ if (aIID.Equals(NS_GET_IID(nsIPrompt))) {
+ nsCOMPtr<nsIPrompt> prompt;
+ EnsurePrompter();
+ prompt = mPrompter;
+ if (prompt) {
+ prompt.forget(aSink);
+ return NS_OK;
+ }
+ return NS_NOINTERFACE;
+ }
+
+ if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
+ nsCOMPtr<nsIAuthPrompt> prompt;
+ EnsureAuthPrompter();
+ prompt = mAuthPrompter;
+ if (prompt) {
+ prompt.forget(aSink);
+ return NS_OK;
+ }
+ return NS_NOINTERFACE;
+ }
+
+ nsCOMPtr<nsIInterfaceRequestor> req = GetOwnerRequestor();
+ if (req) {
+ return req->GetInterface(aIID, aSink);
+ }
+
+ return NS_NOINTERFACE;
+}
+
+//*****************************************************************************
+// nsDocShellTreeOwner::nsIDocShellTreeOwner
+//*****************************************************************************
+
+void
+nsDocShellTreeOwner::EnsurePrompter()
+{
+ if (mPrompter) {
+ return;
+ }
+
+ nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
+ if (wwatch && mWebBrowser) {
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (domWindow) {
+ wwatch->GetNewPrompter(domWindow, getter_AddRefs(mPrompter));
+ }
+ }
+}
+
+void
+nsDocShellTreeOwner::EnsureAuthPrompter()
+{
+ if (mAuthPrompter) {
+ return;
+ }
+
+ nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
+ if (wwatch && mWebBrowser) {
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (domWindow) {
+ wwatch->GetNewAuthPrompter(domWindow, getter_AddRefs(mAuthPrompter));
+ }
+ }
+}
+
+void
+nsDocShellTreeOwner::AddToWatcher()
+{
+ if (mWebBrowser) {
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (domWindow) {
+ nsCOMPtr<nsPIWindowWatcher> wwatch(
+ do_GetService(NS_WINDOWWATCHER_CONTRACTID));
+ if (wwatch) {
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+ if (webBrowserChrome) {
+ wwatch->AddWindow(domWindow, webBrowserChrome);
+ }
+ }
+ }
+ }
+}
+
+void
+nsDocShellTreeOwner::RemoveFromWatcher()
+{
+ if (mWebBrowser) {
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (domWindow) {
+ nsCOMPtr<nsPIWindowWatcher> wwatch(
+ do_GetService(NS_WINDOWWATCHER_CONTRACTID));
+ if (wwatch) {
+ wwatch->RemoveWindow(domWindow);
+ }
+ }
+ }
+}
+
+void
+nsDocShellTreeOwner::EnsureContentTreeOwner()
+{
+ if (mContentTreeOwner) {
+ return;
+ }
+
+ mContentTreeOwner = new nsDocShellTreeOwner();
+ nsCOMPtr<nsIWebBrowserChrome> browserChrome = GetWebBrowserChrome();
+ if (browserChrome) {
+ mContentTreeOwner->SetWebBrowserChrome(browserChrome);
+ }
+
+ if (mWebBrowser) {
+ mContentTreeOwner->WebBrowser(mWebBrowser);
+ }
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
+ bool aPrimary, bool aTargetable,
+ const nsAString& aID)
+{
+ if (mTreeOwner)
+ return mTreeOwner->ContentShellAdded(aContentShell, aPrimary, aTargetable,
+ aID);
+
+ EnsureContentTreeOwner();
+ aContentShell->SetTreeOwner(mContentTreeOwner);
+
+ if (aPrimary) {
+ mPrimaryContentShell = aContentShell;
+ mPrimaryTabParent = nullptr;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
+{
+ if (mTreeOwner) {
+ return mTreeOwner->ContentShellRemoved(aContentShell);
+ }
+
+ if (mPrimaryContentShell == aContentShell) {
+ mPrimaryContentShell = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
+{
+ NS_ENSURE_ARG_POINTER(aShell);
+
+ if (mTreeOwner) {
+ return mTreeOwner->GetPrimaryContentShell(aShell);
+ }
+
+ nsCOMPtr<nsIDocShellTreeItem> shell;
+ if (!mPrimaryTabParent) {
+ shell =
+ mPrimaryContentShell ? mPrimaryContentShell : mWebBrowser->mDocShell;
+ }
+ shell.forget(aShell);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::TabParentAdded(nsITabParent* aTab, bool aPrimary)
+{
+ if (mTreeOwner) {
+ return mTreeOwner->TabParentAdded(aTab, aPrimary);
+ }
+
+ if (aPrimary) {
+ mPrimaryTabParent = aTab;
+ mPrimaryContentShell = nullptr;
+ } else if (mPrimaryTabParent == aTab) {
+ mPrimaryTabParent = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::TabParentRemoved(nsITabParent* aTab)
+{
+ if (mTreeOwner) {
+ return mTreeOwner->TabParentRemoved(aTab);
+ }
+
+ if (aTab == mPrimaryTabParent) {
+ mPrimaryTabParent = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPrimaryTabParent(nsITabParent** aTab)
+{
+ if (mTreeOwner) {
+ return mTreeOwner->GetPrimaryTabParent(aTab);
+ }
+
+ nsCOMPtr<nsITabParent> tab = mPrimaryTabParent;
+ tab.forget(aTab);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPrimaryContentSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPrimaryContentSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetRootShellSize(int32_t* aWidth,
+ int32_t* aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetRootShellSize(int32_t aWidth,
+ int32_t aHeight)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
+ int32_t aCX, int32_t aCY)
+{
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+
+ NS_ENSURE_STATE(mTreeOwner || webBrowserChrome);
+
+ if (mTreeOwner) {
+ return mTreeOwner->SizeShellTo(aShellItem, aCX, aCY);
+ }
+
+ if (aShellItem == mWebBrowser->mDocShell) {
+ nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(webBrowserChrome);
+ if (tabChild) {
+ // The XUL window to resize is in the parent process, but there we
+ // won't be able to get aShellItem to do the hack in nsXULWindow::SizeShellTo,
+ // so let's send the width and height of aShellItem too.
+ nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(aShellItem));
+ NS_ENSURE_TRUE(shellAsWin, NS_ERROR_FAILURE);
+
+ int32_t width = 0;
+ int32_t height = 0;
+ shellAsWin->GetSize(&width, &height);
+ return tabChild->RemoteSizeShellTo(aCX, aCY, width, height);
+ }
+ return webBrowserChrome->SizeBrowserTo(aCX, aCY);
+ }
+
+ nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(aShellItem));
+ NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIDOMDocument> domDocument;
+ webNav->GetDocument(getter_AddRefs(domDocument));
+ NS_ENSURE_TRUE(domDocument, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIDOMElement> domElement;
+ domDocument->GetDocumentElement(getter_AddRefs(domElement));
+ NS_ENSURE_TRUE(domElement, NS_ERROR_FAILURE);
+
+ // Set the preferred Size
+ //XXX
+ NS_ERROR("Implement this");
+ /*
+ Set the preferred size on the aShellItem.
+ */
+
+ RefPtr<nsPresContext> presContext;
+ mWebBrowser->mDocShell->GetPresContext(getter_AddRefs(presContext));
+ NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
+
+ nsIPresShell* presShell = presContext->GetPresShell();
+ NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
+
+ NS_ENSURE_SUCCESS(
+ presShell->ResizeReflow(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE),
+ NS_ERROR_FAILURE);
+
+ nsRect shellArea = presContext->GetVisibleArea();
+
+ int32_t browserCX = presContext->AppUnitsToDevPixels(shellArea.width);
+ int32_t browserCY = presContext->AppUnitsToDevPixels(shellArea.height);
+
+ return webBrowserChrome->SizeBrowserTo(browserCX, browserCY);
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPersistence(bool aPersistPosition,
+ bool aPersistSize,
+ bool aPersistSizeMode)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPersistence(bool* aPersistPosition,
+ bool* aPersistSize,
+ bool* aPersistSizeMode)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetTargetableShellCount(uint32_t* aResult)
+{
+ if (mTreeOwner) {
+ mTreeOwner->GetTargetableShellCount(aResult);
+ } else {
+ *aResult = 0;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetHasPrimaryContent(bool* aResult)
+{
+ *aResult = mPrimaryTabParent || mPrimaryContentShell;
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsDocShellTreeOwner::nsIBaseWindow
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
+ nsIWidget* aParentWidget, int32_t aX,
+ int32_t aY, int32_t aCX, int32_t aCY)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::Create()
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::Destroy()
+{
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+ if (webBrowserChrome) {
+ return webBrowserChrome->DestroyBrowserWindow();
+ }
+
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
+{
+ if (mWebBrowser) {
+ return mWebBrowser->GetUnscaledDevicePixelsPerCSSPixel(aScale);
+ }
+
+ *aScale = 1.0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale)
+{
+ if (mWebBrowser) {
+ return mWebBrowser->GetDevicePixelsPerDesktopPixel(aScale);
+ }
+
+ *aScale = 1.0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPositionDesktopPix(int32_t aX, int32_t aY)
+{
+ if (mWebBrowser) {
+ nsresult rv = mWebBrowser->SetPositionDesktopPix(aX, aY);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ double scale = 1.0;
+ GetDevicePixelsPerDesktopPixel(&scale);
+ return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
+ aX, aY, 0, 0);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPosition(int32_t* aX, int32_t* aY)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
+ aX, aY, nullptr, nullptr);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetSize(int32_t aCX, int32_t aCY, bool aRepaint)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER,
+ 0, 0, aCX, aCY);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetSize(int32_t* aCX, int32_t* aCY)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER,
+ nullptr, nullptr, aCX, aCY);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aCX,
+ int32_t aCY, uint32_t aFlags)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetDimensions(
+ nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER |
+ nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
+ aX, aY, aCX, aCY);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aCX,
+ int32_t* aCY)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetDimensions(
+ nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER |
+ nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
+ aX, aY, aCX, aCY);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::Repaint(bool aForce)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetParentWidget(nsIWidget** aParentWidget)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetParentWidget(nsIWidget* aParentWidget)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetSiteWindow(aParentNativeWindow);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetNativeHandle(nsAString& aNativeHandle)
+{
+ // the nativeHandle should be accessed from nsIXULWindow
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetVisibility(bool* aVisibility)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetVisibility(aVisibility);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetVisibility(bool aVisibility)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetVisibility(aVisibility);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetEnabled(bool* aEnabled)
+{
+ NS_ENSURE_ARG_POINTER(aEnabled);
+ *aEnabled = true;
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetEnabled(bool aEnabled)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetMainWidget(nsIWidget** aMainWidget)
+{
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetFocus()
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetFocus();
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::GetTitle(char16_t** aTitle)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->GetTitle(aTitle);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetTitle(const char16_t* aTitle)
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
+ if (ownerWin) {
+ return ownerWin->SetTitle(aTitle);
+ }
+ return NS_ERROR_NULL_POINTER;
+}
+
+//*****************************************************************************
+// nsDocShellTreeOwner::nsIWebProgressListener
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::OnProgressChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ int32_t aCurSelfProgress,
+ int32_t aMaxSelfProgress,
+ int32_t aCurTotalProgress,
+ int32_t aMaxTotalProgress)
+{
+ // In the absence of DOM document creation event, this method is the
+ // most convenient place to install the mouse listener on the
+ // DOM document.
+ return AddChromeListeners();
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::OnStateChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ uint32_t aProgressStateFlags,
+ nsresult aStatus)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::OnLocationChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsIURI* aURI,
+ uint32_t aFlags)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::OnStatusChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsresult aStatus,
+ const char16_t* aMessage)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::OnSecurityChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aState)
+{
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsDocShellTreeOwner: Accessors
+//*****************************************************************************
+
+void
+nsDocShellTreeOwner::WebBrowser(nsWebBrowser* aWebBrowser)
+{
+ if (!aWebBrowser) {
+ RemoveChromeListeners();
+ }
+ if (aWebBrowser != mWebBrowser) {
+ mPrompter = nullptr;
+ mAuthPrompter = nullptr;
+ }
+
+ mWebBrowser = aWebBrowser;
+
+ if (mContentTreeOwner) {
+ mContentTreeOwner->WebBrowser(aWebBrowser);
+ if (!aWebBrowser) {
+ mContentTreeOwner = nullptr;
+ }
+ }
+}
+
+nsWebBrowser*
+nsDocShellTreeOwner::WebBrowser()
+{
+ return mWebBrowser;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
+{
+ if (aTreeOwner) {
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(aTreeOwner));
+ NS_ENSURE_TRUE(webBrowserChrome, NS_ERROR_INVALID_ARG);
+ NS_ENSURE_SUCCESS(SetWebBrowserChrome(webBrowserChrome),
+ NS_ERROR_INVALID_ARG);
+ mTreeOwner = aTreeOwner;
+ } else {
+ mTreeOwner = nullptr;
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+ if (!webBrowserChrome) {
+ NS_ENSURE_SUCCESS(SetWebBrowserChrome(nullptr), NS_ERROR_FAILURE);
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome)
+{
+ if (!aWebBrowserChrome) {
+ mWebBrowserChrome = nullptr;
+ mOwnerWin = nullptr;
+ mOwnerRequestor = nullptr;
+ mWebBrowserChromeWeak = nullptr;
+ } else {
+ nsCOMPtr<nsISupportsWeakReference> supportsweak =
+ do_QueryInterface(aWebBrowserChrome);
+ if (supportsweak) {
+ supportsweak->GetWeakReference(getter_AddRefs(mWebBrowserChromeWeak));
+ } else {
+ nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin(
+ do_QueryInterface(aWebBrowserChrome));
+ nsCOMPtr<nsIInterfaceRequestor> requestor(
+ do_QueryInterface(aWebBrowserChrome));
+
+ // it's ok for ownerWin or requestor to be null.
+ mWebBrowserChrome = aWebBrowserChrome;
+ mOwnerWin = ownerWin;
+ mOwnerRequestor = requestor;
+ }
+ }
+
+ if (mContentTreeOwner) {
+ mContentTreeOwner->SetWebBrowserChrome(aWebBrowserChrome);
+ }
+
+ return NS_OK;
+}
+
+// Hook up things to the chrome like context menus and tooltips, if the chrome
+// has implemented the right interfaces.
+NS_IMETHODIMP
+nsDocShellTreeOwner::AddChromeListeners()
+{
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+ if (!webBrowserChrome) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // install tooltips
+ if (!mChromeTooltipListener) {
+ nsCOMPtr<nsITooltipListener> tooltipListener(
+ do_QueryInterface(webBrowserChrome));
+ if (tooltipListener) {
+ mChromeTooltipListener = new ChromeTooltipListener(mWebBrowser,
+ webBrowserChrome);
+ rv = mChromeTooltipListener->AddChromeListeners();
+ }
+ }
+
+ // install context menus
+ if (!mChromeContextMenuListener) {
+ nsCOMPtr<nsIContextMenuListener2> contextListener2(
+ do_QueryInterface(webBrowserChrome));
+ nsCOMPtr<nsIContextMenuListener> contextListener(
+ do_QueryInterface(webBrowserChrome));
+ if (contextListener2 || contextListener) {
+ mChromeContextMenuListener =
+ new ChromeContextMenuListener(mWebBrowser, webBrowserChrome);
+ rv = mChromeContextMenuListener->AddChromeListeners();
+ }
+ }
+
+ // register dragover and drop event listeners with the listener manager
+ nsCOMPtr<EventTarget> target;
+ GetDOMEventTarget(mWebBrowser, getter_AddRefs(target));
+
+ EventListenerManager* elmP = target->GetOrCreateListenerManager();
+ if (elmP) {
+ elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
+ TrustedEventsAtSystemGroupBubble());
+ elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
+ TrustedEventsAtSystemGroupBubble());
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::RemoveChromeListeners()
+{
+ if (mChromeTooltipListener) {
+ mChromeTooltipListener->RemoveChromeListeners();
+ mChromeTooltipListener = nullptr;
+ }
+ if (mChromeContextMenuListener) {
+ mChromeContextMenuListener->RemoveChromeListeners();
+ mChromeContextMenuListener = nullptr;
+ }
+
+ nsCOMPtr<EventTarget> piTarget;
+ GetDOMEventTarget(mWebBrowser, getter_AddRefs(piTarget));
+ if (!piTarget) {
+ return NS_OK;
+ }
+
+ EventListenerManager* elmP = piTarget->GetOrCreateListenerManager();
+ if (elmP) {
+ elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("dragover"),
+ TrustedEventsAtSystemGroupBubble());
+ elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("drop"),
+ TrustedEventsAtSystemGroupBubble());
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
+{
+ nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
+ NS_ENSURE_TRUE(dragEvent, NS_ERROR_INVALID_ARG);
+
+ bool defaultPrevented;
+ aEvent->GetDefaultPrevented(&defaultPrevented);
+ if (defaultPrevented) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIDroppedLinkHandler> handler =
+ do_GetService("@mozilla.org/content/dropped-link-handler;1");
+ if (handler) {
+ nsAutoString eventType;
+ aEvent->GetType(eventType);
+ if (eventType.EqualsLiteral("dragover")) {
+ bool canDropLink = false;
+ handler->CanDropLink(dragEvent, false, &canDropLink);
+ if (canDropLink) {
+ aEvent->PreventDefault();
+ }
+ } else if (eventType.EqualsLiteral("drop")) {
+ nsIWebNavigation* webnav = static_cast<nsIWebNavigation*>(mWebBrowser);
+
+ uint32_t linksCount;
+ nsIDroppedLinkItem** links;
+ if (webnav &&
+ NS_SUCCEEDED(handler->DropLinks(dragEvent, true, &linksCount, &links))) {
+ if (linksCount >= 1) {
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
+ if (webBrowserChrome) {
+ nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(webBrowserChrome);
+ if (tabChild) {
+ nsresult rv = tabChild->RemoteDropLinks(linksCount, links);
+ for (uint32_t i = 0; i < linksCount; i++) {
+ NS_RELEASE(links[i]);
+ }
+ free(links);
+ return rv;
+ }
+ }
+ nsAutoString url;
+ if (NS_SUCCEEDED(links[0]->GetUrl(url))) {
+ if (!url.IsEmpty()) {
+ webnav->LoadURI(url.get(), 0, nullptr, nullptr, nullptr);
+ }
+ }
+
+ for (uint32_t i = 0; i < linksCount; i++) {
+ NS_RELEASE(links[i]);
+ }
+ free(links);
+ }
+ } else {
+ aEvent->StopPropagation();
+ aEvent->PreventDefault();
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+already_AddRefed<nsIWebBrowserChrome>
+nsDocShellTreeOwner::GetWebBrowserChrome()
+{
+ nsCOMPtr<nsIWebBrowserChrome> chrome;
+ if (mWebBrowserChromeWeak) {
+ chrome = do_QueryReferent(mWebBrowserChromeWeak);
+ } else if (mWebBrowserChrome) {
+ chrome = mWebBrowserChrome;
+ }
+ return chrome.forget();
+}
+
+already_AddRefed<nsIEmbeddingSiteWindow>
+nsDocShellTreeOwner::GetOwnerWin()
+{
+ nsCOMPtr<nsIEmbeddingSiteWindow> win;
+ if (mWebBrowserChromeWeak) {
+ win = do_QueryReferent(mWebBrowserChromeWeak);
+ } else if (mOwnerWin) {
+ win = mOwnerWin;
+ }
+ return win.forget();
+}
+
+already_AddRefed<nsIInterfaceRequestor>
+nsDocShellTreeOwner::GetOwnerRequestor()
+{
+ nsCOMPtr<nsIInterfaceRequestor> req;
+ if (mWebBrowserChromeWeak) {
+ req = do_QueryReferent(mWebBrowserChromeWeak);
+ } else if (mOwnerRequestor) {
+ req = mOwnerRequestor;
+ }
+ return req.forget();
+}
+
+NS_IMPL_ISUPPORTS(ChromeTooltipListener, nsIDOMEventListener)
+
+ChromeTooltipListener::ChromeTooltipListener(nsWebBrowser* aInBrowser,
+ nsIWebBrowserChrome* aInChrome)
+ : mWebBrowser(aInBrowser)
+ , mWebBrowserChrome(aInChrome)
+ , mTooltipListenerInstalled(false)
+ , mMouseClientX(0)
+ , mMouseClientY(0)
+ , mMouseScreenX(0)
+ , mMouseScreenY(0)
+ , mShowingTooltip(false)
+ , mTooltipShownOnce(false)
+{
+ mTooltipTextProvider = do_GetService(NS_TOOLTIPTEXTPROVIDER_CONTRACTID);
+ if (!mTooltipTextProvider) {
+ mTooltipTextProvider = do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID);
+ }
+}
+
+ChromeTooltipListener::~ChromeTooltipListener()
+{
+}
+
+// Hook up things to the chrome like context menus and tooltips, if the chrome
+// has implemented the right interfaces.
+NS_IMETHODIMP
+ChromeTooltipListener::AddChromeListeners()
+{
+ if (!mEventTarget) {
+ GetDOMEventTarget(mWebBrowser, getter_AddRefs(mEventTarget));
+ }
+
+ // Register the appropriate events for tooltips, but only if
+ // the embedding chrome cares.
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsITooltipListener> tooltipListener(
+ do_QueryInterface(mWebBrowserChrome));
+ if (tooltipListener && !mTooltipListenerInstalled) {
+ rv = AddTooltipListener();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ }
+
+ return rv;
+}
+
+// Subscribe to the events that will allow us to track tooltips. We need "mouse"
+// for mouseExit, "mouse motion" for mouseMove, and "key" for keyDown. As we
+// add the listeners, keep track of how many succeed so we can clean up
+// correctly in Release().
+NS_IMETHODIMP
+ChromeTooltipListener::AddTooltipListener()
+{
+ if (mEventTarget) {
+ nsresult rv = NS_OK;
+ rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("keydown"),
+ this, false, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mousedown"),
+ this, false, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mouseout"),
+ this, false, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mousemove"),
+ this, false, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mTooltipListenerInstalled = true;
+ }
+
+ return NS_OK;
+}
+
+// Unsubscribe from the various things we've hooked up to the window root.
+NS_IMETHODIMP
+ChromeTooltipListener::RemoveChromeListeners()
+{
+ HideTooltip();
+
+ if (mTooltipListenerInstalled) {
+ RemoveTooltipListener();
+ }
+
+ mEventTarget = nullptr;
+
+ // it really doesn't matter if these fail...
+ return NS_OK;
+}
+
+// Unsubscribe from all the various tooltip events that we were listening to.
+NS_IMETHODIMP
+ChromeTooltipListener::RemoveTooltipListener()
+{
+ if (mEventTarget) {
+ nsresult rv = NS_OK;
+ rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"),
+ this, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mousedown"),
+ this, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mouseout"),
+ this, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("mousemove"),
+ this, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mTooltipListenerInstalled = false;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ChromeTooltipListener::HandleEvent(nsIDOMEvent* aEvent)
+{
+ nsAutoString eventType;
+ aEvent->GetType(eventType);
+
+ if (eventType.EqualsLiteral("keydown") ||
+ eventType.EqualsLiteral("mousedown")) {
+ return HideTooltip();
+ } else if (eventType.EqualsLiteral("mouseout")) {
+ // Reset flag so that tooltip will display on the next MouseMove
+ mTooltipShownOnce = false;
+ return HideTooltip();
+ } else if (eventType.EqualsLiteral("mousemove")) {
+ return MouseMove(aEvent);
+ }
+
+ NS_ERROR("Unexpected event type");
+ return NS_OK;
+}
+
+// If we're a tooltip, fire off a timer to see if a tooltip should be shown. If
+// the timer fires, we cache the node in |mPossibleTooltipNode|.
+nsresult
+ChromeTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
+{
+ nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aMouseEvent));
+ if (!mouseEvent) {
+ return NS_OK;
+ }
+
+ // stash the coordinates of the event so that we can still get back to it from
+ // within the timer callback. On win32, we'll get a MouseMove event even when
+ // a popup goes away -- even when the mouse doesn't change position! To get
+ // around this, we make sure the mouse has really moved before proceeding.
+ int32_t newMouseX, newMouseY;
+ mouseEvent->GetClientX(&newMouseX);
+ mouseEvent->GetClientY(&newMouseY);
+ if (mMouseClientX == newMouseX && mMouseClientY == newMouseY) {
+ return NS_OK;
+ }
+
+ // Filter out minor mouse movements.
+ if (mShowingTooltip &&
+ (abs(mMouseClientX - newMouseX) <= kTooltipMouseMoveTolerance) &&
+ (abs(mMouseClientY - newMouseY) <= kTooltipMouseMoveTolerance)) {
+ return NS_OK;
+ }
+
+ mMouseClientX = newMouseX;
+ mMouseClientY = newMouseY;
+ mouseEvent->GetScreenX(&mMouseScreenX);
+ mouseEvent->GetScreenY(&mMouseScreenY);
+
+ if (mTooltipTimer) {
+ mTooltipTimer->Cancel();
+ }
+
+ if (!mShowingTooltip && !mTooltipShownOnce) {
+ mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
+ if (mTooltipTimer) {
+ nsCOMPtr<EventTarget> eventTarget =
+ aMouseEvent->InternalDOMEvent()->GetTarget();
+ if (eventTarget) {
+ mPossibleTooltipNode = do_QueryInterface(eventTarget);
+ }
+ if (mPossibleTooltipNode) {
+ nsresult rv = mTooltipTimer->InitWithFuncCallback(
+ sTooltipCallback, this,
+ LookAndFeel::GetInt(LookAndFeel::eIntID_TooltipDelay, 500),
+ nsITimer::TYPE_ONE_SHOT);
+ if (NS_FAILED(rv)) {
+ mPossibleTooltipNode = nullptr;
+ }
+ }
+ } else {
+ NS_WARNING("Could not create a timer for tooltip tracking");
+ }
+ } else {
+ mTooltipShownOnce = true;
+ return HideTooltip();
+ }
+
+ return NS_OK;
+}
+
+// Tell the registered chrome that they should show the tooltip.
+NS_IMETHODIMP
+ChromeTooltipListener::ShowTooltip(int32_t aInXCoords, int32_t aInYCoords,
+ const nsAString& aInTipText,
+ const nsAString& aTipDir)
+{
+ nsresult rv = NS_OK;
+
+ // do the work to call the client
+ nsCOMPtr<nsITooltipListener> tooltipListener(
+ do_QueryInterface(mWebBrowserChrome));
+ if (tooltipListener) {
+ rv = tooltipListener->OnShowTooltip(aInXCoords, aInYCoords,
+ PromiseFlatString(aInTipText).get(),
+ PromiseFlatString(aTipDir).get());
+ if (NS_SUCCEEDED(rv)) {
+ mShowingTooltip = true;
+ }
+ }
+
+ return rv;
+}
+
+// Tell the registered chrome that they should rollup the tooltip
+// NOTE: This routine is safe to call even if the popup is already closed.
+NS_IMETHODIMP
+ChromeTooltipListener::HideTooltip()
+{
+ nsresult rv = NS_OK;
+
+ // shut down the relevant timers
+ if (mTooltipTimer) {
+ mTooltipTimer->Cancel();
+ mTooltipTimer = nullptr;
+ // release tooltip target
+ mPossibleTooltipNode = nullptr;
+ }
+
+ // if we're showing the tip, tell the chrome to hide it
+ if (mShowingTooltip) {
+ nsCOMPtr<nsITooltipListener> tooltipListener(
+ do_QueryInterface(mWebBrowserChrome));
+ if (tooltipListener) {
+ rv = tooltipListener->OnHideTooltip();
+ if (NS_SUCCEEDED(rv)) {
+ mShowingTooltip = false;
+ }
+ }
+ }
+
+ return rv;
+}
+
+// A timer callback, fired when the mouse has hovered inside of a frame for the
+// appropriate amount of time. Getting to this point means that we should show
+// the tooltip, but only after we determine there is an appropriate TITLE
+// element.
+//
+// This relies on certain things being cached into the |aChromeTooltipListener|
+// object passed to us by the timer:
+// -- the x/y coordinates of the mouse (mMouseClientY, mMouseClientX)
+// -- the dom node the user hovered over (mPossibleTooltipNode)
+void
+ChromeTooltipListener::sTooltipCallback(nsITimer* aTimer,
+ void* aChromeTooltipListener)
+{
+ auto self = static_cast<ChromeTooltipListener*>(aChromeTooltipListener);
+ if (self && self->mPossibleTooltipNode) {
+ // The actual coordinates we want to put the tooltip at are relative to the
+ // toplevel docshell of our mWebBrowser. We know what the screen
+ // coordinates of the mouse event were, which means we just need the screen
+ // coordinates of the docshell. Unfortunately, there is no good way to
+ // find those short of groveling for the presentation in that docshell and
+ // finding the screen coords of its toplevel widget...
+ nsCOMPtr<nsIDocShell> docShell =
+ do_GetInterface(static_cast<nsIWebBrowser*>(self->mWebBrowser));
+ nsCOMPtr<nsIPresShell> shell;
+ if (docShell) {
+ shell = docShell->GetPresShell();
+ }
+
+ nsIWidget* widget = nullptr;
+ if (shell) {
+ nsViewManager* vm = shell->GetViewManager();
+ if (vm) {
+ nsView* view = vm->GetRootView();
+ if (view) {
+ nsPoint offset;
+ widget = view->GetNearestWidget(&offset);
+ }
+ }
+ }
+
+ if (!widget) {
+ // release tooltip target if there is one, NO MATTER WHAT
+ self->mPossibleTooltipNode = nullptr;
+ return;
+ }
+
+ // if there is text associated with the node, show the tip and fire
+ // off a timer to auto-hide it.
+
+ nsXPIDLString tooltipText;
+ nsXPIDLString directionText;
+ if (self->mTooltipTextProvider) {
+ bool textFound = false;
+
+ self->mTooltipTextProvider->GetNodeText(
+ self->mPossibleTooltipNode, getter_Copies(tooltipText),
+ getter_Copies(directionText), &textFound);
+
+ if (textFound) {
+ nsString tipText(tooltipText);
+ nsString dirText(directionText);
+ LayoutDeviceIntPoint screenDot = widget->WidgetToScreenOffset();
+ double scaleFactor = 1.0;
+ if (shell->GetPresContext()) {
+ nsDeviceContext* dc = shell->GetPresContext()->DeviceContext();
+ scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel()) /
+ dc->AppUnitsPerDevPixelAtUnitFullZoom();
+ }
+ // ShowTooltip expects widget-relative position.
+ self->ShowTooltip(self->mMouseScreenX - screenDot.x / scaleFactor,
+ self->mMouseScreenY - screenDot.y / scaleFactor,
+ tipText, dirText);
+ }
+ }
+
+ // release tooltip target if there is one, NO MATTER WHAT
+ self->mPossibleTooltipNode = nullptr;
+ }
+}
+
+NS_IMPL_ISUPPORTS(ChromeContextMenuListener, nsIDOMEventListener)
+
+ChromeContextMenuListener::ChromeContextMenuListener(
+ nsWebBrowser* aInBrowser,
+ nsIWebBrowserChrome* aInChrome)
+ : mContextMenuListenerInstalled(false)
+ , mWebBrowser(aInBrowser)
+ , mWebBrowserChrome(aInChrome)
+{
+}
+
+ChromeContextMenuListener::~ChromeContextMenuListener()
+{
+}
+
+// Subscribe to the events that will allow us to track context menus. Bascially,
+// this is just the context-menu DOM event.
+NS_IMETHODIMP
+ChromeContextMenuListener::AddContextMenuListener()
+{
+ if (mEventTarget) {
+ nsresult rv = mEventTarget->AddEventListener(
+ NS_LITERAL_STRING("contextmenu"), this, false, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mContextMenuListenerInstalled = true;
+ }
+
+ return NS_OK;
+}
+
+// Unsubscribe from all the various context menu events that we were listening
+// to.
+NS_IMETHODIMP
+ChromeContextMenuListener::RemoveContextMenuListener()
+{
+ if (mEventTarget) {
+ nsresult rv = mEventTarget->RemoveEventListener(
+ NS_LITERAL_STRING("contextmenu"), this, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mContextMenuListenerInstalled = false;
+ }
+
+ return NS_OK;
+}
+
+// Hook up things to the chrome like context menus and tooltips, if the chrome
+// has implemented the right interfaces.
+NS_IMETHODIMP
+ChromeContextMenuListener::AddChromeListeners()
+{
+ if (!mEventTarget) {
+ GetDOMEventTarget(mWebBrowser, getter_AddRefs(mEventTarget));
+ }
+
+ // Register the appropriate events for context menus, but only if
+ // the embedding chrome cares.
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsIContextMenuListener2> contextListener2(
+ do_QueryInterface(mWebBrowserChrome));
+ nsCOMPtr<nsIContextMenuListener> contextListener(
+ do_QueryInterface(mWebBrowserChrome));
+ if ((contextListener || contextListener2) && !mContextMenuListenerInstalled) {
+ rv = AddContextMenuListener();
+ }
+
+ return rv;
+}
+
+// Unsubscribe from the various things we've hooked up to the window root.
+NS_IMETHODIMP
+ChromeContextMenuListener::RemoveChromeListeners()
+{
+ if (mContextMenuListenerInstalled) {
+ RemoveContextMenuListener();
+ }
+
+ mEventTarget = nullptr;
+
+ // it really doesn't matter if these fail...
+ return NS_OK;
+}
+
+// We're on call to show the context menu. Dig around in the DOM to find the
+// type of object we're dealing with and notify the front end chrome.
+NS_IMETHODIMP
+ChromeContextMenuListener::HandleEvent(nsIDOMEvent* aMouseEvent)
+{
+ nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
+ NS_ENSURE_TRUE(mouseEvent, NS_ERROR_UNEXPECTED);
+
+ bool isDefaultPrevented = false;
+ aMouseEvent->GetDefaultPrevented(&isDefaultPrevented);
+ if (isDefaultPrevented) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<EventTarget> targetNode =
+ aMouseEvent->InternalDOMEvent()->GetTarget();
+ if (!targetNode) {
+ return NS_ERROR_NULL_POINTER;
+ }
+
+ nsCOMPtr<nsIDOMNode> targetDOMnode;
+ nsCOMPtr<nsIDOMNode> node = do_QueryInterface(targetNode);
+ if (!node) {
+ return NS_OK;
+ }
+
+ // Stop the context menu event going to other windows (bug 78396)
+ aMouseEvent->PreventDefault();
+
+ // If the listener is a nsIContextMenuListener2, create the info object
+ nsCOMPtr<nsIContextMenuListener2> menuListener2(
+ do_QueryInterface(mWebBrowserChrome));
+ nsContextMenuInfo* menuInfoImpl = nullptr;
+ nsCOMPtr<nsIContextMenuInfo> menuInfo;
+ if (menuListener2) {
+ menuInfoImpl = new nsContextMenuInfo;
+ menuInfo = menuInfoImpl;
+ }
+
+ uint32_t flags = nsIContextMenuListener::CONTEXT_NONE;
+ uint32_t flags2 = nsIContextMenuListener2::CONTEXT_NONE;
+
+ // XXX test for selected text
+
+ uint16_t nodeType;
+ nsresult res = node->GetNodeType(&nodeType);
+ NS_ENSURE_SUCCESS(res, res);
+
+ // First, checks for nodes that never have children.
+ if (nodeType == nsIDOMNode::ELEMENT_NODE) {
+ nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(node));
+ if (content) {
+ nsCOMPtr<nsIURI> imgUri;
+ content->GetCurrentURI(getter_AddRefs(imgUri));
+ if (imgUri) {
+ flags |= nsIContextMenuListener::CONTEXT_IMAGE;
+ flags2 |= nsIContextMenuListener2::CONTEXT_IMAGE;
+ targetDOMnode = node;
+ }
+ }
+
+ nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
+ if (formControl) {
+ if (formControl->GetType() == NS_FORM_TEXTAREA) {
+ flags |= nsIContextMenuListener::CONTEXT_TEXT;
+ flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
+ targetDOMnode = node;
+ } else {
+ nsCOMPtr<nsIDOMHTMLInputElement> inputElement(
+ do_QueryInterface(formControl));
+ if (inputElement) {
+ flags |= nsIContextMenuListener::CONTEXT_INPUT;
+ flags2 |= nsIContextMenuListener2::CONTEXT_INPUT;
+
+ if (menuListener2) {
+ if (formControl->IsSingleLineTextControl(false)) {
+ flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
+ }
+ }
+
+ targetDOMnode = node;
+ }
+ }
+ }
+
+ // always consume events for plugins and Java who may throw their
+ // own context menus but not for image objects. Document objects
+ // will never be targets or ancestors of targets, so that's OK.
+ nsCOMPtr<nsIDOMHTMLObjectElement> objectElement;
+ if (!(flags & nsIContextMenuListener::CONTEXT_IMAGE)) {
+ objectElement = do_QueryInterface(node);
+ }
+ nsCOMPtr<nsIDOMHTMLEmbedElement> embedElement(do_QueryInterface(node));
+ nsCOMPtr<nsIDOMHTMLAppletElement> appletElement(do_QueryInterface(node));
+
+ if (objectElement || embedElement || appletElement) {
+ return NS_OK;
+ }
+ }
+
+ // Bubble out, looking for items of interest
+ do {
+ uint16_t nodeType;
+ res = node->GetNodeType(&nodeType);
+ NS_ENSURE_SUCCESS(res, res);
+
+ if (nodeType == nsIDOMNode::ELEMENT_NODE) {
+
+ // Test if the element has an associated link
+ nsCOMPtr<nsIDOMElement> element(do_QueryInterface(node));
+
+ bool hasAttr = false;
+ res = element->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
+
+ if (NS_SUCCEEDED(res) && hasAttr) {
+ flags |= nsIContextMenuListener::CONTEXT_LINK;
+ flags2 |= nsIContextMenuListener2::CONTEXT_LINK;
+ if (!targetDOMnode) {
+ targetDOMnode = node;
+ }
+ if (menuInfoImpl) {
+ menuInfoImpl->SetAssociatedLink(node);
+ }
+ break; // exit do-while
+ }
+ }
+
+ // walk-up-the-tree
+ nsCOMPtr<nsIDOMNode> parentNode;
+ node->GetParentNode(getter_AddRefs(parentNode));
+ node = parentNode;
+ } while (node);
+
+ if (!flags && !flags2) {
+ // We found nothing of interest so far, check if we
+ // have at least an html document.
+ nsCOMPtr<nsIDOMDocument> document;
+ node = do_QueryInterface(targetNode);
+ node->GetOwnerDocument(getter_AddRefs(document));
+ nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(document));
+ if (htmlDocument) {
+ flags |= nsIContextMenuListener::CONTEXT_DOCUMENT;
+ flags2 |= nsIContextMenuListener2::CONTEXT_DOCUMENT;
+ targetDOMnode = node;
+ if (!(flags & nsIContextMenuListener::CONTEXT_IMAGE)) {
+ // check if this is a background image that the user was trying to click
+ // on and if the listener is ready for that (only
+ // nsIContextMenuListener2 and up)
+ if (menuInfoImpl && menuInfoImpl->HasBackgroundImage(targetDOMnode)) {
+ flags2 |= nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE;
+ // For the embedder to get the correct background image
+ // targetDOMnode must point to the original node.
+ targetDOMnode = do_QueryInterface(targetNode);
+ }
+ }
+ }
+ }
+
+ // we need to cache the event target into the focus controller's popupNode
+ // so we can get at it later from command code, etc.:
+
+ // get the dom window
+ nsCOMPtr<mozIDOMWindowProxy> win;
+ res = mWebBrowser->GetContentDOMWindow(getter_AddRefs(win));
+ NS_ENSURE_SUCCESS(res, res);
+ NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
+
+ auto* window = nsPIDOMWindowOuter::From(win);
+ nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
+ NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
+ if (root) {
+ // set the window root's popup node to the event target
+ root->SetPopupNode(targetDOMnode);
+ }
+
+ // Tell the listener all about the event
+ if (menuListener2) {
+ menuInfoImpl->SetMouseEvent(aMouseEvent);
+ menuInfoImpl->SetDOMNode(targetDOMnode);
+ menuListener2->OnShowContextMenu(flags2, menuInfo);
+ } else {
+ nsCOMPtr<nsIContextMenuListener> menuListener(
+ do_QueryInterface(mWebBrowserChrome));
+ if (menuListener) {
+ menuListener->OnShowContextMenu(flags, aMouseEvent, targetDOMnode);
+ }
+ }
+
+ return NS_OK;
+}
diff --git a/embedding/browser/nsDocShellTreeOwner.h b/embedding/browser/nsDocShellTreeOwner.h
new file mode 100644
index 000000000..d935ba165
--- /dev/null
+++ b/embedding/browser/nsDocShellTreeOwner.h
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsDocShellTreeOwner_h__
+#define nsDocShellTreeOwner_h__
+
+// Helper Classes
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+// Interfaces Needed
+#include "nsIBaseWindow.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsIDOMEventListener.h"
+#include "nsIEmbeddingSiteWindow.h"
+#include "nsIWebProgressListener.h"
+#include "nsWeakReference.h"
+#include "nsITimer.h"
+#include "nsIPrompt.h"
+#include "nsIAuthPrompt.h"
+#include "nsITooltipListener.h"
+#include "nsITooltipTextProvider.h"
+#include "nsCTooltipTextProvider.h"
+#include "nsIDroppedLinkHandler.h"
+#include "nsCommandHandler.h"
+
+namespace mozilla {
+namespace dom {
+class EventTarget;
+} // namespace dom
+} // namespace mozilla
+
+class nsWebBrowser;
+class ChromeTooltipListener;
+class ChromeContextMenuListener;
+
+// {6D10C180-6888-11d4-952B-0020183BF181}
+#define NS_ICDOCSHELLTREEOWNER_IID \
+ { 0x6d10c180, 0x6888, 0x11d4, { 0x95, 0x2b, 0x0, 0x20, 0x18, 0x3b, 0xf1, 0x81 } }
+
+// This is a fake 'hidden' interface that nsDocShellTreeOwner implements.
+// Classes such as nsCommandHandler can QI for this interface to be sure that
+// they're dealing with a valid nsDocShellTreeOwner and not some other object
+// that implements nsIDocShellTreeOwner.
+class nsICDocShellTreeOwner : public nsISupports
+{
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICDOCSHELLTREEOWNER_IID)
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsICDocShellTreeOwner, NS_ICDOCSHELLTREEOWNER_IID)
+
+class nsDocShellTreeOwner final : public nsIDocShellTreeOwner,
+ public nsIBaseWindow,
+ public nsIInterfaceRequestor,
+ public nsIWebProgressListener,
+ public nsIDOMEventListener,
+ public nsICDocShellTreeOwner,
+ public nsSupportsWeakReference
+{
+ friend class nsWebBrowser;
+ friend class nsCommandHandler;
+
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSIBASEWINDOW
+ NS_DECL_NSIDOCSHELLTREEOWNER
+ NS_DECL_NSIDOMEVENTLISTENER
+ NS_DECL_NSIINTERFACEREQUESTOR
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+protected:
+ nsDocShellTreeOwner();
+ virtual ~nsDocShellTreeOwner();
+
+ void WebBrowser(nsWebBrowser* aWebBrowser);
+
+ nsWebBrowser* WebBrowser();
+ NS_IMETHOD SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner);
+ NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome);
+
+ NS_IMETHOD AddChromeListeners();
+ NS_IMETHOD RemoveChromeListeners();
+
+ nsresult FindItemWithNameAcrossWindows(
+ const char16_t* aName,
+ nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor,
+ nsIDocShellTreeItem** aFoundItem);
+
+ void EnsurePrompter();
+ void EnsureAuthPrompter();
+
+ void AddToWatcher();
+ void RemoveFromWatcher();
+
+ void EnsureContentTreeOwner();
+
+ // These helper functions return the correct instances of the requested
+ // interfaces. If the object passed to SetWebBrowserChrome() implements
+ // nsISupportsWeakReference, then these functions call QueryReferent on
+ // that object. Otherwise, they return an addrefed pointer. If the
+ // WebBrowserChrome object doesn't exist, they return nullptr.
+ already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
+ already_AddRefed<nsIEmbeddingSiteWindow> GetOwnerWin();
+ already_AddRefed<nsIInterfaceRequestor> GetOwnerRequestor();
+
+protected:
+ // Weak References
+ nsWebBrowser* mWebBrowser;
+ nsIDocShellTreeOwner* mTreeOwner;
+ nsIDocShellTreeItem* mPrimaryContentShell;
+
+ nsIWebBrowserChrome* mWebBrowserChrome;
+ nsIEmbeddingSiteWindow* mOwnerWin;
+ nsIInterfaceRequestor* mOwnerRequestor;
+
+ nsWeakPtr mWebBrowserChromeWeak; // nsIWebBrowserChrome
+
+ // the objects that listen for chrome events like context menus and tooltips.
+ // They are separate objects to avoid circular references between |this|
+ // and the DOM.
+ RefPtr<ChromeTooltipListener> mChromeTooltipListener;
+ RefPtr<ChromeContextMenuListener> mChromeContextMenuListener;
+
+ RefPtr<nsDocShellTreeOwner> mContentTreeOwner;
+
+ nsCOMPtr<nsIPrompt> mPrompter;
+ nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
+ nsCOMPtr<nsITabParent> mPrimaryTabParent;
+};
+
+
+// The class that listens to the chrome events and tells the embedding chrome to
+// show tooltips, as appropriate. Handles registering itself with the DOM with
+// AddChromeListeners() and removing itself with RemoveChromeListeners().
+class ChromeTooltipListener final : public nsIDOMEventListener
+{
+protected:
+ virtual ~ChromeTooltipListener();
+
+public:
+ NS_DECL_ISUPPORTS
+
+ ChromeTooltipListener(nsWebBrowser* aInBrowser, nsIWebBrowserChrome* aInChrome);
+
+ NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
+ NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
+
+ // Add/remove the relevant listeners, based on what interfaces the embedding
+ // chrome implements.
+ NS_IMETHOD AddChromeListeners();
+ NS_IMETHOD RemoveChromeListeners();
+
+private:
+ // various delays for tooltips
+ enum
+ {
+ kTooltipAutoHideTime = 5000, // ms
+ kTooltipMouseMoveTolerance = 7 // pixel tolerance for mousemove event
+ };
+
+ NS_IMETHOD AddTooltipListener();
+ NS_IMETHOD RemoveTooltipListener();
+
+ NS_IMETHOD ShowTooltip(int32_t aInXCoords, int32_t aInYCoords,
+ const nsAString& aInTipText,
+ const nsAString& aDirText);
+ NS_IMETHOD HideTooltip();
+
+ nsWebBrowser* mWebBrowser;
+ nsCOMPtr<mozilla::dom::EventTarget> mEventTarget;
+ nsCOMPtr<nsITooltipTextProvider> mTooltipTextProvider;
+
+ // This must be a strong ref in order to make sure we can hide the tooltip if
+ // the window goes away while we're displaying one. If we don't hold a strong
+ // ref, the chrome might have been disposed of before we get a chance to tell
+ // it, and no one would ever tell us of that fact.
+ nsCOMPtr<nsIWebBrowserChrome> mWebBrowserChrome;
+
+ bool mTooltipListenerInstalled;
+
+ nsCOMPtr<nsITimer> mTooltipTimer;
+ static void sTooltipCallback(nsITimer* aTimer, void* aListener);
+
+ // Mouse coordinates for last mousemove event we saw
+ int32_t mMouseClientX;
+ int32_t mMouseClientY;
+
+ // Mouse coordinates for tooltip event
+ int32_t mMouseScreenX;
+ int32_t mMouseScreenY;
+
+ bool mShowingTooltip;
+ bool mTooltipShownOnce;
+
+ // The node hovered over that fired the timer. This may turn into the node
+ // that triggered the tooltip, but only if the timer ever gets around to
+ // firing. This is a strong reference, because the tooltip content can be
+ // destroyed while we're waiting for the tooltip to pup up, and we need to
+ // detect that. It's set only when the tooltip timer is created and launched.
+ // The timer must either fire or be cancelled (or possibly released?), and we
+ // release this reference in each of those cases. So we don't leak.
+ nsCOMPtr<nsIDOMNode> mPossibleTooltipNode;
+};
+
+// The class that listens to the chrome events and tells the embedding chrome to
+// show context menus, as appropriate. Handles registering itself with the DOM
+// with AddChromeListeners() and removing itself with RemoveChromeListeners().
+class ChromeContextMenuListener : public nsIDOMEventListener
+{
+protected:
+ virtual ~ChromeContextMenuListener();
+
+public:
+ NS_DECL_ISUPPORTS
+
+ ChromeContextMenuListener(nsWebBrowser* aInBrowser,
+ nsIWebBrowserChrome* aInChrome);
+
+ // nsIDOMContextMenuListener
+ NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
+
+ // Add/remove the relevant listeners, based on what interfaces
+ // the embedding chrome implements.
+ NS_IMETHOD AddChromeListeners();
+ NS_IMETHOD RemoveChromeListeners();
+
+private:
+ NS_IMETHOD AddContextMenuListener();
+ NS_IMETHOD RemoveContextMenuListener();
+
+ bool mContextMenuListenerInstalled;
+
+ nsWebBrowser* mWebBrowser;
+ nsCOMPtr<mozilla::dom::EventTarget> mEventTarget;
+ nsCOMPtr<nsIWebBrowserChrome> mWebBrowserChrome;
+};
+
+#endif /* nsDocShellTreeOwner_h__ */
diff --git a/embedding/browser/nsEmbedStream.cpp b/embedding/browser/nsEmbedStream.cpp
new file mode 100644
index 000000000..35347060c
--- /dev/null
+++ b/embedding/browser/nsEmbedStream.cpp
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
+#include "nsIDocShell.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIPipe.h"
+
+#include "nsEmbedStream.h"
+#include "nsError.h"
+#include "nsString.h"
+
+NS_IMPL_ISUPPORTS0(nsEmbedStream)
+
+nsEmbedStream::nsEmbedStream()
+{
+ mOwner = nullptr;
+}
+
+nsEmbedStream::~nsEmbedStream()
+{
+}
+
+void
+nsEmbedStream::InitOwner(nsIWebBrowser* aOwner)
+{
+ mOwner = aOwner;
+}
+
+nsresult
+nsEmbedStream::Init(void)
+{
+ return NS_OK;
+}
+
+nsresult
+nsEmbedStream::OpenStream(nsIURI* aBaseURI, const nsACString& aContentType)
+{
+ nsresult rv;
+ NS_ENSURE_ARG_POINTER(aBaseURI);
+ NS_ENSURE_TRUE(IsASCII(aContentType), NS_ERROR_INVALID_ARG);
+
+ // if we're already doing a stream, return an error
+ if (mOutputStream) {
+ return NS_ERROR_IN_PROGRESS;
+ }
+
+ nsCOMPtr<nsIAsyncInputStream> inputStream;
+ nsCOMPtr<nsIAsyncOutputStream> outputStream;
+ rv = NS_NewPipe2(getter_AddRefs(inputStream), getter_AddRefs(outputStream),
+ true, false, 0, UINT32_MAX);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mOwner);
+ rv = docShell->LoadStream(inputStream, aBaseURI, aContentType,
+ EmptyCString(), nullptr);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ mOutputStream = outputStream;
+ return rv;
+}
+
+nsresult
+nsEmbedStream::AppendToStream(const uint8_t* aData, uint32_t aLen)
+{
+ nsresult rv;
+ NS_ENSURE_STATE(mOutputStream);
+
+ uint32_t bytesWritten = 0;
+ rv = mOutputStream->Write(reinterpret_cast<const char*>(aData),
+ aLen, &bytesWritten);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ NS_ASSERTION(bytesWritten == aLen,
+ "underlying buffer couldn't handle the write");
+ return rv;
+}
+
+nsresult
+nsEmbedStream::CloseStream(void)
+{
+ nsresult rv = NS_OK;
+
+ // NS_ENSURE_STATE returns NS_ERROR_UNEXPECTED if the condition isn't
+ // satisfied; this is exactly what we want to return.
+ NS_ENSURE_STATE(mOutputStream);
+ mOutputStream->Close();
+ mOutputStream = nullptr;
+
+ return rv;
+}
diff --git a/embedding/browser/nsEmbedStream.h b/embedding/browser/nsEmbedStream.h
new file mode 100644
index 000000000..03dca7936
--- /dev/null
+++ b/embedding/browser/nsEmbedStream.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsEmbedStream_h__
+#define nsEmbedStream_h__
+
+#include "nsCOMPtr.h"
+#include "nsIOutputStream.h"
+#include "nsIURI.h"
+#include "nsIWebBrowser.h"
+
+class nsEmbedStream : public nsISupports
+{
+public:
+ nsEmbedStream();
+
+ void InitOwner(nsIWebBrowser* aOwner);
+ nsresult Init(void);
+
+ nsresult OpenStream(nsIURI* aBaseURI, const nsACString& aContentType);
+ nsresult AppendToStream(const uint8_t* aData, uint32_t aLen);
+ nsresult CloseStream(void);
+
+ NS_DECL_ISUPPORTS
+
+protected:
+ virtual ~nsEmbedStream();
+
+private:
+ nsIWebBrowser* mOwner;
+ nsCOMPtr<nsIOutputStream> mOutputStream;
+};
+
+#endif // nsEmbedStream_h__
diff --git a/embedding/browser/nsICommandHandler.idl b/embedding/browser/nsICommandHandler.idl
new file mode 100644
index 000000000..15a2fd23b
--- /dev/null
+++ b/embedding/browser/nsICommandHandler.idl
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface mozIDOMWindowProxy;
+
+[scriptable, uuid(08aed3cc-69f7-47ba-a110-f2efa8a6d7ea)]
+interface nsICommandHandlerInit : nsISupports
+{
+ attribute mozIDOMWindowProxy window;
+};
+
+[scriptable, uuid(34A4FCF0-66FC-11d4-9528-0020183BF181)]
+interface nsICommandHandler : nsISupports
+{
+ /*
+ * Execute the specified command with the specified parameters and return
+ * the result to the caller. The format of the command, parameters and
+ * the result are determined by the acutal implementation.
+ */
+ string exec(in string aCommand, in string aParameters);
+ /*
+ * Query the status of the specified command with the specified parameters
+ * and return the result to the caller. The format of the command,
+ * parameters and the result are determined by the implementation.
+ */
+ string query(in string aCommand, in string aParameters);
+};
+
+%{ C++
+// {3A449110-66FD-11d4-9528-0020183BF181} -
+#define NS_COMMANDHANDLER_CID \
+{ 0x3a449110, 0x66fd, 0x11d4, { 0x95, 0x28, 0x0, 0x20, 0x18, 0x3b, 0xf1, 0x81 } }
+#define NS_COMMANDHANDLER_CONTRACTID \
+"@mozilla.org/embedding/browser/nsCommandHandler;1"
+%}
+
diff --git a/embedding/browser/nsIContextMenuListener.idl b/embedding/browser/nsIContextMenuListener.idl
new file mode 100644
index 000000000..2e4d1c1e9
--- /dev/null
+++ b/embedding/browser/nsIContextMenuListener.idl
@@ -0,0 +1,65 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMEvent;
+interface nsIDOMNode;
+
+/**
+ * An optional interface for embedding clients wishing to receive
+ * notifications for context menu events (e.g. generated by
+ * a user right-mouse clicking on a link). The embedder implements
+ * this interface on the web browser chrome object associated
+ * with the window that notifications are required for. When a context
+ * menu event, the browser will call this interface if present.
+ *
+ * @see nsIDOMNode
+ * @see nsIDOMEvent
+ */
+[scriptable, uuid(3478b6b0-3875-11d4-94ef-0020183bf181)]
+interface nsIContextMenuListener : nsISupports
+{
+ /** Flag. No context. */
+ const unsigned long CONTEXT_NONE = 0;
+ /** Flag. Context is a link element. */
+ const unsigned long CONTEXT_LINK = 1;
+ /** Flag. Context is an image element. */
+ const unsigned long CONTEXT_IMAGE = 2;
+ /** Flag. Context is the whole document. */
+ const unsigned long CONTEXT_DOCUMENT = 4;
+ /** Flag. Context is a text area element. */
+ const unsigned long CONTEXT_TEXT = 8;
+ /** Flag. Context is an input element. */
+ const unsigned long CONTEXT_INPUT = 16;
+
+ /**
+ * Called when the browser receives a context menu event (e.g. user is right-mouse
+ * clicking somewhere on the document). The combination of flags, event and node
+ * provided in the call indicate where and what was clicked on.
+ *
+ * The following table describes what context flags and node combinations are
+ * possible.
+ *
+ * <TABLE>
+ * <TR><TD><B>aContextFlag</B></TD><TD>aNode</TD></TR>
+ * <TR><TD>CONTEXT_LINK</TD><TD>&lt;A&gt;</TD></TR>
+ * <TR><TD>CONTEXT_IMAGE</TD><TD>&lt;IMG&gt;</TD></TR>
+ * <TR><TD>CONTEXT_IMAGE | CONTEXT_LINK</TD><TD>&lt;IMG&gt;
+ * with an &lt;A&gt; as an ancestor</TD></TR>
+ * <TR><TD>CONTEXT_INPUT</TD><TD>&lt;INPUT&gt;</TD></TR>
+ * <TR><TD>CONTEXT_TEXT</TD><TD>&lt;TEXTAREA&gt;</TD></TR>
+ * <TR><TD>CONTEXT_DOCUMENT</TD><TD>&lt;HTML&gt;</TD></TR>
+ * </TABLE>
+ *
+ * @param aContextFlags Flags indicating the kind of context.
+ * @param aEvent The DOM context menu event.
+ * @param aNode The DOM node most relevant to the context.
+ *
+ * @return <CODE>NS_OK</CODE> always.
+ */
+ void onShowContextMenu(in unsigned long aContextFlags, in nsIDOMEvent aEvent, in nsIDOMNode aNode);
+};
+
diff --git a/embedding/browser/nsIContextMenuListener2.idl b/embedding/browser/nsIContextMenuListener2.idl
new file mode 100644
index 000000000..19d898011
--- /dev/null
+++ b/embedding/browser/nsIContextMenuListener2.idl
@@ -0,0 +1,121 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMEvent;
+interface nsIDOMNode;
+interface imgIContainer;
+interface nsIURI;
+interface nsIContextMenuInfo;
+
+/* THIS IS A PUBLIC EMBEDDING API */
+
+/**
+ * nsIContextMenuListener2
+ *
+ * This is an extended version of nsIContextMenuListener
+ * It provides a helper class, nsIContextMenuInfo, to allow access to
+ * background images as well as various utilities.
+ *
+ * @see nsIContextMenuListener
+ * @see nsIContextMenuInfo
+ */
+
+[scriptable, uuid(7fb719b3-d804-4964-9596-77cf924ee314)]
+interface nsIContextMenuListener2 : nsISupports
+{
+ /** Flag. No context. */
+ const unsigned long CONTEXT_NONE = 0;
+ /** Flag. Context is a link element. */
+ const unsigned long CONTEXT_LINK = 1;
+ /** Flag. Context is an image element. */
+ const unsigned long CONTEXT_IMAGE = 2;
+ /** Flag. Context is the whole document. */
+ const unsigned long CONTEXT_DOCUMENT = 4;
+ /** Flag. Context is a text area element. */
+ const unsigned long CONTEXT_TEXT = 8;
+ /** Flag. Context is an input element. */
+ const unsigned long CONTEXT_INPUT = 16;
+ /** Flag. Context is a background image. */
+ const unsigned long CONTEXT_BACKGROUND_IMAGE = 32;
+
+ /**
+ * Called when the browser receives a context menu event (e.g. user is right-mouse
+ * clicking somewhere on the document). The combination of flags, along with the
+ * attributes of <CODE>aUtils</CODE>, indicate where and what was clicked on.
+ *
+ * The following table describes what context flags and node combinations are
+ * possible.
+ *
+ * aContextFlags aUtils.targetNode
+ *
+ * CONTEXT_LINK <A>
+ * CONTEXT_IMAGE <IMG>
+ * CONTEXT_IMAGE | CONTEXT_LINK <IMG> with <A> as an ancestor
+ * CONTEXT_INPUT <INPUT>
+ * CONTEXT_INPUT | CONTEXT_IMAGE <INPUT> with type=image
+ * CONTEXT_TEXT <TEXTAREA>
+ * CONTEXT_DOCUMENT <HTML>
+ * CONTEXT_BACKGROUND_IMAGE <HTML> with background image
+ *
+ * @param aContextFlags Flags indicating the kind of context.
+ * @param aUtils Context information and helper utilities.
+ *
+ * @see nsIContextMenuInfo
+ */
+ void onShowContextMenu(in unsigned long aContextFlags, in nsIContextMenuInfo aUtils);
+};
+
+/**
+ * nsIContextMenuInfo
+ *
+ * A helper object for implementors of nsIContextMenuListener2.
+ */
+
+[scriptable, uuid(2f977d56-5485-11d4-87e2-0010a4e75ef2)]
+interface nsIContextMenuInfo : nsISupports
+{
+ /**
+ * The DOM context menu event.
+ */
+ readonly attribute nsIDOMEvent mouseEvent;
+
+ /**
+ * The DOM node most relevant to the context.
+ */
+ readonly attribute nsIDOMNode targetNode;
+
+ /**
+ * Given the <CODE>CONTEXT_LINK</CODE> flag, <CODE>targetNode</CODE> may not
+ * nescesarily be a link. This returns the anchor from <CODE>targetNode</CODE>
+ * if it has one or that of its nearest ancestor if it does not.
+ */
+ readonly attribute AString associatedLink;
+
+ /**
+ * Given the <CODE>CONTEXT_IMAGE</CODE> flag, these methods can be
+ * used in order to get the image for viewing, saving, or for the clipboard.
+ *
+ * @return <CODE>NS_OK</CODE> if successful, otherwise <CODE>NS_ERROR_FAILURE</CODE> if no
+ * image was found, or NS_ERROR_NULL_POINTER if an internal error occurs where we think there
+ * is an image, but for some reason it cannot be returned.
+ */
+
+ readonly attribute imgIContainer imageContainer;
+ readonly attribute nsIURI imageSrc;
+
+ /**
+ * Given the <CODE>CONTEXT_BACKGROUND_IMAGE</CODE> flag, these methods can be
+ * used in order to get the image for viewing, saving, or for the clipboard.
+ *
+ * @return <CODE>NS_OK</CODE> if successful, otherwise <CODE>NS_ERROR_FAILURE</CODE> if no background
+ * image was found, or NS_ERROR_NULL_POINTER if an internal error occurs where we think there is a
+ * background image, but for some reason it cannot be returned.
+ */
+
+ readonly attribute imgIContainer backgroundImageContainer;
+ readonly attribute nsIURI backgroundImageSrc;
+};
diff --git a/embedding/browser/nsIEmbeddingSiteWindow.idl b/embedding/browser/nsIEmbeddingSiteWindow.idl
new file mode 100644
index 000000000..a8eefacb4
--- /dev/null
+++ b/embedding/browser/nsIEmbeddingSiteWindow.idl
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/* THIS IS A PUBLIC EMBEDDING API */
+
+/**
+ * The nsIEmbeddingSiteWindow is implemented by the embedder to provide
+ * Gecko with the means to call up to the host to resize the window,
+ * hide or show it and set/get its title.
+ */
+[scriptable, uuid(0b976267-4aaa-4f36-a2d4-27b5ca8d73bb)]
+interface nsIEmbeddingSiteWindow : nsISupports
+{
+ /**
+ * Flag indicates that position of the top left corner of the outer area
+ * is required/specified.
+ *
+ * @see setDimensions
+ * @see getDimensions
+ */
+ const unsigned long DIM_FLAGS_POSITION = 1;
+
+ /**
+ * Flag indicates that the size of the inner area is required/specified.
+ *
+ * @note The inner and outer flags are mutually exclusive and it is
+ * invalid to combine them.
+ *
+ * @see setDimensions
+ * @see getDimensions
+ * @see DIM_FLAGS_SIZE_OUTER
+ */
+ const unsigned long DIM_FLAGS_SIZE_INNER = 2;
+
+ /**
+ * Flag indicates that the size of the outer area is required/specified.
+ *
+ * @see setDimensions
+ * @see getDimensions
+ * @see DIM_FLAGS_SIZE_INNER
+ */
+ const unsigned long DIM_FLAGS_SIZE_OUTER = 4;
+
+ /**
+ * Flag indicates that the x parameter should be ignored.
+ *
+ * @see setDimensions
+ */
+ const unsigned long DIM_FLAGS_IGNORE_X = 8;
+
+ /**
+ * Flag indicates that the y parameter should be ignored.
+ *
+ * @see setDimensions
+ */
+ const unsigned long DIM_FLAGS_IGNORE_Y = 16;
+
+ /**
+ * Flag indicates that the cx parameter should be ignored.
+ *
+ * @see setDimensions
+ */
+ const unsigned long DIM_FLAGS_IGNORE_CX = 32;
+
+ /**
+ * Flag indicates that the cy parameter should be ignored.
+ *
+ * @see setDimensions
+ */
+ const unsigned long DIM_FLAGS_IGNORE_CY = 64;
+
+
+ /**
+ * Sets the dimensions for the window; the position & size. The
+ * flags to indicate what the caller wants to set and whether the size
+ * refers to the inner or outer area. The inner area refers to just
+ * the embedded area, wheras the outer area can also include any
+ * surrounding chrome, window frame, title bar, and so on.
+ *
+ * @param flags Combination of position, inner and outer size flags.
+ * The ignore flags are telling the parent to use the
+ * current values for those dimensions and ignore the
+ * corresponding parameters the child sends.
+ * @param x Left hand corner of the outer area.
+ * @param y Top corner of the outer area.
+ * @param cx Width of the inner or outer area.
+ * @param cy Height of the inner or outer area.
+ *
+ * @return <code>NS_OK</code> if operation was performed correctly;
+ * <code>NS_ERROR_UNEXPECTED</code> if window could not be
+ * destroyed;
+ * <code>NS_ERROR_INVALID_ARG</code> for bad flag combination
+ * or illegal dimensions.
+ *
+ * @see getDimensions
+ * @see DIM_FLAGS_POSITION
+ * @see DIM_FLAGS_SIZE_OUTER
+ * @see DIM_FLAGS_SIZE_INNER
+ */
+ void setDimensions(in unsigned long flags, in long x, in long y, in long cx, in long cy);
+
+ /**
+ * Gets the dimensions of the window. The caller may pass
+ * <CODE>nullptr</CODE> for any value it is uninterested in receiving.
+ *
+ * @param flags Combination of position, inner and outer size flag .
+ * @param x Left hand corner of the outer area; or <CODE>nullptr</CODE>.
+ * @param y Top corner of the outer area; or <CODE>nullptr</CODE>.
+ * @param cx Width of the inner or outer area; or <CODE>nullptr</CODE>.
+ * @param cy Height of the inner or outer area; or <CODE>nullptr</CODE>.
+ *
+ * @see setDimensions
+ * @see DIM_FLAGS_POSITION
+ * @see DIM_FLAGS_SIZE_OUTER
+ * @see DIM_FLAGS_SIZE_INNER
+ */
+ void getDimensions(in unsigned long flags, out long x, out long y, out long cx, out long cy);
+
+ /**
+ * Give the window focus.
+ */
+ void setFocus();
+
+ /**
+ * Visibility of the window.
+ */
+ attribute boolean visibility;
+
+ /**
+ * Title of the window.
+ */
+ attribute wstring title;
+
+ /**
+ * Native window for the site's window. The implementor should copy the
+ * native window object into the address supplied by the caller. The
+ * type of the native window that the address refers to is platform
+ * and OS specific as follows:
+ *
+ * <ul>
+ * <li>On Win32 it is an <CODE>HWND</CODE>.</li>
+ * <li>On MacOS this is a <CODE>WindowPtr</CODE>.</li>
+ * <li>On GTK this is a <CODE>GtkWidget*</CODE>.</li>
+ * </ul>
+ */
+ [noscript] readonly attribute voidPtr siteWindow;
+
+ /**
+ * Blur the window. This should unfocus the window and send an onblur event.
+ */
+ void blur();
+};
diff --git a/embedding/browser/nsIPrintPreviewNavigation.idl b/embedding/browser/nsIPrintPreviewNavigation.idl
new file mode 100644
index 000000000..87a39ff72
--- /dev/null
+++ b/embedding/browser/nsIPrintPreviewNavigation.idl
@@ -0,0 +1,52 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+
+/**
+ * The nsIPrintPreviewNavigation
+ */
+[scriptable, uuid(8148E3F1-2E8B-11d5-A86C-00105A183419)]
+interface nsIPrintPreviewNavigation : nsISupports
+{
+
+ readonly attribute long pageCount;
+
+
+ /**
+ * Preview the next Page
+ *
+ * Return - PR_TRUE if success
+ */
+ boolean nextPage();
+
+ /**
+ * Preview the previous Page
+ *
+ * Return - PR_TRUE if success
+ */
+ boolean previousPage();
+
+ /**
+ * Go to a page to preview
+ *
+ * aPageNumber - Page to go preview
+ * Return - PR_TRUE if success
+ */
+ boolean goToPage(unsigned long aPageNumber);
+
+
+ /**
+ * Skip pages
+ *
+ * aNumPages - number of pages to skip including the current page. Neg. goes back
+ * Return - true if success
+ */
+ boolean skipPages(long aNumPages);
+
+
+};
diff --git a/embedding/browser/nsIPrintingPromptService.idl b/embedding/browser/nsIPrintingPromptService.idl
new file mode 100644
index 000000000..81d79b57c
--- /dev/null
+++ b/embedding/browser/nsIPrintingPromptService.idl
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Doc interface here */
+
+#include "nsISupports.idl"
+#include "nsIWebBrowserPrint.idl"
+#include "nsIWebProgressListener.idl"
+#include "nsIPrintProgressParams.idl"
+#include "nsIPrintSettings.idl"
+#include "nsIObserver.idl"
+
+interface nsIDOMWindow;
+
+[scriptable, uuid(328daa3e-09e4-455f-bb6f-0a921766042f)]
+interface nsIPrintingPromptService : nsISupports
+{
+ /**
+ * This service enables embedders to implement their own Print and Progress Dialogs.
+ * Each platform has a "base" or "basckstop" implementation of the service. The
+ * service is automatically registered at start up.
+ *
+ * Historically, platform toolkits with native dialogs have implemented them in the GFX layer
+ * Usually they were displayed when a new DeviceContextSpec specific to that platform
+ * was created.
+ *
+ * Windows: The GFX layer no longers supports default toolkit behavior for displaying the
+ * native Print Dialog.
+ * If an embedder implemented service returns any error code (other than NS_ERROR_ABORT)
+ * printing will terminate.
+ *
+ * Returning NS_OK assumes that the PrintSettings object was correctly filled in and
+ * if it does not have valid fields for printer name, etc. it may also terminate.
+ *
+ * Defaults for platform service:
+ * showPrintDialog - displays a native dialog
+ * showPageSetup - displays a XUL dialog
+ * showProgress - displays a XUL dialog
+ * showPrinterProperties - n/a
+ *
+ * Summary for Windows Embedders:
+ * Stated once again: There is no "fallback" native platform support in GFX for the
+ * displaying of the native print dialog. The current default implementation for Windows
+ * display a native print dialog but a XUL-based progress dialog.
+ * If you wish to have a native progress dialog on Windows you will have to create and
+ * register your own service.
+ *
+ * Note: The Windows version Mozilla implements this service which is
+ * automatically built and registered for you. You can use it as an example.
+ * It is located at "mozilla/embedding/components/printingui/win". That service
+ * is capable of displaying a native print dialog and a XUL progress dialog.
+ *
+ * To fly your own dialog you may:
+ *
+ * 1) Implement this service to display at least the Print Dialog and a Print Progress Dialog
+ * or you may implement just one of the dialogs and pass back NS_ERROR_NOT_IMPLEMENTED
+ * for any of the others.
+ *
+ * 2) For the Print Dialog:
+ * You may stub out this service by having all the methods return NS_ERROR_NOT_IMPLEMENTED.
+ * You can then fly you own dialog and then properly fill in the PrintSettings object
+ * before calling nsIWebBrowserPrint's Print method. If you stub out this service
+ * you MUST set "printSilent" to true, if you do not, Printing will terminate and an
+ * error dialog will be displayed.
+ *
+ * Mac: The GFX layer still supports default toolkit behavior for displaying the Print Dialog.
+ * If an embedder implemented service returns NS_ERROR_NOT_IMPLEMENTED for "showPrintDialog"
+ * The toolkit will display the native print dialog.
+ *
+ * Defaults for platform service:
+ * Mac OS9: showPrintDialog - displays a native dialog
+ * showPageSetup - displays a native dialog
+ * showProgress - displays a XUL dialog
+ * showPrinterProperties - n/a
+ *
+ * Mac OSX: showPrintDialog - displays a native dialog
+ * showPageSetup - displays a native dialog
+ * showProgress - not implemented (provided by OS)
+ * showPrinterProperties - n/a
+ *
+ * GTK: There are no native dialog for GTK.
+ *
+ * Defaults for platform service:
+ * showPrintDialog - displays a XUL dialog
+ * showPageSetup - displays a XUL dialog
+ * showProgress - displays a XUL dialog
+ * showPrinterProperties - displays a XUL dialog
+ *
+ */
+
+
+
+ /**
+ * Show the Print Dialog
+ *
+ * @param parent - a DOM windows the dialog will be parented to (required)
+ * @param webBrowserPrint - represents the document to be printed (required)
+ * @param printSettings - PrintSettings for print "job" (required)
+ *
+ */
+ void showPrintDialog(in mozIDOMWindowProxy parent,
+ in nsIWebBrowserPrint webBrowserPrint,
+ in nsIPrintSettings printSettings);
+
+ /**
+ * Shows the print progress dialog
+ *
+ * @param parent - a DOM windows the dialog will be parented to
+ * @param webBrowserPrint - represents the document to be printed
+ * @param printSettings - PrintSettings for print "job"
+ * @param openDialogObserver - an observer that will be notifed when the dialog is opened
+ * @param isForPrinting - true - for printing, false for print preview
+ * @param webProgressListener - additional listener can be registered for progress notifications
+ * @param printProgressParams - parameter object for passing progress state
+ * @param notifyOnOpen - this indicates that the observer will be notified when the progress
+ * dialog has been opened. If false is returned it means the observer
+ * (usually the caller) shouldn't wait
+ * For Print Preview Progress there is intermediate progress
+ */
+ void showProgress(in mozIDOMWindowProxy parent,
+ in nsIWebBrowserPrint webBrowserPrint,
+ in nsIPrintSettings printSettings,
+ in nsIObserver openDialogObserver,
+ in boolean isForPrinting,
+ out nsIWebProgressListener webProgressListener,
+ out nsIPrintProgressParams printProgressParams,
+ out boolean notifyOnOpen);
+
+ /**
+ * Shows the print progress dialog
+ *
+ * @param parent - a DOM windows the dialog will be parented to (required)
+ * @param printSettings - PrintSettings for page setup (required)
+ * @param aObs - An observer to know if the contents of the Print Settings
+ * object has changed while the dialog is being shown.
+ * For example, some platforms may implement an "Apply" button (not required)
+ */
+ void showPageSetup(in mozIDOMWindowProxy parent,
+ in nsIPrintSettings printSettings,
+ in nsIObserver aObs);
+
+ /**
+ * Sometimes platforms need to bring up a special properties dialog for showing
+ * print specific properties. Although the PrintSettings has a place to set the
+ * printer name, here is is an argument to be clear as to what printer is being
+ * asked to have the properties set for it. The Printer name in the PS is ignored.
+ *
+ * @param parent - a DOM windows the dialog will be parented to (required)
+ * @param printerName - name of printer (required)
+ * @param printSettings - PrintSettings for page setup (required)
+ */
+ void showPrinterProperties(in mozIDOMWindowProxy parent,
+ in wstring printerName,
+ in nsIPrintSettings printSettings);
+
+};
+
+%{C++
+// {260FEDC5-524D-4aa6-9A41-E829F4C78B92}
+#define NS_PRINTINGPROMPTSERVICE_IID \
+ {0x260fedc5, 0x524d, 0x4aa6, { 0x9a, 0x41, 0xe8, 0x29, 0xf4, 0xc7, 0x8b, 0x92}}
+%}
+
diff --git a/embedding/browser/nsITooltipListener.idl b/embedding/browser/nsITooltipListener.idl
new file mode 100644
index 000000000..c6e53736f
--- /dev/null
+++ b/embedding/browser/nsITooltipListener.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * An optional interface for embedding clients wishing to receive
+ * notifications for when a tooltip should be displayed or removed.
+ * The embedder implements this interface on the web browser chrome
+ * object associated with the window that notifications are required
+ * for.
+ *
+ * @see nsITooltipTextProvider
+ */
+[scriptable, uuid(44b78386-1dd2-11b2-9ad2-e4eee2ca1916)]
+interface nsITooltipListener : nsISupports
+{
+ /**
+ * Called when a tooltip should be displayed.
+ *
+ * @param aXCoords The tooltip left edge X coordinate.
+ * @param aYCoords The tooltip top edge Y coordinate.
+ * @param aTipText The text to display in the tooltip, typically obtained
+ * from the TITLE attribute of the node (or containing parent)
+ * over which the pointer has been positioned.
+ * @param aTipDir The direction (ltr or rtl) in which to display the text
+ *
+ * @note
+ * Coordinates are specified in pixels, relative to the top-left
+ * corner of the browser area.
+ *
+ * @return <code>NS_OK</code> if the tooltip was displayed.
+ */
+ void onShowTooltip(in long aXCoords, in long aYCoords, in wstring aTipText,
+ in wstring aTipDir);
+
+ /**
+ * Called when the tooltip should be hidden, either because the pointer
+ * has moved or the tooltip has timed out.
+ */
+ void onHideTooltip();
+};
diff --git a/embedding/browser/nsITooltipTextProvider.idl b/embedding/browser/nsITooltipTextProvider.idl
new file mode 100644
index 000000000..e87344ae0
--- /dev/null
+++ b/embedding/browser/nsITooltipTextProvider.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMNode;
+
+/**
+ * An interface implemented by a tooltip text provider service. This
+ * service is called to discover what tooltip text is associated
+ * with the node that the pointer is positioned over.
+ *
+ * Embedders may implement and register their own tooltip text provider
+ * service if they wish to provide different tooltip text.
+ *
+ * The default service returns the text stored in the TITLE
+ * attribute of the node or a containing parent.
+ *
+ * @note
+ * The tooltip text provider service is registered with the contract
+ * defined in NS_TOOLTIPTEXTPROVIDER_CONTRACTID.
+ *
+ * @see nsITooltipListener
+ * @see nsIComponentManager
+ * @see nsIDOMNode
+ */
+[scriptable, uuid(b128a1e6-44f3-4331-8fbe-5af360ff21ee)]
+interface nsITooltipTextProvider : nsISupports
+{
+ /**
+ * Called to obtain the tooltip text for a node.
+ *
+ * @arg aNode The node to obtain the text from.
+ * @arg aText The tooltip text.
+ * @arg aDirection The text direction (ltr or rtl) to use
+ *
+ * @return <CODE>PR_TRUE</CODE> if tooltip text is associated
+ * with the node and was returned in the aText argument;
+ * <CODE>PR_FALSE</CODE> otherwise.
+ */
+ boolean getNodeText(in nsIDOMNode aNode, out wstring aText, out wstring aDirection);
+};
diff --git a/embedding/browser/nsIWebBrowser.idl b/embedding/browser/nsIWebBrowser.idl
new file mode 100644
index 000000000..e6ff70ae7
--- /dev/null
+++ b/embedding/browser/nsIWebBrowser.idl
@@ -0,0 +1,163 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIInterfaceRequestor;
+interface nsIWebBrowserChrome;
+interface nsIURIContentListener;
+interface nsIDOMWindow;
+interface mozIDOMWindowProxy;
+interface nsIWeakReference;
+
+%{C++
+namespace mozilla {
+class DocShellOriginAttributes;
+}
+%}
+
+[ref] native const_OriginAttributesRef(const mozilla::DocShellOriginAttributes);
+
+/**
+ * The nsIWebBrowser interface is implemented by web browser objects.
+ * Embedders use this interface during initialisation to associate
+ * the new web browser instance with the embedders chrome and
+ * to register any listeners. The interface may also be used at runtime
+ * to obtain the content DOM window and from that the rest of the DOM.
+ */
+[scriptable, uuid(4052b6da-4faa-4646-b3a1-7e16a01c2dc2)]
+interface nsIWebBrowser : nsISupports
+{
+ /**
+ * Registers a listener of the type specified by the iid to receive
+ * callbacks. The browser stores a weak reference to the listener
+ * to avoid any circular dependencies.
+ * Typically this method will be called to register an object
+ * to receive <CODE>nsIWebProgressListener</CODE> or
+ * <CODE>nsISHistoryListener</CODE> notifications in which case the
+ * the IID is that of the interface.
+ *
+ * @param aListener The listener to be added.
+ * @param aIID The IID of the interface that will be called
+ * on the listener as appropriate.
+ * @return <CODE>NS_OK</CODE> for successful registration;
+ * <CODE>NS_ERROR_INVALID_ARG</CODE> if aIID is not
+ * supposed to be registered using this method;
+ * <CODE>NS_ERROR_FAILURE</CODE> either aListener did not
+ * expose the interface specified by the IID, or some
+ * other internal error occurred.
+ *
+ * @see removeWebBrowserListener
+ * @see nsIWeakReference
+ * @see nsIWebProgressListener
+ * @see nsISHistoryListener
+ *
+ * @return <CODE>NS_OK</CODE>, listener was successfully added;
+ * <CODE>NS_ERROR_INVALID_ARG</CODE>, one of the arguments was
+ * invalid or the object did not implement the interface
+ * specified by the IID.
+ */
+ void addWebBrowserListener(in nsIWeakReference aListener, in nsIIDRef aIID);
+
+ /**
+ * Removes a previously registered listener.
+ *
+ * @param aListener The listener to be removed.
+ * @param aIID The IID of the interface on the listener that will
+ * no longer be called.
+ *
+ * @return <CODE>NS_OK</CODE>, listener was successfully removed;
+ * <CODE>NS_ERROR_INVALID_ARG</CODE> arguments was invalid or
+ * the object did not implement the interface specified by the IID.
+ *
+ * @see addWebBrowserListener
+ * @see nsIWeakReference
+ */
+ void removeWebBrowserListener(in nsIWeakReference aListener, in nsIIDRef aIID);
+
+ /**
+ * The chrome object associated with the browser instance. The embedder
+ * must create one chrome object for <I>each</I> browser object
+ * that is instantiated. The embedder must associate the two by setting
+ * this property to point to the chrome object before creating the browser
+ * window via the browser's <CODE>nsIBaseWindow</CODE> interface.
+ *
+ * The chrome object must also implement <CODE>nsIEmbeddingSiteWindow</CODE>.
+ *
+ * The chrome may optionally implement <CODE>nsIInterfaceRequestor</CODE>,
+ * <CODE>nsIWebBrowserChromeFocus</CODE>,
+ * <CODE>nsIContextMenuListener</CODE> and
+ * <CODE>nsITooltipListener</CODE> to receive additional notifications
+ * from the browser object.
+ *
+ * The chrome object may optionally implement <CODE>nsIWebProgressListener</CODE>
+ * instead of explicitly calling <CODE>addWebBrowserListener</CODE> and
+ * <CODE>removeWebBrowserListener</CODE> to register a progress listener
+ * object. If the implementation does this, it must also implement
+ * <CODE>nsIWeakReference</CODE>.
+ *
+ * @note The implementation should not refcount the supplied chrome
+ * object; it should assume that a non <CODE>nullptr</CODE> value is
+ * always valid. The embedder must explicitly set this value back
+ * to nullptr if the chrome object is destroyed before the browser
+ * object.
+ *
+ * @see nsIBaseWindow
+ * @see nsIWebBrowserChrome
+ * @see nsIEmbeddingSiteWindow
+ * @see nsIInterfaceRequestor
+ * @see nsIWebBrowserChromeFocus
+ * @see nsIContextMenuListener
+ * @see nsITooltipListener
+ * @see nsIWeakReference
+ * @see nsIWebProgressListener
+ */
+ attribute nsIWebBrowserChrome containerWindow;
+
+ /**
+ * URI content listener parent. The embedder may set this property to
+ * their own implementation if they intend to override or prevent
+ * how certain kinds of content are loaded.
+ *
+ * @note If this attribute is set to an object that implements
+ * nsISupportsWeakReference, the implementation should get the
+ * nsIWeakReference and hold that. Otherwise, the implementation
+ * should not refcount this interface; it should assume that a non
+ * null value is always valid. In that case, the embedder should
+ * explicitly set this value back to null if the parent content
+ * listener is destroyed before the browser object.
+ *
+ * @see nsIURIContentListener
+ */
+ attribute nsIURIContentListener parentURIContentListener;
+
+ /**
+ * The top-level DOM window. The embedder may walk the entire
+ * DOM starting from this value.
+ *
+ * @see nsIDOMWindow
+ */
+ readonly attribute mozIDOMWindowProxy contentDOMWindow;
+
+ /**
+ * Whether this web browser is active. Active means that it's visible
+ * enough that we want to avoid certain optimizations like discarding
+ * decoded image data and throttling the refresh driver. In Firefox,
+ * this corresponds to the visible tab.
+ *
+ * Defaults to true. For optimal performance, set it to false when
+ * appropriate.
+ */
+ attribute boolean isActive;
+
+ /**
+ * Set Origin Attributes on the nsIWebBrowser.
+ * The Origin Attributes will be passed to the docshell once it has been
+ * created
+ */
+ [noscript, notxpcom, nostdcall, binaryname(SetOriginAttributes)]
+ void binarySetOriginAttributes(in const_OriginAttributesRef aOriginAttrs);
+};
diff --git a/embedding/browser/nsIWebBrowserChrome.idl b/embedding/browser/nsIWebBrowserChrome.idl
new file mode 100644
index 000000000..40f03cbe4
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserChrome.idl
@@ -0,0 +1,147 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIWebBrowser;
+interface nsIDocShellTreeItem;
+
+/**
+ * nsIWebBrowserChrome corresponds to the top-level, outermost window
+ * containing an embedded Gecko web browser.
+ */
+
+[scriptable, uuid(E8C414C4-DC38-4BA3-AB4E-EC4CBBE22907)]
+interface nsIWebBrowserChrome : nsISupports
+{
+ const unsigned long STATUS_SCRIPT = 0x00000001;
+ const unsigned long STATUS_LINK = 0x00000003;
+
+ /**
+ * Called when the status text in the chrome needs to be updated.
+ * @param statusType indicates what is setting the text
+ * @param status status string. null is an acceptable value meaning
+ * no status.
+ */
+ void setStatus(in unsigned long statusType, in wstring status);
+
+ /**
+ * The currently loaded WebBrowser. The browser chrome may be
+ * told to set the WebBrowser object to a new object by setting this
+ * attribute. In this case the implementer is responsible for taking the
+ * new WebBrowser object and doing any necessary initialization or setup
+ * as if it had created the WebBrowser itself. This includes positioning
+ * setting up listeners etc.
+ */
+ attribute nsIWebBrowser webBrowser;
+
+ /**
+ * Definitions for the chrome flags
+ */
+ const unsigned long CHROME_DEFAULT = 0x00000001;
+ const unsigned long CHROME_WINDOW_BORDERS = 0x00000002;
+ const unsigned long CHROME_WINDOW_CLOSE = 0x00000004;
+ const unsigned long CHROME_WINDOW_RESIZE = 0x00000008;
+ const unsigned long CHROME_MENUBAR = 0x00000010;
+ const unsigned long CHROME_TOOLBAR = 0x00000020;
+ const unsigned long CHROME_LOCATIONBAR = 0x00000040;
+ const unsigned long CHROME_STATUSBAR = 0x00000080;
+ const unsigned long CHROME_PERSONAL_TOOLBAR = 0x00000100;
+ const unsigned long CHROME_SCROLLBARS = 0x00000200;
+ const unsigned long CHROME_TITLEBAR = 0x00000400;
+ const unsigned long CHROME_EXTRA = 0x00000800;
+
+ // createBrowserWindow specific flags
+ const unsigned long CHROME_WITH_SIZE = 0x00001000;
+ const unsigned long CHROME_WITH_POSITION = 0x00002000;
+
+ // special cases
+ const unsigned long CHROME_WINDOW_MIN = 0x00004000;
+ const unsigned long CHROME_WINDOW_POPUP = 0x00008000;
+
+ // whether to open a new private window. CHROME_NON_PRIVATE_WINDOW
+ // forces the opened window to be non-private, and overrides
+ // CHROME_PRIVATE_WINDOW if it's set. CHROME_PRIVATE_WINDOW
+ // forces the opened window to be private. If neither of these
+ // flags are specified, the opened window will inherit the privacy
+ // status of its opener. If there is no opener window, the new
+ // window will be non-private.
+ //
+ // CHROME_PRIVATE_LIFETIME causes the docshell to affect private-browsing
+ // session lifetime. This flag is currently respected only for remote
+ // docshells.
+ const unsigned long CHROME_PRIVATE_WINDOW = 0x00010000;
+ const unsigned long CHROME_NON_PRIVATE_WINDOW = 0x00020000;
+ const unsigned long CHROME_PRIVATE_LIFETIME = 0x00040000;
+
+ // Whether this was opened by nsGlobalWindow::ShowModalDialog.
+ const unsigned long CHROME_MODAL_CONTENT_WINDOW = 0x00080000;
+
+ // Whether this window should use remote (out-of-process) tabs.
+ const unsigned long CHROME_REMOTE_WINDOW = 0x00100000;
+
+ // Prevents new window animations on Mac OS X Lion. Ignored on other
+ // platforms.
+ const unsigned long CHROME_MAC_SUPPRESS_ANIMATION = 0x01000000;
+
+ const unsigned long CHROME_WINDOW_RAISED = 0x02000000;
+ const unsigned long CHROME_WINDOW_LOWERED = 0x04000000;
+ const unsigned long CHROME_CENTER_SCREEN = 0x08000000;
+
+ // Make the new window dependent on the parent. This flag is only
+ // meaningful if CHROME_OPENAS_CHROME is set; content windows should not be
+ // dependent.
+ const unsigned long CHROME_DEPENDENT = 0x10000000;
+
+ // Note: The modal style bit just affects the way the window looks and does
+ // mean it's actually modal.
+ const unsigned long CHROME_MODAL = 0x20000000;
+ const unsigned long CHROME_OPENAS_DIALOG = 0x40000000;
+ const unsigned long CHROME_OPENAS_CHROME = 0x80000000;
+
+ const unsigned long CHROME_ALL = 0x00000ffe;
+
+ /**
+ * The chrome flags for this browser chrome. The implementation should
+ * reflect the value of this attribute by hiding or showing its chrome
+ * appropriately.
+ */
+ attribute unsigned long chromeFlags;
+
+ /**
+ * Asks the implementer to destroy the window associated with this
+ * WebBrowser object.
+ */
+ void destroyBrowserWindow();
+
+ /**
+ * Tells the chrome to size itself such that the browser will be the
+ * specified size.
+ * @param aCX new width of the browser
+ * @param aCY new height of the browser
+ */
+ void sizeBrowserTo(in long aCX, in long aCY);
+
+ /**
+ * Shows the window as a modal window.
+ * @return (the function error code) the status value specified by
+ * in exitModalEventLoop.
+ */
+ void showAsModal();
+
+ /**
+ * Is the window modal (that is, currently executing a modal loop)?
+ * @return true if it's a modal window
+ */
+ boolean isWindowModal();
+
+ /**
+ * Exit a modal event loop if we're in one. The implementation
+ * should also exit out of the loop if the window is destroyed.
+ * @param aStatus - the result code to return from showAsModal
+ */
+ void exitModalEventLoop(in nsresult aStatus);
+};
diff --git a/embedding/browser/nsIWebBrowserChrome2.idl b/embedding/browser/nsIWebBrowserChrome2.idl
new file mode 100644
index 000000000..4b479b400
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserChrome2.idl
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIWebBrowserChrome.idl"
+
+/**
+ * nsIWebBrowserChrome2 is an extension to nsIWebBrowserChrome.
+ */
+[scriptable, uuid(2585a7b1-7b47-43c4-bf17-c6bf84e09b7b)]
+interface nsIWebBrowserChrome2 : nsIWebBrowserChrome
+{
+ /**
+ * Called when the status text in the chrome needs to be updated. This
+ * method may be called instead of nsIWebBrowserChrome::SetStatus. An
+ * implementor of this method, should still implement SetStatus.
+ *
+ * @param statusType
+ * Indicates what is setting the text.
+ * @param status
+ * Status string. Null is an acceptable value meaning no status.
+ * @param contextNode
+ * An object that provides context pertaining to the status type.
+ * If statusType is STATUS_LINK, then statusContext may be a DOM
+ * node corresponding to the source of the link. This value can
+ * be null if there is no context.
+ */
+ void setStatusWithContext(in unsigned long statusType,
+ in AString statusText,
+ in nsISupports statusContext);
+};
diff --git a/embedding/browser/nsIWebBrowserChrome3.idl b/embedding/browser/nsIWebBrowserChrome3.idl
new file mode 100644
index 000000000..a95cab911
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserChrome3.idl
@@ -0,0 +1,61 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIWebBrowserChrome2.idl"
+#include "nsIURI.idl"
+#include "nsIDOMNode.idl"
+
+interface nsIDocShell;
+interface nsIInputStream;
+
+/**
+ * nsIWebBrowserChrome3 is an extension to nsIWebBrowserChrome2.
+ */
+[scriptable, uuid(542b6625-35a9-426a-8257-c12a345383b0)]
+interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2
+{
+ /**
+ * Determines the appropriate target for a link.
+ *
+ * @param originalTarget
+ * The original link target.
+ * @param linkURI
+ * Link destination URI.
+ * @param aDOMNode
+ * Link DOM node.
+ * @param isAppTab
+ * Whether or not the link is in an app tab.
+ * @returns A new link target, if appropriate.
+ * Otherwise returns originalTarget.
+ */
+ AString onBeforeLinkTraversal(in AString originalTarget,
+ in nsIURI linkURI,
+ in nsIDOMNode linkNode,
+ in boolean isAppTab);
+
+ /**
+ * Determines whether a load should continue.
+ *
+ * @param aDocShell
+ * The docshell performing the load.
+ * @param aURI
+ * The URI being loaded.
+ * @param aReferrer
+ * The referrer of the load.
+ */
+ bool shouldLoadURI(in nsIDocShell aDocShell,
+ in nsIURI aURI,
+ in nsIURI aReferrer);
+
+ /**
+ * Attempts to load the currently loaded page into a fresh process to increase
+ * available memory.
+ *
+ * @param aDocShell
+ * The docshell performing the load.
+ */
+ bool reloadInFreshProcess(in nsIDocShell aDocShell,
+ in nsIURI aURI,
+ in nsIURI aReferrer);
+};
diff --git a/embedding/browser/nsIWebBrowserChromeFocus.idl b/embedding/browser/nsIWebBrowserChromeFocus.idl
new file mode 100644
index 000000000..8e0b849b9
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserChromeFocus.idl
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 0 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * The nsIWebBrowserChromeFocus is implemented by the same object as the
+ * nsIEmbeddingSiteWindow. It represents the focus up-calls from mozilla
+ * to the embedding chrome. See mozilla bug #70224 for gratuitous info.
+ */
+
+[scriptable, uuid(947B2EE6-51ED-4C2B-9F45-426C27CA84C6)]
+interface nsIWebBrowserChromeFocus : nsISupports
+{
+ /**
+ * Set the focus at the next focusable element in the chrome. If
+ * aForDocumentNavigation is true, this was a document navigation, so
+ * focus the parent window.
+ */
+
+ void focusNextElement(in bool aForDocumentNavigation);
+
+ /**
+ * Set the focus at the previous focusable element in the chrome.
+ */
+
+ void focusPrevElement(in bool aForDocumentNavigation);
+
+};
diff --git a/embedding/browser/nsIWebBrowserFocus.idl b/embedding/browser/nsIWebBrowserFocus.idl
new file mode 100644
index 000000000..e2b4a2788
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserFocus.idl
@@ -0,0 +1,76 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+interface mozIDOMWindowProxy;
+interface nsIDOMElement;
+
+#include "nsISupports.idl"
+
+/**
+ * nsIWebBrowserFocus
+ * Interface that embedders use for controlling and interacting
+ * with the browser focus management. The embedded browser can be focused by
+ * clicking in it or tabbing into it. If the browser is currently focused and
+ * the embedding application's top level window is disabled, deactivate() must
+ * be called, and activate() called again when the top level window is
+ * reactivated for the browser's focus memory to work correctly.
+ */
+
+[scriptable, uuid(7f8c754e-5b36-44be-bc96-191b49f08ea6)]
+interface nsIWebBrowserFocus : nsISupports
+{
+ /**
+ * MANDATORY
+ * activate() is a mandatory call that must be made to the browser
+ * when the embedding application's window is activated *and* the
+ * browser area was the last thing in focus. This method can also be called
+ * if the embedding application wishes to give the browser area focus,
+ * without affecting the currently focused element within the browser.
+ *
+ * @note
+ * If you fail to make this call, mozilla focus memory will not work
+ * correctly.
+ */
+ void activate();
+
+ /**
+ * MANDATORY
+ * deactivate() is a mandatory call that must be made to the browser
+ * when the embedding application's window is deactivated *and* the
+ * browser area was the last thing in focus. On non-windows platforms,
+ * deactivate() should also be called when focus moves from the browser
+ * to the embedding chrome.
+ *
+ * @note
+ * If you fail to make this call, mozilla focus memory will not work
+ * correctly.
+ */
+ void deactivate();
+
+ /**
+ * Give the first element focus within mozilla
+ * (i.e. TAB was pressed and focus should enter mozilla)
+ */
+ void setFocusAtFirstElement();
+
+ /**
+ * Give the last element focus within mozilla
+ * (i.e. SHIFT-TAB was pressed and focus should enter mozilla)
+ */
+ void setFocusAtLastElement();
+
+ /**
+ * The currently focused nsDOMWindow when the browser is active,
+ * or the last focused nsDOMWindow when the browser is inactive.
+ */
+ attribute mozIDOMWindowProxy focusedWindow;
+
+ /**
+ * The currently focused nsDOMElement when the browser is active,
+ * or the last focused nsDOMElement when the browser is inactive.
+ */
+ attribute nsIDOMElement focusedElement;
+};
diff --git a/embedding/browser/nsIWebBrowserPrint.idl b/embedding/browser/nsIWebBrowserPrint.idl
new file mode 100644
index 000000000..c5a014e6a
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserPrint.idl
@@ -0,0 +1,152 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface mozIDOMWindowProxy;
+interface nsIPrintSettings;
+interface nsIWebProgressListener;
+
+/**
+ * nsIWebBrowserPrint corresponds to the main interface
+ * for printing an embedded Gecko web browser window/document
+ */
+[scriptable, uuid(c9a934ed-fff1-4971-bfba-6c25ad70e1e6)]
+interface nsIWebBrowserPrint : nsISupports
+{
+ /**
+ * PrintPreview Navigation Constants
+ */
+ const short PRINTPREVIEW_GOTO_PAGENUM = 0;
+ const short PRINTPREVIEW_PREV_PAGE = 1;
+ const short PRINTPREVIEW_NEXT_PAGE = 2;
+ const short PRINTPREVIEW_HOME = 3;
+ const short PRINTPREVIEW_END = 4;
+
+ /**
+ * Returns a "global" PrintSettings object
+ * Creates a new the first time, if one doesn't exist.
+ *
+ * Then returns the same object each time after that.
+ *
+ * Initializes the globalPrintSettings from the default printer
+ */
+ readonly attribute nsIPrintSettings globalPrintSettings;
+
+ /**
+ * Returns a pointer to the PrintSettings object that
+ * that was passed into either "print" or "print preview"
+ *
+ * This enables any consumers of the interface to have access
+ * to the "current" PrintSetting at later points in the execution
+ */
+ readonly attribute nsIPrintSettings currentPrintSettings;
+
+ /**
+ * Returns a pointer to the current child DOMWindow
+ * that is being print previewed. (FrameSet Frames)
+ *
+ * Returns null if parent document is not a frameset or the entire FrameSet
+ * document is being print previewed
+ *
+ * This enables any consumers of the interface to have access
+ * to the "current" child DOMWindow at later points in the execution
+ */
+ readonly attribute mozIDOMWindowProxy currentChildDOMWindow;
+
+ /**
+ * Returns whether it is in Print mode
+ */
+ readonly attribute boolean doingPrint;
+
+ /**
+ * Returns whether it is in Print Preview mode
+ */
+ readonly attribute boolean doingPrintPreview;
+
+ /**
+ * This returns whether the current document is a frameset document
+ */
+ readonly attribute boolean isFramesetDocument;
+
+ /**
+ * This returns whether the current document is a frameset document
+ */
+ readonly attribute boolean isFramesetFrameSelected;
+
+ /**
+ * This returns whether there is an IFrame selected
+ */
+ readonly attribute boolean isIFrameSelected;
+
+ /**
+ * This returns whether there is a "range" selection
+ */
+ readonly attribute boolean isRangeSelection;
+
+ /**
+ * This returns the total number of pages for the Print Preview
+ */
+ readonly attribute long printPreviewNumPages;
+
+ /**
+ * Print the specified DOM window
+ *
+ * @param aThePrintSettings - Printer Settings for the print job, if aThePrintSettings is null
+ * then the global PS will be used.
+ * @param aWPListener - is updated during the print
+ * @return void
+ */
+ void print(in nsIPrintSettings aThePrintSettings,
+ in nsIWebProgressListener aWPListener);
+
+ /**
+ * Print Preview the specified DOM window
+ *
+ * @param aThePrintSettings - Printer Settings for the print preview, if aThePrintSettings is null
+ * then the global PS will be used.
+ * @param aChildDOMWin - DOM Window to be print previewed.
+ * @param aWPListener - is updated during the printpreview
+ * @return void
+ */
+ void printPreview(in nsIPrintSettings aThePrintSettings,
+ in mozIDOMWindowProxy aChildDOMWin,
+ in nsIWebProgressListener aWPListener);
+
+ /**
+ * Print Preview - Navigates within the window
+ *
+ * @param aNavType - navigation enum
+ * @param aPageNum - page num to navigate to when aNavType = ePrintPreviewGoToPageNum
+ * @return void
+ */
+ void printPreviewNavigate(in short aNavType, in long aPageNum);
+
+ /**
+ * Cancels the current print
+ * @return void
+ */
+ void cancel();
+
+ /**
+ * Returns an array of the names of all documents names (Title or URL)
+ * and sub-documents. This will return a single item if the attr "isFramesetDocument" is false
+ * and may return any number of items is "isFramesetDocument" is true
+ *
+ * @param aCount - returns number of printers returned
+ * @param aResult - returns array of names
+ * @return void
+ */
+ void enumerateDocumentNames(out uint32_t aCount,[retval, array, size_is(aCount)] out wstring aResult);
+
+ /**
+ * This exists PrintPreview mode and returns browser window to galley mode
+ * @return void
+ */
+ void exitPrintPreview();
+
+};
+
diff --git a/embedding/browser/nsIWebBrowserSetup.idl b/embedding/browser/nsIWebBrowserSetup.idl
new file mode 100644
index 000000000..d30645126
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserSetup.idl
@@ -0,0 +1,109 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * The nsIWebBrowserSetup interface lets you set properties on a browser
+ * object; you can do so at any time during the life cycle of the browser.
+ *
+ * @note Unless stated otherwise, settings are presumed to be enabled by
+ * default.
+ */
+[scriptable, uuid(F15398A0-8018-11d3-AF70-00A024FFC08C)]
+interface nsIWebBrowserSetup : nsISupports
+{
+ /**
+ * Boolean. Enables/disables plugin support for this browser.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_PLUGINS = 1;
+
+ /**
+ * Boolean. Enables/disables Javascript support for this browser.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_JAVASCRIPT = 2;
+
+ /**
+ * Boolean. Enables/disables meta redirect support for this browser.
+ * Meta redirect timers will be ignored if this option is disabled.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_META_REDIRECTS = 3;
+
+ /**
+ * Boolean. Enables/disables subframes within the browser
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_SUBFRAMES = 4;
+
+ /**
+ * Boolean. Enables/disables image loading for this browser
+ * window. If you disable the images, load a page, then enable the images,
+ * the page will *not* automatically load the images for the previously
+ * loaded page. This flag controls the state of a webBrowser at load time
+ * and does not automatically re-load a page when the state is toggled.
+ * Reloading must be done by hand, or by walking through the DOM tree and
+ * re-setting the src attributes.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_IMAGES = 5;
+
+ /**
+ * Boolean. Enables/disables whether the document as a whole gets focus before
+ * traversing the document's content, or after traversing its content.
+ *
+ * NOTE: this property is obsolete and now has no effect
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_FOCUS_DOC_BEFORE_CONTENT = 6;
+
+ /**
+ * Boolean. Enables/disables the use of global history in the browser. Visited
+ * URLs will not be recorded in the global history when it is disabled.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_USE_GLOBAL_HISTORY = 256;
+
+ /**
+ * Boolean. A value of PR_TRUE makes the browser a chrome wrapper.
+ * Default is PR_FALSE.
+ *
+ * @since mozilla1.0
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_IS_CHROME_WRAPPER = 7;
+
+
+ /**
+ * Boolean. Enables/disables DNS prefetch for HTML anchors in this browser.
+ * This takes effect starting with the next pageload after the property is
+ * set. The default is to not allow DNS prefetch, for backwards
+ * compatibility.
+ *
+ * @see setProperty
+ */
+ const unsigned long SETUP_ALLOW_DNS_PREFETCH = 8;
+
+ /**
+ * Sets an integer or boolean property on the new web browser object.
+ * Only PR_TRUE and PR_FALSE are legal boolean values.
+ *
+ * @param aId The identifier of the property to be set.
+ * @param aValue The value of the property.
+ */
+ void setProperty(in unsigned long aId, in unsigned long aValue);
+};
+
diff --git a/embedding/browser/nsIWebBrowserStream.idl b/embedding/browser/nsIWebBrowserStream.idl
new file mode 100644
index 000000000..9326b2eaa
--- /dev/null
+++ b/embedding/browser/nsIWebBrowserStream.idl
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIURI;
+
+/**
+ * This interface provides a way to stream data to the web browser. This allows
+ * loading of data from sources which can not be accessed using URIs and
+ * nsIWebNavigation.
+ */
+[scriptable, uuid(86d02f0e-219b-4cfc-9c88-bd98d2cce0b8)]
+interface nsIWebBrowserStream : nsISupports
+{
+ /**
+ * Prepare to load a stream of data. When this function returns successfully,
+ * it must be paired by a call to closeStream.
+ *
+ * @param aBaseURI
+ * The base URI of the data. Must not be null. Relative
+ * URIs will be resolved relative to this URI.
+ * @param aContentType
+ * ASCII string giving the content type of the data. If rendering
+ * content of this type is not supported, this method fails.
+ * This string may include a charset declaration, for example:
+ * text/html;charset=ISO-8859-1
+ *
+ * @throw NS_ERROR_NOT_AVAILABLE
+ * The requested content type is not supported.
+ * @throw NS_ERROR_IN_PROGRESS
+ * openStream was called twice without an intermediate closeStream.
+ */
+ void openStream(in nsIURI aBaseURI, in ACString aContentType);
+
+ /**
+ * Append data to this stream.
+ * @param aData The data to append
+ * @param aLen Length of the data to append.
+ *
+ * @note To append more than 4 GB of data, call this method multiple times.
+ */
+ void appendToStream([const, array, size_is(aLen)] in octet aData,
+ in unsigned long aLen);
+
+ /**
+ * Notifies the browser that all the data has been appended. This may notify
+ * the user that the browser is "done loading" in some form.
+ *
+ * @throw NS_ERROR_UNEXPECTED
+ * This method was called without a preceding openStream.
+ */
+ void closeStream();
+};
diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp
new file mode 100644
index 000000000..655aa1e43
--- /dev/null
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -0,0 +1,1952 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Local Includes
+#include "nsWebBrowser.h"
+
+// Helper Classes
+#include "nsGfxCIID.h"
+#include "nsWidgetsCID.h"
+
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+
+// Interfaces Needed
+#include "nsReadableUtils.h"
+#include "nsIComponentManager.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMWindow.h"
+#include "nsIDOMElement.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsPIDOMWindow.h"
+#include "nsIWebProgress.h"
+#include "nsIWebProgressListener.h"
+#include "nsIWebBrowserFocus.h"
+#include "nsIWebBrowserStream.h"
+#include "nsIPresShell.h"
+#include "nsIURIContentListener.h"
+#include "nsISHistoryListener.h"
+#include "nsIURI.h"
+#include "nsIWebBrowserPersist.h"
+#include "nsCWebBrowserPersist.h"
+#include "nsIServiceManager.h"
+#include "nsFocusManager.h"
+#include "Layers.h"
+#include "gfxContext.h"
+#include "nsILoadContext.h"
+#include "nsDocShell.h"
+
+// for painting the background window
+#include "mozilla/LookAndFeel.h"
+
+// Printing Includes
+#ifdef NS_PRINTING
+#include "nsIWebBrowserPrint.h"
+#include "nsIContentViewer.h"
+#endif
+
+// PSM2 includes
+#include "nsISecureBrowserUI.h"
+#include "nsXULAppAPI.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
+
+nsWebBrowser::nsWebBrowser()
+ : mInitInfo(new nsWebBrowserInitInfo())
+ , mContentType(typeContentWrapper)
+ , mActivating(false)
+ , mShouldEnableHistory(true)
+ , mIsActive(true)
+ , mParentNativeWindow(nullptr)
+ , mProgressListener(nullptr)
+ , mWidgetListenerDelegate(this)
+ , mBackgroundColor(0)
+ , mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY)
+ , mPersistResult(NS_OK)
+ , mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE)
+ , mParentWidget(nullptr)
+{
+ mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
+ NS_ASSERTION(mWWatch, "failed to get WindowWatcher");
+}
+
+nsWebBrowser::~nsWebBrowser()
+{
+ InternalDestroy();
+}
+
+NS_IMETHODIMP
+nsWebBrowser::InternalDestroy()
+{
+ if (mInternalWidget) {
+ mInternalWidget->SetWidgetListener(nullptr);
+ mInternalWidget->Destroy();
+ mInternalWidget = nullptr; // Force release here.
+ }
+
+ SetDocShell(nullptr);
+
+ if (mDocShellTreeOwner) {
+ mDocShellTreeOwner->WebBrowser(nullptr);
+ mDocShellTreeOwner = nullptr;
+ }
+
+ mInitInfo = nullptr;
+
+ mListenerArray = nullptr;
+
+ return NS_OK;
+}
+
+NS_IMPL_ADDREF(nsWebBrowser)
+NS_IMPL_RELEASE(nsWebBrowser)
+
+NS_INTERFACE_MAP_BEGIN(nsWebBrowser)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser)
+ NS_INTERFACE_MAP_ENTRY(nsIWebBrowser)
+ NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
+ NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
+ NS_INTERFACE_MAP_ENTRY(nsIScrollable)
+ NS_INTERFACE_MAP_ENTRY(nsITextScroll)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
+ NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
+ NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
+ NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
+ NS_INTERFACE_MAP_ENTRY(nsICancelable)
+ NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+ NS_INTERFACE_MAP_ENTRY(nsIWebBrowserStream)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+NS_INTERFACE_MAP_END
+
+///*****************************************************************************
+// nsWebBrowser::nsIInterfaceRequestor
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink)
+{
+ NS_ENSURE_ARG_POINTER(aSink);
+
+ if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) {
+ return NS_OK;
+ }
+
+ if (mDocShell) {
+#ifdef NS_PRINTING
+ if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
+ nsCOMPtr<nsIContentViewer> viewer;
+ mDocShell->GetContentViewer(getter_AddRefs(viewer));
+ if (!viewer) {
+ return NS_NOINTERFACE;
+ }
+
+ nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
+ nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
+ NS_ASSERTION(print, "This MUST support this interface!");
+ NS_ADDREF(print);
+ *aSink = print;
+ return NS_OK;
+ }
+#endif
+ return mDocShellAsReq->GetInterface(aIID, aSink);
+ }
+
+ return NS_NOINTERFACE;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebBrowser
+//*****************************************************************************
+
+// listeners that currently support registration through AddWebBrowserListener:
+// - nsIWebProgressListener
+NS_IMETHODIMP
+nsWebBrowser::AddWebBrowserListener(nsIWeakReference* aListener,
+ const nsIID& aIID)
+{
+ NS_ENSURE_ARG_POINTER(aListener);
+
+ nsresult rv = NS_OK;
+ if (!mWebProgress) {
+ // The window hasn't been created yet, so queue up the listener. They'll be
+ // registered when the window gets created.
+ if (!mListenerArray) {
+ mListenerArray = new nsTArray<nsWebBrowserListenerState>();
+ }
+
+ nsWebBrowserListenerState* state = mListenerArray->AppendElement();
+ state->mWeakPtr = aListener;
+ state->mID = aIID;
+ } else {
+ nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
+ if (!supports) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ rv = BindListener(supports, aIID);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::BindListener(nsISupports* aListener, const nsIID& aIID)
+{
+ NS_ENSURE_ARG_POINTER(aListener);
+ NS_ASSERTION(mWebProgress,
+ "this should only be called after we've retrieved a progress iface");
+ nsresult rv = NS_OK;
+
+ // register this listener for the specified interface id
+ if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
+ nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ NS_ENSURE_STATE(mWebProgress);
+ rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL);
+ } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
+ nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = shistory->AddSHistoryListener(listener);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference* aListener,
+ const nsIID& aIID)
+{
+ NS_ENSURE_ARG_POINTER(aListener);
+
+ nsresult rv = NS_OK;
+ if (!mWebProgress) {
+ // if there's no-one to register the listener w/, and we don't have a queue
+ // going, the the called is calling Remove before an Add which doesn't make
+ // sense.
+ if (!mListenerArray) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // iterate the array and remove the queued listener
+ int32_t count = mListenerArray->Length();
+ while (count > 0) {
+ if (mListenerArray->ElementAt(count-1).Equals(aListener, aIID)) {
+ mListenerArray->RemoveElementAt(count-1);
+ break;
+ }
+ count--;
+ }
+
+ // if we've emptied the array, get rid of it.
+ if (0 >= mListenerArray->Length()) {
+ mListenerArray = nullptr;
+ }
+
+ } else {
+ nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
+ if (!supports) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ rv = UnBindListener(supports, aIID);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::UnBindListener(nsISupports* aListener, const nsIID& aIID)
+{
+ NS_ENSURE_ARG_POINTER(aListener);
+ NS_ASSERTION(mWebProgress,
+ "this should only be called after we've retrieved a progress iface");
+ nsresult rv = NS_OK;
+
+ // remove the listener for the specified interface id
+ if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
+ nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ NS_ENSURE_STATE(mWebProgress);
+ rv = mWebProgress->RemoveProgressListener(listener);
+ } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
+ nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = shistory->RemoveSHistoryListener(listener);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::EnableGlobalHistory(bool aEnable)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShell->SetUseGlobalHistory(aEnable);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow)
+{
+ NS_ENSURE_ARG_POINTER(aTopWindow);
+
+ nsCOMPtr<nsIWebBrowserChrome> top;
+ if (mDocShellTreeOwner) {
+ top = mDocShellTreeOwner->GetWebBrowserChrome();
+ }
+
+ top.forget(aTopWindow);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow)
+{
+ NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
+ return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetParentURIContentListener(
+ nsIURIContentListener** aParentContentListener)
+{
+ NS_ENSURE_ARG_POINTER(aParentContentListener);
+ *aParentContentListener = nullptr;
+
+ // get the interface from the docshell
+ nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
+
+ if (listener) {
+ return listener->GetParentContentListener(aParentContentListener);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetParentURIContentListener(
+ nsIURIContentListener* aParentContentListener)
+{
+ // get the interface from the docshell
+ nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
+
+ if (listener) {
+ return listener->SetParentContentListener(aParentContentListener);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy** aResult)
+{
+ if (!mDocShell) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> retval = mDocShell->GetWindow();
+ retval.forget(aResult);
+ return *aResult ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetIsActive(bool* aResult)
+{
+ *aResult = mIsActive;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetIsActive(bool aIsActive)
+{
+ // Set our copy of the value
+ mIsActive = aIsActive;
+
+ // If we have a docshell, pass on the request
+ if (mDocShell) {
+ return mDocShell->SetIsActive(aIsActive);
+ }
+ return NS_OK;
+}
+
+void
+nsWebBrowser::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
+{
+ mOriginAttributes = aAttrs;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIDocShellTreeItem
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetName(nsAString& aName)
+{
+ if (mDocShell) {
+ mDocShell->GetName(aName);
+ } else {
+ aName = mInitInfo->name;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetName(const nsAString& aName)
+{
+ if (mDocShell) {
+ return mDocShell->SetName(aName);
+ } else {
+ mInitInfo->name = aName;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::NameEquals(const nsAString& aName, bool* aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ if (mDocShell) {
+ return mDocShell->NameEquals(aName, aResult);
+ } else {
+ *aResult = mInitInfo->name.Equals(aName);
+ }
+
+ return NS_OK;
+}
+
+/* virtual */ int32_t
+nsWebBrowser::ItemType()
+{
+ return mContentType;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetItemType(int32_t* aItemType)
+{
+ NS_ENSURE_ARG_POINTER(aItemType);
+
+ *aItemType = ItemType();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetItemType(int32_t aItemType)
+{
+ NS_ENSURE_TRUE(
+ aItemType == typeContentWrapper || aItemType == typeChromeWrapper,
+ NS_ERROR_FAILURE);
+ mContentType = aItemType;
+ if (mDocShell) {
+ mDocShell->SetItemType(mContentType == typeChromeWrapper ?
+ static_cast<int32_t>(typeChrome) :
+ static_cast<int32_t>(typeContent));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent)
+{
+ *aParent = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent)
+{
+ *aParent = nullptr;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
+{
+ NS_ENSURE_ARG_POINTER(aRootTreeItem);
+ *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
+
+ nsCOMPtr<nsIDocShellTreeItem> parent;
+ NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
+ while (parent) {
+ *aRootTreeItem = parent;
+ NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)),
+ NS_ERROR_FAILURE);
+ }
+ NS_ADDREF(*aRootTreeItem);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
+{
+ NS_ENSURE_ARG_POINTER(aRootTreeItem);
+ *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
+
+ nsCOMPtr<nsIDocShellTreeItem> parent;
+ NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)),
+ NS_ERROR_FAILURE);
+ while (parent) {
+ *aRootTreeItem = parent;
+ NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)),
+ NS_ERROR_FAILURE);
+ }
+ NS_ADDREF(*aRootTreeItem);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::FindItemWithName(const nsAString& aName,
+ nsISupports* aRequestor,
+ nsIDocShellTreeItem* aOriginalRequestor,
+ nsIDocShellTreeItem** aResult)
+{
+ NS_ENSURE_STATE(mDocShell);
+ NS_ASSERTION(mDocShellTreeOwner,
+ "This should always be set when in this situation");
+
+ return mDocShell->FindItemWithName(
+ aName, static_cast<nsIDocShellTreeOwner*>(mDocShellTreeOwner),
+ aOriginalRequestor, aResult);
+}
+
+nsIDocument*
+nsWebBrowser::GetDocument()
+{
+ return mDocShell ? mDocShell->GetDocument() : nullptr;
+}
+
+nsPIDOMWindowOuter*
+nsWebBrowser::GetWindow()
+{
+ return mDocShell ? mDocShell->GetWindow() : nullptr;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
+{
+ NS_ENSURE_ARG_POINTER(aTreeOwner);
+ *aTreeOwner = nullptr;
+ if (mDocShellTreeOwner) {
+ if (mDocShellTreeOwner->mTreeOwner) {
+ *aTreeOwner = mDocShellTreeOwner->mTreeOwner;
+ } else {
+ *aTreeOwner = mDocShellTreeOwner;
+ }
+ }
+ NS_IF_ADDREF(*aTreeOwner);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
+{
+ NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
+ return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIDocShellTreeItem
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetChildCount(int32_t* aChildCount)
+{
+ NS_ENSURE_ARG_POINTER(aChildCount);
+ *aChildCount = 0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::AddChild(nsIDocShellTreeItem* aChild)
+{
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::RemoveChild(nsIDocShellTreeItem* aChild)
+{
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetChildAt(int32_t aIndex, nsIDocShellTreeItem** aChild)
+{
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::FindChildWithName(const nsAString& aName,
+ bool aRecurse,
+ bool aSameType,
+ nsIDocShellTreeItem* aRequestor,
+ nsIDocShellTreeItem* aOriginalRequestor,
+ nsIDocShellTreeItem** aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ *aResult = nullptr;
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebNavigation
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetCanGoBack(bool* aCanGoBack)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GetCanGoBack(aCanGoBack);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetCanGoForward(bool* aCanGoForward)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GetCanGoForward(aCanGoForward);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GoBack()
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GoBack();
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GoForward()
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GoForward();
+}
+
+NS_IMETHODIMP
+nsWebBrowser::LoadURIWithOptions(const char16_t* aURI, uint32_t aLoadFlags,
+ nsIURI* aReferringURI,
+ uint32_t aReferrerPolicy,
+ nsIInputStream* aPostDataStream,
+ nsIInputStream* aExtraHeaderStream,
+ nsIURI* aBaseURI)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->LoadURIWithOptions(
+ aURI, aLoadFlags, aReferringURI, aReferrerPolicy, aPostDataStream,
+ aExtraHeaderStream, aBaseURI);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
+{
+ return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::LoadURI(const char16_t* aURI, uint32_t aLoadFlags,
+ nsIURI* aReferringURI,
+ nsIInputStream* aPostDataStream,
+ nsIInputStream* aExtraHeaderStream)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->LoadURI(
+ aURI, aLoadFlags, aReferringURI, aPostDataStream, aExtraHeaderStream);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Reload(uint32_t aReloadFlags)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->Reload(aReloadFlags);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GotoIndex(int32_t aIndex)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GotoIndex(aIndex);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Stop(uint32_t aStopFlags)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->Stop(aStopFlags);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetCurrentURI(nsIURI** aURI)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GetCurrentURI(aURI);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetReferringURI(nsIURI** aURI)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GetReferringURI(aURI);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory)
+{
+ if (mDocShell) {
+ return mDocShellAsNav->SetSessionHistory(aSessionHistory);
+ } else {
+ mInitInfo->sessionHistory = aSessionHistory;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory)
+{
+ NS_ENSURE_ARG_POINTER(aSessionHistory);
+ if (mDocShell) {
+ return mDocShellAsNav->GetSessionHistory(aSessionHistory);
+ } else {
+ *aSessionHistory = mInitInfo->sessionHistory;
+ }
+
+ NS_IF_ADDREF(*aSessionHistory);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetDocument(nsIDOMDocument** aDocument)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsNav->GetDocument(aDocument);
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebBrowserSetup
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue)
+{
+ nsresult rv = NS_OK;
+
+ switch (aId) {
+ case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowPlugins(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowJavascript(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowMetaRedirects(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowSubframes(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowImages(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ mDocShell->SetAllowDNSPrefetch(!!aValue);
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY: {
+ NS_ENSURE_STATE(mDocShell);
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ rv = EnableGlobalHistory(!!aValue);
+ mShouldEnableHistory = aValue;
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT: {
+ // obsolete
+ break;
+ }
+ case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER: {
+ NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
+ aValue == static_cast<uint32_t>(false)),
+ NS_ERROR_INVALID_ARG);
+ SetItemType(aValue ? static_cast<int32_t>(typeChromeWrapper) :
+ static_cast<int32_t>(typeContentWrapper));
+ break;
+ }
+ default:
+ rv = NS_ERROR_INVALID_ARG;
+ }
+ return rv;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebProgressListener
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::OnStateChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aStateFlags,
+ nsresult aStatus)
+{
+ if (mPersist) {
+ mPersist->GetCurrentState(&mPersistCurrentState);
+ }
+ if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) {
+ mPersist = nullptr;
+ }
+ if (mProgressListener) {
+ return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
+ aStatus);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::OnProgressChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ int32_t aCurSelfProgress,
+ int32_t aMaxSelfProgress,
+ int32_t aCurTotalProgress,
+ int32_t aMaxTotalProgress)
+{
+ if (mPersist) {
+ mPersist->GetCurrentState(&mPersistCurrentState);
+ }
+ if (mProgressListener) {
+ return mProgressListener->OnProgressChange(
+ aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
+ aCurTotalProgress, aMaxTotalProgress);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::OnLocationChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsIURI* aLocation,
+ uint32_t aFlags)
+{
+ if (mProgressListener) {
+ return mProgressListener->OnLocationChange(aWebProgress, aRequest, aLocation,
+ aFlags);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::OnStatusChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsresult aStatus,
+ const char16_t* aMessage)
+{
+ if (mProgressListener) {
+ return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
+ aMessage);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::OnSecurityChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aState)
+{
+ if (mProgressListener) {
+ return mProgressListener->OnSecurityChange(aWebProgress, aRequest, aState);
+ }
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebBrowserPersist
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags)
+{
+ NS_ENSURE_ARG_POINTER(aPersistFlags);
+ nsresult rv = NS_OK;
+ if (mPersist) {
+ rv = mPersist->GetPersistFlags(&mPersistFlags);
+ }
+ *aPersistFlags = mPersistFlags;
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags)
+{
+ nsresult rv = NS_OK;
+ mPersistFlags = aPersistFlags;
+ if (mPersist) {
+ rv = mPersist->SetPersistFlags(mPersistFlags);
+ mPersist->GetPersistFlags(&mPersistFlags);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetCurrentState(uint32_t* aCurrentState)
+{
+ NS_ENSURE_ARG_POINTER(aCurrentState);
+ if (mPersist) {
+ mPersist->GetCurrentState(&mPersistCurrentState);
+ }
+ *aCurrentState = mPersistCurrentState;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetResult(nsresult* aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ if (mPersist) {
+ mPersist->GetResult(&mPersistResult);
+ }
+ *aResult = mPersistResult;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetProgressListener(nsIWebProgressListener** aProgressListener)
+{
+ NS_ENSURE_ARG_POINTER(aProgressListener);
+ *aProgressListener = mProgressListener;
+ NS_IF_ADDREF(*aProgressListener);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener)
+{
+ mProgressListener = aProgressListener;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SaveURI(nsIURI* aURI,
+ nsISupports* aCacheKey,
+ nsIURI* aReferrer,
+ uint32_t aReferrerPolicy,
+ nsIInputStream* aPostData,
+ const char* aExtraHeaders,
+ nsISupports* aFile,
+ nsILoadContext* aPrivacyContext)
+{
+ return SavePrivacyAwareURI(
+ aURI, aCacheKey, aReferrer, aReferrerPolicy, aPostData, aExtraHeaders,
+ aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
+ nsISupports* aCacheKey,
+ nsIURI* aReferrer,
+ uint32_t aReferrerPolicy,
+ nsIInputStream* aPostData,
+ const char* aExtraHeaders,
+ nsISupports* aFile,
+ bool aIsPrivate)
+{
+ if (mPersist) {
+ uint32_t currentState;
+ mPersist->GetCurrentState(&currentState);
+ if (currentState == PERSIST_STATE_FINISHED) {
+ mPersist = nullptr;
+ } else {
+ // You can't save again until the last save has completed
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ nsCOMPtr<nsIURI> uri;
+ if (aURI) {
+ uri = aURI;
+ } else {
+ nsresult rv = GetCurrentURI(getter_AddRefs(uri));
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Create a throwaway persistence object to do the work
+ nsresult rv;
+ mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ mPersist->SetProgressListener(this);
+ mPersist->SetPersistFlags(mPersistFlags);
+ mPersist->GetCurrentState(&mPersistCurrentState);
+
+ rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy,
+ aPostData, aExtraHeaders, aFile, aIsPrivate);
+ if (NS_FAILED(rv)) {
+ mPersist = nullptr;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SaveChannel(nsIChannel* aChannel, nsISupports* aFile)
+{
+ if (mPersist) {
+ uint32_t currentState;
+ mPersist->GetCurrentState(&currentState);
+ if (currentState == PERSIST_STATE_FINISHED) {
+ mPersist = nullptr;
+ } else {
+ // You can't save again until the last save has completed
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Create a throwaway persistence object to do the work
+ nsresult rv;
+ mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ mPersist->SetProgressListener(this);
+ mPersist->SetPersistFlags(mPersistFlags);
+ mPersist->GetCurrentState(&mPersistCurrentState);
+ rv = mPersist->SaveChannel(aChannel, aFile);
+ if (NS_FAILED(rv)) {
+ mPersist = nullptr;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SaveDocument(nsISupports* aDocumentish,
+ nsISupports* aFile,
+ nsISupports* aDataPath,
+ const char* aOutputContentType,
+ uint32_t aEncodingFlags,
+ uint32_t aWrapColumn)
+{
+ if (mPersist) {
+ uint32_t currentState;
+ mPersist->GetCurrentState(&currentState);
+ if (currentState == PERSIST_STATE_FINISHED) {
+ mPersist = nullptr;
+ } else {
+ // You can't save again until the last save has completed
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Use the specified DOM document, or if none is specified, the one
+ // attached to the web browser.
+
+ nsCOMPtr<nsISupports> doc;
+ if (aDocumentish) {
+ doc = aDocumentish;
+ } else {
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ GetDocument(getter_AddRefs(domDoc));
+ doc = domDoc.forget();
+ }
+ if (!doc) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Create a throwaway persistence object to do the work
+ nsresult rv;
+ mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ mPersist->SetProgressListener(this);
+ mPersist->SetPersistFlags(mPersistFlags);
+ mPersist->GetCurrentState(&mPersistCurrentState);
+ rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType,
+ aEncodingFlags, aWrapColumn);
+ if (NS_FAILED(rv)) {
+ mPersist = nullptr;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::CancelSave()
+{
+ if (mPersist) {
+ return mPersist->CancelSave();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Cancel(nsresult aReason)
+{
+ if (mPersist) {
+ return mPersist->Cancel(aReason);
+ }
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIBaseWindow
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
+ nsIWidget* aParentWidget,
+ int32_t aX, int32_t aY,
+ int32_t aCX, int32_t aCY)
+{
+ NS_ENSURE_ARG(aParentNativeWindow || aParentWidget);
+ NS_ENSURE_STATE(!mDocShell || mInitInfo);
+
+ if (aParentWidget) {
+ NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE);
+ } else
+ NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow),
+ NS_ERROR_FAILURE);
+
+ NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, 0),
+ NS_ERROR_FAILURE);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Create()
+{
+ NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget));
+
+ nsresult rv = EnsureDocShellTreeOwner();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIWidget> docShellParentWidget(mParentWidget);
+ if (!mParentWidget) {
+ // Create the widget
+ mInternalWidget = do_CreateInstance(kChildCID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ docShellParentWidget = mInternalWidget;
+ nsWidgetInitData widgetInit;
+
+ widgetInit.clipChildren = true;
+
+ widgetInit.mWindowType = eWindowType_child;
+ LayoutDeviceIntRect bounds(mInitInfo->x, mInitInfo->y,
+ mInitInfo->cx, mInitInfo->cy);
+
+ mInternalWidget->SetWidgetListener(&mWidgetListenerDelegate);
+ rv = mInternalWidget->Create(nullptr, mParentNativeWindow, bounds,
+ &widgetInit);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ nsCOMPtr<nsIDocShell> docShell(
+ do_CreateInstance("@mozilla.org/docshell;1", &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsDocShell::Cast(docShell)->SetOriginAttributes(mOriginAttributes);
+ rv = SetDocShell(docShell);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // get the system default window background colour
+ LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground,
+ &mBackgroundColor);
+
+ // the docshell has been set so we now have our listener registrars.
+ if (mListenerArray) {
+ // we had queued up some listeners, let's register them now.
+ uint32_t count = mListenerArray->Length();
+ uint32_t i = 0;
+ NS_ASSERTION(count > 0, "array construction problem");
+ while (i < count) {
+ nsWebBrowserListenerState& state = mListenerArray->ElementAt(i);
+ nsCOMPtr<nsISupports> listener = do_QueryReferent(state.mWeakPtr);
+ NS_ASSERTION(listener, "bad listener");
+ (void)BindListener(listener, state.mID);
+ i++;
+ }
+ mListenerArray = nullptr;
+ }
+
+ // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
+ // nsIWebBrowserListener so it can setup its MouseListener in one of the
+ // progress callbacks. If we can register the MouseListener another way, this
+ // registration can go away, and nsDocShellTreeOwner can stop implementing
+ // nsIWebProgressListener.
+ nsCOMPtr<nsISupports> supports = nullptr;
+ (void)mDocShellTreeOwner->QueryInterface(
+ NS_GET_IID(nsIWebProgressListener),
+ static_cast<void**>(getter_AddRefs(supports)));
+ (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener));
+
+ NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nullptr, docShellParentWidget,
+ mInitInfo->x, mInitInfo->y,
+ mInitInfo->cx, mInitInfo->cy),
+ NS_ERROR_FAILURE);
+
+ mDocShell->SetName(mInitInfo->name);
+ if (mContentType == typeChromeWrapper) {
+ mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome);
+ } else {
+ mDocShell->SetItemType(nsIDocShellTreeItem::typeContent);
+ }
+ mDocShell->SetTreeOwner(mDocShellTreeOwner);
+
+ // If the webbrowser is a content docshell item then we won't hear any
+ // events from subframes. To solve that we install our own chrome event
+ // handler that always gets called (even for subframes) for any bubbling
+ // event.
+
+ if (!mInitInfo->sessionHistory) {
+ mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
+
+ if (XRE_IsParentProcess()) {
+ // Hook up global history. Do not fail if we can't - just warn.
+ rv = EnableGlobalHistory(mShouldEnableHistory);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
+ }
+
+ NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
+
+ // Hook into the OnSecurityChange() notification for lock/unlock icon
+ // updates
+ nsCOMPtr<mozIDOMWindowProxy> domWindow;
+ rv = GetContentDOMWindow(getter_AddRefs(domWindow));
+ if (NS_SUCCEEDED(rv)) {
+ // this works because the implementation of nsISecureBrowserUI
+ // (nsSecureBrowserUIImpl) gets a docShell from the domWindow,
+ // and calls docShell->SetSecurityUI(this);
+ nsCOMPtr<nsISecureBrowserUI> securityUI =
+ do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ securityUI->Init(domWindow);
+ }
+ }
+
+ mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
+ mDocShellTreeOwner->AddChromeListeners();
+
+ mInitInfo = nullptr;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Destroy()
+{
+ InternalDestroy();
+
+ if (!mInitInfo) {
+ mInitInfo = new nsWebBrowserInitInfo();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
+{
+ *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale)
+{
+ *aScale = mParentWidget ? mParentWidget->GetDesktopToDeviceScale().scale
+ : 1.0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY)
+{
+ // XXX jfkthame
+ // It's not clear to me whether this will be fully correct across
+ // potential multi-screen, mixed-DPI configurations for all platforms;
+ // we might need to add code paths that make it possible to pass the
+ // desktop-pix parameters all the way through to the native widget,
+ // to avoid the risk of device-pixel coords mapping to the wrong
+ // display on OS X with mixed retina/non-retina screens.
+ double scale = 1.0;
+ GetDevicePixelsPerDesktopPixel(&scale);
+ return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetPosition(int32_t aX, int32_t aY)
+{
+ int32_t cx = 0;
+ int32_t cy = 0;
+
+ GetSize(&cx, &cy);
+
+ return SetPositionAndSize(aX, aY, cx, cy, 0);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY)
+{
+ return GetPositionAndSize(aX, aY, nullptr, nullptr);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint)
+{
+ int32_t x = 0;
+ int32_t y = 0;
+
+ GetPosition(&x, &y);
+
+ return SetPositionAndSize(x, y, aCX, aCY,
+ aRepaint ? nsIBaseWindow::eRepaint : 0);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY)
+{
+ return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY,
+ int32_t aCX, int32_t aCY, uint32_t aFlags)
+{
+ if (!mDocShell) {
+ mInitInfo->x = aX;
+ mInitInfo->y = aY;
+ mInitInfo->cx = aCX;
+ mInitInfo->cy = aCY;
+ } else {
+ int32_t doc_x = aX;
+ int32_t doc_y = aY;
+
+ // If there is an internal widget we need to make the docShell coordinates
+ // relative to the internal widget rather than the calling app's parent.
+ // We also need to resize our widget then.
+ if (mInternalWidget) {
+ doc_x = doc_y = 0;
+ NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY,
+ !!(aFlags & nsIBaseWindow::eRepaint)),
+ NS_ERROR_FAILURE);
+ }
+ // Now reposition/ resize the doc
+ NS_ENSURE_SUCCESS(
+ mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aFlags),
+ NS_ERROR_FAILURE);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY,
+ int32_t* aCX, int32_t* aCY)
+{
+ if (!mDocShell) {
+ if (aX) {
+ *aX = mInitInfo->x;
+ }
+ if (aY) {
+ *aY = mInitInfo->y;
+ }
+ if (aCX) {
+ *aCX = mInitInfo->cx;
+ }
+ if (aCY) {
+ *aCY = mInitInfo->cy;
+ }
+ } else if (mInternalWidget) {
+ LayoutDeviceIntRect bounds = mInternalWidget->GetBounds();
+
+ if (aX) {
+ *aX = bounds.x;
+ }
+ if (aY) {
+ *aY = bounds.y;
+ }
+ if (aCX) {
+ *aCX = bounds.width;
+ }
+ if (aCY) {
+ *aCY = bounds.height;
+ }
+ return NS_OK;
+ } else {
+ // Can directly return this as it is the
+ // same interface, thus same returns.
+ return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Repaint(bool aForce)
+{
+ NS_ENSURE_STATE(mDocShell);
+ // Can directly return this as it is the
+ // same interface, thus same returns.
+ return mDocShellAsWin->Repaint(aForce);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget)
+{
+ NS_ENSURE_ARG_POINTER(aParentWidget);
+
+ *aParentWidget = mParentWidget;
+
+ NS_IF_ADDREF(*aParentWidget);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget)
+{
+ NS_ENSURE_STATE(!mDocShell);
+
+ mParentWidget = aParentWidget;
+ if (mParentWidget) {
+ mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
+ } else {
+ mParentNativeWindow = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
+{
+ NS_ENSURE_ARG_POINTER(aParentNativeWindow);
+
+ *aParentNativeWindow = mParentNativeWindow;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow)
+{
+ NS_ENSURE_STATE(!mDocShell);
+
+ mParentNativeWindow = aParentNativeWindow;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle)
+{
+ // the nativeHandle should be accessed from nsIXULWindow
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetVisibility(bool* aVisibility)
+{
+ NS_ENSURE_ARG_POINTER(aVisibility);
+
+ if (!mDocShell) {
+ *aVisibility = mInitInfo->visible;
+ } else {
+ NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(aVisibility),
+ NS_ERROR_FAILURE);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetVisibility(bool aVisibility)
+{
+ if (!mDocShell) {
+ mInitInfo->visible = aVisibility;
+ } else {
+ NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility),
+ NS_ERROR_FAILURE);
+ if (mInternalWidget) {
+ mInternalWidget->Show(aVisibility);
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetEnabled(bool* aEnabled)
+{
+ if (mInternalWidget) {
+ *aEnabled = mInternalWidget->IsEnabled();
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetEnabled(bool aEnabled)
+{
+ if (mInternalWidget) {
+ return mInternalWidget->Enable(aEnabled);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetMainWidget(nsIWidget** aMainWidget)
+{
+ NS_ENSURE_ARG_POINTER(aMainWidget);
+
+ if (mInternalWidget) {
+ *aMainWidget = mInternalWidget;
+ } else {
+ *aMainWidget = mParentWidget;
+ }
+
+ NS_IF_ADDREF(*aMainWidget);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetFocus()
+{
+ nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
+ NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ return fm ? fm->SetFocusedWindow(window) : NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetTitle(char16_t** aTitle)
+{
+ NS_ENSURE_ARG_POINTER(aTitle);
+ NS_ENSURE_STATE(mDocShell);
+
+ NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetTitle(const char16_t* aTitle)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE);
+
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIScrollable
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::GetDefaultScrollbarPreferences(int32_t aScrollOrientation,
+ int32_t* aScrollbarPref)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsScrollable->GetDefaultScrollbarPreferences(
+ aScrollOrientation, aScrollbarPref);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetDefaultScrollbarPreferences(int32_t aScrollOrientation,
+ int32_t aScrollbarPref)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsScrollable->SetDefaultScrollbarPreferences(
+ aScrollOrientation, aScrollbarPref);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
+ bool* aHorizontalVisible)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible,
+ aHorizontalVisible);
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsITextScroll
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::ScrollByLines(int32_t aNumLines)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsTextScroll->ScrollByLines(aNumLines);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::ScrollByPages(int32_t aNumPages)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsTextScroll->ScrollByPages(aNumPages);
+}
+
+//*****************************************************************************
+// nsWebBrowser: Listener Helpers
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
+{
+ // We need to keep the docshell alive while we perform the changes, but we
+ // don't need to call any methods on it.
+ nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocShell);
+ mozilla::Unused << kungFuDeathGrip;
+
+ if (aDocShell) {
+ NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(aDocShell));
+ nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(aDocShell));
+ nsCOMPtr<nsIWebNavigation> nav(do_QueryInterface(aDocShell));
+ nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(aDocShell));
+ nsCOMPtr<nsITextScroll> textScroll(do_QueryInterface(aDocShell));
+ nsCOMPtr<nsIWebProgress> progress(do_GetInterface(aDocShell));
+ NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress,
+ NS_ERROR_FAILURE);
+
+ mDocShell = aDocShell;
+ mDocShellAsReq = req;
+ mDocShellAsWin = baseWin;
+ mDocShellAsNav = nav;
+ mDocShellAsScrollable = scrollable;
+ mDocShellAsTextScroll = textScroll;
+ mWebProgress = progress;
+
+ // By default, do not allow DNS prefetch, so we don't break our frozen
+ // API. Embeddors who decide to enable it should do so manually.
+ mDocShell->SetAllowDNSPrefetch(false);
+
+ // It's possible to call setIsActive() on us before we have a docshell.
+ // If we're getting a docshell now, pass along our desired value. The
+ // default here (true) matches the default of the docshell, so this is
+ // a no-op unless setIsActive(false) has been called on us.
+ mDocShell->SetIsActive(mIsActive);
+ } else {
+ if (mDocShellTreeOwner) {
+ mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create()
+ }
+ if (mDocShellAsWin) {
+ mDocShellAsWin->Destroy();
+ }
+
+ mDocShell = nullptr;
+ mDocShellAsReq = nullptr;
+ mDocShellAsWin = nullptr;
+ mDocShellAsNav = nullptr;
+ mDocShellAsScrollable = nullptr;
+ mDocShellAsTextScroll = nullptr;
+ mWebProgress = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::EnsureDocShellTreeOwner()
+{
+ if (mDocShellTreeOwner) {
+ return NS_OK;
+ }
+
+ mDocShellTreeOwner = new nsDocShellTreeOwner();
+ mDocShellTreeOwner->WebBrowser(this);
+
+ return NS_OK;
+}
+
+static void
+DrawPaintedLayer(PaintedLayer* aLayer,
+ gfxContext* aContext,
+ const nsIntRegion& aRegionToDraw,
+ const nsIntRegion& aDirtyRegion,
+ DrawRegionClip aClip,
+ const nsIntRegion& aRegionToInvalidate,
+ void* aCallbackData)
+{
+ DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
+
+ ColorPattern color(ToDeviceColor(*static_cast<nscolor*>(aCallbackData)));
+ nsIntRect dirtyRect = aRegionToDraw.GetBounds();
+ aDrawTarget.FillRect(
+ Rect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height), color);
+}
+
+void
+nsWebBrowser::WindowRaised(nsIWidget* aWidget)
+{
+#if defined(DEBUG_smaug)
+ nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
+ nsAutoString documentURI;
+ document->GetDocumentURI(documentURI);
+ printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
+ NS_ConvertUTF16toUTF8(documentURI).get());
+#endif
+ Activate();
+}
+
+void
+nsWebBrowser::WindowLowered(nsIWidget* aWidget)
+{
+#if defined(DEBUG_smaug)
+ nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
+ nsAutoString documentURI;
+ document->GetDocumentURI(documentURI);
+ printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
+ NS_ConvertUTF16toUTF8(documentURI).get());
+#endif
+ Deactivate();
+}
+
+bool
+nsWebBrowser::PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion)
+{
+ LayerManager* layerManager = aWidget->GetLayerManager();
+ NS_ASSERTION(layerManager, "Must be in paint event");
+
+ layerManager->BeginTransaction();
+ RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
+ if (root) {
+ nsIntRect dirtyRect = aRegion.GetBounds().ToUnknownRect();
+ root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
+ layerManager->SetRoot(root);
+ }
+
+ layerManager->EndTransaction(DrawPaintedLayer, &mBackgroundColor);
+ return true;
+}
+/*
+NS_IMETHODIMP
+nsWebBrowser::GetPrimaryContentWindow(mozIDOMWindowProxy** aDOMWindow)
+{
+ *aDOMWindow = nullptr;
+
+ nsCOMPtr<nsIDocShellTreeItem> item;
+ NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_FAILURE);
+ mDocShellTreeOwner->GetPrimaryContentShell(getter_AddRefs(item));
+ NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIDocShell> docShell;
+ docShell = do_QueryInterface(item);
+ NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsPIDOMWindowOuter> domWindow = docShell->GetWindow();
+ NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
+
+ *aDOMWindow = domWindow;
+ NS_ADDREF(*aDOMWindow);
+ return NS_OK;
+}
+*/
+//*****************************************************************************
+// nsWebBrowser::nsIWebBrowserFocus
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::Activate(void)
+{
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
+ if (fm && window) {
+ return fm->WindowRaised(window);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::Deactivate(void)
+{
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
+ if (fm && window) {
+ return fm->WindowLowered(window);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetFocusAtFirstElement(void)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetFocusAtLastElement(void)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetFocusedWindow(mozIDOMWindowProxy** aFocusedWindow)
+{
+ NS_ENSURE_ARG_POINTER(aFocusedWindow);
+ *aFocusedWindow = nullptr;
+
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsPIDOMWindowOuter> window = mDocShell->GetWindow();
+ NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIDOMElement> focusedElement;
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ return fm ? fm->GetFocusedElementForWindow(window, true, aFocusedWindow,
+ getter_AddRefs(focusedElement)) :
+ NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetFocusedWindow(mozIDOMWindowProxy* aFocusedWindow)
+{
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ return fm ? fm->SetFocusedWindow(aFocusedWindow) : NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::GetFocusedElement(nsIDOMElement** aFocusedElement)
+{
+ NS_ENSURE_ARG_POINTER(aFocusedElement);
+ NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsPIDOMWindowOuter> window = mDocShell->GetWindow();
+ NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ return
+ fm ? fm->GetFocusedElementForWindow(window, true, nullptr, aFocusedElement) :
+ NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebBrowser::SetFocusedElement(nsIDOMElement* aFocusedElement)
+{
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ return fm ? fm->SetFocus(aFocusedElement, 0) : NS_OK;
+}
+
+//*****************************************************************************
+// nsWebBrowser::nsIWebBrowserStream
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::OpenStream(nsIURI* aBaseURI, const nsACString& aContentType)
+{
+ nsresult rv;
+
+ if (!mStream) {
+ mStream = new nsEmbedStream();
+ mStream->InitOwner(this);
+ rv = mStream->Init();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ }
+
+ return mStream->OpenStream(aBaseURI, aContentType);
+}
+
+
+NS_IMETHODIMP
+nsWebBrowser::AppendToStream(const uint8_t* aData, uint32_t aLen)
+{
+ if (!mStream) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mStream->AppendToStream(aData, aLen);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::CloseStream()
+{
+ nsresult rv;
+
+ if (!mStream) {
+ return NS_ERROR_FAILURE;
+ }
+ rv = mStream->CloseStream();
+
+ mStream = nullptr;
+
+ return rv;
+}
+
+bool
+nsWebBrowser::WidgetListenerDelegate::PaintWindow(
+ nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion)
+{
+ RefPtr<nsWebBrowser> holder = mWebBrowser;
+ return holder->PaintWindow(aWidget, aRegion);
+}
diff --git a/embedding/browser/nsWebBrowser.h b/embedding/browser/nsWebBrowser.h
new file mode 100644
index 000000000..80c106cb9
--- /dev/null
+++ b/embedding/browser/nsWebBrowser.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsWebBrowser_h__
+#define nsWebBrowser_h__
+
+// Local Includes
+#include "nsDocShellTreeOwner.h"
+
+// Core Includes
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+
+// Interfaces needed
+#include "nsCWebBrowser.h"
+#include "nsIBaseWindow.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIScrollable.h"
+#include "nsISHistory.h"
+#include "nsITextScroll.h"
+#include "nsIWidget.h"
+#include "nsIWebProgress.h"
+#include "nsISecureBrowserUI.h"
+#include "nsIWebBrowser.h"
+#include "nsIWebNavigation.h"
+#include "nsIWebBrowserSetup.h"
+#include "nsIWebBrowserPersist.h"
+#include "nsIWebBrowserFocus.h"
+#include "nsIWebBrowserStream.h"
+#include "nsIWindowWatcher.h"
+#include "nsIPrintSettings.h"
+#include "nsEmbedStream.h"
+#include "nsIWidgetListener.h"
+
+#include "mozilla/BasePrincipal.h"
+#include "nsTArray.h"
+#include "nsWeakPtr.h"
+
+class nsWebBrowserInitInfo
+{
+public:
+ // nsIBaseWindow Stuff
+ int32_t x;
+ int32_t y;
+ int32_t cx;
+ int32_t cy;
+ bool visible;
+ nsCOMPtr<nsISHistory> sessionHistory;
+ nsString name;
+};
+
+class nsWebBrowserListenerState
+{
+public:
+ bool Equals(nsIWeakReference* aListener, const nsIID& aID)
+ {
+ return mWeakPtr.get() == aListener && mID.Equals(aID);
+ }
+
+ nsWeakPtr mWeakPtr;
+ nsIID mID;
+};
+
+// {cda5863a-aa9c-411e-be49-ea0d525ab4b5} -
+#define NS_WEBBROWSER_CID \
+ { 0xcda5863a, 0xaa9c, 0x411e, { 0xbe, 0x49, 0xea, 0x0d, 0x52, 0x5a, 0xb4, 0xb5 } }
+
+
+class nsWebBrowser final : public nsIWebBrowser,
+ public nsIWebNavigation,
+ public nsIWebBrowserSetup,
+ public nsIDocShellTreeItem,
+ public nsIBaseWindow,
+ public nsIScrollable,
+ public nsITextScroll,
+ public nsIInterfaceRequestor,
+ public nsIWebBrowserPersist,
+ public nsIWebBrowserFocus,
+ public nsIWebProgressListener,
+ public nsIWebBrowserStream,
+ public nsSupportsWeakReference
+{
+ friend class nsDocShellTreeOwner;
+
+public:
+
+ // The implementation of non-refcounted nsIWidgetListener, which would hold a
+ // strong reference on stack before calling nsWebBrowser.
+ class WidgetListenerDelegate : public nsIWidgetListener
+ {
+ public:
+ explicit WidgetListenerDelegate(nsWebBrowser* aWebBrowser)
+ : mWebBrowser(aWebBrowser) {}
+ virtual bool PaintWindow(
+ nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion) override;
+
+ private:
+ // The lifetime of WidgetListenerDelegate is bound to nsWebBrowser so we
+ // just use raw pointer here.
+ nsWebBrowser* mWebBrowser;
+ };
+
+ nsWebBrowser();
+
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSIBASEWINDOW
+ NS_DECL_NSIDOCSHELLTREEITEM
+ NS_DECL_NSIINTERFACEREQUESTOR
+ NS_DECL_NSISCROLLABLE
+ NS_DECL_NSITEXTSCROLL
+ NS_DECL_NSIWEBBROWSER
+ NS_DECL_NSIWEBNAVIGATION
+ NS_DECL_NSIWEBBROWSERSETUP
+ NS_DECL_NSIWEBBROWSERPERSIST
+ NS_DECL_NSICANCELABLE
+ NS_DECL_NSIWEBBROWSERFOCUS
+ NS_DECL_NSIWEBBROWSERSTREAM
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+protected:
+ virtual ~nsWebBrowser();
+ NS_IMETHOD InternalDestroy();
+
+ // XXXbz why are these NS_IMETHOD? They're not interface methods!
+ NS_IMETHOD SetDocShell(nsIDocShell* aDocShell);
+ NS_IMETHOD EnsureDocShellTreeOwner();
+ NS_IMETHOD BindListener(nsISupports* aListener, const nsIID& aIID);
+ NS_IMETHOD UnBindListener(nsISupports* aListener, const nsIID& aIID);
+ NS_IMETHOD EnableGlobalHistory(bool aEnable);
+
+ // nsIWidgetListener
+ virtual void WindowRaised(nsIWidget* aWidget);
+ virtual void WindowLowered(nsIWidget* aWidget);
+ bool PaintWindow(nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion);
+
+protected:
+ RefPtr<nsDocShellTreeOwner> mDocShellTreeOwner;
+ nsCOMPtr<nsIDocShell> mDocShell;
+ nsCOMPtr<nsIInterfaceRequestor> mDocShellAsReq;
+ nsCOMPtr<nsIBaseWindow> mDocShellAsWin;
+ nsCOMPtr<nsIWebNavigation> mDocShellAsNav;
+ nsCOMPtr<nsIScrollable> mDocShellAsScrollable;
+ nsCOMPtr<nsITextScroll> mDocShellAsTextScroll;
+ mozilla::DocShellOriginAttributes mOriginAttributes;
+
+ nsCOMPtr<nsIWidget> mInternalWidget;
+ nsCOMPtr<nsIWindowWatcher> mWWatch;
+ nsAutoPtr<nsWebBrowserInitInfo> mInitInfo;
+ uint32_t mContentType;
+ bool mActivating;
+ bool mShouldEnableHistory;
+ bool mIsActive;
+ nativeWindow mParentNativeWindow;
+ nsIWebProgressListener* mProgressListener;
+ nsCOMPtr<nsIWebProgress> mWebProgress;
+
+ nsCOMPtr<nsIPrintSettings> mPrintSettings;
+
+ WidgetListenerDelegate mWidgetListenerDelegate;
+
+ // cached background color
+ nscolor mBackgroundColor;
+
+ // persistence object
+ nsCOMPtr<nsIWebBrowserPersist> mPersist;
+ uint32_t mPersistCurrentState;
+ nsresult mPersistResult;
+ uint32_t mPersistFlags;
+
+ // stream
+ RefPtr<nsEmbedStream> mStream;
+
+ // Weak Reference interfaces...
+ nsIWidget* mParentWidget;
+ nsAutoPtr<nsTArray<nsWebBrowserListenerState> > mListenerArray;
+};
+
+#endif /* nsWebBrowser_h__ */
diff --git a/embedding/browser/nsWebBrowserContentPolicy.cpp b/embedding/browser/nsWebBrowserContentPolicy.cpp
new file mode 100644
index 000000000..f6b17a197
--- /dev/null
+++ b/embedding/browser/nsWebBrowserContentPolicy.cpp
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsWebBrowserContentPolicy.h"
+#include "nsIDocShell.h"
+#include "nsCOMPtr.h"
+#include "nsContentPolicyUtils.h"
+#include "nsIContentViewer.h"
+
+nsWebBrowserContentPolicy::nsWebBrowserContentPolicy()
+{
+ MOZ_COUNT_CTOR(nsWebBrowserContentPolicy);
+}
+
+nsWebBrowserContentPolicy::~nsWebBrowserContentPolicy()
+{
+ MOZ_COUNT_DTOR(nsWebBrowserContentPolicy);
+}
+
+NS_IMPL_ISUPPORTS(nsWebBrowserContentPolicy, nsIContentPolicy)
+
+NS_IMETHODIMP
+nsWebBrowserContentPolicy::ShouldLoad(uint32_t aContentType,
+ nsIURI* aContentLocation,
+ nsIURI* aRequestingLocation,
+ nsISupports* aRequestingContext,
+ const nsACString& aMimeGuess,
+ nsISupports* aExtra,
+ nsIPrincipal* aRequestPrincipal,
+ int16_t* aShouldLoad)
+{
+ NS_PRECONDITION(aShouldLoad, "Null out param");
+
+ MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+ "We should only see external content policy types here.");
+
+ *aShouldLoad = nsIContentPolicy::ACCEPT;
+
+ nsIDocShell* shell = NS_CP_GetDocShellFromContext(aRequestingContext);
+ /* We're going to dereference shell, so make sure it isn't null */
+ if (!shell) {
+ return NS_OK;
+ }
+
+ nsresult rv;
+ bool allowed = true;
+
+ switch (aContentType) {
+ case nsIContentPolicy::TYPE_SCRIPT:
+ rv = shell->GetAllowJavascript(&allowed);
+ break;
+ case nsIContentPolicy::TYPE_SUBDOCUMENT:
+ rv = shell->GetAllowSubframes(&allowed);
+ break;
+#if 0
+ /* XXXtw: commented out in old code; add during conpol phase 2 */
+ case nsIContentPolicy::TYPE_REFRESH:
+ rv = shell->GetAllowMetaRedirects(&allowed); /* meta _refresh_ */
+ break;
+#endif
+ case nsIContentPolicy::TYPE_IMAGE:
+ case nsIContentPolicy::TYPE_IMAGESET:
+ rv = shell->GetAllowImages(&allowed);
+ break;
+ default:
+ return NS_OK;
+ }
+
+ if (NS_SUCCEEDED(rv) && !allowed) {
+ *aShouldLoad = nsIContentPolicy::REJECT_TYPE;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsWebBrowserContentPolicy::ShouldProcess(uint32_t aContentType,
+ nsIURI* aContentLocation,
+ nsIURI* aRequestingLocation,
+ nsISupports* aRequestingContext,
+ const nsACString& aMimeGuess,
+ nsISupports* aExtra,
+ nsIPrincipal* aRequestPrincipal,
+ int16_t* aShouldProcess)
+{
+ NS_PRECONDITION(aShouldProcess, "Null out param");
+
+ MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
+ "We should only see external content policy types here.");
+
+ *aShouldProcess = nsIContentPolicy::ACCEPT;
+
+ // Object tags will always open channels with TYPE_OBJECT, but may end up
+ // loading with TYPE_IMAGE or TYPE_DOCUMENT as their final type, so we block
+ // actual-plugins at the process stage
+ if (aContentType != nsIContentPolicy::TYPE_OBJECT) {
+ return NS_OK;
+ }
+
+ nsIDocShell* shell = NS_CP_GetDocShellFromContext(aRequestingContext);
+ if (shell && (!shell->PluginsAllowedInCurrentDoc())) {
+ *aShouldProcess = nsIContentPolicy::REJECT_TYPE;
+ }
+
+ return NS_OK;
+}
diff --git a/embedding/browser/nsWebBrowserContentPolicy.h b/embedding/browser/nsWebBrowserContentPolicy.h
new file mode 100644
index 000000000..e360e2110
--- /dev/null
+++ b/embedding/browser/nsWebBrowserContentPolicy.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIContentPolicy.h"
+
+/* f66bc334-1dd1-11b2-bab2-90e04fe15c19 */
+#define NS_WEBBROWSERCONTENTPOLICY_CID \
+ { 0xf66bc334, 0x1dd1, 0x11b2, { 0xba, 0xb2, 0x90, 0xe0, 0x4f, 0xe1, 0x5c, 0x19 } }
+
+#define NS_WEBBROWSERCONTENTPOLICY_CONTRACTID \
+ "@mozilla.org/embedding/browser/content-policy;1"
+
+class nsWebBrowserContentPolicy : public nsIContentPolicy
+{
+protected:
+ virtual ~nsWebBrowserContentPolicy();
+
+public:
+ nsWebBrowserContentPolicy();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICONTENTPOLICY
+};