author | Peter Van der Beken <peterv@propagandism.org> |
Wed, 05 Feb 2014 22:09:18 +0100 | |
changeset 177548 | 4fbe5c6db77386bc98efd3a43b78061c48575b2d |
parent 177547 | de6943d52d81efa91c0155e945ab4e00cb0a964c |
child 177549 | 72b4d4463629780dcf5733aea3bbce8fd8b64907 |
push id | 26556 |
push user | ryanvm@gmail.com |
push date | Tue, 08 Apr 2014 22:16:57 +0000 |
treeherder | mozilla-central@5811efc11011 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 990475 |
milestone | 31.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1717,16 +1717,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_ NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGlobalWindow, tmp->mRefCnt.get()) } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArguments) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDialogArguments) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReturnValue) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance) #ifdef MOZ_WEBSPEECH NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis) #endif @@ -1774,16 +1775,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow) nsGlobalWindow::CleanupCachedXBLHandlers(tmp); NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext) NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers) NS_IMPL_CYCLE_COLLECTION_UNLINK(mArguments) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDialogArguments) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mReturnValue) NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator) NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance) #ifdef MOZ_WEBSPEECH NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis) #endif @@ -13416,66 +13418,135 @@ nsGlobalWindow::GetMessageManager(ErrorR MM_CHROME | MM_BROADCASTER); } return myself->mMessageManager; } // nsGlobalModalWindow implementation // QueryInterface implementation for nsGlobalModalWindow -NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsGlobalModalWindow, - nsGlobalWindow, - mReturnValue) - DOMCI_DATA(ModalContentWindow, nsGlobalModalWindow) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalModalWindow) +NS_INTERFACE_MAP_BEGIN(nsGlobalModalWindow) NS_INTERFACE_MAP_ENTRY(nsIDOMModalContentWindow) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ModalContentWindow) NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow) NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow) NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow) +JS::Value +nsGlobalWindow::GetDialogArguments(JSContext* aCx, ErrorResult& aError) +{ + FORWARD_TO_OUTER_OR_THROW(GetDialogArguments, (aCx, aError), aError, + JS::UndefinedValue()); + + MOZ_ASSERT(IsModalContentWindow(), + "This should only be called on modal windows!"); + + // This does an internal origin check, and returns undefined if the subject + // does not subsumes the origin of the arguments. + JSObject* wrapper = GetWrapper(); + JSAutoCompartment ac(aCx, wrapper); + JS::Rooted<JS::Value> args(aCx); + mDialogArguments->Get(aCx, wrapper, nsContentUtils::GetSubjectPrincipal(), + &args, aError); + return args; +} + NS_IMETHODIMP nsGlobalModalWindow::GetDialogArguments(nsIVariant **aArguments) { FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(GetDialogArguments, (aArguments), NS_ERROR_NOT_INITIALIZED); // This does an internal origin check, and returns undefined if the subject // does not subsumes the origin of the arguments. return mDialogArguments->Get(nsContentUtils::GetSubjectPrincipal(), aArguments); } +JS::Value +nsGlobalWindow::GetReturnValue(JSContext* aCx, ErrorResult& aError) +{ + FORWARD_TO_OUTER_OR_THROW(GetReturnValue, (aCx, aError), aError, + JS::UndefinedValue()); + + MOZ_ASSERT(IsModalContentWindow(), + "This should only be called on modal windows!"); + + JS::Rooted<JS::Value> returnValue(aCx); + if (mReturnValue) { + JSObject* wrapper = GetWrapper(); + JSAutoCompartment ac(aCx, wrapper); + mReturnValue->Get(aCx, wrapper, nsContentUtils::GetSubjectPrincipal(), + &returnValue, aError); + } + return returnValue; +} + NS_IMETHODIMP nsGlobalModalWindow::GetReturnValue(nsIVariant **aRetVal) { FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(GetReturnValue, (aRetVal), NS_OK); nsCOMPtr<nsIVariant> result; if (!mReturnValue) { nsCOMPtr<nsIVariant> variant = CreateVoidVariant(); variant.forget(aRetVal); return NS_OK; } return mReturnValue->Get(nsContentUtils::GetSubjectPrincipal(), aRetVal); } +void +nsGlobalWindow::SetReturnValue(JSContext* aCx, + JS::Handle<JS::Value> aReturnValue, + ErrorResult& aError) +{ + FORWARD_TO_OUTER_OR_THROW(SetReturnValue, (aCx, aReturnValue, aError), + aError, ); + + MOZ_ASSERT(IsModalContentWindow(), + "This should only be called on modal windows!"); + + nsCOMPtr<nsIVariant> returnValue; + aError = + nsContentUtils::XPConnect()->JSToVariant(aCx, aReturnValue, + getter_AddRefs(returnValue)); + if (!aError.Failed()) { + mReturnValue = new DialogValueHolder(nsContentUtils::GetSubjectPrincipal(), + returnValue); + } +} + NS_IMETHODIMP nsGlobalModalWindow::SetReturnValue(nsIVariant *aRetVal) { FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(SetReturnValue, (aRetVal), NS_OK); mReturnValue = new DialogValueHolder(nsContentUtils::GetSubjectPrincipal(), aRetVal); return NS_OK; } +/* static */ +bool +nsGlobalWindow::IsModalContentWindow(JSContext* aCx, JSObject* aGlobal) +{ + // For now, have to deal with XPConnect objects here. + nsGlobalWindow* win; + nsresult rv = UNWRAP_OBJECT(Window, aGlobal, win); + if (NS_FAILED(rv)) { + nsCOMPtr<nsPIDOMWindow> piWin = do_QueryWrapper(aCx, aGlobal); + win = static_cast<nsGlobalWindow*>(piWin.get()); + } + return win->IsModalContentWindow(); +} + NS_IMETHODIMP nsGlobalWindow::GetConsole(JSContext* aCx, JS::MutableHandle<JS::Value> aConsole) { ErrorResult rv; nsRefPtr<Console> console = GetConsole(rv); if (rv.Failed()) { return rv.ErrorCode();
--- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -272,16 +272,26 @@ public: if (aSubject->SubsumesConsideringDomain(mOrigin)) { result = mValue; } else { result = CreateVoidVariant(); } result.forget(aResult); return NS_OK; } + void Get(JSContext* aCx, JSObject* aScope, nsIPrincipal* aSubject, + JS::MutableHandle<JS::Value> aResult, mozilla::ErrorResult& aError) + { + if (aSubject->Subsumes(mOrigin)) { + aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope, + mValue, aResult); + } else { + aResult.setUndefined(); + } + } virtual ~DialogValueHolder() {} private: nsCOMPtr<nsIPrincipal> mOrigin; nsCOMPtr<nsIVariant> mValue; }; //***************************************************************************** // nsGlobalWindow: Global Object for Scripting @@ -576,16 +586,19 @@ public: return mCreatingInnerWindow; } bool IsChromeWindow() const { return mIsChrome; } + using nsPIDOMWindow::IsModalContentWindow; + static bool IsModalContentWindow(JSContext* aCx, JSObject* aGlobal); + // GetScrollFrame does not flush. Callers should do it themselves as needed, // depending on which info they actually want off the scrollable frame. nsIScrollableFrame *GetScrollFrame(); nsresult Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData); // Outer windows only. @@ -977,16 +990,21 @@ public: void Restore(mozilla::ErrorResult& aError); void NotifyDefaultButtonLoaded(mozilla::dom::Element& aDefaultButton, mozilla::ErrorResult& aError); nsIMessageBroadcaster* GetMessageManager(mozilla::ErrorResult& aError); void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent, mozilla::dom::Element* aPanel, mozilla::ErrorResult& aError); + JS::Value GetDialogArguments(JSContext* aCx, mozilla::ErrorResult& aError); + JS::Value GetReturnValue(JSContext* aCx, mozilla::ErrorResult& aError); + void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue, + mozilla::ErrorResult& aError); + protected: // Array of idle observers that are notified of idle events. nsTObserverArray<IdleObserverHolder> mIdleObservers; // Idle timer used for function callbacks to notify idle observers. nsCOMPtr<nsITimer> mIdleTimer; // Idle fuzz time added to idle timer callbacks. @@ -1435,16 +1453,19 @@ protected: nsCOMPtr<nsIControllers> mControllers; // For |window.arguments|, via |openDialog|. nsCOMPtr<nsIArray> mArguments; // For |window.dialogArguments|, via |showModalDialog|. nsRefPtr<DialogValueHolder> mDialogArguments; + // Only used in the outer. + nsRefPtr<DialogValueHolder> mReturnValue; + nsRefPtr<mozilla::dom::Navigator> mNavigator; nsRefPtr<nsScreen> mScreen; nsRefPtr<nsDOMWindowList> mFrames; nsRefPtr<mozilla::dom::BarProp> mMenubar; nsRefPtr<mozilla::dom::BarProp> mToolbar; nsRefPtr<mozilla::dom::BarProp> mLocationbar; nsRefPtr<mozilla::dom::BarProp> mPersonalbar; nsRefPtr<mozilla::dom::BarProp> mStatusbar; @@ -1634,22 +1655,16 @@ public: nsGlobalModalWindow(nsGlobalWindow *aOuterWindow) : nsGlobalWindow(aOuterWindow) { mIsModalContentWindow = true; } NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMMODALCONTENTWINDOW - - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalModalWindow, nsGlobalWindow) - -protected: - // For use by outer windows only. - nsRefPtr<DialogValueHolder> mReturnValue; }; /* factory function */ inline already_AddRefed<nsGlobalWindow> NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow) { nsRefPtr<nsGlobalWindow> global;
--- a/dom/tests/mochitest/general/file_showModalDialog.html +++ b/dom/tests/mochitest/general/file_showModalDialog.html @@ -1,15 +1,15 @@ <!DOCTYPE html> <html> <head> <script> function go() { is(SpecialPowers.wrap(window).location.toString(), location.toString(), "sanity"); - is(SpecialPowers.Cu.getClassName(window, /* aUnwrap = */ true), "ModalContentWindow", "We are modal"); + ok("returnValue" in window && "dialogArguments" in window, "We are modal"); var iwin = document.getElementById('ifr').contentWindow; is(SpecialPowers.Cu.getClassName(iwin, /* aUnwrap = */ true), "Window", "Descendant frames should not be modal"); if (location.origin != "http://mochi.test:8888") { is(window.dialogArguments, undefined, "dialogArguments should be undefined cross-origin: " + location.origin); }
--- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -220,16 +220,24 @@ partial interface Window { [NoInterfaceObject] interface SpeechSynthesisGetter { [Throws, Pref="media.webspeech.synth.enabled"] readonly attribute SpeechSynthesis speechSynthesis; }; Window implements SpeechSynthesisGetter; #endif +// http://www.whatwg.org/specs/web-apps/current-work/ +[NoInterfaceObject] +interface WindowModal { + [Throws, Func="nsGlobalWindow::IsModalContentWindow"] readonly attribute any dialogArguments; + [Throws, Func="nsGlobalWindow::IsModalContentWindow"] attribute any returnValue; +}; +Window implements WindowModal; + // Mozilla-specific stuff partial interface Window { //[NewObject, Throws] CSSStyleDeclaration getDefaultComputedStyle(Element elt, optional DOMString pseudoElt = ""); [NewObject, Throws] CSSStyleDeclaration? getDefaultComputedStyle(Element elt, optional DOMString pseudoElt = ""); [Throws] long mozRequestAnimationFrame(MozFrameRequestCallback aCallback); /**