diff --git a/mozilla/layout/html/content/src/nsHTMLGenericContent.cpp b/mozilla/layout/html/content/src/nsHTMLGenericContent.cpp
new file mode 100644
index 00000000000..1d934ec2a9b
--- /dev/null
+++ b/mozilla/layout/html/content/src/nsHTMLGenericContent.cpp
@@ -0,0 +1,1910 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are Copyright (C) 1998
+ * Netscape Communications Corporation. All Rights Reserved.
+ */
+#include "nsHTMLGenericContent.h"
+
+#include "nsIAtom.h"
+#include "nsIContentDelegate.h"
+#include "nsICSSParser.h"
+#include "nsIDocument.h"
+#include "nsIDOMAttribute.h"
+#include "nsIDOMEventReceiver.h"
+#include "nsIDOMNamedNodeMap.h"
+#include "nsIEventListenerManager.h"
+#include "nsIHTMLAttributes.h"
+#include "nsIHTMLContent.h"
+#include "nsIScriptContextOwner.h"
+#include "nsIScriptGlobalObject.h"
+#include "nsIScriptObjectOwner.h"
+#include "nsISizeOfHandler.h"
+#include "nsIStyleRule.h"
+#include "nsISupportsArray.h"
+#include "nsXIFConverter.h"
+#include "nsFrame.h"
+
+#include "nsString.h"
+#include "nsHTMLAtoms.h"
+#include "nsDOMEventsIIDs.h"
+#include "prprf.h"
+
+#include "nsIEventStateManager.h"
+#include "nsDOMEvent.h"
+#include "nsIPrivateDOMEvent.h"
+
+// XXX todo: add in missing out-of-memory checks
+
+NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
+NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
+NS_DEFINE_IID(kIDOMHTMLElementIID, NS_IDOMHTMLELEMENT_IID);
+NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
+NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
+NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
+NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
+//NS_DEFINE_IID(kIHTMLContentIID, NS_IHTMLCONTENT_IID);
+
+static NS_DEFINE_IID(kIContentDelegateIID, NS_ICONTENTDELEGATE_IID);
+static NS_DEFINE_IID(kIDOMAttributeIID, NS_IDOMATTRIBUTE_IID);
+static NS_DEFINE_IID(kIDOMNamedNodeMapIID, NS_IDOMNAMEDNODEMAP_IID);
+static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID);
+static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID);
+
+static nsIContentDelegate* gContentDelegate;
+
+/**
+ * THE html content delegate. There is exactly one instance of this
+ * class and it's used for all html content. It just turns around
+ * and asks the content object to create the frame.
+ */
+class ZContentDelegate : public nsIContentDelegate {
+public:
+ ZContentDelegate();
+ NS_DECL_ISUPPORTS
+ NS_IMETHOD CreateFrame(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParentFrame,
+ nsIStyleContext* aStyleContext,
+ nsIFrame*& aResult);
+protected:
+ ~ZContentDelegate();
+};
+
+// Attribute helper class used to wrap up an attribute with a dom
+// object that implements nsIDOMAttribute and nsIDOMNode and
+// nsIScriptObjectOwner
+class DOMAttribute : public nsIDOMAttribute, public nsIScriptObjectOwner {
+public:
+ DOMAttribute(const nsString &aName, const nsString &aValue);
+ ~DOMAttribute();
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
+ NS_IMETHOD ResetScriptObject();
+
+ // nsIDOMAttribute interface
+ NS_IMETHOD GetSpecified(PRBool* aSpecified);
+ NS_IMETHOD SetSpecified(PRBool aSpecified);
+ NS_IMETHOD GetName(nsString& aReturn);
+ NS_IMETHOD GetValue(nsString& aReturn);
+
+ // nsIDOMNode interface
+ NS_IMETHOD GetNodeName(nsString& aNodeName);
+ NS_IMETHOD GetNodeValue(nsString& aNodeValue);
+ NS_IMETHOD SetNodeValue(const nsString& aNodeValue);
+ NS_IMETHOD GetNodeType(PRInt32* aNodeType);
+ NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode);
+ NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes);
+ NS_IMETHOD GetHasChildNodes(PRBool* aHasChildNodes);
+ NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild);
+ NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild);
+ NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling);
+ NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling);
+ NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
+ NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
+ nsIDOMNode** aReturn);
+ NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
+ nsIDOMNode** aReturn);
+ NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
+ NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn);
+ NS_IMETHOD CloneNode(nsIDOMNode** aReturn);
+ NS_IMETHOD Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn);
+
+private:
+ nsString mName;
+ nsString mValue;
+ void* mScriptObject;
+};
+
+// Another helper class that implements the nsIDOMNamedNodeMap interface.
+class DOMAttributeMap : public nsIDOMNamedNodeMap,
+ public nsIScriptObjectOwner
+{
+public:
+ DOMAttributeMap(nsIHTMLContent &aContent);
+ virtual ~DOMAttributeMap();
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
+ NS_IMETHOD ResetScriptObject();
+
+ // nsIDOMNamedNodeMap interface
+ NS_IMETHOD GetLength(PRUint32* aSize);
+ NS_IMETHOD GetNamedItem(const nsString& aName, nsIDOMNode** aReturn);
+ NS_IMETHOD SetNamedItem(nsIDOMNode* aNode);
+ NS_IMETHOD RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn);
+ NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
+
+private:
+ nsIHTMLContent& mContent;
+ void* mScriptObject;
+};
+
+//----------------------------------------------------------------------
+
+ZContentDelegate::ZContentDelegate()
+{
+ NS_INIT_REFCNT();
+}
+
+NS_IMPL_ISUPPORTS(ZContentDelegate, kIContentDelegateIID);
+
+ZContentDelegate::~ZContentDelegate()
+{
+}
+
+NS_METHOD
+ZContentDelegate::CreateFrame(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParentFrame,
+ nsIStyleContext* aStyleContext,
+ nsIFrame*& aResult)
+{
+ NS_PRECONDITION(nsnull != aContent, "null ptr");
+
+ // Make sure the content is html content
+ nsIHTMLContent* hc;
+ nsIFrame* frame = nsnull;
+ nsresult rv = aContent->QueryInterface(kIHTMLContentIID, (void**) &hc);
+ if (NS_OK != rv) {
+ // This means that *somehow* somebody which is not an html
+ // content object got ahold of this delegate and tried to
+ // create a frame with it. Give them back an nsFrame.
+ rv = nsFrame::NewFrame(&frame, aContent, aParentFrame);
+ if (NS_OK == rv) {
+ frame->SetStyleContext(aPresContext, aStyleContext);
+ }
+ }
+ else {
+ // Ask the content object to create the frame
+ rv = hc->CreateFrame(aPresContext, aParentFrame, aStyleContext, frame);
+ NS_RELEASE(hc);
+ }
+ aResult = frame;
+ return rv;
+}
+
+//----------------------------------------------------------------------
+
+DOMAttribute::DOMAttribute(const nsString& aName, const nsString& aValue)
+ : mName(aName), mValue(aValue)
+{
+ mRefCnt = 1;
+ mScriptObject = nsnull;
+}
+
+DOMAttribute::~DOMAttribute()
+{
+}
+
+nsresult
+DOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+ if (NULL == aInstancePtr) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ if (aIID.Equals(kIDOMAttributeIID)) {
+ nsIDOMAttribute* tmp = this;
+ *aInstancePtr = (void*)tmp;
+ AddRef();
+ return NS_OK;
+ }
+ if (aIID.Equals(kIScriptObjectOwnerIID)) {
+ nsIScriptObjectOwner* tmp = this;
+ *aInstancePtr = (void*)tmp;
+ AddRef();
+ return NS_OK;
+ }
+ if (aIID.Equals(kISupportsIID)) {
+ nsIDOMAttribute* tmp1 = this;
+ nsISupports* tmp2 = tmp1;
+ *aInstancePtr = (void*)tmp2;
+ AddRef();
+ return NS_OK;
+ }
+ return NS_NOINTERFACE;
+}
+
+NS_IMPL_ADDREF(DOMAttribute)
+
+NS_IMPL_RELEASE(DOMAttribute)
+
+nsresult
+DOMAttribute::GetScriptObject(nsIScriptContext *aContext,
+ void** aScriptObject)
+{
+ nsresult res = NS_OK;
+ if (nsnull == mScriptObject) {
+ res = NS_NewScriptAttribute(aContext, this, nsnull,
+ (void **)&mScriptObject);
+ }
+ *aScriptObject = mScriptObject;
+ return res;
+}
+
+nsresult
+DOMAttribute::ResetScriptObject()
+{
+ mScriptObject = nsnull;
+ return NS_OK;
+}
+
+nsresult
+DOMAttribute::GetName(nsString& aName)
+{
+ aName = mName;
+ return NS_OK;
+}
+
+nsresult
+DOMAttribute::GetValue(nsString& aValue)
+{
+ aValue = mValue;
+ return NS_OK;
+}
+
+nsresult
+DOMAttribute::GetSpecified(PRBool* aSpecified)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult
+DOMAttribute::SetSpecified(PRBool specified)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetNodeName(nsString& aNodeName)
+{
+ return GetName(aNodeName);
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetNodeValue(nsString& aNodeValue)
+{
+ return GetValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+DOMAttribute::SetNodeValue(const nsString& aNodeValue)
+{
+ // You can't actually do this, but we'll fail silently
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetNodeType(PRInt32* aNodeType)
+{
+ *aNodeType = (PRInt32)nsIDOMNode::ATTRIBUTE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetParentNode(nsIDOMNode** aParentNode)
+{
+ *aParentNode = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
+{
+ *aChildNodes = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetHasChildNodes(PRBool* aHasChildNodes)
+{
+ *aHasChildNodes = PR_FALSE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
+{
+ *aFirstChild = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetLastChild(nsIDOMNode** aLastChild)
+{
+ *aLastChild = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
+{
+ *aPreviousSibling = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling)
+{
+ *aNextSibling = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
+{
+ *aAttributes = nsnull;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
+{
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+DOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
+{
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+DOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
+{
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+DOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
+{
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+DOMAttribute::CloneNode(nsIDOMNode** aReturn)
+{
+ DOMAttribute* newAttr = new DOMAttribute(mName, mValue);
+ if (nsnull == newAttr) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ *aReturn = newAttr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttribute::Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn)
+{
+ // XXX TBI
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+DOMAttributeMap::DOMAttributeMap(nsIHTMLContent& aContent)
+ : mContent(aContent)
+{
+ mRefCnt = 1;
+ mContent.AddRef();
+ mScriptObject = nsnull;
+}
+
+DOMAttributeMap::~DOMAttributeMap()
+{
+ mContent.Release();
+}
+
+nsresult
+DOMAttributeMap::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+ if (NULL == aInstancePtr) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ if (aIID.Equals(kIDOMNamedNodeMapIID)) {
+ nsIDOMNamedNodeMap* tmp = this;
+ *aInstancePtr = (void*)tmp;
+ AddRef();
+ return NS_OK;
+ }
+ if (aIID.Equals(kIScriptObjectOwnerIID)) {
+ nsIScriptObjectOwner* tmp = this;
+ *aInstancePtr = (void*)tmp;
+ AddRef();
+ return NS_OK;
+ }
+ if (aIID.Equals(kISupportsIID)) {
+ nsIDOMNamedNodeMap* tmp1 = this;
+ nsISupports* tmp2 = tmp1;
+ *aInstancePtr = (void*)tmp2;
+ AddRef();
+ return NS_OK;
+ }
+ return NS_NOINTERFACE;
+}
+
+NS_IMPL_ADDREF(DOMAttributeMap)
+
+NS_IMPL_RELEASE(DOMAttributeMap)
+
+nsresult
+DOMAttributeMap::GetScriptObject(nsIScriptContext *aContext,
+ void** aScriptObject)
+{
+ nsresult res = NS_OK;
+ if (nsnull == mScriptObject) {
+ res = NS_NewScriptNamedNodeMap(aContext, this, nsnull,
+ (void**)&mScriptObject);
+ }
+ *aScriptObject = mScriptObject;
+ return res;
+}
+
+nsresult
+DOMAttributeMap::ResetScriptObject()
+{
+ mScriptObject = nsnull;
+ return NS_OK;
+}
+
+nsresult
+DOMAttributeMap::GetNamedItem(const nsString &aAttrName,
+ nsIDOMNode** aAttribute)
+{
+ nsAutoString value;
+ mContent.GetAttribute(aAttrName, value);
+ *aAttribute = (nsIDOMNode *) new DOMAttribute(aAttrName, value);
+ return NS_OK;
+}
+
+nsresult
+DOMAttributeMap::SetNamedItem(nsIDOMNode *aNode)
+{
+ nsIDOMAttribute *attribute;
+ nsAutoString name, value;
+ nsresult err;
+
+ if (NS_OK != (err = aNode->QueryInterface(kIDOMAttributeIID,
+ (void **)&attribute))) {
+ return err;
+ }
+
+ attribute->GetName(name);
+ attribute->GetValue(value);
+ NS_RELEASE(attribute);
+
+ mContent.SetAttribute(name, value);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn)
+{
+ nsresult res = GetNamedItem(aName, aReturn);
+ if (NS_OK == res) {
+ nsAutoString upper;
+ aName.ToUpperCase(upper);
+ nsIAtom* attr = NS_NewAtom(upper);
+ mContent.UnsetAttribute(attr);
+ }
+
+ return res;
+}
+
+nsresult
+DOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
+{
+ nsresult res = NS_ERROR_FAILURE;
+ nsAutoString name, value;
+ nsISupportsArray *attributes = nsnull;
+ if (NS_OK == NS_NewISupportsArray(&attributes)) {
+ PRInt32 count = mContent.GetAllAttributeNames(attributes);
+ if (count > 0) {
+ if ((PRInt32)aIndex < count) {
+ nsISupports *att = attributes->ElementAt(aIndex);
+ static NS_DEFINE_IID(kIAtom, NS_IATOM_IID);
+ nsIAtom *atName = nsnull;
+ if (nsnull != att && NS_OK == att->QueryInterface(kIAtom, (void**)&atName)) {
+ atName->ToString(name);
+ if (eContentAttr_NotThere != mContent.GetAttribute(name, value)) {
+ *aReturn = (nsIDOMNode *)new DOMAttribute(name, value);
+ res = NS_OK;
+ }
+ NS_RELEASE(atName);
+ }
+ }
+ }
+ NS_RELEASE(attributes);
+ }
+
+ return res;
+}
+
+nsresult
+DOMAttributeMap::GetLength(PRUint32 *aLength)
+{
+ *aLength = mContent.GetAttributeCount();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+nsHTMLGenericContent::nsHTMLGenericContent()
+{
+ mDocument = nsnull;
+ mParent = nsnull;
+ mAttributes = nsnull;
+ mTag = nsnull;
+ mContent = nsnull;
+ mScriptObject = nsnull;
+ mListenerManager = nsnull;
+
+ // Create shared content delegate if this is the first html content
+ // object being created.
+ if (nsnull == gContentDelegate) {
+ gContentDelegate = new ZContentDelegate();
+ }
+
+ // Add a reference to the shared content delegate object
+ NS_ADDREF(gContentDelegate);
+}
+
+nsHTMLGenericContent::~nsHTMLGenericContent()
+{
+ NS_IF_RELEASE(mAttributes);
+ NS_IF_RELEASE(mTag);
+ NS_IF_RELEASE(mListenerManager);
+ // XXX what about mScriptObject? it's now safe to GC it...
+
+ NS_PRECONDITION(nsnull != gContentDelegate, "null content delegate");
+ if (nsnull != gContentDelegate) {
+ // Remove our reference to the shared content delegate object. If
+ // the last reference just went away, null out gContentDelegate.
+ nsrefcnt rc = gContentDelegate->Release();
+ if (0 == rc) {
+ gContentDelegate = nsnull;
+ }
+ }
+}
+
+void
+nsHTMLGenericContent::Init(nsIHTMLContent* aOuterContentObject,
+ nsIAtom* aTag)
+{
+ NS_ASSERTION((nsnull == mContent) && (nsnull != aOuterContentObject),
+ "null ptr");
+ mContent = aOuterContentObject;
+ mTag = aTag;
+ NS_IF_ADDREF(aTag);
+}
+
+nsresult
+nsHTMLGenericContent::GetNodeName(nsString& aNodeName)
+{
+ return GetTagName(aNodeName);
+}
+
+nsresult
+nsHTMLGenericContent::GetNodeValue(nsString& aNodeValue)
+{
+ aNodeValue.Truncate();
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetNodeValue(const nsString& aNodeValue)
+{
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetNodeType(PRInt32* aNodeType)
+{
+ *aNodeType = nsIDOMNode::ELEMENT;
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetParentNode(nsIDOMNode** aParentNode)
+{
+ if (nsnull != mParent) {
+ nsresult res = mParent->QueryInterface(kIDOMNodeIID, (void**)aParentNode);
+ NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
+ return res;
+ }
+ else {
+ *aParentNode = nsnull;
+ }
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetPreviousSibling(nsIDOMNode** aNode)
+{
+ if (nsnull != mParent) {
+ PRInt32 pos = mParent->IndexOf(mContent);
+ if (pos > -1) {
+ nsIContent* prev = mParent->ChildAt(--pos);
+ if (nsnull != prev) {
+ nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode);
+ NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
+ NS_RELEASE(prev); // balance the AddRef in ChildAt()
+ return res;
+ }
+ }
+ }
+ *aNode = nsnull;
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetNextSibling(nsIDOMNode** aNextSibling)
+{
+ if (nsnull != mParent) {
+ PRInt32 pos = mParent->IndexOf(mContent);
+ if (pos > -1 ) {
+ nsIContent* prev = mParent->ChildAt(++pos);
+ if (nsnull != prev) {
+ nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling);
+ NS_ASSERTION(NS_OK == res, "Must be a DOM Node");
+ NS_RELEASE(prev); // balance the AddRef in ChildAt()
+ return res;
+ }
+ }
+ }
+ *aNextSibling = nsnull;
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
+{
+ NS_PRECONDITION(nsnull != aAttributes, "null pointer argument");
+ if (nsnull != mAttributes) {
+ // XXX Should we create a new one every time or should we
+ // cache one after we create it? If we find that this is
+ // something that's called often, we might need to do the
+ // latter.
+ *aAttributes = new DOMAttributeMap(*mContent);
+ }
+ else {
+ *aAttributes = nsnull;
+ }
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetTagName(nsString& aTagName)
+{
+ aTagName.Truncate();
+ if (nsnull != mTag) {
+ mTag->ToString(aTagName);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetDOMAttribute(const nsString& aName, nsString& aReturn)
+{
+ GetAttribute(aName, aReturn);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetDOMAttribute(const nsString& aName,
+ const nsString& aValue)
+{
+ SetAttribute(aName, aValue);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::RemoveAttribute(const nsString& aName)
+{
+ nsAutoString upper;
+ aName.ToUpperCase(upper);
+ nsIAtom* attr = NS_NewAtom(upper);
+ UnsetAttribute(attr);
+ NS_RELEASE(attr);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetAttributeNode(const nsString& aName,
+ nsIDOMAttribute** aReturn)
+{
+ nsAutoString value;
+ if (eContentAttr_NotThere != GetAttribute(aName, value)) {
+ *aReturn = new DOMAttribute(aName, value);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetAttributeNode(nsIDOMAttribute* aAttribute)
+{
+ NS_PRECONDITION(nsnull != aAttribute, "null attribute");
+
+ nsresult res = NS_ERROR_FAILURE;
+
+ if (nsnull != aAttribute) {
+ nsAutoString name, value;
+ res = aAttribute->GetName(name);
+ if (NS_OK == res) {
+ res = aAttribute->GetValue(value);
+ if (NS_OK == res) {
+ SetAttribute(name, value);
+ }
+ }
+ }
+ return res;
+}
+
+nsresult
+nsHTMLGenericContent::RemoveAttributeNode(nsIDOMAttribute* aAttribute)
+{
+ NS_PRECONDITION(nsnull != aAttribute, "null attribute");
+
+ nsresult res = NS_ERROR_FAILURE;
+
+ if (nsnull != aAttribute) {
+ nsAutoString name;
+ res = aAttribute->GetName(name);
+ if (NS_OK == res) {
+ nsAutoString upper;
+ name.ToUpperCase(upper);
+ nsIAtom* attr = NS_NewAtom(upper);
+ UnsetAttribute(attr);
+ }
+ }
+
+ return res;
+}
+
+nsresult
+nsHTMLGenericContent::GetElementsByTagName(const nsString& aTagname,
+ nsIDOMNodeList** aReturn)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;/* XXX */
+}
+
+nsresult
+nsHTMLGenericContent::Normalize()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;/* XXX */
+}
+
+nsresult
+nsHTMLGenericContent::GetId(nsString& aId)
+{
+ GetAttribute(nsHTMLAtoms::id, aId);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetId(const nsString& aId)
+{
+ SetAttribute(nsHTMLAtoms::id, aId);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetTitle(nsString& aTitle)
+{
+ GetAttribute(nsHTMLAtoms::title, aTitle);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetTitle(const nsString& aTitle)
+{
+ SetAttribute(nsHTMLAtoms::title, aTitle);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetLang(nsString& aLang)
+{
+ GetAttribute(nsHTMLAtoms::lang, aLang);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetLang(const nsString& aLang)
+{
+ SetAttribute(nsHTMLAtoms::lang, aLang);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetDir(nsString& aDir)
+{
+ GetAttribute(nsHTMLAtoms::dir, aDir);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetDir(const nsString& aDir)
+{
+ SetAttribute(nsHTMLAtoms::dir, aDir);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetClassName(nsString& aClassName)
+{
+ GetAttribute(nsHTMLAtoms::kClass, aClassName);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::SetClassName(const nsString& aClassName)
+{
+ SetAttribute(nsHTMLAtoms::kClass, aClassName);
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericContent::GetDocument(nsIDocument*& aResult) const
+{
+ aResult = mDocument;
+ NS_IF_ADDREF(mDocument);
+ return NS_OK;
+}
+
+void
+nsHTMLGenericContent::SetDocument(nsIDocument* aDocument)
+{
+ mDocument = aDocument;
+
+ // Once the element is added to the doc tree we need to check if
+ // event handler were registered on it. Unfortunately, this means
+ // doing a GetAttribute for every type of handler.
+ if (nsnull != mAttributes) {
+ nsHTMLValue val;
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onclick, val))
+ AddScriptEventListener(nsHTMLAtoms::onclick, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::ondblclick, val))
+ AddScriptEventListener(nsHTMLAtoms::onclick, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onmousedown, val))
+ AddScriptEventListener(nsHTMLAtoms::onmousedown, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onmouseup, val))
+ AddScriptEventListener(nsHTMLAtoms::onmouseup, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onmouseover, val))
+ AddScriptEventListener(nsHTMLAtoms::onmouseover, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onmouseout, val))
+ AddScriptEventListener(nsHTMLAtoms::onmouseout, val, kIDOMMouseListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onkeydown, val))
+ AddScriptEventListener(nsHTMLAtoms::onkeydown, val, kIDOMKeyListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onkeyup, val))
+ AddScriptEventListener(nsHTMLAtoms::onkeyup, val, kIDOMKeyListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onkeypress, val))
+ AddScriptEventListener(nsHTMLAtoms::onkeypress, val, kIDOMKeyListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onmousemove, val))
+ AddScriptEventListener(nsHTMLAtoms::onmousemove, val, kIDOMMouseMotionListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onload, val))
+ AddScriptEventListener(nsHTMLAtoms::onload, val, kIDOMLoadListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onunload, val))
+ AddScriptEventListener(nsHTMLAtoms::onunload, val, kIDOMLoadListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onabort, val))
+ AddScriptEventListener(nsHTMLAtoms::onabort, val, kIDOMLoadListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onerror, val))
+ AddScriptEventListener(nsHTMLAtoms::onerror, val, kIDOMLoadListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onfocus, val))
+ AddScriptEventListener(nsHTMLAtoms::onfocus, val, kIDOMFocusListenerIID);
+ if (eContentAttr_HasValue == mAttributes->GetAttribute(nsHTMLAtoms::onblur, val))
+ AddScriptEventListener(nsHTMLAtoms::onblur, val, kIDOMFocusListenerIID);
+ }
+}
+
+nsIContent*
+nsHTMLGenericContent::GetParent() const
+{
+ NS_IF_ADDREF(mParent);
+ return mParent;
+}
+
+void
+nsHTMLGenericContent::SetParent(nsIContent* aParent)
+{
+ mParent = aParent;
+}
+
+nsresult
+nsHTMLGenericContent::IsSynthetic(PRBool& aResult)
+{
+ return PR_FALSE;
+}
+
+nsIAtom*
+nsHTMLGenericContent::GetTag() const
+{
+ NS_IF_ADDREF(mTag);
+ return mTag;
+}
+
+//void
+//nsHTMLTagContent::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
+//{
+// if (!aHandler->HaveSeen(mTag)) {
+// mTag->SizeOf(aHandler);
+// }
+// if (!aHandler->HaveSeen(mAttributes)) {
+// mAttributes->SizeOf(aHandler);
+// }
+//}
+
+nsresult
+nsHTMLGenericContent::HandleDOMEvent(nsIPresContext& aPresContext,
+ nsEvent* aEvent,
+ nsIDOMEvent** aDOMEvent,
+ PRUint32 aFlags,
+ nsEventStatus& aEventStatus)
+{
+ nsresult ret = NS_OK;
+
+ nsIDOMEvent* domEvent = nsnull;
+ if (DOM_EVENT_INIT == aFlags) {
+ nsIEventStateManager *manager;
+ if (NS_OK == aPresContext.GetEventStateManager(&manager)) {
+ manager->SetEventTarget(mContent);
+ NS_RELEASE(manager);
+ }
+ aDOMEvent = &domEvent;
+ }
+
+ //Capturing stage
+
+ //Local handling stage
+ if (nsnull != mListenerManager) {
+ mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
+ }
+
+ //Bubbling stage
+ if (DOM_EVENT_CAPTURE != aFlags && mParent != nsnull) {
+ ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
+ DOM_EVENT_BUBBLE, aEventStatus);
+ }
+
+ if (DOM_EVENT_INIT == aFlags) {
+ // We're leaving the DOM event loop so if we created a DOM event,
+ // release here.
+ if (nsnull != *aDOMEvent) {
+ if (0 != (*aDOMEvent)->Release()) {
+ // Okay, so someone in the DOM loop (a listener, JS object)
+ // still has a ref to the DOM Event but the internal data
+ // hasn't been malloc'd. Force a copy of the data here so the
+ // DOM Event is still valid.
+ nsIPrivateDOMEvent *privateEvent;
+ if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&privateEvent)) {
+ privateEvent->DuplicatePrivateData();
+ NS_RELEASE(privateEvent);
+ }
+ }
+ }
+ aDOMEvent = nsnull;
+ }
+
+ if (NS_OK == ret && nsEventStatus_eIgnore == aEventStatus) {
+ switch (aEvent->message) {
+ case NS_MOUSE_LEFT_BUTTON_DOWN:
+ if (mTag == nsHTMLAtoms::a) {
+ nsIEventStateManager *stateManager;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->SetActiveLink(mContent);
+ NS_RELEASE(stateManager);
+ }
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ break;
+
+ case NS_MOUSE_LEFT_BUTTON_UP:
+ if (mTag == nsHTMLAtoms::a) {
+ nsIEventStateManager *stateManager;
+ nsIContent *activeLink;
+ if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
+ stateManager->GetActiveLink(&activeLink);
+ NS_RELEASE(stateManager);
+ }
+
+ if (activeLink == mContent) {
+ nsEventStatus status;
+ nsMouseEvent event;
+ event.eventStructType = NS_MOUSE_EVENT;
+ event.message = NS_MOUSE_LEFT_CLICK;
+ HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
+
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ nsAutoString base, href, target;
+ GetAttribute(nsString(NS_HTML_BASE_HREF), base);
+ GetAttribute(nsString("href"), href);
+ GetAttribute(nsString("target"), target);
+ if (target.Length() == 0) {
+ GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
+ }
+//XXX TriggerLink(aPresContext, base, href, target, PR_TRUE);
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
+ }
+ }
+ }
+ break;
+
+ case NS_MOUSE_RIGHT_BUTTON_DOWN:
+ // XXX Bring up a contextual menu provided by the application
+ break;
+
+ case NS_MOUSE_ENTER:
+ //mouse enter doesn't work yet. Use move until then.
+ if (mTag == nsHTMLAtoms::a) {
+ nsAutoString base, href, target;
+ GetAttribute(nsString(NS_HTML_BASE_HREF), base);
+ GetAttribute(nsString("href"), href);
+ GetAttribute(nsString("target"), target);
+ if (target.Length() == 0) {
+ GetAttribute(nsString(NS_HTML_BASE_TARGET), target);
+ }
+//XXX TriggerLink(aPresContext, base, href, target, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ // XXX this doesn't seem to do anything yet
+ case NS_MOUSE_EXIT:
+ if (mTag == nsHTMLAtoms::a) {
+ nsAutoString empty;
+//XXX TriggerLink(aPresContext, empty, empty, empty, PR_FALSE);
+ aEventStatus = nsEventStatus_eConsumeDoDefault;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ret;
+}
+
+void
+nsHTMLGenericContent::SetAttribute(const nsString& aName,
+ const nsString& aValue)
+{
+ nsAutoString upper;
+ aName.ToUpperCase(upper);
+ nsIAtom* attr = NS_NewAtom(upper);
+ SetAttribute(attr, aValue);
+ NS_RELEASE(attr);
+}
+
+void
+nsHTMLGenericContent::SetAttribute(nsIAtom* aAttribute,
+ const nsString& aValue)
+{
+ if (nsnull == mAttributes) {
+ NS_NewHTMLAttributes(&mAttributes, mContent);
+ }
+ if (nsnull != mAttributes) {
+ nsHTMLValue hval;
+ if (eContentAttr_HasValue ==
+ mContent->StringToAttribute(aAttribute, aValue, hval)) {
+ mAttributes->SetAttribute(aAttribute, hval);
+ }
+ else if (nsHTMLAtoms::style == aAttribute) {
+ // XXX the style sheet language is a document property that
+ // should be used to lookup the style sheet parser to parse the
+ // attribute.
+ nsICSSParser* css;
+ nsresult rv = NS_NewCSSParser(&css);
+ if (NS_OK != rv) {
+ return;
+ }
+ nsIStyleRule* rule;
+ rv = css->ParseDeclarations(aValue, nsnull, rule);
+ if ((NS_OK == rv) && (nsnull != rule)) {
+ mAttributes->SetAttribute(aAttribute, nsHTMLValue(rule));
+ NS_RELEASE(rule);
+ }
+ NS_RELEASE(css);
+ }
+ else {
+ mAttributes->SetAttribute(aAttribute, aValue);
+ }
+ }
+}
+
+void
+nsHTMLGenericContent::SetAttribute(nsIAtom* aAttribute,
+ const nsHTMLValue& aValue)
+{
+ if (nsnull == mAttributes) {
+ NS_NewHTMLAttributes(&mAttributes, mContent);
+ }
+ if (nsnull != mAttributes) {
+ mAttributes->SetAttribute(aAttribute, aValue);
+ }
+}
+
+void
+nsHTMLGenericContent::UnsetAttribute(nsIAtom* aAttribute)
+{
+ if (nsnull != mAttributes) {
+ PRInt32 count = mAttributes->UnsetAttribute(aAttribute);
+ if (0 == count) {
+ NS_RELEASE(mAttributes);
+ }
+ }
+}
+
+nsContentAttr
+nsHTMLGenericContent::GetAttribute(const nsString& aName,
+ nsString& aResult) const
+{
+ nsAutoString upper;
+ aName.ToUpperCase(upper);
+ nsIAtom* attr = NS_NewAtom(upper);
+ nsContentAttr result = GetAttribute(attr, aResult);
+ NS_RELEASE(attr);
+ return result;
+}
+
+
+nsContentAttr
+nsHTMLGenericContent::GetAttribute(nsIAtom *aAttribute,
+ nsString &aResult) const
+{
+ nsHTMLValue value;
+ nsContentAttr result = GetAttribute(aAttribute, value);
+
+ char cbuf[20];
+ nscolor color;
+ if (eContentAttr_HasValue == result) {
+ // Try subclass conversion routine first
+ if (eContentAttr_HasValue ==
+ mContent->AttributeToString(aAttribute, value, aResult)) {
+ return result;
+ }
+
+ // Provide default conversions for most everything
+ switch (value.GetUnit()) {
+ case eHTMLUnit_Empty:
+ aResult.Truncate();
+ break;
+
+ case eHTMLUnit_String:
+ case eHTMLUnit_Null:
+ value.GetStringValue(aResult);
+ break;
+
+ case eHTMLUnit_Integer:
+ aResult.Truncate();
+ aResult.Append(value.GetIntValue(), 10);
+ break;
+
+ case eHTMLUnit_Pixel:
+ aResult.Truncate();
+ aResult.Append(value.GetPixelValue(), 10);
+ break;
+
+ case eHTMLUnit_Percent:
+ aResult.Truncate(0);
+ aResult.Append(PRInt32(value.GetPercentValue() * 100.0f), 10);
+ aResult.Append('%');
+ break;
+
+ case eHTMLUnit_Color:
+ color = nscolor(value.GetColorValue());
+ PR_snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x",
+ NS_GET_R(color), NS_GET_G(color), NS_GET_B(color));
+ aResult.Truncate(0);
+ aResult.Append(cbuf);
+ break;
+
+ default:
+ case eHTMLUnit_Enumerated:
+ NS_NOTREACHED("no default enumerated value to string conversion");
+ result = eContentAttr_NotThere;
+ break;
+ }
+ }
+ return result;
+}
+
+nsContentAttr
+nsHTMLGenericContent::GetAttribute(nsIAtom* aAttribute,
+ nsHTMLValue& aValue) const
+{
+ if (nsnull != mAttributes) {
+ return mAttributes->GetAttribute(aAttribute, aValue);
+ }
+ aValue.Reset();
+ return eContentAttr_NotThere;
+}
+
+PRInt32
+nsHTMLGenericContent::GetAllAttributeNames(nsISupportsArray* aArray) const
+{
+ if (nsnull != mAttributes) {
+ return mAttributes->GetAllAttributeNames(aArray);
+ }
+ return 0;
+}
+
+PRInt32
+nsHTMLGenericContent::GetAttributeCount(void) const
+{
+ if (nsnull != mAttributes) {
+ return mAttributes->Count();
+ }
+ return 0;
+}
+
+void
+nsHTMLGenericContent::SetID(nsIAtom* aID)
+{
+ if (nsnull != aID) {
+ if (nsnull == mAttributes) {
+ NS_NewHTMLAttributes(&mAttributes, mContent);
+ }
+ if (nsnull != mAttributes) {
+ mAttributes->SetID(aID);
+ }
+ }
+ else {
+ if (nsnull != mAttributes) {
+ PRInt32 count = mAttributes->SetID(nsnull);
+ if (0 == count) {
+ NS_RELEASE(mAttributes);
+ }
+ }
+ }
+}
+
+nsIAtom*
+nsHTMLGenericContent::GetID(void) const
+{
+ if (nsnull != mAttributes) {
+ return mAttributes->GetID();
+ }
+ return nsnull;
+}
+
+void
+nsHTMLGenericContent::SetClass(nsIAtom* aClass)
+{
+ if (nsnull != aClass) {
+ if (nsnull == mAttributes) {
+ NS_NewHTMLAttributes(&mAttributes, mContent);
+ }
+ if (nsnull != mAttributes) {
+ mAttributes->SetClass(aClass);
+ }
+ }
+ else {
+ if (nsnull != mAttributes) {
+ PRInt32 count = mAttributes->SetClass(nsnull);
+ if (0 == count) {
+ NS_RELEASE(mAttributes);
+ }
+ }
+ }
+}
+
+nsIAtom*
+nsHTMLGenericContent::GetClass(void) const
+{
+ if (nsnull != mAttributes) {
+ return mAttributes->GetClass();
+ }
+ return nsnull;
+}
+
+nsIStyleRule*
+nsHTMLGenericContent::GetStyleRule(void)
+{
+ nsIStyleRule* result = nsnull;
+
+ if (nsnull != mAttributes) {
+ mAttributes->QueryInterface(kIStyleRuleIID, (void**)&result);
+ }
+ return result;
+}
+
+nsIContentDelegate*
+nsHTMLGenericContent::GetDelegate(nsIPresContext* aCX)
+{
+ gContentDelegate->AddRef();
+ return gContentDelegate;
+}
+
+void
+nsHTMLGenericContent::ListAttributes(FILE* out) const
+{
+ nsISupportsArray* attrs;
+ if (NS_OK == NS_NewISupportsArray(&attrs)) {
+ GetAllAttributeNames(attrs);
+ PRInt32 count = attrs->Count();
+ PRInt32 index;
+ for (index = 0; index < count; index++) {
+ // name
+ nsIAtom* attr = (nsIAtom*)attrs->ElementAt(index);
+ nsAutoString buffer;
+ attr->ToString(buffer);
+
+ // value
+ nsAutoString value;
+ GetAttribute(buffer, value);
+ buffer.Append("=");
+ buffer.Append(value);
+
+ fputs(" ", out);
+ fputs(buffer, out);
+ NS_RELEASE(attr);
+ }
+ NS_RELEASE(attrs);
+ }
+}
+
+void
+nsHTMLGenericContent::List(FILE* out, PRInt32 aIndent) const
+{
+ NS_PRECONDITION(nsnull != mDocument, "bad content");
+
+ PRInt32 index;
+ for (index = aIndent; --index >= 0; ) fputs(" ", out);
+
+ nsIAtom* tag = GetTag();
+ if (tag != nsnull) {
+ nsAutoString buf;
+ tag->ToString(buf);
+ fputs(buf, out);
+ NS_RELEASE(tag);
+ }
+
+ ListAttributes(out);
+
+// fprintf(out, " RefCount=%d<\n", mRefCnt);
+
+ if (mContent->CanContainChildren()) {
+ PRInt32 kids = mContent->ChildCount();
+ for (index = 0; index < kids; index++) {
+ nsIContent* kid = mContent->ChildAt(index);
+ kid->List(out, aIndent + 1);
+ NS_RELEASE(kid);
+ }
+ }
+
+ for (index = aIndent; --index >= 0; ) fputs(" ", out);
+ fputs(">\n", out);
+}
+
+void
+nsHTMLGenericContent::ToHTML(FILE* out) const
+{
+ nsAutoString tmp;
+ ToHTMLString(tmp);
+ fputs(tmp, out);
+}
+// XXX i18n: this is wrong (?) because we need to know the outgoing
+// character set (I think)
+static void
+QuoteForHTML(const nsString& aValue, nsString& aResult)
+{
+ aResult.Truncate();
+ const PRUnichar* cp = aValue.GetUnicode();
+ const PRUnichar* end = aValue.GetUnicode() + aValue.Length();
+ aResult.Append('"');
+ while (cp < end) {
+ PRUnichar ch = *cp++;
+ if ((ch >= 0x20) && (ch <= 0x7f)) {
+ if (ch == '\"') {
+ aResult.Append(""");
+ }
+ else {
+ aResult.Append(ch);
+ }
+ }
+ else {
+ aResult.Append("");
+ aResult.Append((PRInt32) ch, 10);
+ aResult.Append(';');
+ }
+ }
+ aResult.Append('"');
+}
+
+void
+nsHTMLGenericContent::ToHTMLString(nsString& aBuf) const
+{
+ aBuf.Truncate(0);
+ aBuf.Append('<');
+
+ if (nsnull != mTag) {
+ nsAutoString tmp;
+ mTag->ToString(tmp);
+ aBuf.Append(tmp);
+ } else {
+ aBuf.Append("?NULL");
+ }
+
+ if (nsnull != mAttributes) {
+ nsISupportsArray* attrs;
+ nsresult rv = NS_NewISupportsArray(&attrs);
+ if (NS_OK == rv) {
+ mAttributes->GetAllAttributeNames(attrs);
+ PRInt32 i, n = attrs->Count();
+ nsAutoString name, value, quotedValue;
+ for (i = 0; i < n; i++) {
+ nsIAtom* atom = (nsIAtom*) attrs->ElementAt(i);
+ atom->ToString(name);
+ aBuf.Append(' ');
+ aBuf.Append(name);
+ value.Truncate();
+ GetAttribute(name, value);
+ if (value.Length() > 0) {
+ aBuf.Append('=');
+ QuoteForHTML(value, quotedValue);
+ aBuf.Append(quotedValue);
+ }
+ }
+ NS_RELEASE(attrs);
+ }
+ }
+
+ aBuf.Append('>');
+}
+
+//----------------------------------------------------------------------
+
+// XXX this is REALLY temporary code
+
+extern nsresult NS_NewHRFrame(nsIContent* aContent, nsIFrame* aParentFrame,
+ nsIFrame*& aNewFrame);
+
+nsresult
+nsHTMLGenericContent::CreateFrame(nsIPresContext* aPresContext,
+ nsIFrame* aParentFrame,
+ nsIStyleContext* aStyleContext,
+ nsIFrame*& aResult)
+{
+ nsIFrame* frame = nsnull;
+ nsresult rv = NS_OK;
+ if (mTag == nsHTMLAtoms::hr) {
+ rv = NS_NewHRFrame(mContent, aParentFrame, frame);
+ }
+
+ if (nsnull == frame) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ frame->SetStyleContext(aPresContext, aStyleContext);
+ aResult = frame;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+// nsIScriptObjectOwner implementation
+
+nsresult
+nsHTMLGenericContent::GetScriptObject(nsIScriptContext* aContext,
+ void** aScriptObject)
+{
+ nsresult res = NS_OK;
+ if (nsnull == mScriptObject) {
+ nsIDOMElement* ele = nsnull;
+ mContent->QueryInterface(kIDOMElementIID, (void**) &ele);
+ res = NS_NewScriptElement(aContext, ele, mParent, (void**)&mScriptObject);
+ NS_RELEASE(ele);
+ }
+ *aScriptObject = mScriptObject;
+ return res;
+}
+
+nsresult
+nsHTMLGenericContent::ResetScriptObject()
+{
+ mScriptObject = nsnull;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+// nsIDOMEventReceiver implementation
+
+nsresult
+nsHTMLGenericContent::GetListenerManager(nsIEventListenerManager** aResult)
+{
+ if (nsnull != mListenerManager) {
+ NS_ADDREF(mListenerManager);
+ *aResult = mListenerManager;
+ return NS_OK;
+ }
+ nsresult rv = NS_NewEventListenerManager(aResult);
+ if (NS_OK == rv) {
+ mListenerManager = *aResult;
+ NS_ADDREF(mListenerManager);
+ }
+ return rv;
+}
+
+nsresult
+nsHTMLGenericContent::GetNewListenerManager(nsIEventListenerManager** aResult)
+{
+ return NS_NewEventListenerManager(aResult);
+}
+
+nsresult
+nsHTMLGenericContent::AddEventListener(nsIDOMEventListener* aListener,
+ const nsIID& aIID)
+{
+ nsIEventListenerManager *manager;
+
+ if (NS_OK == GetListenerManager(&manager)) {
+ manager->AddEventListener(aListener, aIID);
+ NS_RELEASE(manager);
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
+}
+
+nsresult
+nsHTMLGenericContent::RemoveEventListener(nsIDOMEventListener* aListener,
+ const nsIID& aIID)
+{
+ if (nsnull != mListenerManager) {
+ mListenerManager->RemoveEventListener(aListener, aIID);
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
+}
+
+//----------------------------------------------------------------------
+
+nsresult
+nsHTMLGenericContent::AddScriptEventListener(nsIAtom* aAttribute,
+ nsHTMLValue& aValue,
+ REFNSIID aIID)
+{
+ nsresult ret = NS_OK;
+ nsIScriptContext* context;
+ nsIScriptContextOwner* owner;
+
+ if (nsnull != mDocument) {
+ owner = mDocument->GetScriptContextOwner();
+ if (NS_OK == owner->GetScriptContext(&context)) {
+ if (nsHTMLAtoms::body == mTag || nsHTMLAtoms::frameset == mTag) {
+ nsIDOMEventReceiver *receiver;
+ nsIScriptGlobalObject *global = context->GetGlobalObject();
+
+ if (nsnull != global && NS_OK == global->QueryInterface(kIDOMEventReceiverIID, (void**)&receiver)) {
+ nsIEventListenerManager *manager;
+ if (NS_OK == receiver->GetListenerManager(&manager)) {
+ nsIScriptObjectOwner *mObjectOwner;
+ if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) {
+ nsString value;
+ aValue.GetStringValue(value);
+ ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, value, aIID);
+ NS_RELEASE(mObjectOwner);
+ }
+ NS_RELEASE(manager);
+ }
+ NS_RELEASE(receiver);
+ }
+ NS_IF_RELEASE(global);
+ }
+ else {
+ nsIEventListenerManager *manager;
+ if (NS_OK == GetListenerManager(&manager)) {
+ nsString value;
+ aValue.GetStringValue(value);
+ nsIScriptObjectOwner* owner;
+ if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID,
+ (void**) &owner)) {
+ ret = manager->AddScriptEventListener(context, owner,
+ aAttribute, value, aIID);
+ NS_RELEASE(owner);
+ }
+ NS_RELEASE(manager);
+ }
+ }
+ NS_RELEASE(context);
+ }
+ NS_RELEASE(owner);
+ }
+ return ret;
+}
+
+nsContentAttr
+nsHTMLGenericContent::AttributeToString(nsIAtom* aAttribute,
+ nsHTMLValue& aValue,
+ nsString& aResult) const
+{
+ if (nsHTMLAtoms::style == aAttribute) {
+ if (eHTMLUnit_ISupports == aValue.GetUnit()) {
+ nsIStyleRule* rule = (nsIStyleRule*) aValue.GetISupportsValue();
+ // rule->ToString(str);
+ aResult = "XXX style rule ToString goes here";
+ return eContentAttr_HasValue;
+ }
+ }
+ aResult.Truncate();
+ return eContentAttr_NotThere;
+}
+
+PRBool
+nsHTMLGenericContent::ParseEnumValue(const nsString& aValue,
+ EnumTable* aTable,
+ nsHTMLValue& aResult)
+{
+ while (nsnull != aTable->tag) {
+ if (aValue.EqualsIgnoreCase(aTable->tag)) {
+ aResult.SetIntValue(aTable->value, eHTMLUnit_Enumerated);
+ return PR_TRUE;
+ }
+ aTable++;
+ }
+ return PR_FALSE;
+}
+
+PRBool
+nsHTMLGenericContent::EnumValueToString(const nsHTMLValue& aValue,
+ EnumTable* aTable,
+ nsString& aResult)
+{
+ aResult.Truncate(0);
+ if (aValue.GetUnit() == eHTMLUnit_Enumerated) {
+ PRInt32 v = aValue.GetIntValue();
+ while (nsnull != aTable->tag) {
+ if (aTable->value == v) {
+ aResult.Append(aTable->tag);
+ return PR_TRUE;
+ }
+ aTable++;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool
+nsHTMLGenericContent::ParseValueOrPercent(const nsString& aString,
+ nsHTMLValue& aResult,
+ nsHTMLUnit aValueUnit)
+{ // XXX should vave min/max values?
+ nsAutoString tmp(aString);
+ tmp.CompressWhitespace(PR_TRUE, PR_TRUE);
+ PRInt32 ec, val = tmp.ToInteger(&ec);
+ if (NS_OK == ec) {
+ if (tmp.Last() == '%') {/* XXX not 100% compatible with ebina's code */
+ if (val < 0) val = 0;
+ if (val > 100) val = 100;
+ aResult.SetPercentValue(float(val)/100.0f);
+ } else {
+ if (eHTMLUnit_Pixel == aValueUnit) {
+ aResult.SetPixelValue(val);
+ }
+ else {
+ aResult.SetIntValue(val, aValueUnit);
+ }
+ }
+ return PR_TRUE;
+ }
+
+ // Illegal values are mapped to empty
+ aResult.SetEmptyValue();
+ return PR_FALSE;
+}
+
+/* used to parse attribute values that could be either:
+ * integer (n),
+ * percent (n%),
+ * or proportional (n*)
+ */
+void
+nsHTMLGenericContent::ParseValueOrPercentOrProportional(const nsString& aString,
+ nsHTMLValue& aResult,
+ nsHTMLUnit aValueUnit)
+{ // XXX should have min/max values?
+ nsAutoString tmp(aString);
+ tmp.CompressWhitespace(PR_TRUE, PR_TRUE);
+ PRInt32 ec, val = tmp.ToInteger(&ec);
+ if (tmp.Last() == '%') {/* XXX not 100% compatible with ebina's code */
+ if (val < 0) val = 0;
+ if (val > 100) val = 100;
+ aResult.SetPercentValue(float(val)/100.0f);
+ } else if (tmp.Last() == '*') {
+ if (val < 0) val = 0;
+ aResult.SetIntValue(val, eHTMLUnit_Proportional); // proportional values are integers
+ } else {
+ if (eHTMLUnit_Pixel == aValueUnit) {
+ aResult.SetPixelValue(val);
+ }
+ else {
+ aResult.SetIntValue(val, aValueUnit);
+ }
+ }
+}
+
+PRBool
+nsHTMLGenericContent::ValueOrPercentToString(const nsHTMLValue& aValue,
+ nsString& aResult)
+{
+ aResult.Truncate(0);
+ switch (aValue.GetUnit()) {
+ case eHTMLUnit_Integer:
+ aResult.Append(aValue.GetIntValue(), 10);
+ return PR_TRUE;
+ case eHTMLUnit_Pixel:
+ aResult.Append(aValue.GetPixelValue(), 10);
+ return PR_TRUE;
+ case eHTMLUnit_Percent:
+ aResult.Append(PRInt32(aValue.GetPercentValue() * 100.0f), 10);
+ aResult.Append('%');
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+PRBool
+nsHTMLGenericContent::ParseValue(const nsString& aString, PRInt32 aMin,
+ nsHTMLValue& aResult, nsHTMLUnit aValueUnit)
+{
+ PRInt32 ec, val = aString.ToInteger(&ec);
+ if (NS_OK == ec) {
+ if (val < aMin) val = aMin;
+ if (eHTMLUnit_Pixel == aValueUnit) {
+ aResult.SetPixelValue(val);
+ }
+ else {
+ aResult.SetIntValue(val, aValueUnit);
+ }
+ return PR_TRUE;
+ }
+
+ // Illegal values are mapped to empty
+ aResult.SetEmptyValue();
+ return PR_FALSE;
+}
+
+PRBool
+nsHTMLGenericContent::ParseValue(const nsString& aString, PRInt32 aMin,
+ PRInt32 aMax,
+ nsHTMLValue& aResult, nsHTMLUnit aValueUnit)
+{
+ PRInt32 ec, val = aString.ToInteger(&ec);
+ if (NS_OK == ec) {
+ if (val < aMin) val = aMin;
+ if (val > aMax) val = aMax;
+ if (eHTMLUnit_Pixel == aValueUnit) {
+ aResult.SetPixelValue(val);
+ }
+ else {
+ aResult.SetIntValue(val, aValueUnit);
+ }
+ return PR_TRUE;
+ }
+
+ // Illegal values are mapped to empty
+ aResult.SetEmptyValue();
+ return PR_FALSE;
+}
+
+//----------------------------------------------------------------------
+
+nsHTMLGenericLeafContent::nsHTMLGenericLeafContent()
+{
+}
+
+nsHTMLGenericLeafContent::~nsHTMLGenericLeafContent()
+{
+}
+
+nsresult
+nsHTMLGenericLeafContent::CopyInnerTo(nsIHTMLContent* aSrcContent,
+ nsHTMLGenericLeafContent* aDst)
+{
+ aDst->mContent = aSrcContent;
+ // XXX should the node's document be set?
+ // XXX copy attributes not yet impelemented
+ return NS_OK;
+}
+
+nsresult
+nsHTMLGenericLeafContent::Equals(nsIDOMNode* aNode, PRBool aDeep,
+ PRBool* aReturn)
+{
+ // XXX not yet implemented
+ *aReturn = PR_FALSE;
+ return NS_OK;
+}
+
+void
+nsHTMLGenericLeafContent::BeginConvertToXIF(nsXIFConverter& aConverter) const
+{
+ if (nsnull != mTag)
+ {
+ nsAutoString name;
+ mTag->ToString(name);
+ aConverter.BeginLeaf(name);
+ }
+
+ // Add all attributes to the convert
+ if (nsnull != mAttributes)
+ {
+ nsISupportsArray* attrs;
+ nsresult rv = NS_NewISupportsArray(&attrs);
+ if (NS_OK == rv)
+ {
+ mAttributes->GetAllAttributeNames(attrs);
+ PRInt32 i, n = attrs->Count();
+ nsAutoString name, value;
+ for (i = 0; i < n; i++)
+ {
+ nsIAtom* atom = (nsIAtom*) attrs->ElementAt(i);
+ atom->ToString(name);
+
+ value.Truncate();
+ GetAttribute(name, value);
+
+ aConverter.AddHTMLAttribute(name,value);
+ }
+ NS_RELEASE(attrs);
+ }
+ }
+}
+
+void
+nsHTMLGenericLeafContent::ConvertContentToXIF(nsXIFConverter& aConverter) const
+{
+}
+
+void
+nsHTMLGenericLeafContent::FinishConvertToXIF(nsXIFConverter& aConverter) const
+{
+ if (nsnull != mTag)
+ {
+ nsAutoString name;
+ mTag->ToString(name);
+ aConverter.EndLeaf(name);
+ }
+}
+
+// XXX not really implemented (yet)
+nsresult
+nsHTMLGenericLeafContent::SizeOf(nsISizeOfHandler* aHandler) const
+{
+ aHandler->Add(sizeof(*this));
+ return NS_OK;
+}
diff --git a/mozilla/layout/html/content/src/nsHTMLGenericContent.h b/mozilla/layout/html/content/src/nsHTMLGenericContent.h
new file mode 100644
index 00000000000..1a6f882b3c2
--- /dev/null
+++ b/mozilla/layout/html/content/src/nsHTMLGenericContent.h
@@ -0,0 +1,694 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are Copyright (C) 1998
+ * Netscape Communications Corporation. All Rights Reserved.
+ */
+#ifndef nsHTMLGenericContent_h___
+#define nsHTMLGenericContent_h___
+
+#include "nsIDOMHTMLElement.h"
+#include "nsIContent.h"
+#include "nsHTMLValue.h"
+#include "nsVoidArray.h"
+
+extern const nsIID kIDOMNodeIID;
+extern const nsIID kIDOMElementIID;
+extern const nsIID kIDOMHTMLElementIID;
+extern const nsIID kIDOMEventReceiverIID;
+extern const nsIID kIScriptObjectOwnerIID;
+extern const nsIID kISupportsIID;
+extern const nsIID kIContentIID;
+extern const nsIID kIHTMLContentIID;
+
+class nsIDOMAttribute;
+class nsIDOMEventListener;
+class nsIDOMNodeList;
+class nsIEventListenerManager;
+class nsIFrame;
+class nsIHTMLAttributes;
+class nsIHTMLContent;
+class nsIStyleContext;
+class nsIStyleRule;
+class nsISupportsArray;
+
+struct nsHTMLGenericContent {
+ nsHTMLGenericContent();
+ ~nsHTMLGenericContent();
+
+ void Init(nsIHTMLContent* aOuterContentObject, nsIAtom* aTag);
+
+ // Implementation for nsIDOMNode
+ nsresult GetNodeName(nsString& aNodeName);
+ nsresult GetNodeValue(nsString& aNodeValue);
+ nsresult SetNodeValue(const nsString& aNodeValue);
+ nsresult GetNodeType(PRInt32* aNodeType);
+ nsresult GetParentNode(nsIDOMNode** aParentNode);
+ nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes);
+ nsresult GetPreviousSibling(nsIDOMNode** aPreviousSibling);
+ nsresult GetNextSibling(nsIDOMNode** aNextSibling);
+
+ // Implementation for nsIDOMElement
+ nsresult GetTagName(nsString& aTagName);
+ nsresult GetDOMAttribute(const nsString& aName, nsString& aReturn);
+ nsresult SetDOMAttribute(const nsString& aName, const nsString& aValue);
+ nsresult RemoveAttribute(const nsString& aName);
+ nsresult GetAttributeNode(const nsString& aName,
+ nsIDOMAttribute** aReturn);
+ nsresult SetAttributeNode(nsIDOMAttribute* aNewAttr);
+ nsresult RemoveAttributeNode(nsIDOMAttribute* aOldAttr);
+ nsresult GetElementsByTagName(const nsString& aTagname,
+ nsIDOMNodeList** aReturn);
+ nsresult Normalize();
+
+ // Implementation for nsIDOMHTMLElement
+ nsresult GetId(nsString& aId);
+ nsresult SetId(const nsString& aId);
+ nsresult GetTitle(nsString& aTitle);
+ nsresult SetTitle(const nsString& aTitle);
+ nsresult GetLang(nsString& aLang);
+ nsresult SetLang(const nsString& aLang);
+ nsresult GetDir(nsString& aDir);
+ nsresult SetDir(const nsString& aDir);
+ nsresult GetClassName(nsString& aClassName);
+ nsresult SetClassName(const nsString& aClassName);
+
+ // nsIDOMEventReceiver interface
+ nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
+ nsresult RemoveEventListener(nsIDOMEventListener* aListener,
+ const nsIID& aIID);
+ nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
+ nsresult GetNewListenerManager(nsIEventListenerManager** aInstancePtrResult);
+
+ // nsIScriptObjectOwner interface
+ nsresult GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
+ nsresult ResetScriptObject();
+
+ // Implementation for nsIContent
+ nsresult GetDocument(nsIDocument*& aResult) const;
+ void SetDocument(nsIDocument* aDocument);
+ nsIContent* GetParent() const;
+ void SetParent(nsIContent* aParent);
+ nsresult IsSynthetic(PRBool& aResult);
+ nsIAtom* GetTag() const;
+ void SetAttribute(const nsString& aName, const nsString& aValue);
+ nsContentAttr GetAttribute(const nsString& aName, nsString& aResult) const;
+ nsIContentDelegate* GetDelegate(nsIPresContext* aCX);
+ void List(FILE* out, PRInt32 aIndent) const;
+ nsresult HandleDOMEvent(nsIPresContext& aPresContext,
+ nsEvent* aEvent,
+ nsIDOMEvent** aDOMEvent,
+ PRUint32 aFlags,
+ nsEventStatus& aEventStatus);
+
+ // Implementation for nsIHTMLContent
+ void Compact();
+ void SetAttribute(nsIAtom* aAttribute, const nsString& aValue);
+ void SetAttribute(nsIAtom* aAttribute, const nsHTMLValue& aValue);
+ void UnsetAttribute(nsIAtom* aAttribute);
+ nsContentAttr GetAttribute(nsIAtom *aAttribute,
+ nsString &aResult) const;
+ nsContentAttr GetAttribute(nsIAtom* aAttribute,
+ nsHTMLValue& aValue) const;
+ PRInt32 GetAllAttributeNames(nsISupportsArray* aArray) const;
+ PRInt32 GetAttributeCount(void) const;
+ void SetID(nsIAtom* aID);
+ nsIAtom* GetID(void) const;
+ void SetClass(nsIAtom* aClass);
+ nsIAtom* GetClass(void) const;
+ nsIStyleRule* GetStyleRule(void);
+ void MapAttributesInto(nsIStyleContext* aStyleContext,
+ nsIPresContext* aPresContext);
+ void ToHTMLString(nsString& aResult) const;
+ void ToHTML(FILE* out) const;
+ nsresult CreateFrame(nsIPresContext* aPresContext,
+ nsIFrame* aParentFrame,
+ nsIStyleContext* aStyleContext,
+ nsIFrame*& aResult);
+
+ //----------------------------------------
+
+ nsresult AddScriptEventListener(nsIAtom* aAttribute,
+ nsHTMLValue& aValue,
+ REFNSIID aIID);
+
+ nsContentAttr AttributeToString(nsIAtom* aAttribute,
+ nsHTMLValue& aValue,
+ nsString& aResult) const;
+
+ void ListAttributes(FILE* out) const;
+
+ //----------------------------------------
+
+ // Attribute parsing utilities
+
+ struct EnumTable {
+ const char* tag;
+ PRInt32 value;
+ };
+
+ static PRBool ParseEnumValue(const nsString& aValue,
+ EnumTable* aTable,
+ nsHTMLValue& aResult);
+
+ static PRBool EnumValueToString(const nsHTMLValue& aValue,
+ EnumTable* aTable,
+ nsString& aResult);
+
+ static PRBool ParseValueOrPercent(const nsString& aString,
+ nsHTMLValue& aResult,
+ nsHTMLUnit aValueUnit);
+
+ static void ParseValueOrPercentOrProportional(const nsString& aString,
+ nsHTMLValue& aResult,
+ nsHTMLUnit aValueUnit);
+
+ static PRBool ValueOrPercentToString(const nsHTMLValue& aValue,
+ nsString& aResult);
+
+ static PRBool ParseValue(const nsString& aString, PRInt32 aMin,
+ nsHTMLValue& aResult, nsHTMLUnit aValueUnit);
+
+ static PRBool ParseValue(const nsString& aString, PRInt32 aMin, PRInt32 aMax,
+ nsHTMLValue& aResult, nsHTMLUnit aValueUnit);
+
+ static PRBool ParseColor(const nsString& aString, nsHTMLValue& aResult);
+
+ static PRBool ColorToString(const nsHTMLValue& aValue,
+ nsString& aResult);
+
+ // Up pointer to the real content object that we are
+ // supporting. Sometimes there is work that we just can't do
+ // ourselves, so this is needed to ask the real object to do the
+ // work.
+ nsIHTMLContent* mContent;
+
+ nsIDocument* mDocument;
+ nsIContent* mParent;
+ nsIHTMLAttributes* mAttributes;
+ nsIAtom* mTag;
+ void* mScriptObject;
+ nsIEventListenerManager* mListenerManager;
+};
+
+//----------------------------------------------------------------------
+
+struct nsHTMLGenericLeafContent : public nsHTMLGenericContent {
+ nsHTMLGenericLeafContent();
+ ~nsHTMLGenericLeafContent();
+
+ nsresult CopyInnerTo(nsIHTMLContent* aSrcContent,
+ nsHTMLGenericLeafContent* aDest);
+
+ // Remainder of nsIDOMHTMLElement (and nsIDOMNode)
+ nsresult Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn);
+ nsresult GetChildNodes(nsIDOMNodeList** aChildNodes) {
+ *aChildNodes = nsnull;
+ return NS_OK;
+ }
+ nsresult GetHasChildNodes(PRBool* aHasChildNodes) {
+ *aHasChildNodes = PR_FALSE;
+ return NS_OK;
+ }
+ nsresult GetFirstChild(nsIDOMNode** aFirstChild) {
+ *aFirstChild = nsnull;
+ return NS_OK;
+ }
+ nsresult GetLastChild(nsIDOMNode** aLastChild) {
+ *aLastChild = nsnull;
+ return NS_OK;
+ }
+ nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
+ nsIDOMNode** aReturn) {
+ return NS_ERROR_FAILURE;
+ }
+ nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
+ nsIDOMNode** aReturn) {
+ return NS_ERROR_FAILURE;
+ }
+ nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {
+ return NS_ERROR_FAILURE;
+ }
+ nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Remainder of nsIHTMLContent (and nsIContent)
+ nsresult SizeOf(nsISizeOfHandler* aHandler) const;
+ void BeginConvertToXIF(nsXIFConverter& aConverter) const;
+ void ConvertContentToXIF(nsXIFConverter& aConverter) const;
+ void FinishConvertToXIF(nsXIFConverter& aConverter) const;
+ void Compact() {
+ }
+ PRBool CanContainChildren() const {
+ return PR_FALSE;
+ }
+ PRInt32 ChildCount() const {
+ return 0;
+ }
+ nsIContent* ChildAt(PRInt32 aIndex) const {
+ return nsnull;
+ }
+ PRInt32 IndexOf(nsIContent* aPossibleChild) const {
+ return -1;
+ }
+ nsresult InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
+ return NS_OK;
+ }
+ nsresult ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
+ return NS_OK;
+ }
+ nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify) {
+ return NS_OK;
+ }
+ nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
+ return NS_OK;
+ }
+};
+
+//----------------------------------------------------------------------
+
+struct nsHTMLGenericContainerContent : public nsHTMLGenericContent {
+ nsHTMLGenericContainerContent();
+ ~nsHTMLGenericContainerContent();
+
+ nsresult CopyInnerTo(nsIHTMLContent* aSrcContent,
+ nsHTMLGenericLeafContent* aDest);
+
+ // Remainder of nsIDOMHTMLElement (and nsIDOMNode)
+ nsresult Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn);
+ nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
+ nsresult GetHasChildNodes(PRBool* aHasChildNodes);
+ nsresult GetFirstChild(nsIDOMNode** aFirstChild);
+ nsresult GetLastChild(nsIDOMNode** aLastChild);
+ nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
+ nsIDOMNode** aReturn);
+ nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
+ nsIDOMNode** aReturn);
+ nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
+ nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn);
+
+ // Remainder of nsIHTMLContent (and nsIContent)
+ nsresult SizeOf(nsISizeOfHandler* aHandler) const;
+ void BeginConvertToXIF(nsXIFConverter& aConverter) const;
+ void ConvertContentToXIF(nsXIFConverter& aConverter) const;
+ void FinishConvertToXIF(nsXIFConverter& aConverter) const;
+ void Compact();
+ PRBool CanContainChildren() const;
+ PRInt32 ChildCount() const;
+ nsIContent* ChildAt(PRInt32 aIndex) const;
+ PRInt32 IndexOf(nsIContent* aPossibleChild) const;
+ nsresult InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify);
+ nsresult ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify);
+ nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
+ nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify);
+
+ nsVoidArray mChildren;
+};
+
+//----------------------------------------------------------------------
+
+/**
+ * Mostly implement the nsIDOMNode API by forwarding the methods to a
+ * generic content object (either nsHTMLGenericLeafContent or
+ * nsHTMLGenericContainerContent)
+ *
+ * Note that classes using this macro will need to implement:
+ * NS_IMETHOD CloneNode(nsIDOMNode** aReturn);
+ */
+#define NS_IMPL_IDOMNODE_USING_GENERIC(_g) \
+ NS_IMETHOD GetNodeName(nsString& aNodeName) { \
+ return _g.GetNodeName(aNodeName); \
+ } \
+ NS_IMETHOD GetNodeValue(nsString& aNodeValue) { \
+ return _g.GetNodeValue(aNodeValue); \
+ } \
+ NS_IMETHOD SetNodeValue(const nsString& aNodeValue) { \
+ return _g.SetNodeValue(aNodeValue); \
+ } \
+ NS_IMETHOD GetNodeType(PRInt32* aNodeType) { \
+ return _g.GetNodeType(aNodeType); \
+ } \
+ NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) { \
+ return _g.GetParentNode(aParentNode); \
+ } \
+ NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) { \
+ return _g.GetChildNodes(aChildNodes); \
+ } \
+ NS_IMETHOD GetHasChildNodes(PRBool* aHasChildNodes) { \
+ return _g.GetHasChildNodes(aHasChildNodes); \
+ } \
+ NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) { \
+ return _g.GetFirstChild(aFirstChild); \
+ } \
+ NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) { \
+ return _g.GetLastChild(aLastChild); \
+ } \
+ NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) { \
+ return _g.GetPreviousSibling(aPreviousSibling); \
+ } \
+ NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) { \
+ return _g.GetNextSibling(aNextSibling); \
+ } \
+ NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) { \
+ return _g.GetAttributes(aAttributes); \
+ } \
+ NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, \
+ nsIDOMNode** aReturn) { \
+ return _g.InsertBefore(aNewChild, aRefChild, aReturn); \
+ } \
+ NS_IMETHOD AppendChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
+ return _g.AppendChild(aOldChild, aReturn); \
+ } \
+ NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, \
+ nsIDOMNode** aReturn) { \
+ return _g.ReplaceChild(aNewChild, aOldChild, aReturn); \
+ } \
+ NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
+ return _g.RemoveChild(aOldChild, aReturn); \
+ } \
+ NS_IMETHOD Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn) { \
+ return _g.Equals(aNode, aDeep, aReturn); \
+ } \
+ NS_IMETHOD CloneNode(nsIDOMNode** aReturn);
+
+/**
+ * Implement the nsIDOMElement API by forwarding the methods to a
+ * generic content object (either nsHTMLGenericLeafContent or
+ * nsHTMLGenericContainerContent)
+ */
+#define NS_IMPL_IDOMELEMENT_USING_GENERIC(_g) \
+ NS_IMETHOD GetTagName(nsString& aTagName) { \
+ return _g.GetTagName(aTagName); \
+ } \
+ NS_IMETHOD GetDOMAttribute(const nsString& aName, nsString& aReturn) { \
+ return _g.GetDOMAttribute(aName, aReturn); \
+ } \
+ NS_IMETHOD SetDOMAttribute(const nsString& aName, const nsString& aValue) { \
+ return _g.SetDOMAttribute(aName, aValue); \
+ } \
+ NS_IMETHOD RemoveAttribute(const nsString& aName) { \
+ return _g.RemoveAttribute(aName); \
+ } \
+ NS_IMETHOD GetAttributeNode(const nsString& aName, \
+ nsIDOMAttribute** aReturn) { \
+ return _g.GetAttributeNode(aName, aReturn); \
+ } \
+ NS_IMETHOD SetAttributeNode(nsIDOMAttribute* aNewAttr) { \
+ return _g.SetAttributeNode(aNewAttr); \
+ } \
+ NS_IMETHOD RemoveAttributeNode(nsIDOMAttribute* aOldAttr) { \
+ return _g.RemoveAttributeNode(aOldAttr); \
+ } \
+ NS_IMETHOD GetElementsByTagName(const nsString& aTagname, \
+ nsIDOMNodeList** aReturn) { \
+ return _g.GetElementsByTagName(aTagname, aReturn); \
+ } \
+ NS_IMETHOD Normalize() { \
+ return _g.Normalize(); \
+ }
+
+/**
+ * Implement the nsIDOMHTMLElement API by forwarding the methods to a
+ * generic content object (either nsHTMLGenericLeafContent or
+ * nsHTMLGenericContainerContent)
+ */
+#define NS_IMPL_IDOMHTMLELEMENT_USING_GENERIC(_g) \
+ NS_IMETHOD GetId(nsString& aId) { \
+ return _g.GetId(aId); \
+ } \
+ NS_IMETHOD SetId(const nsString& aId) { \
+ return _g.SetId(aId); \
+ } \
+ NS_IMETHOD GetTitle(nsString& aTitle) { \
+ return _g.GetTitle(aTitle); \
+ } \
+ NS_IMETHOD SetTitle(const nsString& aTitle) { \
+ return _g.SetTitle(aTitle); \
+ } \
+ NS_IMETHOD GetLang(nsString& aLang) { \
+ return _g.GetLang(aLang); \
+ } \
+ NS_IMETHOD SetLang(const nsString& aLang) { \
+ return _g.SetLang(aLang); \
+ } \
+ NS_IMETHOD GetDir(nsString& aDir) { \
+ return _g.GetDir(aDir); \
+ } \
+ NS_IMETHOD SetDir(const nsString& aDir) { \
+ return _g.SetDir(aDir); \
+ } \
+ NS_IMETHOD GetClassName(nsString& aClassName) { \
+ return _g.GetClassName(aClassName); \
+ } \
+ NS_IMETHOD SetClassName(const nsString& aClassName) { \
+ return _g.SetClassName(aClassName); \
+ }
+
+/**
+ * Implement the nsIDOMEventReceiver API by forwarding the methods to a
+ * generic content object (either nsHTMLGenericLeafContent or
+ * nsHTMLGenericContainerContent)
+ */
+#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(_g) \
+ NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, \
+ const nsIID& aIID) { \
+ return _g.AddEventListener(aListener, aIID); \
+ } \
+ NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, \
+ const nsIID& aIID) { \
+ return _g.RemoveEventListener(aListener, aIID); \
+ } \
+ NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
+ return _g.GetListenerManager(aResult); \
+ } \
+ NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
+ return _g.GetNewListenerManager(aResult); \
+ }
+
+/**
+ * Implement the nsIScriptObjectOwner API by forwarding the methods to a
+ * generic content object (either nsHTMLGenericLeafContent or
+ * nsHTMLGenericContainerContent)
+ */
+#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(_g) \
+ NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \
+ void** aScriptObject) { \
+ return _g.GetScriptObject(aContext, aScriptObject); \
+ } \
+ NS_IMETHOD ResetScriptObject() { \
+ return _g.ResetScriptObject(); \
+ }
+
+#define NS_IMPL_ICONTENT_USING_GENERIC(_g) \
+ NS_IMETHOD GetDocument(nsIDocument*& aResult) const { \
+ return _g.GetDocument(aResult); \
+ } \
+ virtual void SetDocument(nsIDocument* aDocument) { \
+ _g.SetDocument(aDocument); \
+ } \
+ virtual nsIContent* GetParent() const { \
+ return _g.GetParent(); \
+ } \
+ virtual void SetParent(nsIContent* aParent) { \
+ _g.SetParent(aParent); \
+ } \
+ virtual PRBool CanContainChildren() const { \
+ return _g.CanContainChildren(); \
+ } \
+ virtual PRInt32 ChildCount() const { \
+ return _g.ChildCount(); \
+ } \
+ virtual nsIContent* ChildAt(PRInt32 aIndex) const { \
+ return _g.ChildAt(aIndex); \
+ } \
+ virtual PRInt32 IndexOf(nsIContent* aPossibleChild) const { \
+ return _g.IndexOf(aPossibleChild); \
+ } \
+ NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex, \
+ PRBool aNotify) { \
+ return _g.InsertChildAt(aKid, aIndex, aNotify); \
+ } \
+ NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, \
+ PRBool aNotify) { \
+ return _g.ReplaceChildAt(aKid, aIndex, aNotify); \
+ } \
+ NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) { \
+ return _g.AppendChildTo(aKid, aNotify); \
+ } \
+ NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { \
+ return _g.RemoveChildAt(aIndex, aNotify); \
+ } \
+ NS_IMETHOD IsSynthetic(PRBool& aResult) { \
+ return _g.IsSynthetic(aResult); \
+ } \
+ virtual nsIAtom* GetTag() const { \
+ return _g.GetTag(); \
+ } \
+ virtual void SetAttribute(const nsString& aName, const nsString& aValue) { \
+ _g.SetAttribute(aName, aValue); \
+ } \
+ virtual nsContentAttr GetAttribute(const nsString& aName, \
+ nsString& aResult) const { \
+ return _g.GetAttribute(aName, aResult); \
+ } \
+ virtual nsIContentDelegate* GetDelegate(nsIPresContext* aCX) { \
+ return _g.GetDelegate(aCX); \
+ } \
+ virtual void List(FILE* out, PRInt32 aIndent) const { \
+ _g.List(out, aIndent); \
+ } \
+ virtual void BeginConvertToXIF(nsXIFConverter& aConverter) const { \
+ _g.BeginConvertToXIF(aConverter); \
+ } \
+ virtual void ConvertContentToXIF(nsXIFConverter& aConverter) const { \
+ _g.ConvertContentToXIF(aConverter); \
+ } \
+ virtual void FinishConvertToXIF(nsXIFConverter& aConverter) const { \
+ _g.FinishConvertToXIF(aConverter); \
+ } \
+ NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const { \
+ return _g.SizeOf(aHandler); \
+ } \
+ NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, \
+ nsEvent* aEvent, \
+ nsIDOMEvent** aDOMEvent, \
+ PRUint32 aFlags, \
+ nsEventStatus& aEventStatus) { \
+ return _g.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, \
+ aEventStatus); \
+ }
+
+#define NS_IMPL_IHTMLCONTENT_USING_GENERIC(_g) \
+ virtual void Compact() { \
+ _g.Compact(); \
+ } \
+ virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue) { \
+ _g.SetAttribute(aAttribute, aValue); \
+ } \
+ virtual void SetAttribute(nsIAtom* aAttribute, \
+ const nsHTMLValue& aValue) { \
+ _g.SetAttribute(aAttribute, aValue); \
+ } \
+ virtual void UnsetAttribute(nsIAtom* aAttribute) { \
+ _g.UnsetAttribute(aAttribute); \
+ } \
+ virtual nsContentAttr GetAttribute(nsIAtom *aAttribute, \
+ nsString &aResult) const { \
+ return _g.GetAttribute(aAttribute, aResult); \
+ } \
+ virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, \
+ nsHTMLValue& aValue) const { \
+ return _g.GetAttribute(aAttribute, aValue); \
+ } \
+ virtual PRInt32 GetAllAttributeNames(nsISupportsArray* aArray) const { \
+ return _g.GetAllAttributeNames(aArray); \
+ } \
+ virtual PRInt32 GetAttributeCount(void) const { \
+ return _g.GetAttributeCount(); \
+ } \
+ virtual void SetID(nsIAtom* aID) { \
+ _g.SetID(aID); \
+ } \
+ virtual nsIAtom* GetID() const { \
+ return _g.GetID(); \
+ } \
+ virtual void SetClass(nsIAtom* aClass) { \
+ _g.SetClass(aClass); \
+ } \
+ virtual nsIAtom* GetClass() const { \
+ return _g.GetClass(); \
+ } \
+ virtual nsIStyleRule* GetStyleRule() { \
+ return _g.GetStyleRule(); \
+ } \
+ virtual void ToHTMLString(nsString& aResult) const { \
+ _g.ToHTMLString(aResult); \
+ } \
+ virtual void ToHTML(FILE* out) const { \
+ _g.ToHTML(out); \
+ } \
+ virtual nsresult CreateFrame(nsIPresContext* aPresContext, \
+ nsIFrame* aParentFrame, \
+ nsIStyleContext* aStyleContext, \
+ nsIFrame*& aResult) { \
+ return _g.CreateFrame(aPresContext, aParentFrame, aStyleContext, \
+ aResult); \
+ } \
+ virtual nsContentAttr StringToAttribute(nsIAtom* aAttribute, \
+ const nsString& aValue, \
+ nsHTMLValue& aResult); \
+ virtual nsContentAttr AttributeToString(nsIAtom* aAttribute, \
+ nsHTMLValue& aValue, \
+ nsString& aResult) const; \
+ virtual void MapAttributesInto(nsIStyleContext* aContext, \
+ nsIPresContext* aPresContext);
+
+/**
+ * This macro implements the portion of query interface that is
+ * generic to all html content objects.
+ */
+#define NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(_id, _iptr, _this) \
+ if (_id.Equals(kISupportsIID)) { \
+ nsIHTMLContent* tmp = _this; \
+ nsISupports* tmp2 = tmp; \
+ *_iptr = (void*) tmp2; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIDOMNodeIID)) { \
+ nsIDOMNode* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIDOMElementIID)) { \
+ nsIDOMElement* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIDOMHTMLElementIID)) { \
+ nsIDOMHTMLElement* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIDOMEventReceiverIID)) { \
+ nsIDOMEventReceiver* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIScriptObjectOwnerIID)) { \
+ nsIScriptObjectOwner* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIContentIID)) { \
+ nsIContent* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ } \
+ if (_id.Equals(kIHTMLContentIID)) { \
+ nsIHTMLContent* tmp = _this; \
+ *_iptr = (void*) tmp; \
+ mRefCnt++; \
+ return NS_OK; \
+ }
+
+#endif /* nsHTMLLeafContent_h___ */
diff --git a/mozilla/layout/html/content/src/nsHTMLHR.cpp b/mozilla/layout/html/content/src/nsHTMLHR.cpp
new file mode 100644
index 00000000000..1f5ee61b027
--- /dev/null
+++ b/mozilla/layout/html/content/src/nsHTMLHR.cpp
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are Copyright (C) 1998
+ * Netscape Communications Corporation. All Rights Reserved.
+ */
+#include "nsIDOMHTMLHRElement.h"
+#include "nsIScriptObjectOwner.h"
+#include "nsIDOMEventReceiver.h"
+#include "nsIHTMLContent.h"
+#include "nsHTMLGenericContent.h"
+#include "nsHTMLAtoms.h"
+#include "nsHTMLIIDs.h"
+#include "nsIStyleContext.h"
+#include "nsStyleConsts.h"
+#include "nsIPresContext.h"
+
+static NS_DEFINE_IID(kIDOMHTMLHRElementIID, NS_IDOMHTMLHRELEMENT_IID);
+
+class nsHTMLHR : public nsIDOMHTMLHRElement,
+ public nsIScriptObjectOwner,
+ public nsIDOMEventReceiver,
+ public nsIHTMLContent
+{
+public:
+ nsHTMLHR(nsIAtom* aTag);
+ ~nsHTMLHR();
+
+ // nsISupports
+ NS_DECL_ISUPPORTS
+
+ // nsIDOMNode
+ NS_IMPL_IDOMNODE_USING_GENERIC(mInner)
+
+ // nsIDOMElement
+ NS_IMPL_IDOMELEMENT_USING_GENERIC(mInner)
+
+ // nsIDOMHTMLElement
+ NS_IMPL_IDOMHTMLELEMENT_USING_GENERIC(mInner)
+
+ // nsIDOMHTMLHRElement
+ NS_IMETHOD GetAlign(nsString& aAlign);
+ NS_IMETHOD SetAlign(const nsString& aAlign);
+ NS_IMETHOD GetNoShade(PRBool* aNoShade);
+ NS_IMETHOD SetNoShade(PRBool aNoShade);
+ NS_IMETHOD GetSize(nsString& aSize);
+ NS_IMETHOD SetSize(const nsString& aSize);
+ NS_IMETHOD GetWidth(nsString& aWidth);
+ NS_IMETHOD SetWidth(const nsString& aWidth);
+
+ // nsIScriptObjectOwner
+ NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
+
+ // nsIDOMEventReceiver
+ NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(mInner)
+
+ // nsIContent
+ NS_IMPL_ICONTENT_USING_GENERIC(mInner)
+
+ // nsIHTMLContent
+ NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
+
+protected:
+ nsHTMLGenericLeafContent mInner;
+};
+
+nsHTMLHR::nsHTMLHR(nsIAtom* aTag)
+{
+ mInner.Init(this, aTag);
+}
+
+nsHTMLHR::~nsHTMLHR()
+{
+}
+
+NS_IMPL_ADDREF(nsHTMLHR)
+
+NS_IMPL_RELEASE(nsHTMLHR)
+
+nsresult
+nsHTMLHR::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+ NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
+ if (aIID.Equals(kIDOMHTMLHRElementIID)) {
+ nsIDOMHTMLHRElement* tmp = this;
+ *aInstancePtr = (void*) tmp;
+ mRefCnt++;
+ return NS_OK;
+ }
+ return NS_NOINTERFACE;
+}
+
+
+nsresult
+nsHTMLHR::CloneNode(nsIDOMNode** aReturn)
+{
+ nsHTMLHR* it = new nsHTMLHR(mInner.mTag);
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mInner.CopyInnerTo(this, &it->mInner);
+ return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
+}
+
+NS_IMETHODIMP
+nsHTMLHR::GetAlign(nsString& aAlign) {
+ mInner.GetAttribute(nsHTMLAtoms::align, aAlign);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::SetAlign(const nsString& aAlign) {
+ mInner.SetAttribute(nsHTMLAtoms::align, aAlign);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::GetNoShade(PRBool* aNoShade)
+{
+ nsHTMLValue val;
+ *aNoShade =
+ eContentAttr_HasValue == mInner.GetAttribute(nsHTMLAtoms::noshade, val);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::SetNoShade(PRBool aNoShade)
+{
+ nsAutoString empty;
+ mInner.SetAttribute(nsHTMLAtoms::noshade, empty);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::GetSize(nsString& aSize)
+{
+ mInner.GetAttribute(nsHTMLAtoms::size, aSize);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::SetSize(const nsString& aSize)
+{
+ mInner.SetAttribute(nsHTMLAtoms::size, aSize);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::GetWidth(nsString& aWidth)
+{
+ mInner.GetAttribute(nsHTMLAtoms::width, aWidth);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLHR::SetWidth(const nsString& aWidth)
+{
+ mInner.SetAttribute(nsHTMLAtoms::width, aWidth);
+ return NS_OK;
+}
+
+static nsHTMLGenericContent::EnumTable kAlignTable[] = {
+ { "left", NS_STYLE_TEXT_ALIGN_LEFT },
+ { "right", NS_STYLE_TEXT_ALIGN_RIGHT },
+ { "center", NS_STYLE_TEXT_ALIGN_CENTER },
+ { 0 }
+};
+
+nsContentAttr
+nsHTMLHR::StringToAttribute(nsIAtom* aAttribute,
+ const nsString& aValue,
+ nsHTMLValue& aResult)
+{
+ if (aAttribute == nsHTMLAtoms::width) {
+ nsHTMLGenericContent::ParseValueOrPercent(aValue, aResult,
+ eHTMLUnit_Pixel);
+ return eContentAttr_HasValue;
+ }
+ else if (aAttribute == nsHTMLAtoms::size) {
+ nsHTMLGenericContent::ParseValue(aValue, 1, 100, aResult, eHTMLUnit_Pixel);
+ return eContentAttr_HasValue;
+ }
+ else if (aAttribute == nsHTMLAtoms::noshade) {
+ aResult.SetEmptyValue();
+ return eContentAttr_HasValue;
+ }
+ else if (aAttribute == nsHTMLAtoms::align) {
+ if (nsHTMLGenericContent::ParseEnumValue(aValue, kAlignTable, aResult)) {
+ return eContentAttr_HasValue;
+ }
+ }
+ return eContentAttr_NotThere;
+}
+
+nsContentAttr
+nsHTMLHR::AttributeToString(nsIAtom* aAttribute,
+ nsHTMLValue& aValue,
+ nsString& aResult) const
+{
+ if (aAttribute == nsHTMLAtoms::align) {
+ if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
+ nsHTMLGenericContent::EnumValueToString(aValue, kAlignTable, aResult);
+ return eContentAttr_HasValue;
+ }
+ }
+ return mInner.AttributeToString(aAttribute, aValue, aResult);
+}
+
+void
+nsHTMLHR::MapAttributesInto(nsIStyleContext* aContext,
+ nsIPresContext* aPresContext)
+{
+ if (nsnull != mInner.mAttributes) {
+ nsHTMLValue value;
+ // align: enum
+ GetAttribute(nsHTMLAtoms::align, value);
+ if (value.GetUnit() == eHTMLUnit_Enumerated) {
+ nsStyleText* text = (nsStyleText*)
+ aContext->GetMutableStyleData(eStyleStruct_Text);
+ text->mTextAlign = value.GetIntValue();
+ }
+
+ // width: pixel, percent
+ float p2t = aPresContext->GetPixelsToTwips();
+ nsStylePosition* pos = (nsStylePosition*)
+ aContext->GetMutableStyleData(eStyleStruct_Position);
+ GetAttribute(nsHTMLAtoms::width, value);
+ if (value.GetUnit() == eHTMLUnit_Pixel) {
+ nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t);
+ pos->mWidth.SetCoordValue(twips);
+ }
+ else if (value.GetUnit() == eHTMLUnit_Percent) {
+ pos->mWidth.SetPercentValue(value.GetPercentValue());
+ }
+ }
+}
+
+nsresult
+NS_NewHTMLHR(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
+{
+ NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
+ if (nsnull == aInstancePtrResult) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsIHTMLContent* it = new nsHTMLHR(aTag);
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
+}