mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 549682 - Port the message-manager API to mozilla-central, r=jst
--HG-- extra : rebase_source : 45b28a7762428193873a636fa7d5108607f9e4a3
This commit is contained in:
parent
bdd5097a41
commit
c719bc6e84
@ -2135,15 +2135,15 @@ nsScriptSecurityManager::GetPrincipalFromContext(JSContext *cx,
|
||||
{
|
||||
*result = nsnull;
|
||||
|
||||
nsIScriptContext *scriptContext = GetScriptContext(cx);
|
||||
nsIScriptContextPrincipal* scp =
|
||||
GetScriptContextPrincipalFromJSContext(cx);
|
||||
|
||||
if (!scriptContext)
|
||||
if (!scp)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> globalData =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
nsIScriptObjectPrincipal* globalData = scp->GetObjectPrincipal();
|
||||
if (globalData)
|
||||
NS_IF_ADDREF(*result = globalData->GetPrincipal());
|
||||
|
||||
@ -2328,11 +2328,11 @@ nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx,
|
||||
return targetPrincipal;
|
||||
}
|
||||
|
||||
nsIScriptContext *scriptContext = GetScriptContext(cx);
|
||||
if (scriptContext)
|
||||
nsIScriptContextPrincipal* scp =
|
||||
GetScriptContextPrincipalFromJSContext(cx);
|
||||
if (scp)
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> globalData =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
nsIScriptObjectPrincipal* globalData = scp->GetObjectPrincipal();
|
||||
if (!globalData)
|
||||
{
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
|
@ -122,6 +122,7 @@ XPIDLSRCS = \
|
||||
nsIFrameLoader.idl \
|
||||
nsIXMLHttpRequest.idl \
|
||||
nsIContentSecurityPolicy.idl \
|
||||
nsIFrameMessageManager.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -1721,7 +1721,7 @@ public:
|
||||
PRBool RePush(nsPIDOMEventTarget *aCurrentTarget);
|
||||
// If a null JSContext is passed to Push(), that will cause no
|
||||
// push to happen and false to be returned.
|
||||
PRBool Push(JSContext *cx);
|
||||
PRBool Push(JSContext *cx, PRBool aRequiresScriptContext = PR_TRUE);
|
||||
// Explicitly push a null JSContext on the the stack
|
||||
PRBool PushNull();
|
||||
|
||||
|
@ -41,8 +41,9 @@
|
||||
|
||||
interface nsIDocShell;
|
||||
interface nsIURI;
|
||||
interface nsIChromeFrameMessageManager;
|
||||
|
||||
[scriptable, uuid(d675c531-6bdc-417c-b176-635060105f07)]
|
||||
[scriptable, uuid(3b256c12-20e1-4fd3-8edb-b9c793919f15)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -74,6 +75,9 @@ interface nsIFrameLoader : nsISupports
|
||||
* or may not be allowed on the loader's docshell.
|
||||
*/
|
||||
readonly attribute boolean depthTooGreat;
|
||||
|
||||
// Note, when frameloaders are swapped, also messageManagers are swapped.
|
||||
readonly attribute nsIChromeFrameMessageManager messageManager;
|
||||
};
|
||||
|
||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||
|
119
content/base/public/nsIFrameMessageManager.idl
Normal file
119
content/base/public/nsIFrameMessageManager.idl
Normal file
@ -0,0 +1,119 @@
|
||||
/* -*- 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 Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDocShell;
|
||||
interface nsIContent;
|
||||
|
||||
[scriptable, function, uuid(938fcb95-3d63-46be-aa72-94d08fd3b418)]
|
||||
interface nsIFrameMessageListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* This is for JS only.
|
||||
* receiveMessage is called with one parameter, which has the following
|
||||
* properties:
|
||||
* {
|
||||
* name: %message name%,
|
||||
* sync: %true or false%.
|
||||
* json: %json object or null%,
|
||||
* objects: %array of cpow or null, always null if sync is false%
|
||||
* }
|
||||
* @note objects property isn't implemented yet.
|
||||
*
|
||||
* if the message is synchronous, possible return value is sent back
|
||||
* as JSON.
|
||||
*
|
||||
* When the listener is called, 'this' value is the target of the message.
|
||||
*/
|
||||
void receiveMessage();
|
||||
};
|
||||
|
||||
[scriptable, uuid(6b736edb-863d-40bd-bca2-62f44da803c0)]
|
||||
interface nsIFrameMessageManager : nsISupports
|
||||
{
|
||||
void addMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
|
||||
void removeMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
|
||||
void sendAsyncMessage(/*in messageName, in JSON*/);
|
||||
};
|
||||
|
||||
[scriptable, uuid(c56e85b8-6736-4ae2-ae90-66bcef952a82)]
|
||||
interface nsIContentFrameMessageManager : nsIFrameMessageManager
|
||||
{
|
||||
/**
|
||||
* @note sending JS objects isn't implemented yet.
|
||||
*
|
||||
* Returns an array of JSON objects.
|
||||
*/
|
||||
void sendSyncMessage(/*in messageName, in JSON, in an array of JS objects,*/);
|
||||
|
||||
/**
|
||||
* The current top level window in the frame or null.
|
||||
*/
|
||||
readonly attribute nsIDOMWindow content;
|
||||
|
||||
/**
|
||||
* The top level docshell or null.
|
||||
*/
|
||||
readonly attribute nsIDocShell docShell;
|
||||
|
||||
/**
|
||||
* Print a string to stdout.
|
||||
*/
|
||||
void dump(in DOMString aStr);
|
||||
};
|
||||
|
||||
[uuid(9c48d557-92fe-4edb-95fc-bfe97e77bdc3)]
|
||||
interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
|
||||
{
|
||||
[notxpcom] nsIContent getOwnerContent();
|
||||
};
|
||||
|
||||
[scriptable, uuid(ed6522fd-ffb6-4920-b50d-cf629309616b)]
|
||||
interface nsIChromeFrameMessageManager : nsIFrameMessageManager
|
||||
{
|
||||
/*
|
||||
* Load a script in the (remote) frame. aURL must be the absolute URL.
|
||||
* data: URLs are also supported. For example data:,dump("foo\n");
|
||||
* If aAllowDelayedLoad is true, script will be loaded when the
|
||||
* remote frame becomes available. Otherwise the script will be loaded
|
||||
* only if the frame is already available.
|
||||
*/
|
||||
void loadFrameScript(in AString aURL, in boolean aAllowDelayedLoad);
|
||||
};
|
||||
|
@ -144,6 +144,8 @@ CPPSRCS = \
|
||||
nsXMLNameSpaceMap.cpp \
|
||||
Link.cpp \
|
||||
nsFileDataProtocolHandler.cpp \
|
||||
nsFrameMessageManager.cpp \
|
||||
nsInProcessTabChildGlobal.cpp \
|
||||
$(NULL)
|
||||
|
||||
GQI_SRCS = contentbase.gqi
|
||||
|
@ -2699,6 +2699,12 @@ nsCxPusher::Push(nsPIDOMEventTarget *aCurrentTarget)
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
if (!scx) {
|
||||
// The target may have a special JS context for event handlers.
|
||||
JSContext* cx = aCurrentTarget->GetJSContextForEventHandlers();
|
||||
if (cx) {
|
||||
DoPush(cx);
|
||||
}
|
||||
|
||||
// Nothing to do here, I guess. Have to return true so that event firing
|
||||
// will still work correctly even if there is no associated JSContext
|
||||
return PR_TRUE;
|
||||
@ -2748,7 +2754,7 @@ nsCxPusher::RePush(nsPIDOMEventTarget *aCurrentTarget)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCxPusher::Push(JSContext *cx)
|
||||
nsCxPusher::Push(JSContext *cx, PRBool aRequiresScriptContext)
|
||||
{
|
||||
if (mPushedSomething) {
|
||||
NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!");
|
||||
@ -2764,7 +2770,7 @@ nsCxPusher::Push(JSContext *cx)
|
||||
// XXXbz do we really need to? If we don't get one of these in Pop(), is
|
||||
// that really a problem? Or do we need to do this to effectively root |cx|?
|
||||
mScx = GetScriptContextFromJSContext(cx);
|
||||
if (!mScx) {
|
||||
if (!mScx && aRequiresScriptContext) {
|
||||
// Should probably return PR_FALSE. See bug 416916.
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -3188,14 +3194,22 @@ nsContentUtils::DispatchChromeEvent(nsIDocument *aDoc,
|
||||
NS_ASSERTION(aDoc, "GetEventAndTarget lied?");
|
||||
if (!aDoc->GetWindow())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
if (!aDoc->GetWindow()->GetChromeEventHandler())
|
||||
|
||||
nsPIDOMEventTarget* piTarget = aDoc->GetWindow()->GetChromeEventHandler();
|
||||
if (!target)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> flo = do_QueryInterface(piTarget);
|
||||
if (flo) {
|
||||
nsRefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
|
||||
if (fl) {
|
||||
nsPIDOMEventTarget* t = fl->GetTabChildGlobalAsEventTarget();
|
||||
piTarget = t ? t : piTarget;
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
rv = aDoc->GetWindow()->GetChromeEventHandler()->DispatchDOMEvent(nsnull,
|
||||
event,
|
||||
nsnull,
|
||||
&status);
|
||||
rv = piTarget->DispatchDOMEvent(nsnull, event, nsnull, &status);
|
||||
if (aDefaultAction) {
|
||||
*aDefaultAction = (status != nsEventStatus_eConsumeNoDefault);
|
||||
}
|
||||
|
@ -87,6 +87,8 @@
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsInProcessTabChildGlobal.h"
|
||||
|
||||
class nsAsyncDocShellDestroyer : public nsRunnable
|
||||
{
|
||||
@ -124,7 +126,20 @@ public:
|
||||
// we'd need to re-institute a fixed version of bug 98158.
|
||||
#define MAX_DEPTH_CONTENT_FRAMES 10
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(nsFrameLoader, mDocShell)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsFrameLoader)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocShell)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChildMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocShell)
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsFrameLoader::mMessageManager");
|
||||
cb.NoteXPCOMChild(static_cast<nsIContentFrameMessageManager*>(tmp->mMessageManager.get()));
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChildMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
|
||||
@ -831,6 +846,38 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
mOwnerContent = otherContent;
|
||||
aOther->mOwnerContent = ourContent;
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ourMessageManager = mMessageManager;
|
||||
nsRefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
|
||||
// Swap pointers in child message managers.
|
||||
if (mChildMessageManager) {
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get());
|
||||
tabChild->SetOwner(otherContent);
|
||||
tabChild->SetChromeMessageManager(otherMessageManager);
|
||||
}
|
||||
if (aOther->mChildMessageManager) {
|
||||
nsInProcessTabChildGlobal* otherTabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(aOther->mChildMessageManager.get());
|
||||
otherTabChild->SetOwner(ourContent);
|
||||
otherTabChild->SetChromeMessageManager(ourMessageManager);
|
||||
}
|
||||
// Swap and setup things in parent message managers.
|
||||
nsFrameMessageManager* ourParentManager = mMessageManager ?
|
||||
mMessageManager->GetParentManager() : nsnull;
|
||||
nsFrameMessageManager* otherParentManager = aOther->mMessageManager ?
|
||||
aOther->mMessageManager->GetParentManager() : nsnull;
|
||||
if (mMessageManager) {
|
||||
mMessageManager->Disconnect();
|
||||
mMessageManager->SetParentManager(otherParentManager);
|
||||
mMessageManager->SetCallbackData(aOther, PR_FALSE);
|
||||
}
|
||||
if (aOther->mMessageManager) {
|
||||
aOther->mMessageManager->Disconnect();
|
||||
aOther->mMessageManager->SetParentManager(ourParentManager);
|
||||
aOther->mMessageManager->SetCallbackData(this, PR_FALSE);
|
||||
}
|
||||
mMessageManager.swap(aOther->mMessageManager);
|
||||
|
||||
aFirstToSwap.swap(aSecondToSwap);
|
||||
|
||||
// Drop any cached content viewers in the two session histories.
|
||||
@ -869,6 +916,13 @@ nsFrameLoader::Destroy()
|
||||
}
|
||||
mDestroyCalled = PR_TRUE;
|
||||
|
||||
if (mMessageManager) {
|
||||
mMessageManager->Disconnect();
|
||||
}
|
||||
if (mChildMessageManager) {
|
||||
static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->Disconnect();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (mOwnerContent) {
|
||||
doc = mOwnerContent->GetOwnerDoc();
|
||||
@ -1019,6 +1073,8 @@ nsFrameLoader::EnsureDocShell()
|
||||
mDocShell->SetChromeEventHandler(chromeEventHandler);
|
||||
}
|
||||
|
||||
EnsureMessageManager();
|
||||
|
||||
// This is nasty, this code (the do_GetInterface(mDocShell) below)
|
||||
// *must* come *after* the above call to
|
||||
// mDocShell->SetChromeEventHandler() for the global window to get
|
||||
@ -1173,3 +1229,101 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
|
||||
viewer->SetDOMDocument(clonedDOMDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool LoadScript(void* aCallbackData, const nsAString& aURL)
|
||||
{
|
||||
nsFrameLoader* fl = static_cast<nsFrameLoader*>(aCallbackData);
|
||||
nsRefPtr<nsInProcessTabChildGlobal> tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(fl->GetTabChildGlobalAsEventTarget());
|
||||
if (tabChild) {
|
||||
tabChild->LoadFrameScript(aURL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class nsAsyncMessageToChild : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToChild(nsFrameLoader* aFrameLoader,
|
||||
const nsAString& aMessage, const nsAString& aJSON)
|
||||
: mFrameLoader(aFrameLoader), mMessage(aMessage), mJSON(aJSON) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(mFrameLoader->mChildMessageManager.get());
|
||||
if (tabChild && tabChild->GetInnerManager()) {
|
||||
tabChild->GetInnerManager()->
|
||||
ReceiveMessage(static_cast<nsPIDOMEventTarget*>(tabChild), mMessage,
|
||||
PR_FALSE, mJSON, nsnull, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
nsString mMessage;
|
||||
nsString mJSON;
|
||||
};
|
||||
|
||||
bool SendAsyncMessageToChild(void* aCallbackData,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aJSON)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToChild(static_cast<nsFrameLoader*>(aCallbackData),
|
||||
aMessage, aJSON);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetMessageManager(nsIChromeFrameMessageManager** aManager)
|
||||
{
|
||||
NS_IF_ADDREF(*aManager = mMessageManager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::EnsureMessageManager()
|
||||
{
|
||||
NS_ENSURE_STATE(mOwnerContent);
|
||||
//XXX Should we create message manager also for chrome iframes?
|
||||
if (!mIsTopLevelContent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
EnsureDocShell();
|
||||
if (mMessageManager) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_STATE(sctx);
|
||||
JSContext* cx = static_cast<JSContext*>(sctx->GetNativeContext());
|
||||
NS_ENSURE_STATE(cx);
|
||||
|
||||
nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
|
||||
do_QueryInterface(mOwnerContent->GetOwnerDoc()->GetWindow());
|
||||
NS_ENSURE_STATE(chromeWindow);
|
||||
nsCOMPtr<nsIChromeFrameMessageManager> parentManager;
|
||||
chromeWindow->GetMessageManager(getter_AddRefs(parentManager));
|
||||
|
||||
mMessageManager = new nsFrameMessageManager(PR_TRUE,
|
||||
nsnull,
|
||||
SendAsyncMessageToChild,
|
||||
LoadScript,
|
||||
this,
|
||||
static_cast<nsFrameMessageManager*>(parentManager.get()),
|
||||
cx);
|
||||
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
|
||||
mChildMessageManager =
|
||||
new nsInProcessTabChildGlobal(mDocShell, mOwnerContent, mMessageManager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPIDOMEventTarget*
|
||||
nsFrameLoader::GetTabChildGlobalAsEventTarget()
|
||||
{
|
||||
return static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get());
|
||||
}
|
||||
|
@ -48,10 +48,12 @@
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsIFrameLoader.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIURI;
|
||||
class nsIFrameFrame;
|
||||
class nsIInProcessContentFrameMessageManager;
|
||||
|
||||
class nsFrameLoader : public nsIFrameLoader
|
||||
{
|
||||
@ -80,7 +82,7 @@ public:
|
||||
nsresult ReallyStartLoading();
|
||||
void Finalize();
|
||||
nsIDocShell* GetExistingDocShell() { return mDocShell; }
|
||||
|
||||
nsPIDOMEventTarget* GetTabChildGlobalAsEventTarget();
|
||||
nsresult CreateStaticClone(nsIFrameLoader* aDest);
|
||||
|
||||
/**
|
||||
@ -109,6 +111,7 @@ public:
|
||||
private:
|
||||
|
||||
NS_HIDDEN_(nsresult) EnsureDocShell();
|
||||
nsresult EnsureMessageManager();
|
||||
NS_HIDDEN_(void) GetURL(nsString& aURL);
|
||||
nsresult CheckURILoad(nsIURI* aURI);
|
||||
void FireErrorEvent();
|
||||
@ -117,6 +120,11 @@ private:
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURIToLoad;
|
||||
nsIContent *mOwnerContent; // WEAK
|
||||
public:
|
||||
// public because a callback needs these.
|
||||
nsRefPtr<nsFrameMessageManager> mMessageManager;
|
||||
nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
|
||||
private:
|
||||
PRPackedBool mDepthTooGreat : 1;
|
||||
PRPackedBool mIsTopLevelContent : 1;
|
||||
PRPackedBool mDestroyCalled : 1;
|
||||
|
457
content/base/src/nsFrameMessageManager.cpp
Normal file
457
content/base/src/nsFrameMessageManager.cpp
Normal file
@ -0,0 +1,457 @@
|
||||
/* -*- 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 Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsinterp.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsFrameMessageManager)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager)
|
||||
PRUint32 count = tmp->mListeners.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mListeners[i] mListener");
|
||||
cb.NoteXPCOMChild(tmp->mListeners[i].mListener.get());
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameMessageManager)
|
||||
tmp->mListeners.Clear();
|
||||
for (PRInt32 i = tmp->mChildManagers.Count(); i > 0; --i) {
|
||||
static_cast<nsFrameMessageManager*>(tmp->mChildManagers[i - 1])->
|
||||
Disconnect(PR_FALSE);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIFrameMessageManager, nsIContentFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIContentFrameMessageManager, !mChrome)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIChromeFrameMessageManager, mChrome)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsFrameMessageManager,
|
||||
nsIContentFrameMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsFrameMessageManager,
|
||||
nsIContentFrameMessageManager)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
|
||||
nsIFrameMessageListener* aListener)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
|
||||
PRUint32 len = mListeners.Length();
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
if (mListeners[i].mMessage == message &&
|
||||
mListeners[i].mListener == aListener) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsMessageListenerInfo* entry = mListeners.AppendElement();
|
||||
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
||||
entry->mMessage = message;
|
||||
entry->mListener = aListener;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::RemoveMessageListener(const nsAString& aMessage,
|
||||
nsIFrameMessageListener* aListener)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
|
||||
PRUint32 len = mListeners.Length();
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
if (mListeners[i].mMessage == message &&
|
||||
mListeners[i].mListener == aListener) {
|
||||
mListeners.RemoveElementAt(i);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
|
||||
PRBool aAllowDelayedLoad)
|
||||
{
|
||||
if (aAllowDelayedLoad && !mCallbackData && !mChildManagers.Count()) {
|
||||
mPendingScripts.AppendElement(aURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mCallbackData) {
|
||||
#ifdef DEBUG_smaug
|
||||
printf("Will load %s \n", NS_ConvertUTF16toUTF8(aURL).get());
|
||||
#endif
|
||||
NS_ENSURE_TRUE(mLoadScriptCallback(mCallbackData, aURL), NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
PRInt32 len = mChildManagers.Count();
|
||||
for (PRInt32 i = 0; i < len; ++i) {
|
||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->LoadFrameScript(aURL,
|
||||
PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JSONCreator(const jschar* aBuf, uint32 aLen, void* aData)
|
||||
{
|
||||
nsAString* result = static_cast<nsAString*>(aData);
|
||||
result->Append((PRUnichar*)aBuf, (PRUint32)aLen);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameMessageManager::GetParamsForMessage(nsAString& aMessageName,
|
||||
nsAString& aJSON)
|
||||
{
|
||||
aMessageName.Truncate();
|
||||
aJSON.Truncate();
|
||||
nsAXPCNativeCallContext* ncc = nsnull;
|
||||
nsresult rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_STATE(ncc);
|
||||
|
||||
JSContext* ctx = nsnull;
|
||||
rv = ncc->GetJSContext(&ctx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 argc;
|
||||
jsval* argv = nsnull;
|
||||
ncc->GetArgc(&argc);
|
||||
ncc->GetArgvPtr(&argv);
|
||||
|
||||
JSAutoRequest ar(ctx);
|
||||
JSString* str;
|
||||
if (argc && (str = JS_ValueToString(ctx, argv[0])) && str) {
|
||||
aMessageName.Assign(nsDependentJSString(str));
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
jsval v = argv[1];
|
||||
nsAutoGCRoot root(&v, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, JS_FALSE);
|
||||
if (JS_TryJSON(ctx, &v)) {
|
||||
JS_Stringify(ctx, &v, nsnull, JSVAL_NULL, JSONCreator, &aJSON);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendSyncMessage()
|
||||
{
|
||||
if (mSyncCallback) {
|
||||
NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
|
||||
nsString messageName;
|
||||
nsString json;
|
||||
nsresult rv = GetParamsForMessage(messageName, json);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsTArray<nsString> retval;
|
||||
if (mSyncCallback(mCallbackData, messageName, json, &retval)) {
|
||||
nsAXPCNativeCallContext* ncc = nsnull;
|
||||
rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_STATE(ncc);
|
||||
|
||||
JSContext* ctx = nsnull;
|
||||
rv = ncc->GetJSContext(&ctx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
JSAutoRequest ar(ctx);
|
||||
|
||||
PRUint32 len = retval.Length();
|
||||
jsval* dest = nsnull;
|
||||
JSObject* dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
|
||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < len; ++i) {
|
||||
jsval ret = JSVAL_VOID;
|
||||
nsAutoGCRoot root(&ret, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
JSONParser* parser = JS_BeginJSONParse(ctx, &ret);
|
||||
JSBool ok = JS_ConsumeJSONText(ctx, parser, (jschar*)retval[i].get(),
|
||||
(uint32)retval[i].Length());
|
||||
ok = JS_FinishJSONParse(ctx, parser, JSVAL_NULL) && ok;
|
||||
if (ok) {
|
||||
dest[i] = ret;
|
||||
}
|
||||
}
|
||||
|
||||
jsval* retvalPtr;
|
||||
ncc->GetRetValPtr(&retvalPtr);
|
||||
*retvalPtr = OBJECT_TO_JSVAL(dataArray);
|
||||
ncc->SetReturnValueWasSet(PR_TRUE);
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameMessageManager::SendAsyncMessageInternal(const nsAString& aMessage,
|
||||
const nsAString& aJSON)
|
||||
{
|
||||
if (mAsyncCallback) {
|
||||
NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
|
||||
mAsyncCallback(mCallbackData, aMessage, aJSON);
|
||||
}
|
||||
PRInt32 len = mChildManagers.Count();
|
||||
for (PRInt32 i = 0; i < len; ++i) {
|
||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
||||
SendAsyncMessageInternal(aMessage, aJSON);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::SendAsyncMessage()
|
||||
{
|
||||
nsString messageName;
|
||||
nsString json;
|
||||
nsresult rv = GetParamsForMessage(messageName, json);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return SendAsyncMessageInternal(messageName, json);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::Dump(const nsAString& aStr)
|
||||
{
|
||||
fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
|
||||
fflush(stdout);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::GetContent(nsIDOMWindow** aContent)
|
||||
{
|
||||
*aContent = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::GetDocShell(nsIDocShell** aDocShell)
|
||||
{
|
||||
*aDocShell = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
const nsAString& aMessage,
|
||||
PRBool aSync, const nsAString& aJSON,
|
||||
JSObject* aObjectsArray,
|
||||
nsTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
if (mListeners.Length()) {
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
|
||||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip(this);
|
||||
|
||||
for (PRUint32 i = 0; i < mListeners.Length(); ++i) {
|
||||
if (mListeners[i].mMessage == name) {
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS =
|
||||
do_QueryInterface(mListeners[i].mListener);
|
||||
if (!wrappedJS) {
|
||||
continue;
|
||||
}
|
||||
JSObject* object = nsnull;
|
||||
wrappedJS->GetJSObject(&object);
|
||||
if (!object) {
|
||||
continue;
|
||||
}
|
||||
nsCxPusher pusher;
|
||||
NS_ENSURE_STATE(pusher.Push(mContext, PR_FALSE));
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
|
||||
// The parameter for the listener function.
|
||||
JSObject* param = JS_NewObject(mContext, NULL, NULL, NULL);
|
||||
NS_ENSURE_TRUE(param, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv;
|
||||
nsAutoGCRoot resultGCRoot(¶m, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
jsval targetv;
|
||||
nsAutoGCRoot resultGCRoot2(&targetv, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsContentUtils::WrapNative(mContext,
|
||||
JS_GetGlobalObject(mContext),
|
||||
aTarget, &targetv);
|
||||
|
||||
// To keep compatibility with e10s message manager,
|
||||
// define empty objects array.
|
||||
if (!aObjectsArray) {
|
||||
jsval* dest = nsnull;
|
||||
// Because we want JS messages to have always the same properties,
|
||||
// create array even if len == 0.
|
||||
aObjectsArray = js_NewArrayObjectWithCapacity(mContext, 0, &dest);
|
||||
if (!aObjectsArray) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nsAutoGCRoot arrayGCRoot(&aObjectsArray, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
jsval json = JSVAL_NULL;
|
||||
nsAutoGCRoot root(&json, &rv);
|
||||
if (NS_SUCCEEDED(rv) && !aJSON.IsEmpty()) {
|
||||
JSONParser* parser = JS_BeginJSONParse(mContext, &json);
|
||||
if (parser) {
|
||||
JSBool ok = JS_ConsumeJSONText(mContext, parser,
|
||||
(jschar*)nsString(aJSON).get(),
|
||||
(uint32)aJSON.Length());
|
||||
ok = JS_FinishJSONParse(mContext, parser, JSVAL_NULL) && ok;
|
||||
if (!ok) {
|
||||
json = JSVAL_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
JSString* jsMessage =
|
||||
JS_NewUCStringCopyN(mContext,
|
||||
reinterpret_cast<const jschar *>(nsString(aMessage).get()),
|
||||
aMessage.Length());
|
||||
NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
|
||||
JS_DefineProperty(mContext, param, "target", targetv, NULL, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(mContext, param, "name",
|
||||
STRING_TO_JSVAL(jsMessage), NULL, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(mContext, param, "sync",
|
||||
BOOLEAN_TO_JSVAL(aSync), NULL, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(mContext, param, "json", json, NULL, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(mContext, param, "objects", OBJECT_TO_JSVAL(aObjectsArray),
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
|
||||
jsval thisValue = JSVAL_VOID;
|
||||
nsAutoGCRoot resultGCRoot3(&thisValue, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
jsval funval = JSVAL_VOID;
|
||||
if (JS_ObjectIsFunction(mContext, object)) {
|
||||
// If the listener is a JS function:
|
||||
funval = OBJECT_TO_JSVAL(object);
|
||||
nsCOMPtr<nsISupports> defaultThisValue =
|
||||
do_QueryInterface(static_cast<nsIContentFrameMessageManager*>(this));
|
||||
nsContentUtils::WrapNative(mContext,
|
||||
JS_GetGlobalObject(mContext),
|
||||
defaultThisValue, &thisValue);
|
||||
} else {
|
||||
// If the listener is a JS object which has receiveMessage function:
|
||||
NS_ENSURE_STATE(JS_GetProperty(mContext, object, "receiveMessage",
|
||||
&funval) &&
|
||||
JSVAL_IS_OBJECT(funval) &&
|
||||
!JSVAL_IS_NULL(funval));
|
||||
JSObject* funobject = JSVAL_TO_OBJECT(funval);
|
||||
NS_ENSURE_STATE(JS_ObjectIsFunction(mContext, funobject));
|
||||
thisValue = OBJECT_TO_JSVAL(object);
|
||||
}
|
||||
|
||||
jsval rval = JSVAL_VOID;
|
||||
nsAutoGCRoot resultGCRoot4(&rval, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
void* mark = nsnull;
|
||||
jsval* argv = js_AllocStack(mContext, 1, &mark);
|
||||
NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
argv[0] = OBJECT_TO_JSVAL(param);
|
||||
JSObject* thisObject = JSVAL_TO_OBJECT(thisValue);
|
||||
JS_CallFunctionValue(mContext, thisObject,
|
||||
funval, 1, argv, &rval);
|
||||
if (aJSONRetVal) {
|
||||
nsString json;
|
||||
if (JS_TryJSON(mContext, &rval) &&
|
||||
JS_Stringify(mContext, &rval, nsnull, JSVAL_NULL,
|
||||
JSONCreator, &json)) {
|
||||
aJSONRetVal->AppendElement(json);
|
||||
}
|
||||
}
|
||||
js_FreeStack(mContext, mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||
aSync, aJSON, aObjectsArray,
|
||||
aJSONRetVal) : NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameMessageManager::AddChildManager(nsFrameMessageManager* aManager,
|
||||
PRBool aLoadScripts)
|
||||
{
|
||||
mChildManagers.AppendObject(aManager);
|
||||
if (aLoadScripts) {
|
||||
for (PRUint32 i = 0; i < mPendingScripts.Length(); ++i) {
|
||||
aManager->LoadFrameScript(mPendingScripts[i], PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameMessageManager::SetCallbackData(void* aData, PRBool aLoadScripts)
|
||||
{
|
||||
if (aData && mCallbackData != aData) {
|
||||
mCallbackData = aData;
|
||||
// First load global scripts by adding this to parent manager.
|
||||
if (mParentManager) {
|
||||
mParentManager->AddChildManager(this, aLoadScripts);
|
||||
}
|
||||
if (aLoadScripts) {
|
||||
for (PRUint32 i = 0; i < mPendingScripts.Length(); ++i) {
|
||||
LoadFrameScript(mPendingScripts[i], PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameMessageManager::Disconnect(PRBool aRemoveFromParent)
|
||||
{
|
||||
if (mParentManager && aRemoveFromParent) {
|
||||
mParentManager->RemoveChildManager(this);
|
||||
}
|
||||
mParentManager = nsnull;
|
||||
mCallbackData = nsnull;
|
||||
}
|
143
content/base/src/nsFrameMessageManager.h
Normal file
143
content/base/src/nsFrameMessageManager.h
Normal file
@ -0,0 +1,143 @@
|
||||
/* -*- 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 Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 nsFrameMessageManager_h__
|
||||
#define nsFrameMessageManager_h__
|
||||
|
||||
#include "nsIFrameMessageManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsAXPCNativeCallContext;
|
||||
struct JSContext;
|
||||
struct JSObject;
|
||||
|
||||
struct nsMessageListenerInfo
|
||||
{
|
||||
nsCOMPtr<nsIFrameMessageListener> mListener;
|
||||
nsCOMPtr<nsIAtom> mMessage;
|
||||
};
|
||||
|
||||
typedef bool (*nsLoadScriptCallback)(void* aCallbackData, const nsAString& aURL);
|
||||
typedef bool (*nsSyncMessageCallback)(void* aCallbackData,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aJSON,
|
||||
nsTArray<nsString>* aJSONRetVal);
|
||||
typedef bool (*nsAsyncMessageCallback)(void* aCallbackData,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aJSON);
|
||||
|
||||
class nsFrameMessageManager : public nsIContentFrameMessageManager,
|
||||
public nsIChromeFrameMessageManager
|
||||
{
|
||||
public:
|
||||
nsFrameMessageManager(PRBool aChrome,
|
||||
nsSyncMessageCallback aSyncCallback,
|
||||
nsAsyncMessageCallback aAsyncCallback,
|
||||
nsLoadScriptCallback aLoadScriptCallback,
|
||||
void* aCallbackData,
|
||||
nsFrameMessageManager* aParentManager,
|
||||
JSContext* aContext)
|
||||
: mChrome(aChrome), mParentManager(aParentManager),
|
||||
mSyncCallback(aSyncCallback), mAsyncCallback(aAsyncCallback),
|
||||
mLoadScriptCallback(aLoadScriptCallback), mCallbackData(aCallbackData),
|
||||
mContext(aContext)
|
||||
{
|
||||
NS_ASSERTION(mContext, "Should have mContext!");
|
||||
NS_ASSERTION(aChrome || !aParentManager, "Should not set parent manager!");
|
||||
if (mParentManager && mCallbackData) {
|
||||
mParentManager->AddChildManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
~nsFrameMessageManager()
|
||||
{
|
||||
for (PRInt32 i = mChildManagers.Count(); i > 0; --i) {
|
||||
static_cast<nsFrameMessageManager*>(mChildManagers[i - 1])->
|
||||
Disconnect(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameMessageManager,
|
||||
nsIContentFrameMessageManager)
|
||||
NS_DECL_NSIFRAMEMESSAGEMANAGER
|
||||
NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
|
||||
NS_DECL_NSICHROMEFRAMEMESSAGEMANAGER
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||
PRBool aSync, const nsAString& aJSON,
|
||||
JSObject* aObjectsArray,
|
||||
nsTArray<nsString>* aJSONRetVal);
|
||||
void AddChildManager(nsFrameMessageManager* aManager,
|
||||
PRBool aLoadScripts = PR_TRUE);
|
||||
void RemoveChildManager(nsFrameMessageManager* aManager)
|
||||
{
|
||||
mChildManagers.RemoveObject(aManager);
|
||||
}
|
||||
|
||||
void Disconnect(PRBool aRemoveFromParent = PR_TRUE);
|
||||
void SetCallbackData(void* aData, PRBool aLoadScripts = PR_TRUE);
|
||||
nsresult GetParamsForMessage(nsAString& aMessageName, nsAString& aJSON);
|
||||
nsresult SendAsyncMessageInternal(const nsAString& aMessage,
|
||||
const nsAString& aJSON);
|
||||
JSContext* GetJSContext() { return mContext; }
|
||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||
void SetParentManager(nsFrameMessageManager* aParent)
|
||||
{
|
||||
NS_ASSERTION(!mParentManager, "We have parent manager already!");
|
||||
NS_ASSERTION(mChrome, "Should not set parent manager!");
|
||||
mParentManager = aParent;
|
||||
}
|
||||
protected:
|
||||
nsTArray<nsMessageListenerInfo> mListeners;
|
||||
nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
|
||||
PRBool mChrome;
|
||||
nsFrameMessageManager* mParentManager;
|
||||
nsSyncMessageCallback mSyncCallback;
|
||||
nsAsyncMessageCallback mAsyncCallback;
|
||||
nsLoadScriptCallback mLoadScriptCallback;
|
||||
void* mCallbackData;
|
||||
JSContext* mContext;
|
||||
nsTArray<nsString> mPendingScripts;
|
||||
};
|
||||
|
||||
#endif
|
366
content/base/src/nsInProcessTabChildGlobal.cpp
Normal file
366
content/base/src/nsInProcessTabChildGlobal.cpp
Normal file
@ -0,0 +1,366 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* ***** 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 Content App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsInProcessTabChildGlobal.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsFrameLoader.h"
|
||||
|
||||
bool SendSyncMessageToParent(void* aCallbackData,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aJSON,
|
||||
nsTArray<nsString>* aJSONRetVal)
|
||||
{
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(aCallbackData);
|
||||
PRInt32 count = tabChild->mASyncMessages.Count();
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIRunnable> async = tabChild->mASyncMessages.SafeObjectAt(i);
|
||||
async->Run();
|
||||
}
|
||||
if (tabChild->mChromeMessageManager) {
|
||||
tabChild->mChromeMessageManager->ReceiveMessage(tabChild->mOwner, aMessage, PR_TRUE,
|
||||
aJSON, nsnull, aJSONRetVal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class nsAsyncMessageToParent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToParent(nsInProcessTabChildGlobal* aTabChild,
|
||||
const nsAString& aMessage, const nsAString& aJSON)
|
||||
: mTabChild(aTabChild), mMessage(aMessage), mJSON(aJSON) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mTabChild->mASyncMessages.RemoveObject(this);
|
||||
if (mTabChild->mChromeMessageManager) {
|
||||
mTabChild->mChromeMessageManager->ReceiveMessage(mTabChild->mOwner, mMessage,
|
||||
PR_FALSE,
|
||||
mJSON, nsnull, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
|
||||
nsString mMessage;
|
||||
nsString mJSON;
|
||||
};
|
||||
|
||||
bool SendAsyncMessageToParent(void* aCallbackData,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aJSON)
|
||||
{
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(aCallbackData);
|
||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToParent(tabChild, aMessage, aJSON);
|
||||
tabChild->mASyncMessages.AppendObject(ev);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int tabChildC = 0;
|
||||
nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
|
||||
nsIContent* aOwner,
|
||||
nsFrameMessageManager* aChrome)
|
||||
: mCx(nsnull), mDocShell(aShell), mInitialized(PR_FALSE), mLoadingScript(PR_FALSE),
|
||||
mDelayedDisconnect(PR_FALSE), mOwner(aOwner), mChromeMessageManager(aChrome)
|
||||
{
|
||||
}
|
||||
|
||||
nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
|
||||
{
|
||||
Disconnect();
|
||||
NS_ASSERTION(!mCx, "Couldn't release JSContext?!?");
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInProcessTabChildGlobal::Init()
|
||||
{
|
||||
nsresult rv = InitTabChildGlobal();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Couldn't initialize nsInProcessTabChildGlobal");
|
||||
mMessageManager = new nsFrameMessageManager(PR_FALSE,
|
||||
SendSyncMessageToParent,
|
||||
SendAsyncMessageToParent,
|
||||
nsnull,
|
||||
this,
|
||||
nsnull,
|
||||
mCx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, nsDOMEventTargetHelper)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInProcessTabChildGlobal::GetContent(nsIDOMWindow** aContent)
|
||||
{
|
||||
*aContent = nsnull;
|
||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
|
||||
window.swap(*aContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
|
||||
{
|
||||
NS_IF_ADDREF(*aDocShell = mDocShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsInProcessTabChildGlobal::Disconnect()
|
||||
{
|
||||
mDocShell = nsnull;
|
||||
mOwner = nsnull;
|
||||
mChromeMessageManager = nsnull;
|
||||
if (mMessageManager) {
|
||||
static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
|
||||
mMessageManager = nsnull;
|
||||
}
|
||||
if (!mLoadingScript) {
|
||||
if (mCx) {
|
||||
JS_DestroyContext(mCx);
|
||||
mCx = nsnull;
|
||||
}
|
||||
} else {
|
||||
mDelayedDisconnect = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsIContent *)
|
||||
nsInProcessTabChildGlobal::GetOwnerContent()
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInProcessTabChildGlobal::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
aVisitor.mParentTarget = mOwner;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mOwner) {
|
||||
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
|
||||
nsRefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
|
||||
if (fl) {
|
||||
NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
|
||||
"Wrong event target!");
|
||||
NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
|
||||
"Wrong message manager!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInProcessTabChildGlobal::InitTabChildGlobal()
|
||||
{
|
||||
nsCOMPtr<nsIJSRuntimeService> runtimeSvc =
|
||||
do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
|
||||
NS_ENSURE_STATE(runtimeSvc);
|
||||
|
||||
JSRuntime* rt = nsnull;
|
||||
runtimeSvc->GetRuntime(&rt);
|
||||
NS_ENSURE_STATE(rt);
|
||||
|
||||
JSContext* cx = JS_NewContext(rt, 8192);
|
||||
NS_ENSURE_STATE(cx);
|
||||
|
||||
mCx = cx;
|
||||
|
||||
nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
|
||||
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
|
||||
|
||||
PRUint32 stackDummy;
|
||||
jsuword stackLimit, currentStackAddr = (jsuword)&stackDummy;
|
||||
|
||||
// 256k stack space.
|
||||
const jsuword kStackSize = 0x40000;
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION < 0
|
||||
stackLimit = (currentStackAddr > kStackSize) ?
|
||||
currentStackAddr - kStackSize :
|
||||
0;
|
||||
#else
|
||||
stackLimit = (currentStackAddr + kStackSize > currentStackAddr) ?
|
||||
currentStackAddr + kStackSize :
|
||||
(jsuword) -1;
|
||||
#endif
|
||||
|
||||
JS_SetThreadStackLimit(cx, stackLimit);
|
||||
JS_SetScriptStackQuota(cx, 100*1024*1024);
|
||||
|
||||
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_ANONFUNFIX | JSOPTION_PRIVATE_IS_NSISUPPORTS);
|
||||
JS_SetVersion(cx, JSVERSION_LATEST);
|
||||
JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 1 * 1024 * 1024);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
|
||||
/*nsIXPConnect::OMIT_COMPONENTS_OBJECT ? |*/
|
||||
nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
|
||||
|
||||
nsISupports* scopeSupports =
|
||||
NS_ISUPPORTS_CAST(nsPIDOMEventTarget*, this);
|
||||
JS_SetContextPrivate(cx, scopeSupports);
|
||||
|
||||
nsresult rv =
|
||||
xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports,
|
||||
NS_GET_IID(nsISupports), flags,
|
||||
getter_AddRefs(mGlobal));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
JSObject* global = nsnull;
|
||||
rv = mGlobal->GetJSObject(&global);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
JS_SetGlobalObject(cx, global);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL)
|
||||
{
|
||||
if (!mInitialized) {
|
||||
mInitialized = PR_TRUE;
|
||||
Init();
|
||||
}
|
||||
if (!mGlobal || !mCx) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCString url = NS_ConvertUTF16toUTF8(aURL);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
NS_NewChannel(getter_AddRefs(channel), uri);
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> input;
|
||||
channel->Open(getter_AddRefs(input));
|
||||
nsString dataString;
|
||||
if (input) {
|
||||
const PRUint32 bufferSize = 256;
|
||||
char buffer[bufferSize];
|
||||
nsCString data;
|
||||
PRUint32 avail = 0;
|
||||
input->Available(&avail);
|
||||
PRUint32 read = 0;
|
||||
if (avail) {
|
||||
while (NS_SUCCEEDED(input->Read(buffer, bufferSize, &read)) && read) {
|
||||
data.Append(buffer, read);
|
||||
read = 0;
|
||||
}
|
||||
}
|
||||
nsScriptLoader::ConvertToUTF16(channel, (PRUint8*)data.get(), data.Length(),
|
||||
EmptyString(), nsnull, dataString);
|
||||
}
|
||||
|
||||
if (!dataString.IsEmpty()) {
|
||||
JSAutoRequest ar(mCx);
|
||||
jsval retval;
|
||||
JSObject* global = nsnull;
|
||||
mGlobal->GetJSObject(&global);
|
||||
if (!global) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSPrincipals* jsprin = nsnull;
|
||||
mPrincipal->GetJSPrincipals(mCx, &jsprin);
|
||||
nsContentUtils::XPConnect()->FlagSystemFilenamePrefix(url.get(), PR_TRUE);
|
||||
nsContentUtils::ThreadJSContextStack()->Push(mCx);
|
||||
PRBool tmp = mLoadingScript;
|
||||
mLoadingScript = PR_TRUE;
|
||||
JS_EvaluateUCScriptForPrincipals(mCx, global, jsprin,
|
||||
(jschar*)dataString.get(),
|
||||
dataString.Length(),
|
||||
url.get(), 1, &retval);
|
||||
//XXX Argh, JSPrincipals are manually refcounted!
|
||||
JSPRINCIPALS_DROP(mCx, jsprin);
|
||||
mLoadingScript = tmp;
|
||||
JSContext* unused;
|
||||
nsContentUtils::ThreadJSContextStack()->Pop(&unused);
|
||||
}
|
||||
if (!mLoadingScript && mDelayedDisconnect) {
|
||||
mDelayedDisconnect = PR_FALSE;
|
||||
Disconnect();
|
||||
}
|
||||
}
|
142
content/base/src/nsInProcessTabChildGlobal.h
Normal file
142
content/base/src/nsInProcessTabChildGlobal.h
Normal file
@ -0,0 +1,142 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* ***** 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 Content App.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 nsInProcessTabChildGlobal_h
|
||||
#define nsInProcessTabChildGlobal_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsInProcessTabChildGlobal : public nsDOMEventTargetHelper,
|
||||
public nsIInProcessContentFrameMessageManager,
|
||||
public nsIScriptObjectPrincipal,
|
||||
public nsIScriptContextPrincipal
|
||||
{
|
||||
public:
|
||||
nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
|
||||
nsFrameMessageManager* aChrome);
|
||||
virtual ~nsInProcessTabChildGlobal();
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_FORWARD_SAFE_NSIFRAMEMESSAGEMANAGER(mMessageManager)
|
||||
NS_IMETHOD SendSyncMessage()
|
||||
{
|
||||
return mMessageManager ? mMessageManager->SendSyncMessage()
|
||||
: NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent);
|
||||
NS_IMETHOD GetDocShell(nsIDocShell** aDocShell);
|
||||
NS_IMETHOD Dump(const nsAString& aStr)
|
||||
{
|
||||
return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
|
||||
}
|
||||
NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||
nsIDOMEventListener* aListener,
|
||||
PRBool aUseCapture)
|
||||
{
|
||||
// By default add listeners only for trusted events!
|
||||
return nsDOMEventTargetHelper::AddEventListener(aType, aListener,
|
||||
aUseCapture, PR_FALSE, 1);
|
||||
}
|
||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||
nsIDOMEventListener* aListener,
|
||||
PRBool aUseCapture, PRBool aWantsUntrusted,
|
||||
PRUint8 optional_argc)
|
||||
{
|
||||
return nsDOMEventTargetHelper::AddEventListener(aType, aListener,
|
||||
aUseCapture,
|
||||
aWantsUntrusted,
|
||||
optional_argc);
|
||||
}
|
||||
|
||||
virtual nsIScriptObjectPrincipal* GetObjectPrincipal() { return this; }
|
||||
virtual JSContext* GetJSContextForEventHandlers() { return mCx; }
|
||||
virtual nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
||||
void LoadFrameScript(const nsAString& aURL);
|
||||
void Disconnect();
|
||||
void SendMessageToParent(const nsString& aMessage, PRBool aSync,
|
||||
const nsString& aJSON,
|
||||
nsTArray<nsString>* aJSONRetVal);
|
||||
nsFrameMessageManager* GetInnerManager()
|
||||
{
|
||||
return static_cast<nsFrameMessageManager*>(mMessageManager.get());
|
||||
}
|
||||
|
||||
void SetOwner(nsIContent* aOwner) { mOwner = aOwner; }
|
||||
nsFrameMessageManager* GetChromeMessageManager()
|
||||
{
|
||||
return mChromeMessageManager;
|
||||
}
|
||||
void SetChromeMessageManager(nsFrameMessageManager* aParent)
|
||||
{
|
||||
mChromeMessageManager = aParent;
|
||||
}
|
||||
protected:
|
||||
nsresult Init();
|
||||
nsresult InitTabChildGlobal();
|
||||
nsCOMPtr<nsIContentFrameMessageManager> mMessageManager;
|
||||
JSContext* mCx;
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
PRPackedBool mInitialized;
|
||||
PRPackedBool mLoadingScript;
|
||||
PRPackedBool mDelayedDisconnect;
|
||||
public:
|
||||
nsIContent* mOwner;
|
||||
nsFrameMessageManager* mChromeMessageManager;
|
||||
nsCOMArray<nsIRunnable> mASyncMessages;
|
||||
};
|
||||
|
||||
#endif
|
@ -930,7 +930,7 @@ nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const PRUint8* aData,
|
||||
DetectByteOrderMark(aData, aLength, characterSet);
|
||||
}
|
||||
|
||||
if (characterSet.IsEmpty()) {
|
||||
if (characterSet.IsEmpty() && aDocument) {
|
||||
// charset from document default
|
||||
characterSet = aDocument->GetDocumentCharacterSet();
|
||||
}
|
||||
|
@ -55,6 +55,8 @@ _CHROME_FILES = \
|
||||
test_bug467123.xul \
|
||||
test_title.xul \
|
||||
title_window.xul \
|
||||
test_bug549682.xul \
|
||||
file_bug549682.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
45
content/base/test/chrome/file_bug549682.xul
Normal file
45
content/base/test/chrome/file_bug549682.xul
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=549682
|
||||
-->
|
||||
<window title="Mozilla Bug 549682"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="run()">
|
||||
<label value="Mozilla Bug 549682"/>
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var didRunAsync = false;
|
||||
|
||||
function asyncL(m) {
|
||||
didRunAsync = true;
|
||||
opener.wrappedJSObject.is(m.name, "async", "Wrong message!");
|
||||
opener.wrappedJSObject.is(m.json.data, 1234, "Wrong data!");
|
||||
}
|
||||
|
||||
function syncL(m) {
|
||||
opener.wrappedJSObject.is(m.name, "sync", "Wrong message!");
|
||||
opener.wrappedJSObject.is(m.json.data, 1234, "Wrong data!");
|
||||
opener.wrappedJSObject.ok(didRunAsync, "Should have run async!");
|
||||
opener.setTimeout("done()", 0);
|
||||
var i = document.getElementById("ifr");
|
||||
i.parentNode.removeChild(i); // This is a crash test!
|
||||
window.close();
|
||||
}
|
||||
|
||||
function loadScript() {
|
||||
// Async should be prosessed first!
|
||||
messageManager.loadFrameScript("data:,sendAsyncMessage('async', { data: 1234 }); sendSyncMessage('sync', { data: 1234 });", true);
|
||||
}
|
||||
|
||||
function run() {
|
||||
messageManager.addMessageListener("async", asyncL);
|
||||
messageManager.addMessageListener("sync", syncL);
|
||||
setTimeout(loadScript, 0);
|
||||
}
|
||||
|
||||
]]></script>
|
||||
<browser type="content" src="about:blank" id="ifr"/>
|
||||
</window>
|
35
content/base/test/chrome/test_bug549682.xul
Normal file
35
content/base/test/chrome/test_bug549682.xul
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=549682
|
||||
-->
|
||||
<window title="Mozilla Bug 549682"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<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>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=549682"
|
||||
target="_blank">Mozilla Bug 549682</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 549682 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function done() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
window.open("file_bug549682.xul", "", "chrome");
|
||||
});
|
||||
]]></script>
|
||||
</window>
|
@ -49,11 +49,12 @@ class nsIEventListenerManager;
|
||||
class nsIDOMEventListener;
|
||||
class nsIDOMEventGroup;
|
||||
class nsIScriptContext;
|
||||
struct JSContext;
|
||||
|
||||
// e6579895-a23c-4afc-872a-d53da71def5d
|
||||
// 89292f3a-535d-4ba0-882a-10cff9e21bcc
|
||||
#define NS_PIDOMEVENTTARGET_IID \
|
||||
{ 0xe6579895, 0xa23c, 0x4afc, \
|
||||
{ 0x87, 0x2a, 0xd5, 0x3d, 0xa7, 0x1d, 0xef, 0x5d } }
|
||||
{ 0x89292f3a, 0x535d, 0x4ba0, \
|
||||
{ 0x88, 0x2a, 0x10, 0xcf, 0xf9, 0xe2, 0x1b, 0xcc } }
|
||||
|
||||
class nsPIDOMEventTarget : public nsISupports
|
||||
{
|
||||
@ -164,6 +165,12 @@ public:
|
||||
* @note Caller *must* check the value of aRv.
|
||||
*/
|
||||
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv) = 0;
|
||||
|
||||
/**
|
||||
* If the method above returns null, but a success code, this method
|
||||
* is called.
|
||||
*/
|
||||
virtual JSContext* GetJSContextForEventHandlers() { return nsnull; }
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMEventTarget, NS_PIDOMEVENTTARGET_IID)
|
||||
|
@ -469,6 +469,7 @@
|
||||
#include "nsIDOMNSMouseEvent.h"
|
||||
|
||||
#include "nsIEventListenerService.h"
|
||||
#include "nsIFrameMessageManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
@ -550,6 +551,7 @@ static const char kDOMStringBundleURL[] =
|
||||
DOMCI_DATA(Crypto, void)
|
||||
DOMCI_DATA(CRMFObject, void)
|
||||
DOMCI_DATA(SmartCardEvent, void)
|
||||
DOMCI_DATA(ContentFrameMessageManager, void)
|
||||
|
||||
DOMCI_DATA(DOMPrototype, void)
|
||||
DOMCI_DATA(DOMConstructor, void)
|
||||
@ -1383,6 +1385,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(TransitionEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(ContentFrameMessageManager, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(FormData, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
@ -3834,6 +3838,13 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ContentFrameMessageManager, nsIContentFrameMessageManager)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIFrameMessageManager)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIContentFrameMessageManager)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(FormData, nsIDOMFormData)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFormData)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -468,5 +468,6 @@ DOMCI_CLASS(PopStateEvent)
|
||||
DOMCI_CLASS(EventListenerInfo)
|
||||
|
||||
DOMCI_CLASS(TransitionEvent)
|
||||
DOMCI_CLASS(ContentFrameMessageManager)
|
||||
|
||||
DOMCI_CLASS(FormData)
|
||||
|
@ -23,6 +23,22 @@ GetScriptContextFromJSContext(JSContext *cx)
|
||||
return scx;
|
||||
}
|
||||
|
||||
inline nsIScriptContextPrincipal*
|
||||
GetScriptContextPrincipalFromJSContext(JSContext *cx)
|
||||
{
|
||||
if (!(::JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptContextPrincipal> scx =
|
||||
do_QueryInterface(static_cast<nsISupports *>
|
||||
(::JS_GetContextPrivate(cx)));
|
||||
|
||||
// This will return a pointer to something that's about to be
|
||||
// released, but that's ok here.
|
||||
return scx;
|
||||
}
|
||||
|
||||
// A factory function for turning a jsval argv into an nsIArray
|
||||
// but also supports an effecient way of extracting the original argv.
|
||||
// Bug 312003 describes why this must be "void *", but argv will be cast to
|
||||
|
@ -204,6 +204,7 @@
|
||||
|
||||
#include "nsIDragService.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
||||
@ -296,6 +297,17 @@ static PRBool gDOMWindowDumpEnabled = PR_FALSE;
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define FORWARD_TO_INNER_CHROME(method, args, err_rval) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IsOuterWindow()) { \
|
||||
if (!mInnerWindow) { \
|
||||
NS_WARNING("No inner window available!"); \
|
||||
return err_rval; \
|
||||
} \
|
||||
return ((nsGlobalChromeWindow *)mInnerWindow)->method args; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IsInnerWindow()) { \
|
||||
@ -2373,7 +2385,16 @@ nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
aVisitor.mParentTarget = mChromeEventHandler;
|
||||
nsPIDOMEventTarget* chromeTarget = mChromeEventHandler;
|
||||
nsCOMPtr<nsIFrameLoaderOwner> flo = do_QueryInterface(mChromeEventHandler);
|
||||
if (flo) {
|
||||
nsRefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
|
||||
if (fl) {
|
||||
nsPIDOMEventTarget* t = fl->GetTabChildGlobalAsEventTarget();
|
||||
chromeTarget = t ? t : chromeTarget;
|
||||
}
|
||||
}
|
||||
aVisitor.mParentTarget = chromeTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -9376,6 +9397,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||
nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBrowserDOMWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
DOMCI_DATA(ChromeWindow, nsGlobalChromeWindow)
|
||||
@ -9608,6 +9630,28 @@ nsGlobalChromeWindow::NotifyDefaultButtonLoaded(nsIDOMElement* aDefaultButton)
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::GetMessageManager(nsIChromeFrameMessageManager** aManager)
|
||||
{
|
||||
FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_FAILURE);
|
||||
if (!mMessageManager) {
|
||||
nsIScriptContext* scx = GetContextInternal();
|
||||
NS_ENSURE_STATE(scx);
|
||||
JSContext* cx = (JSContext *)scx->GetNativeContext();
|
||||
NS_ENSURE_STATE(cx);
|
||||
mMessageManager = new nsFrameMessageManager(PR_TRUE,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
cx);
|
||||
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
NS_ADDREF(*aManager = mMessageManager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsGlobalModalWindow implementation
|
||||
|
||||
// QueryInterface implementation for nsGlobalModalWindow
|
||||
|
@ -101,6 +101,7 @@
|
||||
#include "nsPIDOMEventTarget.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
|
||||
#define DEFAULT_HOME_PAGE "www.mozilla.org"
|
||||
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
|
||||
@ -858,6 +859,7 @@ public:
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
nsCOMPtr<nsIChromeFrameMessageManager> mMessageManager;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -53,9 +53,25 @@ class nsIVariant;
|
||||
class nsIObjectInputStream;
|
||||
class nsIObjectOutputStream;
|
||||
class nsScriptObjectHolder;
|
||||
class nsIScriptObjectPrincipal;
|
||||
|
||||
typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
|
||||
|
||||
#define NS_ISCRIPTCONTEXTPRINCIPAL_IID \
|
||||
{ 0xd012cdb3, 0x8f1e, 0x4440, \
|
||||
{ 0x8c, 0xbd, 0x32, 0x7f, 0x98, 0x1d, 0x37, 0xb4 } }
|
||||
|
||||
class nsIScriptContextPrincipal : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXTPRINCIPAL_IID)
|
||||
|
||||
virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
|
||||
NS_ISCRIPTCONTEXTPRINCIPAL_IID)
|
||||
|
||||
// A4FE2B52-62B5-40C3-BF9C-5E0A27B10F90
|
||||
#define NS_ISCRIPTCONTEXT_IID \
|
||||
{ 0xA4FE2B52, 0x62B5, 0x40C3, \
|
||||
@ -72,7 +88,7 @@ typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
|
||||
* should be removed in a short time. Ideally this interface will be
|
||||
* language neutral</I>
|
||||
*/
|
||||
class nsIScriptContext : public nsISupports
|
||||
class nsIScriptContext : public nsIScriptContextPrincipal
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXT_IID)
|
||||
|
@ -1480,6 +1480,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSContext)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScriptContext)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXPCScriptNotify)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptContext)
|
||||
NS_INTERFACE_MAP_END
|
||||
@ -1668,6 +1669,13 @@ JSValueToAString(JSContext *cx, jsval val, nsAString *result,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIScriptObjectPrincipal*
|
||||
nsJSContext::GetObjectPrincipal()
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> prin = do_QueryInterface(GetGlobalObject());
|
||||
return prin;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSContext::EvaluateString(const nsAString& aScript,
|
||||
void *aScopeObject,
|
||||
|
@ -65,6 +65,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext,
|
||||
nsIScriptContext)
|
||||
|
||||
virtual nsIScriptObjectPrincipal* GetObjectPrincipal();
|
||||
|
||||
virtual PRUint32 GetScriptTypeID()
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
||||
|
@ -40,8 +40,9 @@
|
||||
|
||||
interface nsIBrowserDOMWindow;
|
||||
interface nsIDOMElement;
|
||||
interface nsIChromeFrameMessageManager;
|
||||
|
||||
[scriptable, uuid(09b86cbd-9784-4fe4-9be6-70b9bbca3a9c)]
|
||||
[scriptable, uuid(adf6b19f-459f-4892-93eb-71c527bae2af)]
|
||||
interface nsIDOMChromeWindow : nsISupports
|
||||
{
|
||||
const unsigned short STATE_MAXIMIZED = 1;
|
||||
@ -73,4 +74,6 @@ interface nsIDOMChromeWindow : nsISupports
|
||||
* defaultButton is the default button.
|
||||
*/
|
||||
void notifyDefaultButtonLoaded(in nsIDOMElement defaultButton);
|
||||
|
||||
readonly attribute nsIChromeFrameMessageManager messageManager;
|
||||
};
|
||||
|
@ -123,11 +123,10 @@ XPCJSContextStack::Pop(JSContext * *_retval)
|
||||
static nsIPrincipal*
|
||||
GetPrincipalFromCx(JSContext *cx)
|
||||
{
|
||||
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
|
||||
if(scriptContext)
|
||||
nsIScriptContextPrincipal* scp = GetScriptContextPrincipalFromJSContext(cx);
|
||||
if(scp)
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> globalData =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
nsIScriptObjectPrincipal* globalData = scp->GetObjectPrincipal();
|
||||
if(globalData)
|
||||
return globalData->GetPrincipal();
|
||||
}
|
||||
|
@ -96,6 +96,7 @@
|
||||
#include "nsObjectFrame.h"
|
||||
#include "nsTransitionManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIFrameMessageManager.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILAnimationController.h"
|
||||
@ -2052,7 +2053,22 @@ MayHavePaintEventListener(nsPIDOMWindow* aInnerWindow)
|
||||
if (!chromeEventHandler)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(chromeEventHandler);
|
||||
nsIEventListenerManager* manager = nsnull;
|
||||
nsCOMPtr<nsINode> node;
|
||||
nsCOMPtr<nsIInProcessContentFrameMessageManager> mm =
|
||||
do_QueryInterface(chromeEventHandler);
|
||||
if (mm) {
|
||||
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(mm);
|
||||
if (target && (manager = target->GetListenerManager(PR_FALSE)) &&
|
||||
manager->MayHavePaintEventListener()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
node = mm->GetOwnerContent();
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
node = do_QueryInterface(chromeEventHandler);
|
||||
}
|
||||
if (node)
|
||||
return MayHavePaintEventListener(node->GetOwnerDoc()->GetInnerWindow());
|
||||
|
||||
@ -2060,7 +2076,7 @@ MayHavePaintEventListener(nsPIDOMWindow* aInnerWindow)
|
||||
if (window)
|
||||
return MayHavePaintEventListener(window);
|
||||
|
||||
nsIEventListenerManager* manager =
|
||||
manager =
|
||||
chromeEventHandler->GetListenerManager(PR_FALSE);
|
||||
if (manager && manager->MayHavePaintEventListener())
|
||||
return PR_TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user