Bug 34623. Add 'rebuild()' API to XUL elements.

This commit is contained in:
waterson%netscape.com 2000-05-05 23:39:59 +00:00
Родитель e365632082
Коммит 3a3b744651
17 изменённых файлов: 309 добавлений и 173 удалений

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

@ -31,6 +31,8 @@
#include "nsISupports.h"
class nsIAtom;
class nsIRDFCompositeDataSource;
class nsIXULTemplateBuilder;
class nsString;
// {39C5ECC0-5C47-11d3-BE36-00104BDE6048}
@ -111,6 +113,12 @@ public:
* should call this method, think again. You shouldn't.
*/
NS_IMETHOD ForceElementToOwnResource(PRBool aForce) = 0;
/**
* Initialize the root element in a XUL template
*/
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder) = 0;
};
#endif // nsIXULContent_h__

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

@ -97,6 +97,7 @@
#include "nsIXULDocument.h"
#include "nsIXULPopupListener.h"
#include "nsIXULPrototypeDocument.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIXBLService.h"
#include "nsLayoutCID.h"
#include "nsRDFCID.h"
@ -1812,6 +1813,26 @@ nsXULElement::ForceElementToOwnResource(PRBool aForce)
return NS_OK;
}
NS_IMETHODIMP
nsXULElement::InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder)
{
// Sanity check
NS_PRECONDITION(Database() == nsnull, "already initialized");
if (Database())
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv;
rv = EnsureSlots();
if (NS_FAILED(rv)) return rv;
mSlots->mDatabase = aDatabase;
mSlots->mBuilder = aBuilder;
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMEventReceiver interface
@ -3529,10 +3550,6 @@ nsXULElement::GetResource(nsIRDFResource** aResource)
NS_IMETHODIMP
nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
{
NS_PRECONDITION(aDatabase != nsnull, "null ptr");
if (! aDatabase)
return NS_ERROR_NULL_POINTER;
*aDatabase = Database();
NS_IF_ADDREF(*aDatabase);
return NS_OK;
@ -3540,21 +3557,10 @@ nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
NS_IMETHODIMP
nsXULElement::SetDatabase(nsIRDFCompositeDataSource* aDatabase)
nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
{
// XXX maybe someday you'll be allowed to change it.
NS_PRECONDITION(Database() == nsnull, "already initialized");
if (Database())
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv;
rv = EnsureSlots();
if (NS_FAILED(rv)) return rv;
mSlots->mDatabase = aDatabase;
// XXX reconstruct the entire tree now!
*aBuilder = Builder();
NS_IF_ADDREF(*aBuilder);
return NS_OK;
}
@ -4494,6 +4500,7 @@ nsXULElement::Slots::Slots(nsXULElement* aElement)
mNameSpaceID(0),
mBroadcastListeners(nsnull),
mBroadcaster(nsnull),
mBuilder(nsnull),
mAttributes(nsnull),
mInnerXULElement(nsnull)
{

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

@ -68,6 +68,7 @@ class nsIRDFService;
class nsISupportsArray;
class nsIXULContentUtils;
class nsIXULPrototypeDocument;
class nsIXULTemplateBuilder;
class nsRDFDOMNodeList;
class nsString;
class nsVoidArray;
@ -445,6 +446,8 @@ public:
NS_IMETHOD GetLazyState(PRInt32 aFlag, PRBool& aValue);
NS_IMETHOD AddScriptEventListener(nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
NS_IMETHOD ForceElementToOwnResource(PRBool aForce);
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder);
// nsIBindableContent interface
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);
@ -587,6 +590,7 @@ protected:
nsIDOMXULElement* mBroadcaster; // [WEAK]
nsCOMPtr<nsIControllers> mControllers; // [OWNER]
nsCOMPtr<nsIRDFCompositeDataSource> mDatabase; // [OWNER]
nsIXULTemplateBuilder* mBuilder; // [WEAK]
nsCOMPtr<nsIRDFResource> mOwnedResource; // [OWNER]
nsXULAttributes* mAttributes;
nsCOMPtr<nsIXBLBinding> mBinding; // [OWNER]
@ -613,6 +617,7 @@ protected:
nsIDOMXULElement* Broadcaster() const { return mSlots ? mSlots->mBroadcaster : nsnull; }
nsIControllers* Controllers() const { return mSlots ? mSlots->mControllers.get() : nsnull; }
nsIRDFCompositeDataSource* Database() const { return mSlots ? mSlots->mDatabase.get() : nsnull; }
nsIXULTemplateBuilder* Builder() const { return mSlots ? mSlots->mBuilder : nsnull; }
nsIRDFResource* OwnedResource() const { return mSlots ? mSlots->mOwnedResource.get() : nsnull; }
nsXULAttributes* Attributes() const { return mSlots ? mSlots->mAttributes : nsnull; }
nsXULAggregateElement* InnerXULElement() const { return mSlots ? mSlots->mInnerXULElement : nsnull; }

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

@ -62,6 +62,7 @@
#include "nsIRDFContainerUtils.h"
#include "nsIRDFContentModelBuilder.h"
#include "nsIXULDocument.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIRDFNode.h"
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
@ -2333,7 +2334,8 @@ ContentSupportMap::Get(nsIContent* aElement, Match** aMatch)
// nsXULTemplateBuilder
//
class nsXULTemplateBuilder : public nsIRDFContentModelBuilder,
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
public nsIRDFContentModelBuilder,
public nsIRDFObserver
{
public:
@ -2345,6 +2347,9 @@ public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIXULTemplateBuilder interface
NS_DECL_NSIXULTEMPLATEBUILDER
// nsIRDFContentModelBuilder interface
NS_IMETHOD SetDocument(nsIXULDocument* aDocument);
NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase);
@ -2514,7 +2519,6 @@ public:
nsresult RemoveGeneratedContent(nsIContent* aElement);
// XXX. Urg. Hack until layout can batch reflows. See bug 10818.
PRBool
IsTreeWidgetItem(nsIContent* aElement);
@ -2522,7 +2526,7 @@ public:
GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult);
nsresult
AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsIRDFCompositeDataSource* aDataBase);
InitHTMLTemplateRoot();
nsresult
GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements);
@ -3979,7 +3983,23 @@ nsXULTemplateBuilder::Init()
return NS_OK;
}
NS_IMPL_ISUPPORTS2(nsXULTemplateBuilder, nsIRDFContentModelBuilder, nsIRDFObserver);
NS_IMPL_ISUPPORTS3(nsXULTemplateBuilder,
nsIXULTemplateBuilder,
nsIRDFContentModelBuilder,
nsIRDFObserver);
//----------------------------------------------------------------------
//
// nsIXULTemplateBuilder methods
//
NS_IMETHODIMP
nsXULTemplateBuilder::Rebuild()
{
CompileRules();
RebuildContainer(mRoot);
return NS_OK;
}
//----------------------------------------------------------------------
//
@ -3995,7 +4015,6 @@ nsXULTemplateBuilder::SetDocument(nsIXULDocument* aDocument)
return NS_OK;
}
NS_IMETHODIMP
nsXULTemplateBuilder::SetDataBase(nsIRDFCompositeDataSource* aDataBase)
{
@ -4015,15 +4034,15 @@ nsXULTemplateBuilder::SetDataBase(nsIRDFCompositeDataSource* aDataBase)
// Now set the database on the element, so that script writers can
// access it.
nsCOMPtr<nsIDOMXULElement> element( do_QueryInterface(mRoot) );
if (element) {
rv = element->SetDatabase(aDataBase);
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(mRoot);
if (xulcontent) {
rv = xulcontent->InitTemplateRoot(aDataBase, this);
if (NS_FAILED(rv)) return rv;
}
else {
// Hmm. This must be an HTML element. Try to set it as a
// JS property "by hand".
rv = AddDatabasePropertyToHTMLElement(mRoot, mDB);
rv = InitHTMLTemplateRoot();
if (NS_FAILED(rv)) return rv;
}
}
@ -5957,9 +5976,7 @@ nsXULTemplateBuilder::RemoveGeneratedContent(nsIContent* aElement)
PRBool
nsXULTemplateBuilder::IsTreeWidgetItem(nsIContent* aElement)
{
// Determine if this is a <tree> or a <treeitem> tag, in which
// case, some special logic will kick in to force batched reflows.
// XXX Should be removed when Bug 10818 is fixed.
// Determine if this is a <tree> or a <treeitem> element
nsresult rv;
PRInt32 nameSpaceID;
@ -5970,23 +5987,21 @@ nsXULTemplateBuilder::IsTreeWidgetItem(nsIContent* aElement)
rv = aElement->GetTag(*getter_AddRefs(tag));
if (NS_FAILED(rv)) return PR_FALSE;
// If we're building content under a <tree> or a <treeitem>,
// then DO NOT notify layout until we're all done.
if ((nameSpaceID == kNameSpaceID_XUL) &&
((tag.get() == nsXULAtoms::tree) || (tag.get() == nsXULAtoms::treeitem))) {
return PR_TRUE;
}
else {
if (nameSpaceID != kNameSpaceID_XUL)
return PR_FALSE;
}
if ((tag.get() == nsXULAtoms::tree) || (tag.get() == nsXULAtoms::treeitem))
return PR_TRUE;
return PR_FALSE;
}
nsresult
nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsIRDFCompositeDataSource* aDataBase)
nsXULTemplateBuilder::InitHTMLTemplateRoot()
{
// Use XPConnect and the JS APIs to whack aDatabase as the
// 'database' property onto aElement.
// 'database' and 'builder' properties onto aElement.
nsresult rv;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
@ -6009,10 +6024,10 @@ nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsI
if (! jscontext)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIScriptObjectOwner> owner = do_QueryInterface(aElement);
nsCOMPtr<nsIScriptObjectOwner> owner = do_QueryInterface(mRoot);
NS_ASSERTION(owner != nsnull, "unable to get script object owner");
if (! owner)
return NS_ERROR_UNEXPECTED;
return NS_ERROR_UNEXPECTED;
JSObject* jselement;
rv = owner->GetScriptObject(context, (void**) &jselement);
@ -6024,28 +6039,54 @@ nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsI
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
aDataBase,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(wrapper));
{
// database
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
mDB,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(wrapper));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap database");
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap database");
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
if (NS_FAILED(rv)) return rv;
jsval jsdatabase = OBJECT_TO_JSVAL(jsobj);
jsval jsdatabase = OBJECT_TO_JSVAL(jsobj);
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "database", &jsdatabase);
NS_ASSERTION(ok, "unable to set database property");
if (! ok)
return NS_ERROR_FAILURE;
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "database", &jsdatabase);
NS_ASSERTION(ok, "unable to set database property");
if (! ok)
return NS_ERROR_FAILURE;
}
{
// builder
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
NS_STATIC_CAST(nsIXULTemplateBuilder*, this),
NS_GET_IID(nsIXULTemplateBuilder),
getter_AddRefs(wrapper));
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
if (NS_FAILED(rv)) return rv;
jsval jsbuilder = OBJECT_TO_JSVAL(jsobj);
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "builder", &jsbuilder);
if (! ok)
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@ -6151,6 +6192,7 @@ nsXULTemplateBuilder::SetEmpty(nsIContent *aElement, const Match* aMatch)
}
void
nsXULTemplateBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
{

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

@ -5,7 +5,8 @@ interface XULElement : Element {
attribute DOMString id;
attribute DOMString className;
readonly attribute CSSStyleDeclaration style;
attribute xpidl nsIRDFCompositeDataSource database;
readonly attribute xpidl nsIRDFCompositeDataSource database;
readonly attribute xpidl nsIXULTemplateBuilder builder;
readonly attribute xpidl nsIRDFResource resource;
readonly attribute xpidl nsIControllers controllers;
readonly attribute NodeList anonymousContent;
@ -14,9 +15,9 @@ interface XULElement : Element {
void removeBroadcastListener(in DOMString attr, in Element element);
void doCommand();
void focus();
void blur();
void click();
void focus();
void blur();
void click();
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
};

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

@ -978,6 +978,7 @@ enum nsDOMProp {
NS_DOM_PROP_XULEDITORELEMENT_EDITORSHELL,
NS_DOM_PROP_XULELEMENT_ADDBROADCASTLISTENER,
NS_DOM_PROP_XULELEMENT_ANONYMOUSCONTENT,
NS_DOM_PROP_XULELEMENT_BUILDER,
NS_DOM_PROP_XULELEMENT_BLUR,
NS_DOM_PROP_XULELEMENT_CLASSNAME,
NS_DOM_PROP_XULELEMENT_CLICK,

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

@ -977,6 +977,7 @@
"xuleditorelement.editorshell", \
"xulelement.addbroadcastlistener", \
"xulelement.anonymouscontent", \
"xulelement.builder", \
"xulelement.blur", \
"xulelement.classname", \
"xulelement.click", \

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

@ -32,6 +32,7 @@
class nsIDOMElement;
class nsIDOMCSSStyleDeclaration;
class nsIRDFCompositeDataSource;
class nsIXULTemplateBuilder;
class nsIRDFResource;
class nsIDOMNodeList;
class nsIControllers;
@ -53,7 +54,8 @@ public:
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle)=0;
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase)=0;
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase)=0;
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder)=0;
NS_IMETHOD GetResource(nsIRDFResource** aResource)=0;
@ -84,7 +86,7 @@ public:
NS_IMETHOD SetClassName(const nsString& aClassName); \
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle); \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase); \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase); \
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder); \
NS_IMETHOD GetResource(nsIRDFResource** aResource); \
NS_IMETHOD GetControllers(nsIControllers** aControllers); \
NS_IMETHOD GetAnonymousContent(nsIDOMNodeList** aAnonymousContent); \
@ -105,7 +107,7 @@ public:
NS_IMETHOD SetClassName(const nsString& aClassName) { return _to SetClassName(aClassName); } \
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) { return _to GetStyle(aStyle); } \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase) { return _to GetDatabase(aDatabase); } \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase) { return _to SetDatabase(aDatabase); } \
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder) { return _to GetBuilder(aBuilder); } \
NS_IMETHOD GetResource(nsIRDFResource** aResource) { return _to GetResource(aResource); } \
NS_IMETHOD GetControllers(nsIControllers** aControllers) { return _to GetControllers(aControllers); } \
NS_IMETHOD GetAnonymousContent(nsIDOMNodeList** aAnonymousContent) { return _to GetAnonymousContent(aAnonymousContent); } \

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

@ -38,6 +38,7 @@
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsIRDFCompositeDataSource.h"
#include "nsIDOMXULElement.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIRDFResource.h"
#include "nsIDOMNodeList.h"
#include "nsIControllers.h"
@ -50,6 +51,7 @@ static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kICSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID);
static NS_DEFINE_IID(kIRDFCompositeDataSourceIID, NS_IRDFCOMPOSITEDATASOURCE_IID);
static NS_DEFINE_IID(kIXULElementIID, NS_IDOMXULELEMENT_IID);
static NS_DEFINE_IID(kIXULTemplateBuilderIID, NS_IXULTEMPLATEBUILDER_IID);
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
static NS_DEFINE_IID(kIControllersIID, NS_ICONTROLLERS_IID);
@ -62,9 +64,10 @@ enum XULElement_slots {
XULELEMENT_CLASSNAME = -2,
XULELEMENT_STYLE = -3,
XULELEMENT_DATABASE = -4,
XULELEMENT_RESOURCE = -5,
XULELEMENT_CONTROLLERS = -6,
XULELEMENT_ANONYMOUSCONTENT = -7
XULELEMENT_BUILDER = -5,
XULELEMENT_RESOURCE = -6,
XULELEMENT_CONTROLLERS = -7,
XULELEMENT_ANONYMOUSCONTENT = -8
};
/***********************************************************************/
@ -137,6 +140,19 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
break;
}
case XULELEMENT_BUILDER:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_BUILDER, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
nsIXULTemplateBuilder* prop;
rv = a->GetBuilder(&prop);
if (NS_SUCCEEDED(rv)) {
// get the js object; n.b., this will do a release on 'prop'
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIXULTemplateBuilder), cx, obj, vp);
}
}
break;
}
case XULELEMENT_RESOURCE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_RESOURCE, PR_FALSE);
@ -233,21 +249,6 @@ SetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
break;
}
case XULELEMENT_DATABASE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_DATABASE, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsIRDFCompositeDataSource* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToXPCObject((nsISupports **) &prop,
kIRDFCompositeDataSourceIID, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_XPC_OBJECT_ERR;
}
rv = a->SetDatabase(prop);
NS_IF_RELEASE(prop);
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
@ -602,7 +603,8 @@ static JSPropertySpec XULElementProperties[] =
{"id", XULELEMENT_ID, JSPROP_ENUMERATE},
{"className", XULELEMENT_CLASSNAME, JSPROP_ENUMERATE},
{"style", XULELEMENT_STYLE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"database", XULELEMENT_DATABASE, JSPROP_ENUMERATE},
{"database", XULELEMENT_DATABASE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"builder", XULELEMENT_BUILDER, JSPROP_ENUMERATE | JSPROP_READONLY},
{"resource", XULELEMENT_RESOURCE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"controllers", XULELEMENT_CONTROLLERS, JSPROP_ENUMERATE | JSPROP_READONLY},
{"anonymousContent", XULELEMENT_ANONYMOUSCONTENT, JSPROP_ENUMERATE | JSPROP_READONLY},

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

@ -5,7 +5,8 @@ interface XULElement : Element {
attribute DOMString id;
attribute DOMString className;
readonly attribute CSSStyleDeclaration style;
attribute xpidl nsIRDFCompositeDataSource database;
readonly attribute xpidl nsIRDFCompositeDataSource database;
readonly attribute xpidl nsIXULTemplateBuilder builder;
readonly attribute xpidl nsIRDFResource resource;
readonly attribute xpidl nsIControllers controllers;
readonly attribute NodeList anonymousContent;
@ -14,9 +15,9 @@ interface XULElement : Element {
void removeBroadcastListener(in DOMString attr, in Element element);
void doCommand();
void focus();
void blur();
void click();
void focus();
void blur();
void click();
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
};

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

@ -20,7 +20,7 @@
# Contributor(s):
MODULE=rdf
MODULE=xul
DEPTH=..\..\..

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

@ -32,6 +32,7 @@
class nsIDOMElement;
class nsIDOMCSSStyleDeclaration;
class nsIRDFCompositeDataSource;
class nsIXULTemplateBuilder;
class nsIRDFResource;
class nsIDOMNodeList;
class nsIControllers;
@ -53,7 +54,8 @@ public:
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle)=0;
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase)=0;
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase)=0;
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder)=0;
NS_IMETHOD GetResource(nsIRDFResource** aResource)=0;
@ -84,7 +86,7 @@ public:
NS_IMETHOD SetClassName(const nsString& aClassName); \
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle); \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase); \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase); \
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder); \
NS_IMETHOD GetResource(nsIRDFResource** aResource); \
NS_IMETHOD GetControllers(nsIControllers** aControllers); \
NS_IMETHOD GetAnonymousContent(nsIDOMNodeList** aAnonymousContent); \
@ -105,7 +107,7 @@ public:
NS_IMETHOD SetClassName(const nsString& aClassName) { return _to SetClassName(aClassName); } \
NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) { return _to GetStyle(aStyle); } \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase) { return _to GetDatabase(aDatabase); } \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase) { return _to SetDatabase(aDatabase); } \
NS_IMETHOD GetBuilder(nsIXULTemplateBuilder** aBuilder) { return _to GetBuilder(aBuilder); } \
NS_IMETHOD GetResource(nsIRDFResource** aResource) { return _to GetResource(aResource); } \
NS_IMETHOD GetControllers(nsIControllers** aControllers) { return _to GetControllers(aControllers); } \
NS_IMETHOD GetAnonymousContent(nsIDOMNodeList** aAnonymousContent) { return _to GetAnonymousContent(aAnonymousContent); } \

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

@ -31,6 +31,8 @@
#include "nsISupports.h"
class nsIAtom;
class nsIRDFCompositeDataSource;
class nsIXULTemplateBuilder;
class nsString;
// {39C5ECC0-5C47-11d3-BE36-00104BDE6048}
@ -111,6 +113,12 @@ public:
* should call this method, think again. You shouldn't.
*/
NS_IMETHOD ForceElementToOwnResource(PRBool aForce) = 0;
/**
* Initialize the root element in a XUL template
*/
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder) = 0;
};
#endif // nsIXULContent_h__

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

@ -38,6 +38,7 @@
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsIRDFCompositeDataSource.h"
#include "nsIDOMXULElement.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIRDFResource.h"
#include "nsIDOMNodeList.h"
#include "nsIControllers.h"
@ -50,6 +51,7 @@ static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kICSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID);
static NS_DEFINE_IID(kIRDFCompositeDataSourceIID, NS_IRDFCOMPOSITEDATASOURCE_IID);
static NS_DEFINE_IID(kIXULElementIID, NS_IDOMXULELEMENT_IID);
static NS_DEFINE_IID(kIXULTemplateBuilderIID, NS_IXULTEMPLATEBUILDER_IID);
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
static NS_DEFINE_IID(kIControllersIID, NS_ICONTROLLERS_IID);
@ -62,9 +64,10 @@ enum XULElement_slots {
XULELEMENT_CLASSNAME = -2,
XULELEMENT_STYLE = -3,
XULELEMENT_DATABASE = -4,
XULELEMENT_RESOURCE = -5,
XULELEMENT_CONTROLLERS = -6,
XULELEMENT_ANONYMOUSCONTENT = -7
XULELEMENT_BUILDER = -5,
XULELEMENT_RESOURCE = -6,
XULELEMENT_CONTROLLERS = -7,
XULELEMENT_ANONYMOUSCONTENT = -8
};
/***********************************************************************/
@ -137,6 +140,19 @@ GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
break;
}
case XULELEMENT_BUILDER:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_BUILDER, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
nsIXULTemplateBuilder* prop;
rv = a->GetBuilder(&prop);
if (NS_SUCCEEDED(rv)) {
// get the js object; n.b., this will do a release on 'prop'
nsJSUtils::nsConvertXPCObjectToJSVal(prop, NS_GET_IID(nsIXULTemplateBuilder), cx, obj, vp);
}
}
break;
}
case XULELEMENT_RESOURCE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_RESOURCE, PR_FALSE);
@ -233,21 +249,6 @@ SetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
break;
}
case XULELEMENT_DATABASE:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_XULELEMENT_DATABASE, PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsIRDFCompositeDataSource* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToXPCObject((nsISupports **) &prop,
kIRDFCompositeDataSourceIID, cx, *vp)) {
rv = NS_ERROR_DOM_NOT_XPC_OBJECT_ERR;
}
rv = a->SetDatabase(prop);
NS_IF_RELEASE(prop);
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, obj, id, vp);
}
@ -602,7 +603,8 @@ static JSPropertySpec XULElementProperties[] =
{"id", XULELEMENT_ID, JSPROP_ENUMERATE},
{"className", XULELEMENT_CLASSNAME, JSPROP_ENUMERATE},
{"style", XULELEMENT_STYLE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"database", XULELEMENT_DATABASE, JSPROP_ENUMERATE},
{"database", XULELEMENT_DATABASE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"builder", XULELEMENT_BUILDER, JSPROP_ENUMERATE | JSPROP_READONLY},
{"resource", XULELEMENT_RESOURCE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"controllers", XULELEMENT_CONTROLLERS, JSPROP_ENUMERATE | JSPROP_READONLY},
{"anonymousContent", XULELEMENT_ANONYMOUSCONTENT, JSPROP_ENUMERATE | JSPROP_READONLY},

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

@ -97,6 +97,7 @@
#include "nsIXULDocument.h"
#include "nsIXULPopupListener.h"
#include "nsIXULPrototypeDocument.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIXBLService.h"
#include "nsLayoutCID.h"
#include "nsRDFCID.h"
@ -1812,6 +1813,26 @@ nsXULElement::ForceElementToOwnResource(PRBool aForce)
return NS_OK;
}
NS_IMETHODIMP
nsXULElement::InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder)
{
// Sanity check
NS_PRECONDITION(Database() == nsnull, "already initialized");
if (Database())
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv;
rv = EnsureSlots();
if (NS_FAILED(rv)) return rv;
mSlots->mDatabase = aDatabase;
mSlots->mBuilder = aBuilder;
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMEventReceiver interface
@ -3529,10 +3550,6 @@ nsXULElement::GetResource(nsIRDFResource** aResource)
NS_IMETHODIMP
nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
{
NS_PRECONDITION(aDatabase != nsnull, "null ptr");
if (! aDatabase)
return NS_ERROR_NULL_POINTER;
*aDatabase = Database();
NS_IF_ADDREF(*aDatabase);
return NS_OK;
@ -3540,21 +3557,10 @@ nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
NS_IMETHODIMP
nsXULElement::SetDatabase(nsIRDFCompositeDataSource* aDatabase)
nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
{
// XXX maybe someday you'll be allowed to change it.
NS_PRECONDITION(Database() == nsnull, "already initialized");
if (Database())
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv;
rv = EnsureSlots();
if (NS_FAILED(rv)) return rv;
mSlots->mDatabase = aDatabase;
// XXX reconstruct the entire tree now!
*aBuilder = Builder();
NS_IF_ADDREF(*aBuilder);
return NS_OK;
}
@ -4494,6 +4500,7 @@ nsXULElement::Slots::Slots(nsXULElement* aElement)
mNameSpaceID(0),
mBroadcastListeners(nsnull),
mBroadcaster(nsnull),
mBuilder(nsnull),
mAttributes(nsnull),
mInnerXULElement(nsnull)
{

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

@ -68,6 +68,7 @@ class nsIRDFService;
class nsISupportsArray;
class nsIXULContentUtils;
class nsIXULPrototypeDocument;
class nsIXULTemplateBuilder;
class nsRDFDOMNodeList;
class nsString;
class nsVoidArray;
@ -445,6 +446,8 @@ public:
NS_IMETHOD GetLazyState(PRInt32 aFlag, PRBool& aValue);
NS_IMETHOD AddScriptEventListener(nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
NS_IMETHOD ForceElementToOwnResource(PRBool aForce);
NS_IMETHOD InitTemplateRoot(nsIRDFCompositeDataSource* aDatabase,
nsIXULTemplateBuilder* aBuilder);
// nsIBindableContent interface
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);
@ -587,6 +590,7 @@ protected:
nsIDOMXULElement* mBroadcaster; // [WEAK]
nsCOMPtr<nsIControllers> mControllers; // [OWNER]
nsCOMPtr<nsIRDFCompositeDataSource> mDatabase; // [OWNER]
nsIXULTemplateBuilder* mBuilder; // [WEAK]
nsCOMPtr<nsIRDFResource> mOwnedResource; // [OWNER]
nsXULAttributes* mAttributes;
nsCOMPtr<nsIXBLBinding> mBinding; // [OWNER]
@ -613,6 +617,7 @@ protected:
nsIDOMXULElement* Broadcaster() const { return mSlots ? mSlots->mBroadcaster : nsnull; }
nsIControllers* Controllers() const { return mSlots ? mSlots->mControllers.get() : nsnull; }
nsIRDFCompositeDataSource* Database() const { return mSlots ? mSlots->mDatabase.get() : nsnull; }
nsIXULTemplateBuilder* Builder() const { return mSlots ? mSlots->mBuilder : nsnull; }
nsIRDFResource* OwnedResource() const { return mSlots ? mSlots->mOwnedResource.get() : nsnull; }
nsXULAttributes* Attributes() const { return mSlots ? mSlots->mAttributes : nsnull; }
nsXULAggregateElement* InnerXULElement() const { return mSlots ? mSlots->mInnerXULElement : nsnull; }

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

@ -62,6 +62,7 @@
#include "nsIRDFContainerUtils.h"
#include "nsIRDFContentModelBuilder.h"
#include "nsIXULDocument.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIRDFNode.h"
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
@ -2333,7 +2334,8 @@ ContentSupportMap::Get(nsIContent* aElement, Match** aMatch)
// nsXULTemplateBuilder
//
class nsXULTemplateBuilder : public nsIRDFContentModelBuilder,
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
public nsIRDFContentModelBuilder,
public nsIRDFObserver
{
public:
@ -2345,6 +2347,9 @@ public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIXULTemplateBuilder interface
NS_DECL_NSIXULTEMPLATEBUILDER
// nsIRDFContentModelBuilder interface
NS_IMETHOD SetDocument(nsIXULDocument* aDocument);
NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase);
@ -2514,7 +2519,6 @@ public:
nsresult RemoveGeneratedContent(nsIContent* aElement);
// XXX. Urg. Hack until layout can batch reflows. See bug 10818.
PRBool
IsTreeWidgetItem(nsIContent* aElement);
@ -2522,7 +2526,7 @@ public:
GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult);
nsresult
AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsIRDFCompositeDataSource* aDataBase);
InitHTMLTemplateRoot();
nsresult
GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements);
@ -3979,7 +3983,23 @@ nsXULTemplateBuilder::Init()
return NS_OK;
}
NS_IMPL_ISUPPORTS2(nsXULTemplateBuilder, nsIRDFContentModelBuilder, nsIRDFObserver);
NS_IMPL_ISUPPORTS3(nsXULTemplateBuilder,
nsIXULTemplateBuilder,
nsIRDFContentModelBuilder,
nsIRDFObserver);
//----------------------------------------------------------------------
//
// nsIXULTemplateBuilder methods
//
NS_IMETHODIMP
nsXULTemplateBuilder::Rebuild()
{
CompileRules();
RebuildContainer(mRoot);
return NS_OK;
}
//----------------------------------------------------------------------
//
@ -3995,7 +4015,6 @@ nsXULTemplateBuilder::SetDocument(nsIXULDocument* aDocument)
return NS_OK;
}
NS_IMETHODIMP
nsXULTemplateBuilder::SetDataBase(nsIRDFCompositeDataSource* aDataBase)
{
@ -4015,15 +4034,15 @@ nsXULTemplateBuilder::SetDataBase(nsIRDFCompositeDataSource* aDataBase)
// Now set the database on the element, so that script writers can
// access it.
nsCOMPtr<nsIDOMXULElement> element( do_QueryInterface(mRoot) );
if (element) {
rv = element->SetDatabase(aDataBase);
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(mRoot);
if (xulcontent) {
rv = xulcontent->InitTemplateRoot(aDataBase, this);
if (NS_FAILED(rv)) return rv;
}
else {
// Hmm. This must be an HTML element. Try to set it as a
// JS property "by hand".
rv = AddDatabasePropertyToHTMLElement(mRoot, mDB);
rv = InitHTMLTemplateRoot();
if (NS_FAILED(rv)) return rv;
}
}
@ -5957,9 +5976,7 @@ nsXULTemplateBuilder::RemoveGeneratedContent(nsIContent* aElement)
PRBool
nsXULTemplateBuilder::IsTreeWidgetItem(nsIContent* aElement)
{
// Determine if this is a <tree> or a <treeitem> tag, in which
// case, some special logic will kick in to force batched reflows.
// XXX Should be removed when Bug 10818 is fixed.
// Determine if this is a <tree> or a <treeitem> element
nsresult rv;
PRInt32 nameSpaceID;
@ -5970,23 +5987,21 @@ nsXULTemplateBuilder::IsTreeWidgetItem(nsIContent* aElement)
rv = aElement->GetTag(*getter_AddRefs(tag));
if (NS_FAILED(rv)) return PR_FALSE;
// If we're building content under a <tree> or a <treeitem>,
// then DO NOT notify layout until we're all done.
if ((nameSpaceID == kNameSpaceID_XUL) &&
((tag.get() == nsXULAtoms::tree) || (tag.get() == nsXULAtoms::treeitem))) {
return PR_TRUE;
}
else {
if (nameSpaceID != kNameSpaceID_XUL)
return PR_FALSE;
}
if ((tag.get() == nsXULAtoms::tree) || (tag.get() == nsXULAtoms::treeitem))
return PR_TRUE;
return PR_FALSE;
}
nsresult
nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsIRDFCompositeDataSource* aDataBase)
nsXULTemplateBuilder::InitHTMLTemplateRoot()
{
// Use XPConnect and the JS APIs to whack aDatabase as the
// 'database' property onto aElement.
// 'database' and 'builder' properties onto aElement.
nsresult rv;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
@ -6009,10 +6024,10 @@ nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsI
if (! jscontext)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIScriptObjectOwner> owner = do_QueryInterface(aElement);
nsCOMPtr<nsIScriptObjectOwner> owner = do_QueryInterface(mRoot);
NS_ASSERTION(owner != nsnull, "unable to get script object owner");
if (! owner)
return NS_ERROR_UNEXPECTED;
return NS_ERROR_UNEXPECTED;
JSObject* jselement;
rv = owner->GetScriptObject(context, (void**) &jselement);
@ -6024,28 +6039,54 @@ nsXULTemplateBuilder::AddDatabasePropertyToHTMLElement(nsIContent* aElement, nsI
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
aDataBase,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(wrapper));
{
// database
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
mDB,
NS_GET_IID(nsIRDFCompositeDataSource),
getter_AddRefs(wrapper));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap database");
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap database");
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
if (NS_FAILED(rv)) return rv;
jsval jsdatabase = OBJECT_TO_JSVAL(jsobj);
jsval jsdatabase = OBJECT_TO_JSVAL(jsobj);
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "database", &jsdatabase);
NS_ASSERTION(ok, "unable to set database property");
if (! ok)
return NS_ERROR_FAILURE;
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "database", &jsdatabase);
NS_ASSERTION(ok, "unable to set database property");
if (! ok)
return NS_ERROR_FAILURE;
}
{
// builder
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
jselement,
NS_STATIC_CAST(nsIXULTemplateBuilder*, this),
NS_GET_IID(nsIXULTemplateBuilder),
getter_AddRefs(wrapper));
if (NS_FAILED(rv)) return rv;
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
if (NS_FAILED(rv)) return rv;
jsval jsbuilder = OBJECT_TO_JSVAL(jsobj);
PRBool ok;
ok = JS_SetProperty(jscontext, jselement, "builder", &jsbuilder);
if (! ok)
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@ -6151,6 +6192,7 @@ nsXULTemplateBuilder::SetEmpty(nsIContent *aElement, const Match* aMatch)
}
void
nsXULTemplateBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
{