diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 012d68455c..44c8699e61 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -82,6 +82,7 @@ #include "nsIRefreshURI.h" #include "nsIWebNavigation.h" #include "nsIScriptError.h" +#include "nsISimpleEnumerator.h" #include "nsStyleSheetService.h" #include "nsNetUtil.h" // for NS_NewURI @@ -6739,8 +6740,17 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const nsINode* imported = &aNode; switch (imported->NodeType()) { - case nsIDOMNode::ATTRIBUTE_NODE: + case nsIDOMNode::DOCUMENT_NODE: + { + break; + } case nsIDOMNode::DOCUMENT_FRAGMENT_NODE: + { + if (ShadowRoot::FromNode(imported)) { + break; + } + } + case nsIDOMNode::ATTRIBUTE_NODE: case nsIDOMNode::ELEMENT_NODE: case nsIDOMNode::PROCESSING_INSTRUCTION_NODE: case nsIDOMNode::TEXT_NODE: @@ -6760,11 +6770,10 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const default: { NS_WARNING("Don't know how to clone this nodetype for importNode."); - - rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); } } + rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } @@ -7767,6 +7776,12 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv) break; } case nsIDOMNode::DOCUMENT_FRAGMENT_NODE: + { + if (ShadowRoot::FromNode(adoptedNode)) { + rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); + return nullptr; + } + } case nsIDOMNode::ELEMENT_NODE: case nsIDOMNode::PROCESSING_INSTRUCTION_NODE: case nsIDOMNode::TEXT_NODE: diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 550c29fcaf..bd95868bcd 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -409,18 +409,6 @@ nsGlobalWindow::DOMMinTimeoutValue() const { } \ PR_END_MACRO -#define FORWARD_TO_INNER_OR_THROW(method, args, errorresult, err_rval) \ - PR_BEGIN_MACRO \ - if (IsOuterWindow()) { \ - if (!mInnerWindow) { \ - NS_WARNING("No inner window available!"); \ - errorresult.Throw(NS_ERROR_NOT_INITIALIZED); \ - return err_rval; \ - } \ - return GetCurrentInnerWindowInternal()->method args; \ - } \ - PR_END_MACRO - #define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval) \ PR_BEGIN_MACRO \ if (IsOuterWindow()) { \ @@ -3583,7 +3571,7 @@ nsGlobalWindow::GetSelf(nsIDOMWindow** aWindow) Navigator* nsGlobalWindow::GetNavigator(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetNavigator, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mNavigator) { mNavigator = new Navigator(this); @@ -3595,6 +3583,8 @@ nsGlobalWindow::GetNavigator(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetNavigator(nsIDOMNavigator** aNavigator) { + FORWARD_TO_INNER(GetNavigator, (aNavigator), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr navigator = GetNavigator(rv); navigator.forget(aNavigator); @@ -3605,7 +3595,7 @@ nsGlobalWindow::GetNavigator(nsIDOMNavigator** aNavigator) nsScreen* nsGlobalWindow::GetScreen(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetScreen, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mScreen) { mScreen = nsScreen::Create(this); @@ -3621,6 +3611,8 @@ nsGlobalWindow::GetScreen(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetScreen(nsIDOMScreen** aScreen) { + FORWARD_TO_INNER(GetScreen, (aScreen), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsRefPtr screen = GetScreen(rv); screen.forget(aScreen); @@ -3631,7 +3623,7 @@ nsGlobalWindow::GetScreen(nsIDOMScreen** aScreen) nsHistory* nsGlobalWindow::GetHistory(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetHistory, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mHistory) { mHistory = new nsHistory(this); @@ -3643,6 +3635,8 @@ nsGlobalWindow::GetHistory(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetHistory(nsISupports** aHistory) { + FORWARD_TO_INNER(GetHistory, (aHistory), NS_ERROR_FAILURE); + ErrorResult rv; nsCOMPtr history = GetHistory(rv); history.forget(aHistory); @@ -3769,7 +3763,7 @@ nsPIDOMWindow::RefreshMediaElements() SpeechSynthesis* nsGlobalWindow::GetSpeechSynthesis(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetSpeechSynthesis, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mSpeechSynthesis) { mSpeechSynthesis = new SpeechSynthesis(this); @@ -3999,6 +3993,8 @@ nsGlobalWindow::GetContent(nsIDOMWindow** aContent) MozSelfSupport* nsGlobalWindow::GetMozSelfSupport(ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + if (mMozSelfSupport) { return mMozSelfSupport; } @@ -4047,7 +4043,7 @@ nsGlobalWindow::GetPrompter(nsIPrompt** aPrompt) BarProp* nsGlobalWindow::GetMenubar(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetMenubar, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mMenubar) { mMenubar = new MenubarProp(this); @@ -4059,6 +4055,8 @@ nsGlobalWindow::GetMenubar(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetMenubar(nsISupports** aMenubar) { + FORWARD_TO_INNER(GetMenubar, (aMenubar), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr menubar = GetMenubar(rv); menubar.forget(aMenubar); @@ -4069,7 +4067,7 @@ nsGlobalWindow::GetMenubar(nsISupports** aMenubar) BarProp* nsGlobalWindow::GetToolbar(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetToolbar, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mToolbar) { mToolbar = new ToolbarProp(this); @@ -4081,6 +4079,8 @@ nsGlobalWindow::GetToolbar(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetToolbar(nsISupports** aToolbar) { + FORWARD_TO_INNER(GetToolbar, (aToolbar), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr toolbar = GetToolbar(rv); toolbar.forget(aToolbar); @@ -4091,7 +4091,7 @@ nsGlobalWindow::GetToolbar(nsISupports** aToolbar) BarProp* nsGlobalWindow::GetLocationbar(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetLocationbar, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mLocationbar) { mLocationbar = new LocationbarProp(this); @@ -4102,6 +4102,8 @@ nsGlobalWindow::GetLocationbar(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetLocationbar(nsISupports** aLocationbar) { + FORWARD_TO_INNER(GetLocationbar, (aLocationbar), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr locationbar = GetLocationbar(rv); locationbar.forget(aLocationbar); @@ -4112,7 +4114,7 @@ nsGlobalWindow::GetLocationbar(nsISupports** aLocationbar) BarProp* nsGlobalWindow::GetPersonalbar(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetPersonalbar, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mPersonalbar) { mPersonalbar = new PersonalbarProp(this); @@ -4123,6 +4125,8 @@ nsGlobalWindow::GetPersonalbar(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetPersonalbar(nsISupports** aPersonalbar) { + FORWARD_TO_INNER(GetPersonalbar, (aPersonalbar), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr personalbar = GetPersonalbar(rv); personalbar.forget(aPersonalbar); @@ -4133,7 +4137,7 @@ nsGlobalWindow::GetPersonalbar(nsISupports** aPersonalbar) BarProp* nsGlobalWindow::GetStatusbar(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetStatusbar, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mStatusbar) { mStatusbar = new StatusbarProp(this); @@ -4144,6 +4148,8 @@ nsGlobalWindow::GetStatusbar(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetStatusbar(nsISupports** aStatusbar) { + FORWARD_TO_INNER(GetStatusbar, (aStatusbar), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr statusbar = GetStatusbar(rv); statusbar.forget(aStatusbar); @@ -4154,7 +4160,7 @@ nsGlobalWindow::GetStatusbar(nsISupports** aStatusbar) BarProp* nsGlobalWindow::GetScrollbars(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetScrollbars, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mScrollbars) { mScrollbars = new ScrollbarsProp(this); @@ -4166,6 +4172,8 @@ nsGlobalWindow::GetScrollbars(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetScrollbars(nsISupports** aScrollbars) { + FORWARD_TO_INNER(GetScrollbars, (aScrollbars), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr scrollbars = GetScrollbars(rv); scrollbars.forget(aScrollbars); @@ -4307,6 +4315,7 @@ void nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, nsTArray& aNames, ErrorResult& aRv) { + MOZ_ASSERT(IsInnerWindow()); // "Components" is marked as enumerable but only resolved on demand :-/. //aNames.AppendElement(NS_LITERAL_STRING("Components")); @@ -4351,7 +4360,7 @@ nsGlobalWindow::IsShowModalDialogEnabled(JSContext*, JSObject*) nsIDOMOfflineResourceList* nsGlobalWindow::GetApplicationCache(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetApplicationCache, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mApplicationCache) { nsCOMPtr webNav(do_QueryInterface(GetDocShell())); @@ -4383,6 +4392,8 @@ nsGlobalWindow::GetApplicationCache(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetApplicationCache(nsIDOMOfflineResourceList **aApplicationCache) { + FORWARD_TO_INNER(GetApplicationCache, (aApplicationCache), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr applicationCache = GetApplicationCache(rv); @@ -4394,7 +4405,7 @@ nsGlobalWindow::GetApplicationCache(nsIDOMOfflineResourceList **aApplicationCach Crypto* nsGlobalWindow::GetCrypto(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetCrypto, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mCrypto) { mCrypto = new Crypto(); @@ -4406,6 +4417,8 @@ nsGlobalWindow::GetCrypto(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto) { + FORWARD_TO_INNER(GetCrypto, (aCrypto), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr crypto = GetCrypto(rv); crypto.forget(aCrypto); @@ -5308,6 +5321,8 @@ NS_IMETHODIMP nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback, int32_t *aHandle) { + FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback, aHandle), NS_ERROR_UNEXPECTED); + if (!aCallback) { if (mDoc) { mDoc->WarnOnceAbout(nsIDocument::eMozBeforePaint); @@ -5326,6 +5341,8 @@ int32_t nsGlobalWindow::RequestAnimationFrame(FrameRequestCallback& aCallback, ErrorResult& aError) { + MOZ_RELEASE_ASSERT(IsInnerWindow()); + nsIDocument::FrameRequestCallbackHolder holder(&aCallback); return RequestAnimationFrame(holder, aError); } @@ -5334,6 +5351,7 @@ int32_t nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback, ErrorResult& aError) { + MOZ_RELEASE_ASSERT(IsInnerWindow()); nsIDocument::FrameRequestCallbackHolder holder(aCallback); return RequestAnimationFrame(holder, aError); } @@ -5342,8 +5360,7 @@ int32_t nsGlobalWindow::RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback, ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(RequestAnimationFrame, (aCallback, aError), aError, - 0); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mDoc) { return 0; @@ -5363,6 +5380,7 @@ nsGlobalWindow::RequestAnimationFrame(JS::Handle aCallback, JSContext* cx, int32_t* aHandle) { + FORWARD_TO_INNER(RequestAnimationFrame, (aCallback, cx, aHandle), NS_ERROR_UNEXPECTED); if (!aCallback.isObject() || !JS::IsCallable(&aCallback.toObject())) { return NS_ERROR_INVALID_ARG; } @@ -5380,19 +5398,21 @@ nsGlobalWindow::RequestAnimationFrame(JS::Handle aCallback, NS_IMETHODIMP nsGlobalWindow::MozCancelRequestAnimationFrame(int32_t aHandle) { + FORWARD_TO_INNER(MozCancelRequestAnimationFrame, (aHandle), NS_ERROR_UNEXPECTED); return CancelAnimationFrame(aHandle); } NS_IMETHODIMP nsGlobalWindow::MozCancelAnimationFrame(int32_t aHandle) { + FORWARD_TO_INNER(MozCancelAnimationFrame, (aHandle), NS_ERROR_UNEXPECTED); return CancelAnimationFrame(aHandle); } void nsGlobalWindow::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(CancelAnimationFrame, (aHandle, aError), aError, ); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mDoc) { return; @@ -5404,6 +5424,8 @@ nsGlobalWindow::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::CancelAnimationFrame(int32_t aHandle) { + FORWARD_TO_INNER(CancelAnimationFrame, (aHandle), NS_ERROR_UNEXPECTED); + ErrorResult rv; CancelAnimationFrame(aHandle, rv); @@ -5413,7 +5435,7 @@ nsGlobalWindow::CancelAnimationFrame(int32_t aHandle) int64_t nsGlobalWindow::GetMozAnimationStartTime(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetMozAnimationStartTime, (aError), aError, 0); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (mDoc) { nsIPresShell* presShell = mDoc->GetShell(); @@ -5430,6 +5452,8 @@ nsGlobalWindow::GetMozAnimationStartTime(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetMozAnimationStartTime(int64_t *aTime) { + FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_UNEXPECTED); + ErrorResult rv; *aTime = GetMozAnimationStartTime(rv); @@ -7521,6 +7545,8 @@ nsGlobalWindow::MozRequestOverfill(OverfillCallback& aCallback, void nsGlobalWindow::ClearTimeout(int32_t aHandle, ErrorResult& aError) { + MOZ_RELEASE_ASSERT(IsInnerWindow()); + if (aHandle > 0) { ClearTimeoutOrInterval(aHandle, aError); } @@ -7529,6 +7555,8 @@ nsGlobalWindow::ClearTimeout(int32_t aHandle, ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::ClearTimeout(int32_t aHandle) { + FORWARD_TO_INNER(ClearTimeout, (aHandle), NS_ERROR_UNEXPECTED); + ErrorResult rv; ClearTimeout(aHandle, rv); @@ -8919,12 +8947,47 @@ nsGlobalWindow::GetRealFrameElement(nsIDOMElement** aFrameElement) return rv.StealNSResult(); } +/* static */ bool +nsGlobalWindow::TokenizeDialogOptions(nsAString& aToken, + nsAString::const_iterator& aIter, + nsAString::const_iterator aEnd) +{ + while (aIter != aEnd && nsCRT::IsAsciiSpace(*aIter)) { + ++aIter; + } + + if (aIter == aEnd) { + return false; + } + + if (*aIter == ';' || *aIter == ':' || *aIter == '=') { + aToken.Assign(*aIter); + ++aIter; + return true; + } + + nsAString::const_iterator start = aIter; + + // Skip characters until we find whitespace, ';', ':', or '=' + while (aIter != aEnd && !nsCRT::IsAsciiSpace(*aIter) && + *aIter != ';' && + *aIter != ':' && + *aIter != '=') { + ++aIter; + } + + aToken.Assign(Substring(start, aIter)); + return true; +} + // Helper for converting window.showModalDialog() options (list of ';' // separated name (:|=) value pairs) to a format that's parsable by // our normal window opening code. +/* static */ void -ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult) +nsGlobalWindow::ConvertDialogOptions(const nsAString& aOptions, + nsAString& aResult) { nsAString::const_iterator end; aOptions.EndReading(end); @@ -8932,68 +8995,35 @@ ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult) nsAString::const_iterator iter; aOptions.BeginReading(iter); - while (iter != end) { - // Skip whitespace. - while (nsCRT::IsAsciiSpace(*iter) && iter != end) { - ++iter; + nsAutoString token; + nsAutoString name; + nsAutoString value; + + while (true) { + if (!TokenizeDialogOptions(name, iter, end)) { + break; } - nsAString::const_iterator name_start = iter; - - // Skip characters until we find whitespace, ';', ':', or '=' - while (iter != end && !nsCRT::IsAsciiSpace(*iter) && - *iter != ';' && - *iter != ':' && - *iter != '=') { - ++iter; + // Invalid name. + if (name.EqualsLiteral("=") || + name.EqualsLiteral(":") || + name.EqualsLiteral(";")) { + break; } - nsAString::const_iterator name_end = iter; - - // Skip whitespace. - while (nsCRT::IsAsciiSpace(*iter) && iter != end) { - ++iter; + if (!TokenizeDialogOptions(token, iter, end)) { + break; } - if (*iter == ';') { - // No value found, skip the ';' and keep going. - ++iter; - + if (!token.EqualsLiteral(":") && !token.EqualsLiteral("=")) { continue; } - nsAString::const_iterator value_start = iter; - nsAString::const_iterator value_end = iter; - - if (*iter == ':' || *iter == '=') { - // We found name followed by ':' or '='. Look for a value. - - iter++; // Skip the ':' or '=' - - // Skip whitespace. - while (nsCRT::IsAsciiSpace(*iter) && iter != end) { - ++iter; - } - - value_start = iter; - - // Skip until we find whitespace, or ';'. - while (iter != end && !nsCRT::IsAsciiSpace(*iter) && - *iter != ';') { - ++iter; - } - - value_end = iter; - - // Skip whitespace. - while (nsCRT::IsAsciiSpace(*iter) && iter != end) { - ++iter; - } + // We found name followed by ':' or '='. Look for a value. + if (!TokenizeDialogOptions(value, iter, end)) { + break; } - const nsDependentSubstring& name = Substring(name_start, name_end); - const nsDependentSubstring& value = Substring(value_start, value_end); - if (name.LowerCaseEqualsLiteral("center")) { if (value.LowerCaseEqualsLiteral("on") || value.LowerCaseEqualsLiteral("yes") || @@ -9034,11 +9064,11 @@ ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult) } } - if (iter == end) { + if (iter == end || + !TokenizeDialogOptions(token, iter, end) || + !token.EqualsLiteral(";")) { break; } - - iter++; } } @@ -9620,11 +9650,10 @@ nsGlobalWindow::GetPrivateRoot() return static_cast(top.get()); } - nsLocation* nsGlobalWindow::GetLocation(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetLocation, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); nsIDocShell *docShell = GetDocShell(); if (!mLocation && docShell) { @@ -9636,6 +9665,8 @@ nsGlobalWindow::GetLocation(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetLocation(nsIDOMLocation ** aLocation) { + FORWARD_TO_INNER(GetLocation, (aLocation), NS_ERROR_UNEXPECTED); + ErrorResult rv; nsCOMPtr location = GetLocation(rv); location.forget(aLocation); @@ -10016,7 +10047,7 @@ private: nsresult nsGlobalWindow::DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI) { - FORWARD_TO_INNER(DispatchAsyncHashchange, (aOldURI, aNewURI), NS_OK); + MOZ_RELEASE_ASSERT(IsInnerWindow()); // Make sure that aOldURI and aNewURI are identical up to the '#', and that // their hashes are different. @@ -10046,8 +10077,9 @@ nsGlobalWindow::FireHashchange(const nsAString &aOldURL, MOZ_ASSERT(IsInnerWindow()); // Don't do anything if the window is frozen. - if (IsFrozen()) + if (IsFrozen()) { return NS_OK; + } // Get a presentation shell for use in creating the hashchange event. NS_ENSURE_STATE(IsCurrentInnerWindow()); @@ -10077,8 +10109,7 @@ nsGlobalWindow::FireHashchange(const nsAString &aOldURL, nsresult nsGlobalWindow::DispatchSyncPopState() { - FORWARD_TO_INNER(DispatchSyncPopState, (), NS_OK); - + MOZ_RELEASE_ASSERT(IsInnerWindow()); NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "Must be safe to run script here."); @@ -10306,7 +10337,7 @@ nsGlobalWindow::GetComputedStyleHelper(Element& aElt, DOMStorage* nsGlobalWindow::GetSessionStorage(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetSessionStorage, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); nsIPrincipal *principal = GetPrincipal(); nsIDocShell* docShell = GetDocShell(); @@ -10385,6 +10416,8 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError) NS_IMETHODIMP nsGlobalWindow::GetSessionStorage(nsISupports** aSessionStorage) { + FORWARD_TO_INNER(GetSessionStorage, (aSessionStorage), NS_ERROR_FAILURE); + ErrorResult rv; nsCOMPtr storage = GetSessionStorage(rv); storage.forget(aSessionStorage); @@ -10395,7 +10428,7 @@ nsGlobalWindow::GetSessionStorage(nsISupports** aSessionStorage) DOMStorage* nsGlobalWindow::GetLocalStorage(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetLocalStorage, (aError), aError, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!Preferences::GetBool(kStorageEnabled)) { return nullptr; @@ -10451,6 +10484,7 @@ NS_IMETHODIMP nsGlobalWindow::GetLocalStorage(nsISupports** aLocalStorage) { NS_ENSURE_ARG(aLocalStorage); + FORWARD_TO_INNER(GetLocalStorage, (aLocalStorage), NS_ERROR_UNEXPECTED); ErrorResult rv; nsCOMPtr storage = GetLocalStorage(rv); @@ -10462,6 +10496,7 @@ nsGlobalWindow::GetLocalStorage(nsISupports** aLocalStorage) IDBFactory* nsGlobalWindow::GetIndexedDB(ErrorResult& aError) { + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mIndexedDB) { // This may keep mIndexedDB null without setting an error. aError = IDBFactory::CreateForWindow(this, getter_AddRefs(mIndexedDB)); @@ -10564,13 +10599,9 @@ already_AddRefed nsGlobalWindow::GetCaches(ErrorResult& aRv) { if (!mCacheStorage) { - bool forceTrustedOrigin = false; - if (IsOuterWindow()) { - forceTrustedOrigin = GetServiceWorkersTestingEnabled(); - } else { - nsRefPtr outer = GetOuterWindowInternal(); - forceTrustedOrigin = outer->GetServiceWorkersTestingEnabled(); - } + bool forceTrustedOrigin = + GetOuterWindowInternal()->GetServiceWorkersTestingEnabled(); + mCacheStorage = CacheStorage::CreateOnMainThread(cache::DEFAULT_NAMESPACE, this, GetPrincipal(), IsPrivateBrowsing(), @@ -12409,8 +12440,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) void nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID, ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(ClearTimeoutOrInterval, (aTimerID, aError), - aError, ); + MOZ_RELEASE_ASSERT(IsInnerWindow()); uint32_t public_id = (uint32_t)aTimerID; nsTimeout *timeout; @@ -13654,6 +13684,8 @@ nsGlobalWindow::NotifyDefaultButtonLoaded(Element& aDefaultButton, NS_IMETHODIMP nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager) { + FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_UNEXPECTED); + ErrorResult rv; NS_IF_ADDREF(*aManager = GetMessageManager(rv)); return rv.StealNSResult(); @@ -13662,8 +13694,8 @@ nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager) nsIMessageBroadcaster* nsGlobalWindow::GetMessageManager(ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetMessageManager, (aError), aError, nullptr); MOZ_ASSERT(IsChromeWindow()); + MOZ_RELEASE_ASSERT(IsInnerWindow()); nsGlobalChromeWindow* myself = static_cast(this); if (!myself->mMessageManager) { nsCOMPtr globalMM = @@ -13680,6 +13712,8 @@ NS_IMETHODIMP nsGlobalChromeWindow::GetGroupMessageManager(const nsAString& aGroup, nsIMessageBroadcaster** aManager) { + FORWARD_TO_INNER_CHROME(GetGroupMessageManager, (aGroup, aManager), NS_ERROR_UNEXPECTED); + ErrorResult rv; NS_IF_ADDREF(*aManager = GetGroupMessageManager(aGroup, rv)); return rv.StealNSResult(); @@ -13689,8 +13723,8 @@ nsIMessageBroadcaster* nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup, ErrorResult& aError) { - FORWARD_TO_INNER_OR_THROW(GetGroupMessageManager, (aGroup, aError), aError, nullptr); MOZ_ASSERT(IsChromeWindow()); + MOZ_RELEASE_ASSERT(IsInnerWindow()); nsGlobalChromeWindow* myself = static_cast(this); nsCOMPtr messageManager = @@ -13855,6 +13889,8 @@ NS_IMETHODIMP nsGlobalWindow::GetConsole(JSContext* aCx, JS::MutableHandle aConsole) { + FORWARD_TO_INNER(GetConsole, (aCx, aConsole), NS_ERROR_FAILURE); + ErrorResult rv; nsRefPtr console = GetConsole(rv); if (rv.Failed()) { @@ -13879,7 +13915,7 @@ nsGlobalWindow::SetConsole(JSContext* aCx, JS::Handle aValue) Console* nsGlobalWindow::GetConsole(ErrorResult& aRv) { - FORWARD_TO_INNER_OR_THROW(GetConsole, (aRv), aRv, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mConsole) { mConsole = new Console(this); @@ -13891,7 +13927,7 @@ nsGlobalWindow::GetConsole(ErrorResult& aRv) already_AddRefed nsGlobalWindow::GetExternal(ErrorResult& aRv) { - FORWARD_TO_INNER_OR_THROW(GetExternal, (aRv), aRv, nullptr); + MOZ_RELEASE_ASSERT(IsInnerWindow()); #ifdef HAVE_SIDEBAR if (!mExternal) { @@ -13917,7 +13953,7 @@ void nsGlobalWindow::GetSidebar(OwningExternalOrWindowProxy& aResult, ErrorResult& aRv) { - FORWARD_TO_INNER_OR_THROW(GetSidebar, (aResult, aRv), aRv, ); + MOZ_RELEASE_ASSERT(IsInnerWindow()); #ifdef HAVE_SIDEBAR // First check for a named frame named "sidebar" diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 0ee4d9a6af..ee4350933e 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -893,6 +893,13 @@ public: mozilla::ErrorResult& aRv); already_AddRefed GetExternal(mozilla::ErrorResult& aRv); + // Exposed only for testing + static bool + TokenizeDialogOptions(nsAString& aToken, nsAString::const_iterator& aIter, + nsAString::const_iterator aEnd); + static void + ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult); + protected: bool AlertOrConfirm(bool aAlert, const nsAString& aMessage, mozilla::ErrorResult& aError); @@ -1622,6 +1629,7 @@ protected: nsRefPtr mNavigator; nsRefPtr mScreen; nsRefPtr mFrames; + // All BarProps are inner window only. nsRefPtr mMenubar; nsRefPtr mToolbar; nsRefPtr mLocationbar; diff --git a/dom/base/nsHistory.cpp b/dom/base/nsHistory.cpp index 09d54d6068..837a2694f6 100644 --- a/dom/base/nsHistory.cpp +++ b/dom/base/nsHistory.cpp @@ -46,6 +46,7 @@ NS_INTERFACE_MAP_END nsHistory::nsHistory(nsPIDOMWindow* aInnerWindow) : mInnerWindow(do_GetWeakReference(aInnerWindow)) { + MOZ_ASSERT(aInnerWindow->IsInnerWindow()); } nsHistory::~nsHistory() diff --git a/dom/base/nsScreen.cpp b/dom/base/nsScreen.cpp index b1249691f2..3d7fb38b08 100644 --- a/dom/base/nsScreen.cpp +++ b/dom/base/nsScreen.cpp @@ -25,6 +25,7 @@ using namespace mozilla::dom; nsScreen::Create(nsPIDOMWindow* aWindow) { MOZ_ASSERT(aWindow); + MOZ_ASSERT(aWindow->IsInnerWindow()); if (!aWindow->GetDocShell()) { return nullptr; diff --git a/dom/base/test/gtest/TestParserDialogOptions.cpp b/dom/base/test/gtest/TestParserDialogOptions.cpp new file mode 100644 index 0000000000..055f9ebfdf --- /dev/null +++ b/dom/base/test/gtest/TestParserDialogOptions.cpp @@ -0,0 +1,138 @@ +/* -*- 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 "gtest/gtest.h" +#include "nsGlobalWindow.h" + +struct dialog_test { + const char* input; + const char* output; +}; + +void runTokenizeTest(dialog_test& test) +{ + NS_ConvertUTF8toUTF16 input(test.input); + + nsAString::const_iterator end; + input.EndReading(end); + + nsAString::const_iterator iter; + input.BeginReading(iter); + + nsAutoString result; + nsAutoString token; + + while (nsGlobalWindow::TokenizeDialogOptions(token, iter, end)) { + if (!result.IsEmpty()) { + result.Append(','); + } + + result.Append(token); + } + + ASSERT_STREQ(test.output, NS_ConvertUTF16toUTF8(result).get()) << "Testing " << test.input; +} + +void runTest(dialog_test& test) +{ + NS_ConvertUTF8toUTF16 input(test.input); + + nsAutoString result; + nsGlobalWindow::ConvertDialogOptions(input, result); + + ASSERT_STREQ(test.output, NS_ConvertUTF16toUTF8(result).get()) << "Testing " << test.input; +} + +TEST(GlobalWindowDialogOptions, TestDialogTokenize) +{ + dialog_test tests[] = { + /// Empty strings + { "", "" }, + { " ", "" }, + { " ", "" }, + + // 1 token + { "a", "a" }, + { " a", "a" }, + { " a ", "a" }, + { "aa", "aa" }, + { " aa", "aa" }, + { " aa ", "aa" }, + { ";", ";" }, + { ":", ":" }, + { "=", "=" }, + + // 2 tokens + { "a=", "a,=" }, + { " a= ", "a,=" }, + { " a = ", "a,=" }, + { "aa=", "aa,=" }, + { " aa= ", "aa,=" }, + { " aa = ", "aa,=" }, + { ";= ", ";,=" }, + { "==", "=,=" }, + { "::", ":,:" }, + + // 3 tokens + { "a=2", "a,=,2" }, + { "===", "=,=,=" }, + { ";:=", ";,:,=" }, + + // more + { "aaa;bbb:ccc", "aaa,;,bbb,:,ccc" }, + + // sentinel + { nullptr, nullptr } + }; + + for (uint32_t i = 0; tests[i].input; ++i) { + runTokenizeTest(tests[i]); + } +} +TEST(GlobalWindowDialogOptions, TestDialogOptions) +{ + dialog_test tests[] = { + /// Empty strings + { "", "" }, + { " ", "" }, + { " ", "" }, + + // Name without params + { "a", "" }, + { " a", "" }, + { " a ", "" }, + { "a=", "" }, + { " a= ", "" }, + { " a = ", "" }, + + // 1 unknown value + { "a=2", "" }, + { " a=2 ", "" }, + { " a = 2 ", "" }, + { "a:2", "" }, + { " a:2 ", "" }, + { " a : 2 ", "" }, + + // 1 known value, wrong value + { "center=2", "" }, + { "center:2", "" }, + + // 1 known value, good value + { "center=on", ",centerscreen=1" }, + { "center:on", ",centerscreen=1" }, + { " center : on ", ",centerscreen=1" }, + + // nonsense stuff + { " ; ", "" }, + + // sentinel + { nullptr, nullptr } + }; + + for (uint32_t i = 0; tests[i].input; ++i) { + runTest(tests[i]); + } +} diff --git a/dom/base/test/gtest/moz.build b/dom/base/test/gtest/moz.build new file mode 100644 index 0000000000..cd62303789 --- /dev/null +++ b/dom/base/test/gtest/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; c-basic-offset: 4; 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/. + +UNIFIED_SOURCES += [ + 'TestParserDialogOptions.cpp', +] + +LOCAL_INCLUDES += [ + '/dom/base' +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul-gtest' diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 4b338d791c..b6fad6710d 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -660,6 +660,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 904183 # b2g(bug 904183 [test_createHTMLDocument.html] [test_declare_stylesheet_obsolete.html] [test_document_constructor.html] +[test_document_importNode_document.html] [test_domparser_null_char.html] [test_domparsing.html] [test_elementTraversal.html] diff --git a/dom/base/test/moz.build b/dom/base/test/moz.build index 9fdfe9ae43..0e21c2f09d 100644 --- a/dom/base/test/moz.build +++ b/dom/base/test/moz.build @@ -36,3 +36,7 @@ MOCHITEST_CHROME_MANIFESTS += [ BROWSER_CHROME_MANIFESTS += [ 'browser.ini', ] + +TEST_DIRS += [ + 'gtest', +] diff --git a/dom/base/test/test_document_importNode_document.html b/dom/base/test/test_document_importNode_document.html new file mode 100644 index 0000000000..e33575e844 --- /dev/null +++ b/dom/base/test/test_document_importNode_document.html @@ -0,0 +1,32 @@ + + + + + Test for Bug 1177914 + + + + + +Mozilla Bug 1177914 +

+ +
+
+
+ + diff --git a/dom/media/webspeech/synth/SpeechSynthesis.cpp b/dom/media/webspeech/synth/SpeechSynthesis.cpp index 4601c09267..e09537685a 100644 --- a/dom/media/webspeech/synth/SpeechSynthesis.cpp +++ b/dom/media/webspeech/synth/SpeechSynthesis.cpp @@ -73,6 +73,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechSynthesis) SpeechSynthesis::SpeechSynthesis(nsPIDOMWindow* aParent) : mParent(aParent) { + MOZ_ASSERT(aParent->IsInnerWindow()); } SpeechSynthesis::~SpeechSynthesis() diff --git a/dom/tests/mochitest/webcomponents/mochitest.ini b/dom/tests/mochitest/webcomponents/mochitest.ini index b15f84a522..35dcd73be7 100644 --- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -17,6 +17,8 @@ support-files = [test_fallback_dest_insertion_points.html] [test_detached_style.html] [test_dynamic_content_element_matching.html] +[test_document_adoptnode.html] +[test_document_importnode.html] [test_document_register.html] [test_document_register_base_queue.html] [test_document_register_lifecycle.html] diff --git a/dom/tests/mochitest/webcomponents/test_document_adoptnode.html b/dom/tests/mochitest/webcomponents/test_document_adoptnode.html new file mode 100644 index 0000000000..b00bb4fac7 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_document_adoptnode.html @@ -0,0 +1,36 @@ + + + + + Test for Bug 1177991 + + + + + +Mozilla Bug 1177991 +

+ +
+
+
+ + diff --git a/dom/tests/mochitest/webcomponents/test_document_importnode.html b/dom/tests/mochitest/webcomponents/test_document_importnode.html new file mode 100644 index 0000000000..f9042fddfa --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_document_importnode.html @@ -0,0 +1,37 @@ + + + + + Test for Bug 1177914 + + + + + +Mozilla Bug 1177914 +

+ +
+
+
+ + diff --git a/xpfe/appshell/nsXULWindow.cpp b/xpfe/appshell/nsXULWindow.cpp index ef4fb74242..730c58b0a0 100644 --- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -1962,8 +1962,15 @@ void nsXULWindow::PlaceWindowLayersBehind(uint32_t aLowLevel, void nsXULWindow::SetContentScrollbarVisibility(bool aVisible) { nsCOMPtr contentWin(do_GetInterface(mPrimaryContentShell)); + if (!contentWin) { + return; + } + + MOZ_ASSERT(contentWin->IsOuterWindow()); + contentWin = contentWin->GetCurrentInnerWindow(); if (contentWin) { mozilla::ErrorResult rv; + nsRefPtr window = static_cast(contentWin.get()); nsRefPtr scrollbars = window->GetScrollbars(rv); if (scrollbars) {