diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 50516d129bf..948f18b5d4d 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -132,6 +132,7 @@ @BINPATH@/components/autocomplete.xpt @BINPATH@/components/autoconfig.xpt @BINPATH@/components/browsercompsbase.xpt +@BINPATH@/components/browser-element.xpt @BINPATH@/components/browser-feeds.xpt @BINPATH@/components/caps.xpt @BINPATH@/components/chardet.xpt diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 7f81993c60e..a7d975de399 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -177,6 +177,7 @@ @BINPATH@/components/appstartup.xpt @BINPATH@/components/autocomplete.xpt @BINPATH@/components/autoconfig.xpt +@BINPATH@/components/browser-element.xpt @BINPATH@/browser/components/browsercompsbase.xpt @BINPATH@/browser/components/browser-feeds.xpt @BINPATH@/components/caps.xpt diff --git a/dom/browser-element/moz.build b/dom/browser-element/moz.build index 01bacdfec69..cae90a01847 100644 --- a/dom/browser-element/moz.build +++ b/dom/browser-element/moz.build @@ -12,6 +12,12 @@ SOURCES += [ 'BrowserElementParent.cpp', ] +XPIDL_SOURCES += [ + 'nsIBrowserElementAPI.idl', +] + +XPIDL_MODULE = 'browser-element' + EXTRA_COMPONENTS += [ 'BrowserElementParent.js', 'BrowserElementParent.manifest', diff --git a/dom/browser-element/nsIBrowserElementAPI.idl b/dom/browser-element/nsIBrowserElementAPI.idl new file mode 100644 index 00000000000..46a888ac3ce --- /dev/null +++ b/dom/browser-element/nsIBrowserElementAPI.idl @@ -0,0 +1,74 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=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 "nsISupports.idl" + +interface nsIDOMDOMRequest; +interface nsIFrameLoader; + +[scriptable, function, uuid(c0c2dd9b-41ef-42dd-a4c1-e456619c1941)] +interface nsIBrowserElementNextPaintListener : nsISupports +{ + void recvNextPaint(); +}; + +%{C++ +#define BROWSER_ELEMENT_API_CONTRACTID "@mozilla.org/dom/browser-element-api;1" +#define BROWSER_ELEMENT_API_CID \ + { 0x651db7e3, 0x1734, 0x4536, \ + { 0xb1, 0x5a, 0x5b, 0x3a, 0xe6, 0x44, 0x13, 0x4c } } +%} + +/** + * Interface to the BrowserElementParent implementation. All methods + * but setFrameLoader throw when the remote process is dead. + */ +[scriptable, uuid(abae4fb1-7d6f-4e3f-b435-6501f1d4c659)] +interface nsIBrowserElementAPI : nsISupports +{ + void setFrameLoader(in nsIFrameLoader frameLoader); + + void setVisible(in boolean visible); + nsIDOMDOMRequest getVisible(); + void setActive(in boolean active); + boolean getActive(); + + void sendMouseEvent(in DOMString type, + in uint32_t x, + in uint32_t y, + in uint32_t button, + in uint32_t clickCount, + in uint32_t mifiers); + void sendTouchEvent(in DOMString aType, + [const, array, size_is(count)] in uint32_t aIdentifiers, + [const, array, size_is(count)] in int32_t aXs, + [const, array, size_is(count)] in int32_t aYs, + [const, array, size_is(count)] in uint32_t aRxs, + [const, array, size_is(count)] in uint32_t aRys, + [const, array, size_is(count)] in float aRotationAngles, + [const, array, size_is(count)] in float aForces, + in uint32_t count, + in long aModifiers); + void goBack(); + void goForward(); + void reload(in boolean hardReload); + void stop(); + nsIDOMDOMRequest download(in DOMString url, + [optional] in jsval options); + nsIDOMDOMRequest purgeHistory(); + nsIDOMDOMRequest getScreenshot(in uint32_t width, + in uint32_t height, + [optional] in DOMString mimeType); + void zoom(in float zoom); + nsIDOMDOMRequest getCanGoBack(); + nsIDOMDOMRequest getCanGoForward(); + nsIDOMDOMRequest getContentDimensions(); + + void addNextPaintListener(in nsIBrowserElementNextPaintListener listener); + void removeNextPaintListener(in nsIBrowserElementNextPaintListener listener); + + nsIDOMDOMRequest setInputMethodActive(in boolean isActive); +}; diff --git a/dom/html/nsBrowserElement.cpp b/dom/html/nsBrowserElement.cpp index fc14ad3e92f..bc24e73d566 100644 --- a/dom/html/nsBrowserElement.cpp +++ b/dom/html/nsBrowserElement.cpp @@ -6,36 +6,198 @@ #include "nsBrowserElement.h" +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" #include "mozilla/dom/BrowserElementBinding.h" #include "mozilla/dom/DOMRequest.h" -#include "mozilla/Preferences.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/ToJSValue.h" + +#include "nsComponentManagerUtils.h" +#include "nsContentUtils.h" +#include "nsFrameLoader.h" +#include "nsIDOMDOMRequest.h" +#include "nsIDOMElement.h" +#include "nsINode.h" +#include "nsIObserver.h" +#include "nsIObserverService.h" +#include "nsIPrincipal.h" +#include "nsWeakReference.h" + +using namespace mozilla::dom; namespace mozilla { +static const char kRemoteBrowserPending[] = "remote-browser-pending"; +static const char kInprocessBrowserShown[] = "inprocess-browser-shown"; + +class nsBrowserElement::BrowserShownObserver : public nsIObserver + , public nsSupportsWeakReference +{ +public: + BrowserShownObserver(nsBrowserElement* aBrowserElement); + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + void AddObserver(); + void RemoveObserver(); +private: + virtual ~BrowserShownObserver(); + + // Weak reference to the browser element. nsBrowserElement has a + // reference to us. nsBrowserElement's destructor is responsible to + // null out this weak reference via RemoveObserver() + nsBrowserElement* mBrowserElement; +}; + +NS_IMPL_ISUPPORTS(nsBrowserElement::BrowserShownObserver, nsIObserver, nsISupportsWeakReference) + +nsBrowserElement::BrowserShownObserver::BrowserShownObserver(nsBrowserElement* aBrowserElement) + : mBrowserElement(aBrowserElement) +{ +} + +nsBrowserElement::BrowserShownObserver::~BrowserShownObserver() +{ + RemoveObserver(); +} + +NS_IMETHODIMP +nsBrowserElement::BrowserShownObserver::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) +{ + NS_ENSURE_TRUE(mBrowserElement, NS_OK); + + if (!strcmp(aTopic, kRemoteBrowserPending) || + !strcmp(aTopic, kInprocessBrowserShown)) { + nsCOMPtr frameLoader = do_QueryInterface(aSubject); + nsCOMPtr myFrameLoader = mBrowserElement->GetFrameLoader(); + // The browser element API needs the frameloader to + // initialize. We still use the observer to get notified when the + // frameloader is created. So we check if the frameloader created + // is ours, then initialize the browser element API. + if (frameLoader && frameLoader == myFrameLoader) { + mBrowserElement->InitBrowserElementAPI(); + } + } + return NS_OK; +} + +void +nsBrowserElement::BrowserShownObserver::AddObserver() +{ + nsCOMPtr obs = services::GetObserverService(); + if (obs) { + obs->AddObserver(this, kRemoteBrowserPending, true); + obs->AddObserver(this, kInprocessBrowserShown, true); + } +} + +void +nsBrowserElement::BrowserShownObserver::RemoveObserver() +{ + nsCOMPtr obs = services::GetObserverService(); + if (obs) { + obs->RemoveObserver(this, kRemoteBrowserPending); + obs->RemoveObserver(this, kInprocessBrowserShown); + } + mBrowserElement = nullptr; +} + +bool +nsBrowserElement::IsBrowserElementOrThrow(ErrorResult& aRv) +{ + if (mBrowserElementAPI) { + return true; + } + aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR); + return false; +} + +void +nsBrowserElement::InitBrowserElementAPI() +{ + bool isBrowserOrApp; + nsCOMPtr frameLoader = GetFrameLoader(); + NS_ENSURE_TRUE_VOID(frameLoader); + nsresult rv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp); + NS_ENSURE_SUCCESS_VOID(rv); + + if (!isBrowserOrApp) { + return; + } + + mBrowserElementAPI = do_CreateInstance("@mozilla.org/dom/browser-element-api;1"); + if (mBrowserElementAPI) { + mBrowserElementAPI->SetFrameLoader(frameLoader); + } +} + +nsBrowserElement::nsBrowserElement() +{ + mObserver = new BrowserShownObserver(this); + mObserver->AddObserver(); +} + +nsBrowserElement::~nsBrowserElement() +{ + mObserver->RemoveObserver(); +} + void nsBrowserElement::SetVisible(bool aVisible, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->SetVisible(aVisible); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } -already_AddRefed +already_AddRefed nsBrowserElement::GetVisible(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->GetVisible(getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } void nsBrowserElement::SetActive(bool aVisible, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->SetActive(aVisible); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } bool nsBrowserElement::GetActive(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return false; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), false); + + bool isActive; + nsresult rv = mBrowserElementAPI->GetActive(&isActive); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return false; + } + + return isActive; } void @@ -47,122 +209,307 @@ nsBrowserElement::SendMouseEvent(const nsAString& aType, uint32_t aModifiers, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->SendMouseEvent(aType, + aX, + aY, + aButton, + aClickCount, + aModifiers); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void nsBrowserElement::SendTouchEvent(const nsAString& aType, - const dom::Sequence& aIdentifiers, - const dom::Sequence& aXs, - const dom::Sequence& aYs, - const dom::Sequence& aRxs, - const dom::Sequence& aRys, - const dom::Sequence& aRotationAngles, - const dom::Sequence& aForces, + const Sequence& aIdentifiers, + const Sequence& aXs, + const Sequence& aYs, + const Sequence& aRxs, + const Sequence& aRys, + const Sequence& aRotationAngles, + const Sequence& aForces, uint32_t aCount, uint32_t aModifiers, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + if (aIdentifiers.Length() != aCount || + aXs.Length() != aCount || + aYs.Length() != aCount || + aRxs.Length() != aCount || + aRys.Length() != aCount || + aRotationAngles.Length() != aCount || + aForces.Length() != aCount) { + aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); + return; + } + + nsresult rv = mBrowserElementAPI->SendTouchEvent(aType, + aIdentifiers.Elements(), + aXs.Elements(), + aYs.Elements(), + aRxs.Elements(), + aRys.Elements(), + aRotationAngles.Elements(), + aForces.Elements(), + aCount, + aModifiers); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void nsBrowserElement::GoBack(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->GoBack(); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void nsBrowserElement::GoForward(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->GoForward(); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void nsBrowserElement::Reload(bool aHardReload, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->Reload(aHardReload); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void nsBrowserElement::Stop(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + nsresult rv = mBrowserElementAPI->Stop(); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } -already_AddRefed +already_AddRefed nsBrowserElement::Download(const nsAString& aUrl, - const dom::BrowserElementDownloadOptions& aOptions, + const BrowserElementDownloadOptions& aOptions, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + AutoJSAPI jsapi; + jsapi.Init(); + JS::Rooted options(jsapi.cx()); + if (!ToJSValue(jsapi.cx(), aOptions, &options)) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + nsresult rv = mBrowserElementAPI->Download(aUrl, options, getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } -already_AddRefed +already_AddRefed nsBrowserElement::PurgeHistory(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->PurgeHistory(getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } -already_AddRefed +already_AddRefed nsBrowserElement::GetScreenshot(uint32_t aWidth, uint32_t aHeight, - const dom::Optional& aMimeType, + const nsAString& aMimeType, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->GetScreenshot(aWidth, aHeight, aMimeType, + getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + if (rv == NS_ERROR_INVALID_ARG) { + aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); + } else { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } + return nullptr; + } + + return req.forget().downcast(); } void nsBrowserElement::Zoom(float aZoom, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + nsresult rv = mBrowserElementAPI->Zoom(aZoom); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } -already_AddRefed +already_AddRefed nsBrowserElement::GetCanGoBack(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->GetCanGoBack(getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } -already_AddRefed +already_AddRefed nsBrowserElement::GetCanGoForward(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->GetCanGoForward(getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } -already_AddRefed +already_AddRefed nsBrowserElement::GetContentDimensions(ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr req; + nsresult rv = mBrowserElementAPI->GetContentDimensions(getter_AddRefs(req)); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + return req.forget().downcast(); } void -nsBrowserElement::AddNextPaintListener(dom::BrowserElementNextPaintEventCallback& aListener, +nsBrowserElement::AddNextPaintListener(BrowserElementNextPaintEventCallback& aListener, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + CallbackObjectHolder holder(&aListener); + nsCOMPtr listener = holder.ToXPCOMCallback(); + + nsresult rv = mBrowserElementAPI->AddNextPaintListener(listener); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } void -nsBrowserElement::RemoveNextPaintListener(dom::BrowserElementNextPaintEventCallback& aListener, +nsBrowserElement::RemoveNextPaintListener(BrowserElementNextPaintEventCallback& aListener, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv)); + + CallbackObjectHolder holder(&aListener); + nsCOMPtr listener = holder.ToXPCOMCallback(); + + nsresult rv = mBrowserElementAPI->RemoveNextPaintListener(listener); + + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } } -already_AddRefed +already_AddRefed nsBrowserElement::SetInputMethodActive(bool aIsActive, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); + + nsCOMPtr frameLoader = GetFrameLoader(); + if (!frameLoader) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + + nsCOMPtr ownerElement; + nsresult rv = frameLoader->GetOwnerElement(getter_AddRefs(ownerElement)); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + + nsCOMPtr node = do_QueryInterface(ownerElement); + nsCOMPtr principal = node->NodePrincipal(); + if (!nsContentUtils::IsExactSitePermAllow(principal, "input-manage")) { + aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); + return nullptr; + } + + nsCOMPtr req; + rv = mBrowserElementAPI->SetInputMethodActive(aIsActive, + getter_AddRefs(req)); + if (NS_WARN_IF(NS_FAILED(rv))) { + if (rv == NS_ERROR_INVALID_ARG) { + aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); + } else { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + } + return nullptr; + } + + return req.forget().downcast(); } } // namespace mozilla diff --git a/dom/html/nsBrowserElement.h b/dom/html/nsBrowserElement.h index ce5772cd044..e78f26bc7dd 100644 --- a/dom/html/nsBrowserElement.h +++ b/dom/html/nsBrowserElement.h @@ -10,6 +10,10 @@ #include "mozilla/dom/BindingDeclarations.h" #include "nsCOMPtr.h" +#include "nsIBrowserElementAPI.h" + +class nsFrameLoader; +class nsIObserver; namespace mozilla { @@ -27,6 +31,9 @@ class ErrorResult; class nsBrowserElement { public: + nsBrowserElement(); + virtual ~nsBrowserElement(); + void SetVisible(bool aVisible, ErrorResult& aRv); already_AddRefed GetVisible(ErrorResult& aRv); void SetActive(bool aActive, ErrorResult& aRv); @@ -65,7 +72,7 @@ public: already_AddRefed GetScreenshot(uint32_t aWidth, uint32_t aHeight, - const dom::Optional& aMimeType, + const nsAString& aMimeType, ErrorResult& aRv); void Zoom(float aZoom, ErrorResult& aRv); @@ -81,6 +88,18 @@ public: already_AddRefed SetInputMethodActive(bool isActive, ErrorResult& aRv); + +protected: + NS_IMETHOD_(already_AddRefed) GetFrameLoader() = 0; + nsCOMPtr mBrowserElementAPI; + +private: + void InitBrowserElementAPI(); + bool IsBrowserElementOrThrow(ErrorResult& aRv); + + class BrowserShownObserver; + friend class BrowserShownObserver; + nsRefPtr mObserver; }; } // namespace mozilla diff --git a/dom/html/nsGenericHTMLFrameElement.cpp b/dom/html/nsGenericHTMLFrameElement.cpp index 8b17fe7d57b..fab61b63189 100644 --- a/dom/html/nsGenericHTMLFrameElement.cpp +++ b/dom/html/nsGenericHTMLFrameElement.cpp @@ -34,6 +34,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement) diff --git a/dom/html/nsGenericHTMLFrameElement.h b/dom/html/nsGenericHTMLFrameElement.h index ce89fa8e875..06ee2c514a4 100644 --- a/dom/html/nsGenericHTMLFrameElement.h +++ b/dom/html/nsGenericHTMLFrameElement.h @@ -34,6 +34,7 @@ public: mozilla::dom::FromParser aFromParser) : nsGenericHTMLElement(aNodeInfo) , nsElementFrameLoaderOwner(aFromParser) + , nsBrowserElement() { } @@ -73,6 +74,19 @@ public: static bool BrowserFramesEnabled(); + /** + * nsIFrameLoaderOwner defines two GetFrameLoader() overloads. One + * is XPCOM style interface, the other one is C++ only. "using" pulls + * them both in, now GetFrameLoader() is ambiguous because + * nsBrowserElement also has GetFrameLoader(). Explicit redefine + * GetFrameLoader() to choose nsElementFrameLoaderOwner::GetFrameLoader() + */ + using nsElementFrameLoaderOwner::GetFrameLoader; + NS_IMETHOD_(already_AddRefed) GetFrameLoader() MOZ_OVERRIDE + { + return nsElementFrameLoaderOwner::GetFrameLoader(); + } + /** * Helper method to map a HTML 'scrolling' attribute value to a nsIScrollable * enum value. scrolling="no" (and its synonyms) maps to diff --git a/dom/webidl/BrowserElement.webidl b/dom/webidl/BrowserElement.webidl index a569d8e55ce..8fddcdbc446 100644 --- a/dom/webidl/BrowserElement.webidl +++ b/dom/webidl/BrowserElement.webidl @@ -113,7 +113,7 @@ interface BrowserElementPrivileged { CheckPermissions="browser"] DOMRequest getScreenshot([EnforceRange] unsigned long width, [EnforceRange] unsigned long height, - optional DOMString mimeType); + optional DOMString mimeType=""); [Throws, Pref="dom.mozBrowserFramesEnabled", diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index cffd15a560b..32e4bb6b206 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -117,6 +117,7 @@ @BINPATH@/components/autocomplete.xpt @BINPATH@/components/autoconfig.xpt @BINPATH@/components/browsercompsbase.xpt +@BINPATH@/components/browser-element.xpt @BINPATH@/components/browser-feeds.xpt @BINPATH@/components/caps.xpt @BINPATH@/components/chardet.xpt