Fix for 106153, avoid building a content model for XBL event handlers, r=bryner, sr=waterson

This commit is contained in:
hyatt%netscape.com 2001-11-02 01:53:13 +00:00
Родитель 3b29928835
Коммит 19490453c9
52 изменённых файлов: 1915 добавлений и 1097 удалений

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

@ -80,6 +80,7 @@ class nsISupportsArray;
class nsIScriptLoader;
class nsString;
class nsIFocusController;
class nsIContentSink;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
@ -109,7 +110,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset) = 0;
PRBool aReset,
nsIContentSink* aSink = nsnull) = 0;
NS_IMETHOD StopDocumentLoad() = 0;

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

@ -55,6 +55,7 @@ class nsIElementFactory;
#define kNameSpaceID_XLink 4
#define kNameSpaceID_HTML2 5 // This is not a real namespace
#define kNameSpaceID_XSLT 6
#define kNameSpaceID_XBL 7
#define kNameSpaceID_XHTML kNameSpaceID_HTML
// 'html' is by definition bound to the namespace name "urn:w3-org-ns:HTML" XXX ???

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

@ -719,7 +719,8 @@ nsDocument::StartDocumentLoad(const char* aCommand,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset)
PRBool aReset,
nsIContentSink* aSink)
{
nsresult rv = NS_OK;
if (aReset)
@ -3268,7 +3269,6 @@ PRBool nsDocument::InternalRegisterCompileEventHandler(JSContext* aContext, jsv
}
#endif
NS_IMETHODIMP
nsDocument::SaveFile( nsIURI* aLocation,
PRBool aReplaceExisting, // only used for local file locations

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

@ -248,7 +248,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
PRBool aReset = PR_TRUE,
nsIContentSink* aContentSink = nsnull);
NS_IMETHOD StopDocumentLoad();

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

@ -58,6 +58,7 @@ static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40"; // X
static const char kXHTMLNameSpaceURI[] = "http://www.w3.org/1999/xhtml";
static const char kXLinkNameSpaceURI[] = "http://www.w3.org/1999/xlink";
static const char kXSLTNameSpaceURI[] = "http://www.w3.org/1999/XSL/Transform";
static const char kXBLNameSpaceURI[] = "http://www.mozilla.org/xbl";
//-----------------------------------------------------------
// Name Space ID table support
@ -89,24 +90,31 @@ static void InitializeNameSpaceManager()
nsString* xlink = new nsString( NS_ConvertASCIItoUCS2(kXLinkNameSpaceURI) );
nsString* html = new nsString( NS_ConvertASCIItoUCS2(kHTMLNameSpaceURI) );
nsString* xslt = new nsString( NS_ConvertASCIItoUCS2(kXSLTNameSpaceURI) );
nsString* xbl = new nsString(NS_ConvertASCIItoUCS2(kXBLNameSpaceURI));
gURIArray->AppendElement(xmlns); // ordering here needs to match IDs
gURIArray->AppendElement(xml);
gURIArray->AppendElement(xhtml);
gURIArray->AppendElement(xlink);
gURIArray->AppendElement(html);
gURIArray->AppendElement(xslt);
gURIArray->AppendElement(xbl);
nsStringKey xmlnsKey(*xmlns);
nsStringKey xmlKey(*xml);
nsStringKey xhtmlKey(*xhtml);
nsStringKey xlinkKey(*xlink);
nsStringKey htmlKey(*html);
nsStringKey xsltKey(*xslt);
nsStringKey xblKey(*xbl);
gURIToIDTable->Put(&xmlnsKey, (void*)kNameSpaceID_XMLNS);
gURIToIDTable->Put(&xmlKey, (void*)kNameSpaceID_XML);
gURIToIDTable->Put(&xhtmlKey, (void*)kNameSpaceID_HTML);
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
gURIToIDTable->Put(&xsltKey, (void*)kNameSpaceID_XSLT);
gURIToIDTable->Put(&xblKey, (void*)kNameSpaceID_XBL);
NS_NewISupportsArray(&gElementFactoryArray);

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

@ -36,6 +36,7 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsXBLAtoms.h" // to addref/release table
#include "nsCSSAtoms.h" // to addref/release table
#include "nsCSSKeywords.h" // to addref/release table
#include "nsCSSProps.h" // to addref/release table
@ -170,6 +171,7 @@ Initialize(nsIModule* aSelf)
nsCSSProps::AddRefTable();
nsColorNames::AddRefTable();
nsHTMLAtoms::AddRefAtoms();
nsXBLAtoms::AddRefAtoms();
nsLayoutAtoms::AddRefAtoms();
#ifdef MOZ_XUL
@ -213,6 +215,7 @@ Shutdown(nsIModule* aSelf)
nsCSSKeywords::ReleaseTable();
nsCSSAtoms::ReleaseAtoms();
nsHTMLAtoms::ReleaseAtoms();
nsXBLAtoms::ReleaseAtoms();
nsLayoutAtoms::ReleaseAtoms();
#ifdef MOZ_XUL

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

@ -401,7 +401,8 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset)
PRBool aReset,
nsIContentSink* aSink)
{
PRBool needsParser=PR_TRUE;
if (aCommand)
@ -821,9 +822,15 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
mParser->SetCommand(aCommand);
// create the content sink
nsCOMPtr<nsIWebShell> webShell(do_QueryInterface(docShell));
if (aSink)
sink = do_QueryInterface(aSink);
else {
rv = NS_NewHTMLContentSink(getter_AddRefs(sink), this, aURL, webShell,aChannel);
if (NS_FAILED(rv)) { return rv; }
NS_ASSERTION(sink, "null sink with successful result from factory method");
}
mParser->SetContentSink(sink);
// parser the content of the URL
mParser->Parse(aURL, nsnull, PR_FALSE, (void *)this);

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

@ -91,7 +91,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
PRBool aReset = PR_TRUE,
nsIContentSink* aSink = nsnull);
NS_IMETHOD StopDocumentLoad();

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

@ -98,7 +98,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
PRBool aReset = PR_TRUE,
nsIContentSink* aSink = nsnull);
nsresult CreateSyntheticDocument();
@ -249,7 +250,8 @@ nsImageDocument::StartDocumentLoad(const char* aCommand,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset)
PRBool aReset,
nsIContentSink* aSink)
{
NS_ASSERTION(aDocListener, "null aDocListener");
NS_ENSURE_ARG_POINTER(aContainer);
@ -262,7 +264,7 @@ nsImageDocument::StartDocumentLoad(const char* aCommand,
}
rv = nsDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup,
aContainer, aDocListener, aReset);
aContainer, aDocListener, aReset, aSink);
if (NS_FAILED(rv)) {
return rv;
}

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

@ -22,3 +22,6 @@ nsStyleStruct.h
nsTextFragment.h
nsXULAtomList.h
nsXULAtoms.h
nsXBLAtomList.h
nsXBLAtoms.h

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

@ -50,6 +50,8 @@ nsStyleStruct.h \
nsTextFragment.h \
nsXULAtomList.h \
nsXULAtoms.h \
nsXBLAtomList.h \
nsXBLAtoms.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

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

@ -43,6 +43,8 @@ EXPORTS = \
nsTextFragment.h \
nsXULAtomList.h \
nsXULAtoms.h \
nsXBLAtomList.h \
nsXBLAtoms.h \
$(NULL)
include <$(DEPTH)\config\rules.mak>

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

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/******
This file contains the list of all XBL nsIAtoms and their values
It is designed to be used as inline input to nsXBLAtoms.cpp *only*
through the magic of C preprocessing.
All entires must be enclosed in the macro XBL_ATOM which will have cruel
and unusual things done to it
It is recommended (but not strictly necessary) to keep all entries
in alphabetical order
The first argument to XBL_ATOM is the C++ identifier of the atom
The second argument is the string value of the atom
******/
XBL_ATOM(binding, "binding")
XBL_ATOM(bindings, "bindings")
XBL_ATOM(handlers, "handlers")
XBL_ATOM(handler, "handler")
XBL_ATOM(resources, "resources")
XBL_ATOM(image, "image")
XBL_ATOM(stylesheet, "stylesheet")
XBL_ATOM(implementation, "implementation")
XBL_ATOM(implements, "implements")
XBL_ATOM(xbltext, "xbl:text")
XBL_ATOM(method, "method")
XBL_ATOM(property, "property")
XBL_ATOM(field, "field")
XBL_ATOM(event, "event")
XBL_ATOM(phase, "phase")
XBL_ATOM(action, "action")
XBL_ATOM(command, "command")
XBL_ATOM(modifiers, "modifiers")
XBL_ATOM(clickcount, "clickcount")
XBL_ATOM(charcode, "charcode")
XBL_ATOM(keycode, "keycode")
XBL_ATOM(key, "key")
XBL_ATOM(onget, "onget")
XBL_ATOM(onset, "onset")
XBL_ATOM(name, "name")
XBL_ATOM(getter, "getter")
XBL_ATOM(setter, "setter")
XBL_ATOM(body, "body")
XBL_ATOM(readonly, "readonly")
XBL_ATOM(parameter, "parameter")
XBL_ATOM(children, "children")
XBL_ATOM(extends, "extends")
XBL_ATOM(display, "display")
XBL_ATOM(inherits, "inherits")
XBL_ATOM(includes, "includes")
XBL_ATOM(excludes, "excludes")
XBL_ATOM(content, "content")
XBL_ATOM(constructor, "constructor")
XBL_ATOM(destructor, "destructor")
XBL_ATOM(inheritstyle, "inheritstyle")

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

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsXBLAtoms_h___
#define nsXBLAtoms_h___
#include "prtypes.h"
#include "nsIAtom.h"
class nsINameSpaceManager;
/**
* This class wraps up the creation and destruction of the standard
* set of XBL atoms used during normal XBL handling. This object
* is created when the first XBL content object is created, and
* destroyed when the last such content object is destroyed.
*/
class nsXBLAtoms {
public:
static void AddRefAtoms();
static void ReleaseAtoms();
// XBL namespace ID, good for the life of the nsXBLAtoms object
static PRInt32 nameSpaceID;
/* Declare all atoms
The atom names and values are stored in nsCSSAtomList.h and
are brought to you by the magic of C preprocessing
Add new atoms to nsCSSAtomList and all support logic will be auto-generated
*/
#define XBL_ATOM(_name, _value) static nsIAtom* _name;
#include "nsXBLAtomList.h"
#undef XBL_ATOM
};
#endif /* nsXBLAtoms_h___ */

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

@ -56,6 +56,7 @@ CPPSRCS = \
nsStyleUtil.cpp \
nsTextFragment.cpp \
nsXULAtoms.cpp \
nsXBLAtoms.cpp \
nsStyleCoord.cpp \
nsStyleStruct.cpp \
$(NULL)

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

@ -57,6 +57,7 @@ CPPSRCS = \
nsStyleStruct.cpp \
nsTextFragment.cpp \
nsXULAtoms.cpp \
nsXBLAtoms.cpp \
nsStyleCoord.cpp \
$(NULL)
@ -74,6 +75,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsStyleStruct.obj \
.\$(OBJDIR)\nsTextFragment.obj \
.\$(OBJDIR)\nsXULAtoms.obj \
.\$(OBJDIR)\nsXBLAtoms.obj \
.\$(OBJDIR)\nsStyleCoord.obj \
$(NULL)

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

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsString.h"
#include "nsXBLAtoms.h"
#include "nsContentCID.h"
// define storage for all atoms
#define XBL_ATOM(_name, _value) nsIAtom* nsXBLAtoms::_name;
#include "nsXBLAtomList.h"
#undef XBL_ATOM
static nsrefcnt gRefCnt = 0;
void nsXBLAtoms::AddRefAtoms() {
if (gRefCnt == 0) {
// now register the atoms
#define XBL_ATOM(_name, _value) _name = NS_NewPermanentAtom(_value);
#include "nsXBLAtomList.h"
#undef XBL_ATOM
}
++gRefCnt;
}
void nsXBLAtoms::ReleaseAtoms() {
NS_PRECONDITION(gRefCnt != 0, "bad release of XBL atoms");
if (--gRefCnt == 0) {
#define XBL_ATOM(_name, _value) NS_RELEASE(_name);
#include "nsXBLAtomList.h"
#undef XBL_ATOM
}
}

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

@ -162,6 +162,7 @@ public:
NS_IMETHOD ExecuteDetachedHandlers()=0;
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)=0;
NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)=0;
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult)=0;
NS_IMETHOD PutLoadingDocListener(const nsCString& aURL, nsIStreamListener* aListener) = 0;

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

@ -126,6 +126,8 @@ public:
NS_IMETHOD AddResourceListener(nsIContent* aBoundElement)=0;
NS_IMETHOD GetConstructor(nsIXBLPrototypeHandler** aResult)=0;
NS_IMETHOD Initialize()=0;
};
extern nsresult

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

@ -46,6 +46,8 @@
#ifndef nsIXBLPrototypeHandler_h__
#define nsIXBLPrototypeHandler_h__
#include "nsAReadableString.h"
class nsIContent;
class nsIDOMEvent;
class nsIDOMMouseEvent;
@ -67,6 +69,9 @@ public:
NS_IMETHOD KeyEventMatched(nsIAtom* aEventType, nsIDOMKeyEvent* aEvent, PRBool* aResult) = 0;
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
NS_IMETHOD SetHandlerText(const nsAReadableString& aText) = 0;
NS_IMETHOD GetPhase(PRUint8* aPhase) = 0;
NS_IMETHOD BindingAttached(nsIDOMEventReceiver* aRec)=0;
NS_IMETHOD BindingDetached(nsIDOMEventReceiver* aRec)=0;
@ -81,6 +86,14 @@ public:
};
extern nsresult
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
NS_NewXBLPrototypeHandler(nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount,
nsIXBLPrototypeHandler** aResult);
extern nsresult
NS_NewXULKeyHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
#endif // nsIXBLPrototypeHandler_h__

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

@ -35,6 +35,7 @@ REQUIRES = xpcom \
gfx \
layout \
widget \
view \
caps \
htmlparser \
necko \
@ -47,11 +48,14 @@ REQUIRES = xpcom \
xuldoc \
gfx2 \
imglib2 \
unicharutil \
$(NULL)
CPPSRCS = \
nsXBLBinding.cpp \
nsXBLPrototypeBinding.cpp \
nsXBLDocumentInfo.cpp \
nsXBLContentSink.cpp \
nsXBLPrototypeProperty.cpp \
nsXBLEventHandler.cpp \
nsXBLWindowHandler.cpp \
@ -89,5 +93,6 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../../html/base/src \
-I$(srcdir)/../../html/document/src \
-I$(srcdir)/../../xml/document/src \
-I$(srcdir)/../../xsl/document/src \
$(NULL)

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

@ -28,6 +28,7 @@ REQUIRES = xpcom \
js \
dom \
widget \
view \
caps \
htmlparser \
necko \
@ -41,6 +42,7 @@ REQUIRES = xpcom \
layout \
gfx \
content_xul \
unicharutil \
$(NULL)
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
@ -48,6 +50,8 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \
nsXBLBinding.cpp \
nsXBLPrototypeBinding.cpp \
nsXBLDocumentInfo.cpp \
nsXBLContentSink.cpp \
nsXBLService.cpp \
nsXBLEventHandler.cpp \
nsXBLWindowHandler.cpp \
@ -73,6 +77,8 @@ CPPSRCS= \
CPP_OBJS= \
.\$(OBJDIR)\nsXBLBinding.obj \
.\$(OBJDIR)\nsXBLPrototypeBinding.obj \
.\$(OBJDIR)\nsXBLDocumentInfo.obj \
.\$(OBJDIR)\nsXBLContentSink.obj \
.\$(OBJDIR)\nsXBLEventHandler.obj \
.\$(OBJDIR)\nsXBLWindowHandler.obj \
.\$(OBJDIR)\nsXBLWindowKeyHandler.obj \
@ -101,6 +107,7 @@ EXPORTS = \
LINCS=-I..\..\html\style\src -I..\..\html\base\src \
-I..\..\html\document\src \
-I..\..\xml\document\src \
-I..\..\xsl\document\src \
-I..\..\base\src \
$(NULL)

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

@ -97,394 +97,6 @@ static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
// an XBLDocumentInfo object has a special context associated with it which we can use to pre-compile properties and methods
// of XBL widgets against.....
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
class nsXBLDocGlobalObject : public nsIScriptGlobalObject,
public nsIScriptObjectPrincipal
{
public:
nsXBLDocGlobalObject();
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIScriptGlobalObject methods
NS_IMETHOD SetContext(nsIScriptContext *aContext);
NS_IMETHOD GetContext(nsIScriptContext **aContext);
NS_IMETHOD SetNewDocument(nsIDOMDocument *aDocument,
PRBool removeEventListeners);
NS_IMETHOD SetDocShell(nsIDocShell *aDocShell);
NS_IMETHOD GetDocShell(nsIDocShell **aDocShell);
NS_IMETHOD SetOpenerWindow(nsIDOMWindowInternal *aOpener);
NS_IMETHOD SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner);
NS_IMETHOD GetGlobalObjectOwner(nsIScriptGlobalObjectOwner** aOwner);
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD_(JSObject *) GetGlobalJSObject();
NS_IMETHOD OnFinalize(JSObject *aObject);
// nsIScriptObjectPrincipal methods
NS_IMETHOD GetPrincipal(nsIPrincipal** aPrincipal);
protected:
virtual ~nsXBLDocGlobalObject();
nsCOMPtr<nsIScriptContext> mScriptContext;
JSObject *mJSObject; // XXX JS language rabies bigotry badness
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // weak reference
static JSClass gSharedGlobalClass;
};
void PR_CALLBACK nsXBLDocGlobalObject_finalize(JSContext *cx, JSObject *obj)
{
nsISupports *nativeThis = (nsISupports*)JS_GetPrivate(cx, obj);
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nativeThis));
if (sgo)
sgo->OnFinalize(obj);
// The addref was part of JSObject construction
NS_RELEASE(nativeThis);
}
JSBool PR_CALLBACK nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id)
{
JSBool did_resolve = JS_FALSE;
return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
}
JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
"nsXBLPrototypeScript compilation scope",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, nsXBLDocGlobalObject_resolve, JS_ConvertStub,
nsXBLDocGlobalObject_finalize
};
//----------------------------------------------------------------------
//
// nsXBLDocGlobalObject
//
nsXBLDocGlobalObject::nsXBLDocGlobalObject()
: mJSObject(nsnull),
mGlobalObjectOwner(nsnull)
{
NS_INIT_REFCNT();
}
nsXBLDocGlobalObject::~nsXBLDocGlobalObject()
{}
NS_IMPL_ISUPPORTS2(nsXBLDocGlobalObject, nsIScriptGlobalObject, nsIScriptObjectPrincipal)
//----------------------------------------------------------------------
//
// nsIScriptGlobalObject methods
//
NS_IMETHODIMP
nsXBLDocGlobalObject::SetContext(nsIScriptContext *aContext)
{
mScriptContext = aContext;
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetContext(nsIScriptContext **aContext)
{
// This whole fragile mess is predicated on the fact that
// GetContext() will be called before GetScriptObject() is.
if (! mScriptContext) {
nsCOMPtr<nsIDOMScriptObjectFactory> factory = do_GetService(kDOMScriptObjectFactoryCID);
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
nsresult rv = factory->NewScriptContext(nsnull, getter_AddRefs(mScriptContext));
if (NS_FAILED(rv))
return rv;
JSContext *cx = (JSContext *)mScriptContext->GetNativeContext();
mJSObject = ::JS_NewObject(cx, &gSharedGlobalClass, nsnull, nsnull);
if (!mJSObject)
return NS_ERROR_OUT_OF_MEMORY;
::JS_SetGlobalObject(cx, mJSObject);
// Add an owning reference from JS back to us. This'll be
// released when the JSObject is finalized.
::JS_SetPrivate(cx, mJSObject, this);
NS_ADDREF(this);
}
*aContext = mScriptContext;
NS_IF_ADDREF(*aContext);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetNewDocument(nsIDOMDocument *aDocument,
PRBool removeEventListeners)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetDocShell(nsIDocShell *aDocShell)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetDocShell(nsIDocShell **aDocShell)
{
NS_WARNING("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetOpenerWindow(nsIDOMWindowInternal *aOpener)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner)
{
mGlobalObjectOwner = aOwner; // weak reference
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetGlobalObjectOwner(nsIScriptGlobalObjectOwner** aOwner)
{
*aOwner = mGlobalObjectOwner;
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP_(JSObject *)
nsXBLDocGlobalObject::GetGlobalJSObject()
{
// The prototype document has its own special secret script object
// that can be used to compile scripts and event handlers.
if (!mScriptContext)
return nsnull;
JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
mScriptContext->GetNativeContext());
if (!cx)
return nsnull;
return ::JS_GetGlobalObject(cx);
}
NS_IMETHODIMP
nsXBLDocGlobalObject::OnFinalize(JSObject *aObject)
{
NS_ASSERTION(aObject == mJSObject, "Wrong object finalized!");
mJSObject = nsnull;
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsIScriptObjectPrincipal methods
//
NS_IMETHODIMP
nsXBLDocGlobalObject::GetPrincipal(nsIPrincipal** aPrincipal)
{
nsresult rv = NS_OK;
if (!mGlobalObjectOwner) {
*aPrincipal = nsnull;
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIXBLDocumentInfo> docInfo = do_QueryInterface(mGlobalObjectOwner, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> document;
rv = docInfo->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return document->GetPrincipal(aPrincipal);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
class nsXBLDocumentInfo : public nsIXBLDocumentInfo, public nsIScriptGlobalObjectOwner, public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument);
virtual ~nsXBLDocumentInfo();
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; };
NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult);
NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding);
// nsIScriptGlobalObjectOwner methods
NS_DECL_NSISCRIPTGLOBALOBJECTOWNER
private:
nsCOMPtr<nsIDocument> mDocument;
nsCString mDocURI;
PRBool mScriptAccess;
nsSupportsHashtable* mBindingTable;
nsCOMPtr<nsIScriptGlobalObject> mGlobalObject;
};
/* Implementation file */
NS_IMPL_ISUPPORTS3(nsXBLDocumentInfo, nsIXBLDocumentInfo, nsIScriptGlobalObjectOwner, nsISupportsWeakReference)
nsXBLDocumentInfo::nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mDocURI = aDocURI;
mDocument = aDocument;
mScriptAccess = PR_TRUE;
mBindingTable = nsnull;
}
nsXBLDocumentInfo::~nsXBLDocumentInfo()
{
/* destructor code */
if (mGlobalObject) {
mGlobalObject->SetContext(nsnull); // remove circular reference
mGlobalObject->SetGlobalObjectOwner(nsnull); // just in case
}
delete mBindingTable;
}
NS_IMETHODIMP
nsXBLDocumentInfo::GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult)
{
*aResult = nsnull;
if (!mBindingTable)
return NS_OK;
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
*aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here.
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding)
{
if (!mBindingTable)
mBindingTable = new nsSupportsHashtable();
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
mBindingTable->Put(&key, aBinding);
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsIScriptGlobalObjectOwner methods
//
NS_IMETHODIMP
nsXBLDocumentInfo::GetScriptGlobalObject(nsIScriptGlobalObject** _result)
{
if (!mGlobalObject) {
mGlobalObject = new nsXBLDocGlobalObject();
if (!mGlobalObject) {
*_result = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
mGlobalObject->SetGlobalObjectOwner(this); // does not refcount
}
*_result = mGlobalObject;
NS_ADDREF(*_result);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocumentInfo::ReportScriptError(nsIScriptError *errorObject)
{
if (errorObject == nsnull)
return NS_ERROR_NULL_POINTER;
// Get the console service, where we're going to register the error.
nsCOMPtr<nsIConsoleService> consoleService (do_GetService("@mozilla.org/consoleservice;1"));
if (!consoleService)
return NS_ERROR_NOT_AVAILABLE;
return consoleService->LogMessage(errorObject);
}
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
{
nsCOMPtr<nsIURI> url;
aDocument->GetDocumentURL(getter_AddRefs(url));
nsXPIDLCString str;
url->GetSpec(getter_Copies(str));
*aResult = new nsXBLDocumentInfo((const char*)str, aDocument);
NS_IF_ADDREF(*aResult);
return NS_OK;
}
// ==================================================================
// = nsAnonymousContentList
// ==================================================================
@ -661,6 +273,7 @@ public:
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult);
NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD PutLoadingDocListener(const nsCString& aURL, nsIStreamListener* aListener);
NS_IMETHOD GetLoadingDocListener(const nsCString& aURL, nsIStreamListener** aResult);
@ -1351,6 +964,25 @@ nsBindingManager::PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo)
{
if (!mDocumentTable)
return NS_OK;
nsCOMPtr<nsIDocument> doc;
aDocumentInfo->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIURI> uri;
doc->GetDocumentURL(getter_AddRefs(uri));
nsXPIDLCString str;
uri->GetSpec(getter_Copies(str));
nsCStringKey key((const char*)str);
mDocumentTable->Remove(&key);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::GetXBLDocumentInfo(const nsCString& aURL, nsIXBLDocumentInfo** aResult)
{

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

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/******
This file contains the list of all XBL nsIAtoms and their values
It is designed to be used as inline input to nsXBLAtoms.cpp *only*
through the magic of C preprocessing.
All entires must be enclosed in the macro XBL_ATOM which will have cruel
and unusual things done to it
It is recommended (but not strictly necessary) to keep all entries
in alphabetical order
The first argument to XBL_ATOM is the C++ identifier of the atom
The second argument is the string value of the atom
******/
XBL_ATOM(binding, "binding")
XBL_ATOM(bindings, "bindings")
XBL_ATOM(handlers, "handlers")
XBL_ATOM(handler, "handler")
XBL_ATOM(resources, "resources")
XBL_ATOM(image, "image")
XBL_ATOM(stylesheet, "stylesheet")
XBL_ATOM(implementation, "implementation")
XBL_ATOM(implements, "implements")
XBL_ATOM(xbltext, "xbl:text")
XBL_ATOM(method, "method")
XBL_ATOM(property, "property")
XBL_ATOM(field, "field")
XBL_ATOM(event, "event")
XBL_ATOM(phase, "phase")
XBL_ATOM(action, "action")
XBL_ATOM(command, "command")
XBL_ATOM(modifiers, "modifiers")
XBL_ATOM(clickcount, "clickcount")
XBL_ATOM(charcode, "charcode")
XBL_ATOM(keycode, "keycode")
XBL_ATOM(key, "key")
XBL_ATOM(onget, "onget")
XBL_ATOM(onset, "onset")
XBL_ATOM(name, "name")
XBL_ATOM(getter, "getter")
XBL_ATOM(setter, "setter")
XBL_ATOM(body, "body")
XBL_ATOM(readonly, "readonly")
XBL_ATOM(parameter, "parameter")
XBL_ATOM(children, "children")
XBL_ATOM(extends, "extends")
XBL_ATOM(display, "display")
XBL_ATOM(inherits, "inherits")
XBL_ATOM(includes, "includes")
XBL_ATOM(excludes, "excludes")
XBL_ATOM(content, "content")
XBL_ATOM(constructor, "constructor")
XBL_ATOM(destructor, "destructor")
XBL_ATOM(inheritstyle, "inheritstyle")

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

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsString.h"
#include "nsXBLAtoms.h"
#include "nsContentCID.h"
// define storage for all atoms
#define XBL_ATOM(_name, _value) nsIAtom* nsXBLAtoms::_name;
#include "nsXBLAtomList.h"
#undef XBL_ATOM
static nsrefcnt gRefCnt = 0;
void nsXBLAtoms::AddRefAtoms() {
if (gRefCnt == 0) {
// now register the atoms
#define XBL_ATOM(_name, _value) _name = NS_NewPermanentAtom(_value);
#include "nsXBLAtomList.h"
#undef XBL_ATOM
}
++gRefCnt;
}
void nsXBLAtoms::ReleaseAtoms() {
NS_PRECONDITION(gRefCnt != 0, "bad release of XBL atoms");
if (--gRefCnt == 0) {
#define XBL_ATOM(_name, _value) NS_RELEASE(_name);
#include "nsXBLAtomList.h"
#undef XBL_ATOM
}
}

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

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsXBLAtoms_h___
#define nsXBLAtoms_h___
#include "prtypes.h"
#include "nsIAtom.h"
class nsINameSpaceManager;
/**
* This class wraps up the creation and destruction of the standard
* set of XBL atoms used during normal XBL handling. This object
* is created when the first XBL content object is created, and
* destroyed when the last such content object is destroyed.
*/
class nsXBLAtoms {
public:
static void AddRefAtoms();
static void ReleaseAtoms();
// XBL namespace ID, good for the life of the nsXBLAtoms object
static PRInt32 nameSpaceID;
/* Declare all atoms
The atom names and values are stored in nsCSSAtomList.h and
are brought to you by the magic of C preprocessing
Add new atoms to nsCSSAtomList and all support logic will be auto-generated
*/
#define XBL_ATOM(_name, _value) static nsIAtom* _name;
#include "nsXBLAtomList.h"
#undef XBL_ATOM
};
#endif /* nsXBLAtoms_h___ */

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

@ -88,11 +88,14 @@
#include "nsIDOMMutationListener.h"
#include "nsIDOMContextMenuListener.h"
#include "nsXBLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIDOMAttr.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsIXBLPrototypeProperty.h"
#include "nsXBLPrototypeHandler.h"
#include "nsXBLKeyHandler.h"
#include "nsXBLFocusHandler.h"
@ -163,30 +166,6 @@ nsXBLJSClass::Destroy()
// Static initialization
PRUint32 nsXBLBinding::gRefCnt = 0;
nsIAtom* nsXBLBinding::kXULTemplateAtom = nsnull;
nsIAtom* nsXBLBinding::kXULObservesAtom = nsnull;
nsIAtom* nsXBLBinding::kContentAtom = nsnull;
nsIAtom* nsXBLBinding::kImplementationAtom = nsnull;
nsIAtom* nsXBLBinding::kHandlersAtom = nsnull;
nsIAtom* nsXBLBinding::kExcludesAtom = nsnull;
nsIAtom* nsXBLBinding::kIncludesAtom = nsnull;
nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
nsIAtom* nsXBLBinding::kEventAtom = nsnull;
nsIAtom* nsXBLBinding::kPhaseAtom = nsnull;
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
nsIAtom* nsXBLBinding::kActionAtom = nsnull;
nsIAtom* nsXBLBinding::kMethodAtom = nsnull;
nsIAtom* nsXBLBinding::kParameterAtom = nsnull;
nsIAtom* nsXBLBinding::kBodyAtom = nsnull;
nsIAtom* nsXBLBinding::kOnSetAtom = nsnull;
nsIAtom* nsXBLBinding::kOnGetAtom = nsnull;
nsIAtom* nsXBLBinding::kGetterAtom = nsnull;
nsIAtom* nsXBLBinding::kSetterAtom = nsnull;
nsIAtom* nsXBLBinding::kNameAtom = nsnull;
nsIAtom* nsXBLBinding::kReadOnlyAtom = nsnull;
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
nsXBLBinding::EventHandlerMapEntry
nsXBLBinding::kEventHandlerMap[] = {
{ "click", nsnull, &NS_GET_IID(nsIDOMMouseListener) },
@ -270,30 +249,6 @@ nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding* aBinding)
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
if (gRefCnt == 1) {
kXULTemplateAtom = NS_NewAtom("template");
kXULObservesAtom = NS_NewAtom("observes");
kContentAtom = NS_NewAtom("content");
kImplementationAtom = NS_NewAtom("implementation");
kHandlersAtom = NS_NewAtom("handlers");
kExcludesAtom = NS_NewAtom("excludes");
kIncludesAtom = NS_NewAtom("includes");
kInheritsAtom = NS_NewAtom("inherits");
kEventAtom = NS_NewAtom("event");
kPhaseAtom = NS_NewAtom("phase");
kExtendsAtom = NS_NewAtom("extends");
kActionAtom = NS_NewAtom("action");
kMethodAtom = NS_NewAtom("method");
kParameterAtom = NS_NewAtom("parameter");
kBodyAtom = NS_NewAtom("body");
kOnSetAtom = NS_NewAtom("onset");
kOnGetAtom = NS_NewAtom("onget");
kGetterAtom = NS_NewAtom("getter");
kSetterAtom = NS_NewAtom("setter");
kNameAtom = NS_NewAtom("name");
kReadOnlyAtom = NS_NewAtom("readonly");
kAttachToAtom = NS_NewAtom("attachto");
EventHandlerMapEntry* entry = kEventHandlerMap;
while (entry->mAttributeName) {
entry->mAttributeAtom = NS_NewAtom(entry->mAttributeName);
@ -311,30 +266,6 @@ nsXBLBinding::~nsXBLBinding(void)
// printf("REF COUNT DOWN: %d %s\n", gRefCnt, (const char*)mID);
if (gRefCnt == 0) {
NS_RELEASE(kXULTemplateAtom);
NS_RELEASE(kXULObservesAtom);
NS_RELEASE(kContentAtom);
NS_RELEASE(kImplementationAtom);
NS_RELEASE(kHandlersAtom);
NS_RELEASE(kExcludesAtom);
NS_RELEASE(kIncludesAtom);
NS_RELEASE(kInheritsAtom);
NS_RELEASE(kEventAtom);
NS_RELEASE(kPhaseAtom);
NS_RELEASE(kExtendsAtom);
NS_RELEASE(kActionAtom);
NS_RELEASE(kMethodAtom);
NS_RELEASE(kParameterAtom);
NS_RELEASE(kBodyAtom);
NS_RELEASE(kOnSetAtom);
NS_RELEASE(kOnGetAtom);
NS_RELEASE(kGetterAtom);
NS_RELEASE(kSetterAtom);
NS_RELEASE(kNameAtom);
NS_RELEASE(kReadOnlyAtom);
NS_RELEASE(kAttachToAtom);
EventHandlerMapEntry* entry = kEventHandlerMap;
while (entry->mAttributeName) {
NS_IF_RELEASE(entry->mAttributeAtom);
@ -678,7 +609,7 @@ nsXBLBinding::GenerateAnonymousContent()
{
// Fetch the content element for this binding.
nsCOMPtr<nsIContent> content;
GetImmediateChild(kContentAtom, getter_AddRefs(content));
GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(content));
if (!content) {
// We have no anonymous content.
@ -700,7 +631,7 @@ nsXBLBinding::GenerateAnonymousContent()
#ifdef DEBUG
// See if there's an includes attribute.
nsAutoString includes;
content->GetAttr(kNameSpaceID_None, kIncludesAtom, includes);
content->GetAttr(kNameSpaceID_None, nsXBLAtoms::includes, includes);
if (!includes.IsEmpty()) {
nsCAutoString id;
mPrototypeBinding->GetID(id);
@ -743,7 +674,7 @@ nsXBLBinding::GenerateAnonymousContent()
childContent = do_QueryInterface(node);
nsCOMPtr<nsIAtom> tag;
childContent->GetTag(*getter_AddRefs(tag));
if (tag.get() != kXULObservesAtom && tag.get() != kXULTemplateAtom) {
if (tag != nsXULAtoms::observes && tag != nsXULAtoms::templateAtom) {
hasContent = PR_FALSE;
break;
}
@ -824,7 +755,7 @@ nsXBLBinding::GenerateAnonymousContent()
// should be thrown out. Special-case template and observes.
nsCOMPtr<nsIAtom> tag;
childContent->GetTag(*getter_AddRefs(tag));
if (tag.get() != kXULObservesAtom && tag.get() != kXULTemplateAtom) {
if (tag != nsXULAtoms::observes && tag != nsXULAtoms::templateAtom) {
// Kill all anonymous content.
mContent = nsnull;
bindingManager->SetContentListFor(mBoundElement, nsnull);
@ -879,7 +810,7 @@ nsXBLBinding::GenerateAnonymousContent()
for (PRInt32 i = 0; i < length; ++i) {
content->GetAttrNameAt(i, namespaceID, *getter_AddRefs(name), *getter_AddRefs(prefix));
if (name.get() != kIncludesAtom) {
if (name != nsXBLAtoms::includes) {
nsAutoString value;
mBoundElement->GetAttr(namespaceID, name, value);
if (value.IsEmpty()) {
@ -915,11 +846,7 @@ nsXBLBinding::InstallEventHandlers()
nsXBLEventHandler* currHandler = nsnull;
while (curr) {
nsCOMPtr<nsIContent> child;
curr->GetHandlerElement(getter_AddRefs(child));
// Fetch the type attribute.
// XXX Deal with a comma-separated list of types
// Fetch the event type.
nsCOMPtr<nsIAtom> eventAtom;
curr->GetEventName(getter_AddRefs(eventAtom));
@ -956,11 +883,9 @@ nsXBLBinding::InstallEventHandlers()
*/
// Figure out if we're using capturing or not.
PRBool useCapture = PR_FALSE;
nsAutoString capturer;
child->GetAttr(kNameSpaceID_None, kPhaseAtom, capturer);
if (capturer == NS_LITERAL_STRING("capturing"))
useCapture = PR_TRUE;
PRUint8 phase;
curr->GetPhase(&phase);
PRBool useCapture = (phase == NS_PHASE_CAPTURING);
// Create a new nsXBLEventHandler.
nsXBLEventHandler* handler = nsnull;
@ -1037,11 +962,8 @@ nsXBLBinding::InstallEventHandlers()
}
else {
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
nsAutoString value;
child->GetAttr(kNameSpaceID_None, kActionAtom, value);
if (value.IsEmpty())
GetTextData(child, value);
AddScriptEventListener(mBoundElement, eventAtom, value);
// XXX Need to get the event text from the prototype handler!
//AddScriptEventListener(mBoundElement, eventAtom, value);
}
// We chain all our event handlers together for easy
@ -1191,7 +1113,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
if (mIsStyleBinding) {
// Now the binding dies. Unhook our prototypes.
nsCOMPtr<nsIContent> interfaceElement;
GetImmediateChild(kImplementationAtom, getter_AddRefs(interfaceElement));
GetImmediateChild(nsXBLAtoms::implementation, getter_AddRefs(interfaceElement));
if (interfaceElement) {
nsCOMPtr<nsIScriptGlobalObject> global;
@ -1480,7 +1402,7 @@ nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
binding->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get()) {
if (aTag == tag) {
*aResult = child;
NS_ADDREF(*aResult);
return;

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

@ -135,31 +135,6 @@ public:
// Static members
static PRUint32 gRefCnt;
static nsIAtom* kXULTemplateAtom;
static nsIAtom* kXULObservesAtom;
static nsIAtom* kContentAtom;
static nsIAtom* kImplementationAtom;
static nsIAtom* kHandlersAtom;
static nsIAtom* kExcludesAtom;
static nsIAtom* kIncludesAtom;
static nsIAtom* kInheritsAtom;
static nsIAtom* kEventAtom;
static nsIAtom* kPhaseAtom;
static nsIAtom* kExtendsAtom;
static nsIAtom* kChildrenAtom;
static nsIAtom* kMethodAtom;
static nsIAtom* kParameterAtom;
static nsIAtom* kBodyAtom;
static nsIAtom* kOnSetAtom;
static nsIAtom* kOnGetAtom;
static nsIAtom* kGetterAtom;
static nsIAtom* kSetterAtom;
static nsIAtom* kActionAtom;
static nsIAtom* kNameAtom;
static nsIAtom* kReadOnlyAtom;
static nsIAtom* kAttachToAtom;
// Used to easily obtain the correct IID for an event.
struct EventHandlerMapEntry {
const char* mAttributeName;

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

@ -0,0 +1,310 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsXBLContentSink.h"
#include "nsIDocument.h"
#include "nsIBindingManager.h"
#include "nsIDOMNode.h"
#include "nsIParser.h"
#include "nsXBLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLTokens.h"
#include "nsIURI.h"
nsresult
NS_NewXBLContentSink(nsIXMLContentSink** aResult,
nsIDocument* aDoc,
nsIURI* aURL,
nsIWebShell* aWebShell)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (!aResult)
return NS_ERROR_NULL_POINTER;
nsXBLContentSink* it;
NS_NEWXPCOM(it, nsXBLContentSink);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = it->Init(aDoc, aURL, aWebShell);
if (NS_FAILED(rv))
return rv;
return it->QueryInterface(NS_GET_IID(nsIXMLContentSink), (void **)aResult);
}
nsXBLContentSink::nsXBLContentSink()
{
mState = eXBL_InDocument;
mSecondaryState = eXBL_None;
mDocInfo = nsnull;
mIsChromeOrResource = PR_FALSE;
}
nsXBLContentSink::~nsXBLContentSink()
{
}
nsresult
nsXBLContentSink::Init(nsIDocument* aDoc,
nsIURI* aURL,
nsIWebShell* aContainer)
{
nsresult rv;
rv = nsXMLContentSink::Init(aDoc, aURL, aContainer);
return rv;
}
PRBool
nsXBLContentSink::OnOpenContainer(const nsIParserNode& aNode, PRInt32 aNameSpaceID, nsIAtom* aTagName)
{
PRBool ret = PR_TRUE;
if (aNameSpaceID == kNameSpaceID_XBL) {
if (aTagName == nsXBLAtoms::bindings) {
NS_NewXBLDocumentInfo(mDocument, &mDocInfo);
if (!mDocInfo)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIBindingManager> bindingManager;
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
bindingManager->PutXBLDocumentInfo(mDocInfo);
nsCOMPtr<nsIURI> url;
mDocument->GetDocumentURL(getter_AddRefs(url));
PRBool isChrome = PR_FALSE;
PRBool isRes = PR_FALSE;
url->SchemeIs("chrome", &isChrome);
url->SchemeIs("resource", &isRes);
mIsChromeOrResource = isChrome || isRes;
nsIXBLDocumentInfo* info = mDocInfo;
NS_RELEASE(info); // We keep a weak ref. We've created a cycle between doc/binding manager/doc info.
}
else if (aTagName == nsXBLAtoms::binding)
mState = eXBL_InBinding;
else if (aTagName == nsXBLAtoms::handlers) {
mState = eXBL_InHandlers;
ret = PR_FALSE; // The XML content sink should not do anything with <handlers>.
}
else if (aTagName == nsXBLAtoms::handler) {
mSecondaryState = eXBL_InHandler;
ConstructHandler(aNode);
ret = PR_FALSE;
}
else if (aTagName == nsXBLAtoms::resources) {
// mState = eXBL_InResources;
// ret = PR_FALSE; // The XML content sink should ignore all <resources>.
}
else if (aTagName == nsXBLAtoms::implementation) {
// mState = eXBL_InImplementation;
// ret = PR_FALSE; // The XML content sink should ignore the <implementation>.
}
}
return ret;
}
NS_IMETHODIMP
nsXBLContentSink::OpenContainer(const nsIParserNode& aNode)
{
nsresult rv = nsXMLContentSink::OpenContainer(aNode);
if (NS_FAILED(rv))
return rv;
if (mState == eXBL_InBinding && !mBinding)
ConstructBinding();
return rv;
}
NS_IMETHODIMP
nsXBLContentSink::CloseContainer(const nsIParserNode& aNode)
{
if (mState != eXBL_InDocument) {
nsCOMPtr<nsIAtom> nameSpacePrefix, tagAtom;
SplitXMLName(aNode.GetText(), getter_AddRefs(nameSpacePrefix),
getter_AddRefs(tagAtom));
PRInt32 nameSpaceID = GetNameSpaceId(nameSpacePrefix);
if (nameSpaceID == kNameSpaceID_XBL) {
if (mState == eXBL_InHandlers) {
if (tagAtom == nsXBLAtoms::handlers) {
mState = eXBL_InBinding;
mHandler = nsnull;
}
else if (tagAtom == nsXBLAtoms::handler)
mSecondaryState = eXBL_None;
return NS_OK;
}
nsresult rv = nsXMLContentSink::CloseContainer(aNode);
if (NS_FAILED(rv))
return rv;
if (mState == eXBL_InImplementation && tagAtom == nsXBLAtoms::implementation)
mState = eXBL_InBinding;
else if (mState == eXBL_InResources && tagAtom == nsXBLAtoms::resources)
mState = eXBL_InBinding;
else if (mState == eXBL_InBinding && tagAtom == nsXBLAtoms::binding) {
mState = eXBL_InDocument;
mBinding->Initialize();
mBinding = nsnull; // Clear our current binding ref.
}
return NS_OK;
}
}
return nsXMLContentSink::CloseContainer(aNode);
}
NS_IMETHODIMP
nsXBLContentSink::AddLeaf(const nsIParserNode& aNode)
{
if (mState == eXBL_InHandlers) {
if (mSecondaryState == eXBL_InHandler) {
// Get the text and add it to the event handler.
switch (aNode.GetTokenType()) {
case eToken_text:
case eToken_cdatasection:
mHandler->SetHandlerText(aNode.GetText());
case eToken_entity:
{
nsAutoString tmp;
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp);
if (unicode < 0)
mHandler->SetHandlerText(aNode.GetText());
else
mHandler->SetHandlerText(aNode.GetText());
}
}
}
return NS_OK;
}
return nsXMLContentSink::AddLeaf(aNode);
}
void
nsXBLContentSink::ConstructBinding()
{
nsCOMPtr<nsIContent> binding = getter_AddRefs(GetCurrentContent());
nsAutoString id;
binding->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, id);
nsCAutoString cid; cid.AssignWithConversion(id);
if (!cid.IsEmpty()) {
NS_NewXBLPrototypeBinding(cid, binding, mDocInfo, getter_AddRefs(mBinding));
mDocInfo->SetPrototypeBinding(cid, mBinding);
binding->UnsetAttr(kNameSpaceID_None, nsHTMLAtoms::id, PR_FALSE);
}
}
void
nsXBLContentSink::ConstructHandler(const nsIParserNode& aNode)
{
nsCOMPtr<nsIAtom> nameSpacePrefix, nameAtom;
PRInt32 ac = aNode.GetAttributeCount();
nsAReadableString* event = nsnull;
nsAReadableString* modifiers = nsnull;
nsAReadableString* button = nsnull;
nsAReadableString* clickcount = nsnull;
nsAReadableString* keycode = nsnull;
nsAReadableString* charcode = nsnull;
nsAReadableString* phase = nsnull;
nsAReadableString* command = nsnull;
nsAReadableString* action = nsnull;
for (PRInt32 i = 0; i < ac; i++) {
// Get upper-cased key
const nsAReadableString& key = aNode.GetKeyAt(i);
SplitXMLName(key, getter_AddRefs(nameSpacePrefix),
getter_AddRefs(nameAtom));
if (nameSpacePrefix || nameAtom.get() == nsLayoutAtoms::xmlnsNameSpace)
continue;
// Is this attribute one of the ones we care about?
nsAReadableString* ref = nsnull;
if (key.Equals(NS_LITERAL_STRING("event")))
event = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("modifiers")))
modifiers = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("button")))
button = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("clickcount")))
clickcount = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("keycode")))
keycode = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("key")) || key.Equals(NS_LITERAL_STRING("charcode")))
charcode = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("phase")))
phase = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("command")))
command = &(aNode.GetValueAt(i));
else if (key.Equals(NS_LITERAL_STRING("action")))
action = &(aNode.GetValueAt(i));
else
continue; // Nope, it's some irrelevant attribute. Ignore it and move on.
}
if (command && !mIsChromeOrResource)
// Make sure the XBL doc is chrome or resource if we have a command
// shorthand syntax.
return; // Don't even make this handler.
// All of our pointers are now filled in. Construct our handler with all of these
// parameters.
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
NS_NewXBLPrototypeHandler(event, phase, action, command,
keycode, charcode, modifiers, button, clickcount,
getter_AddRefs(newHandler));
if (newHandler) {
// Add this handler to our chain of handlers.
if (mHandler)
mHandler->SetNextHandler(newHandler); // Already have a chain. Just append to the end.
else
mBinding->SetPrototypeHandlers(newHandler); // We're the first handler in the chain.
mHandler = newHandler; // Adjust our mHandler pointer to point to the new last handler in the chain.
}
}

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

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Hyatt <hyatt@netscape.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsXBLContentSink_h__
#define nsXBLContentSink_h__
#include "nsXMLContentSink.h"
#include "nsXBLDocumentInfo.h"
#include "nsIXBLPrototypeBinding.h"
#include "nsIXBLPrototypeHandler.h"
typedef enum {
eXBL_InDocument,
eXBL_InBinding,
eXBL_InResources,
eXBL_InImplementation,
eXBL_InHandlers
} XBLPrimaryState;
typedef enum {
eXBL_None,
eXBL_InHandler,
eXBL_InMethod,
eXBL_InProperty,
eXBL_InField,
eXBL_InBody,
eXBL_InGetter,
eXBL_InSetter
} XBLSecondaryState;
// The XBL content sink overrides the XML content sink to
// builds its own lightweight data structures for the <resources>,
// <handlers>, <implementation>, and
class nsXBLContentSink : public nsXMLContentSink {
public:
nsXBLContentSink();
~nsXBLContentSink();
nsresult Init(nsIDocument* aDoc,
nsIURI* aURL,
nsIWebShell* aContainer);
// nsIContentSink overrides
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
NS_IMETHOD CloseContainer(const nsIParserNode& aNode);
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
protected:
// nsXMLContentSink overrides
PRBool OnOpenContainer(const nsIParserNode& aNode, PRInt32 aNameSpaceID, nsIAtom* aTagName);
// Our own helpers for constructing XBL prototype objects.
void ConstructBinding();
void ConstructHandler(const nsIParserNode& aNode);
protected:
XBLPrimaryState mState;
XBLSecondaryState mSecondaryState;
nsIXBLDocumentInfo* mDocInfo;
PRBool mIsChromeOrResource; // For bug #45989
nsCOMPtr<nsIXBLPrototypeBinding> mBinding;
nsCOMPtr<nsIXBLPrototypeHandler> mHandler;
};
nsresult
NS_NewXBLContentSink(nsIXMLContentSink** aResult,
nsIDocument* aDoc,
nsIURI* aURL,
nsIWebShell* aWebShell);
#endif // nsXBLContentSink_h__

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

@ -0,0 +1,389 @@
#include "nsXBLDocumentInfo.h"
#include "nsHashtable.h"
#include "nsIDocument.h"
#include "nsIXBLPrototypeBinding.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIScriptContext.h"
#include "nsIDOMScriptObjectFactory.h"
#include "jsapi.h"
#include "nsIURI.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
#include "nsIChromeRegistry.h"
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
// An XBLDocumentInfo object has a special context associated with it which we can use to pre-compile
// properties and methods of XBL bindings against.
class nsXBLDocGlobalObject : public nsIScriptGlobalObject,
public nsIScriptObjectPrincipal
{
public:
nsXBLDocGlobalObject();
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIScriptGlobalObject methods
NS_IMETHOD SetContext(nsIScriptContext *aContext);
NS_IMETHOD GetContext(nsIScriptContext **aContext);
NS_IMETHOD SetNewDocument(nsIDOMDocument *aDocument,
PRBool removeEventListeners);
NS_IMETHOD SetDocShell(nsIDocShell *aDocShell);
NS_IMETHOD GetDocShell(nsIDocShell **aDocShell);
NS_IMETHOD SetOpenerWindow(nsIDOMWindowInternal *aOpener);
NS_IMETHOD SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner);
NS_IMETHOD GetGlobalObjectOwner(nsIScriptGlobalObjectOwner** aOwner);
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD_(JSObject *) GetGlobalJSObject();
NS_IMETHOD OnFinalize(JSObject *aObject);
// nsIScriptObjectPrincipal methods
NS_IMETHOD GetPrincipal(nsIPrincipal** aPrincipal);
protected:
virtual ~nsXBLDocGlobalObject();
nsCOMPtr<nsIScriptContext> mScriptContext;
JSObject *mJSObject; // XXX JS language rabies bigotry badness
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // weak reference
static JSClass gSharedGlobalClass;
};
void PR_CALLBACK nsXBLDocGlobalObject_finalize(JSContext *cx, JSObject *obj)
{
nsISupports *nativeThis = (nsISupports*)JS_GetPrivate(cx, obj);
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nativeThis));
if (sgo)
sgo->OnFinalize(obj);
// The addref was part of JSObject construction
NS_RELEASE(nativeThis);
}
JSBool PR_CALLBACK nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id)
{
JSBool did_resolve = JS_FALSE;
return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
}
JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
"nsXBLPrototypeScript compilation scope",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, nsXBLDocGlobalObject_resolve, JS_ConvertStub,
nsXBLDocGlobalObject_finalize
};
//----------------------------------------------------------------------
//
// nsXBLDocGlobalObject
//
nsXBLDocGlobalObject::nsXBLDocGlobalObject()
: mJSObject(nsnull),
mGlobalObjectOwner(nsnull)
{
NS_INIT_REFCNT();
}
nsXBLDocGlobalObject::~nsXBLDocGlobalObject()
{}
NS_IMPL_ISUPPORTS2(nsXBLDocGlobalObject, nsIScriptGlobalObject, nsIScriptObjectPrincipal)
//----------------------------------------------------------------------
//
// nsIScriptGlobalObject methods
//
NS_IMETHODIMP
nsXBLDocGlobalObject::SetContext(nsIScriptContext *aContext)
{
mScriptContext = aContext;
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetContext(nsIScriptContext **aContext)
{
// This whole fragile mess is predicated on the fact that
// GetContext() will be called before GetScriptObject() is.
if (! mScriptContext) {
nsCOMPtr<nsIDOMScriptObjectFactory> factory = do_GetService(kDOMScriptObjectFactoryCID);
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
nsresult rv = factory->NewScriptContext(nsnull, getter_AddRefs(mScriptContext));
if (NS_FAILED(rv))
return rv;
JSContext *cx = (JSContext *)mScriptContext->GetNativeContext();
mJSObject = ::JS_NewObject(cx, &gSharedGlobalClass, nsnull, nsnull);
if (!mJSObject)
return NS_ERROR_OUT_OF_MEMORY;
::JS_SetGlobalObject(cx, mJSObject);
// Add an owning reference from JS back to us. This'll be
// released when the JSObject is finalized.
::JS_SetPrivate(cx, mJSObject, this);
NS_ADDREF(this);
}
*aContext = mScriptContext;
NS_IF_ADDREF(*aContext);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetNewDocument(nsIDOMDocument *aDocument,
PRBool removeEventListeners)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetDocShell(nsIDocShell *aDocShell)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetDocShell(nsIDocShell **aDocShell)
{
NS_WARNING("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetOpenerWindow(nsIDOMWindowInternal *aOpener)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::SetGlobalObjectOwner(nsIScriptGlobalObjectOwner* aOwner)
{
mGlobalObjectOwner = aOwner; // weak reference
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::GetGlobalObjectOwner(nsIScriptGlobalObjectOwner** aOwner)
{
*aOwner = mGlobalObjectOwner;
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocGlobalObject::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_NOTREACHED("waaah!");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP_(JSObject *)
nsXBLDocGlobalObject::GetGlobalJSObject()
{
// The prototype document has its own special secret script object
// that can be used to compile scripts and event handlers.
if (!mScriptContext)
return nsnull;
JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
mScriptContext->GetNativeContext());
if (!cx)
return nsnull;
return ::JS_GetGlobalObject(cx);
}
NS_IMETHODIMP
nsXBLDocGlobalObject::OnFinalize(JSObject *aObject)
{
NS_ASSERTION(aObject == mJSObject, "Wrong object finalized!");
mJSObject = nsnull;
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsIScriptObjectPrincipal methods
//
NS_IMETHODIMP
nsXBLDocGlobalObject::GetPrincipal(nsIPrincipal** aPrincipal)
{
nsresult rv = NS_OK;
if (!mGlobalObjectOwner) {
*aPrincipal = nsnull;
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIXBLDocumentInfo> docInfo = do_QueryInterface(mGlobalObjectOwner, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> document;
rv = docInfo->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return document->GetPrincipal(aPrincipal);
}
static PRBool IsChromeOrResourceURI(nsIURI* aURI)
{
PRBool isChrome = PR_FALSE;
PRBool isResource = PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) &&
NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)))
return (isChrome || isResource);
return PR_FALSE;
}
/* Implementation file */
NS_IMPL_ISUPPORTS3(nsXBLDocumentInfo, nsIXBLDocumentInfo, nsIScriptGlobalObjectOwner, nsISupportsWeakReference)
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
nsXBLDocumentInfo::nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mDocURI = aDocURI;
mDocument = aDocument;
mScriptAccess = PR_TRUE;
mBindingTable = nsnull;
nsCOMPtr<nsIURI> uri;
mDocument->GetDocumentURL(getter_AddRefs(uri));
if (IsChromeOrResourceURI(uri)) {
// Cache whether or not this chrome XBL can execute scripts.
nsCOMPtr<nsIChromeRegistry> reg(do_GetService(kChromeRegistryCID));
if (reg) {
PRBool allow = PR_TRUE;
reg->AllowScriptsForSkin(uri, &allow);
SetScriptAccess(allow);
}
}
}
nsXBLDocumentInfo::~nsXBLDocumentInfo()
{
/* destructor code */
if (mGlobalObject) {
mGlobalObject->SetContext(nsnull); // remove circular reference
mGlobalObject->SetGlobalObjectOwner(nsnull); // just in case
}
delete mBindingTable;
}
NS_IMETHODIMP
nsXBLDocumentInfo::GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult)
{
*aResult = nsnull;
if (!mBindingTable)
return NS_OK;
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
*aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here.
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding)
{
if (!mBindingTable)
mBindingTable = new nsSupportsHashtable();
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
mBindingTable->Put(&key, aBinding);
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsIScriptGlobalObjectOwner methods
//
NS_IMETHODIMP
nsXBLDocumentInfo::GetScriptGlobalObject(nsIScriptGlobalObject** _result)
{
if (!mGlobalObject) {
mGlobalObject = new nsXBLDocGlobalObject();
if (!mGlobalObject) {
*_result = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
mGlobalObject->SetGlobalObjectOwner(this); // does not refcount
}
*_result = mGlobalObject;
NS_ADDREF(*_result);
return NS_OK;
}
NS_IMETHODIMP
nsXBLDocumentInfo::ReportScriptError(nsIScriptError *errorObject)
{
if (errorObject == nsnull)
return NS_ERROR_NULL_POINTER;
// Get the console service, where we're going to register the error.
nsCOMPtr<nsIConsoleService> consoleService (do_GetService("@mozilla.org/consoleservice;1"));
if (!consoleService)
return NS_ERROR_NOT_AVAILABLE;
return consoleService->LogMessage(errorObject);
}
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
{
nsCOMPtr<nsIURI> url;
aDocument->GetDocumentURL(getter_AddRefs(url));
nsXPIDLCString str;
url->GetSpec(getter_Copies(str));
*aResult = new nsXBLDocumentInfo((const char*)str, aDocument);
NS_IF_ADDREF(*aResult);
return NS_OK;
}

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

@ -0,0 +1,38 @@
#include "nsCOMPtr.h"
#include "nsIXBLDocumentInfo.h"
#include "nsIScriptGlobalObjectOwner.h"
#include "nsWeakReference.h"
#include "nsIDocument.h"
class nsIXBLPrototypeBinding;
class nsSupportsHashtable;
class nsXBLDocumentInfo : public nsIXBLDocumentInfo, public nsIScriptGlobalObjectOwner, public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument);
virtual ~nsXBLDocumentInfo();
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; };
NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult);
NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding);
// nsIScriptGlobalObjectOwner methods
NS_DECL_NSISCRIPTGLOBALOBJECTOWNER
private:
nsCOMPtr<nsIDocument> mDocument;
nsCString mDocURI;
PRBool mScriptAccess;
nsSupportsHashtable* mBindingTable;
nsCOMPtr<nsIScriptGlobalObject> mGlobalObject;
};

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

@ -39,7 +39,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsXBLPrototypeHandler.h"
#include "nsXBLEventHandler.h"
#include "nsIContent.h"
#include "nsIAtom.h"
@ -75,16 +75,7 @@
#include "nsIDOMDragListener.h"
#include "nsIDOMScrollListener.h"
#include "nsIDOMFormListener.h"
PRUint32 nsXBLEventHandler::gRefCnt = 0;
nsIAtom* nsXBLEventHandler::kKeyCodeAtom = nsnull;
nsIAtom* nsXBLEventHandler::kCharCodeAtom = nsnull;
nsIAtom* nsXBLEventHandler::kKeyAtom = nsnull;
nsIAtom* nsXBLEventHandler::kActionAtom = nsnull;
nsIAtom* nsXBLEventHandler::kCommandAtom = nsnull;
nsIAtom* nsXBLEventHandler::kClickCountAtom = nsnull;
nsIAtom* nsXBLEventHandler::kButtonAtom = nsnull;
nsIAtom* nsXBLEventHandler::kModifiersAtom = nsnull;
#include "nsXBLAtoms.h"
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandler)
{
@ -92,32 +83,10 @@ nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBL
mEventReceiver = aEventReceiver;
mProtoHandler = aHandler;
mNextHandler = nsnull;
gRefCnt++;
if (gRefCnt == 1) {
kKeyCodeAtom = NS_NewAtom("keycode");
kKeyAtom = NS_NewAtom("key");
kCharCodeAtom = NS_NewAtom("charcode");
kModifiersAtom = NS_NewAtom("modifiers");
kActionAtom = NS_NewAtom("action");
kCommandAtom = NS_NewAtom("command");
kClickCountAtom = NS_NewAtom("clickcount");
kButtonAtom = NS_NewAtom("button");
}
}
nsXBLEventHandler::~nsXBLEventHandler()
{
gRefCnt--;
if (gRefCnt == 0) {
NS_RELEASE(kKeyAtom);
NS_RELEASE(kKeyCodeAtom);
NS_RELEASE(kCharCodeAtom);
NS_RELEASE(kModifiersAtom);
NS_RELEASE(kActionAtom);
NS_RELEASE(kCommandAtom);
NS_RELEASE(kButtonAtom);
NS_RELEASE(kClickCountAtom);
}
}
NS_IMPL_ISUPPORTS1(nsXBLEventHandler, nsISupports)
@ -135,20 +104,12 @@ nsXBLEventHandler::RemoveEventHandlers()
nsCOMPtr<nsIAtom> eventName;
mProtoHandler->GetEventName(getter_AddRefs(eventName));
nsCOMPtr<nsIContent> handlerElement;
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
mProtoHandler = nsnull;
if (!handlerElement)
return;
PRBool useCapture = PR_FALSE;
nsAutoString capturer;
handlerElement->GetAttr(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
if (capturer == NS_LITERAL_STRING("capturing"))
useCapture = PR_TRUE;
nsAutoString type;
handlerElement->GetAttr(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
eventName->ToString(type);
PRUint8 phase;
mProtoHandler->GetPhase(&phase);
PRBool useCapture = (phase == NS_PHASE_CAPTURING);
PRBool found = PR_FALSE;
nsIID iid;

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

@ -75,17 +75,6 @@ public:
static nsresult GetTextData(nsIContent *aParent, nsAWritableString& aResult);
protected:
static PRUint32 gRefCnt;
static nsIAtom* kKeyAtom;
static nsIAtom* kKeyCodeAtom;
static nsIAtom* kCharCodeAtom;
static nsIAtom* kActionAtom;
static nsIAtom* kCommandAtom;
static nsIAtom* kClickCountAtom;
static nsIAtom* kButtonAtom;
static nsIAtom* kModifiersAtom;
protected:
nsCOMPtr<nsIDOMEventReceiver> mEventReceiver;
nsCOMPtr<nsIXBLPrototypeHandler> mProtoHandler;

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

@ -75,6 +75,7 @@
#include "nsIDocumentObserver.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsXBLAtoms.h"
#include "nsIScriptContext.h"
@ -231,23 +232,7 @@ NS_IMPL_QUERY_INTERFACE1(nsXBLInsertionPointEntry, nsIXBLInsertionPointEntry)
// Static initialization
PRUint32 nsXBLPrototypeBinding::gRefCnt = 0;
nsIAtom* nsXBLPrototypeBinding::kInheritStyleAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kHandlersAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kChildrenAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kIncludesAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kContentAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kResourcesAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kResourceAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kStyleSheetAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kSrcAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kInheritsAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kHTMLAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kValueAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kXBLTextAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kConstructorAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kDestructorAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kImplementationAtom = nsnull;
nsIAtom* nsXBLPrototypeBinding::kImplementsAtom = nsnull;
nsFixedSizeAllocator* nsXBLPrototypeBinding::kAttrPool;
nsFixedSizeAllocator* nsXBLPrototypeBinding::kInsPool;
@ -273,7 +258,8 @@ static const PRInt32 kInsInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLInsertionPoi
NS_IMPL_ISUPPORTS3(nsXBLPrototypeBinding, nsIXBLPrototypeBinding, nsICSSLoaderObserver, nsISupportsWeakReference)
// Constructors/Destructors
nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsAReadableCString& aID, nsIXBLDocumentInfo* aInfo)
nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsAReadableCString& aID, nsIXBLDocumentInfo* aInfo,
nsIContent* aElement)
: mID(aID),
mInheritStyle(PR_TRUE),
mHasBaseProto(PR_TRUE),
@ -298,51 +284,36 @@ nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsAReadableCString& aID, nsIX
kAttrPool->Init("XBL Attribute Entries", kAttrBucketSizes, kAttrNumBuckets, kAttrInitialSize);
kInsPool = new nsFixedSizeAllocator();
kInsPool->Init("XBL Insertion Point Entries", kInsBucketSizes, kInsNumBuckets, kInsInitialSize);
kInheritStyleAtom = NS_NewAtom("inheritstyle");
kHandlersAtom = NS_NewAtom("handlers");
kChildrenAtom = NS_NewAtom("children");
kContentAtom = NS_NewAtom("content");
kResourcesAtom = NS_NewAtom("resources");
kResourceAtom = NS_NewAtom("resource");
kStyleSheetAtom = NS_NewAtom("stylesheet");
kSrcAtom = NS_NewAtom("src");
kIncludesAtom = NS_NewAtom("includes");
kInheritsAtom = NS_NewAtom("inherits");
kHTMLAtom = NS_NewAtom("html");
kValueAtom = NS_NewAtom("value");
kXBLTextAtom = NS_NewAtom("xbl:text");
kConstructorAtom = NS_NewAtom("constructor");
kDestructorAtom = NS_NewAtom("destructor");
kImplementationAtom = NS_NewAtom("implementation");
kImplementsAtom = NS_NewAtom("implements");
}
}
void nsXBLPrototypeBinding::Initialize(nsIContent * aElement, nsIXBLDocumentInfo* aInfo)
{
// These all use atoms, so we have to do these ops last to ensure
// the atoms exist.
SetBindingElement(aElement);
}
NS_IMETHODIMP
nsXBLPrototypeBinding::Initialize()
{
nsCOMPtr<nsIXBLDocumentInfo> info(do_QueryReferent(mXBLDocInfoWeak));
PRBool allowScripts;
aInfo->GetScriptAccess(&allowScripts);
info->GetScriptAccess(&allowScripts);
if (allowScripts) {
ConstructHandlers();
BuildConstructorAndDestructor();
ConstructProperties();
}
nsCOMPtr<nsIContent> content;
GetImmediateChild(kContentAtom, getter_AddRefs(content));
GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(content));
if (content) {
ConstructAttributeTable(content);
ConstructInsertionTable(content);
}
nsCOMPtr<nsIContent> impl;
GetImmediateChild(kImplementationAtom, getter_AddRefs(impl));
GetImmediateChild(nsXBLAtoms::implementation, getter_AddRefs(impl));
if (impl)
ConstructInterfaceTable(impl);
return NS_OK;
}
nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
@ -352,24 +323,6 @@ nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
delete mInterfaceTable;
gRefCnt--;
if (gRefCnt == 0) {
NS_RELEASE(kInheritStyleAtom);
NS_RELEASE(kHandlersAtom);
NS_RELEASE(kChildrenAtom);
NS_RELEASE(kContentAtom);
NS_RELEASE(kResourcesAtom);
NS_RELEASE(kResourceAtom);
NS_RELEASE(kStyleSheetAtom);
NS_RELEASE(kSrcAtom);
NS_RELEASE(kIncludesAtom);
NS_RELEASE(kInheritsAtom);
NS_RELEASE(kHTMLAtom);
NS_RELEASE(kValueAtom);
NS_RELEASE(kXBLTextAtom);
NS_RELEASE(kConstructorAtom);
NS_RELEASE(kDestructorAtom);
NS_RELEASE(kImplementationAtom);
NS_RELEASE(kImplementsAtom);
delete kAttrPool;
delete kInsPool;
}
@ -413,7 +366,7 @@ nsXBLPrototypeBinding::SetBindingElement(nsIContent* aElement)
{
mBinding = aElement;
nsAutoString inheritStyle;
mBinding->GetAttr(kNameSpaceID_None, kInheritStyleAtom, inheritStyle);
mBinding->GetAttr(kNameSpaceID_None, nsXBLAtoms::inheritstyle, inheritStyle);
if (inheritStyle == NS_LITERAL_STRING("false"))
mInheritStyle = PR_FALSE;
@ -481,7 +434,7 @@ nsXBLPrototypeBinding::LoadResources(PRBool* aResult)
nsresult rv = NS_OK;
nsCOMPtr<nsIContent> content;
GetImmediateChild(kResourcesAtom, getter_AddRefs(content));
GetImmediateChild(nsXBLAtoms::resources, getter_AddRefs(content));
if (content) {
#ifdef USE_IMG2
// Declare our loaders.
@ -513,7 +466,7 @@ nsXBLPrototypeBinding::LoadResources(PRBool* aResult)
resource->GetTag(*getter_AddRefs(tag));
nsAutoString src;
resource->GetAttr(kNameSpaceID_None, kSrcAtom, src);
resource->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
if (src.Length() == 0)
continue;
@ -523,8 +476,7 @@ nsXBLPrototypeBinding::LoadResources(PRBool* aResult)
if (NS_FAILED(rv))
continue;
#ifdef USE_IMG2
if (tag.get() == nsXULAtoms::image) {
if (tag == nsXBLAtoms::image) {
// Obtain our src attribute.
// Construct a URI out of our src attribute.
// We need to ensure the image loader is constructed.
@ -537,9 +489,7 @@ nsXBLPrototypeBinding::LoadResources(PRBool* aResult)
nsCOMPtr<imgIRequest> req;
il->LoadImage(url, nsnull, nsnull, nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, nsnull, getter_AddRefs(req));
}
else
#endif
if (tag.get() == kStyleSheetAtom) {
else if (tag == nsXBLAtoms::stylesheet) {
if (!cssLoader) {
nsCOMPtr<nsIHTMLContentContainer> htmlContent(do_QueryInterface(doc));
htmlContent->GetCSSLoader(*getter_AddRefs(cssLoader));
@ -680,7 +630,7 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceI
// Iterate over the elements in the array.
nsCOMPtr<nsIContent> content;
GetImmediateChild(kContentAtom, getter_AddRefs(content));
GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(content));
while (xblAttr) {
nsCOMPtr<nsIContent> element;
nsCOMPtr<nsIAtom> dstAttr;
@ -699,7 +649,7 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceI
nsAutoString value;
// Check to see if the src attribute is xbl:text. If so, then we need to obtain the
// children of the real element and get the text nodes' values.
if (aAttribute == kXBLTextAtom) {
if (aAttribute == nsXBLAtoms::xbltext) {
nsXBLBinding::GetTextData(aChangedElement, value);
value.StripChar('\n');
value.StripChar('\r');
@ -723,7 +673,7 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceI
// xbl:text set on us.
nsCOMPtr<nsIAtom> tag;
realElement->GetTag(*getter_AddRefs(tag));
if (dstAttr.get() == kXBLTextAtom || (tag.get() == kHTMLAtom) && (dstAttr.get() == kValueAtom)) {
if (dstAttr == nsXBLAtoms::xbltext || (tag == nsHTMLAtoms::html) && (dstAttr == nsHTMLAtoms::value)) {
// Flush out all our kids.
PRInt32 childCount;
realElement->ChildCount(childCount);
@ -784,7 +734,7 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void*
nsCOMPtr<nsIContent> instanceRoot;
binding->GetAnonymousContent(getter_AddRefs(instanceRoot));
nsCOMPtr<nsIContent> templRoot;
proto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(templRoot));
proto->GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(templRoot));
proto->LocateInstance(nsnull, templRoot, instanceRoot, content, getter_AddRefs(realContent));
if (!realContent)
binding->GetBoundElement(getter_AddRefs(realContent));
@ -842,7 +792,7 @@ nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent*
nsCOMPtr<nsIXBLInsertionPointEntry> entry = getter_AddRefs(NS_STATIC_CAST(nsIXBLInsertionPointEntry*,
mInsertionPointTable->Get(&key)));
if (!entry) {
nsISupportsKey key2(kChildrenAtom);
nsISupportsKey key2(nsXBLAtoms::children);
entry = getter_AddRefs(NS_STATIC_CAST(nsIXBLInsertionPointEntry*, mInsertionPointTable->Get(&key2)));
}
@ -853,7 +803,7 @@ nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent*
entry->GetInsertionIndex(aIndex);
entry->GetDefaultContent(aDefaultContent); // Addref happens here.
nsCOMPtr<nsIContent> templContent;
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(templContent));
LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent));
}
else {
@ -881,7 +831,7 @@ nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
{
if (mInsertionPointTable) {
if(mInsertionPointTable->Count() == 1) {
nsISupportsKey key(kChildrenAtom);
nsISupportsKey key(nsXBLAtoms::children);
nsCOMPtr<nsIXBLInsertionPointEntry> entry = getter_AddRefs(NS_STATIC_CAST(nsIXBLInsertionPointEntry*,
mInsertionPointTable->Get(&key)));
nsCOMPtr<nsIContent> realContent;
@ -891,7 +841,7 @@ nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
entry->GetInsertionIndex(aIndex);
entry->GetDefaultContent(aDefaultContent); // Addref happens here.
nsCOMPtr<nsIContent> templContent;
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(templContent));
LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent));
}
else {
@ -969,7 +919,7 @@ nsXBLPrototypeBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
mBinding->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get()) {
if (aTag == tag) {
*aResult = child;
NS_ADDREF(*aResult);
return;
@ -983,7 +933,7 @@ void
nsXBLPrototypeBinding::ConstructProperties()
{
nsCOMPtr<nsIContent> properties;
GetImmediateChild(kImplementationAtom, getter_AddRefs(properties));
GetImmediateChild(nsXBLAtoms::implementation, getter_AddRefs(properties));
if (properties && mBinding) {
nsXBLService::BuildPropertyChain(this, properties, getter_AddRefs(mPrototypeProperty));
}
@ -1094,16 +1044,10 @@ nsXBLPrototypeBinding::InitClass(const nsCString& aClassName, nsIScriptContext *
}
void
nsXBLPrototypeBinding::ConstructHandlers()
nsXBLPrototypeBinding::BuildConstructorAndDestructor()
{
// See if this binding has a handler elt.
nsCOMPtr<nsIContent> handlers;
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
if (handlers)
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(mPrototypeHandler));
nsCOMPtr<nsIContent> impl;
GetImmediateChild(kImplementationAtom, getter_AddRefs(impl));
GetImmediateChild(nsXBLAtoms::implementation, getter_AddRefs(impl));
if (impl) {
// Look for <constructor> and <destructor>.
PRInt32 count;
@ -1113,12 +1057,18 @@ nsXBLPrototypeBinding::ConstructHandlers()
impl->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (tag.get() == kConstructorAtom) {
NS_NewXBLPrototypeHandler(child, getter_AddRefs(mConstructor));
if (tag == nsXBLAtoms::constructor) {
nsAutoString value;
nsXBLBinding::GetTextData(child, value);
NS_NewXBLPrototypeHandler(nsnull, nsnull, &value, nsnull, nsnull, nsnull, nsnull,
nsnull, nsnull, getter_AddRefs(mConstructor));
mConstructor->SetEventName(tag);
}
else if (tag.get() == kDestructorAtom) {
NS_NewXBLPrototypeHandler(child, getter_AddRefs(mDestructor));
else if (tag == nsXBLAtoms::destructor) {
nsAutoString value;
nsXBLBinding::GetTextData(child, value);
NS_NewXBLPrototypeHandler(nsnull, nsnull, &value, nsnull, nsnull, nsnull, nsnull,
nsnull, nsnull, getter_AddRefs(mDestructor));
mDestructor->SetEventName(tag);
}
}
@ -1144,7 +1094,7 @@ nsXBLPrototypeBinding::LocateInstance(nsIContent* aBoundElement, nsIContent* aTe
if (aBoundElement) {
nsCOMPtr<nsIAtom> tag;
templParent->GetTag(*getter_AddRefs(tag));
if (tag == kChildrenAtom) {
if (tag == nsXBLAtoms::children) {
childPoint = templParent;
childPoint->GetParent(*getter_AddRefs(templParent));
}
@ -1153,7 +1103,7 @@ nsXBLPrototypeBinding::LocateInstance(nsIContent* aBoundElement, nsIContent* aTe
if (!templParent)
return;
if (templParent.get() == aTemplRoot)
if (templParent == aTemplRoot)
copyParent = aCopyRoot;
else
LocateInstance(aBoundElement, aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent));
@ -1237,7 +1187,7 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
nsAutoString value;
PRBool attrPresent = PR_TRUE;
if (src.get() == nsXBLPrototypeBinding::kXBLTextAtom) {
if (src == nsXBLAtoms::xbltext) {
nsXBLBinding::GetTextData(changeData->mBoundElement, value);
value.StripChar('\n');
value.StripChar('\r');
@ -1255,7 +1205,7 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
if (attrPresent) {
nsCOMPtr<nsIContent> content;
changeData->mProto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(content));
changeData->mProto->GetImmediateChild(nsXBLAtoms::content, getter_AddRefs(content));
nsCOMPtr<nsIXBLAttributeEntry> curr = entry;
while (curr) {
@ -1271,8 +1221,8 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
realElement->SetAttr(kNameSpaceID_None, dst, value, PR_FALSE);
nsCOMPtr<nsIAtom> tag;
realElement->GetTag(*getter_AddRefs(tag));
if (dst.get() == nsXBLPrototypeBinding::kXBLTextAtom ||
(tag.get() == nsXBLPrototypeBinding::kHTMLAtom) && (dst.get() == nsXBLPrototypeBinding::kValueAtom) && !value.IsEmpty()) {
if (dst == nsXBLAtoms::xbltext ||
(tag == nsHTMLAtoms::html) && (dst == nsHTMLAtoms::value) && !value.IsEmpty()) {
nsCOMPtr<nsIDOMText> textNode;
nsCOMPtr<nsIDocument> doc;
changeData->mBoundElement->GetDocument(*getter_AddRefs(doc));
@ -1324,7 +1274,7 @@ nsXBLPrototypeBinding::ShouldBuildChildFrames(PRBool* aResult)
{
*aResult = PR_TRUE;
if (mAttributeTable) {
nsISupportsKey key(kXBLTextAtom);
nsISupportsKey key(nsXBLAtoms::xbltext);
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
mAttributeTable->Get(&key)));
@ -1338,7 +1288,7 @@ void
nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
{
nsAutoString inherits;
aElement->GetAttr(kNameSpaceID_None, kInheritsAtom, inherits);
aElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::inherits, inherits);
if (!inherits.IsEmpty()) {
if (!mAttributeTable) {
mAttributeTable = new nsSupportsHashtable(4);
@ -1400,7 +1350,7 @@ nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
// Now remove the inherits attribute from the element so that it doesn't
// show up on clones of the element. It is used
// by the template only, and we don't need it anymore.
aElement->UnsetAttr(kNameSpaceID_None, kInheritsAtom, PR_FALSE);
aElement->UnsetAttr(kNameSpaceID_None, nsXBLAtoms::inherits, PR_FALSE);
token = nsCRT::strtok( newStr, ", ", &newStr );
}
@ -1422,7 +1372,7 @@ void
nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
{
nsCOMPtr<nsISupportsArray> childrenElements;
GetNestedChildren(kChildrenAtom, aContent, getter_AddRefs(childrenElements));
GetNestedChildren(nsXBLAtoms::children, aContent, getter_AddRefs(childrenElements));
if (!childrenElements)
return;
@ -1444,9 +1394,9 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
nsXBLInsertionPointEntry* xblIns = nsXBLInsertionPointEntry::Create(parent);
nsAutoString includes;
child->GetAttr(kNameSpaceID_None, kIncludesAtom, includes);
child->GetAttr(kNameSpaceID_None, nsXBLAtoms::includes, includes);
if (includes.IsEmpty()) {
nsISupportsKey key(kChildrenAtom);
nsISupportsKey key(nsXBLAtoms::children);
mInsertionPointTable->Put(&key, xblIns);
}
else {
@ -1510,7 +1460,7 @@ void
nsXBLPrototypeBinding::ConstructInterfaceTable(nsIContent* aElement)
{
nsAutoString impls;
aElement->GetAttr(kNameSpaceID_None, kImplementsAtom, impls);
aElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::implements, impls);
if (!impls.IsEmpty()) {
// Obtain the interface info manager that can tell us the IID
// for a given interface name.
@ -1557,7 +1507,7 @@ nsXBLPrototypeBinding::GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, ns
aContent->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get()) {
if (aTag == tag) {
if (!*aList)
NS_NewISupportsArray(aList); // Addref happens here.
(*aList)->AppendElement(child);
@ -1671,13 +1621,11 @@ nsresult
NS_NewXBLPrototypeBinding(const nsAReadableCString& aRef, nsIContent* aElement,
nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult)
{
nsXBLPrototypeBinding * binding = new nsXBLPrototypeBinding(aRef, aInfo);
nsXBLPrototypeBinding * binding = new nsXBLPrototypeBinding(aRef, aInfo, aElement);
if (!binding)
return NS_ERROR_OUT_OF_MEMORY;
binding->QueryInterface(NS_GET_IID(nsIXBLPrototypeBinding), (void **) aResult);
binding->Initialize(aElement, aInfo);
*aResult = binding;
NS_ADDREF(*aResult);
return NS_OK;
}

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

@ -129,31 +129,15 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding, public nsICSSLoaderO
NS_IMETHOD GetConstructor(nsIXBLPrototypeHandler** aResult) { *aResult = mConstructor; NS_IF_ADDREF(*aResult); return NS_OK; };
NS_IMETHOD Initialize();
public:
nsXBLPrototypeBinding(const nsAReadableCString& aRef, nsIXBLDocumentInfo* aInfo);
nsXBLPrototypeBinding(const nsAReadableCString& aRef, nsIXBLDocumentInfo* aInfo, nsIContent* aElement);
virtual ~nsXBLPrototypeBinding();
void Initialize(nsIContent * aElement, nsIXBLDocumentInfo* aInfo);
// Static members
static PRUint32 gRefCnt;
static nsIAtom* kInheritStyleAtom;
static nsIAtom* kHandlersAtom;
static nsIAtom* kChildrenAtom;
static nsIAtom* kIncludesAtom;
static nsIAtom* kContentAtom;
static nsIAtom* kResourcesAtom;
static nsIAtom* kResourceAtom;
static nsIAtom* kStyleSheetAtom;
static nsIAtom* kSrcAtom;
static nsIAtom* kInheritsAtom;
static nsIAtom* kHTMLAtom;
static nsIAtom* kValueAtom;
static nsIAtom* kXBLTextAtom;
static nsIAtom* kConstructorAtom;
static nsIAtom* kDestructorAtom;
static nsIAtom* kImplementationAtom;
static nsIAtom* kImplementsAtom;
static nsFixedSizeAllocator* kAttrPool;
static nsFixedSizeAllocator* kInsPool;
@ -165,7 +149,7 @@ public:
nsIContent* aTemplChild, nsIContent** aCopyResult);
protected:
void ConstructHandlers();
void BuildConstructorAndDestructor();
void ConstructProperties();
void ConstructAttributeTable(nsIContent* aElement);
void ConstructInsertionTable(nsIContent* aElement);

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

@ -70,10 +70,14 @@
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsXULAtoms.h"
#include "nsXBLAtoms.h"
#include "nsLayoutAtoms.h"
#include "nsGUIEvent.h"
#include "nsIXPConnect.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsDOMCID.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
@ -81,20 +85,6 @@ static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
PRUint32 nsXBLPrototypeHandler::gRefCnt = 0;
nsIAtom* nsXBLPrototypeHandler::kBindingAttachedAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kBindingDetachedAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kKeyCodeAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kCharCodeAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kKeyAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kActionAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kCommandAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kOnCommandAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kFocusCommandAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kClickCountAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kButtonAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kModifiersAtom = nsnull;
nsIAtom* nsXBLPrototypeHandler::kTypeAtom = nsnull;
PRInt32 nsXBLPrototypeHandler::kMenuAccessKey = -1;
PRInt32 nsXBLPrototypeHandler::kAccelKey = -1;
@ -103,52 +93,42 @@ const PRInt32 nsXBLPrototypeHandler::cAlt = (1<<2);
const PRInt32 nsXBLPrototypeHandler::cControl = (1<<3);
const PRInt32 nsXBLPrototypeHandler::cMeta = (1<<4);
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount)
{
NS_INIT_REFCNT();
gRefCnt++;
if (gRefCnt == 1)
// Get the primary accelerator key.
InitAccessKeys();
mHandlerText = nsnull;
ConstructPrototype(nsnull, aEvent, aPhase, aAction, aCommand, aKeyCode, aCharCode, aModifiers,
aButton, aClickCount);
}
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
{
NS_INIT_REFCNT();
mHandlerElement = aHandlerElement;
gRefCnt++;
if (gRefCnt == 1) {
kBindingAttachedAtom = NS_NewAtom("bindingattached");
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
kKeyCodeAtom = NS_NewAtom("keycode");
kKeyAtom = NS_NewAtom("key");
kCharCodeAtom = NS_NewAtom("charcode");
kModifiersAtom = NS_NewAtom("modifiers");
kActionAtom = NS_NewAtom("action");
kCommandAtom = NS_NewAtom("command");
kOnCommandAtom = NS_NewAtom("oncommand");
kFocusCommandAtom = NS_NewAtom("focuscommand");
kClickCountAtom = NS_NewAtom("clickcount");
kButtonAtom = NS_NewAtom("button");
kTypeAtom = NS_NewAtom("event");
gRefCnt++;
if (gRefCnt == 1)
// Get the primary accelerator key.
InitAccessKeys();
}
// Make sure our mask is initialized.
ConstructMask();
// Make sure our prototype is initialized.
ConstructPrototype(aHandlerElement);
}
nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
{
gRefCnt--;
if (gRefCnt == 0) {
NS_RELEASE(kBindingAttachedAtom);
NS_RELEASE(kBindingDetachedAtom);
NS_RELEASE(kKeyAtom);
NS_RELEASE(kKeyCodeAtom);
NS_RELEASE(kCharCodeAtom);
NS_RELEASE(kModifiersAtom);
NS_RELEASE(kActionAtom);
NS_RELEASE(kOnCommandAtom);
NS_RELEASE(kCommandAtom);
NS_RELEASE(kFocusCommandAtom);
NS_RELEASE(kButtonAtom);
NS_RELEASE(kClickCountAtom);
NS_RELEASE(kTypeAtom);
}
if (mType != NS_HANDLER_TYPE_XUL && mHandlerText)
nsMemory::Free(mHandlerText);
}
NS_IMPL_ISUPPORTS1(nsXBLPrototypeHandler, nsIXBLPrototypeHandler)
@ -156,8 +136,21 @@ NS_IMPL_ISUPPORTS1(nsXBLPrototypeHandler, nsIXBLPrototypeHandler)
NS_IMETHODIMP
nsXBLPrototypeHandler::GetHandlerElement(nsIContent** aResult)
{
if (mType == NS_HANDLER_TYPE_XUL) {
*aResult = mHandlerElement;
NS_IF_ADDREF(*aResult);
}
else
*aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXBLPrototypeHandler::SetHandlerText(const nsAReadableString& aText)
{
if (mHandlerText)
nsMemory::Free(mHandlerText);
mHandlerText = ToNewUnicode(aText);
return NS_OK;
}
@ -209,13 +202,11 @@ NS_IMETHODIMP
nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
nsIDOMEvent* aEvent)
{
if (!mHandlerElement)
if (!mHandlerElement) // This works for both types of handlers. In both cases, the union's var should be defined.
return NS_ERROR_FAILURE;
// See if our event receiver is a content node (and not us).
nsCOMPtr<nsIAtom> tag;
mHandlerElement->GetTag(*getter_AddRefs(tag));
PRBool isXULKey = (tag.get() == nsXULAtoms::key);
PRBool isXULKey = (mType == NS_HANDLER_TYPE_XUL);
PRBool isReceiverCommandElement = PR_FALSE;
nsCOMPtr<nsIContent> content(do_QueryInterface(aReceiver));
@ -224,25 +215,7 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
// This is a special-case optimization to make command handling fast.
// It isn't really a part of XBL, but it helps speed things up.
nsAutoString command;
mHandlerElement->GetAttr(kNameSpaceID_None, kCommandAtom, command);
if (!command.IsEmpty() && !isReceiverCommandElement) {
// Make sure the XBL doc is chrome or resource
// Fix for bug #45989
nsCOMPtr<nsIDocument> document;
mHandlerElement->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIURI> url;
document->GetDocumentURL(getter_AddRefs(url));
PRBool isChrome = PR_FALSE;
PRBool isRes = PR_FALSE;
url->SchemeIs("chrome", &isChrome);
url->SchemeIs("resource", &isRes);
if (!isChrome && !isRes)
return NS_OK;
if (mType == NS_HANDLER_TYPE_XBL_COMMAND && !isReceiverCommandElement) {
// See if preventDefault has been set. If so, don't execute.
PRBool preventDefault;
nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent(do_QueryInterface(aEvent));
@ -291,16 +264,18 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
privateWindow->GetRootFocusController(getter_AddRefs(focusController));
}
nsDependentString command(mHandlerText);
if (focusController)
focusController->GetControllerForCommand(command, getter_AddRefs(controller));
else GetController(aReceiver, getter_AddRefs(controller)); // We're attached to the receiver possibly.
nsAutoString type;
GetEventType (type);
mEventName->ToString(type);
if (type == NS_LITERAL_STRING("keypress") &&
mDetail == nsIDOMKeyEvent::DOM_VK_SPACE &&
mDetail2 == 1) {
mMisc == 1) {
// get the focused element so that we can pageDown only at
// certain times.
nsCOMPtr<nsIDOMElement> focusedElement;
@ -338,26 +313,21 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
void* handler = nsnull;
// Compile the event handler.
nsAutoString handlerText;
mHandlerElement->GetAttr(kNameSpaceID_None, kActionAtom, handlerText);
if (handlerText.IsEmpty()) {
// look to see if action content is contained by the handler element
GetTextData(mHandlerElement, handlerText);
if (handlerText.IsEmpty()) {
nsAutoString xulText;
if (isXULKey) {
// Try an oncommand attribute (used by XUL <key> elements, which
// are implemented using this code).
mHandlerElement->GetAttr(kNameSpaceID_None, kOnCommandAtom, handlerText);
if (handlerText.IsEmpty()) {
mHandlerElement->GetAttr(kNameSpaceID_None, nsLayoutAtoms::oncommand, xulText);
if (xulText.IsEmpty()) {
// Maybe the receiver is a <command> elt.
if (isReceiverCommandElement)
// It is! See if it has an oncommand attribute.
content->GetAttr(kNameSpaceID_None, kOnCommandAtom, handlerText);
content->GetAttr(kNameSpaceID_None, nsLayoutAtoms::oncommand, xulText);
if (handlerText.IsEmpty())
if (xulText.IsEmpty())
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
}
}
}
if (isXULKey)
aEvent->PreventDefault(); // Preventing default for XUL key handlers
@ -425,8 +395,16 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
NS_ENSURE_SUCCESS(rv, rv);
}
if (isXULKey)
boundContext->CompileEventHandler(scriptObject, onEventAtom, xulText,
PR_TRUE, &handler);
else {
nsDependentString handlerText(mHandlerText);
if (handlerText.IsEmpty())
return NS_ERROR_FAILURE;
boundContext->CompileEventHandler(scriptObject, onEventAtom, handlerText,
PR_TRUE, &handler);
}
// Temporarily bind it to the bound element
boundContext->BindCompiledEventHandler(scriptObject, onEventAtom, handler);
@ -583,12 +561,12 @@ nsXBLPrototypeHandler::KeyEventMatched(nsIAtom* aEventType, nsIDOMKeyEvent* aKey
{
*aResult = PR_TRUE;
if (!mHandlerElement || (aEventType != mEventName.get())) {
if (aEventType != mEventName.get()) {
*aResult = PR_FALSE;
return NS_OK;
}
if (mDetail == -1 && mDetail2 == 0 && mKeyMask == 0)
if (mDetail == -1 && mMisc == 0 && mKeyMask == 0)
return NS_OK; // No filters set up. It's generic.
// Get the keycode and charcode of the key event.
@ -596,7 +574,7 @@ nsXBLPrototypeHandler::KeyEventMatched(nsIAtom* aEventType, nsIDOMKeyEvent* aKey
aKeyEvent->GetKeyCode(&keyCode);
aKeyEvent->GetCharCode(&charCode);
PRBool keyMatched = (mDetail == PRInt32(mDetail2 ? charCode : keyCode));
PRBool keyMatched = (mDetail == PRInt32(mMisc ? charCode : keyCode));
if (!keyMatched) {
*aResult = PR_FALSE;
@ -614,12 +592,12 @@ nsXBLPrototypeHandler::MouseEventMatched(nsIAtom* aEventType, nsIDOMMouseEvent*
{
*aResult = PR_TRUE;
if (!mHandlerElement || (aEventType != mEventName.get())) {
if (aEventType != mEventName.get()) {
*aResult = PR_FALSE;
return NS_OK;
}
if (mDetail == -1 && mDetail2 == 0 && mKeyMask == 0)
if (mDetail == -1 && mMisc == 0 && mKeyMask == 0)
return NS_OK; // No filters set up. It's generic.
unsigned short button;
@ -631,7 +609,7 @@ nsXBLPrototypeHandler::MouseEventMatched(nsIAtom* aEventType, nsIDOMMouseEvent*
PRInt32 clickcount;
aMouseEvent->GetDetail(&clickcount);
if (mDetail2 != 0 && (clickcount != mDetail2)) {
if (mMisc != 0 && (clickcount != mMisc)) {
*aResult = PR_FALSE;
return NS_OK;
}
@ -641,7 +619,7 @@ nsXBLPrototypeHandler::MouseEventMatched(nsIAtom* aEventType, nsIDOMMouseEvent*
return NS_OK;
}
PRInt32 nsXBLPrototypeHandler::GetMatchingKeyCode(const nsString& aKeyName)
PRInt32 nsXBLPrototypeHandler::GetMatchingKeyCode(const nsAReadableString& aKeyName)
{
nsCAutoString keyName; keyName.AssignWithConversion(aKeyName);
@ -930,58 +908,78 @@ PRInt32 nsXBLPrototypeHandler::KeyToMask(PRInt32 key)
}
void
nsXBLPrototypeHandler::GetEventType(nsAWritableString &type)
nsXBLPrototypeHandler::GetEventType(nsAWritableString& aEvent)
{
mHandlerElement->GetAttr(kNameSpaceID_None, kTypeAtom, type);
mHandlerElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::event, aEvent);
if (type.IsEmpty()) {
// If we're a XUL key element, let's assume that we're "keypress".
nsCOMPtr<nsIAtom> tag;
mHandlerElement->GetTag(*getter_AddRefs(tag));
if (tag.get() == kKeyAtom)
type = NS_LITERAL_STRING("keypress");
}
if (aEvent.IsEmpty() && mType == NS_HANDLER_TYPE_XUL)
// If no type is specified for a XUL <key> element, let's assume that we're "keypress".
aEvent = NS_LITERAL_STRING("keypress");
}
void
nsXBLPrototypeHandler::ConstructMask()
nsXBLPrototypeHandler::ConstructPrototype(nsIContent* aKeyElement,
nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount)
{
if (aKeyElement) {
mType = NS_HANDLER_TYPE_XUL;
mHandlerElement = aKeyElement;
}
else {
mType = aCommand ? NS_HANDLER_TYPE_XBL_COMMAND : NS_HANDLER_TYPE_XBL_JS;
mHandlerText = nsnull;
}
mDetail = -1;
mDetail2 = 0;
mMisc = 0;
mKeyMask = 0;
mPhase = NS_PHASE_BUBBLING;
nsAutoString type;
mHandlerElement->GetAttr(kNameSpaceID_None, kTypeAtom, type);
if (aAction)
mHandlerText = ToNewUnicode(*aAction);
else if (aCommand)
mHandlerText = ToNewUnicode(*aCommand);
if (type.IsEmpty()) {
// If we're a XUL key element, let's assume that we're "keypress".
nsCOMPtr<nsIAtom> tag;
mHandlerElement->GetTag(*getter_AddRefs(tag));
if (tag.get() == kKeyAtom)
type = NS_LITERAL_STRING("keypress");
else return;
nsAutoString event;
if (!aEvent) {
if (mType == NS_HANDLER_TYPE_XUL)
GetEventType(event);
if (event.IsEmpty())
return;
aEvent = &event;
}
mEventName = getter_AddRefs(NS_NewAtom(type));
if ((*aEvent).IsEmpty())
return;
mEventName = getter_AddRefs(NS_NewAtom(*aEvent));
nsAutoString buttonStr, clickCountStr;
mHandlerElement->GetAttr(kNameSpaceID_None, kClickCountAtom, clickCountStr);
mHandlerElement->GetAttr(kNameSpaceID_None, kButtonAtom, buttonStr);
if (!buttonStr.IsEmpty()) {
PRInt32 error;
mDetail = buttonStr.ToInteger(&error);
if (aPhase) {
if ((*aPhase).Equals(NS_LITERAL_STRING("capturing")))
mPhase = NS_PHASE_CAPTURING;
else if ((*aPhase).Equals(NS_LITERAL_STRING("target")))
mPhase = NS_PHASE_TARGET;
}
if (!clickCountStr.IsEmpty()) {
PRInt32 error;
mDetail2 = clickCountStr.ToInteger(&error);
}
// Button and clickcount apply only to XBL handlers and don't apply to XUL key
// handlers.
if (aButton && !(*aButton).IsEmpty())
mDetail = (*aButton).First() - '0';
if (aClickCount && !(*aClickCount).IsEmpty())
mMisc = (*aClickCount).First() - '0';
// Modifiers are supported by both types of handlers (XUL and XBL).
nsAutoString modifiers;
mHandlerElement->GetAttr(kNameSpaceID_None, kModifiersAtom, modifiers);
if (!modifiers.IsEmpty()) {
char* str = ToNewCString(modifiers);
if (!aModifiers)
aModifiers = &modifiers;
if (mType == NS_HANDLER_TYPE_XUL)
mHandlerElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::modifiers, modifiers);
if (!(*aModifiers).IsEmpty()) {
char* str = ToNewCString(*aModifiers);
char* newStr;
char* token = nsCRT::strtok( str, ", ", &newStr );
while( token != NULL ) {
@ -1005,24 +1003,34 @@ nsXBLPrototypeHandler::ConstructMask()
}
nsAutoString key;
mHandlerElement->GetAttr(kNameSpaceID_None, kKeyAtom, key);
if (!aCharCode) {
aCharCode = &key;
if (mType == NS_HANDLER_TYPE_XUL) {
mHandlerElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::key, key);
if (key.IsEmpty())
mHandlerElement->GetAttr(kNameSpaceID_None, kCharCodeAtom, key);
if (!key.IsEmpty()) {
mHandlerElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::charcode, key);
}
}
if (!(*aCharCode).IsEmpty()) {
nsAutoString charCode(*aCharCode);
if ((mKeyMask & cShift) != 0)
key.ToUpperCase();
else key.ToLowerCase();
charCode.ToUpperCase();
else
charCode.ToLowerCase();
// We have a charcode.
mDetail2 = 1;
mDetail = key[0];
mMisc = 1;
mDetail = charCode[0];
}
else {
mHandlerElement->GetAttr(kNameSpaceID_None, kKeyCodeAtom, key);
if (!key.IsEmpty())
mDetail = GetMatchingKeyCode(key);
if (!aKeyCode)
aKeyCode = &key;
if (mType == NS_HANDLER_TYPE_XUL)
mHandlerElement->GetAttr(kNameSpaceID_None, nsXBLAtoms::keycode, key);
if (!(*aKeyCode).IsEmpty())
mDetail = GetMatchingKeyCode(*aKeyCode);
}
}
@ -1079,7 +1087,23 @@ nsXBLPrototypeHandler::GetTextData(nsIContent *aParent, nsString& aResult)
///////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult)
NS_NewXBLPrototypeHandler(nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount,
nsIXBLPrototypeHandler** aResult)
{
*aResult = new nsXBLPrototypeHandler(aEvent, aPhase, aAction, aCommand, aKeyCode,
aCharCode, aModifiers, aButton, aClickCount);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult
NS_NewXULKeyHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult)
{
*aResult = new nsXBLPrototypeHandler(aHandlerElement);
if (!*aResult)
@ -1087,3 +1111,4 @@ NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler**
NS_ADDREF(*aResult);
return NS_OK;
}

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

@ -42,6 +42,7 @@
#include "nsIXBLPrototypeHandler.h"
#include "nsIAtom.h"
#include "nsString.h"
class nsIXBLBinding;
class nsIDOMEvent;
@ -49,12 +50,28 @@ class nsIContent;
class nsIDOMUIEvent;
class nsIDOMKeyEvent;
class nsIDOMMouseEvent;
class nsString;
#define NS_HANDLER_TYPE_XBL_JS 0
#define NS_HANDLER_TYPE_XBL_COMMAND 1
#define NS_HANDLER_TYPE_XUL 2
#define NS_PHASE_BUBBLING 0
#define NS_PHASE_TARGET 1
#define NS_PHASE_CAPTURING 2
class nsXBLPrototypeHandler : public nsIXBLPrototypeHandler
{
public:
nsXBLPrototypeHandler(nsIContent* aHandlerElement);
// This constructor is used by XBL handlers (both the JS and command shorthand variety)
nsXBLPrototypeHandler(nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount);
// This constructor is used only by XUL key handlers (e.g., <key>)
nsXBLPrototypeHandler(nsIContent* aKeyElement);
virtual ~nsXBLPrototypeHandler();
NS_DECL_ISUPPORTS
@ -64,6 +81,10 @@ public:
NS_IMETHOD GetHandlerElement(nsIContent** aResult);
NS_IMETHOD SetHandlerText(const nsAReadableString& aText);
NS_IMETHOD GetPhase(PRUint8* aResult) { *aResult = mPhase; return NS_OK; };
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult);
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler);
@ -80,25 +101,17 @@ public:
static PRUint32 gRefCnt;
static nsIAtom* kBindingAttachedAtom;
static nsIAtom* kBindingDetachedAtom;
static nsIAtom* kKeyAtom;
static nsIAtom* kKeyCodeAtom;
static nsIAtom* kCharCodeAtom;
static nsIAtom* kActionAtom;
static nsIAtom* kCommandAtom;
static nsIAtom* kOnCommandAtom;
static nsIAtom* kFocusCommandAtom;
static nsIAtom* kClickCountAtom;
static nsIAtom* kButtonAtom;
static nsIAtom* kModifiersAtom;
static nsIAtom* kTypeAtom;
protected:
NS_IMETHOD GetController(nsIDOMEventReceiver* aReceiver, nsIController** aResult);
inline PRInt32 GetMatchingKeyCode(const nsString& aKeyName);
void ConstructMask();
inline PRInt32 GetMatchingKeyCode(const nsAReadableString& aKeyName);
void ConstructPrototype(nsIContent* aKeyElement,
nsAReadableString* aEvent=nsnull, nsAReadableString* aPhase=nsnull,
nsAReadableString* aAction=nsnull, nsAReadableString* aCommand=nsnull,
nsAReadableString* aKeyCode=nsnull, nsAReadableString* aCharCode=nsnull,
nsAReadableString* aModifiers=nsnull, nsAReadableString* aButton=nsnull,
nsAReadableString* aClickCount=nsnull);
void GetEventType(nsAWritableString& type);
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
@ -117,23 +130,42 @@ protected:
static const PRInt32 cMeta;
protected:
nsIContent* mHandlerElement; // This ref is weak.
union {
nsIContent* mHandlerElement; // For XUL <key> element handlers.
PRUnichar* mHandlerText; // For XBL handlers (we don't build an element for the <handler>,
// and instead we cache the JS text or command name that we should
// use.
};
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
// The following four values make up 32 bits.
PRUint8 mPhase; // The phase (capturing, bubbling)
PRUint8 mKeyMask; // Which modifier keys this event handler expects to have down
// in order to be matched.
PRUint8 mType; // The type of the handler. The handler is either a XUL key
// handler, an XBL "command" event, or a normal XBL event with
// accompanying JavaScript.
PRUint8 mMisc; // Miscellaneous extra information. For key events,
// stores whether or not we're a key code or char code.
// For mouse events, stores the clickCount.
// The primary filter information for mouse/key events.
PRInt32 mDetail; // For key events, contains a charcode or keycode. For
// mouse events, stores the button info.
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
// stores whether or not we're a key code or char code.
// For mouse events, stores the clickCount.
nsCOMPtr<nsIXBLPrototypeHandler> mNextHandler; // Prototype handlers are chained. We own the next handler in the chain.
nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress"
};
extern nsresult
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
NS_NewXBLPrototypeHandler(nsAReadableString* aEvent, nsAReadableString* aPhase,
nsAReadableString* aAction, nsAReadableString* aCommand,
nsAReadableString* aKeyCode, nsAReadableString* aCharCode,
nsAReadableString* aModifiers, nsAReadableString* aButton,
nsAReadableString* aClickCount, nsIXBLPrototypeHandler** aResult);
extern nsresult
NS_NewXULKeyHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
#endif

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

@ -70,10 +70,11 @@
#include "nsIMemory.h"
#include "nsIObserverService.h"
#include "nsIDOMNodeList.h"
#include "nsXBLContentSink.h"
#include "nsIXBLBinding.h"
#include "nsIXBLPrototypeBinding.h"
#include "nsIXBLDocumentInfo.h"
#include "nsXBLAtoms.h"
#include "nsIXBLPrototypeHandler.h"
#include "nsIXBLPrototypeProperty.h"
@ -91,7 +92,6 @@
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static PRBool IsChromeOrResourceURI(nsIURI* aURI)
{
@ -392,9 +392,12 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
return NS_ERROR_FAILURE;
}
// Put our doc in the doc table.
// Put our doc info in the doc table.
nsCOMPtr<nsIXBLDocumentInfo> info;
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
nsCOMPtr<nsIBindingManager> xblDocBindingManager;
mBindingDocument->GetBindingManager(getter_AddRefs(xblDocBindingManager));
xblDocBindingManager->GetXBLDocumentInfo(nsCAutoString(NS_STATIC_CAST(const char*, str)), getter_AddRefs(info));
xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
// If the doc is a chrome URI, then we put it into the XUL cache.
PRBool cached = PR_FALSE;
@ -405,14 +408,6 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
cached = PR_TRUE;
gXULCache->PutXBLDocumentInfo(info);
}
// Cache whether or not this chrome XBL can execute scripts.
nsCOMPtr<nsIChromeRegistry> reg(do_GetService(kChromeRegistryCID, &rv));
if (NS_SUCCEEDED(rv) && reg) {
PRBool allow = PR_TRUE;
reg->AllowScriptsForSkin(uri, &allow);
info->SetScriptAccess(allow);
}
}
if (!cached)
@ -542,8 +537,6 @@ JSCList nsXBLService::gClassLRUList = JS_INIT_STATIC_CLIST(&nsXBLService::gClas
PRUint32 nsXBLService::gClassLRUListLength = 0;
PRUint32 nsXBLService::gClassLRUListQuota = 64;
nsIAtom* nsXBLService::kDisplayAtom = nsnull;
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
nsIAtom* nsXBLService::kEventAtom = nsnull;
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
nsIAtom* nsXBLService::kInputAtom = nsnull;
@ -552,8 +545,6 @@ nsIAtom* nsXBLService::kInputAtom = nsnull;
PRBool nsXBLService::gDisableChromeCache = PR_FALSE;
static const char kDisableChromeCachePref[] = "nglayout.debug.disable_xul_cache";
PRInt32 nsXBLService::kNameSpaceID_XBL;
// Implement our nsISupports methods
NS_IMPL_ISUPPORTS3(nsXBLService, nsIXBLService, nsIObserver, nsISupportsWeakReference)
@ -565,8 +556,6 @@ nsXBLService::nsXBLService(void)
gRefCnt++;
if (gRefCnt == 1) {
// Register the XBL namespace.
nsresult rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
nsnull,
NS_GET_IID(nsINameSpaceManager),
@ -574,17 +563,7 @@ nsXBLService::nsXBLService(void)
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create namespace manager");
if (NS_FAILED(rv)) return;
// XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp
static const char kXBLNameSpaceURI[]
= "http://www.mozilla.org/xbl";
rv = gNameSpaceManager->RegisterNameSpace(NS_ConvertASCIItoUCS2(kXBLNameSpaceURI), kNameSpaceID_XBL);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register XBL namespace");
if (NS_FAILED(rv)) return;
// Create our atoms
kDisplayAtom = NS_NewAtom("display");
kExtendsAtom = NS_NewAtom("extends");
kEventAtom = NS_NewAtom("event");
kScrollbarAtom = NS_NewAtom("scrollbar");
kInputAtom = NS_NewAtom("input");
@ -610,8 +589,6 @@ nsXBLService::~nsXBLService(void)
NS_IF_RELEASE(gNameSpaceManager);
// Release our atoms
NS_RELEASE(kDisplayAtom);
NS_RELEASE(kExtendsAtom);
NS_RELEASE(kEventAtom);
NS_RELEASE(kScrollbarAtom);
NS_RELEASE(kInputAtom);
@ -976,43 +953,14 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
nsCOMPtr<nsIXBLPrototypeBinding> protoBinding;
docInfo->GetPrototypeBinding(ref, getter_AddRefs(protoBinding));
nsCOMPtr<nsIContent> child;
if (!protoBinding) {
// We have a doc. Obtain our specific binding element.
// Walk the children looking for the binding that matches the ref
// specified in the URL.
nsCOMPtr<nsIContent> root;
doc->GetRootContent(getter_AddRefs(root));
if (!root)
return NS_ERROR_FAILURE;
nsAutoString bindingName; bindingName.AssignWithConversion( ref.get() );
PRInt32 count;
root->ChildCount(count);
for (PRInt32 i = 0; i < count; i++) {
root->ChildAt(i, *getter_AddRefs(child));
nsAutoString value;
child->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, value);
// If no ref is specified just use this.
if ((bindingName.IsEmpty()) || (bindingName == value)) {
// Construct a prototype binding.
NS_NewXBLPrototypeBinding(ref, child, docInfo, getter_AddRefs(protoBinding));
docInfo->SetPrototypeBinding(ref, protoBinding);
break;
}
}
}
else
protoBinding->GetBindingElement(getter_AddRefs(child));
NS_ASSERTION(protoBinding, "Unable to locate an XBL binding.");
if (!protoBinding)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> child;
protoBinding->GetBindingElement(getter_AddRefs(child));
// Our prototype binding must have all its resources loaded.
PRBool ready;
protoBinding->LoadResources(&ready);
@ -1034,17 +982,12 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
baseProto->GetBindingURI(url);
if (NS_FAILED(GetBindingInternal(aBoundElement, url, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
return NS_ERROR_FAILURE; // We aren't ready yet.
if (!aPeekOnly) {
// Make sure to set the base prototype.
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
protoBinding->SetBasePrototype(baseProto);
}
}
else if (hasBase) {
// Check for the presence of 'extends' and 'display' attributes
nsAutoString display, extends;
child->GetAttr(kNameSpaceID_None, kDisplayAtom, display);
child->GetAttr(kNameSpaceID_None, kExtendsAtom, extends);
child->GetAttr(kNameSpaceID_None, nsXBLAtoms::display, display);
child->GetAttr(kNameSpaceID_None, nsXBLAtoms::extends, extends);
PRBool hasDisplay = !display.IsEmpty();
PRBool hasExtends = !extends.IsEmpty();
@ -1053,6 +996,7 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
if (!hasExtends)
protoBinding->SetHasBasePrototype(PR_FALSE);
else {
// Now slice 'em up to see what we've got.
nsAutoString prefix;
PRInt32 offset;
if (hasDisplay) {
@ -1085,8 +1029,8 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
if (!hasDisplay) {
// We extend some widget/frame. We don't really have a
// base binding.
protoBinding->SetHasBasePrototype(PR_FALSE);
//child->UnsetAttr(kNameSpaceID_None, nsXBLAtoms::extends, PR_FALSE);
}
PRInt32 nameSpaceID;
@ -1114,6 +1058,8 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
// Make sure to set the base prototype.
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
protoBinding->SetBasePrototype(baseProto);
child->UnsetAttr(kNameSpaceID_None, nsXBLAtoms::extends, PR_FALSE);
child->UnsetAttr(kNameSpaceID_None, nsXBLAtoms::display, PR_FALSE);
}
}
}
@ -1198,7 +1144,10 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
FetchBindingDocument(aBoundElement, aBoundDocument, uri, aRef, aForceSyncLoad, getter_AddRefs(document));
if (document) {
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
nsCOMPtr<nsIBindingManager> xblDocBindingManager;
document->GetBindingManager(getter_AddRefs(xblDocBindingManager));
xblDocBindingManager->GetXBLDocumentInfo(aURLStr, getter_AddRefs(info));
xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
// If the doc is a chrome URI, then we put it into the XUL cache.
PRBool cached = PR_FALSE;
@ -1207,14 +1156,6 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
cached = PR_TRUE;
gXULCache->PutXBLDocumentInfo(info);
}
// Cache whether or not this chrome XBL can execute scripts.
nsCOMPtr<nsIChromeRegistry> reg(do_GetService(kChromeRegistryCID, &rv));
if (NS_SUCCEEDED(rv) && reg) {
PRBool allow = PR_TRUE;
reg->AllowScriptsForSkin(uri, &allow);
info->SetScriptAccess(allow);
}
}
if (!cached && bindingManager) {
@ -1272,12 +1213,19 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
aForceSyncLoad = PR_TRUE;
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsIXMLContentSink> xblSink;
NS_NewXBLContentSink(getter_AddRefs(xblSink), xmlDoc, aURI, nsnull);
if (!xblSink)
return NS_ERROR_FAILURE;
if(!aForceSyncLoad) {
if (NS_FAILED(rv = xmlDoc->StartDocumentLoad("loadAsData",
channel,
loadGroup,
nsnull,
getter_AddRefs(listener)))) {
getter_AddRefs(listener),
PR_TRUE,
xblSink))) {
NS_ERROR("Failure to init XBL doc prior to load.");
return rv;
}
@ -1331,7 +1279,9 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
channel,
loadGroup,
nsnull,
getter_AddRefs(listener)))) {
getter_AddRefs(listener),
PR_TRUE,
xblSink))) {
NS_ERROR("Failure to init XBL doc prior to load.");
return rv;
}
@ -1457,38 +1407,6 @@ nsXBLService::BuildPropertyChain(nsIXBLPrototypeBinding * aPrototypeBinding, nsI
return NS_OK;
}
nsresult
nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult)
{
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
PRInt32 handlerCount;
aContent->ChildCount(handlerCount);
for (PRInt32 j = 0; j < handlerCount; j++) {
nsCOMPtr<nsIContent> handler;
aContent->ChildAt(j, *getter_AddRefs(handler));
nsAutoString event;
handler->GetAttr(kNameSpaceID_None, kEventAtom, event);
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
NS_NewXBLPrototypeHandler(handler, getter_AddRefs(newHandler));
if (newHandler) {
if (currHandler)
currHandler->SetNextHandler(newHandler);
else firstHandler = newHandler;
currHandler = newHandler;
}
}
*aResult = firstHandler;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult NS_NewXBLService(nsIXBLService** aResult);

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

@ -118,7 +118,6 @@ public:
// This method walks a binding document and removes any text nodes
// that contain only whitespace.
static nsresult StripWhitespaceNodes(nsIContent* aContent);
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
static nsresult BuildPropertyChain(nsIXBLPrototypeBinding * aPrototypeBinding, nsIContent * aContent, nsIXBLPrototypeProperty ** aResult);
// MEMBER VARIABLES
@ -127,7 +126,6 @@ public:
static nsIXULPrototypeCache* gXULCache;
static nsINameSpaceManager* gNameSpaceManager; // Used to register the XBL namespace
static PRInt32 kNameSpaceID_XBL; // Convenient cached XBL namespace.
static PRUint32 gRefCnt; // A count of XBLservice instances.
@ -140,8 +138,6 @@ public:
static PRUint32 gClassLRUListQuota; // Quota on class LRU list.
// XBL Atoms
static nsIAtom* kDisplayAtom;
static nsIAtom* kExtendsAtom;
static nsIAtom* kEventAtom;
static nsIAtom* kScrollbarAtom;
static nsIAtom* kInputAtom;

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

@ -148,29 +148,11 @@ nsXBLSpecialDocInfo::GetHandlers(nsIXBLDocumentInfo* aInfo,
{
nsCOMPtr<nsIXBLPrototypeBinding> binding;
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
if (!binding) {
nsCOMPtr<nsIDocument> doc;
aInfo->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIContent> root;
doc->GetRootContent(getter_AddRefs(root));
if (root) { // no root, no handlers. don't crash please.
PRInt32 childCount;
root->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
root->ChildAt(i, *getter_AddRefs(child));
nsAutoString id;
child->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id, id);
if (id.EqualsWithConversion(PromiseFlatCString(aRef).get())) {
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
aInfo->SetPrototypeBinding(aRef, binding);
break;
}
}
}
}
if (binding)
NS_ASSERTION(binding, "No binding found for the XBL window key handler.");
if (!binding)
return;
binding->GetPrototypeHandlers(aResult); // Addref happens here.
} // GetHandlers
@ -318,6 +300,7 @@ nsXBLWindowHandler::WalkHandlersInternal(nsIDOMEvent* aEvent, nsIAtom* aEventTyp
}
}
if (commandElt)
commandElt->GetAttribute(NS_LITERAL_STRING("disabled"), disabled);
if (!disabled.Equals(NS_LITERAL_STRING("true"))) {
nsCOMPtr<nsIDOMEventReceiver> rec = mReceiver;

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

@ -53,6 +53,7 @@
#include "nsIXBLDocumentInfo.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMElement.h"
#include "nsXBLAtoms.h"
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
@ -85,6 +86,32 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener)
static void
BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult)
{
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
PRInt32 handlerCount;
aContent->ChildCount(handlerCount);
for (PRInt32 j = 0; j < handlerCount; j++) {
nsCOMPtr<nsIContent> handler;
aContent->ChildAt(j, *getter_AddRefs(handler));
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
NS_NewXULKeyHandler(handler, getter_AddRefs(newHandler));
if (newHandler) {
if (currHandler)
currHandler->SetNextHandler(newHandler);
else firstHandler = newHandler;
currHandler = newHandler;
}
}
*aResult = firstHandler;
NS_IF_ADDREF(*aResult);
}
//
// EnsureHandlers
@ -95,18 +122,17 @@ NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler, nsIDOMKeyListener)
nsresult
nsXBLWindowKeyHandler::EnsureHandlers()
{
nsresult rv = NS_ERROR_FAILURE;
if (mElement) {
// We are actually a XUL <keyset>.
if (mHandler)
return NS_OK;
nsCOMPtr<nsIContent> content(do_QueryInterface(mElement));
rv = nsXBLService::BuildHandlerChain(content, getter_AddRefs(mHandler));
BuildHandlerChain(content, getter_AddRefs(mHandler));
}
else
else // We are an XBL file of handlers.
nsXBLWindowHandler::EnsureHandlers();
return rv;
return NS_OK;
}

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

@ -63,6 +63,7 @@
#include "nsIServiceManager.h"
#include "nsIURI.h"
#include "nsXPIDLString.h"
#include "nsXBLAtoms.h"
PRUint32 nsXBLXULHandler::gRefCnt = 0;
nsIAtom* nsXBLXULHandler::kPopupShowingAtom = nsnull;
@ -113,7 +114,7 @@ nsresult nsXBLXULHandler::Command(nsIDOMEvent* aEvent)
nsCOMPtr<nsIAtom> eventName;
mProtoHandler->GetEventName(getter_AddRefs(eventName));
if (eventName.get() != nsXBLPrototypeHandler::kCommandAtom)
if (eventName.get() != nsXBLAtoms::command)
return NS_OK;
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);

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

@ -704,6 +704,9 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
PRInt32 nameSpaceID = GetNameSpaceId(nameSpacePrefix);
if (!OnOpenContainer(aNode, nameSpaceID, tagAtom))
return NS_OK;
nsCOMPtr<nsINodeInfo> nodeInfo;
mNodeInfoManager->GetNodeInfo(tagAtom, nameSpacePrefix, nameSpaceID,

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

@ -184,6 +184,8 @@ protected:
void ScrollToRef();
virtual PRBool OnOpenContainer(const nsIParserNode& aNode, PRInt32 aNameSpaceID, nsIAtom* aTagName) { return PR_TRUE; };
static nsINameSpaceManager* gNameSpaceManager;
static PRUint32 gRefCnt;

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

@ -370,12 +370,13 @@ nsXMLDocument::StartDocumentLoad(const char* aCommand,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset)
PRBool aReset,
nsIContentSink* aSink)
{
nsresult rv = nsDocument::StartDocumentLoad(aCommand,
aChannel, aLoadGroup,
aContainer,
aDocListener, aReset);
aDocListener, aReset, aSink);
if (NS_FAILED(rv)) return rv;
nsAutoString charset(NS_LITERAL_STRING("UTF-8"));
@ -424,7 +425,7 @@ nsXMLDocument::StartDocumentLoad(const char* aCommand,
(void **)&mParser);
if (NS_FAILED(rv)) return rv;
nsIXMLContentSink* sink;
nsCOMPtr<nsIXMLContentSink> sink;
nsCOMPtr<nsIDocShell> docShell;
if(aContainer)
@ -586,10 +587,17 @@ nsXMLDocument::StartDocumentLoad(const char* aCommand,
} //got content view
nsCOMPtr<nsIWebShell> webShell(do_QueryInterface(docShell));
rv = NS_NewXMLContentSink(&sink, this, aUrl, webShell);
}
if (aSink)
sink = do_QueryInterface(aSink);
else
rv = NS_NewXMLContentSink(&sink, this, aUrl, nsnull);
rv = NS_NewXMLContentSink(getter_AddRefs(sink), this, aUrl, webShell);
}
else {
if (aSink)
sink = do_QueryInterface(aSink);
else
rv = NS_NewXMLContentSink(getter_AddRefs(sink), this, aUrl, nsnull);
}
if (NS_OK == rv) {
// Set the parser as the stream listener for the document loader...
@ -602,7 +610,6 @@ nsXMLDocument::StartDocumentLoad(const char* aCommand,
mParser->SetContentSink(sink);
mParser->Parse(aUrl, nsnull, PR_FALSE, (void *)this);
}
NS_RELEASE(sink);
}
return rv;

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

@ -74,7 +74,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
PRBool aReset = PR_TRUE,
nsIContentSink* aSink = nsnull);
NS_IMETHOD EndLoad();

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

@ -726,7 +726,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset)
PRBool aReset,
nsIContentSink* aSink)
{
nsresult rv;

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

@ -149,7 +149,8 @@ public:
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset);
PRBool aReset = PR_TRUE,
nsIContentSink* aSink = nsnull);
NS_IMETHOD StopDocumentLoad();

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

@ -13095,6 +13095,9 @@ nsCSSFrameConstructor::WipeContainingBlock(nsIPresContext* aPresContext,
// situation: an inline frame that will now contain block
// frames. This is a no-no and the frame construction logic knows
// how to fix this.
if (!aBlockContent)
return PR_FALSE;
const nsStyleDisplay* parentDisplay;
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&) parentDisplay);
if (NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) {

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

@ -52,6 +52,7 @@
#include "nsIPrintContext.h"
#include "nsTextTransformer.h"
#include "nsXBLAtoms.h" // to addref/release table
#include "nsHTMLAtoms.h" // to addref/release table
#include "nsLayoutAtoms.h" // to addref/release table
#include "nsCSSKeywords.h" // to addref/release table
@ -100,6 +101,7 @@ Initialize(nsIModule* self)
nsCSSProps::AddRefTable();
nsColorNames::AddRefTable();
nsHTMLAtoms::AddRefAtoms();
nsXBLAtoms::AddRefAtoms();
nsLayoutAtoms::AddRefAtoms();
#ifdef INCLUDE_XUL
nsXULAtoms::AddRefAtoms();
@ -142,6 +144,7 @@ Shutdown(nsIModule* self)
nsCSSKeywords::ReleaseTable();
nsCSSAtoms::ReleaseAtoms();
nsHTMLAtoms::ReleaseAtoms();
nsXBLAtoms::ReleaseAtoms();
nsLayoutAtoms::ReleaseAtoms();
#ifdef INCLUDE_XUL

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

@ -13095,6 +13095,9 @@ nsCSSFrameConstructor::WipeContainingBlock(nsIPresContext* aPresContext,
// situation: an inline frame that will now contain block
// frames. This is a no-no and the frame construction logic knows
// how to fix this.
if (!aBlockContent)
return PR_FALSE;
const nsStyleDisplay* parentDisplay;
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&) parentDisplay);
if (NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) {