Landing the split window work, bug 296639. This change doesn't have full reviews yet, bzbarsky@mit.edu and shaver@mozilla.org have done partial reviews, but there's still more to look at. Given the current time constraint this is landed with reviews and followup changes that result to come after the initial checkin. a=drivers

This commit is contained in:
jst%mozilla.jstenback.com 2005-07-30 20:57:07 +00:00
Родитель a5ccd68271
Коммит 9700a6e483
53 изменённых файлов: 2070 добавлений и 706 удалений

Просмотреть файл

@ -461,9 +461,10 @@ public:
virtual nsIHTMLCSSStyleSheet* GetInlineStyleSheet() const = 0;
/**
* Set the object from which a document can get a script context.
* This is the context within which all scripts (during document
* creation and during event handling) will run.
* Get/set the object from which a document can get a script context
* and scope. This is the context within which all scripts (during
* document creation and during event handling) will run. Note that
* this is the *inner* window object.
*/
virtual nsIScriptGlobalObject* GetScriptGlobalObject() const = 0;
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;

Просмотреть файл

@ -96,6 +96,7 @@
#include "nsIPrivateDOMImplementation.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMElement.h"
#include "nsIBoxObject.h"
@ -2914,11 +2915,19 @@ nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
NS_IMETHODIMP
nsDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView)
{
if (mScriptGlobalObject) {
return CallQueryInterface(mScriptGlobalObject, aDefaultView);
*aDefaultView = nsnull;
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mScriptGlobalObject));
if (win) {
// The default view is our outer window.
if (!win->IsInnerWindow()) {
return NS_ERROR_UNEXPECTED;
}
return CallQueryInterface(win->GetOuterWindow(), aDefaultView);
}
*aDefaultView = nsnull;
return NS_OK;
}

Просмотреть файл

@ -172,7 +172,6 @@ public:
protected:
PRInt32 mLength;
nsIDocument* mDocument;
void* mScriptObject;
};
class nsOnloadBlocker : public nsIRequest
@ -616,7 +615,12 @@ protected:
// Basically always has at least 1 entry
nsAutoVoidArray mObservers;
// The document's script global object, the object from which the
// document can get its script context and scope. This is the
// *inner* window object.
nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
nsCOMPtr<nsIEventListenerManager> mListenerManager;
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
nsCOMPtr<nsIScriptLoader> mScriptLoader;

Просмотреть файл

@ -749,9 +749,9 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
mCurrentScript = aRequest->mElement;
PRBool isUndefined;
context->EvaluateString(aScript, nsnull, principal, url.get(),
aRequest->mLineNo, aRequest->mJSVersion, nsnull,
&isUndefined);
context->EvaluateString(aScript, globalObject->GetGlobalJSObject(),
principal, url.get(), aRequest->mLineNo,
aRequest->mJSVersion, nsnull, &isUndefined);
// Put the old script back in case it wants to do anything else.
mCurrentScript = oldCurrent;

Просмотреть файл

@ -48,6 +48,7 @@ class nsIScriptContext;
class nsIDOMEventTarget;
class nsIDOMEventGroup;
class nsIAtom;
struct JSObject;
/*
* Event listener manager interface.
@ -115,6 +116,7 @@ public:
* @param the name of an event listener
*/
NS_IMETHOD RegisterScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom* aName) = 0;
@ -123,6 +125,7 @@ public:
* script object for a given event type.
* @param an event listener */
NS_IMETHOD CompileScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom* aName,
PRBool *aDidCompile) = 0;

Просмотреть файл

@ -88,7 +88,6 @@
#include "nsIPresShell.h"
#include "nsMutationEvent.h"
#include "nsIXPConnect.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsDOMCID.h"
#include "nsIScriptObjectOwner.h" // for nsIScriptEventHandlerOwner
#include "nsIClassInfo.h"
@ -1102,7 +1101,8 @@ nsEventListenerManager::FindJSEventListener(EventArrayType aType)
}
nsresult
nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom* aName,
PRBool aIsString,
@ -1121,13 +1121,9 @@ nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
if (nsnull == ls) {
// If we didn't find a script listener or no listeners existed
// create and add a new one.
nsCOMPtr<nsIDOMScriptObjectFactory> factory =
do_GetService(kDOMScriptObjectFactoryCID);
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMEventListener> scriptListener;
rv = factory->NewJSEventListener(aContext, aObject,
getter_AddRefs(scriptListener));
rv = NS_NewJSEventListener(aContext, aScopeObject, aObject,
getter_AddRefs(scriptListener));
if (NS_SUCCEEDED(rv)) {
AddEventListener(scriptListener, arrayType, NS_EVENT_BITS_NONE, nsnull,
NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT, nsnull);
@ -1172,6 +1168,8 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
nsISupports *objiSupp = aObject;
JSObject *scope = nsnull;
if (content) {
// Try to get context from doc
doc = content->GetOwnerDoc();
@ -1179,6 +1177,7 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
if (doc && (global = doc->GetScriptGlobalObject())) {
context = global->GetContext();
scope = global->GetGlobalJSObject();
}
} else {
nsCOMPtr<nsIDOMWindow> win(do_QueryInterface(aObject));
@ -1199,11 +1198,13 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
}
if (global) {
context = global->GetContext();
scope = global->GetGlobalJSObject();
}
}
if (!context) {
// Get JSContext from stack.
// Get JSContext from stack, or use the safe context (and hidden
// window global) if no JS is running.
nsCOMPtr<nsIThreadJSContextStack> stack =
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE);
@ -1216,6 +1217,13 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
context = nsJSUtils::GetDynamicScriptContext(cx);
NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
scope = ::JS_GetGlobalObject(cx);
} else if (!scope) {
NS_ERROR("Context reachable, but no scope reachable in "
"AddScriptEventListener()!");
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv;
@ -1224,8 +1232,7 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
JSContext *cx = (JSContext *)context->GetNativeContext();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = nsContentUtils::XPConnect()->WrapNative(cx, ::JS_GetGlobalObject(cx),
aObject,
rv = nsContentUtils::XPConnect()->WrapNative(cx, scope, aObject,
NS_GET_IID(nsISupports),
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
@ -1297,7 +1304,7 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
}
}
return SetJSEventListener(context, objiSupp, aName, aDeferCompilation,
return SetJSEventListener(context, scope, objiSupp, aName, aDeferCompilation,
aPermitUntrustedEvents);
}
@ -1335,6 +1342,7 @@ nsEventListenerManager::sAddListenerID = JSVAL_VOID;
NS_IMETHODIMP
nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom *aName)
{
@ -1357,8 +1365,8 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = nsContentUtils::XPConnect()->
WrapNative(current_cx, ::JS_GetGlobalObject(current_cx), aObject,
NS_GET_IID(nsISupports), getter_AddRefs(holder));
WrapNative(current_cx, aScopeObject, aObject, NS_GET_IID(nsISupports),
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
// Since JSEventListeners only have a raw nsISupports pointer, it's
@ -1372,11 +1380,11 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
rv = holder->GetJSObject(&jsobj);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aObject);
if (sAddListenerID == JSVAL_VOID && cx) {
sAddListenerID =
STRING_TO_JSVAL(::JS_InternString(cx, "addEventListener"));
if (cx) {
if (sAddListenerID == JSVAL_VOID) {
sAddListenerID =
STRING_TO_JSVAL(::JS_InternString(cx, "addEventListener"));
}
rv = nsContentUtils::GetSecurityManager()->
CheckPropertyAccess(cx, jsobj,
@ -1391,12 +1399,13 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
// Untrusted events are always permitted for non-chrome script
// handlers.
return SetJSEventListener(aContext, wrapper->Native(), aName, PR_FALSE,
!nsContentUtils::IsCallerChrome());
return SetJSEventListener(aContext, aScopeObject, wrapper->Native(), aName,
PR_FALSE, !nsContentUtils::IsCallerChrome());
}
nsresult
nsEventListenerManager::CompileScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom *aName,
PRBool *aDidCompile)
@ -1419,7 +1428,8 @@ nsEventListenerManager::CompileScriptEventListener(nsIScriptContext *aContext,
}
if (ls->mHandlerIsString & subType) {
rv = CompileEventHandlerInternal(aContext, aObject, aName, ls, /*XXX fixme*/nsnull, subType);
rv = CompileEventHandlerInternal(aContext, aScopeObject, aObject, aName,
ls, /*XXX fixme*/nsnull, subType);
}
// Set *aDidCompile to true even if we didn't really compile
@ -1434,6 +1444,7 @@ nsEventListenerManager::CompileScriptEventListener(nsIScriptContext *aContext,
nsresult
nsEventListenerManager::CompileEventHandlerInternal(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom *aName,
nsListenerStruct *aListenerStruct,
@ -1445,9 +1456,7 @@ nsEventListenerManager::CompileEventHandlerInternal(nsIScriptContext *aContext,
JSContext *cx = (JSContext *)aContext->GetNativeContext();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
result = nsContentUtils::XPConnect()->WrapNative(cx,
::JS_GetGlobalObject(cx),
aObject,
result = nsContentUtils::XPConnect()->WrapNative(cx, aScopeObject, aObject,
NS_GET_IID(nsISupports),
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(result, result);
@ -1561,6 +1570,7 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + eventString);
result = CompileEventHandlerInternal(jslistener->GetEventContext(),
jslistener->GetEventScope(),
jslistener->GetEventTarget(),
atom, aListenerStruct,
aCurrentTarget,
@ -2141,7 +2151,7 @@ nsEventListenerManager::FixContextMenuEvent(nsPresContext* aPresContext,
currentTarget = do_QueryInterface(currentFocus);
nsCOMPtr<nsIPrivateDOMEvent> pEvent(do_QueryInterface(*aDOMEvent));
pEvent->SetTarget (currentTarget);
pEvent->SetTarget(currentTarget);
}
}

Просмотреть файл

@ -130,10 +130,12 @@ public:
PRBool aDeferCompilation,
PRBool aPermitUntrustedEvents);
NS_IMETHOD RegisterScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom* aName);
NS_IMETHOD RemoveScriptEventListener(nsIAtom *aName);
NS_IMETHOD CompileScriptEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom* aName, PRBool *aDidCompile);
@ -195,6 +197,7 @@ protected:
PRUint32 aSubType,
PRUint32 aPhaseFlags);
nsresult CompileEventHandlerInternal(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject,
nsIAtom *aName,
nsListenerStruct *aListenerStruct,
@ -202,8 +205,9 @@ protected:
PRUint32 aSubType);
nsListenerStruct* FindJSEventListener(EventArrayType aType);
nsresult SetJSEventListener(nsIScriptContext *aContext,
nsISupports *aObject, nsIAtom* aName,
PRBool aIsString, PRBool aPermitUntrustedEvents);
JSObject *aScopeObject, nsISupports *aObject,
nsIAtom* aName, PRBool aIsString,
PRBool aPermitUntrustedEvents);
nsresult AddEventListener(nsIDOMEventListener *aListener,
EventArrayType aType,
PRInt32 aSubType,

Просмотреть файл

@ -167,6 +167,43 @@ enum {
MOUSE_SCROLL_TEXTSIZE
};
static nsIScriptGlobalObject *
GetDocumentOuterWindow(nsIDocument *aDocument)
{
if (aDocument) {
nsIScriptGlobalObject *sgo = aDocument->GetScriptGlobalObject();
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(sgo);
if (win) {
nsCOMPtr<nsIScriptGlobalObject> outersgo =
do_QueryInterface(win->GetOuterWindow());
return outersgo;
}
return sgo;
}
return nsnull;
}
static nsIDocument *
GetInnerDocument(nsISupports *aWindow)
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aWindow);
nsPIDOMWindow *innerWin;
nsIDocument *doc = nsnull;
if (win && (innerWin = win->GetCurrentInnerWindow())) {
nsCOMPtr<nsIDocument> tmp =
do_QueryInterface(innerWin->GetExtantDocument());
doc = tmp;
}
return doc;
}
/******************************************************************/
/* nsEventStateManager */
/******************************************************************/
@ -514,7 +551,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
if (mDocument) {
if (gLastFocusedDocument && gLastFocusedPresContext) {
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(gLastFocusedDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> ourWindow =
do_QueryInterface(GetDocumentOuterWindow(gLastFocusedDocument));
// If the focus controller is already suppressed, it means that we
// are in the middle of an activate sequence. In this case, we do
@ -594,7 +632,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// then the content node, then the window.
nsCOMPtr<nsIScriptGlobalObject> globalObject =
mDocument->GetScriptGlobalObject();
GetDocumentOuterWindow(mDocument);
if (globalObject) {
// We don't want there to be a focused content node while we're
@ -628,12 +666,14 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
if (gLastFocusedDocument && gLastFocusedDocument != mDocument) {
nsIFocusController *lastController = nsnull;
nsCOMPtr<nsPIDOMWindow> lastWindow = do_QueryInterface(gLastFocusedDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> lastWindow =
do_QueryInterface(GetDocumentOuterWindow(gLastFocusedDocument));
if (lastWindow)
lastController = lastWindow->GetRootFocusController();
nsIFocusController *nextController = nsnull;
nsCOMPtr<nsPIDOMWindow> nextWindow = do_QueryInterface(mDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> nextWindow =
do_QueryInterface(GetDocumentOuterWindow(mDocument));
if (nextWindow)
nextController = nextWindow->GetRootFocusController();
@ -680,15 +720,17 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
if (gLastFocusedContent) {
nsIDocument* doc = gLastFocusedContent->GetDocument();
if (doc)
ourGlobal = doc->GetScriptGlobalObject();
else {
ourGlobal = mDocument->GetScriptGlobalObject();
if (doc) {
ourGlobal = GetDocumentOuterWindow(doc);
} else {
ourGlobal = GetDocumentOuterWindow(mDocument);
NS_RELEASE(gLastFocusedContent);
}
}
else
ourGlobal = mDocument->GetScriptGlobalObject();
else {
ourGlobal = GetDocumentOuterWindow(mDocument);
}
// Now fire blurs. We fire a blur on the focused document, element,
// and window.
@ -724,7 +766,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// get the window here, in case the event causes
// gLastFocusedDocument to change.
nsCOMPtr<nsIScriptGlobalObject> globalObject = gLastFocusedDocument->GetScriptGlobalObject();
nsCOMPtr<nsIScriptGlobalObject> globalObject =
GetDocumentOuterWindow(gLastFocusedDocument);
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext,
&event, nsnull,
@ -754,7 +797,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
EnsureDocument(aPresContext);
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mDocument->GetScriptGlobalObject()));
nsCOMPtr<nsPIDOMWindow> win =
do_QueryInterface(GetDocumentOuterWindow(mDocument));
if (!win) {
NS_ERROR("win is null. this happens [often on xlib builds]. see bug #79213");
@ -763,7 +807,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// Hold a strong ref to the focus controller, since we need
// it after event dispatch.
nsCOMPtr<nsIFocusController> focusController = win->GetRootFocusController();
nsCOMPtr<nsIFocusController> focusController =
win->GetRootFocusController();
nsCOMPtr<nsIDOMElement> focusedElement;
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
@ -785,11 +830,9 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
if (focusedWindow) {
focusedWindow->Focus();
nsCOMPtr<nsIDOMDocument> domDoc;
focusedWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> document = GetInnerDocument(focusedWindow);
if (domDoc) {
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
if (document) {
nsIPresShell *shell = document->GetShellAt(0);
NS_ASSERTION(shell, "Focus events should not be getting thru when this is null!");
if (shell) {
@ -833,7 +876,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
{
EnsureDocument(aPresContext);
nsCOMPtr<nsIScriptGlobalObject> ourGlobal = mDocument->GetScriptGlobalObject();
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
GetDocumentOuterWindow(mDocument);
// Suppress the focus controller for the duration of the
// de-activation. This will cause it to remember the last
@ -1582,21 +1626,18 @@ nsEventStateManager::ChangeTextSize(PRInt32 change)
{
if(!gLastFocusedDocument) return NS_ERROR_FAILURE;
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(gLastFocusedDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> ourWindow =
do_QueryInterface(GetDocumentOuterWindow(gLastFocusedDocument));
if(!ourWindow) return NS_ERROR_FAILURE;
nsIDOMWindowInternal *rootWindow = ourWindow->GetPrivateRoot();
if(!rootWindow) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMWindow> windowContent;
rootWindow->GetContent(getter_AddRefs(windowContent));
if(!windowContent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMWindow> contentWindow;
rootWindow->GetContent(getter_AddRefs(contentWindow));
if(!contentWindow) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMDocument> domDoc;
windowContent->GetDocument(getter_AddRefs(domDoc));
if(!domDoc) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
nsIDocument *doc = GetInnerDocument(contentWindow);
if(!doc) return NS_ERROR_FAILURE;
nsIPresShell *presShell = doc->GetShellAt(0);
@ -3101,7 +3142,8 @@ PrintDocTree(nsIDocShellTreeNode * aParentNode, int aLevel)
parentAsDocShell->GetPresContext(getter_AddRefs(presContext));
nsIDocument *doc = presShell->GetDocument();
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(doc->GetScriptGlobalObject()));
nsCOMPtr<nsIDOMWindowInternal> domwin =
do_QueryInterface(GetDocumentOuterWindow(doc));
nsCOMPtr<nsIWidget> widget;
nsIViewManager* vm = presShell->GetViewManager();
@ -4066,9 +4108,9 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
nsIFocusController *newFocusController = nsnull;
nsIFocusController *oldFocusController = nsnull;
nsCOMPtr<nsPIDOMWindow> newWindow =
do_QueryInterface(mDocument->GetScriptGlobalObject());
do_QueryInterface(GetDocumentOuterWindow(mDocument));
nsCOMPtr<nsPIDOMWindow> oldWindow =
do_QueryInterface(gLastFocusedDocument->GetScriptGlobalObject());
do_QueryInterface(GetDocumentOuterWindow(gLastFocusedDocument));
if(newWindow)
newFocusController = newWindow->GetRootFocusController();
if(oldWindow)
@ -4108,7 +4150,7 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
nsCOMPtr<nsIScriptGlobalObject> globalObject;
if(gLastFocusedDocument)
globalObject = gLastFocusedDocument->GetScriptGlobalObject();
globalObject = GetDocumentOuterWindow(gLastFocusedDocument);
EnsureDocument(presShell);
@ -4121,8 +4163,10 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
if (mDocument) {
nsIFocusController *newFocusController = nsnull;
nsIFocusController *oldFocusController = nsnull;
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(mDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(gLastFocusedDocument->GetScriptGlobalObject());
nsCOMPtr<nsPIDOMWindow> newWindow =
do_QueryInterface(GetDocumentOuterWindow(mDocument));
nsCOMPtr<nsPIDOMWindow> oldWindow =
do_QueryInterface(GetDocumentOuterWindow(gLastFocusedDocument));
if (newWindow)
newFocusController = newWindow->GetRootFocusController();

Просмотреть файл

@ -3437,9 +3437,15 @@ nsGenericHTMLFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
mFrameLoader->GetDocShell(getter_AddRefs(doc_shell));
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(doc_shell));
win.swap(*aContentWindow);
nsCOMPtr<nsPIDOMWindow> piwin(do_QueryInterface(win));
return NS_OK;
if (piwin && piwin->IsInnerWindow()) {
// We got an inner window here somehow, this just should not happen.
return NS_ERROR_UNEXPECTED;
}
return CallQueryInterface(piwin->GetOuterWindow(), aContentWindow);
}
nsresult

Просмотреть файл

@ -207,12 +207,13 @@ nsHTMLScriptEventHandler::Invoke(nsISupports *aTargetObject,
// Get the script context...
nsCOMPtr<nsIDOMDocument> domdoc;
nsCOMPtr<nsIScriptContext> scriptContext;
nsIScriptGlobalObject *sgo;
mOuter->GetOwnerDocument(getter_AddRefs(domdoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
if (doc) {
nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
sgo = doc->GetScriptGlobalObject();
if (sgo) {
scriptContext = sgo->GetContext();
}
@ -227,7 +228,7 @@ nsHTMLScriptEventHandler::Invoke(nsISupports *aTargetObject,
JSObject *scriptObject = nsnull;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsContentUtils::XPConnect()->WrapNative(cx, ::JS_GetGlobalObject(cx),
nsContentUtils::XPConnect()->WrapNative(cx, sgo->GetGlobalJSObject(),
aTargetObject,
NS_GET_IID(nsISupports),
getter_AddRefs(holder));

Просмотреть файл

@ -988,7 +988,7 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
xpConnect->GetWrappedNativeOfNativeObject(jscontext,
JS_GetGlobalObject(jscontext),
global->GetGlobalJSObject(),
aContent,
NS_GET_IID(nsISupports),
getter_AddRefs(wrapper));

Просмотреть файл

@ -879,7 +879,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
nsresult rv = nsContentUtils::XPConnect()->
WrapNative(jscontext, ::JS_GetGlobalObject(jscontext),
WrapNative(jscontext, global->GetGlobalJSObject(),
mBoundElement, NS_GET_IID(nsISupports),
getter_AddRefs(wrapper));
if (NS_FAILED(rv))
@ -1113,11 +1113,18 @@ nsXBLBinding::InitClass(const nsCString& aClassName,
// Obtain the bound element's current script object.
JSContext* cx = (JSContext*)aContext->GetNativeContext();
nsIDocument *ownerDoc = mBoundElement->GetOwnerDoc();
nsIScriptGlobalObject *sgo;
if (!ownerDoc || !(sgo = ownerDoc->GetScriptGlobalObject())) {
NS_ERROR("Can't find global object for bound content!");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
JSObject* global = ::JS_GetGlobalObject(cx);
rv = nsContentUtils::XPConnect()->WrapNative(cx, global, mBoundElement,
rv = nsContentUtils::XPConnect()->WrapNative(cx, sgo->GetGlobalJSObject(),
mBoundElement,
NS_GET_IID(nsISupports),
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
@ -1130,7 +1137,8 @@ nsXBLBinding::InitClass(const nsCString& aClassName,
// First ensure our JS class is initialized.
rv = DoInitJSClass(cx, global, object, aClassName, aClassObject);
rv = DoInitJSClass(cx, sgo->GetGlobalJSObject(), object, aClassName,
aClassObject);
NS_ENSURE_SUCCESS(rv, rv);
// Root mBoundElement so that it doesn't lose it's binding

Просмотреть файл

@ -82,6 +82,7 @@ public:
virtual JSObject *GetGlobalJSObject();
virtual void OnFinalize(JSObject *aObject);
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
virtual nsresult SetNewArguments(JSObject *aArguments);
// nsIScriptObjectPrincipal methods
virtual nsIPrincipal* GetPrincipal();
@ -305,6 +306,12 @@ nsXBLDocGlobalObject::SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts)
// We don't care...
}
nsresult
nsXBLDocGlobalObject::SetNewArguments(JSObject *aArguments)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
//----------------------------------------------------------------------
//

Просмотреть файл

@ -114,10 +114,19 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
return NS_OK; // This can be ok, if all we've got are fields (and no methods/properties).
}
nsIDocument *ownerDoc = aBoundElement->GetOwnerDoc();
nsIScriptGlobalObject *sgo;
if (!ownerDoc || !(sgo = ownerDoc->GetScriptGlobalObject())) {
NS_ERROR("Can't find global object for bound content!");
return NS_ERROR_UNEXPECTED;
}
// Because our prototype implementation has a class, we need to build up a corresponding
// class for the concrete implementation in the bound document.
JSContext* jscontext = (JSContext*)aContext->GetNativeContext();
JSObject* global = ::JS_GetGlobalObject(jscontext);
JSObject* global = sgo->GetGlobalJSObject();
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = nsContentUtils::XPConnect()->WrapNative(jscontext, global,
aBoundElement,
@ -165,7 +174,9 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding)
NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY);
void* classObject;
nsresult rv = aBinding->InitClass(mClassName, context, nsnull, &classObject);
nsresult rv = aBinding->InitClass(mClassName, context,
globalObject->GetGlobalJSObject(),
&classObject);
if (NS_FAILED(rv))
return rv;

Просмотреть файл

@ -135,13 +135,23 @@ nsXBLProtoImplMethod::InstallMember(nsIScriptContext* aContext,
NS_PRECONDITION(mIsCompiled,
"Should not be installing an uncompiled method");
JSContext* cx = (JSContext*) aContext->GetNativeContext();
nsIDocument *ownerDoc = aBoundElement->GetOwnerDoc();
nsIScriptGlobalObject *sgo;
if (!ownerDoc || !(sgo = ownerDoc->GetScriptGlobalObject())) {
NS_ERROR("Can't find global object for bound content!");
return NS_ERROR_UNEXPECTED;
}
JSObject * scriptObject = (JSObject *) aScriptObject;
NS_ASSERTION(scriptObject, "uh-oh, script Object should NOT be null or bad things will happen");
if (!scriptObject)
return NS_ERROR_FAILURE;
JSObject * targetClassObject = (JSObject *) aTargetClassObject;
JSObject * globalObject = ::JS_GetGlobalObject(cx);
JSObject * globalObject = sgo->GetGlobalJSObject();
// now we want to reevaluate our property using aContext and the script object for this window...
if (mJSMethodObject && targetClassObject) {
@ -290,7 +300,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement)
JSContext* cx = (JSContext*) context->GetNativeContext();
JSObject* globalObject = ::JS_GetGlobalObject(cx);
JSObject* globalObject = global->GetGlobalJSObject();
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
nsresult rv =

Просмотреть файл

@ -40,11 +40,13 @@
#include "nsString.h"
#include "jsapi.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsString.h"
#include "nsXBLProtoImplProperty.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
MOZ_DECL_CTOR_COUNTER(nsXBLProtoImplProperty)
@ -170,13 +172,23 @@ nsXBLProtoImplProperty::InstallMember(nsIScriptContext* aContext,
NS_PRECONDITION(mIsCompiled,
"Should not be installing an uncompiled property");
JSContext* cx = (JSContext*) aContext->GetNativeContext();
nsIDocument *ownerDoc = aBoundElement->GetOwnerDoc();
nsIScriptGlobalObject *sgo;
if (!ownerDoc || !(sgo = ownerDoc->GetScriptGlobalObject())) {
NS_ERROR("Can't find global object for bound content!");
return NS_ERROR_UNEXPECTED;
}
JSObject * scriptObject = (JSObject *) aScriptObject;
NS_ASSERTION(scriptObject, "uh-oh, script Object should NOT be null or bad things will happen");
if (!scriptObject)
return NS_ERROR_FAILURE;
JSObject * targetClassObject = (JSObject *) aTargetClassObject;
JSObject * globalObject = ::JS_GetGlobalObject(cx);
JSObject * globalObject = sgo->GetGlobalJSObject();
// now we want to reevaluate our property using aContext and the script object for this window...
if ((mJSGetterObject || mJSSetterObject) && targetClassObject) {

Просмотреть файл

@ -743,9 +743,14 @@ nsXBLPrototypeBinding::InitClass(const nsCString& aClassName,
JSContext* cx = (JSContext*)aContext->GetNativeContext();
JSObject* scriptObject = (JSObject*) aScriptObject;
JSObject* tmp, *global = scriptObject;
return nsXBLBinding::DoInitJSClass(cx, ::JS_GetGlobalObject(cx),
scriptObject, aClassName, aClassObject);
while ((tmp = ::JS_GetParent(cx, global))) {
global = tmp;
}
return nsXBLBinding::DoInitJSClass(cx, global, scriptObject, aClassName,
aClassObject);
}
nsIContent*

Просмотреть файл

@ -405,6 +405,11 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
// that.
if (focusedWin) {
nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(focusedWin));
if (piWin && piWin->GetCurrentInnerWindow()) {
piWin = piWin->GetCurrentInnerWindow();
}
boundGlobal = do_QueryInterface(piWin->GetPrivateRoot());
}
else boundGlobal = do_QueryInterface(aReceiver);
@ -481,15 +486,9 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
boundContext->BindCompiledEventHandler(scriptObject, onEventAtom, handler);
// Execute it.
nsCOMPtr<nsIDOMScriptObjectFactory> factory =
do_GetService(kDOMScriptObjectFactoryCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMEventListener> eventListener;
rv = factory->NewJSEventListener(boundContext, aReceiver,
getter_AddRefs(eventListener));
NS_ENSURE_SUCCESS(rv, rv);
NS_NewJSEventListener(boundContext, boundGlobal->GetGlobalJSObject(),
aReceiver, getter_AddRefs(eventListener));
nsCOMPtr<nsIJSEventListener> jsListener(do_QueryInterface(eventListener));
jsListener->SetEventName(onEventAtom);

Просмотреть файл

@ -51,7 +51,6 @@
#include "nsIServiceManager.h"
#include "nsHTMLAtoms.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMElement.h"
#include "nsXBLAtoms.h"
#include "nsINativeKeyBindings.h"

Просмотреть файл

@ -3505,7 +3505,9 @@ nsXULDocument::ExecuteScript(JSObject* aScriptObject)
nsCOMPtr<nsIScriptContext> context;
if (mScriptGlobalObject && (context = mScriptGlobalObject->GetContext()))
rv = context->ExecuteScript(aScriptObject, nsnull, nsnull, nsnull);
rv = context->ExecuteScript(aScriptObject,
mScriptGlobalObject->GetGlobalJSObject(),
nsnull, nsnull);
return rv;
}

Просмотреть файл

@ -104,6 +104,7 @@ public:
virtual JSObject *GetGlobalJSObject();
virtual void OnFinalize(JSObject *aObject);
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
virtual nsresult SetNewArguments(JSObject *aArguments);
// nsIScriptObjectPrincipal methods
virtual nsIPrincipal* GetPrincipal();
@ -932,6 +933,12 @@ nsXULPDGlobalObject::SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts)
// We don't care...
}
nsresult
nsXULPDGlobalObject::SetNewArguments(JSObject *aArguments)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
//----------------------------------------------------------------------
//

Просмотреть файл

@ -862,6 +862,8 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
if (! global)
return NS_ERROR_UNEXPECTED;
JSObject *scope = global->GetGlobalJSObject();
nsIScriptContext *context = global->GetContext();
if (! context)
return NS_ERROR_UNEXPECTED;
@ -876,8 +878,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
JSObject* jselement = nsnull;
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext, ::JS_GetGlobalObject(jscontext), mRoot,
NS_GET_IID(nsIDOMElement),
rv = xpc->WrapNative(jscontext, scope, mRoot, NS_GET_IID(nsIDOMElement),
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
@ -886,7 +887,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
{
// database
rv = xpc->WrapNative(jscontext, ::JS_GetGlobalObject(jscontext), mDB,
rv = xpc->WrapNative(jscontext, scope, mDB,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -7815,7 +7815,7 @@ NS_IMETHODIMP nsDocShell::EnsureFind()
}
// we promise that the nsIWebBrowserFind that we return has been set
// up to point to the focussed, or content window, so we have to
// up to point to the focused, or content window, so we have to
// set that up each time.
nsIScriptGlobalObject* scriptGO = GetScriptGlobalObject();
@ -7825,17 +7825,17 @@ NS_IMETHODIMP nsDocShell::EnsureFind()
nsCOMPtr<nsIDOMWindow> rootWindow = do_QueryInterface(scriptGO);
nsCOMPtr<nsIDOMWindow> windowToSearch = rootWindow;
// if we can, search the focussed window
// if we can, search the focused window
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(scriptGO);
nsIFocusController *focusController = nsnull;
if (ourWindow)
focusController = ourWindow->GetRootFocusController();
if (focusController)
{
nsCOMPtr<nsIDOMWindowInternal> focussedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focussedWindow));
if (focussedWindow)
windowToSearch = focussedWindow;
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (focusedWindow)
windowToSearch = focusedWindow;
}
nsCOMPtr<nsIWebBrowserFindInFrames> findInFrames = do_QueryInterface(mFind);

Просмотреть файл

@ -93,46 +93,94 @@ public:
virtual nsresult Activate() = 0;
virtual nsresult Deactivate() = 0;
nsIChromeEventHandler* GetChromeEventHandler()
{
nsIChromeEventHandler* GetChromeEventHandler() const
{
return mChromeEventHandler;
}
PRBool HasMutationListeners(PRUint32 aMutationEventType)
PRBool HasMutationListeners(PRUint32 aMutationEventType) const
{
return (mMutationBits & aMutationEventType) != 0;
const nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
return (win->mMutationBits & aMutationEventType) != 0;
}
void SetMutationListeners(PRUint32 aType) { mMutationBits |= aType; }
void SetMutationListeners(PRUint32 aType)
{
nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
win->mMutationBits |= aType;
}
virtual nsIFocusController* GetRootFocusController() = 0;
// GetExtantDocument provides a backdoor to the DOM GetDocument accessor
nsIDOMDocument* GetExtantDocument() { return mDocument; }
nsIDOMDocument* GetExtantDocument() const
{
return mDocument;
}
// Internal getter/setter for the frame element, this version of the
// getter crosses chrome boundaries whereas the public scriptable
// one doesn't for security reasons.
nsIDOMElement* GetFrameElementInternal() { return mFrameElement; }
nsIDOMElement* GetFrameElementInternal() const
{
if (IsInnerWindow()) {
return mOuterWindow->GetFrameElementInternal();
}
return mFrameElement;
}
void SetFrameElementInternal(nsIDOMElement *aFrameElement)
{
if (IsInnerWindow()) {
mOuterWindow->SetFrameElementInternal(aFrameElement);
}
mFrameElement = aFrameElement;
}
PRBool IsLoadingOrRunningTimeout() const
{
return !mIsDocumentLoaded || mRunningTimeout;
const nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
return !win->mIsDocumentLoaded || win->mRunningTimeout;
}
// Check whether a document is currently loading
PRBool IsLoading() const
{
return !mIsDocumentLoaded;
const nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
return !win->mIsDocumentLoaded;
}
PRBool IsHandlingResizeEvent() const
{
return mIsHandlingResizeEvent;
const nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
return win->mIsHandlingResizeEvent;
}
virtual void SetOpenerScriptURL(nsIURI* aURI) = 0;
@ -143,30 +191,62 @@ public:
virtual PopupControlState GetPopupControlState() const = 0;
virtual OpenAllowValue GetOpenAllow(const nsAString &aName) = 0;
// Returns an object containing the window's state. This also suspends
// Returns an object containing the window's state. This also suspends
// all running timeouts in the window.
virtual nsresult SaveWindowState(nsISupports **aState) = 0;
// Restore the window state from aState.
virtual nsresult RestoreWindowState(nsISupports *aState) = 0;
nsPIDOMWindow *GetOuterWindow()
{
return mOuterWindow ? mOuterWindow : this;
}
nsPIDOMWindow *GetCurrentInnerWindow() const
{
return mInnerWindow;
}
PRBool IsInnerWindow() const
{
return mOuterWindow != nsnull;
}
PRBool IsOuterWindow() const
{
return !IsInnerWindow();
}
protected:
nsPIDOMWindow()
: mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(PR_FALSE),
mIsHandlingResizeEvent(PR_FALSE)
nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
: mFrameElement(nsnull), mRunningTimeout(nsnull), mMutationBits(0),
mIsDocumentLoaded(PR_FALSE), mIsHandlingResizeEvent(PR_FALSE),
mInnerWindow(nsnull), mOuterWindow(aOuterWindow)
{
}
// These two variables are special in that they're set to the same
// value on both the outer window and the current inner window. Make
// sure you keep them in sync!
nsCOMPtr<nsIChromeEventHandler> mChromeEventHandler; // strong
nsCOMPtr<nsIDOMDocument> mDocument; // strong
// These members are only used on outer windows.
nsIDOMElement *mFrameElement; // weak
nsCOMPtr<nsIURI> mOpenerScriptURL; // strong; used to determine whether to clear scope
// These variables are only used on inner windows.
nsTimeout *mRunningTimeout;
PRUint32 mMutationBits;
PRPackedBool mIsDocumentLoaded;
PRPackedBool mIsHandlingResizeEvent;
// And these are the references between inner and outer windows.
nsPIDOMWindow *mInnerWindow;
nsPIDOMWindow *mOuterWindow;
};

Просмотреть файл

@ -43,8 +43,8 @@
#include "nsString.h"
#define NS_IDOM_SCRIPT_OBJECT_FACTORY_IID \
{ 0xa6cf9064, 0x15b3, 0x11d2, \
{ 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
{ 0xbac2482a, 0x456e, 0x4ea5, \
{ 0x83, 0xfb, 0x16, 0xe1, 0x24, 0x9c, 0x16, 0x6f } }
class nsIScriptContext;
class nsIScriptGlobalObject;
@ -57,10 +57,6 @@ public:
NS_IMETHOD NewScriptContext(nsIScriptGlobalObject *aGlobal,
nsIScriptContext **aContext) = 0;
NS_IMETHOD NewJSEventListener(nsIScriptContext *aContext,
nsISupports* aObject,
nsIDOMEventListener ** aInstancePtrResult) = 0;
NS_IMETHOD NewScriptGlobalObject(PRBool aIsChrome,
nsIScriptGlobalObject **aGlobal) = 0;

Просмотреть файл

@ -43,6 +43,7 @@
class nsIScriptObjectOwner;
class nsIDOMEventListener;
class nsIAtom;
struct JSObject;
#define NS_IJSEVENTLISTENER_IID \
{ 0xa6cf9118, 0x15b3, 0x11d2, \
@ -55,8 +56,9 @@ class nsIJSEventListener : public nsISupports
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IJSEVENTLISTENER_IID)
nsIJSEventListener(nsIScriptContext *aContext, nsISupports *aTarget)
: mContext(aContext), mTarget(aTarget)
nsIJSEventListener(nsIScriptContext *aContext, JSObject *aScopeObject,
nsISupports *aTarget)
: mContext(aContext), mScopeObject(aScopeObject), mTarget(aTarget)
{
// mTarget is a weak reference. We are guaranteed because of the
// ownership model that the target will be freed (and the
@ -76,6 +78,11 @@ public:
return mTarget;
}
JSObject *GetEventScope()
{
return mScopeObject;
}
virtual void SetEventName(nsIAtom* aName) = 0;
protected:
@ -85,7 +92,13 @@ protected:
}
nsIScriptContext *mContext;
JSObject *mScopeObject;
nsISupports *mTarget;
};
/* factory function */
nsresult NS_NewJSEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject, nsISupports *aObject,
nsIDOMEventListener **aReturn);
#endif // nsIJSEventListener_h__

Просмотреть файл

@ -335,6 +335,21 @@ public:
* Tell the context whether or not to GC when destroyed.
*/
virtual void SetGCOnDestruction(PRBool aGCOnDestruction) = 0;
/**
* Initialize DOM classes on aGlobalObj
*/
virtual nsresult InitClasses(JSObject *aGlobalObj) = 0;
/**
* Tell the context we're about to be reinitialize it.
*/
virtual void WillInitializeContext() = 0;
/**
* Dell the context we're done reinitializing it.
*/
virtual void DidInitializeContext() = 0;
};
inline nsIScriptContext *

Просмотреть файл

@ -107,6 +107,13 @@ public:
* Called to enable/disable scripts.
*/
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts) = 0;
/** Set a new arguments object for this window. This will be set on
* the window right away (if there's an existing document) and it
* will also be installed on the window when the next document is
* loaded.
*/
virtual nsresult SetNewArguments(JSObject *aArguments) = 0;
};
#endif

Просмотреть файл

@ -46,7 +46,6 @@
#include "nsISupportsPrimitives.h"
#include "nsIXPConnect.h"
#include "nsIJSContextStack.h"
#include "nsIScriptContext.h"
#include "nsIXPCSecurityManager.h"
#include "nsIStringBundle.h"
#include "nsIConsoleService.h"
@ -61,8 +60,10 @@
#include "jsapi.h"
#include "jsnum.h"
#include "jsdbgapi.h"
#include "jscntxt.h"
// General helper includes
#include "nsGlobalWindow.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
@ -486,6 +487,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
nsIXPCScriptable::WANT_ADDPROPERTY |
nsIXPCScriptable::WANT_DELPROPERTY |
nsIXPCScriptable::WANT_ENUMERATE |
nsIXPCScriptable::WANT_EQUALITY |
nsIXPCScriptable::WANT_OUTER_OBJECT |
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
// Don't allow modifications to Location.prototype
@ -493,8 +496,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS &
~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE)
NS_DEFINE_CLASSINFO_DATA(Navigator, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_PRECREATE)
NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH,
ARRAY_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(PluginArray, nsPluginArraySH,
@ -3213,6 +3217,24 @@ nsDOMClassInfo::Mark(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDOMClassInfo::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, jsval val, PRBool *bp)
{
NS_ERROR("Don't call me!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
NS_ERROR("Don't call me!");
return NS_ERROR_UNEXPECTED;
}
// static
nsIClassInfo *
@ -3487,13 +3509,13 @@ nsDOMClassInfo::doCheckPropertyAccess(JSContext *cx, JSObject *obj, jsval id,
}
nsIScriptContext *scx = sgo->GetContext();
JSObject *global;
if (!scx || !scx->IsContextInitialized()) {
if (!scx || !scx->IsContextInitialized() ||
!(global = sgo->GetGlobalJSObject())) {
return NS_OK;
}
JSObject *global = sgo->GetGlobalJSObject();
return sSecMan->CheckPropertyAccess(cx, global, mData->mName, id,
accessMode);
}
@ -3680,8 +3702,8 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
}
// static
JSObject *
nsWindowSH::GetInvalidatedGlobalScopePolluter(JSContext *cx, JSObject *obj)
void
nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj)
{
JSObject *proto;
@ -3693,38 +3715,31 @@ nsWindowSH::GetInvalidatedGlobalScopePolluter(JSContext *cx, JSObject *obj)
::JS_SetPrivate(cx, proto, nsnull);
// Pull the global scope polluter out of the prototype chain.
// Pull the global scope polluter out of the prototype chain so
// that it can be freed.
::JS_SetPrototype(cx, obj, ::JS_GetPrototype(cx, proto));
::JS_ClearScope(cx, proto);
break;
}
obj = proto;
}
return proto;
}
// static
nsresult
nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
JSObject *oldPolluter,
nsIHTMLDocument *doc)
{
// If global scope pollution is disabled, do nothing
if (sDisableGlobalScopePollutionSupport) {
// If global scope pollution is disabled, or if our document is not
// a HTML document, do nothing
if (sDisableGlobalScopePollutionSupport || !doc) {
return NS_OK;
}
JSObject *gsp = oldPolluter;
JSObject *gsp = ::JS_NewObject(cx, &sGlobalScopePolluterClass, nsnull, obj);
if (!gsp) {
gsp = ::JS_NewObject(cx, &sGlobalScopePolluterClass, nsnull, obj);
if (!gsp) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_ERROR_OUT_OF_MEMORY;
}
JSObject *o = obj, *proto;
@ -3756,18 +3771,16 @@ nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
}
// The global scope polluter will release doc on destruction (or
// reinitialzation).
NS_IF_ADDREF(doc);
// invalidation).
NS_ADDREF(doc);
return NS_OK;
}
static
already_AddRefed<nsIDOMWindow>
GetChildFrame(nsIXPConnectWrappedNative *wrapper, jsval id)
GetChildFrame(nsGlobalWindow *win, jsval id)
{
nsCOMPtr<nsIDOMWindowInternal> win(do_QueryWrappedNative(wrapper));
nsCOMPtr<nsIDOMWindowCollection> frames;
win->GetFrames(getter_AddRefs(frames));
@ -3784,6 +3797,54 @@ NS_IMETHODIMP
nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
#ifdef DEBUG_SH_FORWARDING
{
nsDependentJSString str(::JS_ValueToString(cx, id));
if (win->IsInnerWindow()) {
#ifdef DEBUG_PRINT_INNER
printf("Property '%s' get on inner window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
#endif
} else {
printf("Property '%s' get on outer window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
}
}
#endif
if (win->IsOuterWindow() && !ObjectIsNativeWrapper(cx, obj)) {
// XXXjst: Do security checks here when we remove the security
// checks on the inner window.
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
JSObject *innerObj;
if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Forwarding get to inner window %p\n", (void *)innerWin);
#endif
// Forward the get to the inner object
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
*_retval = ::JS_GetUCProperty(cx, innerObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), vp);
} else if (JSVAL_IS_INT(id)) {
*_retval = ::JS_GetElement(cx, innerObj, JSVAL_TO_INT(id), vp);
} else {
NS_ERROR("Write me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_OK;
}
}
// The order in which things are done in this method are a bit
// whacky, that's because this method is *extremely* performace
// critical. Don't touch this unless you know what you're doing.
@ -3794,7 +3855,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// if window.frames[n] is a child frame, wrap the frame and return
// it without doing a security check.
nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(wrapper, id);
nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(win, id);
nsresult rv = NS_OK;
if (frame) {
@ -3802,8 +3863,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// child frame, wrap the child frame without doing a security
// check and return.
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), frame,
NS_GET_IID(nsIDOMWindow), vp);
rv = WrapNative(cx, obj, frame, NS_GET_IID(nsIDOMWindow), vp);
}
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
@ -3859,6 +3919,54 @@ NS_IMETHODIMP
nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
#ifdef DEBUG_SH_FORWARDING
{
nsDependentJSString str(::JS_ValueToString(cx, id));
if (win->IsInnerWindow()) {
#ifdef DEBUG_PRINT_INNER
printf("Property '%s' set on inner window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
#endif
} else {
printf("Property '%s' set on outer window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
}
}
#endif
if (win->IsOuterWindow() && !ObjectIsNativeWrapper(cx, obj)) {
// XXXjst: Do security checks here when we remove the security
// checks on the inner window.
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
JSObject *innerObj;
if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Forwarding set to inner window %p\n", (void *)innerWin);
#endif
// Forward the set to the inner object
if (JSVAL_IS_STRING(id)) {
JSString *str = JSVAL_TO_STRING(id);
*_retval = ::JS_SetUCProperty(cx, innerObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), vp);
} else if (JSVAL_IS_INT(id)) {
*_retval = ::JS_SetElement(cx, innerObj, JSVAL_TO_INT(id), vp);
} else {
NS_ERROR("Write me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_OK;
}
}
if (needsSecurityCheck(cx, wrapper)) {
nsresult rv =
doCheckPropertyAccess(cx, obj, id, wrapper,
@ -3901,6 +4009,46 @@ nsWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp,
PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
#ifdef DEBUG_SH_FORWARDING
{
nsDependentJSString str(::JS_ValueToString(cx, id));
if (win->IsInnerWindow()) {
#ifdef DEBUG_PRINT_INNER
printf("Property '%s' add on inner window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
#endif
} else {
printf("Property '%s' add on outer window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
}
}
#endif
if (win->IsOuterWindow() && !ObjectIsNativeWrapper(cx, obj) ) {
// XXXjst: Do security checks here when we remove the security
// checks on the inner window.
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
JSObject *innerObj;
if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Forwarding add to inner window %p\n", (void *)innerWin);
#endif
// Forward the add to the inner object
jsid interned_id;
*_retval = (::JS_ValueToId(cx, id, &interned_id) &&
OBJ_DEFINE_PROPERTY(cx, innerObj, interned_id, *vp, nsnull,
nsnull, JSPROP_ENUMERATE, nsnull));
return NS_OK;
}
}
// If we're in a state where we're not supposed to do a security
// check, return early.
if (!sDoSecurityCheckInAddProperty) {
@ -3936,6 +4084,45 @@ nsWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp,
PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
#ifdef DEBUG_SH_FORWARDING
{
nsDependentJSString str(::JS_ValueToString(cx, id));
if (win->IsInnerWindow()) {
#ifdef DEBUG_PRINT_INNER
printf("Property '%s' del on inner window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
#endif
} else {
printf("Property '%s' del on outer window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
}
}
#endif
if (win->IsOuterWindow() && !ObjectIsNativeWrapper(cx, obj)) {
// XXXjst: Do security checks here when we remove the security
// checks on the inner window.
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
JSObject *innerObj;
if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Forwarding add to inner window %p\n", (void *)innerWin);
#endif
// Forward the del to the inner object
jsid interned_id;
*_retval = (::JS_ValueToId(cx, id, &interned_id) &&
OBJ_DELETE_PROPERTY(cx, innerObj, interned_id, vp));
return NS_OK;
}
}
if (id == sLocation_id) {
// Don't allow deleting window.location, allowing that could lead
// to security bugs (see bug 143369).
@ -4007,7 +4194,7 @@ BaseStubConstructor(const nsGlobalNameStruct *name_struct, JSContext *cx,
return rv;
}
rv = nsDOMGenericSH::WrapNative(cx, ::JS_GetGlobalObject(cx), native,
rv = nsDOMGenericSH::WrapNative(cx, GetGlobalJSObject(cx, obj), native,
NS_GET_IID(nsISupports), rval);
return NS_SUCCEEDED(rv) ? JS_TRUE : JS_FALSE;
@ -5052,8 +5239,7 @@ nsWindowSH::GlobalResolve(nsIScriptGlobalObject *global, JSContext *cx,
prop_val = OBJECT_TO_JSVAL(prop_obj);
} else {
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), native,
NS_GET_IID(nsISupports), &prop_val);
rv = WrapNative(cx, obj, native, NS_GET_IID(nsISupports), &prop_val);
}
NS_ENSURE_SUCCESS(rv, rv);
@ -5083,26 +5269,122 @@ nsWindowSH::GlobalResolve(nsIScriptGlobalObject *global, JSContext *cx,
return rv;
}
// static
nsresult
nsWindowSH::OnDocumentChanged(JSContext *cx, JSObject *obj,
nsIDOMWindow *window)
{
nsCOMPtr<nsIDOMDocument> document;
nsresult rv = window->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
// The PostCreate hook for the document will handle defining the property
jsval v;
return WrapNative(cx, obj, document, NS_GET_IID(nsIDOMDocument), &v);
}
NS_IMETHODIMP
nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags,
JSObject **objp, PRBool *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
#ifdef DEBUG_SH_FORWARDING
{
nsDependentJSString str(::JS_ValueToString(cx, id));
if (win->IsInnerWindow()) {
#ifdef DEBUG_PRINT_INNER
printf("Property '%s' resolve on inner window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
#endif
} else {
printf("Property '%s' resolve on outer window %p\n",
NS_ConvertUTF16toUTF8(str).get(), (void *)win);
}
}
#endif
// Note, we won't forward resolve of the location property to the
// inner window, we need to deal with that one for the outer too
// since we've got special security protection code for that
// property.
if (win->IsOuterWindow() && id != sLocation_id &&
!ObjectIsNativeWrapper(cx, obj)) {
// XXXjst: Do security checks here when we remove the security
// checks on the inner window.
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
if (!innerWin || !innerWin->GetExtantDocument()) {
// We're resolving a property on an outer window for which there
// is no inner window yet. If the context is already initalized,
// trigger creation of a new inner window by calling
// GetDocument() on the outer window. This will create a
// synthetic about:blank document, and an inner window which may
// be reused by the actual document being loaded into this outer
// window. This way properties defined on the window while the
// document before the document load stated will be visible to
// the document once it's loaded, assuming same origin etc.
nsIScriptContext *scx = win->GetContextInternal();
if (scx && scx->IsContextInitialized()) {
nsCOMPtr<nsIDOMDocument> doc;
win->GetDocument(getter_AddRefs(doc));
// Grab the new inner window.
innerWin = win->GetCurrentInnerWindowInternal();
}
}
JSObject *innerObj;
if (innerWin && (innerObj = innerWin->GetGlobalJSObject())) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Forwarding resolve to inner window %p\n", (void *)innerWin);
#endif
jsid interned_id;
JSObject *pobj;
JSProperty *prop = nsnull;
*_retval = (::JS_ValueToId(cx, id, &interned_id) &&
OBJ_LOOKUP_PROPERTY(cx, innerObj, interned_id, &pobj,
&prop));
if (*_retval && prop) {
#ifdef DEBUG_SH_FORWARDING
printf(" --- Resolve on inner window found property.\n");
#endif
OBJ_DROP_PROPERTY(cx, pobj, prop);
JSObject *proto;
if (pobj != innerObj && (proto = ::JS_GetPrototype(cx, obj))) {
// A property was found on one of innerObj's prototypes,
// this means the property could've been found on the
// XPCWrappedNative proto, which means that the property is
// likely a function (getter, setter, or a method). In this
// case we can't expose this method as a property of the
// outer since a call to it would be on the wrong object and
// XPConnect can't deal. In this case only, check if the
// property also exists on our prototype, and if it does,
// return it instead of the one found on the inner object's
// prototype chain.
#ifdef DEBUG_SH_FORWARDING
printf(" ... but the propety was found on the prototype, "
"checking to see if the property also exists on our "
"prototype.\n");
#endif
JSObject *mypobj;
OBJ_LOOKUP_PROPERTY(cx, proto, interned_id, &mypobj,
&prop);
if (prop) {
// We found the prop on obj's prototype too, use it
// instead.
OBJ_DROP_PROPERTY(cx, mypobj, prop);
pobj = mypobj;
}
}
*objp = pobj;
}
return NS_OK;
}
}
if (!JSVAL_IS_STRING(id)) {
if (JSVAL_IS_INT(id) && !(flags & JSRESOLVE_ASSIGNING)) {
// If we're resolving a numeric property, treat that as if
@ -5110,7 +5392,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// window), if window.frames[n] is a child frame, define a
// property for this index.
nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(wrapper, id);
nsCOMPtr<nsIDOMWindow> frame = GetChildFrame(win, id);
if (frame) {
// A numeric property accessed and the numeric property is a
@ -5128,10 +5410,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
nsIScriptContext *my_context = sgo->GetContext();
nsIScriptContext *my_context = win->GetContextInternal();
nsresult rv = NS_OK;
@ -5145,7 +5424,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// initialization to behave as if it were done eagerly, on each
// window's own context (not on some other window-caller's
// context).
JSContext *my_cx;
if (!my_context) {
@ -5190,7 +5469,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSString *str = JSVAL_TO_STRING(id);
nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(sgo->GetDocShell()));
nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(win->GetDocShell()));
PRInt32 count = 0;
@ -5214,8 +5493,11 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// on the wrapper so that ::NewResolve() doesn't get called
// again for this property name.
JSObject *wrapperObj;
wrapper->GetJSObject(&wrapperObj);
jsval v;
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), child_win,
rv = WrapNative(cx, wrapperObj, child_win,
NS_GET_IID(nsIDOMWindowInternal), &v);
NS_ENSURE_SUCCESS(rv, rv);
@ -5258,7 +5540,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// which have been registered with the script namespace manager.
JSBool did_resolve = JS_FALSE;
rv = GlobalResolve(sgo, cx, obj, str, flags, &did_resolve);
rv = GlobalResolve(win, cx, obj, str, flags, &did_resolve);
NS_ENSURE_SUCCESS(rv, rv);
if (did_resolve) {
@ -5304,15 +5586,28 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// here) since we must define window.location to prevent the
// getter from being overriden (for security reasons).
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(sgo));
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMLocation> location;
rv = window->GetLocation(getter_AddRefs(location));
rv = win->GetLocation(getter_AddRefs(location));
NS_ENSURE_SUCCESS(rv, rv);
// Make sure we wrap the location object in the inner window's
// scope if we've got an inner window.
JSObject *scope = nsnull;
if (win->IsOuterWindow()) {
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
if (innerWin) {
scope = innerWin->GetGlobalJSObject();
}
}
if (!scope) {
scope = obj;
}
jsval v;
rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), &v);
rv = WrapNative(cx, GetGlobalJSObject(cx, scope), location,
NS_GET_IID(nsIDOMLocation), &v);
NS_ENSURE_SUCCESS(rv, rv);
sDoSecurityCheckInAddProperty = PR_FALSE;
@ -5354,11 +5649,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
} else {
if (id == sNavigator_id) {
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(sgo));
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMNavigator> navigator;
rv = window->GetNavigator(getter_AddRefs(navigator));
rv = win->GetNavigator(getter_AddRefs(navigator));
NS_ENSURE_SUCCESS(rv, rv);
jsval v;
@ -5377,25 +5669,33 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
if (id == sDocument_id) {
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(sgo));
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
rv = OnDocumentChanged(cx, obj, window);
nsCOMPtr<nsIDOMDocument> document;
nsresult rv = win->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
jsval v;
rv = WrapNative(cx, obj, document, NS_GET_IID(nsIDOMDocument), &v);
NS_ENSURE_SUCCESS(rv, rv);
if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), v, nsnull,
nsnull, JSPROP_READONLY | JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
if (id == sWindow_id) {
jsval v;
rv = WrapNative(cx, obj, sgo, NS_GET_IID(nsIDOMWindow), &v);
NS_ENSURE_SUCCESS(rv, rv);
// window should *always* be the outer window object.
win = win->GetOuterWindowInternal();
if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), v, nsnull,
nsnull,
::JS_GetStringLength(str),
OBJECT_TO_JSVAL(win->GetGlobalJSObject()),
nsnull, nsnull,
JSPROP_READONLY | JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
@ -5441,6 +5741,49 @@ nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
NS_IMETHODIMP
nsWindowSH::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, jsval val, PRBool *bp)
{
*bp = PR_FALSE;
if (JSVAL_IS_PRIMITIVE(val)) {
return NS_OK;
}
nsCOMPtr<nsIXPConnectWrappedNative> other_wrapper;
nsContentUtils::XPConnect()->
GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
getter_AddRefs(other_wrapper));
if (!other_wrapper) {
// Not equal.
return NS_OK;
}
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
nsCOMPtr<nsPIDOMWindow> other = do_QueryWrappedNative(other_wrapper);
if (other) {
*bp = win->GetOuterWindow() == other->GetOuterWindow();
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
// Always return the outer window.
*_retval = win->GetOuterWindowInternal()->GetGlobalJSObject();
return NS_OK;
}
// DOM Location helper
@ -5462,12 +5805,42 @@ nsLocationSH::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
// DOM Navigator helper
nsresult
nsNavigatorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
{
// window.navigator is persisted across document transitions if
// we're loading a page from the same origin. Because of that we
// need to parent the navigator wrapper at the outer window to avoid
// holding on to the inner window where the navigator was initially
// created too long.
*parentObj = globalObj;
nsNavigator *nav = (nsNavigator *)(nsIDOMNavigator *)nativeObj;
nsIDocShell *ds = nav->GetDocShell();
nsCOMPtr<nsIScriptGlobalObject> sgo = do_GetInterface(ds);
if (sgo) {
JSObject *global = sgo->GetGlobalJSObject();
if (global) {
*parentObj = global;
}
}
return NS_OK;
}
// DOM Node helper
NS_IMETHODIMP
nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
JSObject **parentObj)
{
// XXXjst: Add code that asserts the the scope is an inner window
nsCOMPtr<nsIContent> content(do_QueryInterface(nativeObj));
nsCOMPtr<nsIDocument> doc;
@ -5544,8 +5917,13 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
}
}
// XXXjst: Maybe we need to find the global to use from the
// nsIScriptGlobalObject that's reachable from the node we're about
// to wrap here? But that's not always reachable, let's use
// globalObj for now...
jsval v;
nsresult rv = WrapNative(cx, ::JS_GetGlobalObject(cx), native_parent,
nsresult rv = WrapNative(cx, globalObj, native_parent,
NS_GET_IID(nsISupports), &v);
*parentObj = JSVAL_TO_OBJECT(v);
@ -5786,13 +6164,16 @@ nsEventReceiverSH::RegisterCompileHandler(nsIXPConnectWrappedNative *wrapper,
nsresult rv;
JSObject *scope = GetGlobalJSObject(cx, obj);
if (compile) {
rv = manager->CompileScriptEventListener(script_cx, receiver, atom,
rv = manager->CompileScriptEventListener(script_cx, scope, receiver, atom,
did_define);
} else if (remove) {
rv = manager->RemoveScriptEventListener(atom);
} else {
rv = manager->RegisterScriptEventListener(script_cx, receiver, atom);
rv = manager->RegisterScriptEventListener(script_cx, scope, receiver,
atom);
}
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
@ -6020,7 +6401,7 @@ nsArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
NS_ENSURE_SUCCESS(rv, rv);
if (array_item) {
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), array_item,
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), array_item,
NS_GET_IID(nsISupports), vp);
NS_ENSURE_SUCCESS(rv, rv);
@ -6059,7 +6440,7 @@ nsNamedArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
NS_ENSURE_SUCCESS(rv, rv);
if (item) {
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), item,
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), item,
NS_GET_IID(nsISupports), vp);
NS_ENSURE_SUCCESS(rv, rv);
@ -6159,7 +6540,7 @@ nsContentListSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
}
jsval v;
nsresult rv = WrapNative(cx, ::JS_GetGlobalObject(cx), native_parent,
nsresult rv = WrapNative(cx, globalObj, native_parent,
NS_GET_IID(nsISupports), &v);
*parentObj = JSVAL_TO_OBJECT(v);
@ -6212,13 +6593,6 @@ documentNeedsSecurityCheck(JSContext *cx, nsIXPConnectWrappedNative *wrapper)
}
#endif
if (wrapper_global != ::JS_GetGlobalObject(cx)) {
// cx is not the context in the global object in wrapper, force
// a security check.
return PR_TRUE;
}
// Check if the calling function comes from the same scope that the
// wrapper comes from. If that's the case, or if there's no JS
// running at the moment (i.e. someone is using the JS engine API
@ -6265,6 +6639,7 @@ documentNeedsSecurityCheck(JSContext *cx, nsIXPConnectWrappedNative *wrapper)
// object in the scope that wrapper came from, no need to do a
// security check now.
cached_doc_needs_check = PR_FALSE;
return PR_FALSE;
}
@ -6326,7 +6701,8 @@ nsDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
jsval v;
rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), &v);
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), location,
NS_GET_IID(nsIDOMLocation), &v);
NS_ENSURE_SUCCESS(rv, rv);
sDoSecurityCheckInAddProperty = PR_FALSE;
@ -6433,7 +6809,8 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
rv = location->SetHref(nsDependentJSString(val));
NS_ENSURE_SUCCESS(rv, rv);
rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), vp);
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), location,
NS_GET_IID(nsIDOMLocation), vp);
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
}
@ -6476,11 +6853,11 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
if (SameCOMIdentity(doc, currentDoc)) {
jsval winVal;
nsresult rv = WrapNative(cx, ::JS_GetGlobalObject(cx), win,
nsresult rv = WrapNative(cx, GetGlobalJSObject(cx, obj), win,
NS_GET_IID(nsIDOMWindow), &winVal);
NS_ENSURE_SUCCESS(rv, rv);
NS_NAMED_LITERAL_STRING(doc_str, "document");
if (!::JS_DefineUCProperty(cx, JSVAL_TO_OBJECT(winVal),
@ -6579,7 +6956,7 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc,
return JS_FALSE;
}
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), retval,
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), retval,
NS_GET_IID(nsIDOMDocument), rval);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!");
@ -7189,8 +7566,7 @@ nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
NS_ENSURE_SUCCESS(rv, rv);
if (result) {
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), result,
NS_GET_IID(nsISupports), vp);
rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), vp);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
}
@ -7325,7 +7701,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
if (result) {
// Wrap result, result can be either an element or a list of
// elements
nsresult rv = WrapNative(cx, ::JS_GetGlobalObject(cx), result,
nsresult rv = WrapNative(cx, GetGlobalJSObject(cx, obj), result,
NS_GET_IID(nsISupports), vp);
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
@ -7340,7 +7716,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
form->GetElementAt(n, getter_AddRefs(control));
if (control) {
nsresult rv = WrapNative(cx, ::JS_GetGlobalObject(cx), control,
nsresult rv = WrapNative(cx, GetGlobalJSObject(cx, obj), control,
NS_GET_IID(nsISupports), vp);
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
@ -7446,7 +7822,7 @@ nsHTMLSelectElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
options->Item(n, getter_AddRefs(node));
rv = WrapNative(cx, ::JS_GetGlobalObject(cx), node,
rv = WrapNative(cx, GetGlobalJSObject(cx, obj), node,
NS_GET_IID(nsIDOMNode), vp);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
@ -8041,7 +8417,7 @@ nsHTMLPluginObjElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
}
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = sXPConnect->WrapNative(cx, ::JS_GetGlobalObject(cx), pi, *iid,
rv = sXPConnect->WrapNative(cx, GetGlobalJSObject(cx, obj), pi, *iid,
getter_AddRefs(holder));
if (NS_SUCCEEDED(rv)) {

Просмотреть файл

@ -43,6 +43,7 @@
#include "nsIXPCScriptable.h"
#include "jsapi.h"
#include "nsIScriptSecurityManager.h"
#include "nsIScriptContext.h"
class nsIDOMWindow;
class nsIDOMNSHTMLOptionCollection;
@ -153,9 +154,18 @@ public:
static PRBool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
{
NS_PRECONDITION(sXPCNativeWrapperClass,
"Must know what the XPCNativeWrapper class is!");
return ::JS_GetClass(cx, obj) == sXPCNativeWrapperClass;
#ifdef DEBUG
{
nsIScriptContext *scx = GetScriptContextFromJSContext(cx);
NS_PRECONDITION(!scx || !scx->IsContextInitialized() ||
sXPCNativeWrapperClass,
"Must know what the XPCNativeWrapper class is!");
}
#endif
return sXPCNativeWrapperClass &&
::JS_GetClass(cx, obj) == sXPCNativeWrapperClass;
}
/**
@ -422,9 +432,10 @@ public:
JSObject **objp, PRBool *_retval);
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj);
static nsresult OnDocumentChanged(JSContext *cx, JSObject *obj,
nsIDOMWindow *window);
NS_IMETHOD Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, jsval val, PRBool *bp);
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval);
static JSBool JS_DLL_CALLBACK GlobalScopePolluterNewResolve(JSContext *cx,
JSObject *obj,
@ -438,10 +449,8 @@ public:
static JSBool JS_DLL_CALLBACK SecurityCheckOnSetProp(JSContext *cx,
JSObject *obj, jsval id,
jsval *vp);
static JSObject *GetInvalidatedGlobalScopePolluter(JSContext *cx,
JSObject *obj);
static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
JSObject *oldPolluter,
nsIHTMLDocument *doc);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
@ -476,6 +485,30 @@ public:
};
// Navigator scriptable helper
class nsNavigatorSH : public nsDOMGenericSH
{
protected:
nsNavigatorSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
{
}
virtual ~nsNavigatorSH()
{
}
public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsNavigatorSH(aData);
}
};
// DOM Node helper, this class deals with setting the parent for the
// wrappers

Просмотреть файл

@ -98,22 +98,14 @@ NS_IMPL_RELEASE(nsDOMScriptObjectFactory)
NS_IMETHODIMP
nsDOMScriptObjectFactory::NewScriptContext(nsIScriptGlobalObject *aGlobal,
nsIScriptContext **aContext)
nsIScriptContext **aContext)
{
return NS_CreateScriptContext(aGlobal, aContext);
}
NS_IMETHODIMP
nsDOMScriptObjectFactory::NewJSEventListener(nsIScriptContext *aContext,
nsISupports *aObject,
nsIDOMEventListener **aInstancePtrResult)
{
return NS_NewJSEventListener(aInstancePtrResult, aContext, aObject);
}
NS_IMETHODIMP
nsDOMScriptObjectFactory::NewScriptGlobalObject(PRBool aIsChrome,
nsIScriptGlobalObject **aGlobal)
nsIScriptGlobalObject **aGlobal)
{
return NS_NewScriptGlobalObject(aIsChrome, aGlobal);
}
@ -157,8 +149,8 @@ nsDOMScriptObjectFactory::GetExternalClassInfoInstance(const nsAString& aName)
NS_IMETHODIMP
nsDOMScriptObjectFactory::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *someData)
const char *aTopic,
const PRUnichar *someData)
{
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
#ifdef MOZ_XUL

Просмотреть файл

@ -73,10 +73,6 @@ public:
NS_IMETHOD NewScriptContext(nsIScriptGlobalObject *aGlobal,
nsIScriptContext **aContext);
NS_IMETHOD NewJSEventListener(nsIScriptContext *aContext,
nsISupports *aObject,
nsIDOMEventListener **aInstancePtrResult);
NS_IMETHOD NewScriptGlobalObject(PRBool aIsChrome,
nsIScriptGlobalObject **aGlobal);

Просмотреть файл

@ -150,18 +150,33 @@ nsFocusController::RewindFocusState()
NS_IMETHODIMP
nsFocusController::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
{
if (aWindow && (mCurrentWindow != aWindow)) {
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(aWindow);
if (pwin) {
pwin = pwin->GetOuterWindow();
}
NS_ASSERTION(!pwin || !pwin->IsInnerWindow(),
"Uh, inner window can't have focus!");
nsCOMPtr<nsIDOMWindowInternal> win = do_QueryInterface(pwin);
if (win && (mCurrentWindow != win)) {
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(win);
if (sgo) {
nsCOMPtr<nsIBaseWindow> basewin = do_QueryInterface(sgo->GetDocShell());
if (basewin)
basewin->SetFocus();
}
}
if(mCurrentWindow) mPreviousWindow = mCurrentWindow;
else if (aWindow) mPreviousWindow = aWindow;
mCurrentWindow = aWindow;
if (mCurrentWindow) {
mPreviousWindow = mCurrentWindow;
} else if (win) {
mPreviousWindow = win;
}
mCurrentWindow = win;
if (mUpdateWindowWatcher) {
NS_ASSERTION(mActive, "This shouldn't happen");
@ -306,18 +321,16 @@ nsFocusController::Focus(nsIDOMEvent* aEvent)
// but we don't hear the subsequent focus to the Ender window.
nsCOMPtr<nsIDOMDocument> ownerDoc;
domElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(ownerDoc, getter_AddRefs(domWindow));
nsCOMPtr<nsIDOMWindowInternal> domWindow = GetWindowFromDocument(ownerDoc);
if (domWindow)
SetFocusedWindow(domWindow);
}
else {
// We're focusing a window. We only want to do an update commands
// if no element is focused.
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
nsCOMPtr<nsIDOMWindowInternal> domWindow = GetWindowFromDocument(domDoc);
if (domWindow) {
SetFocusedWindow(domWindow);
if (mCurrentElement) {
@ -361,10 +374,9 @@ nsFocusController::Blur(nsIDOMEvent* aEvent)
SetFocusedElement(nsnull);
}
nsCOMPtr<nsIDOMWindowInternal> domWindow;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(t);
if (domDoc) {
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
nsCOMPtr<nsIDOMWindowInternal> domWindow = GetWindowFromDocument(domDoc);
if (domWindow)
SetFocusedWindow(nsnull);
}
@ -372,20 +384,21 @@ nsFocusController::Blur(nsIDOMEvent* aEvent)
return NS_OK;
}
nsresult
nsFocusController::GetParentWindowFromDocument(nsIDOMDocument* aDocument,
nsIDOMWindowInternal** aWindow)
nsPIDOMWindow *
nsFocusController::GetWindowFromDocument(nsIDOMDocument* aDocument)
{
NS_ENSURE_ARG_POINTER(aWindow);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
if (!doc)
return NS_OK;
nsCOMPtr<nsIDocument> objectOwner = do_QueryInterface(aDocument);
if(!objectOwner) return NS_OK;
nsCOMPtr<nsPIDOMWindow> win =
do_QueryInterface(doc->GetScriptGlobalObject());
nsCOMPtr<nsIDOMWindowInternal> domWindow =
do_QueryInterface(objectOwner->GetScriptGlobalObject());
*aWindow = domWindow;
NS_IF_ADDREF(*aWindow);
return NS_OK;
if (win->IsInnerWindow()) {
return win->GetOuterWindow();
}
return win;
}
NS_IMETHODIMP
@ -412,9 +425,7 @@ nsFocusController::GetControllerForCommand(const char * aCommand,
// Move up to the window.
nsCOMPtr<nsIDOMDocument> domDoc;
mCurrentElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow;
GetParentWindowFromDocument(domDoc, getter_AddRefs(domWindow));
currentWindow = do_QueryInterface(domWindow);
currentWindow = do_QueryInterface(GetWindowFromDocument(domDoc));
}
else if (mCurrentWindow) {
nsGlobalWindow *win =
@ -426,20 +437,20 @@ nsFocusController::GetControllerForCommand(const char * aCommand,
while(currentWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow(do_QueryInterface(currentWindow));
if(domWindow) {
nsCOMPtr<nsIControllers> controllers2;
domWindow->GetControllers(getter_AddRefs(controllers2));
if(controllers2) {
nsCOMPtr<nsIController> controller;
controllers2->GetControllerForCommand(aCommand,
getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
nsCOMPtr<nsIControllers> controllers2;
domWindow->GetControllers(getter_AddRefs(controllers2));
if(controllers2) {
nsCOMPtr<nsIController> controller;
controllers2->GetControllerForCommand(aCommand,
getter_AddRefs(controller));
if(controller) {
*_retval = controller;
NS_ADDREF(*_retval);
return NS_OK;
}
}
}
nsGlobalWindow *win =
NS_STATIC_CAST(nsGlobalWindow *,
NS_STATIC_CAST(nsIDOMWindowInternal *, currentWindow));

Просмотреть файл

@ -50,6 +50,7 @@
class nsIDOMElement;
class nsIDOMWindow;
class nsPIDOMWindow;
class nsIController;
class nsIControllers;
@ -105,7 +106,7 @@ protected:
void UpdateWWActiveWindow();
public:
static nsresult GetParentWindowFromDocument(nsIDOMDocument* aElement, nsIDOMWindowInternal** aWindow);
static nsPIDOMWindow *GetWindowFromDocument(nsIDOMDocument* aElement);
// Members
protected:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -70,6 +70,7 @@
#include "nsIDOMJSWindow.h"
#include "nsIDOMChromeWindow.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsITimer.h"
#include "nsIWebBrowserChrome.h"
@ -86,6 +87,7 @@
#include "nsPoint.h"
#include "nsSize.h"
#include "mozFlushType.h"
#include "prclist.h"
#define DEFAULT_HOME_PAGE "www.mozilla.org"
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
@ -126,7 +128,8 @@ class nsGlobalWindow : public nsIScriptGlobalObject,
public nsIDOMNSEventTarget,
public nsIDOMViewCSS,
public nsSupportsWeakReference,
public nsIInterfaceRequestor
public nsIInterfaceRequestor,
public PRCListStr
{
public:
// public methods
@ -155,6 +158,7 @@ public:
virtual JSObject *GetGlobalJSObject();
virtual void OnFinalize(JSObject *aJSObject);
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
virtual nsresult SetNewArguments(JSObject *aArguments);
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();
@ -206,7 +210,7 @@ public:
virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState);
virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
// nsIDOMViewCSS
NS_DECL_NSIDOMVIEWCSS
@ -217,7 +221,37 @@ public:
NS_DECL_NSIINTERFACEREQUESTOR
// Object Management
nsGlobalWindow();
nsGlobalWindow(nsGlobalWindow *aOuterWindow);
static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper)
{
// Make sure this matches the casts we do in QueryInterface().
return (nsGlobalWindow *)(nsIScriptGlobalObject *)wrapper->Native();
}
nsIScriptContext *GetContextInternal()
{
if (IsInnerWindow()) {
return GetOuterWindowInternal()->mContext;
}
return mContext;
}
nsGlobalWindow *GetOuterWindowInternal()
{
return NS_STATIC_CAST(nsGlobalWindow *, GetOuterWindow());
}
nsGlobalWindow *GetCurrentInnerWindowInternal()
{
return NS_STATIC_CAST(nsGlobalWindow *, mInnerWindow);
}
nsIDocShell *GetDocShellInternal()
{
return GetOuterWindowInternal()->mDocShell;
}
static void ShutDown();
static PRBool IsCallerChrome();
@ -230,12 +264,24 @@ protected:
void CleanUp();
void ClearControllers();
nsresult SetNewDocument(nsIDOMDocument *aDocument,
PRBool aRemoveEventListeners,
PRBool aClearScopeHint,
PRBool aIsInternalCall);
// Get the parent, returns null if this is a toplevel window
nsIDOMWindowInternal *GetParentInternal();
// popup tracking
PRBool IsPopupSpamWindow() const { return mIsPopupSpam; }
void SetPopupSpamWindow(PRBool aPopup) { mIsPopupSpam = aPopup; }
PRBool IsPopupSpamWindow()
{
return GetOuterWindowInternal()->mIsPopupSpam;
}
void SetPopupSpamWindow(PRBool aPopup)
{
GetOuterWindowInternal()->mIsPopupSpam = aPopup;
}
// Window Control Functions
NS_IMETHOD OpenInternal(const nsAString& aUrl,
@ -244,6 +290,7 @@ protected:
PRBool aDialog, jsval *argv, PRUint32 argc,
nsISupports *aExtraArgument, nsIDOMWindow **aReturn);
static void CloseWindow(nsISupports* aWindow);
static void ClearWindowScope(nsISupports* aWindow);
// Timeout Functions
nsresult SetTimeoutOrInterval(PRBool aIsInterval, PRInt32* aReturn);
@ -318,18 +365,20 @@ protected:
// objects will keep the global object (this object) alive. To prevent
// these cycles, ownership of such members must be released in
// |CleanUp| and |SetDocShell|.
PRPackedBool mFirstDocumentLoad;
PRPackedBool mIsScopeClear;
// These members are only used on outer window objects. Make sure
// you never set any of these on an inner object!
PRPackedBool mFullScreen;
PRPackedBool mIsClosed;
PRPackedBool mInClose;
PRPackedBool mOpenerWasCleared;
PRPackedBool mIsPopupSpam;
nsCOMPtr<nsIScriptContext> mContext;
nsCOMPtr<nsIDOMWindowInternal> mOpener;
nsCOMPtr<nsIControllers> mControllers;
nsCOMPtr<nsIEventListenerManager> mListenerManager;
JSObject* mJSObject;
JSObject* mArguments;
nsRefPtr<nsNavigator> mNavigator;
nsRefPtr<nsScreen> mScreen;
nsRefPtr<nsHistory> mHistory;
@ -351,19 +400,13 @@ protected:
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // Weak Reference
nsIDocShell* mDocShell; // Weak Reference
nsEvent* mCurrentEvent;
nsCOMPtr<nsIDOMCrypto> mCrypto;
nsCOMPtr<nsIDOMPkcs11> mPkcs11;
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
// XXX We need mNavigatorHolder because we make two SetNewDocument()
// calls when transitioning from page to page. This keeps a reference
// to the JSObject holder for the navigator object in between
// SetNewDocument() calls so that the JSObject doesn't get garbage
// collected in between these calls.
// See bug 163645 for more on why we need this and bug 209607 for info
// on how we can remove the need for this.
nsCOMPtr<nsIXPConnectJSObjectHolder> mNavigatorHolder;
nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
// This member variable is used only on the inner window.
nsCOMPtr<nsIEventListenerManager> mListenerManager;
friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils;
@ -385,6 +428,11 @@ public:
// nsIDOMChromeWindow interface
NS_DECL_NSIDOMCHROMEWINDOW
nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
: nsGlobalWindow(aOuterWindow)
{
}
protected:
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
};
@ -496,6 +544,11 @@ public:
NS_DECL_NSIDOMJSNAVIGATOR
void SetDocShell(nsIDocShell *aDocShell);
nsIDocShell *GetDocShell()
{
return mDocShell;
}
void LoadingNewDocument();
nsresult RefreshMIMEArray();

Просмотреть файл

@ -1609,7 +1609,9 @@ nsJSContext::InitContext(nsIScriptGlobalObject *aGlobalObject)
// or Release() methods are called
mGlobalWrapperRef = holder;
rv = InitClasses(); // this will complete global object initialization
holder->GetJSObject(&global);
rv = InitClasses(global); // this will complete global object initialization
NS_ENSURE_SUCCESS(rv, rv);
mIsInitialized = PR_TRUE;
@ -1626,7 +1628,7 @@ nsJSContext::InitializeExternalClasses()
}
nsresult
nsJSContext::InitializeLiveConnectClasses()
nsJSContext::InitializeLiveConnectClasses(JSObject *aGlobalObj)
{
nsresult rv = NS_OK;
@ -1644,7 +1646,7 @@ nsJSContext::InitializeLiveConnectClasses()
do_QueryInterface(jvmManager);
if (liveConnectManager) {
rv = liveConnectManager->InitLiveConnectClasses(mContext, ::JS_GetGlobalObject(mContext));
rv = liveConnectManager->InitLiveConnectClasses(mContext, aGlobalObj);
}
}
}
@ -1937,22 +1939,21 @@ static JSFunctionSpec JProfFunctions[] = {
#endif /* defined(MOZ_JPROF) */
nsresult
nsJSContext::InitClasses()
nsJSContext::InitClasses(JSObject *aGlobalObj)
{
nsresult rv = NS_OK;
JSObject *globalObj = ::JS_GetGlobalObject(mContext);
rv = InitializeExternalClasses();
NS_ENSURE_SUCCESS(rv, rv);
rv = InitializeLiveConnectClasses();
rv = InitializeLiveConnectClasses(aGlobalObj);
NS_ENSURE_SUCCESS(rv, rv);
rv = nsDOMClassInfo::InitDOMJSClass(mContext, globalObj);
rv = nsDOMClassInfo::InitDOMJSClass(mContext, aGlobalObj);
NS_ENSURE_SUCCESS(rv, rv);
// Initialize the options object and set default options in mContext
JSObject *optionsObj = ::JS_DefineObject(mContext, globalObj, "_options",
JSObject *optionsObj = ::JS_DefineObject(mContext, aGlobalObj, "_options",
&OptionsClass, nsnull, 0);
if (optionsObj &&
::JS_DefineProperties(mContext, optionsObj, OptionsProperties)) {
@ -1963,17 +1964,29 @@ nsJSContext::InitClasses()
#ifdef NS_TRACE_MALLOC
// Attempt to initialize TraceMalloc functions
::JS_DefineFunctions(mContext, globalObj, TraceMallocFunctions);
::JS_DefineFunctions(mContext, aGlobalObj, TraceMallocFunctions);
#endif
#ifdef MOZ_JPROF
// Attempt to initialize JProf functions
::JS_DefineFunctions(mContext, globalObj, JProfFunctions);
::JS_DefineFunctions(mContext, aGlobalObj, JProfFunctions);
#endif
return rv;
}
void
nsJSContext::WillInitializeContext()
{
mIsInitialized = PR_FALSE;
}
void
nsJSContext::DidInitializeContext()
{
mIsInitialized = PR_TRUE;
}
PRBool
nsJSContext::IsContextInitialized()
{

Просмотреть файл

@ -130,14 +130,18 @@ public:
virtual void SetGCOnDestruction(PRBool aGCOnDestruction);
virtual nsresult InitClasses(JSObject *aGlobalObj);
virtual void WillInitializeContext();
virtual void DidInitializeContext();
NS_DECL_NSIXPCSCRIPTNOTIFY
NS_DECL_NSITIMERCALLBACK
protected:
nsresult InitClasses();
nsresult InitializeExternalClasses();
nsresult InitializeLiveConnectClasses();
nsresult InitializeLiveConnectClasses(JSObject *aGlobalObj);
// aHolder should be holding our global object
nsresult FindXPCNativeWrapperClass(nsIXPConnectJSObjectHolder *aHolder);
@ -153,14 +157,16 @@ protected:
struct TerminationFuncHolder;
friend struct TerminationFuncHolder;
struct TerminationFuncClosure {
struct TerminationFuncClosure
{
TerminationFuncClosure(nsScriptTerminationFunc aFunc,
nsISupports* aArg,
TerminationFuncClosure* aNext) :
mTerminationFunc(aFunc),
mTerminationFuncArg(aArg),
mNext(aNext)
{}
{
}
~TerminationFuncClosure()
{
delete mNext;
@ -171,14 +177,16 @@ protected:
TerminationFuncClosure* mNext;
};
struct TerminationFuncHolder {
TerminationFuncHolder(nsJSContext* aContext) :
mContext(aContext),
mTerminations(aContext->mTerminations)
struct TerminationFuncHolder
{
TerminationFuncHolder(nsJSContext* aContext)
: mContext(aContext),
mTerminations(aContext->mTerminations)
{
aContext->mTerminations = nsnull;
}
~TerminationFuncHolder() {
~TerminationFuncHolder()
{
// Have to be careful here. mContext might have picked up new
// termination funcs while the script was evaluating. Prepend whatever
// we have to the current termination funcs on the context (since our

Просмотреть файл

@ -51,9 +51,10 @@
/*
* nsJSEventListener implementation
*/
nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext,
nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext,
JSObject *aScopeObject,
nsISupports *aObject)
: nsIJSEventListener(aContext, aObject),
: nsIJSEventListener(aContext, aScopeObject, aObject),
mReturnResult(nsReturnResult_eNotSet)
{
}
@ -119,8 +120,8 @@ nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
// root
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), mTarget,
NS_GET_IID(nsISupports), getter_AddRefs(wrapper));
rv = xpc->WrapNative(cx, mScopeObject, mTarget, NS_GET_IID(nsISupports),
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
JSObject* obj = nsnull;
@ -221,16 +222,16 @@ nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
*/
nsresult
NS_NewJSEventListener(nsIDOMEventListener ** aInstancePtrResult,
nsIScriptContext *aContext, nsISupports *aObject)
NS_NewJSEventListener(nsIScriptContext *aContext, JSObject *aScopeObject,
nsISupports *aObject, nsIDOMEventListener ** aReturn)
{
nsJSEventListener* it = new nsJSEventListener(aContext, aObject);
nsJSEventListener* it =
new nsJSEventListener(aContext, aScopeObject, aObject);
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aInstancePtrResult = it;
NS_ADDREF(*aInstancePtrResult);
NS_ADDREF(*aReturn = it);
return NS_OK;
}

Просмотреть файл

@ -51,7 +51,8 @@ class nsJSEventListener : public nsIDOMEventListener,
public nsIJSEventListener
{
public:
nsJSEventListener(nsIScriptContext *aContext, nsISupports* aObject);
nsJSEventListener(nsIScriptContext *aContext, JSObject *aScopeObject,
nsISupports* aObject);
virtual ~nsJSEventListener();
NS_DECL_ISUPPORTS
@ -74,10 +75,5 @@ protected:
nsReturnResult mReturnResult;
};
/* factory function */
nsresult NS_NewJSEventListener(nsIDOMEventListener **aInstancePtrResult,
nsIScriptContext *aContext,
nsISupports *aObject);
#endif //nsJSEventListener_h__

Просмотреть файл

@ -908,6 +908,15 @@ nsWindowWatcher::GetActiveWindow(nsIDOMWindow **aActiveWindow)
NS_IMETHODIMP
nsWindowWatcher::SetActiveWindow(nsIDOMWindow *aActiveWindow)
{
#ifdef DEBUG
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aActiveWindow));
NS_ASSERTION(!win || win->IsOuterWindow(),
"Uh, the active window must be an outer window!");
}
#endif
if (FindWindowEntry(aActiveWindow)) {
mActiveWindow = aActiveWindow;
return NS_OK;
@ -924,6 +933,15 @@ nsWindowWatcher::AddWindow(nsIDOMWindow *aWindow, nsIWebBrowserChrome *aChrome)
if (!aWindow)
return NS_ERROR_INVALID_ARG;
#ifdef DEBUG
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aWindow));
NS_ASSERTION(win->IsOuterWindow(),
"Uh, the active window must be an outer window!");
}
#endif
{
nsWatcherWindowEntry *info;
nsAutoLock lock(mListLock);
@ -1730,43 +1748,20 @@ nsWindowWatcher::AttachArguments(nsIDOMWindow *aWindow,
NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_UNEXPECTED);
nsIScriptContext *scriptContext = scriptGlobal->GetContext();
nsresult rv = NS_OK;
if (scriptContext) {
JSContext *cx;
cx = (JSContext *)scriptContext->GetNativeContext();
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), aWindow,
NS_GET_IID(nsIDOMWindow), getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
JSObject *window_obj;
rv = wrapper->GetJSObject(&window_obj);
NS_ENSURE_SUCCESS(rv, rv);
JSObject *args;
args = ::JS_NewArrayObject(cx, argc, argv);
if (args) {
// If this is an existing window that we're opening into, the document
// change in it will wipe out the JS scope. In particular it would clear
// the "arguments" property we're about to set. So set the document in
// the window to null right away, so that when the new document loads we
// don't clear the scope.
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(aWindow));
if (globalObject) {
globalObject->SetNewDocument(nsnull, PR_TRUE, PR_TRUE);
}
jsval argsVal = OBJECT_TO_JSVAL(args);
// ::JS_DefineProperty(cx, window_obj, "arguments",
// argsVal, NULL, NULL, JSPROP_PERMANENT);
::JS_SetProperty(cx, window_obj, "arguments", &argsVal);
rv = scriptGlobal->SetNewArguments(args);
}
}
return NS_OK;
return rv;
}
nsresult

Просмотреть файл

@ -815,7 +815,13 @@ struct JSClass {
struct JSExtendedClass {
JSClass base;
JSEqualityOp equality;
jsword reserved[7];
JSObjectOp outerObject;
jsword reserved0;
jsword reserved1;
jsword reserved2;
jsword reserved3;
jsword reserved4;
jsword reserved5;
};
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
@ -853,7 +859,7 @@ struct JSExtendedClass {
/* Initializer for unused members of statically initialized JSClass structs. */
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
#define JSCLASS_NO_RESERVED_MEMBERS {0,0,0,0,0,0,0}
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0,0,0
/* For detailed comments on these function pointer types, see jspubtd.h. */
struct JSObjectOps {

Просмотреть файл

@ -3781,7 +3781,22 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
break;
case JSOP_THIS:
PUSH_OPND(OBJECT_TO_JSVAL(fp->thisp));
obj = fp->thisp;
clasp = OBJ_GET_CLASS(cx, obj);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp;
xclasp = (JSExtendedClass *) clasp;
if (xclasp->outerObject) {
obj = xclasp->outerObject(cx, obj);
if (!obj) {
ok = JS_FALSE;
goto out;
}
}
}
PUSH_OPND(OBJECT_TO_JSVAL(obj));
obj = NULL;
break;

Просмотреть файл

@ -143,6 +143,9 @@ obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
jsid propid;
JSAccessMode mode;
uintN attrs;
JSObject *pobj;
JSClass *clasp;
JSExtendedClass *xclasp;
slot = (uint32) JSVAL_TO_INT(id);
if (id == INT_TO_JSVAL(JSSLOT_PROTO)) {
@ -152,9 +155,24 @@ obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
propid = ATOM_TO_JSID(cx->runtime->atomState.parentAtom);
mode = JSACC_PARENT;
}
/* Let OBJ_CHECK_ACCESS get the slot's value, based on the access mode. */
if (!OBJ_CHECK_ACCESS(cx, obj, propid, mode, vp, &attrs))
return JS_FALSE;
*vp = OBJ_GET_SLOT(cx, obj, slot);
pobj = JSVAL_TO_OBJECT(*vp);
if (pobj) {
clasp = OBJ_GET_CLASS(cx, pobj);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
xclasp = (JSExtendedClass *) clasp;
if (xclasp->outerObject) {
pobj = xclasp->outerObject(cx, pobj);
if (!pobj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(pobj);
}
}
}
return JS_TRUE;
}
@ -2175,7 +2193,7 @@ HidePropertyName(JSContext *cx, jsid *idp)
{
jsid id;
JSAtom *atom, *hidden;
id = *idp;
JS_ASSERT(JSID_IS_ATOM(id));

Просмотреть файл

@ -252,6 +252,7 @@ JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass = {
NULL, NULL, NULL, NULL,
NULL, NULL, namespace_mark, NULL },
namespace_equality,
NULL,
JSCLASS_NO_RESERVED_MEMBERS
};
@ -454,6 +455,7 @@ JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = {
NULL, NULL, NULL, NULL,
NULL, NULL, qname_mark, NULL },
qname_equality,
NULL,
JSCLASS_NO_RESERVED_MEMBERS
};

Просмотреть файл

@ -53,7 +53,7 @@
* to *_retval unless they want to return PR_FALSE.
*/
[uuid(3a592a93-bf40-4ca1-9025-ef05dc2b0cd9)]
[uuid(f617776f-c0f8-465f-8e60-268a1bf05a76)]
interface nsIXPCScriptable : nsISupports
{
/* bitflags used for 'flags' (only 32 bits available!) */
@ -86,6 +86,8 @@ interface nsIXPCScriptable : nsISupports
const PRUint32 ALLOW_PROP_MODS_TO_PROTOTYPE = 1 << 25;
const PRUint32 DONT_SHARE_PROTOTYPE = 1 << 26;
const PRUint32 DONT_REFLECT_INTERFACE_NAMES = 1 << 27;
const PRUint32 WANT_EQUALITY = 1 << 28;
const PRUint32 WANT_OUTER_OBJECT = 1 << 29;
// The high order bit is RESERVED for consumers of these flags.
// No implementor of this interface should ever return flags
@ -160,4 +162,10 @@ interface nsIXPCScriptable : nsISupports
PRUint32 mark(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj, in voidPtr arg);
PRBool equality(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj, in JSVal val);
JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj);
};

Просмотреть файл

@ -177,7 +177,7 @@ interface nsIXPCComponents : nsISupports
readonly attribute nsIStackFrame stack;
readonly attribute nsIXPCComponents_Results results;
readonly attribute nsIComponentManager manager;
readonly attribute nsIXPCComponents_Utils utils;
readonly attribute nsIXPCComponents_Utils utils;
readonly attribute nsIXPCComponents_ID ID;
readonly attribute nsIXPCComponents_Exception Exception;

Просмотреть файл

@ -112,6 +112,12 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::GetScriptableFlags(PRUint32 *aFlags)
#ifdef XPC_MAP_WANT_MARK
nsIXPCScriptable::WANT_MARK |
#endif
#ifdef XPC_MAP_WANT_EQUALITY
nsIXPCScriptable::WANT_EQUALITY |
#endif
#ifdef XPC_MAP_WANT_OUTER_OBJECT
nsIXPCScriptable::WANT_OUTER_OBJECT |
#endif
#ifdef XPC_MAP_FLAGS
XPC_MAP_FLAGS |
@ -208,6 +214,16 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Mark(nsIXPConnectWrappedNative *wrapper, JSCont
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
#ifndef XPC_MAP_WANT_EQUALITY
NS_IMETHODIMP XPC_MAP_CLASSNAME::Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsval val, PRBool *bp)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
#ifndef XPC_MAP_WANT_OUTER_OBJECT
NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
/**************************************************************/
#undef XPC_MAP_CLASSNAME
@ -281,6 +297,14 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Mark(nsIXPConnectWrappedNative *wrapper, JSCont
#undef XPC_MAP_WANT_MARK
#endif
#ifdef XPC_MAP_WANT_EQUALITY
#undef XPC_MAP_WANT_EQUALITY
#endif
#ifdef XPC_MAP_WANT_OUTER_OBJECT
#undef XPC_MAP_WANT_OUTER_OBJECT
#endif
#ifdef XPC_MAP_FLAGS
#undef XPC_MAP_FLAGS
#endif

Просмотреть файл

@ -139,7 +139,7 @@
#define DEBUG_xpc_hacker
#endif
#if defined(DEBUG_brendan) || defined(DEBUG_bzbarsky) || defined(DEBUG_jst)
#if defined(DEBUG_brendan) || defined(DEBUG_bzbarsky)
#define DEBUG_XPCNativeWrapper 1
#endif
@ -1433,6 +1433,8 @@ public:
JSBool WantConstruct() GET_IT(WANT_CONSTRUCT)
JSBool WantHasInstance() GET_IT(WANT_HASINSTANCE)
JSBool WantMark() GET_IT(WANT_MARK)
JSBool WantEquality() GET_IT(WANT_EQUALITY)
JSBool WantOuterObject() GET_IT(WANT_OUTER_OBJECT)
JSBool UseJSStubForAddProperty() GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
JSBool UseJSStubForDelProperty() GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
JSBool UseJSStubForSetProperty() GET_IT(USE_JSSTUB_FOR_SETPROPERTY)

Просмотреть файл

@ -740,13 +740,12 @@ GetIdentityObject(JSContext *cx, JSObject *obj)
{
XPCWrappedNative *wrapper;
if (XPCNativeWrapper::IsNativeWrapper(cx, obj)) {
if(XPCNativeWrapper::IsNativeWrapper(cx, obj))
wrapper = XPCNativeWrapper::GetWrappedNative(cx, obj);
} else {
else
wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
}
if (!wrapper) {
if(!wrapper) {
return nsnull;
}
@ -756,18 +755,68 @@ GetIdentityObject(JSContext *cx, JSObject *obj)
JS_STATIC_DLL_CALLBACK(JSBool)
XPC_WN_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
{
if (JSVAL_IS_PRIMITIVE(v)) {
*bp = JS_FALSE;
XPCWrappedNative *wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
if(si && si->GetFlags().WantEquality())
{
nsresult rv = si->GetCallback()->Equality(wrapper, cx, obj, v, bp);
if(NS_FAILED(rv))
return Throw(rv, cx);
}
else if(!JSVAL_IS_PRIMITIVE(v))
{
JSObject *other = JSVAL_TO_OBJECT(v);
*bp = (obj == other ||
GetIdentityObject(cx, obj) == GetIdentityObject(cx, other));
}
return JS_TRUE;
}
}
JSObject *other = JSVAL_TO_OBJECT(v);
JS_STATIC_DLL_CALLBACK(JSObject *)
XPC_WN_OuterObject(JSContext *cx, JSObject *obj)
{
XPCWrappedNative *wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
if(!wrapper)
{
Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
*bp = (obj == other ||
GetIdentityObject(cx, obj) == GetIdentityObject(cx, other));
return nsnull;
}
return JS_TRUE;
if(!wrapper->IsValid())
{
Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx);
return nsnull;
}
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
if(si && si->GetFlags().WantOuterObject())
{
JSObject *newThis;
nsresult rv =
si->GetCallback()->OuterObject(wrapper, cx, obj, &newThis);
if(NS_FAILED(rv))
{
Throw(rv, cx);
return nsnull;
}
obj = newThis;
}
return obj;
}
@ -798,7 +847,8 @@ JSExtendedClass XPC_WN_NoHelper_JSClass = {
XPC_WN_Shared_Mark, // mark;
nsnull // spare;
},
XPC_WN_Equality
XPC_WN_Equality,
XPC_WN_OuterObject
};
@ -1326,6 +1376,7 @@ XPCNativeScriptableShared::PopulateJSClass()
mJSClass.base.mark = XPC_WN_Shared_Mark;
mJSClass.equality = XPC_WN_Equality;
mJSClass.outerObject = XPC_WN_OuterObject;
}
/***************************************************************************/

Просмотреть файл

@ -840,7 +840,6 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
getter_AddRefs(global));
if (global) {
mDocument->SetScriptGlobalObject(global);
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(mDocument));
if (domdoc) {
@ -1259,14 +1258,6 @@ DocumentViewerImpl::Close(nsISHEntry *aSHEntry)
}
#endif
// Break global object circular reference on the document created
// in the DocViewer Init
nsIScriptGlobalObject* globalObject = mDocument->GetScriptGlobalObject();
if (globalObject) {
globalObject->SetNewDocument(nsnull, PR_TRUE, PR_TRUE);
}
#ifdef NS_PRINTING
// A Close was called while we were printing
// so don't clear the ScriptGlobalObject
@ -1511,19 +1502,21 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument)
nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
newDoc->SetContainer(container);
// Replace the old document with the new one
mDocument = newDoc;
if (mDocument != newDoc) {
// Replace the old document with the new one. Do this only when
// the new document really is a new document.
mDocument = newDoc;
// Set the script global object on the new document
nsCOMPtr<nsIScriptGlobalObject> global = do_GetInterface(container);
if (global) {
mDocument->SetScriptGlobalObject(global);
global->SetNewDocument(aDocument, PR_TRUE, PR_TRUE);
rv = SyncParentSubDocMap();
NS_ENSURE_SUCCESS(rv, rv);
// Set the script global object on the new document
nsCOMPtr<nsIScriptGlobalObject> global = do_GetInterface(container);
if (global) {
global->SetNewDocument(aDocument, PR_TRUE, PR_TRUE);
}
}
rv = SyncParentSubDocMap();
NS_ENSURE_SUCCESS(rv, rv);
// Replace the current pres shell with a new shell for the new document
nsCOMPtr<nsILinkHandler> linkHandler;
@ -3210,7 +3203,7 @@ nsDocViewerFocusListener::Focus(nsIDOMEvent* aEvent)
nsCOMPtr<nsISelectionController> selCon;
selCon = do_QueryInterface(shell);
PRInt16 selectionStatus;
selCon->GetDisplaySelection( &selectionStatus);
selCon->GetDisplaySelection(&selectionStatus);
//if selection was nsISelectionController::SELECTION_OFF, do nothing
//otherwise re-enable it.

Просмотреть файл

@ -713,7 +713,7 @@ protected:
#endif
private:
protected:
~nsPresContext() NS_HIDDEN;

Просмотреть файл

@ -2671,6 +2671,9 @@ static void CheckForFocus(nsPIDOMWindow* aOurWindow,
nsIFocusController* aFocusController,
nsIDocument* aDocument)
{
NS_ASSERTION(aOurWindow->IsOuterWindow(),
"Uh, our window has to be an outer window!");
// Now that we have a root frame, we can set focus on the presshell.
// We do this only if our DOM window is currently focused or is an
// an ancestor of a previously focused window.
@ -2711,8 +2714,10 @@ static void CheckForFocus(nsPIDOMWindow* aOurWindow,
}
while (curDoc) {
nsCOMPtr<nsIDOMWindowInternal> curWin = do_QueryInterface(curDoc->GetScriptGlobalObject());
if (curWin == ourWin || !curWin)
nsCOMPtr<nsPIDOMWindow> curWin =
do_QueryInterface(curDoc->GetScriptGlobalObject());
if (!curWin || curWin->GetOuterWindow() == ourWin)
break;
curDoc = curDoc->GetParentDocument();
@ -4359,12 +4364,13 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
// Now focus the document itself if focus is on an element within it.
nsCOMPtr<nsPIDOMWindow> win =
do_QueryInterface(mDocument->GetScriptGlobalObject());
if (win) {
nsCOMPtr<nsIFocusController> focusController = win->GetRootFocusController();
if (focusController) {
nsCOMPtr<nsIDOMWindowInternal> focusedWin;
focusController->GetFocusedWindow(getter_AddRefs(focusedWin));
if (SameCOMIdentity(win, focusedWin)) {
if (SameCOMIdentity(win->GetOuterWindow(), focusedWin)) {
esm->ChangeFocusWith(nsnull, nsIEventStateManager::eEventFocusedByApplication);
}
}