Mozilla/mozilla/layout/html/content/src/nsHTMLTableRowElement.cpp
jst%netscape.com 96aefc9b5d Landing changes Vidur made while the tree was closed for beta1 work, here's a list of the changes. r=me
[1] Cutting down the size of content. Made nsIJSScriptObject inherit from nsIScriptObjectOwner
[2] Cutting down the size of content. Made nsITextContent inherit from nsIContent.
[3] Cutting down the size of content. Moved implementation of nsIDOMReceiver to nsListenerManager. This is not true aggregation since it isn't transitive, but it's OK for now. It will be necessary for nsListenerManager to have a reference to its content in the future anyway, so the transitivity could be done.

dom/public/nsDOMPropEnums.h,v  - bug 12559
dom/public/nsIJSScriptObject.h,v - [1]
dom/public/html/MANIFEST,v - bug 12559
dom/public/html/Makefile.in,v - bug 12559
dom/public/html/makefile.win,v -  bug 12559
dom/public/html/nsIDOMHTMLInputElement.h,v - bug 17544
dom/public/idl/html/HTMLAnchorElement.idl,v - bug 12559
dom/public/idl/html/HTMLAreaElement.idl,v - bug 12559
dom/public/idl/html/HTMLInputElement.idl,v - bug 17544
dom/src/base/nsGlobalWindow.cpp,v - bug 30700
dom/src/base/nsGlobalWindow.h,v - [1]
dom/src/base/nsLocation.cpp,v - [1]
dom/src/html/nsJSHTMLAnchorElement.cpp,v - bug 12559
dom/src/html/nsJSHTMLAreaElement.cpp,v - bug 12559
dom/src/html/nsJSHTMLInputElement.cpp,v - bug 17544
layout/base/public/nsIDocument.h,v - bug 27953
layout/base/public/nsITextContent.h,v - [2]
layout/base/src/nsCommentNode.cpp,v - [2]
layout/base/src/nsDocument.cpp,v - bug 27953
layout/base/src/nsDocument.h,v - bug 27953
layout/base/src/nsDocumentViewer.cpp,v - bug 27953
layout/base/src/nsGenericDOMDataNode.cpp,v - [3]
layout/base/src/nsGenericDOMDataNode.h,v - [3]
layout/base/src/nsGenericElement.cpp,v - [3]
layout/base/src/nsGenericElement.h,v - [3]
layout/base/src/nsNameSpaceManager.cpp,v - bug 7834
layout/base/src/nsStyleContext.cpp,v - outline property shouldn't reflow
layout/base/src/nsTextNode.cpp,v - [2]
layout/events/src/nsEventListenerManager.cpp,v - [3]
layout/events/src/nsEventListenerManager.h,v - [3]
layout/html/base/src/nsGfxScrollFrame.cpp,v - nsString->nsAutoString
layout/html/content/src/nsAttributeContent.cpp,v - [2]
layout/html/content/src/nsHTMLAnchorElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLAppletElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLAreaElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLBRElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLBaseElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLBaseFontElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLBodyElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLButtonElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLDListElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLDelElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLDirectoryElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLDivElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLEmbedElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLFieldSetElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLFontElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLFormElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLFrameElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLFrameSetElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLHRElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLHeadElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLHeadingElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLHtmlElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLIFrameElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLImageElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLInputElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLInsElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLIsIndexElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLLIElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLLabelElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLLayerElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLLegendElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLLinkElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLMapElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLMenuElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLMetaElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLModElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLOListElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLObjectElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLOptGroupElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLOptionElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLParagraphElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLParamElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLPreElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLQuoteElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLScriptElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLSelectElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLSpacerElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLSpanElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLStyleElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableCaptionElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableCellElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableColElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableColGroupElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableRowElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTableSectionElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTextAreaElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLTitleElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLUListElement.cpp,v - [1][3]
layout/html/content/src/nsHTMLWBRElement.cpp,v - [1][3]
layout/html/document/src/nsHTMLDocument.cpp,v - bug 27953
layout/html/document/src/nsHTMLDocument.h,v - bug 27953
layout/xml/content/src/nsXMLCDATASection.cpp,v - [1][2]
layout/xml/content/src/nsXMLDocumentType.cpp,v - [1][2]
layout/xml/content/src/nsXMLElement.h,v - [1][2]
layout/xml/content/src/nsXMLEntity.cpp,v - [1][2]
layout/xml/content/src/nsXMLNotation.cpp,v - [1][2]
layout/xml/content/src/nsXMLProcessingInstruction.cpp,v - [1][2]
layout/xul/base/src/nsBoxFrame.cpp,v - nsString->nsAutoString
layout/xul/base/src/nsSliderFrame.cpp,v - nsString->nsAutoString
netwerk/protocol/http/src/nsHTTPRequest.cpp,v - nsString->nsAutoString
rdf/content/src/nsXULDocument.cpp,v - bug 27953
rdf/content/src/nsXULDocument.h,v - bug 27953
rdf/content/src/nsXULElement.h,v - [1]
xpcom/base/IIDS.h,v  - bug 12559


git-svn-id: svn://10.0.0.236/trunk@63290 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-17 13:27:00 +00:00

756 lines
22 KiB
C++

/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIDOMHTMLTableRowElement.h"
#include "nsIDOMHTMLTableElement.h"
#include "nsIDOMHTMLTableSectionElement.h"
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
#include "GenericElementCollection.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsIStyleContext.h"
#include "nsIMutableStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsHTMLParts.h"
// temporary
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIFrame.h"
static NS_DEFINE_IID(kIDOMHTMLTableRowElementIID, NS_IDOMHTMLTABLEROWELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableElementIID, NS_IDOMHTMLTABLEELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableSectionElementIID, NS_IDOMHTMLTABLESECTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableCellElementIID, NS_IDOMHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
// nsTableCellCollection is needed because GenericElementCollection
// only supports element of a single tag. This collection supports
// elements <td> or <th> elements.
class nsTableCellCollection : public GenericElementCollection
{
public:
nsTableCellCollection(nsIContent* aParent,
nsIAtom* aTag);
~nsTableCellCollection();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
};
nsTableCellCollection::nsTableCellCollection(nsIContent* aParent,
nsIAtom* aTag)
: GenericElementCollection(aParent, aTag)
{
}
nsTableCellCollection::~nsTableCellCollection()
{
}
NS_IMETHODIMP
nsTableCellCollection::GetLength(PRUint32* aLength)
{
if (!aLength) {
return NS_ERROR_NULL_POINTER;
}
*aLength = 0;
nsresult result = NS_OK;
if (mParent) {
nsIContent* child = nsnull;
PRUint32 childIndex = 0;
mParent->ChildAt(childIndex, child);
while (child) {
nsIAtom* childTag;
child->GetTag(childTag);
if ((nsHTMLAtoms::td ==childTag) || (nsHTMLAtoms::th ==childTag)) {
(*aLength)++;
}
NS_RELEASE(childTag);
NS_RELEASE(child);
childIndex++;
mParent->ChildAt(childIndex, child);
}
}
return result;
}
NS_IMETHODIMP
nsTableCellCollection::Item(PRUint32 aIndex,
nsIDOMNode** aReturn)
{
*aReturn = nsnull;
PRUint32 theIndex = 0;
nsresult rv = NS_OK;
if (mParent) {
nsIContent* child = nsnull;
PRUint32 childIndex = 0;
mParent->ChildAt(childIndex, child);
while (child) {
nsIAtom* childTag;
child->GetTag(childTag);
if ((nsHTMLAtoms::td ==childTag) || (nsHTMLAtoms::th ==childTag)) {
if (aIndex == theIndex) {
child->QueryInterface(kIDOMNodeIID, (void**)aReturn); // out-param addref
NS_ASSERTION(aReturn, "content element must be an nsIDOMNode");
NS_RELEASE(childTag);
NS_RELEASE(child);
break;
}
theIndex++;
}
NS_RELEASE(childTag);
NS_RELEASE(child);
childIndex++;
mParent->ChildAt(childIndex, child);
}
}
return rv;
}
//----------------------------------------------------------------------
class nsHTMLTableRowElement : public nsIDOMHTMLTableRowElement,
public nsIJSScriptObject,
public nsIHTMLContent
{
public:
nsHTMLTableRowElement(nsIAtom* aTag);
virtual ~nsHTMLTableRowElement();
// 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)
// nsIDOMHTMLTableRowElement
NS_IMETHOD GetRowIndex(PRInt32* aRowIndex);
NS_IMETHOD SetRowIndex(PRInt32 aRowIndex);
NS_IMETHOD GetSectionRowIndex(PRInt32* aSectionRowIndex);
NS_IMETHOD SetSectionRowIndex(PRInt32 aSectionRowIndex);
NS_IMETHOD GetCells(nsIDOMHTMLCollection** aCells);
NS_IMETHOD SetCells(nsIDOMHTMLCollection* aCells);
NS_IMETHOD GetAlign(nsString& aAlign);
NS_IMETHOD SetAlign(const nsString& aAlign);
NS_IMETHOD GetBgColor(nsString& aBgColor);
NS_IMETHOD SetBgColor(const nsString& aBgColor);
NS_IMETHOD GetCh(nsString& aCh);
NS_IMETHOD SetCh(const nsString& aCh);
NS_IMETHOD GetChOff(nsString& aChOff);
NS_IMETHOD SetChOff(const nsString& aChOff);
NS_IMETHOD GetVAlign(nsString& aVAlign);
NS_IMETHOD SetVAlign(const nsString& aVAlign);
NS_IMETHOD InsertCell(PRInt32 aIndex, nsIDOMHTMLElement** aReturn);
NS_IMETHOD DeleteCell(PRInt32 aIndex);
// nsIJSScriptObject
NS_IMPL_IJSSCRIPTOBJECT_USING_GENERIC(mInner)
// nsIContent
NS_IMPL_ICONTENT_USING_GENERIC(mInner)
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
protected:
nsresult GetSection(nsIDOMHTMLTableSectionElement** aSection);
nsresult GetTable(nsIDOMHTMLTableElement** aTable);
nsGenericHTMLContainerElement mInner;
nsTableCellCollection* mCells;
};
#ifdef XXX_debugging
static
void DebugList(nsIDOMHTMLTableElement* aTable) {
nsIHTMLContent* content = nsnull;
nsresult result = aTable->QueryInterface(kIHTMLContentIID, (void**)&content);
if (NS_SUCCEEDED(result) && (nsnull != content)) {
nsIDocument* doc = nsnull;
result = content->GetDocument(doc);
if (NS_SUCCEEDED(result) && (nsnull != doc)) {
nsIContent* root = doc->GetRootContent();
if (root) {
root->List();
}
nsIPresShell* shell = doc->GetShellAt(0);
if (nsnull != shell) {
nsIFrame* rootFrame;
shell->GetRootFrame(rootFrame);
if (nsnull != rootFrame) {
rootFrame->List(stdout, 0);
}
}
NS_RELEASE(shell);
NS_RELEASE(doc);
}
NS_RELEASE(content);
}
}
#endif
nsresult
NS_NewHTMLTableRowElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsHTMLTableRowElement(aTag);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsHTMLTableRowElement::nsHTMLTableRowElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mCells = nsnull;
}
nsHTMLTableRowElement::~nsHTMLTableRowElement()
{
if (nsnull != mCells) {
mCells->ParentDestroyed();
NS_RELEASE(mCells);
}
}
NS_IMPL_ADDREF(nsHTMLTableRowElement)
NS_IMPL_RELEASE(nsHTMLTableRowElement)
nsresult
nsHTMLTableRowElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLTableRowElementIID)) {
nsIDOMHTMLTableRowElement* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
nsHTMLTableRowElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsHTMLTableRowElement* it = new nsHTMLTableRowElement(mInner.mTag);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
mInner.CopyInnerTo(this, &it->mInner, aDeep);
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
// protected method
nsresult
nsHTMLTableRowElement::GetSection(nsIDOMHTMLTableSectionElement** aSection)
{
*aSection = nsnull;
if (nsnull == aSection) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsIDOMNode *sectionNode = nsnull;
nsresult result = GetParentNode(&sectionNode);
if (NS_SUCCEEDED(result) && (nsnull != sectionNode)) {
result = sectionNode->QueryInterface(kIDOMHTMLTableSectionElementIID, (void**)aSection);
NS_RELEASE(sectionNode);
}
return result;
}
// protected method
nsresult
nsHTMLTableRowElement::GetTable(nsIDOMHTMLTableElement** aTable)
{
*aTable = nsnull;
if (nsnull == aTable) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsIDOMNode *sectionNode = nsnull;
nsresult result = GetParentNode(&sectionNode);
if (NS_SUCCEEDED(result) && (nsnull != sectionNode)) {
nsIDOMNode *tableNode = nsnull;
result = sectionNode->GetParentNode(&tableNode);
if (NS_SUCCEEDED(result) && (nsnull != tableNode)) {
result = tableNode->QueryInterface(kIDOMHTMLTableElementIID, (void**)aTable);
NS_RELEASE(tableNode);
}
NS_RELEASE(sectionNode);
}
return result;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetRowIndex(PRInt32* aValue)
{
*aValue = -1;
nsIDOMHTMLTableElement* table = nsnull;
nsresult result = GetTable(&table);
if (NS_SUCCEEDED(result) && (nsnull != table)) {
nsIDOMHTMLCollection *rows = nsnull;
table->GetRows(&rows);
PRUint32 numRows;
rows->GetLength(&numRows);
PRBool found = PR_FALSE;
for (PRUint32 i = 0; (i < numRows) && !found; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
found = PR_TRUE;
}
NS_IF_RELEASE(node);
}
NS_RELEASE(rows);
NS_RELEASE(table);
}
return result;
}
// this tells the table to delete a row and then insert it in a different place. This will generate 2 reflows
// until things get fixed at a higher level (e.g. DOM batching).
NS_IMETHODIMP
nsHTMLTableRowElement::SetRowIndex(PRInt32 aValue)
{
PRInt32 oldIndex;
nsresult result = GetRowIndex(&oldIndex);
if ((-1 == oldIndex) || (oldIndex == aValue) || (NS_OK != result)) {
return result;
}
nsIDOMHTMLTableElement* table = nsnull;
result = GetTable(&table);
if (NS_FAILED(result) || (nsnull == table)) {
return result;
}
nsIDOMHTMLCollection *rows = nsnull;
table->GetRows(&rows);
PRUint32 numRowsU;
rows->GetLength(&numRowsU);
PRInt32 numRows = numRowsU; // numRows will be > 0 since this must be a row
// check if it really moves
if ( !(((0 == oldIndex) && (aValue <= 0)) || ((numRows-1 == oldIndex) && (aValue >= numRows-1)))) {
nsIDOMNode *section = nsnull;
nsIDOMNode* refRow = nsnull;
PRInt32 refIndex = aValue;
if (aValue < numRows) {
refIndex = 0;
} else {
refIndex = numRows-1;
}
rows->Item(refIndex, &refRow);
refRow->GetParentNode(&section);
AddRef(); // don't use NS_ADDREF_THIS
table->DeleteRow(oldIndex); // delete this from the table
nsIDOMNode *returnNode;
if (aValue >= numRows) {
section->AppendChild(this, &returnNode); // add this back into the table
} else {
section->InsertBefore(this, refRow, &returnNode); // add this back into the table
}
Release(); // from addref above, can't use NS_RELEASE
NS_RELEASE(section);
NS_RELEASE(refRow); // XXX is this right, check nsHTMLTableElement also
}
NS_RELEASE(rows);
NS_RELEASE(table);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetSectionRowIndex(PRInt32* aValue)
{
*aValue = -1;
nsIDOMHTMLTableSectionElement* section = nsnull;
nsresult result = GetSection(&section);
if (NS_SUCCEEDED(result) && (nsnull != section)) {
nsIDOMHTMLCollection *rows = nsnull;
section->GetRows(&rows);
PRUint32 numRows;
rows->GetLength(&numRows);
PRBool found = PR_FALSE;
for (PRUint32 i = 0; (i < numRows) && !found; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
found = PR_TRUE;
}
NS_IF_RELEASE(node);
}
NS_RELEASE(rows);
NS_RELEASE(section);
}
return NS_OK;
}
// this generates 2 reflows like SetRowIndex
NS_IMETHODIMP
nsHTMLTableRowElement::SetSectionRowIndex(PRInt32 aValue)
{
PRInt32 oldIndex;
nsresult result = GetRowIndex(&oldIndex);
if ((-1 == oldIndex) || (oldIndex == aValue) || (NS_OK != result)) {
return result;
}
nsIDOMHTMLTableSectionElement* section = nsnull;
result = GetSection(&section);
if (NS_FAILED(result) || (nsnull == section)) {
return result;
}
nsIDOMHTMLCollection *rows = nsnull;
section->GetRows(&rows);
PRUint32 numRowsU;
rows->GetLength(&numRowsU);
PRInt32 numRows = numRowsU;
// check if it really moves
if ( !(((0 == oldIndex) && (aValue <= 0)) || ((numRows-1 == oldIndex) && (aValue >= numRows-1)))) {
AddRef(); // don't use NS_ADDREF_THIS
section->DeleteRow(oldIndex); // delete this from the section
numRows--;
nsIDOMNode *returnNode;
if ((numRows <= 0) || (aValue >= numRows)) {
section->AppendChild(this, &returnNode); // add this back into the section
} else {
PRInt32 newIndex = aValue;
if (aValue <= 0) {
newIndex = 0;
} else if (aValue > oldIndex) {
newIndex--; // since this got removed before GetLength was called
}
nsIDOMNode *refNode;
rows->Item(newIndex, &refNode);
section->InsertBefore(this, refNode, &returnNode); // add this back into the section
NS_IF_RELEASE(refNode);
}
Release(); // from addref above, can't use NS_RELEASE
}
NS_RELEASE(rows);
NS_RELEASE(section);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetCells(nsIDOMHTMLCollection** aValue)
{
if (nsnull == mCells) {
mCells = new nsTableCellCollection(this, nsHTMLAtoms::td);
NS_ADDREF(mCells); // this table's reference, released in the destructor
}
mCells->QueryInterface(kIDOMHTMLCollectionIID, (void **)aValue); // caller's addref
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::SetCells(nsIDOMHTMLCollection* aValue)
{
nsIDOMHTMLCollection* cells;
GetCells(&cells);
PRUint32 numCells;
cells->GetLength(&numCells);
PRUint32 i;
for (i = 0; i < numCells; i++) {
DeleteCell(i);
}
aValue->GetLength(&numCells);
for (i = 0; i < numCells; i++) {
nsIDOMNode *node = nsnull;
cells->Item(i, &node);
nsIDOMNode* aReturn;
AppendChild(node, (nsIDOMNode**)&aReturn);
}
NS_RELEASE(cells);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::InsertCell(PRInt32 aIndex, nsIDOMHTMLElement** aValue)
{
*aValue = nsnull;
PRInt32 refIndex = (0 <= aIndex) ? aIndex : 0;
nsIDOMHTMLCollection *cells;
GetCells(&cells);
PRUint32 cellCount;
cells->GetLength(&cellCount);
if (cellCount <= PRUint32(aIndex)) {
refIndex = cellCount - 1; // refIndex will be -1 if there are no cells
}
// create the cell
nsIHTMLContent *cellContent = nsnull;
nsresult rv = NS_NewHTMLTableCellElement(&cellContent, nsHTMLAtoms::td);
if (NS_SUCCEEDED(rv) && (nsnull != cellContent)) {
nsIDOMNode *cellNode = nsnull;
rv = cellContent->QueryInterface(kIDOMNodeIID, (void **)&cellNode);
if (NS_SUCCEEDED(rv) && (nsnull != cellNode)) {
if (refIndex >= 0) {
nsIDOMNode *refCell;
cells->Item(refIndex, &refCell);
rv = InsertBefore(cellNode, refCell, (nsIDOMNode **)aValue);
} else {
rv = AppendChild(cellNode, (nsIDOMNode **)aValue);
}
NS_RELEASE(cellNode);
}
NS_RELEASE(cellContent);
}
NS_RELEASE(cells);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::DeleteCell(PRInt32 aValue)
{
nsIDOMHTMLCollection *cells;
GetCells(&cells);
nsIDOMNode *cell = nsnull;
cells->Item(aValue, &cell);
if (nsnull != cell) {
RemoveChild(cell, &cell);
}
NS_RELEASE(cells);
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Align, align)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, BgColor, bgcolor)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Ch, ch)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, ChOff, choff)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, VAlign, valign)
NS_IMETHODIMP
nsHTMLTableRowElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
/* ignore these attributes, stored simply as strings
ch
*/
/* attributes that resolve to integers with default=0*/
if (aAttribute == nsHTMLAtoms::choff) {
if (nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
/* attributes that resolve to integers or percents */
else if (aAttribute == nsHTMLAtoms::height) {
if (nsGenericHTMLElement::ParseValueOrPercent(aValue, aResult, eHTMLUnit_Pixel)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
/* attributes that resolve to integers or percents or proportions */
else if (aAttribute == nsHTMLAtoms::width) {
if (nsGenericHTMLElement::ParseValueOrPercentOrProportional(aValue, aResult, eHTMLUnit_Pixel)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
/* other attributes */
else if (aAttribute == nsHTMLAtoms::align) {
if (mInner.ParseTableCellHAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::bgcolor) {
if (nsGenericHTMLElement::ParseColor(aValue, mInner.mDocument, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::valign) {
if (nsGenericHTMLElement::ParseTableVAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHODIMP
nsHTMLTableRowElement::AttributeToString(nsIAtom* aAttribute,
const nsHTMLValue& aValue,
nsString& aResult) const
{
/* ignore these attributes, stored already as strings
ch
*/
/* ignore attributes that are of standard types
choff, height, width, background, bgcolor
*/
if (aAttribute == nsHTMLAtoms::align) {
if (mInner.TableCellHAlignValueToString(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::valign) {
if (nsGenericHTMLElement::TableVAlignValueToString(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
static void
MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes,
nsIMutableStyleContext* aContext,
nsIPresContext* aPresContext)
{
NS_PRECONDITION(nsnull!=aContext, "bad style context arg");
NS_PRECONDITION(nsnull!=aPresContext, "bad presentation context arg");
if (nsnull!=aAttributes)
{
nsHTMLValue value;
nsHTMLValue widthValue;
nsStyleText* textStyle = nsnull;
// align: enum
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (value.GetUnit() == eHTMLUnit_Enumerated)
{
textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text);
textStyle->mTextAlign = value.GetIntValue();
}
// valign: enum
aAttributes->GetAttribute(nsHTMLAtoms::valign, value);
if (value.GetUnit() == eHTMLUnit_Enumerated)
{
if (nsnull==textStyle)
textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text);
textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
}
// height: pixel
aAttributes->GetAttribute(nsHTMLAtoms::height, value);
if (value.GetUnit() == eHTMLUnit_Pixel) {
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nsStylePosition* pos = (nsStylePosition*)
aContext->GetMutableStyleData(eStyleStruct_Position);
nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t);
pos->mHeight.SetCoordValue(twips);
}
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aContext, aPresContext);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetMappedAttributeImpact(const nsIAtom* aAttribute,
PRInt32& aHint) const
{
if ((aAttribute == nsHTMLAtoms::align) ||
(aAttribute == nsHTMLAtoms::valign) ||
(aAttribute == nsHTMLAtoms::height)) {
aHint = NS_STYLE_HINT_REFLOW;
}
else if (! nsGenericHTMLElement::GetCommonMappedAttributesImpact(aAttribute, aHint)) {
if (! nsGenericHTMLElement::GetBackgroundAttributesImpact(aAttribute, aHint)) {
aHint = NS_STYLE_HINT_CONTENT;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetAttributeMappingFunctions(nsMapAttributesFunc& aFontMapFunc,
nsMapAttributesFunc& aMapFunc) const
{
aFontMapFunc = nsnull;
aMapFunc = &MapAttributesInto;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsHTMLTableRowElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
{
if (!aResult) return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
PRUint32 sum = 0;
mInner.SizeOf(aSizer, &sum, sizeof(*this));
if (mCells) {
PRUint32 asize;
mCells->SizeOf(aSizer, &asize);
sum += asize;
}
*aResult = sum;
#endif
return NS_OK;
}