diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 9bac8ee273..49bf298b66 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -428,6 +428,8 @@ @RESPATH@/components/nsLoginInfo.js @RESPATH@/components/nsLoginManager.js @RESPATH@/components/nsLoginManagerPrompter.js +@RESPATH@/components/TooltipTextProvider.js +@RESPATH@/components/TooltipTextProvider.manifest @RESPATH@/components/NetworkGeolocationProvider.manifest @RESPATH@/components/NetworkGeolocationProvider.js @RESPATH@/components/TVSimulatorService.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 47950714ac..16dd167e85 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -413,6 +413,8 @@ @RESPATH@/components/nsLoginManagerPrompter.js @RESPATH@/components/storage-json.js @RESPATH@/components/crypto-SDR.js +@RESPATH@/components/TooltipTextProvider.js +@RESPATH@/components/TooltipTextProvider.manifest @RESPATH@/components/jsconsole-clhandler.manifest @RESPATH@/components/jsconsole-clhandler.js #ifdef MOZ_DEVTOOLS diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 728e272766..d3b5e28481 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -10028,31 +10028,44 @@ nsDocShell::InternalLoad2(nsIURI* aURI, aLoadType == LOAD_HISTORY || aLoadType == LOAD_LINK) { nsCOMPtr currentURI = mCurrentURI; - // Split currentURI and aURI on the '#' character. Make sure we read - // the return values of SplitURIAtHash; if it fails, we don't want to - // allow a short-circuited navigation. - nsAutoCString curBeforeHash, curHash, newBeforeHash, newHash; - nsresult splitRv1, splitRv2; - splitRv1 = currentURI ? - nsContentUtils::SplitURIAtHash(currentURI, curBeforeHash, curHash) : - NS_ERROR_FAILURE; - splitRv2 = nsContentUtils::SplitURIAtHash(aURI, newBeforeHash, newHash); - bool sameExceptHashes = NS_SUCCEEDED(splitRv1) && - NS_SUCCEEDED(splitRv2) && - curBeforeHash.Equals(newBeforeHash); + nsAutoCString curHash, newHash; + bool curURIHasRef = false, newURIHasRef = false; + + nsresult rvURINew = aURI->GetRef(newHash); + if (NS_SUCCEEDED(rvURINew)) { + rvURINew = aURI->GetHasRef(&newURIHasRef); + } + + bool sameExceptHashes = false; + if (currentURI && NS_SUCCEEDED(rvURINew)) { + nsresult rvURIOld = currentURI->GetRef(curHash); + if (NS_SUCCEEDED(rvURIOld)) { + rvURIOld = currentURI->GetHasRef(&curURIHasRef); + } + if (NS_SUCCEEDED(rvURIOld)) { + if (NS_FAILED(currentURI->EqualsExceptRef(aURI, &sameExceptHashes))) { + sameExceptHashes = false; + } + } + } if (!sameExceptHashes && sURIFixup && currentURI && - NS_SUCCEEDED(splitRv2)) { + NS_SUCCEEDED(rvURINew)) { // Maybe aURI came from the exposable form of currentURI? nsCOMPtr currentExposableURI; rv = sURIFixup->CreateExposableURI(currentURI, getter_AddRefs(currentExposableURI)); NS_ENSURE_SUCCESS(rv, rv); - splitRv1 = nsContentUtils::SplitURIAtHash(currentExposableURI, - curBeforeHash, curHash); - sameExceptHashes = - NS_SUCCEEDED(splitRv1) && curBeforeHash.Equals(newBeforeHash); + nsresult rvURIOld = currentExposableURI->GetRef(curHash); + if (NS_SUCCEEDED(rvURIOld)) { + rvURIOld = currentExposableURI->GetHasRef(&curURIHasRef); + } + if (NS_SUCCEEDED(rvURIOld)) { + if (NS_FAILED(currentExposableURI->EqualsExceptRef(aURI, &sameExceptHashes))) { + sameExceptHashes = false; + } + } } bool historyNavBetweenSameDoc = false; @@ -10088,7 +10101,7 @@ nsDocShell::InternalLoad2(nsIURI* aURI, bool doShortCircuitedLoad = (historyNavBetweenSameDoc && mOSHE != aSHEntry) || (!aSHEntry && !aPostData && - sameExceptHashes && !newHash.IsEmpty()); + sameExceptHashes && newURIHasRef); if (doShortCircuitedLoad) { // Save the position of the scrollers. @@ -10243,7 +10256,7 @@ nsDocShell::InternalLoad2(nsIURI* aURI, // arguments it receives. But even if we don't end up scrolling, // ScrollToAnchor performs other important tasks, such as informing // the presShell that we have a new hash. See bug 680257. - rv = ScrollToAnchor(curHash, newHash, aLoadType); + rv = ScrollToAnchor(curURIHasRef, newURIHasRef, newHash, aLoadType); NS_ENSURE_SUCCESS(rv, rv); /* restore previous position of scroller(s), if we're moving @@ -10266,7 +10279,8 @@ nsDocShell::InternalLoad2(nsIURI* aURI, // reference to avoid null derefs. See bug 914521. if (win) { // Fire a hashchange event URIs differ, and only in their hashes. - bool doHashchange = sameExceptHashes && !curHash.Equals(newHash); + bool doHashchange = sameExceptHashes && + (curURIHasRef != newURIHasRef || !curHash.Equals(newHash)); if (historyNavBetweenSameDoc || doHashchange) { win->DispatchSyncPopState(); @@ -11151,8 +11165,8 @@ nsDocShell::DoChannelLoad(nsIChannel* aChannel, } nsresult -nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash, - uint32_t aLoadType) +nsDocShell::ScrollToAnchor(bool aCurHasRef, bool aNewHasRef, + nsACString& aNewHash, uint32_t aLoadType) { if (!mCurrentURI) { return NS_OK; @@ -11174,25 +11188,20 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash, // current anchor and we are doing a history load. So return if we have no // new anchor, and there is no current anchor or the load is not a history // load. - if ((aCurHash.IsEmpty() || aLoadType != LOAD_HISTORY) && - aNewHash.IsEmpty()) { + if ((!aCurHasRef || aLoadType != LOAD_HISTORY) && !aNewHasRef) { return NS_OK; } - // Take the '#' off aNewHash to get the ref name. (aNewHash might be empty, - // but that's fine.) - nsDependentCSubstring newHashName(aNewHash, 1); - // Both the new and current URIs refer to the same page. We can now // browse to the hash stored in the new URI. - if (!newHashName.IsEmpty()) { + if (!aNewHash.IsEmpty()) { // anchor is there, but if it's a load from history, // we don't have any anchor jumping to do bool scroll = aLoadType != LOAD_HISTORY && aLoadType != LOAD_RELOAD_NORMAL; - char* str = ToNewCString(newHashName); + char* str = ToNewCString(aNewHash); if (!str) { return NS_ERROR_OUT_OF_MEMORY; } @@ -11234,7 +11243,7 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash, nsXPIDLString uStr; rv = textToSubURI->UnEscapeAndConvert(PromiseFlatCString(aCharset).get(), - PromiseFlatCString(newHashName).get(), + PromiseFlatCString(aNewHash).get(), getter_Copies(uStr)); NS_ENSURE_SUCCESS(rv, rv); @@ -11244,7 +11253,7 @@ nsDocShell::ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash, // with the new URI no matter whether we actually scrolled // somewhere). // - // When newHashName contains "%00", unescaped string may be empty. + // When aNewHash contains "%00", unescaped string may be empty. // And GoToAnchor asserts if we ask it to scroll to an empty ref. shell->GoToAnchor(uStr, scroll && !uStr.IsEmpty(), nsIPresShell::SCROLL_SMOOTH_AUTO); diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index eaeb4cb903..d0027d75c9 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -377,7 +377,9 @@ protected: nsIURILoader* aURILoader, bool aBypassClassifier); - nsresult ScrollToAnchor(nsACString& aCurHash, nsACString& aNewHash, + nsresult ScrollToAnchor(bool aCurHasRef, + bool aNewHasRef, + nsACString& aNewHash, uint32_t aLoadType); // Returns true if would have called FireOnLocationChange, diff --git a/dom/audiochannel/AudioChannelService.cpp b/dom/audiochannel/AudioChannelService.cpp index 87399953c4..a4d10167e5 100644 --- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -397,7 +397,8 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel, } *aVolume *= window->GetAudioVolume(); - *aMuted = *aMuted || window->GetAudioMuted(); + // TODO : distiguish between suspend and mute, it would be done in bug1242874. + *aMuted = *aMuted || window->GetMediaSuspended() || window->GetAudioMuted(); nsCOMPtr win = window->GetScriptableParent(); if (window == win) { diff --git a/dom/base/File.cpp b/dom/base/File.cpp index 724c281d2e..36d2abc988 100644 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -456,7 +456,7 @@ File::WrapObject(JSContext* aCx, JS::Handle aGivenProto) } void -File::GetName(nsAString& aFileName) +File::GetName(nsAString& aFileName) const { mImpl->GetName(aFileName); } @@ -675,7 +675,7 @@ NS_IMPL_ISUPPORTS(BlobImpl, BlobImpl) NS_IMPL_ISUPPORTS_INHERITED0(BlobImplFile, BlobImpl) void -BlobImplBase::GetName(nsAString& aName) +BlobImplBase::GetName(nsAString& aName) const { NS_ASSERTION(mIsFile, "Should only be called on files"); aName = mName; @@ -951,6 +951,11 @@ EmptyBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength, { MOZ_ASSERT(!aStart && !aLength); RefPtr impl = new EmptyBlobImpl(aContentType); + + DebugOnly isMutable; + MOZ_ASSERT(NS_SUCCEEDED(impl->GetMutable(&isMutable))); + MOZ_ASSERT(!isMutable); + return impl.forget(); } @@ -958,6 +963,11 @@ void EmptyBlobImpl::GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv) { + if (NS_WARN_IF(!aStream)) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + nsresult rv = NS_NewCStringInputStream(aStream, EmptyCString()); if (NS_WARN_IF(NS_FAILED(rv))) { aRv.Throw(rv); diff --git a/dom/base/File.h b/dom/base/File.h index a052eb8b7b..0c1825ab63 100644 --- a/dom/base/File.h +++ b/dom/base/File.h @@ -224,7 +224,7 @@ public: const ChromeFilePropertyBag& aBag, ErrorResult& aRv); - void GetName(nsAString& aName); + void GetName(nsAString& aName) const; int64_t GetLastModified(ErrorResult& aRv); @@ -256,7 +256,7 @@ public: BlobImpl() {} - virtual void GetName(nsAString& aName) = 0; + virtual void GetName(nsAString& aName) const = 0; virtual void GetPath(nsAString& aName, ErrorResult& aRv) = 0; @@ -392,7 +392,7 @@ public: mContentType.SetIsVoid(false); } - virtual void GetName(nsAString& aName) override; + virtual void GetName(nsAString& aName) const override; virtual void GetPath(nsAString& aName, ErrorResult& aRv) override; @@ -759,7 +759,17 @@ public: explicit EmptyBlobImpl(const nsAString& aContentType) : BlobImplBase(aContentType, 0 /* aLength */) - {} + { + mImmutable = true; + } + + EmptyBlobImpl(const nsAString& aName, + const nsAString& aContentType, + int64_t aLastModifiedDate) + : BlobImplBase(aName, aContentType, 0, aLastModifiedDate) + { + mImmutable = true; + } virtual void GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv) override; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 1d5cc868ed..e905cec394 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -5416,32 +5416,6 @@ nsContentUtils::URIIsLocalFile(nsIURI *aURI) isFile; } -nsresult -nsContentUtils::SplitURIAtHash(nsIURI *aURI, - nsACString &aBeforeHash, - nsACString &aAfterHash) -{ - // See bug 225910 for why we can't do this using nsIURL. - - aBeforeHash.Truncate(); - aAfterHash.Truncate(); - - NS_ENSURE_ARG_POINTER(aURI); - - nsAutoCString spec; - nsresult rv = aURI->GetSpec(spec); - NS_ENSURE_SUCCESS(rv, rv); - - int32_t index = spec.FindChar('#'); - if (index == -1) { - index = spec.Length(); - } - - aBeforeHash.Assign(Substring(spec, 0, index)); - aAfterHash.Assign(Substring(spec, index)); - return NS_OK; -} - /* static */ nsIScriptContext* nsContentUtils::GetContextForEventHandlers(nsINode* aNode, diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 9163947eee..f5203376c0 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -1537,14 +1537,6 @@ public: */ static bool URIIsLocalFile(nsIURI *aURI); - /** - * Given a URI, return set beforeHash to the part before the '#', and - * afterHash to the remainder of the URI, including the '#'. - */ - static nsresult SplitURIAtHash(nsIURI *aURI, - nsACString &aBeforeHash, - nsACString &aAfterHash); - /** * Get the application manifest URI for this document. The manifest URI * is specified in the manifest= attribute of the root element of the diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index e6ed9b6ef0..a19caa5e74 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -3759,6 +3759,26 @@ nsDOMWindowUtils::PostRestyleSelfEvent(nsIDOMElement* aElement) return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::GetMediaSuspended(bool* aSuspended) +{ + nsCOMPtr window = do_QueryReferent(mWindow); + NS_ENSURE_STATE(window); + + *aSuspended = window->GetMediaSuspended(); + return NS_OK; +} + +NS_IMETHODIMP +nsDOMWindowUtils::SetMediaSuspended(bool aSuspended) +{ + nsCOMPtr window = do_QueryReferent(mWindow); + NS_ENSURE_STATE(window); + + window->SetMediaSuspended(aSuspended); + return NS_OK; +} + NS_IMETHODIMP nsDOMWindowUtils::GetAudioMuted(bool* aMuted) { diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 64ef0c8fad..f591b74014 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -831,6 +831,8 @@ GK_ATOM(onmozbrowserbeforekeydown, "onmozbrowserbeforekeydown") GK_ATOM(onmozbrowserbeforekeyup, "onmozbrowserbeforekeyup") GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange") GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror") +GK_ATOM(onmozkeydownonplugin, "onmozkeydownonplugin") +GK_ATOM(onmozkeyuponplugin, "onmozkeyuponplugin") GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange") GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror") GK_ATOM(onmoztimechange, "onmoztimechange") diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 42060c2de4..caeed4e12c 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -618,7 +618,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow) mMayHavePointerEnterLeaveEventListener(false), mInnerObjectsFreed(false), mIsModalContentWindow(false), - mIsActive(false), mIsBackground(false), + mIsActive(false), mIsBackground(false), mMediaSuspended(false), mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false), mDesktopModeViewport(false), mInnerWindow(nullptr), mOuterWindow(aOuterWindow), @@ -3717,6 +3717,32 @@ nsPIDOMWindow::CreatePerformanceObjectIfNeeded() } } +bool +nsPIDOMWindow::GetMediaSuspended() const +{ + if (IsInnerWindow()) { + return mOuterWindow->GetMediaSuspended(); + } + + return mMediaSuspended; +} + +void +nsPIDOMWindow::SetMediaSuspended(bool aSuspended) +{ + if (IsInnerWindow()) { + mOuterWindow->SetMediaSuspended(aSuspended); + return; + } + + if (mMediaSuspended == aSuspended) { + return; + } + + mMediaSuspended = aSuspended; + RefreshMediaElements(); +} + bool nsPIDOMWindow::GetAudioMuted() const { @@ -3782,6 +3808,28 @@ nsPIDOMWindow::RefreshMediaElements() } } +void +nsPIDOMWindow::SetServiceWorkersTestingEnabled(bool aEnabled) +{ + // Devtools should only be setting this on the top level window. Its + // ok if devtools clears the flag on clean up of nested windows, though. + // It will have no affect. +#ifdef DEBUG + nsCOMPtr topWindow = GetScriptableTop(); + MOZ_ASSERT_IF(aEnabled, this == topWindow); +#endif + mServiceWorkersTestingEnabled = aEnabled; +} + +bool +nsPIDOMWindow::GetServiceWorkersTestingEnabled() +{ + // Automatically get this setting from the top level window so that nested + // iframes get the correct devtools setting. + nsCOMPtr topWindow = GetScriptableTop(); + return topWindow->mServiceWorkersTestingEnabled; +} + bool nsPIDOMWindow::GetAudioCaptured() const { @@ -6674,10 +6722,7 @@ nsGlobalWindow::CanMoveResizeWindows(bool aCallerIsChrome) } } - // The preference is useful for the webapp runtime. Webapps should be able - // to resize or move their window. - if (mDocShell && !Preferences::GetBool("dom.always_allow_move_resize_window", - false)) { + if (mDocShell) { bool allow; nsresult rv = mDocShell->GetAllowWindowControl(&allow); if (NS_SUCCEEDED(rv) && !allow) @@ -10404,12 +10449,15 @@ nsGlobalWindow::DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI) // Make sure that aOldURI and aNewURI are identical up to the '#', and that // their hashes are different. - nsAutoCString oldBeforeHash, oldHash, newBeforeHash, newHash; - nsContentUtils::SplitURIAtHash(aOldURI, oldBeforeHash, oldHash); - nsContentUtils::SplitURIAtHash(aNewURI, newBeforeHash, newHash); - - NS_ENSURE_STATE(oldBeforeHash.Equals(newBeforeHash)); - NS_ENSURE_STATE(!oldHash.Equals(newHash)); + bool equal = false; + NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->EqualsExceptRef(aNewURI, &equal)) && equal); + nsAutoCString oldHash, newHash; + bool oldHasHash, newHasHash; + NS_ENSURE_STATE(NS_SUCCEEDED(aOldURI->GetRef(oldHash)) && + NS_SUCCEEDED(aNewURI->GetRef(newHash)) && + NS_SUCCEEDED(aOldURI->GetHasRef(&oldHasHash)) && + NS_SUCCEEDED(aNewURI->GetHasRef(&newHasHash)) && + (oldHasHash != newHasHash || !oldHash.Equals(newHash))); nsAutoCString oldSpec, newSpec; aOldURI->GetSpec(oldSpec); diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index ef310e1917..daddce96bd 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -202,6 +202,9 @@ public: virtual bool IsRunningTimeout() = 0; // Audio API + bool GetMediaSuspended() const; + void SetMediaSuspended(bool aSuspended); + bool GetAudioMuted() const; void SetAudioMuted(bool aMuted); @@ -211,17 +214,8 @@ public: bool GetAudioCaptured() const; nsresult SetAudioCapture(bool aCapture); - virtual void SetServiceWorkersTestingEnabled(bool aEnabled) - { - MOZ_ASSERT(IsOuterWindow()); - mServiceWorkersTestingEnabled = aEnabled; - } - - bool GetServiceWorkersTestingEnabled() - { - MOZ_ASSERT(IsOuterWindow()); - return mServiceWorkersTestingEnabled; - } + void SetServiceWorkersTestingEnabled(bool aEnabled); + bool GetServiceWorkersTestingEnabled(); already_AddRefed GetServiceWorkerRegistration(const nsAString& aScope); @@ -850,6 +844,7 @@ protected: // "active". Only used on outer windows. bool mIsBackground; + bool mMediaSuspended; bool mAudioMuted; float mAudioVolume; diff --git a/dom/browser-element/BrowserElementParent.cpp b/dom/browser-element/BrowserElementParent.cpp index 3b48ef0ba4..ec4d46de06 100644 --- a/dom/browser-element/BrowserElementParent.cpp +++ b/dom/browser-element/BrowserElementParent.cpp @@ -23,9 +23,12 @@ #include "nsVariant.h" #include "mozilla/dom/BrowserElementDictionariesBinding.h" #include "mozilla/dom/CustomEvent.h" +#include "mozilla/layout/RenderFrameParent.h" using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::layers; +using namespace mozilla::layout; namespace { @@ -205,9 +208,12 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement, BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent, TabParent* aPopupTabParent, + PRenderFrameParent* aRenderFrame, const nsAString& aURL, const nsAString& aName, - const nsAString& aFeatures) + const nsAString& aFeatures, + TextureFactoryIdentifier* aTextureFactoryIdentifier, + uint64_t* aLayersId) { // Create an iframe owned by the same document which owns openerFrameElement. nsCOMPtr openerFrameElement = aOpenerTabParent->GetOwnerElement(); @@ -241,6 +247,13 @@ BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent, aPopupTabParent->SetOwnerElement(popupFrameElement); popupFrameElement->AllowCreateFrameLoader(); popupFrameElement->CreateRemoteFrameLoader(aPopupTabParent); + + RenderFrameParent* rfp = static_cast(aRenderFrame); + if (!aPopupTabParent->SetRenderFrame(rfp) || + !aPopupTabParent->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) { + return BrowserElementParent::OPEN_WINDOW_IGNORED; + } + return opened; } diff --git a/dom/browser-element/BrowserElementParent.h b/dom/browser-element/BrowserElementParent.h index d67481cff9..219092b250 100644 --- a/dom/browser-element/BrowserElementParent.h +++ b/dom/browser-element/BrowserElementParent.h @@ -22,6 +22,14 @@ namespace dom { class TabParent; } // namespace dom +namespace layers { +struct TextureFactoryIdentifier; +} // namespace layers + +namespace layout { +class PRenderFrameParent; +} // namespace layout + /** * BrowserElementParent implements a portion of the parent-process side of *