mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-05 13:45:46 +00:00
Bug 387706 - Implement HTML5's cross-document messaging API (postMessage), enabling secure cross-origin communication between windows. r+sr=sicking, sr=jst, a=jst
This commit is contained in:
parent
59a622849e
commit
637b116885
@ -102,5 +102,7 @@ nsresult
|
||||
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsXULCommandEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
@ -80,6 +80,7 @@ CPPSRCS = \
|
||||
nsDOMPageTransitionEvent.cpp \
|
||||
nsDOMXULCommandEvent.cpp \
|
||||
nsDOMCommandEvent.cpp \
|
||||
nsDOMMessageEvent.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
nsDOMEventGroup.cpp \
|
||||
nsXMLEventsManager.cpp \
|
||||
|
131
content/events/src/nsDOMMessageEvent.cpp
Normal file
131
content/events/src/nsDOMMessageEvent.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMMessageEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMessageEvent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMMessageEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMessageEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MessageEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMMessageEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMMessageEvent, nsDOMEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::GetData(nsAString& aData)
|
||||
{
|
||||
aData = mData;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::GetDomain(nsAString& aDomain)
|
||||
{
|
||||
aDomain = mDomain;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::GetUri(nsAString& aURI)
|
||||
{
|
||||
aURI = mURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::GetSource(nsIDOMWindow** aSource)
|
||||
{
|
||||
NS_IF_ADDREF(*aSource = mSource);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::InitMessageEvent(const nsAString& aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
const nsAString& aData,
|
||||
const nsAString& aDomain,
|
||||
const nsAString& aURI,
|
||||
nsIDOMWindow* aSource)
|
||||
{
|
||||
nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mData = aData;
|
||||
mDomain = aDomain;
|
||||
mURI = aURI;
|
||||
mSource = aSource;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMessageEvent::InitMessageEventNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
const nsAString& aData,
|
||||
const nsAString& aDomain,
|
||||
const nsAString& aURI,
|
||||
nsIDOMWindow* aSource)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
{
|
||||
nsDOMMessageEvent* it = new nsDOMMessageEvent(aPresContext, aEvent);
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return CallQueryInterface(it, aInstancePtrResult);
|
||||
}
|
76
content/events/src/nsDOMMessageEvent.h
Normal file
76
content/events/src/nsDOMMessageEvent.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMMessageEvent_h__
|
||||
#define nsDOMMessageEvent_h__
|
||||
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
/**
|
||||
* Implements the MessageEvent event, used for cross-document messaging.
|
||||
*
|
||||
* See http://www.whatwg.org/specs/web-apps/current-work/#messageevent for
|
||||
* further details.
|
||||
*/
|
||||
class nsDOMMessageEvent : public nsIDOMMessageEvent,
|
||||
public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
nsDOMMessageEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMMessageEvent, nsDOMEvent)
|
||||
|
||||
NS_DECL_NSIDOMMESSAGEEVENT
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
private:
|
||||
nsString mData;
|
||||
nsString mDomain;
|
||||
nsString mURI;
|
||||
nsCOMPtr<nsIDOMWindow> mSource;
|
||||
};
|
||||
|
||||
#endif // nsDOMMessageEvent_h__
|
@ -651,6 +651,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
|
||||
return NS_NewDOMDataContainerEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("messageevent"))
|
||||
return NS_NewDOMMessageEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
@ -44,7 +44,14 @@ interface nsIControllers;
|
||||
interface nsIDOMLocation;
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(0d12a345-3fe2-491e-af0d-bcfd5c4baa03)]
|
||||
%{C++
|
||||
/* I hate you, Windows. */
|
||||
#ifdef PostMessage
|
||||
#undef PostMessage
|
||||
#endif
|
||||
%}
|
||||
|
||||
[scriptable, uuid(86f7b733-aff9-469a-9e8c-2996f7db2720)]
|
||||
interface nsIDOMWindowInternal : nsIDOMWindow2
|
||||
{
|
||||
readonly attribute nsIDOMWindowInternal window;
|
||||
@ -200,4 +207,19 @@ interface nsIDOMWindowInternal : nsIDOMWindow2
|
||||
nsIVariant showModalDialog(in DOMString aURI,
|
||||
[optional] in nsIVariant aArgs,
|
||||
[optional] in DOMString aOptions);
|
||||
|
||||
/**
|
||||
* Implements a safe message-passing system which can cross same-origin
|
||||
* boundaries.
|
||||
*
|
||||
* This method, when called, causes a MessageEvent to be dispatched at the
|
||||
* primary document for the window upon which this method is called. (Note
|
||||
* that the postMessage property on windows is allAccess and thus is readable
|
||||
* cross-origin.) The dispatched event will have message as its data, the
|
||||
* calling context's window as its source, and a domain and URI determined by
|
||||
* the calling context's main document URI.
|
||||
*
|
||||
* See the WHATWG HTML5 specification, section 6.4, for more details.
|
||||
*/
|
||||
void postMessage(in DOMString message);
|
||||
};
|
||||
|
@ -71,6 +71,7 @@ XPIDLSRCS = \
|
||||
nsIDOMSmartCardEvent.idl \
|
||||
nsIDOMPageTransitionEvent.idl \
|
||||
nsIDOMCommandEvent.idl \
|
||||
nsIDOMMessageEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
97
dom/public/idl/events/nsIDOMMessageEvent.idl
Normal file
97
dom/public/idl/events/nsIDOMMessageEvent.idl
Normal file
@ -0,0 +1,97 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMEvent.idl"
|
||||
|
||||
/**
|
||||
* The nsIDOMMessageEvent interface is used for server-sent events and for
|
||||
* cross-domain messaging.
|
||||
*
|
||||
* For more information on this interface, please see
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/multipage/section-event0.html#event0
|
||||
*/
|
||||
[scriptable, uuid(3CF6163E-0227-49D9-B52B-F061828FB9B8)]
|
||||
interface nsIDOMMessageEvent : nsIDOMEvent
|
||||
{
|
||||
/**
|
||||
* Custom string data associated with this event.
|
||||
*/
|
||||
readonly attribute DOMString data;
|
||||
|
||||
/**
|
||||
* The domain of the site from which this event originated.
|
||||
*/
|
||||
readonly attribute DOMString domain;
|
||||
|
||||
/**
|
||||
* The URI of the site from which this event was created.
|
||||
*/
|
||||
readonly attribute DOMString uri;
|
||||
|
||||
/**
|
||||
* The window which originated this event.
|
||||
*/
|
||||
readonly attribute nsIDOMWindow source;
|
||||
|
||||
/**
|
||||
* Initializes this event with the given data, in a manner analogous to
|
||||
* the similarly-named method on the nsIDOMEvent interface, also setting the
|
||||
* data, domain, uri, and source attributes of this appropriately.
|
||||
*/
|
||||
void initMessageEvent(in DOMString aType,
|
||||
in boolean aCanBubble,
|
||||
in boolean aCancelable,
|
||||
in DOMString aData,
|
||||
in DOMString aDomain,
|
||||
in DOMString aURI,
|
||||
in nsIDOMWindow aSource);
|
||||
|
||||
/**
|
||||
* Initializes this event with the given data, in a manner analogous to
|
||||
* the similarly-named method on the Event interface, also setting the data,
|
||||
* domain, uri, and source attributes of this appropriately.
|
||||
*/
|
||||
void initMessageEventNS(in DOMString aNamespaceURI,
|
||||
in DOMString aType,
|
||||
in boolean aCanBubble,
|
||||
in boolean aCancelable,
|
||||
in DOMString aData,
|
||||
in DOMString aDomain,
|
||||
in DOMString aURI,
|
||||
in nsIDOMWindow aSource);
|
||||
};
|
@ -420,6 +420,10 @@ enum nsDOMClassInfoID {
|
||||
// Data Events
|
||||
eDOMClassInfo_DataContainerEvent_id,
|
||||
|
||||
// event used for cross-domain message-passing and for server-sent events in
|
||||
// HTML5
|
||||
eDOMClassInfo_MessageEvent_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
@ -236,6 +236,7 @@
|
||||
#include "nsIDOMSmartCardEvent.h"
|
||||
#include "nsIDOMXULCommandEvent.h"
|
||||
#include "nsIDOMPageTransitionEvent.h"
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsIDOMNSDocumentStyle.h"
|
||||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentTraversal.h"
|
||||
@ -1227,6 +1228,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
@ -3366,6 +3370,11 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataContainerEvent)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MessageEvent, nsIDOMMessageEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMessageEvent)
|
||||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
|
@ -29,6 +29,7 @@
|
||||
* Johnny Stenback <jst@netscape.com>
|
||||
* Mark Hammond <mhammond@skippinet.com.au>
|
||||
* Ryan Jones <sciguyryan@gmail.com>
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -106,6 +107,7 @@
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsIDOMPopupBlockedEvent.h"
|
||||
#include "nsIDOMPkcs11.h"
|
||||
#include "nsIDOMOfflineResourceList.h"
|
||||
@ -4970,6 +4972,147 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsGlobalWindow*
|
||||
CallerInnerWindow()
|
||||
{
|
||||
nsAXPCNativeCallContext *ncc;
|
||||
nsresult rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
|
||||
if (NS_FAILED(rv) || !ncc) {
|
||||
NS_ASSERTION(ncc, "Please don't call this method from C++!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSContext *cx = nsnull;
|
||||
if (NS_FAILED(ncc->GetJSContext(&cx))) {
|
||||
NS_WARNING("couldn't get JS context from native context");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSObject *scope = ::JS_GetScopeChain(cx);
|
||||
if (!scope)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
nsContentUtils::XPConnect()->
|
||||
GetWrappedNativeOfJSObject(cx, ::JS_GetGlobalForObject(cx, scope),
|
||||
getter_AddRefs(wrapper));
|
||||
if (!wrapper)
|
||||
return nsnull;
|
||||
|
||||
// The calling window must be holding a reference, so we can just return a
|
||||
// raw pointer here and let the QI's addref be balanced by the nsCOMPtr
|
||||
// destructor's release.
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryWrappedNative(wrapper);
|
||||
return static_cast<nsGlobalWindow*>(win.get());
|
||||
}
|
||||
|
||||
/* I hate you, Windows. */
|
||||
#ifdef PostMessage
|
||||
#undef PostMessage
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::PostMessage(const nsAString& aMessage)
|
||||
{
|
||||
FORWARD_TO_INNER_CREATE(PostMessage, (aMessage));
|
||||
|
||||
//
|
||||
// Window.postMessage is an intentional subversion of the same-origin policy.
|
||||
// As such, this code must be particularly careful in the information it
|
||||
// exposes to calling code.
|
||||
//
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/section-crossDocumentMessages.html
|
||||
//
|
||||
|
||||
|
||||
// First, get the caller's window
|
||||
nsRefPtr<nsGlobalWindow> callerInnerWin = CallerInnerWindow();
|
||||
if (!callerInnerWin)
|
||||
return NS_OK;
|
||||
NS_ASSERTION(callerInnerWin->IsInnerWindow(), "should have gotten an inner window here");
|
||||
|
||||
// Obtain the caller's principal, from which we can usually extract a URI
|
||||
// and domain for the event.
|
||||
nsIPrincipal* callerPrin = callerInnerWin->GetPrincipal();
|
||||
if (!callerPrin)
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIURI> docURI;
|
||||
if (NS_FAILED(callerPrin->GetURI(getter_AddRefs(docURI))))
|
||||
return NS_OK;
|
||||
|
||||
// If we hit this, we're probably in chrome context and have the URI-less
|
||||
// system principal, so get the URI off the caller's document.
|
||||
if (!docURI) {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(callerInnerWin->mDocument);
|
||||
if (!doc)
|
||||
return NS_OK;
|
||||
|
||||
docURI = doc->GetDocumentURI();
|
||||
if (!docURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString domain, uri;
|
||||
nsresult rv = docURI->GetSpec(uri);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_OK;
|
||||
|
||||
// This really shouldn't be necessary -- URLs which don't have a host should
|
||||
// return the empty string -- but nsSimpleURI just errors instead of
|
||||
// truncating domain. We could just ignore the returned error, but in the
|
||||
// interests of playing it safe in a sensitive API, we check and truncate if
|
||||
// GetHost fails. Empty hosts are valid for some URI schemes, and any code
|
||||
// which expects a non-empty host should ignore the message we'll dispatch.
|
||||
if (NS_FAILED(docURI->GetHost(domain)))
|
||||
domain.Truncate();
|
||||
|
||||
// Create the event
|
||||
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
|
||||
if (!docEvent)
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
docEvent->CreateEvent(NS_LITERAL_STRING("MessageEvent"),
|
||||
getter_AddRefs(event));
|
||||
if (!event)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMMessageEvent> message = do_QueryInterface(event);
|
||||
rv = message->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
PR_TRUE /* bubbling */,
|
||||
PR_TRUE /* cancelable */,
|
||||
aMessage,
|
||||
NS_ConvertUTF8toUTF16(domain),
|
||||
NS_ConvertUTF8toUTF16(uri),
|
||||
nsContentUtils::IsCallerChrome()
|
||||
? nsnull
|
||||
: callerInnerWin->GetOuterWindowInternal());
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
||||
// Finally, dispatch the event, ignoring the result to prevent an exception
|
||||
// from revealing anything about the document for this window.
|
||||
PRBool dummy;
|
||||
nsCOMPtr<nsIDOMEventTarget> targetDoc = do_QueryInterface(mDocument);
|
||||
targetDoc->DispatchEvent(message, &dummy);
|
||||
|
||||
// Cancel exceptions that might somehow be pending. XPConnect swallows these
|
||||
// exceptions across JS contexts, but there can be concerns if the caller
|
||||
// and the thrower are same-context but different-origin -- see bug 387706
|
||||
// comment 26, waring the typo in it. Consequently, we play it safe and always
|
||||
// cancel exceptions.
|
||||
nsAXPCNativeCallContext *ncc;
|
||||
rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
|
||||
if (NS_FAILED(rv) || !ncc)
|
||||
return NS_OK;
|
||||
|
||||
JSContext *cx = nsnull;
|
||||
if (NS_SUCCEEDED(ncc->GetJSContext(&cx)))
|
||||
::JS_ClearPendingException(cx);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class nsCloseEvent : public nsRunnable {
|
||||
public:
|
||||
nsCloseEvent (nsGlobalWindow *aWindow)
|
||||
@ -7192,33 +7335,7 @@ nsGlobalWindow::SetTimeoutOrInterval(PRBool aIsInterval, PRInt32 *aReturn)
|
||||
// inner window that's calling window.setTimeout().
|
||||
|
||||
if (IsOuterWindow()) {
|
||||
nsAXPCNativeCallContext *ncc = nsnull;
|
||||
nsresult rv = nsContentUtils::XPConnect()->
|
||||
GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!ncc) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
JSContext *cx = nsnull;
|
||||
|
||||
rv = ncc->GetJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSObject *scope = ::JS_GetScopeChain(cx);
|
||||
|
||||
if (!scope) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
nsContentUtils::XPConnect()->
|
||||
GetWrappedNativeOfJSObject(cx, ::JS_GetGlobalForObject(cx, scope),
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_TRUE(wrapper, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsGlobalWindow *callerInner = FromWrapper(wrapper);
|
||||
nsGlobalWindow* callerInner = CallerInnerWindow();
|
||||
NS_ENSURE_TRUE(callerInner, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If the caller and the callee share the same outer window,
|
||||
|
@ -98,6 +98,11 @@
|
||||
#include "nsPIDOMEventTarget.h"
|
||||
#include "nsIArray.h"
|
||||
|
||||
/* I hate you, Windows. */
|
||||
#ifdef PostMessage
|
||||
#undef PostMessage
|
||||
#endif
|
||||
|
||||
#define DEFAULT_HOME_PAGE "www.mozilla.org"
|
||||
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
|
||||
|
||||
@ -211,7 +216,7 @@ private:
|
||||
// jst@netscape.com
|
||||
|
||||
// nsGlobalWindow inherits PRCList for maintaining a list of all inner
|
||||
// widows still in memory for any given outer window. This list is
|
||||
// windows still in memory for any given outer window. This list is
|
||||
// needed to ensure that mOuterWindow doesn't end up dangling. The
|
||||
// nature of PRCList means that the window itself is always in the
|
||||
// list, and an outer window's list will also contain all inner window
|
||||
|
@ -49,6 +49,7 @@ DIRS += \
|
||||
ajax \
|
||||
bugs \
|
||||
chrome \
|
||||
whatwg \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
77
dom/tests/mochitest/whatwg/Makefile.in
Normal file
77
dom/tests/mochitest/whatwg/Makefile.in
Normal file
@ -0,0 +1,77 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Jeff Walden <jwalden+code@mit.edu>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/whatwg
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
browserFu.js \
|
||||
test_MessageEvent.html \
|
||||
test_postMessage.html \
|
||||
postMessage_helper.html \
|
||||
test_postMessage_joined.html \
|
||||
postMessage_joined_helper.html \
|
||||
postMessage_joined_helper2.html \
|
||||
test_postMessage_onOther.html \
|
||||
postMessage_onOther.html \
|
||||
test_MessageEvent_dispatchToOther.html \
|
||||
test_postMessage_override.html \
|
||||
postMessage_override_helper.html \
|
||||
test_postMessage_throw.html \
|
||||
postMessage_throw_helper.html \
|
||||
postMessage_chrome_helper.html \
|
||||
test_postMessage_special.xhtml \
|
||||
test_postMessage_idn.xhtml \
|
||||
postMessage_idn_helper.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
test_postMessage_chrome.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
||||
|
||||
libs:: $(_CHROME_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
6
dom/tests/mochitest/whatwg/browserFu.js
Normal file
6
dom/tests/mochitest/whatwg/browserFu.js
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* File which includes stuff for Mozilla-specific checks which shouldn't happen
|
||||
* in other browsers but which we wish to test.
|
||||
*/
|
||||
|
||||
var isMozilla = navigator.product === "Gecko" && "buildID" in navigator;
|
45
dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
Normal file
45
dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>postMessage chrome message receiver</title>
|
||||
<script type="application/javascript">
|
||||
var sourcePath = "chrome://mochikit/content/chrome/" +
|
||||
"dom/tests/mochitest/whatwg/test_postMessage_chrome.html";
|
||||
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
// Content cannot post to chrome without privileges
|
||||
window.parent.postMessage("SHOULD NOT GET THIS!");
|
||||
|
||||
var msg = "post-to-content-response";
|
||||
|
||||
if (evt.source !== null)
|
||||
msg += " wrong-source(" + evt.source + ")";
|
||||
if (!evt.isTrusted)
|
||||
msg += " unexpected-untrusted-event";
|
||||
if (evt.type !== "message")
|
||||
msg += " wrong-type(" + evt.type + ")";
|
||||
if (evt.uri !== sourcePath)
|
||||
msg += " wrong-uri(" + evt.uri + ")";
|
||||
if (evt.domain !== "mochikit")
|
||||
msg += " wrong-domain(" + evt.domain + ")";
|
||||
if (evt.data !== "post-to-content")
|
||||
msg += " wrong-message(" + evt.data + ")";
|
||||
|
||||
respond(msg);
|
||||
}
|
||||
|
||||
function respond(msg)
|
||||
{
|
||||
// ...so get privileges and test that this works with privileges
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
window.parent.postMessage(msg);
|
||||
}
|
||||
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="domain">example.org</h1>
|
||||
</body>
|
||||
</html>
|
109
dom/tests/mochitest/whatwg/postMessage_helper.html
Normal file
109
dom/tests/mochitest/whatwg/postMessage_helper.html
Normal file
@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>postMessage message receiver</title>
|
||||
<script type="application/javascript" src="browserFu.js"></script>
|
||||
<script type="application/javascript">
|
||||
function $(id) { return document.getElementById(id); }
|
||||
|
||||
function setup()
|
||||
{
|
||||
$("domain").textContent = location.hostname + ":" + (location.port || 80);
|
||||
}
|
||||
|
||||
var otherPath = "/tests/dom/tests/mochitest/whatwg/test_postMessage.html";
|
||||
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
var response = evt.data + "-response";
|
||||
|
||||
if (evt.source !== window.parent)
|
||||
{
|
||||
response += " unexpected-source(" + evt.source + ")";
|
||||
response += " window-parent-is(" + window.parent + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
if (isMozilla && evt.isTrusted)
|
||||
response += " unexpected-trusted";
|
||||
|
||||
if (evt.type != "message")
|
||||
response += " wrong-type(" + evt.type + ")";
|
||||
|
||||
var data = evt.data;
|
||||
if (data == "post-to-other-same-domain")
|
||||
{
|
||||
receiveSame(evt, response);
|
||||
}
|
||||
else if (data == "post-to-other-cross-domain")
|
||||
{
|
||||
receiveCross(evt, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
response += " unexpected-message-to(" + window.location.href + ")";
|
||||
window.parent.postMessage(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function receiveSame(evt, response)
|
||||
{
|
||||
var source = evt.source;
|
||||
try
|
||||
{
|
||||
if (evt.domain != "localhost")
|
||||
response += " unexpected-domain(" + evt.domain + ")";
|
||||
if (evt.uri != "http://localhost:8888" + otherPath)
|
||||
response += " unexpected-uri(" + evt.uri + ")";
|
||||
|
||||
try
|
||||
{
|
||||
var threw = false;
|
||||
var privateVariable = source.privateVariable;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
threw = true;
|
||||
}
|
||||
if (threw || privateVariable !== window.parent.privateVariable)
|
||||
response += " accessed-source!!!";
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
source.postMessage(response);
|
||||
}
|
||||
}
|
||||
|
||||
function receiveCross(evt, response)
|
||||
{
|
||||
var source = evt.source;
|
||||
if (evt.domain != "localhost")
|
||||
response += " unexpected-domain(" + evt.domain + ")";
|
||||
if (evt.uri != "http://localhost:8888" + otherPath)
|
||||
response += " unexpected-uri(" + evt.uri + ")";
|
||||
|
||||
try
|
||||
{
|
||||
var threw = false;
|
||||
var privateVariable = source.privateVariable;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
threw = true;
|
||||
}
|
||||
if (!threw || privateVariable !== undefined)
|
||||
response += " accessed-source!!!";
|
||||
|
||||
source.postMessage(response);
|
||||
}
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="domain"></h1>
|
||||
</body>
|
||||
</html>
|
41
dom/tests/mochitest/whatwg/postMessage_idn_helper.html
Normal file
41
dom/tests/mochitest/whatwg/postMessage_idn_helper.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>postMessage IDN test page</title>
|
||||
<script type="application/javascript">
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
var response = "idn-response";
|
||||
|
||||
if (!(evt instanceof MessageEvent))
|
||||
response += " not-a-MessageEvent";
|
||||
if (evt.uri !== "http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_idn.xhtml")
|
||||
response += " wrong-sender-uri(" + evt.uri + ")";
|
||||
if (evt.domain !== "localhost")
|
||||
response += " wrong-sender-domain(" + evt.domain + ")";
|
||||
if (evt.data !== "idn-message")
|
||||
response += " wrong-data(" + evt.data + ")";
|
||||
if (evt.source !== window.parent)
|
||||
response += " wrong-source";
|
||||
if (evt.target !== document)
|
||||
response += " wrong-target";
|
||||
if (evt.type !== "message")
|
||||
response += " wrong-type(" + evt.type + ")";
|
||||
|
||||
evt.source.postMessage(response);
|
||||
}
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
|
||||
function setup()
|
||||
{
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = document.domain;
|
||||
}
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="location">No location!</h1>
|
||||
</body>
|
||||
</html>
|
100
dom/tests/mochitest/whatwg/postMessage_joined_helper.html
Normal file
100
dom/tests/mochitest/whatwg/postMessage_joined_helper.html
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
http://sub1.test1.example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper.html
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage joined domains, inner frame</title>
|
||||
<script type="application/javascript" src="browserFu.js"></script>
|
||||
<script type="application/javascript">
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
var response, target;
|
||||
var data = evt.data;
|
||||
if (data === "subframe-test-finished")
|
||||
{
|
||||
target = window.parent;
|
||||
response = "test-passed";
|
||||
}
|
||||
else if (data === "start-test")
|
||||
{
|
||||
target = window.frames.innermost;
|
||||
response = "start-test";
|
||||
}
|
||||
else
|
||||
{
|
||||
target = window.parent;
|
||||
response = "not reached";
|
||||
}
|
||||
|
||||
if (evt.type !== "message")
|
||||
response += " wrong-type(" + evt.type + ")";
|
||||
|
||||
if (evt.target !== document)
|
||||
{
|
||||
response += " wrong-target(" + evt.target + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
if (isMozilla && evt.isTrusted === true)
|
||||
{
|
||||
response += " unexpected-trusted-event";
|
||||
}
|
||||
|
||||
var uri, domain;
|
||||
if (data == "subframe-test-finished")
|
||||
{
|
||||
uri = "http://example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper2.html";
|
||||
domain = "example.org";
|
||||
}
|
||||
else if (data === "start-test")
|
||||
{
|
||||
uri = "http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_joined.html";
|
||||
domain = "localhost";
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = "unreached";
|
||||
domain = "unreached";
|
||||
}
|
||||
|
||||
if (evt.uri !== uri)
|
||||
{
|
||||
response += " wrong-uri(" + evt.uri + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
if (evt.domain !== domain)
|
||||
{
|
||||
response += " wrong-domain(" + evt.domain + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
target.postMessage(response);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
var oldDomain = document.domain;
|
||||
var newDomain = "example.org";
|
||||
|
||||
document.domain = newDomain;
|
||||
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = "Location: " + oldDomain +
|
||||
", effective domain: " + newDomain;
|
||||
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
}
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="location">No location!</p>
|
||||
|
||||
<iframe src="http://example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper2.html"
|
||||
name="innermost"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
83
dom/tests/mochitest/whatwg/postMessage_joined_helper2.html
Normal file
83
dom/tests/mochitest/whatwg/postMessage_joined_helper2.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
http://example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper2.html
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage joined domains, innermost frame</title>
|
||||
<script type="application/javascript" src="browserFu.js"></script>
|
||||
<script type="application/javascript">
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
var response = "subframe-test-finished";
|
||||
|
||||
if (evt.data !== "start-test")
|
||||
response += " incorrect-subframe-data(" + evt.data + ")";
|
||||
if (evt.type !== "message")
|
||||
response += " wrong-type(" + evt.type + ")";
|
||||
if (evt.target !== document)
|
||||
{
|
||||
response += " wrong-target(" + evt.target + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
if (isMozilla && evt.isTrusted)
|
||||
{
|
||||
response += " unexpected-trusted-event";
|
||||
}
|
||||
|
||||
if (evt.source !== window.parent)
|
||||
{
|
||||
response += " unexpected-source(" + evt.source + ")";
|
||||
response += " window-parent-is(" + window.parent + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
// verify that document.domain was actually joined with this domain
|
||||
try
|
||||
{
|
||||
var passed = evt.source.document.domain === document.domain;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
}
|
||||
|
||||
if (!passed)
|
||||
response += " expected-joined-domains";
|
||||
|
||||
if (evt.uri !== "http://sub1.test1.example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper.html")
|
||||
{
|
||||
response += " wrong-uri(" + evt.uri + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
if (evt.domain !== "sub1.test1.example.org")
|
||||
{
|
||||
response += " wrong-domain(" + evt.domain + ")";
|
||||
response += " location(" + window.location.href + ")";
|
||||
}
|
||||
|
||||
window.parent.postMessage(response);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
var oldDomain = document.domain;
|
||||
var newDomain = "example.org"; // join with parent
|
||||
|
||||
document.domain = newDomain;
|
||||
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = "Location: " + oldDomain +
|
||||
", effective domain: " + newDomain;
|
||||
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
}
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="location">No location!</p>
|
||||
</body>
|
||||
</html>
|
54
dom/tests/mochitest/whatwg/postMessage_onOther.html
Normal file
54
dom/tests/mochitest/whatwg/postMessage_onOther.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>postMessage called through another frame</title>
|
||||
<script type="application/javascript">
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
var response = "response-to-sibling-sent-message";
|
||||
|
||||
// Our parent frame called testSiblingPostMessage (below) on a frame
|
||||
// containing this page on localhost:8888. testSiblingPostMessage then
|
||||
// called postMessage on this page on example.org:8000. We thus expect
|
||||
// to see an event whose source is the window of our sibling frame on
|
||||
// localhost:8888. In other words, the event we receive should have:
|
||||
//
|
||||
// http://localhost:8888/tests/dom/tests/mochitest/whatwg/postMessage_onOther.html
|
||||
//
|
||||
// and not
|
||||
//
|
||||
// http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_onOther.html
|
||||
//
|
||||
// as its source.
|
||||
|
||||
if (evt.data !== "message-from-sibling")
|
||||
response += " wrong-data(" + evt.data + ")";
|
||||
if (evt.uri !== "http://localhost:8888/tests/dom/tests/mochitest/whatwg/postMessage_onOther.html")
|
||||
response += " failed-wrong-uri(" + evt.uri + ")";
|
||||
if (evt.domain !== "localhost")
|
||||
response += " failed-wrong-domain(" + evt.domain + ")";
|
||||
if (evt.source !== window.parent.firstFrame)
|
||||
response += " failed-wrong-source";
|
||||
|
||||
window.parent.postMessage(response);
|
||||
}
|
||||
|
||||
function testSiblingPostMessage()
|
||||
{
|
||||
window.parent.secondFrame.postMessage("message-from-sibling");
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = document.domain;
|
||||
}
|
||||
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="location">No location!</h1>
|
||||
</body>
|
||||
</html>
|
42
dom/tests/mochitest/whatwg/postMessage_override_helper.html
Normal file
42
dom/tests/mochitest/whatwg/postMessage_override_helper.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Overriding postMessage and dispatchEvent bindings</title>
|
||||
<script type="application/javascript">
|
||||
window.postMessage = function (evt)
|
||||
{
|
||||
window.parent.postMessage("FAIL overridden postMessage called");
|
||||
};
|
||||
|
||||
var count = 0;
|
||||
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
count++;
|
||||
if (count == 1)
|
||||
{
|
||||
window.dispatchEvent = function(evt)
|
||||
{
|
||||
window.parent.postMessage("FAIL");
|
||||
throw "dispatchEvent threw";
|
||||
};
|
||||
}
|
||||
|
||||
window.parent.postMessage(evt.data);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = document.domain;
|
||||
}
|
||||
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="location">No location!</h1>
|
||||
</body>
|
||||
</html>
|
24
dom/tests/mochitest/whatwg/postMessage_throw_helper.html
Normal file
24
dom/tests/mochitest/whatwg/postMessage_throw_helper.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>postMessage throwing page</title>
|
||||
<script type="application/javascript">
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
throw 17;
|
||||
}
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
|
||||
function setup()
|
||||
{
|
||||
var target = document.getElementById("location");
|
||||
target.textContent = document.domain;
|
||||
}
|
||||
|
||||
window.addEventListener("load", setup, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="location">No location!</h1>
|
||||
</body>
|
||||
</html>
|
113
dom/tests/mochitest/whatwg/test_MessageEvent.html
Normal file
113
dom/tests/mochitest/whatwg/test_MessageEvent.html
Normal file
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>MessageEvent tests</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="browserFu.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
<button id="target">target</button>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var data = "foobar";
|
||||
var domain = "cool.example.com";
|
||||
var uri = "http://cool.example.com/bar";
|
||||
var bubbles = true, cancelable = true;
|
||||
|
||||
var target;
|
||||
|
||||
var count = 0;
|
||||
|
||||
function sendMsg()
|
||||
{
|
||||
try
|
||||
{
|
||||
var evt = document.createEvent("MessageEvent");
|
||||
ok(evt instanceof MessageEvent, "I ordered a MessageEvent!");
|
||||
|
||||
if (isMozilla)
|
||||
{
|
||||
is(evt.source, null,
|
||||
"not initialized yet, so null in our implementation");
|
||||
}
|
||||
|
||||
evt.initMessageEvent("message", bubbles, cancelable, data, domain, uri, null);
|
||||
ok(evt.source === null, "null source is fine for a MessageEvent");
|
||||
|
||||
evt.initMessageEvent("message", bubbles, cancelable, data, domain, uri, window);
|
||||
|
||||
is(evt.data, data, "unexpected data");
|
||||
is(evt.domain, domain, "unexpected domain");
|
||||
is(evt.uri, uri, "unexpected uri");
|
||||
|
||||
is(evt.cancelable, cancelable, "wrong cancelable property");
|
||||
is(evt.bubbles, bubbles, "wrong bubbling property");
|
||||
is(evt.source, window, "wrong source");
|
||||
|
||||
return target.dispatchEvent(evt);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "exception thrown: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function recvMsg(evt)
|
||||
{
|
||||
is(evt.data, data, "unexpected data");
|
||||
is(evt.domain, domain, "unexpected domain");
|
||||
is(evt.uri, uri, "unexpected uri");
|
||||
|
||||
is(evt.cancelable, cancelable, "wrong cancelable property");
|
||||
is(evt.bubbles, bubbles, "wrong bubbling property");
|
||||
is(evt.source, window, "wrong source");
|
||||
|
||||
is(evt.target, target, "wrong target");
|
||||
|
||||
if (target == evt.currentTarget)
|
||||
{
|
||||
is(Event.AT_TARGET, evt.eventPhase, "this listener was on the target");
|
||||
}
|
||||
else
|
||||
{
|
||||
is(evt.currentTarget, document, "should have gotten this at the window");
|
||||
is(Event.BUBBLING_PHASE, evt.eventPhase, "wrong phase");
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
target = $("target");
|
||||
target.addEventListener("message", recvMsg, false);
|
||||
document.addEventListener("message", recvMsg, false);
|
||||
var res = sendMsg();
|
||||
ok(res === true, "nothing canceled this");
|
||||
is(count, 2, "listener not called twice");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(setup);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>Dispatching MessageEvent across origins</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://example.com/" name="otherDomain"></iframe>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function run()
|
||||
{
|
||||
try
|
||||
{
|
||||
var msg = document.createEvent("MessageEvent");
|
||||
msg.initMessageEvent("message", true, true,
|
||||
"foo", "evil.com", "http://evil.com/", window);
|
||||
|
||||
try
|
||||
{
|
||||
var ex;
|
||||
window.frames.otherDomain.dispatchEvent(msg);
|
||||
ok(false, "should have thrown a security exception per HTML5");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(true, "correctly threw an exception (security exception, but " +
|
||||
"what that entails isn't yet defined in the spec)");
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "threw exception during execution: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(run);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
203
dom/tests/mochitest/whatwg/test_postMessage.html
Normal file
203
dom/tests/mochitest/whatwg/test_postMessage.html
Normal file
@ -0,0 +1,203 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>Basic postMessage tests</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="browserFu.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://localhost:8888/tests/dom/tests/mochitest/whatwg/postMessage_helper.html"
|
||||
name="otherSameDomain"></iframe>
|
||||
<iframe src="http://example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_helper.html"
|
||||
name="otherCrossDomain"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var otherPath = "/tests/dom/tests/mochitest/whatwg/postMessage_helper.html";
|
||||
var path = "/tests/dom/tests/mochitest/whatwg/test_postMessage.html";
|
||||
|
||||
var testsCompletedCount = 0;
|
||||
|
||||
/** Variable for receivers to attempt to get. */
|
||||
window.privateVariable = 17;
|
||||
|
||||
/** For sentinel finish, if necessary in deficient browsers */
|
||||
var finished = false;
|
||||
|
||||
/** Receives MessageEvents to this window. */
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
ok(evt instanceof MessageEvent, "umm, how did we get this?");
|
||||
is(evt.type, "message", "expected events of type 'message'");
|
||||
|
||||
if (isMozilla)
|
||||
{
|
||||
ok(evt.isTrusted === false, "shouldn't have been a trusted event");
|
||||
}
|
||||
|
||||
var data = evt.data;
|
||||
|
||||
// Check for the message we send to ourselves; it can't be
|
||||
// counted as a test, and it's conceptually distinct from
|
||||
// the other cases, so just return after handling it.
|
||||
if (data === "post-to-self")
|
||||
{
|
||||
respondToSelf(evt);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (evt.data)
|
||||
{
|
||||
case "post-to-self":
|
||||
|
||||
case "post-to-self-response":
|
||||
receiveSelf(evt);
|
||||
break;
|
||||
|
||||
case "post-to-other-same-domain-response":
|
||||
receiveOtherSameDomain(evt);
|
||||
break;
|
||||
|
||||
case "post-to-other-cross-domain-response":
|
||||
receiveOtherCrossDomain(evt);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "unexpected message: " + evt.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "error processing event with data '" + evt.data + "': " + e);
|
||||
}
|
||||
|
||||
// if all the tests have executed, we're done
|
||||
if (++testsCompletedCount == allTests.length)
|
||||
{
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
* SELF-RESPONDER *
|
||||
******************/
|
||||
|
||||
function respondToSelf(evt)
|
||||
{
|
||||
is(evt.domain, "localhost", "what domain are we on again?");
|
||||
is(evt.uri, "http://localhost:8888" + path, "event has wrong URI");
|
||||
is(evt.source, window, "we posted this message!");
|
||||
|
||||
evt.source.postMessage("post-to-self-response");
|
||||
}
|
||||
|
||||
|
||||
/*************
|
||||
* RECEIVERS *
|
||||
*************/
|
||||
|
||||
function receiveSelf(evt)
|
||||
{
|
||||
is(evt.domain, "localhost", "what domain are we on again?");
|
||||
is(evt.uri, "http://localhost:8888" + path, "event has wrong URI");
|
||||
is(evt.source, window, "we posted this message!");
|
||||
}
|
||||
|
||||
function receiveOtherSameDomain(evt)
|
||||
{
|
||||
is(evt.domain, "localhost", "we should be same domain");
|
||||
is(evt.uri, "http://localhost:8888" + otherPath,
|
||||
"same-domain response event has wrong URI");
|
||||
is(evt.source, window.frames.otherSameDomain,
|
||||
"wrong source for same-domain message!");
|
||||
}
|
||||
|
||||
function receiveOtherCrossDomain(evt)
|
||||
{
|
||||
is(evt.domain, "example.org", "we should be same domain");
|
||||
is(evt.uri, "http://example.org:8000" + otherPath,
|
||||
"same-domain response event has wrong URI");
|
||||
|
||||
// can't use |is| here, because ok tries to get properties on its arguments
|
||||
// for creating a formatted logging message
|
||||
ok(evt.source === window.frames.otherCrossDomain,
|
||||
"wrong source for cross-domain message!");
|
||||
}
|
||||
|
||||
|
||||
/**************
|
||||
* TEST SETUP *
|
||||
**************/
|
||||
|
||||
document.addEventListener("message", messageReceiver, false);
|
||||
|
||||
/**
|
||||
* Returns a nullary function which posts the given message to the given
|
||||
* destination.
|
||||
*/
|
||||
function createMessageDispatcher(message, destination)
|
||||
{
|
||||
function dispatcher()
|
||||
{
|
||||
try
|
||||
{
|
||||
destination.postMessage(message);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "error while calling postMessage: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
var allTests =
|
||||
[
|
||||
createMessageDispatcher("post-to-self", window),
|
||||
createMessageDispatcher("post-to-other-same-domain",
|
||||
window.frames.otherSameDomain),
|
||||
createMessageDispatcher("post-to-other-cross-domain",
|
||||
window.frames.otherCrossDomain),
|
||||
];
|
||||
|
||||
for (var i = 0, sz = allTests.length; i != sz; i++)
|
||||
addLoadEvent(allTests[i]);
|
||||
|
||||
/**
|
||||
* Browsers which fail to send a response to a postMessage need this to
|
||||
* finish the test.
|
||||
*/
|
||||
function sentinel()
|
||||
{
|
||||
if (!finished)
|
||||
{
|
||||
ok(false, "shouldn't be necessary (finished in last of allTests)");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(sentinel);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
119
dom/tests/mochitest/whatwg/test_postMessage_chrome.html
Normal file
119
dom/tests/mochitest/whatwg/test_postMessage_chrome.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage chrome tests</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
This test runs at the following URL:
|
||||
chrome://mochikit/content/chrome/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
|
||||
-->
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://example.org/tests/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html"
|
||||
name="contentDomain"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var pathHead = "chrome://mochikit/content/chrome";
|
||||
var path = "/dom/tests/mochitest/whatwg/test_postMessage_chrome.html";
|
||||
var otherPath = "/tests/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html";
|
||||
|
||||
var testsCompletedCount = 0;
|
||||
|
||||
/** Receives MessageEvents to this window. */
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
ok(evt instanceof MessageEvent, "umm, how did we get this?");
|
||||
is(evt.type, "message", "expected events of type 'message'");
|
||||
|
||||
switch (evt.data)
|
||||
{
|
||||
case "post-to-self":
|
||||
checkSelf(evt);
|
||||
break;
|
||||
|
||||
case "post-to-content-response":
|
||||
receiveContent(evt);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "unexpected message: " + evt.data);
|
||||
break;
|
||||
}
|
||||
|
||||
// if all the tests have executed, we're done
|
||||
if (++testsCompletedCount == allTests.length)
|
||||
setTimeout(SimpleTest.finish, 0);
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
* SELF-RESPONDER *
|
||||
******************/
|
||||
|
||||
function checkSelf(evt)
|
||||
{
|
||||
is(evt.isTrusted, true, "should have sent a trusted event");
|
||||
is(evt.domain, "mochikit", "chrome: protocol's domain is the package");
|
||||
is(evt.uri, pathHead + path, "event has wrong URI");
|
||||
is(evt.source, null, "chrome posters get a null source, for security");
|
||||
}
|
||||
|
||||
|
||||
/*************
|
||||
* RECEIVERS *
|
||||
*************/
|
||||
|
||||
function receiveContent(evt)
|
||||
{
|
||||
is(evt.isTrusted, true, "should have sent a trusted event");
|
||||
is(evt.domain, "example.org", "wrong domain for content page");
|
||||
is(evt.uri, "http://example.org" + otherPath,
|
||||
"content response event has wrong URI");
|
||||
is(evt.source, window.frames.contentDomain,
|
||||
"wrong source for same-domain message!");
|
||||
}
|
||||
|
||||
|
||||
/**************
|
||||
* TEST SETUP *
|
||||
**************/
|
||||
|
||||
document.addEventListener("message", messageReceiver, false);
|
||||
|
||||
/**
|
||||
* Returns a nullary function which posts the given message to the given
|
||||
* destination.
|
||||
*/
|
||||
function createMessageDispatcher(message, destination)
|
||||
{
|
||||
return function() { destination.postMessage(message); };
|
||||
}
|
||||
|
||||
var allTests =
|
||||
[
|
||||
createMessageDispatcher("post-to-self", window),
|
||||
createMessageDispatcher("post-to-content",
|
||||
window.frames.contentDomain),
|
||||
];
|
||||
|
||||
allTests.forEach(addLoadEvent);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
76
dom/tests/mochitest/whatwg/test_postMessage_idn.xhtml
Normal file
76
dom/tests/mochitest/whatwg/test_postMessage_idn.xhtml
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage uri/domain values and IDN encoding</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="browserFu.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://sub1.ält.example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_idn_helper.html"></iframe>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var responseReceived = false;
|
||||
var idnWindow = null;
|
||||
|
||||
function receiveMessage(evt)
|
||||
{
|
||||
ok(evt instanceof MessageEvent, "umm, how did we get this?");
|
||||
is(evt.type, "message", "expected events of type 'message'");
|
||||
|
||||
if (isMozilla)
|
||||
{
|
||||
ok(evt.isTrusted === false, "shouldn't have been a trusted event");
|
||||
}
|
||||
|
||||
is(evt.uri, "http://sub1.ält.example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_idn_helper.html",
|
||||
"wrong URI -- IDN issue, perhaps?");
|
||||
is(evt.domain, "sub1.ält.example.org",
|
||||
"wrong domain -- IDN issue, perhaps?");
|
||||
|
||||
is(evt.data, "idn-response", "unexpected test result");
|
||||
ok(evt.source === idnWindow, "wrong source");
|
||||
|
||||
responseReceived = true;
|
||||
}
|
||||
document.addEventListener("message", receiveMessage, false);
|
||||
|
||||
var xhtmlns = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
function setup()
|
||||
{
|
||||
try
|
||||
{
|
||||
var idnFrame = document.getElementsByTagNameNS(xhtmlns, "iframe")[0];
|
||||
idnWindow = idnFrame.contentWindow;
|
||||
idnWindow.postMessage("idn-message");
|
||||
|
||||
ok(responseReceived, "should have gotten a response before returning");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "failed to post message: " + e);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(setup);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
66
dom/tests/mochitest/whatwg/test_postMessage_joined.html
Normal file
66
dom/tests/mochitest/whatwg/test_postMessage_joined.html
Normal file
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage with document.domain setting to join origins</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="browserFu.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://sub1.test1.example.org/tests/dom/tests/mochitest/whatwg/postMessage_joined_helper.html"
|
||||
name="container"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function receiveTestResult(evt)
|
||||
{
|
||||
ok(evt instanceof MessageEvent, "umm, how did we get this?");
|
||||
is(evt.type, "message", "expected events of type 'message'");
|
||||
|
||||
if (isMozilla)
|
||||
{
|
||||
ok(evt.isTrusted === false, "shouldn't have been a trusted event");
|
||||
}
|
||||
|
||||
var data = evt.data;
|
||||
|
||||
// Either we passed the test or we failed it. The message's
|
||||
// contents should help to diagnose the failure. Either way,
|
||||
// consider this the end of the test.
|
||||
is(data, "test-passed", "unexpected test result");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
document.addEventListener("message", receiveTestResult, false);
|
||||
try
|
||||
{
|
||||
window.frames.container.postMessage("start-test");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "failed to post message");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(setup);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
78
dom/tests/mochitest/whatwg/test_postMessage_onOther.html
Normal file
78
dom/tests/mochitest/whatwg/test_postMessage_onOther.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage called through a different same-origin page</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://localhost:8888/tests/dom/tests/mochitest/whatwg/postMessage_onOther.html"
|
||||
name="firstFrame"></iframe>
|
||||
<iframe src="http://example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_onOther.html"
|
||||
name="secondFrame"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var finished = false;
|
||||
|
||||
/** Receives MessageEvents to this window. */
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
var fromURI = "http://example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_onOther.html";
|
||||
ok(evt instanceof MessageEvent, "wrong event type");
|
||||
is(evt.uri, fromURI, "unexpected URI");
|
||||
is(evt.domain, "example.org", "unexpected domain");
|
||||
is(evt.data, "response-to-sibling-sent-message",
|
||||
"unexpected data in message");
|
||||
|
||||
// Handle buggy browsers that might somehow have received a message twice
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function postToSecondFrameThroughFirstFrame()
|
||||
{
|
||||
try
|
||||
{
|
||||
window.frames.firstFrame.testSiblingPostMessage();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "threw exception trying to post through firstFrame: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/** For buggy browsers that didn't send a response. */
|
||||
function sentinel()
|
||||
{
|
||||
if (!finished)
|
||||
{
|
||||
ok(false, "should have been finished by now -- didn't receive response?");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("message", messageReceiver, false);
|
||||
|
||||
addLoadEvent(postToSecondFrameThroughFirstFrame);
|
||||
addLoadEvent(sentinel);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
83
dom/tests/mochitest/whatwg/test_postMessage_override.html
Normal file
83
dom/tests/mochitest/whatwg/test_postMessage_override.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage override test</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_override_helper.html"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var count = 0;
|
||||
|
||||
function test()
|
||||
{
|
||||
try
|
||||
{
|
||||
count++;
|
||||
switch (count)
|
||||
{
|
||||
case 1:
|
||||
window.frames[0].postMessage("PASS 1");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
window.frames[0].postMessage("PASS 2");
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "unexpected");
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "error running test " + count + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
var expect;
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 1:
|
||||
expect = "PASS 1";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
expect = "PASS 2";
|
||||
break;
|
||||
|
||||
default:
|
||||
expect = "unexpected";
|
||||
break;
|
||||
}
|
||||
|
||||
is(evt.data, expect, "uh-oh, we didn't get the right postMessage!");
|
||||
}
|
||||
|
||||
document.addEventListener("message", messageReceiver, false);
|
||||
|
||||
addLoadEvent(test);
|
||||
addLoadEvent(test);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
397
dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
Normal file
397
dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
Normal file
@ -0,0 +1,397 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage from about:blank, data URLs</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="browserFu.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript"><![CDATA[
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/**
|
||||
* Encodes an array of bytes into a string using the base 64 encoding scheme.
|
||||
*
|
||||
* @param bytes
|
||||
* An array of bytes to encode.
|
||||
*/
|
||||
function b64(str) {
|
||||
var byteArray = new Array(str.length);
|
||||
for (var i = 0, sz = str.length; i < sz; i++)
|
||||
byteArray[i] = str.charCodeAt(i);
|
||||
|
||||
var index = 0;
|
||||
function get3Bytes()
|
||||
{
|
||||
if (byteArray.length - index < 3)
|
||||
return null; // Less than three bytes remaining
|
||||
|
||||
// Return the next three bytes in the array, and increment index for our
|
||||
// next invocation
|
||||
return byteArray.slice(index, index += 3);
|
||||
}
|
||||
|
||||
var out = "";
|
||||
var bytes = null;
|
||||
while ((bytes = get3Bytes()))
|
||||
{
|
||||
var bits = 0;
|
||||
for (var i = 0; i < 3; i++)
|
||||
bits = (bits << 8) | bytes[i];
|
||||
for (var j = 18; j >= 0; j -= 6)
|
||||
out += B64_CHARS[(bits>>j) & 0x3F];
|
||||
}
|
||||
|
||||
// Get the remaining bytes
|
||||
bytes = byteArray.slice(index);
|
||||
|
||||
switch (bytes.length)
|
||||
{
|
||||
case 2:
|
||||
out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
|
||||
B64_CHARS[((bytes[0] & 0x03) << 4) | ((bytes[1] >> 4) & 0x0F)] +
|
||||
B64_CHARS[((bytes[1] & 0x0F) << 2)] +
|
||||
"=";
|
||||
break;
|
||||
case 1:
|
||||
out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
|
||||
B64_CHARS[(bytes[0] & 0x03) << 4] +
|
||||
"==";
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
var aboutBlankWindow = null;
|
||||
var aboutBlank2Window = null;
|
||||
var dataWindow = null;
|
||||
|
||||
var aboutBlankResponseReceived = false;
|
||||
var aboutBlank2ResponseReceived = false;
|
||||
var dataResponseReceived = false;
|
||||
|
||||
var finished = false;
|
||||
|
||||
/** Convert a nullable string to a pretty representation */
|
||||
function sourceify(v)
|
||||
{
|
||||
if (typeof v == "string")
|
||||
return "'" + v + "'";
|
||||
return String(v);
|
||||
}
|
||||
|
||||
/** Receives MessageEvents to this window. */
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
// It's not clear what the security model is for data: URLs and whether they
|
||||
// can access their parents; WebKit denies access, while Gecko currently
|
||||
// allows it. We work around this problem by using postMessage (surprise!)
|
||||
// to start the round of tests when each iframe loads.
|
||||
if (evt.data === "next-test")
|
||||
{
|
||||
setTimeout(nextTest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
ok(evt instanceof MessageEvent, "umm, how did we get this?");
|
||||
is(evt.type, "message", "expected events of type 'message'");
|
||||
|
||||
if (isMozilla)
|
||||
{
|
||||
ok(evt.isTrusted === false, "shouldn't have been a trusted event");
|
||||
}
|
||||
|
||||
if (evt.data === "about:blank-response")
|
||||
{
|
||||
// This isn't clarified in HTML5 yet, but the origin for a document which
|
||||
// has been open()ed is the origin of the calling code, somewhat loosely
|
||||
// speaking. For the specific case of about:blank it's also possible
|
||||
// that the origin is determined by the code that opens the window. It's
|
||||
// not codified yet which of these two causes the identifier tokens on
|
||||
// the event generated by the new window to be those of this window, but
|
||||
// in either case this is what they should be.
|
||||
is(evt.uri, "http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml",
|
||||
"wrong uri for event from about:blank");
|
||||
ok(evt.domain === "localhost",
|
||||
"wrong domain for event from about:blank; " +
|
||||
"got " + sourceify(evt.domain) + ", " +
|
||||
"expected 'localhost'");
|
||||
is(evt.source, aboutBlankWindow, "wrong source");
|
||||
aboutBlankResponseReceived = true;
|
||||
}
|
||||
else if (evt.data === "about:blank2-response")
|
||||
{
|
||||
is(evt.uri, "http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml",
|
||||
"wrong uri for event from about:blank #2");
|
||||
ok(evt.domain === "localhost",
|
||||
"wrong domain for event from about:blank; " +
|
||||
"got " + sourceify(evt.domain) + ", expected 'localhost'");
|
||||
is(evt.source, aboutBlank2Window, "wrong source");
|
||||
aboutBlank2ResponseReceived = true;
|
||||
}
|
||||
else if (evt.data === "data-response")
|
||||
{
|
||||
// Again, HTML5 hasn't yet defined this, but we're going to do the same
|
||||
// thing as with about:blank -- for a data: URL opened from page A, the
|
||||
// uri and domain properties correspond to those of page A. This happens
|
||||
// to fall out naturally from using the window's security principal to
|
||||
// determine these two properties.
|
||||
//
|
||||
// Mozilla currently gives data: URLs the principal of the opener/parent
|
||||
// window, and at least for now we'll test for that behavior. If we ever
|
||||
// change how data: URLs are given principals, we can update this test
|
||||
// then.
|
||||
if (isMozilla)
|
||||
{
|
||||
is(evt.uri, "http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml",
|
||||
"wrong uri for event from data URL (but note that this URI is " +
|
||||
"the result of Mozilla's current policy that data: URLs inherit " +
|
||||
"the principal of their opener/parent, a policy not currently " +
|
||||
"specified by any standards)");
|
||||
ok(evt.domain === "localhost",
|
||||
"wrong domain for event from data URL; " +
|
||||
"got " + sourceify(evt.domain) + ", expected ''");
|
||||
}
|
||||
|
||||
is(evt.source, dataWindow, "wrong source");
|
||||
dataResponseReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(false, "unexpected message: " + evt.data);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "error processing event with data '" + evt.data + "': " + e);
|
||||
}
|
||||
}
|
||||
|
||||
function getContents(description, responseText)
|
||||
{
|
||||
var contents =
|
||||
"<!DOCTYPE html>\n" +
|
||||
"<html>\n" +
|
||||
"<head>\n" +
|
||||
" <title>about:blank</title>\n" +
|
||||
" <script type='application/javascript'>\n" +
|
||||
"function receive(evt)\n" +
|
||||
"{\n" +
|
||||
" var response = '" + responseText + "';\n" +
|
||||
"\n" +
|
||||
" if (evt.source !== window.parent)\n" +
|
||||
" response += ' wrong-source';\n" +
|
||||
" if (evt.uri !== 'http://localhost:8888/tests/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml')\n" +
|
||||
" response += ' wrong-uri(' + evt.uri + ')';\n" +
|
||||
" if (evt.domain !== 'localhost')\n" +
|
||||
" response += ' wrong-domain(' + evt.domain + ')';\n" +
|
||||
" if (evt.data !== 'from-opener')\n" +
|
||||
" response += ' wrong-data(' + evt.data + ')';\n" +
|
||||
"\n" +
|
||||
" window.parent.postMessage(response);\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"function ready()\n" +
|
||||
"{\n" +
|
||||
" window.parent.postMessage('next-test');\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"window.addEventListener('load', ready, false);\n" +
|
||||
"document.addEventListener('message', receive, false);\n" +
|
||||
" </script>\n" +
|
||||
"</head>\n" +
|
||||
"<body><p>" + description + "</p></body>\n" +
|
||||
"</html>";
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
var xhtmlns = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
function insert(el)
|
||||
{
|
||||
var content = $("content");
|
||||
content.parentNode.insertBefore(el, content);
|
||||
}
|
||||
|
||||
var LOAD_TIMEOUT = 5000;
|
||||
|
||||
function setupBlank()
|
||||
{
|
||||
var aboutBlankFrame = document.createElementNS(xhtmlns, "iframe");
|
||||
aboutBlankFrame.setAttribute("src", "about:blank");
|
||||
insert(aboutBlankFrame);
|
||||
|
||||
aboutBlankWindow = aboutBlankFrame.contentWindow;
|
||||
var doc = aboutBlankWindow.document;
|
||||
doc.open();
|
||||
doc.write(getContents("This was about:blank #1", "about:blank-response"));
|
||||
doc.close();
|
||||
|
||||
// I don't believe anything guarantees sync parsing, so we have to wait for
|
||||
// the new window to poke us to actually do the test. :-\
|
||||
|
||||
// Catch recalcitrant browsers that fail inside the iframe document code.
|
||||
setTimeout(blankFailed, LOAD_TIMEOUT);
|
||||
}
|
||||
|
||||
function blankFailed()
|
||||
{
|
||||
if (!aboutBlankResponseReceived && !finished)
|
||||
{
|
||||
ok(false,
|
||||
"test timed out (postMessage not accessible on window.parent in " +
|
||||
"the first about:blank iframe?)");
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function setupBlank2()
|
||||
{
|
||||
var aboutBlank2Frame = document.createElementNS(xhtmlns, "iframe");
|
||||
aboutBlank2Frame.addEventListener("load", nextTest, false);
|
||||
aboutBlank2Frame.setAttribute("src", "about:blank");
|
||||
|
||||
insert(aboutBlank2Frame);
|
||||
}
|
||||
|
||||
// Could use window.btoa here, but that's not standardized, and we want to be
|
||||
// able to run these tests against browsers that don't support it.
|
||||
var dataURI = "data:text/html;base64," +
|
||||
b64(getContents("A data: URL", "data-response"));
|
||||
|
||||
function setupData()
|
||||
{
|
||||
var dataFrame = document.createElementNS(xhtmlns, "iframe");
|
||||
dataFrame.setAttribute("src", dataURI);
|
||||
insert(dataFrame);
|
||||
|
||||
dataWindow = dataFrame.contentWindow;
|
||||
|
||||
// ...and wait again for the window to load...
|
||||
|
||||
// Catch recalcitrant browsers that fail inside the iframe document code.
|
||||
setTimeout(dataFailed, LOAD_TIMEOUT);
|
||||
}
|
||||
|
||||
function dataFailed()
|
||||
{
|
||||
if (!dataResponseReceived && !finished)
|
||||
{
|
||||
ok(false,
|
||||
"test timed out (postMessage not accessible on window.parent in " +
|
||||
"the data: iframe?)");
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
function nextTest()
|
||||
{
|
||||
switch (count++)
|
||||
{
|
||||
case 0:
|
||||
testBlank();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
testBlank2();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
testData();
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "unreached");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function testBlank()
|
||||
{
|
||||
try
|
||||
{
|
||||
aboutBlankWindow.postMessage("from-opener");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "exception thrown trying to post message #1 to about:blank");
|
||||
}
|
||||
|
||||
ok(aboutBlankResponseReceived, "about:blank never got a response!");
|
||||
|
||||
setTimeout(setupBlank2, 0);
|
||||
}
|
||||
|
||||
function testBlank2()
|
||||
{
|
||||
// For some reason we can't access this across browsers prior to the iframe
|
||||
// loading, so set its value here.
|
||||
aboutBlank2Window = window.frames[1];
|
||||
|
||||
var doc = aboutBlank2Window.document;
|
||||
|
||||
doc.body.textContent = "This was about:blank #2";
|
||||
|
||||
var script = doc.createElement("script");
|
||||
script.textContent = "window.parent.postMessage('about:blank2-response');";
|
||||
doc.body.appendChild(script);
|
||||
|
||||
// Note that this script gets run synchronously, so we're done with the
|
||||
// test here.
|
||||
ok(aboutBlank2ResponseReceived, "postMessage from about:blank #2 failed");
|
||||
|
||||
setTimeout(setupData, 0);
|
||||
}
|
||||
|
||||
function testData()
|
||||
{
|
||||
try
|
||||
{
|
||||
dataWindow.postMessage("from-opener");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "exception thrown trying to post message to data: URL window");
|
||||
}
|
||||
|
||||
ok(dataResponseReceived, "we never got a response!");
|
||||
|
||||
// Don't re-report -- we must have already failed, and this can
|
||||
// screw up the displayed results.
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
finished = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
document.addEventListener("message", messageReceiver, false);
|
||||
|
||||
addLoadEvent(setupBlank);
|
||||
]]></script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
75
dom/tests/mochitest/whatwg/test_postMessage_throw.html
Normal file
75
dom/tests/mochitest/whatwg/test_postMessage_throw.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
|
||||
-->
|
||||
<head>
|
||||
<title>postMessage with a thrown exception</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
||||
<iframe src="http://localhost:8888/tests/dom/tests/mochitest/whatwg/postMessage_throw_helper.html"
|
||||
name="sameDomain"></iframe>
|
||||
<iframe src="http://example.org:8000/tests/dom/tests/mochitest/whatwg/postMessage_throw_helper.html"
|
||||
name="crossDomain"></iframe>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
/** Test for Bug 387706 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function atLoad()
|
||||
{
|
||||
try
|
||||
{
|
||||
sameDomain.postMessage("foo");
|
||||
ok(true, "should not have thrown for same-domain exception");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "uh-oh, threw a same-domain exception: " + e);
|
||||
}
|
||||
|
||||
setTimeout(next, 0);
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
ok(true, "no pending-exception wackiness for same-domain");
|
||||
setTimeout(next2, 0);
|
||||
}
|
||||
|
||||
function next2()
|
||||
{
|
||||
try
|
||||
{
|
||||
crossDomain.postMessage("foo");
|
||||
ok(true, "should not have thrown for cross-domain exception");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
ok(false, "uh-oh, threw a cross-domain exception: " + e);
|
||||
}
|
||||
|
||||
setTimeout(next3, 0);
|
||||
}
|
||||
|
||||
function next3()
|
||||
{
|
||||
ok(true, "no pending-exception wackiness for cross-domain");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(atLoad);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -309,6 +309,7 @@ pref("capability.policy.default.Window.length.get", "allAccess");
|
||||
pref("capability.policy.default.Window.location", "allAccess");
|
||||
pref("capability.policy.default.Window.opener.get", "allAccess");
|
||||
pref("capability.policy.default.Window.parent.get", "allAccess");
|
||||
pref("capability.policy.default.Window.postMessage.get", "allAccess");
|
||||
pref("capability.policy.default.Window.self.get", "allAccess");
|
||||
pref("capability.policy.default.Window.top.get", "allAccess");
|
||||
pref("capability.policy.default.Window.window.get", "allAccess");
|
||||
|
@ -45,8 +45,8 @@
|
||||
var tableContent = srvScope.linksToTableRows(links);
|
||||
function populate() {
|
||||
$("list-holder").setAttribute("rowspan", 1 + count);
|
||||
$("test-list").innerHTML += listContent.toLowerCase();
|
||||
$("test-table").innerHTML += tableContent.toLowerCase();
|
||||
$("test-list").innerHTML += listContent;
|
||||
$("test-table").innerHTML += tableContent;
|
||||
$("wrapper").innerHTML += " "; // redraw the table
|
||||
}
|
||||
gTestList = eval(srvScope.jsonArrayOfTestFiles(links));
|
||||
|
@ -105,7 +105,8 @@ use constant SERVER_STARTUP_TIMEOUT => 45;
|
||||
# servers onto localhost:8888. We have to grant them the same privileges as
|
||||
# localhost:8888 here, since the browser only knows them as the URLs they're
|
||||
# pretending to be.
|
||||
my @servers = ("localhost:8888", # MUST be first -- see PAC pref-setting code
|
||||
my @servers = (
|
||||
"localhost:8888", # MUST be first -- see PAC pref-setting code
|
||||
"example.org:80",
|
||||
"test1.example.org:80",
|
||||
"test2.example.org:80",
|
||||
@ -128,7 +129,10 @@ my @servers = ("localhost:8888", # MUST be first -- see PAC pref-setting code
|
||||
"sub2.test1.example.com:80",
|
||||
"sub2.test2.example.com:80",
|
||||
"sectest1.example.org:80",
|
||||
"sub.sectest2.example.org:80");
|
||||
"sub.sectest2.example.org:80",
|
||||
"sub1.xn--lt-uia.example.org:8000", # U+00E4 U+006C U+0074
|
||||
"sub2.xn--lt-uia.example.org:80", # U+00E4 U+006C U+0074
|
||||
);
|
||||
|
||||
|
||||
my $profile = "mochitesttestingprofile";
|
||||
|
Loading…
x
Reference in New Issue
Block a user