Many bug fixes to the RDF content model including namespace changes and

style support.
This commit is contained in:
hyatt%netscape.com 1999-03-05 00:01:26 +00:00
Родитель c7503b0018
Коммит 7eb40f9c2d
10 изменённых файлов: 822 добавлений и 364 удалений

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

@ -39,7 +39,7 @@
#include "nsCOMPtr.h"
#include "nsDOMCID.h"
#include "nsDOMEvent.h"
#include "nsGenericAttribute.h"
#include "nsXULAttributes.h"
#include "nsHashtable.h"
#include "nsIAtom.h"
#include "nsIXMLContent.h"
@ -81,6 +81,10 @@
#include "nsIDOMKeyListener.h"
#include "nsIDOMFormListener.h"
#include "nsIScriptContextOwner.h"
#include "nsIStyledContent.h"
#include "nsIStyleRule.h"
#include "nsIURL.h"
#include "rdfutil.h"
// The XUL interfaces implemented by the RDF content node.
#include "nsIDOMXULElement.h"
@ -141,7 +145,7 @@ class RDFElementImpl : public nsIDOMXULElement,
public nsIDOMEventReceiver,
public nsIScriptObjectOwner,
public nsIJSScriptObject,
public nsIXMLContent
public nsIStyledContent
{
public:
RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag);
@ -161,7 +165,7 @@ public:
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIContent (from nsIRDFContent via nsIXMLContent)
// nsIContent (from nsIStyledContent)
// Any of the nsIContent methods that directly manipulate content
// (e.g., AppendChildTo()), are assumed to "know what they're
@ -204,7 +208,22 @@ public:
NS_IMETHOD RangeRemove(nsIDOMRange& aRange);
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const;
// nsIXMLContent (from nsIRDFContent)
NS_IMETHOD GetID(nsIAtom*& aResult) const;
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass) const;
NS_IMETHOD GetContentStyleRule(nsIStyleRule*& aResult);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule*& aResult);
/** NRA ***
* Get a hint that tells the style system what to do when
* an attribute on this node changes.
*/
NS_IMETHOD GetStyleHintForAttributeChange(
const nsIAtom* aAttribute,
PRInt32 *aHint) const;
// nsIXMLContent (no longer implemented)
NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace);
NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const;
NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace);
@ -256,6 +275,8 @@ private:
static PRInt32 kNameSpaceID_RDF;
static PRInt32 kNameSpaceID_XUL;
static nsIAtom* kIdAtom;
static nsIAtom* kClassAtom;
static nsIAtom* kStyleAtom;
static nsIAtom* kContainerAtom;
nsIDocument* mDocument;
@ -267,10 +288,10 @@ private:
PRInt32 mNameSpaceID;
nsIAtom* mTag;
nsIEventListenerManager* mListenerManager;
nsVoidArray* mAttributes;
nsXULAttributes* mAttributes;
PRBool mContentsMustBeGenerated;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
};
@ -278,6 +299,8 @@ nsrefcnt RDFElementImpl::gRefCnt;
nsIRDFService* RDFElementImpl::gRDFService;
nsINameSpaceManager* RDFElementImpl::gNameSpaceManager;
nsIAtom* RDFElementImpl::kIdAtom;
nsIAtom* RDFElementImpl::kClassAtom;
nsIAtom* RDFElementImpl::kStyleAtom;
nsIAtom* RDFElementImpl::kContainerAtom;
PRInt32 RDFElementImpl::kNameSpaceID_RDF;
PRInt32 RDFElementImpl::kNameSpaceID_XUL;
@ -310,6 +333,8 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
NS_VERIFY(NS_SUCCEEDED(rv), "unable to get RDF service");
kIdAtom = NS_NewAtom("id");
kClassAtom = NS_NewAtom("class");
kStyleAtom = NS_NewAtom("style");
kContainerAtom = NS_NewAtom("container");
rv = nsRepository::CreateInstance(kNameSpaceManagerCID,
@ -328,15 +353,7 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
RDFElementImpl::~RDFElementImpl()
{
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
delete attr;
}
delete mAttributes;
}
delete mAttributes; // nsXULAttributes destructor takes care of the rest.
//NS_IF_RELEASE(mDocument); // not refcounted
//NS_IF_RELEASE(mParent) // not refcounted
@ -358,6 +375,8 @@ RDFElementImpl::~RDFElementImpl()
}
NS_IF_RELEASE(kIdAtom);
NS_IF_RELEASE(kClassAtom);
NS_IF_RELEASE(kStyleAtom);
NS_IF_RELEASE(kContainerAtom);
NS_IF_RELEASE(gNameSpaceManager);
}
@ -396,7 +415,7 @@ RDFElementImpl::QueryInterface(REFNSIID iid, void** result)
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIXMLContentIID) ||
if (iid.Equals(nsIStyledContent::GetIID()) ||
iid.Equals(kIContentIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIContent*, this);
@ -1121,11 +1140,12 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
nsresult rv;
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
nsCOMPtr<nsIRDFDocument> rdfDoc;
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Remove this element from the RDF resource-to-element map in
// the old document.
@ -1156,6 +1176,10 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
mDocument = aDocument; // not refcounted
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Add this element to the RDF resource-to-element map in the
// new document.
@ -1306,7 +1330,7 @@ RDFElementImpl::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildInserted(this, aIndex);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, aIndex);
}
@ -1338,7 +1362,7 @@ RDFElementImpl::ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildReplaced(this, aIndex, oldKid);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentReplaced(this, oldKid, aKid, aIndex);
}
@ -1371,7 +1395,7 @@ RDFElementImpl::AppendChildTo(nsIContent* aKid, PRBool aNotify)
// ranges don't need adjustment since new child is at end of list
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, mChildren->Count() - 1);
}
@ -1504,7 +1528,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
return NS_ERROR_NULL_POINTER;
if (nsnull == mAttributes) {
if ((mAttributes = new nsVoidArray()) == nsnull)
if ((mAttributes = new nsXULAttributes()) == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
@ -1529,15 +1553,35 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
}
}
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList(aValue);
}
// Check to see if the STYLE attribute is being set. If so, we need to create a new
// style rule based off the value of this attribute, and we need to let the document
// know about the StyleRule change.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, aValue);
// XXX Some kind of special document update might need to happen here.
}
// XXX need to check if they're changing an event handler: if so, then we need
// to unhook the old one.
nsGenericAttribute* attr;
nsXULAttribute* attr;
PRBool successful = PR_FALSE;
PRInt32 index = 0;
PRInt32 count = mAttributes->Count();
while (index < count) {
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
attr = mAttributes->ElementAt(index);
if ((aNameSpaceID == attr->mNameSpaceID) && (aName == attr->mName))
break;
index++;
@ -1547,7 +1591,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
attr->mValue = aValue;
}
else { // didn't find it
attr = new nsGenericAttribute(aNameSpaceID, aName, aValue);
attr = new nsXULAttribute(aNameSpaceID, aName, aValue);
if (! attr)
return NS_ERROR_OUT_OF_MEMORY;
@ -1609,24 +1653,11 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
// Set the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
if (contentNode) {
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->SetAttribute(listenerNameSpaceID, aName, aValue, aNotify);
else contentNode->SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
if (xulListener->mAttribute == aString) {
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->SetAttribute(aString, aValue);
}
}
@ -1721,7 +1752,7 @@ done:
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index);
const nsXULAttribute* attr = (const nsXULAttribute*)mAttributes->ElementAt(index);
if (((attr->mNameSpaceID == aNameSpaceID) ||
(aNameSpaceID == kNameSpaceID_Unknown) ||
(aNameSpaceID == kNameSpaceID_None)) &&
@ -1733,6 +1764,24 @@ done:
else {
rv = NS_CONTENT_ATTR_NO_VALUE;
}
if ((aNameSpaceID == kNameSpaceID_None) &&
(attr->mName == kIdAtom))
{
aResult = attr->mValue;
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-absolute URI into a relative ID attribute.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeRelative(url, aResult);
NS_RELEASE(docURL);
}
}
}
break;
}
}
@ -1748,13 +1797,30 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
return NS_ERROR_NULL_POINTER;
}
// Check to see if the CLASS attribute is being unset. If so, we need to delete our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList("");
}
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, "");
// XXX Some kind of special document update might need to happen here.
}
nsresult rv = NS_OK;
PRBool successful = PR_FALSE;
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(index);
if ((attr->mNameSpaceID == aNameSpaceID) && (attr->mName == aName)) {
mAttributes->RemoveElementAt(index);
delete attr;
@ -1772,22 +1838,12 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
if (xulListener->mAttribute == aString) {
// Unset the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->UnsetAttribute(listenerNameSpaceID, aName, aNotify);
else contentNode->UnsetAttribute(aNameSpaceID, aName, aNotify);
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->RemoveAttribute(aString);
}
}
@ -1857,7 +1913,7 @@ done:
#endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
if (nsnull != mAttributes) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(aIndex);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(aIndex);
if (nsnull != attr) {
aNameSpaceID = attr->mNameSpaceID;
aName = attr->mName;
@ -2181,7 +2237,20 @@ nsresult
RDFElementImpl::GetResource(nsIRDFResource** aResource)
{
nsAutoString uri;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_RDF, kIdAtom, uri)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_None, kIdAtom, uri)) {
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeAbsolute(url, uri);
NS_RELEASE(docURL);
}
}
return gRDFService->GetUnicodeResource(uri, aResource);
}
@ -2329,3 +2398,70 @@ RDFElementImpl::GetElementsByAttribute(nsIDOMNode* aNode,
return NS_OK;
}
// nsIStyledContent Implementation
NS_IMETHODIMP
RDFElementImpl::GetID(nsIAtom*& aResult) const
{
nsString value;
GetAttribute(kNameSpaceID_None, kIdAtom, value);
aResult = NS_NewAtom(value); // The NewAtom call does the AddRef.
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetClasses(nsVoidArray& aArray) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::HasClass(nsIAtom* aClass) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetContentStyleRule(nsIStyleRule*& aResult)
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetInlineStyleRule(nsIStyleRule*& aResult)
{
// Fetch the cached style rule from the attributes.
nsresult result = NS_ERROR_NULL_POINTER;
aResult = nsnull;
if (mAttributes != nsnull)
result = mAttributes->GetInlineStyleRule(aResult);
return result;
}
NS_IMETHODIMP
RDFElementImpl::GetStyleHintForAttributeChange(const nsIAtom* aAttribute, PRInt32 *aHint) const
{
*aHint = NS_STYLE_HINT_REFLOW;
if (mNameSpaceID == kNameSpaceID_XUL)
{
// We are a XUL tag and need to specify a style hint.
if (!mTag)
return NS_OK;
nsString tagName;
mTag->ToString(tagName);
nsString attributeName;
aAttribute->ToString(attributeName);
if (tagName == "progressmeter")
{
// Give hints for the values that should only involve a content change
if (attributeName == "value" || attributeName == "mode")
*aHint = NS_STYLE_HINT_CONTENT;
}
}
return NS_OK;
}

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

@ -94,6 +94,7 @@ static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID);
static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@ -117,6 +118,7 @@ static NS_DEFINE_IID(kIXULContentSinkIID, NS_IXULCONTENTSINK_IID);
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX
static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID);
@ -544,7 +546,7 @@ public:
nsresult Init(void);
nsresult StartLayout(void);
void SearchForNodeByID(const nsString& anID, nsIContent* anElement, nsIDOMNode** aReturn);
void SearchForNodeByID(const nsString& anID, nsIContent* anElement, nsIDOMElement** aReturn);
static nsresult
GetElementsByTagName(nsIDOMNode* aNode,
@ -818,6 +820,27 @@ XULDocumentImpl::StartDocumentLoad(nsIURL *aURL,
NS_ERROR("unable to add HTML style sheet");
return rv;
}
// Create an inline style sheet for inline content that contains a style
// attribute.
nsIHTMLCSSStyleSheet* inlineSheet;
if (NS_SUCCEEDED(rv = nsRepository::CreateInstance(kHTMLCSSStyleSheetCID,
nsnull,
kIHTMLCSSStyleSheetIID,
(void**) &inlineSheet))) {
if (NS_SUCCEEDED(rv = inlineSheet->Init(aURL, this))) {
mInlineStyleSheet = inlineSheet;
NS_ADDREF(mInlineStyleSheet);
AddStyleSheet(mInlineStyleSheet);
}
NS_RELEASE(inlineSheet);
}
if (NS_FAILED(rv)) {
NS_ERROR("unable to add inline style sheet");
return rv;
}
// Create a composite data source that'll tie together local and
// remote stores.
@ -1803,9 +1826,7 @@ XULDocumentImpl::SplitProperty(nsIRDFResource* aProperty,
if ((index = uri.RFind('#')) < 0) {
if ((index = uri.RFind('/')) < 0) {
*aNameSpaceID = kNameSpaceID_None;
nsAutoString name;
uri.Right(name, uri.Length()-1);
*aTag = NS_NewAtom(name);
*aTag = NS_NewAtom(uri);
return NS_OK;
}
}
@ -1962,21 +1983,16 @@ XULDocumentImpl::CreateContents(nsIContent* aElement)
nsString elementValue;
nsString attributeValue;
PRInt32 namespaceID = -1;
pChildContent->GetNameSpaceID(namespaceID);
pChildContent->GetAttribute(namespaceID,
pChildContent->GetAttribute(kNameSpaceID_None,
kElementAtom,
elementValue);
pChildContent->GetAttribute(namespaceID,
pChildContent->GetAttribute(kNameSpaceID_None,
kAttributeAtom,
attributeValue);
nsIDOMNode* pDOMNode = nsnull;
GetElementByID(elementValue, &pDOMNode);
nsIDOMElement* pDOMNode = nsnull;
GetElementById(elementValue, &pDOMNode);
if (!pDOMNode)
break;
@ -2194,7 +2210,7 @@ XULDocumentImpl::GetStyleSheets(nsIDOMStyleSheetCollection** aStyleSheets)
// nsIDOMXULDocument interface
NS_IMETHODIMP
XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
{
nsresult rv;
@ -2223,8 +2239,8 @@ XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
if (elements->Count() > 0) {
nsISupports* element = elements->ElementAt(0);
rv = element->QueryInterface(nsIDOMNode::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM node");
rv = element->QueryInterface(nsIDOMElement::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
NS_RELEASE(element);
return rv;
}
@ -2239,7 +2255,7 @@ XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
void
XULDocumentImpl::SearchForNodeByID(const nsString& anID,
nsIContent* anElement,
nsIDOMNode** aReturn)
nsIDOMElement** aReturn)
{
// See if we match.
PRInt32 namespaceID;
@ -2251,7 +2267,7 @@ XULDocumentImpl::SearchForNodeByID(const nsString& anID,
if (idValue == anID)
{
nsCOMPtr<nsIDOMNode> pDomNode( do_QueryInterface(anElement) );
nsCOMPtr<nsIDOMElement> pDomNode( do_QueryInterface(anElement) );
if (pDomNode)
{
*aReturn = pDomNode;

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

@ -26,7 +26,7 @@
#include "nsIScriptGlobalObject.h"
#include "nsIPtr.h"
#include "nsString.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMNodeList.h"
@ -34,11 +34,11 @@
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kINodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXULDocumentIID, NS_IDOMXULDOCUMENT_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
NS_DEF_PTR(nsIDOMNode);
NS_DEF_PTR(nsIDOMElement);
NS_DEF_PTR(nsIDOMXULDocument);
NS_DEF_PTR(nsIDOMNodeList);
@ -131,14 +131,14 @@ ResolveXULDocument(JSContext *cx, JSObject *obj, jsval id)
//
// Native method GetElementByID
// Native method GetElementById
//
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementByID(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNode* nativeRet;
nsIDOMElement* nativeRet;
nsAutoString b0;
*rval = JSVAL_NULL;
@ -152,14 +152,14 @@ XULDocumentGetElementByID(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
if (NS_OK != nativeThis->GetElementByID(b0, &nativeRet)) {
if (NS_OK != nativeThis->GetElementById(b0, &nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function getElementByID requires 1 parameters");
JS_ReportError(cx, "Function getElementById requires 1 parameters");
return JS_FALSE;
}
@ -239,7 +239,7 @@ static JSPropertySpec XULDocumentProperties[] =
//
static JSFunctionSpec XULDocumentMethods[] =
{
{"getElementByID", XULDocumentGetElementByID, 1},
{"getElementById", XULDocumentGetElementById, 1},
{"getElementsByAttribute", XULDocumentGetElementsByAttribute, 2},
{0}
};

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

@ -26,7 +26,7 @@
#include "nsIScriptGlobalObject.h"
#include "nsIPtr.h"
#include "nsString.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMNodeList.h"
@ -34,11 +34,11 @@
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kINodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXULDocumentIID, NS_IDOMXULDOCUMENT_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
NS_DEF_PTR(nsIDOMNode);
NS_DEF_PTR(nsIDOMElement);
NS_DEF_PTR(nsIDOMXULDocument);
NS_DEF_PTR(nsIDOMNodeList);
@ -131,14 +131,14 @@ ResolveXULDocument(JSContext *cx, JSObject *obj, jsval id)
//
// Native method GetElementByID
// Native method GetElementById
//
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementByID(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNode* nativeRet;
nsIDOMElement* nativeRet;
nsAutoString b0;
*rval = JSVAL_NULL;
@ -152,14 +152,14 @@ XULDocumentGetElementByID(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
if (NS_OK != nativeThis->GetElementByID(b0, &nativeRet)) {
if (NS_OK != nativeThis->GetElementById(b0, &nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function getElementByID requires 1 parameters");
JS_ReportError(cx, "Function getElementById requires 1 parameters");
return JS_FALSE;
}
@ -239,7 +239,7 @@ static JSPropertySpec XULDocumentProperties[] =
//
static JSFunctionSpec XULDocumentMethods[] =
{
{"getElementByID", XULDocumentGetElementByID, 1},
{"getElementById", XULDocumentGetElementById, 1},
{"getElementsByAttribute", XULDocumentGetElementsByAttribute, 2},
{0}
};

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

@ -39,7 +39,7 @@
#include "nsCOMPtr.h"
#include "nsDOMCID.h"
#include "nsDOMEvent.h"
#include "nsGenericAttribute.h"
#include "nsXULAttributes.h"
#include "nsHashtable.h"
#include "nsIAtom.h"
#include "nsIXMLContent.h"
@ -81,6 +81,10 @@
#include "nsIDOMKeyListener.h"
#include "nsIDOMFormListener.h"
#include "nsIScriptContextOwner.h"
#include "nsIStyledContent.h"
#include "nsIStyleRule.h"
#include "nsIURL.h"
#include "rdfutil.h"
// The XUL interfaces implemented by the RDF content node.
#include "nsIDOMXULElement.h"
@ -141,7 +145,7 @@ class RDFElementImpl : public nsIDOMXULElement,
public nsIDOMEventReceiver,
public nsIScriptObjectOwner,
public nsIJSScriptObject,
public nsIXMLContent
public nsIStyledContent
{
public:
RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag);
@ -161,7 +165,7 @@ public:
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIContent (from nsIRDFContent via nsIXMLContent)
// nsIContent (from nsIStyledContent)
// Any of the nsIContent methods that directly manipulate content
// (e.g., AppendChildTo()), are assumed to "know what they're
@ -204,7 +208,22 @@ public:
NS_IMETHOD RangeRemove(nsIDOMRange& aRange);
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const;
// nsIXMLContent (from nsIRDFContent)
NS_IMETHOD GetID(nsIAtom*& aResult) const;
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass) const;
NS_IMETHOD GetContentStyleRule(nsIStyleRule*& aResult);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule*& aResult);
/** NRA ***
* Get a hint that tells the style system what to do when
* an attribute on this node changes.
*/
NS_IMETHOD GetStyleHintForAttributeChange(
const nsIAtom* aAttribute,
PRInt32 *aHint) const;
// nsIXMLContent (no longer implemented)
NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace);
NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const;
NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace);
@ -256,6 +275,8 @@ private:
static PRInt32 kNameSpaceID_RDF;
static PRInt32 kNameSpaceID_XUL;
static nsIAtom* kIdAtom;
static nsIAtom* kClassAtom;
static nsIAtom* kStyleAtom;
static nsIAtom* kContainerAtom;
nsIDocument* mDocument;
@ -267,10 +288,10 @@ private:
PRInt32 mNameSpaceID;
nsIAtom* mTag;
nsIEventListenerManager* mListenerManager;
nsVoidArray* mAttributes;
nsXULAttributes* mAttributes;
PRBool mContentsMustBeGenerated;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
};
@ -278,6 +299,8 @@ nsrefcnt RDFElementImpl::gRefCnt;
nsIRDFService* RDFElementImpl::gRDFService;
nsINameSpaceManager* RDFElementImpl::gNameSpaceManager;
nsIAtom* RDFElementImpl::kIdAtom;
nsIAtom* RDFElementImpl::kClassAtom;
nsIAtom* RDFElementImpl::kStyleAtom;
nsIAtom* RDFElementImpl::kContainerAtom;
PRInt32 RDFElementImpl::kNameSpaceID_RDF;
PRInt32 RDFElementImpl::kNameSpaceID_XUL;
@ -310,6 +333,8 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
NS_VERIFY(NS_SUCCEEDED(rv), "unable to get RDF service");
kIdAtom = NS_NewAtom("id");
kClassAtom = NS_NewAtom("class");
kStyleAtom = NS_NewAtom("style");
kContainerAtom = NS_NewAtom("container");
rv = nsRepository::CreateInstance(kNameSpaceManagerCID,
@ -328,15 +353,7 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
RDFElementImpl::~RDFElementImpl()
{
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
delete attr;
}
delete mAttributes;
}
delete mAttributes; // nsXULAttributes destructor takes care of the rest.
//NS_IF_RELEASE(mDocument); // not refcounted
//NS_IF_RELEASE(mParent) // not refcounted
@ -358,6 +375,8 @@ RDFElementImpl::~RDFElementImpl()
}
NS_IF_RELEASE(kIdAtom);
NS_IF_RELEASE(kClassAtom);
NS_IF_RELEASE(kStyleAtom);
NS_IF_RELEASE(kContainerAtom);
NS_IF_RELEASE(gNameSpaceManager);
}
@ -396,7 +415,7 @@ RDFElementImpl::QueryInterface(REFNSIID iid, void** result)
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIXMLContentIID) ||
if (iid.Equals(nsIStyledContent::GetIID()) ||
iid.Equals(kIContentIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIContent*, this);
@ -1121,11 +1140,12 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
nsresult rv;
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
nsCOMPtr<nsIRDFDocument> rdfDoc;
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Remove this element from the RDF resource-to-element map in
// the old document.
@ -1156,6 +1176,10 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
mDocument = aDocument; // not refcounted
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Add this element to the RDF resource-to-element map in the
// new document.
@ -1306,7 +1330,7 @@ RDFElementImpl::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildInserted(this, aIndex);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, aIndex);
}
@ -1338,7 +1362,7 @@ RDFElementImpl::ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildReplaced(this, aIndex, oldKid);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentReplaced(this, oldKid, aKid, aIndex);
}
@ -1371,7 +1395,7 @@ RDFElementImpl::AppendChildTo(nsIContent* aKid, PRBool aNotify)
// ranges don't need adjustment since new child is at end of list
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, mChildren->Count() - 1);
}
@ -1504,7 +1528,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
return NS_ERROR_NULL_POINTER;
if (nsnull == mAttributes) {
if ((mAttributes = new nsVoidArray()) == nsnull)
if ((mAttributes = new nsXULAttributes()) == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
@ -1529,15 +1553,35 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
}
}
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList(aValue);
}
// Check to see if the STYLE attribute is being set. If so, we need to create a new
// style rule based off the value of this attribute, and we need to let the document
// know about the StyleRule change.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, aValue);
// XXX Some kind of special document update might need to happen here.
}
// XXX need to check if they're changing an event handler: if so, then we need
// to unhook the old one.
nsGenericAttribute* attr;
nsXULAttribute* attr;
PRBool successful = PR_FALSE;
PRInt32 index = 0;
PRInt32 count = mAttributes->Count();
while (index < count) {
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
attr = mAttributes->ElementAt(index);
if ((aNameSpaceID == attr->mNameSpaceID) && (aName == attr->mName))
break;
index++;
@ -1547,7 +1591,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
attr->mValue = aValue;
}
else { // didn't find it
attr = new nsGenericAttribute(aNameSpaceID, aName, aValue);
attr = new nsXULAttribute(aNameSpaceID, aName, aValue);
if (! attr)
return NS_ERROR_OUT_OF_MEMORY;
@ -1609,24 +1653,11 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
// Set the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
if (contentNode) {
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->SetAttribute(listenerNameSpaceID, aName, aValue, aNotify);
else contentNode->SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
if (xulListener->mAttribute == aString) {
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->SetAttribute(aString, aValue);
}
}
@ -1721,7 +1752,7 @@ done:
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index);
const nsXULAttribute* attr = (const nsXULAttribute*)mAttributes->ElementAt(index);
if (((attr->mNameSpaceID == aNameSpaceID) ||
(aNameSpaceID == kNameSpaceID_Unknown) ||
(aNameSpaceID == kNameSpaceID_None)) &&
@ -1733,6 +1764,24 @@ done:
else {
rv = NS_CONTENT_ATTR_NO_VALUE;
}
if ((aNameSpaceID == kNameSpaceID_None) &&
(attr->mName == kIdAtom))
{
aResult = attr->mValue;
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-absolute URI into a relative ID attribute.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeRelative(url, aResult);
NS_RELEASE(docURL);
}
}
}
break;
}
}
@ -1748,13 +1797,30 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
return NS_ERROR_NULL_POINTER;
}
// Check to see if the CLASS attribute is being unset. If so, we need to delete our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList("");
}
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, "");
// XXX Some kind of special document update might need to happen here.
}
nsresult rv = NS_OK;
PRBool successful = PR_FALSE;
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(index);
if ((attr->mNameSpaceID == aNameSpaceID) && (attr->mName == aName)) {
mAttributes->RemoveElementAt(index);
delete attr;
@ -1772,22 +1838,12 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
if (xulListener->mAttribute == aString) {
// Unset the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->UnsetAttribute(listenerNameSpaceID, aName, aNotify);
else contentNode->UnsetAttribute(aNameSpaceID, aName, aNotify);
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->RemoveAttribute(aString);
}
}
@ -1857,7 +1913,7 @@ done:
#endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
if (nsnull != mAttributes) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(aIndex);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(aIndex);
if (nsnull != attr) {
aNameSpaceID = attr->mNameSpaceID;
aName = attr->mName;
@ -2181,7 +2237,20 @@ nsresult
RDFElementImpl::GetResource(nsIRDFResource** aResource)
{
nsAutoString uri;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_RDF, kIdAtom, uri)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_None, kIdAtom, uri)) {
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeAbsolute(url, uri);
NS_RELEASE(docURL);
}
}
return gRDFService->GetUnicodeResource(uri, aResource);
}
@ -2329,3 +2398,70 @@ RDFElementImpl::GetElementsByAttribute(nsIDOMNode* aNode,
return NS_OK;
}
// nsIStyledContent Implementation
NS_IMETHODIMP
RDFElementImpl::GetID(nsIAtom*& aResult) const
{
nsString value;
GetAttribute(kNameSpaceID_None, kIdAtom, value);
aResult = NS_NewAtom(value); // The NewAtom call does the AddRef.
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetClasses(nsVoidArray& aArray) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::HasClass(nsIAtom* aClass) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetContentStyleRule(nsIStyleRule*& aResult)
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetInlineStyleRule(nsIStyleRule*& aResult)
{
// Fetch the cached style rule from the attributes.
nsresult result = NS_ERROR_NULL_POINTER;
aResult = nsnull;
if (mAttributes != nsnull)
result = mAttributes->GetInlineStyleRule(aResult);
return result;
}
NS_IMETHODIMP
RDFElementImpl::GetStyleHintForAttributeChange(const nsIAtom* aAttribute, PRInt32 *aHint) const
{
*aHint = NS_STYLE_HINT_REFLOW;
if (mNameSpaceID == kNameSpaceID_XUL)
{
// We are a XUL tag and need to specify a style hint.
if (!mTag)
return NS_OK;
nsString tagName;
mTag->ToString(tagName);
nsString attributeName;
aAttribute->ToString(attributeName);
if (tagName == "progressmeter")
{
// Give hints for the values that should only involve a content change
if (attributeName == "value" || attributeName == "mode")
*aHint = NS_STYLE_HINT_CONTENT;
}
}
return NS_OK;
}

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

@ -416,7 +416,7 @@ RDFHTMLBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
if (NS_FAILED(rv = aResource->GetValue(&uri)))
return rv;
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_RDF, kIdAtom, uri, PR_FALSE)))
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_None, kIdAtom, uri, PR_FALSE)))
return rv;
*aResult = result;

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

@ -71,6 +71,7 @@
#include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsIURL.h"
#include "nsLayoutCID.h"
#include "nsRDFCID.h"
#include "nsRDFContentUtils.h"
@ -257,6 +258,9 @@ public:
nsresult
CloseTreeItem(nsIContent* aElement);
nsresult
GetElementResource(nsIContent* aElement, nsIRDFResource** aResult);
};
////////////////////////////////////////////////////////////////////////
@ -688,23 +692,6 @@ RDFTreeBuilderImpl::CreateContents(nsIContent* aElement)
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrValue.EqualsIgnoreCase("true")))
return NS_OK;
// Get the treeitem's resource so that we can generate cell
// values. We could QI for the nsIRDFResource here, but doing this
// via the nsIContent interface allows us to support generic nodes
// that might get added in by DOM calls.
nsAutoString uri;
if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_RDF,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no RDF:ID");
return NS_ERROR_UNEXPECTED;
}
// Now mark the element's contents as being generated so that
// any re-entrant calls don't trigger an infinite recursion.
if (NS_FAILED(rv = aElement->SetAttribute(kNameSpaceID_None,
@ -715,17 +702,21 @@ RDFTreeBuilderImpl::CreateContents(nsIContent* aElement)
return rv;
}
// Get the treeitem's resource so that we can generate cell
// values. We could QI for the nsIRDFResource here, but doing this
// via the nsIContent interface allows us to support generic nodes
// that might get added in by DOM calls.
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = GetElementResource(aElement, getter_AddRefs(resource)))) {
NS_ERROR("unable to get element resource");
return rv;
}
// XXX Eventually, we may want to factor this into one method that
// handles RDF containers (RDF:Bag, et al.) and another that
// handles multi-attributes. For performance...
// Create a cursor that'll enumerate all of the outbound arcs
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, getter_AddRefs(resource)))) {
NS_ERROR("unable to create resource");
return rv;
}
nsCOMPtr<nsIRDFArcsOutCursor> properties;
if (NS_FAILED(rv = mDB->ArcLabelsOut(resource, getter_AddRefs(properties))))
return rv;
@ -1250,10 +1241,6 @@ RDFTreeBuilderImpl::FindChildByTagAndResource(nsIContent* aElement,
{
nsresult rv;
const char* resourceURI;
if (NS_FAILED(rv = aResource->GetValue(&resourceURI)))
return rv;
PRInt32 count;
if (NS_FAILED(rv = aElement->ChildCount(count)))
return rv;
@ -1281,17 +1268,13 @@ RDFTreeBuilderImpl::FindChildByTagAndResource(nsIContent* aElement,
// Now get the resource ID from the RDF:ID attribute. We do it
// via the content model, because you're never sure who
// might've added this stuff in...
nsAutoString uri;
if (NS_FAILED(rv = kid->GetAttribute(kNameSpaceID_RDF, kIdAtom, uri))) {
NS_ERROR("severe error retrieving attribute");
return rv; // XXX fatal
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = GetElementResource(kid, getter_AddRefs(resource)))) {
NS_ERROR("severe error retrieving resource");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE)
continue;
if (! uri.Equals(resourceURI))
if (resource != aResource)
continue; // not the resource we want
// Fount it!
@ -1618,21 +1601,11 @@ RDFTreeBuilderImpl::CreateTreeItemCells(nsIContent* aTreeItemElement)
// values. We could QI for the nsIRDFResource here, but doing this
// via the nsIContent interface allows us to support generic nodes
// that might get added in by DOM calls.
nsAutoString treeItemResourceURI;
if (NS_FAILED(rv = aTreeItemElement->GetAttribute(kNameSpaceID_RDF,
kIdAtom,
treeItemResourceURI)))
return rv;
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("xul:treeitem has no RDF:ID");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRDFResource> treeItemResource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(treeItemResourceURI,
getter_AddRefs(treeItemResource))))
if (NS_FAILED(rv = GetElementResource(aTreeItemElement, getter_AddRefs(treeItemResource)))) {
NS_ERROR("unable to get tree item resource");
return rv;
}
PRInt32 count;
if (NS_FAILED(rv = mRoot->ChildCount(count))) {
@ -1947,7 +1920,7 @@ RDFTreeBuilderImpl::IsTreeProperty(nsIContent* aElement, nsIRDFResource* aProper
if (nameSpaceID != kNameSpaceID_HTML) {
// Is this the "rdf:containment? property?
if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_RDF, kContainmentAtom, uri))) {
if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_None, kContainmentAtom, uri))) {
NS_ERROR("unable to get attribute value");
return PR_FALSE;
}
@ -2060,26 +2033,7 @@ RDFTreeBuilderImpl::GetDOMNodeResource(nsIDOMNode* aNode, nsIRDFResource** aReso
return rv;
}
nsAutoString uri;
if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_RDF,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no RDF:ID");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, aResource))) {
NS_ERROR("unable to create resource");
return rv;
}
return NS_OK;
return GetElementResource(element, aResource);
}
nsresult
@ -2098,7 +2052,7 @@ RDFTreeBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
if (NS_FAILED(rv = aResource->GetValue(&uri)))
return rv;
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_RDF, kIdAtom, uri, PR_FALSE)))
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_None, kIdAtom, uri, PR_FALSE)))
return rv;
*aResult = result;
@ -2195,3 +2149,49 @@ RDFTreeBuilderImpl::CloseTreeItem(nsIContent* aElement)
return NS_OK;
}
nsresult
RDFTreeBuilderImpl::GetElementResource(nsIContent* aElement, nsIRDFResource** aResult)
{
// Perform a reverse mapping from an element in the content model
// to an RDF resource.
nsresult rv;
nsAutoString uri;
if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_None,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no ID");
return NS_ERROR_UNEXPECTED;
}
// Since the element will store its ID attribute as a document-relative value,
// we may need to qualify it first...
NS_ASSERTION(mDocument != nsnull, "builder has no document -- can't fully qualify URI");
if (nsnull != mDocument) {
nsCOMPtr<nsIDocument> doc( do_QueryInterface(mDocument) );
NS_ASSERTION(doc, "doesn't support nsIDocument");
if (doc) {
nsIURL* docURL = nsnull;
doc->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeAbsolute(url, uri);
NS_RELEASE(docURL);
}
}
}
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, aResult))) {
NS_ERROR("unable to create resource");
return rv;
}
return NS_OK;
}

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

@ -53,6 +53,7 @@
#include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsIURL.h"
#include "nsLayoutCID.h"
#include "nsRDFCID.h"
#include "nsRDFContentUtils.h"
@ -206,6 +207,9 @@ public:
GetResource(PRInt32 aNameSpaceID,
nsIAtom* aNameAtom,
nsIRDFResource** aResource);
nsresult
GetElementResource(nsIContent* aElement, nsIRDFResource** aResult);
};
////////////////////////////////////////////////////////////////////////
@ -279,7 +283,6 @@ RDFXULBuilderImpl::RDFXULBuilderImpl(void)
kDataSourcesAtom = NS_NewAtom("datasources");
kTreeAtom = NS_NewAtom("tree");
if (NS_SUCCEEDED(rv = nsServiceManager::GetService(kRDFServiceCID,
kIRDFServiceIID,
(nsISupports**) &gRDFService))) {
@ -485,22 +488,9 @@ RDFXULBuilderImpl::CreateContents(nsIContent* aElement)
// values. We could QI for the nsIRDFResource here, but doing this
// via the nsIContent interface allows us to support generic nodes
// that might get added in by DOM calls.
nsAutoString uri;
if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_RDF,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no RDF:ID");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, getter_AddRefs(resource)))) {
NS_ERROR("unable to create resource");
if (NS_FAILED(rv = GetElementResource(aElement, getter_AddRefs(resource)))) {
NS_ERROR("unable to get element resource");
return rv;
}
@ -1015,6 +1005,13 @@ RDFXULBuilderImpl::OnSetAttribute(nsIDOMElement* aElement, const nsString& aName
return NS_OK;
}
// Get the nsIContent interface, it's a bit more utilitarian
nsCOMPtr<nsIContent> element( do_QueryInterface(aElement) );
if (! element) {
NS_ERROR("element doesn't support nsIContent");
return NS_ERROR_UNEXPECTED;
}
// Make sure it's a XUL element; otherwise, we really don't have
// any business with the attribute.
PRBool isXULElement;
@ -1215,10 +1212,6 @@ RDFXULBuilderImpl::RemoveChild(nsIContent* aElement, nsIRDFNode* aValue)
if (NS_SUCCEEDED(rv = aValue->QueryInterface(kIRDFResourceIID,
(void**) getter_AddRefs(resource)))) {
// If it's a resource, then look for a child container to remove
const char* resourceURI;
resource->GetValue(&resourceURI);
PRInt32 count;
aElement->ChildCount(count);
while (--count >= 0) {
@ -1229,12 +1222,10 @@ RDFXULBuilderImpl::RemoveChild(nsIContent* aElement, nsIRDFNode* aValue)
if (IsHTMLElement(child))
continue;
nsAutoString uri;
rv = child->GetAttribute(kNameSpaceID_RDF, kIdAtom, uri);
if (rv != NS_CONTENT_ATTR_HAS_VALUE)
continue;
nsCOMPtr<nsIRDFResource> elementResource;
rv = GetElementResource(child, getter_AddRefs(elementResource));
if (! uri.Equals(resourceURI))
if (resource != elementResource)
continue;
// okay, found it. now blow it away...
@ -1752,26 +1743,7 @@ RDFXULBuilderImpl::GetDOMNodeResource(nsIDOMNode* aNode, nsIRDFResource** aResou
return rv;
}
nsAutoString uri;
if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_RDF,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no RDF:ID");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRDFResource> resource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, aResource))) {
NS_ERROR("unable to create resource");
return rv;
}
return NS_OK;
return GetElementResource(element, aResource);
}
nsresult
@ -1790,7 +1762,7 @@ RDFXULBuilderImpl::CreateResourceElement(PRInt32 aNameSpaceID,
if (NS_FAILED(rv = aResource->GetValue(&uri)))
return rv;
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_RDF, kIdAtom, uri, PR_FALSE)))
if (NS_FAILED(rv = result->SetAttribute(kNameSpaceID_None, kIdAtom, uri, PR_FALSE)))
return rv;
*aResult = result;
@ -1828,3 +1800,49 @@ RDFXULBuilderImpl::GetResource(PRInt32 aNameSpaceID,
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
return rv;
}
nsresult
RDFXULBuilderImpl::GetElementResource(nsIContent* aElement, nsIRDFResource** aResult)
{
// Perform a reverse mapping from an element in the content model
// to an RDF resource.
nsresult rv;
nsAutoString uri;
if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_None,
kIdAtom,
uri))) {
NS_ERROR("severe error retrieving attribute");
return rv;
}
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
NS_ERROR("tree element has no ID");
return NS_ERROR_UNEXPECTED;
}
// Since the element will store its ID attribute as a document-relative value,
// we may need to qualify it first...
NS_ASSERTION(mDocument != nsnull, "builder has no document -- can't fully qualify URI");
if (nsnull != mDocument) {
nsCOMPtr<nsIDocument> doc( do_QueryInterface(mDocument) );
NS_ASSERTION(doc, "doesn't support nsIDocument");
if (doc) {
nsIURL* docURL = nsnull;
doc->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeAbsolute(url, uri);
NS_RELEASE(docURL);
}
}
}
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, aResult))) {
NS_ERROR("unable to create resource");
return rv;
}
return NS_OK;
}

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

@ -94,6 +94,7 @@ static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID);
static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@ -117,6 +118,7 @@ static NS_DEFINE_IID(kIXULContentSinkIID, NS_IXULCONTENTSINK_IID);
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX
static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID);
@ -544,7 +546,7 @@ public:
nsresult Init(void);
nsresult StartLayout(void);
void SearchForNodeByID(const nsString& anID, nsIContent* anElement, nsIDOMNode** aReturn);
void SearchForNodeByID(const nsString& anID, nsIContent* anElement, nsIDOMElement** aReturn);
static nsresult
GetElementsByTagName(nsIDOMNode* aNode,
@ -818,6 +820,27 @@ XULDocumentImpl::StartDocumentLoad(nsIURL *aURL,
NS_ERROR("unable to add HTML style sheet");
return rv;
}
// Create an inline style sheet for inline content that contains a style
// attribute.
nsIHTMLCSSStyleSheet* inlineSheet;
if (NS_SUCCEEDED(rv = nsRepository::CreateInstance(kHTMLCSSStyleSheetCID,
nsnull,
kIHTMLCSSStyleSheetIID,
(void**) &inlineSheet))) {
if (NS_SUCCEEDED(rv = inlineSheet->Init(aURL, this))) {
mInlineStyleSheet = inlineSheet;
NS_ADDREF(mInlineStyleSheet);
AddStyleSheet(mInlineStyleSheet);
}
NS_RELEASE(inlineSheet);
}
if (NS_FAILED(rv)) {
NS_ERROR("unable to add inline style sheet");
return rv;
}
// Create a composite data source that'll tie together local and
// remote stores.
@ -1803,9 +1826,7 @@ XULDocumentImpl::SplitProperty(nsIRDFResource* aProperty,
if ((index = uri.RFind('#')) < 0) {
if ((index = uri.RFind('/')) < 0) {
*aNameSpaceID = kNameSpaceID_None;
nsAutoString name;
uri.Right(name, uri.Length()-1);
*aTag = NS_NewAtom(name);
*aTag = NS_NewAtom(uri);
return NS_OK;
}
}
@ -1962,21 +1983,16 @@ XULDocumentImpl::CreateContents(nsIContent* aElement)
nsString elementValue;
nsString attributeValue;
PRInt32 namespaceID = -1;
pChildContent->GetNameSpaceID(namespaceID);
pChildContent->GetAttribute(namespaceID,
pChildContent->GetAttribute(kNameSpaceID_None,
kElementAtom,
elementValue);
pChildContent->GetAttribute(namespaceID,
pChildContent->GetAttribute(kNameSpaceID_None,
kAttributeAtom,
attributeValue);
nsIDOMNode* pDOMNode = nsnull;
GetElementByID(elementValue, &pDOMNode);
nsIDOMElement* pDOMNode = nsnull;
GetElementById(elementValue, &pDOMNode);
if (!pDOMNode)
break;
@ -2194,7 +2210,7 @@ XULDocumentImpl::GetStyleSheets(nsIDOMStyleSheetCollection** aStyleSheets)
// nsIDOMXULDocument interface
NS_IMETHODIMP
XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
XULDocumentImpl::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
{
nsresult rv;
@ -2223,8 +2239,8 @@ XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
if (elements->Count() > 0) {
nsISupports* element = elements->ElementAt(0);
rv = element->QueryInterface(nsIDOMNode::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM node");
rv = element->QueryInterface(nsIDOMElement::GetIID(), (void**) aReturn);
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
NS_RELEASE(element);
return rv;
}
@ -2239,7 +2255,7 @@ XULDocumentImpl::GetElementByID(const nsString& aId, nsIDOMNode** aReturn)
void
XULDocumentImpl::SearchForNodeByID(const nsString& anID,
nsIContent* anElement,
nsIDOMNode** aReturn)
nsIDOMElement** aReturn)
{
// See if we match.
PRInt32 namespaceID;
@ -2251,7 +2267,7 @@ XULDocumentImpl::SearchForNodeByID(const nsString& anID,
if (idValue == anID)
{
nsCOMPtr<nsIDOMNode> pDomNode( do_QueryInterface(anElement) );
nsCOMPtr<nsIDOMElement> pDomNode( do_QueryInterface(anElement) );
if (pDomNode)
{
*aReturn = pDomNode;

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

@ -39,7 +39,7 @@
#include "nsCOMPtr.h"
#include "nsDOMCID.h"
#include "nsDOMEvent.h"
#include "nsGenericAttribute.h"
#include "nsXULAttributes.h"
#include "nsHashtable.h"
#include "nsIAtom.h"
#include "nsIXMLContent.h"
@ -81,6 +81,10 @@
#include "nsIDOMKeyListener.h"
#include "nsIDOMFormListener.h"
#include "nsIScriptContextOwner.h"
#include "nsIStyledContent.h"
#include "nsIStyleRule.h"
#include "nsIURL.h"
#include "rdfutil.h"
// The XUL interfaces implemented by the RDF content node.
#include "nsIDOMXULElement.h"
@ -141,7 +145,7 @@ class RDFElementImpl : public nsIDOMXULElement,
public nsIDOMEventReceiver,
public nsIScriptObjectOwner,
public nsIJSScriptObject,
public nsIXMLContent
public nsIStyledContent
{
public:
RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag);
@ -161,7 +165,7 @@ public:
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIContent (from nsIRDFContent via nsIXMLContent)
// nsIContent (from nsIStyledContent)
// Any of the nsIContent methods that directly manipulate content
// (e.g., AppendChildTo()), are assumed to "know what they're
@ -204,7 +208,22 @@ public:
NS_IMETHOD RangeRemove(nsIDOMRange& aRange);
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const;
// nsIXMLContent (from nsIRDFContent)
NS_IMETHOD GetID(nsIAtom*& aResult) const;
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass) const;
NS_IMETHOD GetContentStyleRule(nsIStyleRule*& aResult);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule*& aResult);
/** NRA ***
* Get a hint that tells the style system what to do when
* an attribute on this node changes.
*/
NS_IMETHOD GetStyleHintForAttributeChange(
const nsIAtom* aAttribute,
PRInt32 *aHint) const;
// nsIXMLContent (no longer implemented)
NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace);
NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const;
NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace);
@ -256,6 +275,8 @@ private:
static PRInt32 kNameSpaceID_RDF;
static PRInt32 kNameSpaceID_XUL;
static nsIAtom* kIdAtom;
static nsIAtom* kClassAtom;
static nsIAtom* kStyleAtom;
static nsIAtom* kContainerAtom;
nsIDocument* mDocument;
@ -267,10 +288,10 @@ private:
PRInt32 mNameSpaceID;
nsIAtom* mTag;
nsIEventListenerManager* mListenerManager;
nsVoidArray* mAttributes;
nsXULAttributes* mAttributes;
PRBool mContentsMustBeGenerated;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
nsIDOMNode* mBroadcaster;
nsVoidArray mBroadcastListeners;
};
@ -278,6 +299,8 @@ nsrefcnt RDFElementImpl::gRefCnt;
nsIRDFService* RDFElementImpl::gRDFService;
nsINameSpaceManager* RDFElementImpl::gNameSpaceManager;
nsIAtom* RDFElementImpl::kIdAtom;
nsIAtom* RDFElementImpl::kClassAtom;
nsIAtom* RDFElementImpl::kStyleAtom;
nsIAtom* RDFElementImpl::kContainerAtom;
PRInt32 RDFElementImpl::kNameSpaceID_RDF;
PRInt32 RDFElementImpl::kNameSpaceID_XUL;
@ -310,6 +333,8 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
NS_VERIFY(NS_SUCCEEDED(rv), "unable to get RDF service");
kIdAtom = NS_NewAtom("id");
kClassAtom = NS_NewAtom("class");
kStyleAtom = NS_NewAtom("style");
kContainerAtom = NS_NewAtom("container");
rv = nsRepository::CreateInstance(kNameSpaceManagerCID,
@ -328,15 +353,7 @@ RDFElementImpl::RDFElementImpl(PRInt32 aNameSpaceID, nsIAtom* aTag)
RDFElementImpl::~RDFElementImpl()
{
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
delete attr;
}
delete mAttributes;
}
delete mAttributes; // nsXULAttributes destructor takes care of the rest.
//NS_IF_RELEASE(mDocument); // not refcounted
//NS_IF_RELEASE(mParent) // not refcounted
@ -358,6 +375,8 @@ RDFElementImpl::~RDFElementImpl()
}
NS_IF_RELEASE(kIdAtom);
NS_IF_RELEASE(kClassAtom);
NS_IF_RELEASE(kStyleAtom);
NS_IF_RELEASE(kContainerAtom);
NS_IF_RELEASE(gNameSpaceManager);
}
@ -396,7 +415,7 @@ RDFElementImpl::QueryInterface(REFNSIID iid, void** result)
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIXMLContentIID) ||
if (iid.Equals(nsIStyledContent::GetIID()) ||
iid.Equals(kIContentIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIContent*, this);
@ -1121,11 +1140,12 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
nsresult rv;
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
nsCOMPtr<nsIRDFDocument> rdfDoc;
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Remove this element from the RDF resource-to-element map in
// the old document.
@ -1156,6 +1176,10 @@ RDFElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep)
mDocument = aDocument; // not refcounted
if (mDocument) {
// Need to do a GetResource() here, because changing the document
// may actually change the element's URI.
nsCOMPtr<nsIRDFResource> resource;
GetResource(getter_AddRefs(resource));
// Add this element to the RDF resource-to-element map in the
// new document.
@ -1306,7 +1330,7 @@ RDFElementImpl::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildInserted(this, aIndex);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, aIndex);
}
@ -1338,7 +1362,7 @@ RDFElementImpl::ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
//nsRange::OwnerChildReplaced(this, aIndex, oldKid);
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentReplaced(this, oldKid, aKid, aIndex);
}
@ -1371,7 +1395,7 @@ RDFElementImpl::AppendChildTo(nsIContent* aKid, PRBool aNotify)
// ranges don't need adjustment since new child is at end of list
nsIDocument* doc = mDocument;
if (nsnull != doc) {
aKid->SetDocument(doc, PR_FALSE);
aKid->SetDocument(doc, PR_TRUE);
if (aNotify) {
doc->ContentInserted(this, aKid, mChildren->Count() - 1);
}
@ -1504,7 +1528,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
return NS_ERROR_NULL_POINTER;
if (nsnull == mAttributes) {
if ((mAttributes = new nsVoidArray()) == nsnull)
if ((mAttributes = new nsXULAttributes()) == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
@ -1529,15 +1553,35 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
}
}
// Check to see if the CLASS attribute is being set. If so, we need to rebuild our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList(aValue);
}
// Check to see if the STYLE attribute is being set. If so, we need to create a new
// style rule based off the value of this attribute, and we need to let the document
// know about the StyleRule change.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, aValue);
// XXX Some kind of special document update might need to happen here.
}
// XXX need to check if they're changing an event handler: if so, then we need
// to unhook the old one.
nsGenericAttribute* attr;
nsXULAttribute* attr;
PRBool successful = PR_FALSE;
PRInt32 index = 0;
PRInt32 count = mAttributes->Count();
while (index < count) {
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
attr = mAttributes->ElementAt(index);
if ((aNameSpaceID == attr->mNameSpaceID) && (aName == attr->mName))
break;
index++;
@ -1547,7 +1591,7 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
attr->mValue = aValue;
}
else { // didn't find it
attr = new nsGenericAttribute(aNameSpaceID, aName, aValue);
attr = new nsXULAttribute(aNameSpaceID, aName, aValue);
if (! attr)
return NS_ERROR_OUT_OF_MEMORY;
@ -1609,24 +1653,11 @@ RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
// Set the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
if (contentNode) {
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->SetAttribute(listenerNameSpaceID, aName, aValue, aNotify);
else contentNode->SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
if (xulListener->mAttribute == aString) {
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->SetAttribute(aString, aValue);
}
}
@ -1721,7 +1752,7 @@ done:
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
const nsGenericAttribute* attr = (const nsGenericAttribute*)mAttributes->ElementAt(index);
const nsXULAttribute* attr = (const nsXULAttribute*)mAttributes->ElementAt(index);
if (((attr->mNameSpaceID == aNameSpaceID) ||
(aNameSpaceID == kNameSpaceID_Unknown) ||
(aNameSpaceID == kNameSpaceID_None)) &&
@ -1733,6 +1764,24 @@ done:
else {
rv = NS_CONTENT_ATTR_NO_VALUE;
}
if ((aNameSpaceID == kNameSpaceID_None) &&
(attr->mName == kIdAtom))
{
aResult = attr->mValue;
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-absolute URI into a relative ID attribute.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeRelative(url, aResult);
NS_RELEASE(docURL);
}
}
}
break;
}
}
@ -1748,13 +1797,30 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
return NS_ERROR_NULL_POINTER;
}
// Check to see if the CLASS attribute is being unset. If so, we need to delete our
// class list.
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {
mAttributes->UpdateClassList("");
}
if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {
nsIURL* docURL = nsnull;
if (nsnull != mDocument) {
mDocument->GetBaseURL(docURL);
}
mAttributes->UpdateStyleRule(docURL, "");
// XXX Some kind of special document update might need to happen here.
}
nsresult rv = NS_OK;
PRBool successful = PR_FALSE;
if (nsnull != mAttributes) {
PRInt32 count = mAttributes->Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(index);
if ((attr->mNameSpaceID == aNameSpaceID) && (attr->mName == aName)) {
mAttributes->RemoveElementAt(index);
delete attr;
@ -1772,22 +1838,12 @@ RDFElementImpl::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNot
XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners[i];
nsString aString;
aName->ToString(aString);
if (xulListener->mAttribute.EqualsIgnoreCase(aString)) {
if (xulListener->mAttribute == aString) {
// Unset the attribute in the broadcast listener.
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(xulListener->mListener));
// If the namespace of the attribute and the namespace of the
// tag are identical, then use the namespace of the listener's tag.
// This allows you to do things like set xul:disabled on a xul tag
// and have an html tag be annotated with an html:disabled instead.
PRInt32 thisNameSpaceID, listenerNameSpaceID;
GetNameSpaceID(thisNameSpaceID);
contentNode->GetNameSpaceID(listenerNameSpaceID);
if (aNameSpaceID == thisNameSpaceID)
contentNode->UnsetAttribute(listenerNameSpaceID, aName, aNotify);
else contentNode->UnsetAttribute(aNameSpaceID, aName, aNotify);
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(xulListener->mListener);
if (element)
element->RemoveAttribute(aString);
}
}
@ -1857,7 +1913,7 @@ done:
#endif // defined(CREATE_PROPERTIES_AS_ATTRIBUTES)
if (nsnull != mAttributes) {
nsGenericAttribute* attr = (nsGenericAttribute*)mAttributes->ElementAt(aIndex);
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(aIndex);
if (nsnull != attr) {
aNameSpaceID = attr->mNameSpaceID;
aName = attr->mName;
@ -2181,7 +2237,20 @@ nsresult
RDFElementImpl::GetResource(nsIRDFResource** aResource)
{
nsAutoString uri;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_RDF, kIdAtom, uri)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(kNameSpaceID_None, kIdAtom, uri)) {
// RDF will treat all document IDs as absolute URIs, so we'll need convert
// a possibly-relative ID attribute into a fully-qualified (that is, with
// the current document's URL) URI.
if (nsnull != mDocument) {
nsIURL* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (docURL) {
const char* url;
docURL->GetSpec(&url);
rdf_PossiblyMakeAbsolute(url, uri);
NS_RELEASE(docURL);
}
}
return gRDFService->GetUnicodeResource(uri, aResource);
}
@ -2329,3 +2398,70 @@ RDFElementImpl::GetElementsByAttribute(nsIDOMNode* aNode,
return NS_OK;
}
// nsIStyledContent Implementation
NS_IMETHODIMP
RDFElementImpl::GetID(nsIAtom*& aResult) const
{
nsString value;
GetAttribute(kNameSpaceID_None, kIdAtom, value);
aResult = NS_NewAtom(value); // The NewAtom call does the AddRef.
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetClasses(nsVoidArray& aArray) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::HasClass(nsIAtom* aClass) const
{
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetContentStyleRule(nsIStyleRule*& aResult)
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
RDFElementImpl::GetInlineStyleRule(nsIStyleRule*& aResult)
{
// Fetch the cached style rule from the attributes.
nsresult result = NS_ERROR_NULL_POINTER;
aResult = nsnull;
if (mAttributes != nsnull)
result = mAttributes->GetInlineStyleRule(aResult);
return result;
}
NS_IMETHODIMP
RDFElementImpl::GetStyleHintForAttributeChange(const nsIAtom* aAttribute, PRInt32 *aHint) const
{
*aHint = NS_STYLE_HINT_REFLOW;
if (mNameSpaceID == kNameSpaceID_XUL)
{
// We are a XUL tag and need to specify a style hint.
if (!mTag)
return NS_OK;
nsString tagName;
mTag->ToString(tagName);
nsString attributeName;
aAttribute->ToString(attributeName);
if (tagName == "progressmeter")
{
// Give hints for the values that should only involve a content change
if (attributeName == "value" || attributeName == "mode")
*aHint = NS_STYLE_HINT_CONTENT;
}
}
return NS_OK;
}