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:
jwalden@mit.edu 2008-01-29 17:31:29 -08:00
parent c7e2ea8cf6
commit 035ea5179c
36 changed files with 2357 additions and 33 deletions

View File

@ -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__

View File

@ -80,6 +80,7 @@ CPPSRCS = \
nsDOMPageTransitionEvent.cpp \
nsDOMXULCommandEvent.cpp \
nsDOMCommandEvent.cpp \
nsDOMMessageEvent.cpp \
nsPrivateTextRange.cpp \
nsDOMEventGroup.cpp \
nsXMLEventsManager.cpp \

View 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);
}

View 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__

View File

@ -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;
}

View File

@ -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);
};

View File

@ -71,6 +71,7 @@ XPIDLSRCS = \
nsIDOMSmartCardEvent.idl \
nsIDOMPageTransitionEvent.idl \
nsIDOMCommandEvent.idl \
nsIDOMMessageEvent.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View 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);
};

View File

@ -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
};

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -49,6 +49,7 @@ DIRS += \
ajax \
bugs \
chrome \
whatwg \
$(NULL)
include $(topsrcdir)/config/rules.mk

View 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)

View 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;

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@ -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");

View File

@ -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));

View File

@ -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";