This commit is contained in:
karnaze%netscape.com 1998-12-18 17:05:17 +00:00
Родитель 9eadd75926
Коммит 00b411a715
11 изменённых файлов: 879 добавлений и 56 удалений

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

@ -18,6 +18,8 @@
*/
#include "nsIHTMLTableCellElement.h"
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIDOMHTMLTableRowElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -31,6 +33,7 @@
static NS_DEFINE_IID(kIDOMHTMLTableCellElementIID, NS_IDOMHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIHTMLTableCellElementIID, NS_IHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableRowElementIID, NS_IDOMHTMLTABLEROWELEMENT_IID);
class nsHTMLTableCellElement : public nsIHTMLTableCellElement,
public nsIDOMHTMLTableCellElement,
@ -108,6 +111,8 @@ public:
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
protected:
nsresult GetRow(nsIDOMHTMLTableRowElement** aRow);
nsGenericHTMLContainerElement mInner;
PRInt32 mColIndex;
};
@ -185,17 +190,79 @@ NS_METHOD nsHTMLTableCellElement::SetColIndex (PRInt32 aColIndex)
return NS_OK;
}
// protected method
nsresult
nsHTMLTableCellElement::GetRow(nsIDOMHTMLTableRowElement** aRow)
{
nsIDOMNode *rowNode;
GetParentNode(&rowNode);
nsresult result = rowNode->QueryInterface(kIDOMHTMLTableRowElementIID, (void**)aRow);
NS_RELEASE(rowNode);
return result;
}
NS_IMETHODIMP
nsHTMLTableCellElement::GetCellIndex(PRInt32* aCellIndex)
{
*aCellIndex = 0;/* XXX */
*aCellIndex = -1;
nsIDOMHTMLTableRowElement* row = nsnull;
GetRow(&row);
nsIDOMHTMLCollection *cells = nsnull;
row->GetCells(&cells);
PRUint32 numCells;
cells->GetLength(&numCells);
for (PRUint32 i = 0; i < numCells; i++) {
nsIDOMNode *node = nsnull;
cells->Item(i, &node);
if (this == node) {
*aCellIndex = i;
break;
}
}
NS_RELEASE(cells);
NS_RELEASE(row);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableCellElement::SetCellIndex(PRInt32 aCellIndex)
{
// XXX write me
PRInt32 oldIndex;
GetCellIndex(&oldIndex);
if (oldIndex == aCellIndex) { // no change in index, don't do anything
return NS_OK;
}
nsIDOMHTMLTableRowElement* row = nsnull;
GetRow(&row);
row->DeleteCell(oldIndex); // delete this from the row
nsIDOMHTMLCollection *cells = nsnull;
row->GetCells(&cells);
PRUint32 numCells;
cells->GetLength(&numCells);
nsIDOMNode *returnNode;
if (numCells <= 0) {
row->AppendChild(this, &returnNode); // add this back into the row
} else {
PRInt32 newIndex = oldIndex;
if (aCellIndex <= 0) {
newIndex = 0;
} else if ((PRUint32)aCellIndex >= numCells) {
newIndex = numCells - 1;
} else if (aCellIndex > oldIndex) {
newIndex--; // since this got removed before GetLength was called
}
nsIDOMNode *refNode;
cells->Item(newIndex, &refNode);
row->InsertBefore(this, refNode, &returnNode); // add this back into the row
}
NS_RELEASE(cells);
NS_RELEASE(row);
return NS_OK;
}

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

@ -17,18 +17,32 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#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 "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);
class nsHTMLTableRowElement : public nsIDOMHTMLTableRowElement,
public nsIScriptObjectOwner,
@ -84,9 +98,37 @@ public:
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
protected:
nsresult GetSection(nsIDOMHTMLTableSectionElement** aSection);
nsresult GetTable(nsIDOMHTMLTableElement** aTable);
nsGenericHTMLContainerElement mInner;
GenericElementCollection* mCells;
};
void TempList(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();
if (nsnull != rootFrame) {
rootFrame->List(stdout, 0, nsnull);
}
}
NS_RELEASE(shell);
NS_RELEASE(doc);
}
NS_RELEASE(content);
}
}
nsresult
NS_NewHTMLTableRowElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -105,10 +147,15 @@ 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)
@ -139,63 +186,284 @@ nsHTMLTableRowElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetRowIndex(PRInt32* aValue)
// protected method
nsresult
nsHTMLTableRowElement::GetSection(nsIDOMHTMLTableSectionElement** aSection)
{
*aValue = 0;
// XXX write me
return NS_OK;
*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);
for (PRUint32 i = 0; i < numRows; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
break;
}
}
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)
{
// XXX write me
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;
// check if it really moves
if ( !(((0 == oldIndex) && (aValue <= 0)) || ((numRows-1 == oldIndex) && (aValue >= numRows-1)))) {
AddRef(); // don't use NS_ADDREF_THIS
table->DeleteRow(oldIndex); // delete this from the table
numRows--;
nsIDOMNode *returnNode;
if ((numRows <= 0) || (aValue >= numRows)) {
table->AppendChild(this, &returnNode); // add this back into the table
} 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);
table->InsertBefore(this, refNode, &returnNode); // add this back into the table
}
Release(); // from addref above, can't use NS_RELEASE
}
NS_RELEASE(rows);
NS_RELEASE(table);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetSectionRowIndex(PRInt32* aValue)
{
*aValue = 0;
// XXX write me
*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);
for (PRUint32 i = 0; i < numRows; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
break;
}
}
NS_RELEASE(rows);
NS_RELEASE(section);
}
return NS_OK;
}
// this generates 2 reflows like SetRowIndex
NS_IMETHODIMP
nsHTMLTableRowElement::SetSectionRowIndex(PRInt32 aValue)
{
// XXX write me
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
}
Release(); // from addref above, can't use NS_RELEASE
}
NS_RELEASE(rows);
NS_RELEASE(section);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetCells(nsIDOMHTMLCollection** aValue)
{
*aValue = 0;
// XXX write me
if (nsnull == mCells) {
NS_ADDREF(nsHTMLAtoms::td);
mCells = new GenericElementCollection(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)
{
// XXX write me
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 = 0;
// XXX write me
*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)
{
// XXX write me
nsIDOMHTMLCollection *cells;
GetCells(&cells);
nsIDOMNode *cell = nsnull;
cells->Item(aValue, &cell);
if (nsnull != cell) {
RemoveChild(cell, &cell);
}
NS_RELEASE(cells);
return NS_OK;
}
@ -359,4 +627,4 @@ nsHTMLTableRowElement::GetStyleHintForAttributeChange(
*aHint = NS_STYLE_HINT_REFLOW;
}
return NS_OK;
}
}

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

@ -24,11 +24,14 @@
#include "nsGenericHTMLElement.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLParts.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "GenericElementCollection.h"
static NS_DEFINE_IID(kIDOMHTMLTableSectionElementIID, NS_IDOMHTMLTABLESECTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
// you will see the phrases "rowgroup" and "section" used interchangably
@ -80,6 +83,7 @@ public:
protected:
nsGenericHTMLContainerElement mInner;
GenericElementCollection *mRows;
};
nsresult
@ -100,10 +104,15 @@ nsHTMLTableSectionElement::nsHTMLTableSectionElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mRows = nsnull;
}
nsHTMLTableSectionElement::~nsHTMLTableSectionElement()
{
if (nsnull!=mRows) {
mRows->ParentDestroyed();
NS_RELEASE(mRows);
}
}
NS_IMPL_ADDREF(nsHTMLTableSectionElement)
@ -142,23 +151,66 @@ NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, ChOff, choff)
NS_IMETHODIMP
nsHTMLTableSectionElement::GetRows(nsIDOMHTMLCollection** aValue)
{
*aValue = 0;
// XXX write me
*aValue = nsnull;
if (nsnull == mRows) {
NS_ADDREF(nsHTMLAtoms::tr);
mRows = new GenericElementCollection(this, nsHTMLAtoms::tr);
NS_ADDREF(mRows); // this table's reference, released in the destructor
}
mRows->QueryInterface(kIDOMHTMLCollectionIID, (void **)aValue); // caller's addref
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableSectionElement::InsertRow(PRInt32 aIndex, nsIDOMHTMLElement** aValue)
{
*aValue = 0;
// XXX write me
*aValue = nsnull;
PRInt32 refIndex = (0 <= aIndex) ? aIndex : 0;
nsIDOMHTMLCollection *rows;
GetRows(&rows);
PRUint32 rowCount;
rows->GetLength(&rowCount);
if (rowCount <= PRUint32(aIndex)) {
refIndex = rowCount - 1; // refIndex will be -1 if there are no rows
}
// create the row
nsIHTMLContent *rowContent = nsnull;
nsresult rv = NS_NewHTMLTableRowElement(&rowContent, nsHTMLAtoms::tr);
if (NS_SUCCEEDED(rv) && (nsnull != rowContent)) {
nsIDOMNode *rowNode = nsnull;
rv = rowContent->QueryInterface(kIDOMNodeIID, (void **)&rowNode);
if (NS_SUCCEEDED(rv) && (nsnull != rowNode)) {
if (refIndex >= 0) {
nsIDOMNode *refRow;
rows->Item(refIndex, &refRow);
rv = InsertBefore(rowNode, refRow, (nsIDOMNode **)aValue);
} else {
rv = AppendChild(rowNode, (nsIDOMNode **)aValue);
}
NS_RELEASE(rowNode);
}
NS_RELEASE(rowContent);
}
NS_RELEASE(rows);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableSectionElement::DeleteRow(PRInt32 aIndex)
nsHTMLTableSectionElement::DeleteRow(PRInt32 aValue)
{
// XXX write me
nsIDOMHTMLCollection *rows;
GetRows(&rows);
nsIDOMNode *row = nsnull;
rows->Item(aValue, &row);
if (nsnull != row) {
RemoveChild(row, &row);
}
NS_RELEASE(rows);
return NS_OK;
}

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
// XXX ask Peter if this can go away
#define NS_IHTMLTABLECELLELEMENT_IID \
{ 0x243CA090, 0x4914, 0x11d2, \
{ 0x8F, 0x3F, 0x00, 0x60, 0x08, 0x15, 0x9B, 0x0C } }

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
// XXX ask Peter if this can go away
#define NS_IHTMLTABLECOLELEMENT_IID \
{ 0xcc60f140, 0x4bf4, 0x11d2, \
{ 0x8F, 0x40, 0x00, 0x60, 0x08, 0x15, 0x9B, 0x0C } }

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

@ -18,6 +18,8 @@
*/
#include "nsIHTMLTableCellElement.h"
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIDOMHTMLTableRowElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -31,6 +33,7 @@
static NS_DEFINE_IID(kIDOMHTMLTableCellElementIID, NS_IDOMHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIHTMLTableCellElementIID, NS_IHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableRowElementIID, NS_IDOMHTMLTABLEROWELEMENT_IID);
class nsHTMLTableCellElement : public nsIHTMLTableCellElement,
public nsIDOMHTMLTableCellElement,
@ -108,6 +111,8 @@ public:
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
protected:
nsresult GetRow(nsIDOMHTMLTableRowElement** aRow);
nsGenericHTMLContainerElement mInner;
PRInt32 mColIndex;
};
@ -185,17 +190,79 @@ NS_METHOD nsHTMLTableCellElement::SetColIndex (PRInt32 aColIndex)
return NS_OK;
}
// protected method
nsresult
nsHTMLTableCellElement::GetRow(nsIDOMHTMLTableRowElement** aRow)
{
nsIDOMNode *rowNode;
GetParentNode(&rowNode);
nsresult result = rowNode->QueryInterface(kIDOMHTMLTableRowElementIID, (void**)aRow);
NS_RELEASE(rowNode);
return result;
}
NS_IMETHODIMP
nsHTMLTableCellElement::GetCellIndex(PRInt32* aCellIndex)
{
*aCellIndex = 0;/* XXX */
*aCellIndex = -1;
nsIDOMHTMLTableRowElement* row = nsnull;
GetRow(&row);
nsIDOMHTMLCollection *cells = nsnull;
row->GetCells(&cells);
PRUint32 numCells;
cells->GetLength(&numCells);
for (PRUint32 i = 0; i < numCells; i++) {
nsIDOMNode *node = nsnull;
cells->Item(i, &node);
if (this == node) {
*aCellIndex = i;
break;
}
}
NS_RELEASE(cells);
NS_RELEASE(row);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableCellElement::SetCellIndex(PRInt32 aCellIndex)
{
// XXX write me
PRInt32 oldIndex;
GetCellIndex(&oldIndex);
if (oldIndex == aCellIndex) { // no change in index, don't do anything
return NS_OK;
}
nsIDOMHTMLTableRowElement* row = nsnull;
GetRow(&row);
row->DeleteCell(oldIndex); // delete this from the row
nsIDOMHTMLCollection *cells = nsnull;
row->GetCells(&cells);
PRUint32 numCells;
cells->GetLength(&numCells);
nsIDOMNode *returnNode;
if (numCells <= 0) {
row->AppendChild(this, &returnNode); // add this back into the row
} else {
PRInt32 newIndex = oldIndex;
if (aCellIndex <= 0) {
newIndex = 0;
} else if ((PRUint32)aCellIndex >= numCells) {
newIndex = numCells - 1;
} else if (aCellIndex > oldIndex) {
newIndex--; // since this got removed before GetLength was called
}
nsIDOMNode *refNode;
cells->Item(newIndex, &refNode);
row->InsertBefore(this, refNode, &returnNode); // add this back into the row
}
NS_RELEASE(cells);
NS_RELEASE(row);
return NS_OK;
}

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

@ -17,18 +17,32 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#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 "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);
class nsHTMLTableRowElement : public nsIDOMHTMLTableRowElement,
public nsIScriptObjectOwner,
@ -84,9 +98,37 @@ public:
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
protected:
nsresult GetSection(nsIDOMHTMLTableSectionElement** aSection);
nsresult GetTable(nsIDOMHTMLTableElement** aTable);
nsGenericHTMLContainerElement mInner;
GenericElementCollection* mCells;
};
void TempList(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();
if (nsnull != rootFrame) {
rootFrame->List(stdout, 0, nsnull);
}
}
NS_RELEASE(shell);
NS_RELEASE(doc);
}
NS_RELEASE(content);
}
}
nsresult
NS_NewHTMLTableRowElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -105,10 +147,15 @@ 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)
@ -139,63 +186,284 @@ nsHTMLTableRowElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetRowIndex(PRInt32* aValue)
// protected method
nsresult
nsHTMLTableRowElement::GetSection(nsIDOMHTMLTableSectionElement** aSection)
{
*aValue = 0;
// XXX write me
return NS_OK;
*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);
for (PRUint32 i = 0; i < numRows; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
break;
}
}
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)
{
// XXX write me
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;
// check if it really moves
if ( !(((0 == oldIndex) && (aValue <= 0)) || ((numRows-1 == oldIndex) && (aValue >= numRows-1)))) {
AddRef(); // don't use NS_ADDREF_THIS
table->DeleteRow(oldIndex); // delete this from the table
numRows--;
nsIDOMNode *returnNode;
if ((numRows <= 0) || (aValue >= numRows)) {
table->AppendChild(this, &returnNode); // add this back into the table
} 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);
table->InsertBefore(this, refNode, &returnNode); // add this back into the table
}
Release(); // from addref above, can't use NS_RELEASE
}
NS_RELEASE(rows);
NS_RELEASE(table);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetSectionRowIndex(PRInt32* aValue)
{
*aValue = 0;
// XXX write me
*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);
for (PRUint32 i = 0; i < numRows; i++) {
nsIDOMNode *node = nsnull;
rows->Item(i, &node);
if (this == node) {
*aValue = i;
break;
}
}
NS_RELEASE(rows);
NS_RELEASE(section);
}
return NS_OK;
}
// this generates 2 reflows like SetRowIndex
NS_IMETHODIMP
nsHTMLTableRowElement::SetSectionRowIndex(PRInt32 aValue)
{
// XXX write me
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
}
Release(); // from addref above, can't use NS_RELEASE
}
NS_RELEASE(rows);
NS_RELEASE(section);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableRowElement::GetCells(nsIDOMHTMLCollection** aValue)
{
*aValue = 0;
// XXX write me
if (nsnull == mCells) {
NS_ADDREF(nsHTMLAtoms::td);
mCells = new GenericElementCollection(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)
{
// XXX write me
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 = 0;
// XXX write me
*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)
{
// XXX write me
nsIDOMHTMLCollection *cells;
GetCells(&cells);
nsIDOMNode *cell = nsnull;
cells->Item(aValue, &cell);
if (nsnull != cell) {
RemoveChild(cell, &cell);
}
NS_RELEASE(cells);
return NS_OK;
}
@ -359,4 +627,4 @@ nsHTMLTableRowElement::GetStyleHintForAttributeChange(
*aHint = NS_STYLE_HINT_REFLOW;
}
return NS_OK;
}
}

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

@ -24,11 +24,14 @@
#include "nsGenericHTMLElement.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLParts.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "GenericElementCollection.h"
static NS_DEFINE_IID(kIDOMHTMLTableSectionElementIID, NS_IDOMHTMLTABLESECTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
// you will see the phrases "rowgroup" and "section" used interchangably
@ -80,6 +83,7 @@ public:
protected:
nsGenericHTMLContainerElement mInner;
GenericElementCollection *mRows;
};
nsresult
@ -100,10 +104,15 @@ nsHTMLTableSectionElement::nsHTMLTableSectionElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mRows = nsnull;
}
nsHTMLTableSectionElement::~nsHTMLTableSectionElement()
{
if (nsnull!=mRows) {
mRows->ParentDestroyed();
NS_RELEASE(mRows);
}
}
NS_IMPL_ADDREF(nsHTMLTableSectionElement)
@ -142,23 +151,66 @@ NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, ChOff, choff)
NS_IMETHODIMP
nsHTMLTableSectionElement::GetRows(nsIDOMHTMLCollection** aValue)
{
*aValue = 0;
// XXX write me
*aValue = nsnull;
if (nsnull == mRows) {
NS_ADDREF(nsHTMLAtoms::tr);
mRows = new GenericElementCollection(this, nsHTMLAtoms::tr);
NS_ADDREF(mRows); // this table's reference, released in the destructor
}
mRows->QueryInterface(kIDOMHTMLCollectionIID, (void **)aValue); // caller's addref
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableSectionElement::InsertRow(PRInt32 aIndex, nsIDOMHTMLElement** aValue)
{
*aValue = 0;
// XXX write me
*aValue = nsnull;
PRInt32 refIndex = (0 <= aIndex) ? aIndex : 0;
nsIDOMHTMLCollection *rows;
GetRows(&rows);
PRUint32 rowCount;
rows->GetLength(&rowCount);
if (rowCount <= PRUint32(aIndex)) {
refIndex = rowCount - 1; // refIndex will be -1 if there are no rows
}
// create the row
nsIHTMLContent *rowContent = nsnull;
nsresult rv = NS_NewHTMLTableRowElement(&rowContent, nsHTMLAtoms::tr);
if (NS_SUCCEEDED(rv) && (nsnull != rowContent)) {
nsIDOMNode *rowNode = nsnull;
rv = rowContent->QueryInterface(kIDOMNodeIID, (void **)&rowNode);
if (NS_SUCCEEDED(rv) && (nsnull != rowNode)) {
if (refIndex >= 0) {
nsIDOMNode *refRow;
rows->Item(refIndex, &refRow);
rv = InsertBefore(rowNode, refRow, (nsIDOMNode **)aValue);
} else {
rv = AppendChild(rowNode, (nsIDOMNode **)aValue);
}
NS_RELEASE(rowNode);
}
NS_RELEASE(rowContent);
}
NS_RELEASE(rows);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTableSectionElement::DeleteRow(PRInt32 aIndex)
nsHTMLTableSectionElement::DeleteRow(PRInt32 aValue)
{
// XXX write me
nsIDOMHTMLCollection *rows;
GetRows(&rows);
nsIDOMNode *row = nsnull;
rows->Item(aValue, &row);
if (nsnull != row) {
RemoveChild(row, &row);
}
NS_RELEASE(rows);
return NS_OK;
}

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
// XXX ask Peter if this can go away
#define NS_IHTMLTABLECELLELEMENT_IID \
{ 0x243CA090, 0x4914, 0x11d2, \
{ 0x8F, 0x3F, 0x00, 0x60, 0x08, 0x15, 0x9B, 0x0C } }

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

@ -23,6 +23,7 @@
#include "nsISupports.h"
// XXX ask Peter if this can go away
#define NS_IHTMLTABLECOLELEMENT_IID \
{ 0xcc60f140, 0x4bf4, 0x11d2, \
{ 0x8F, 0x40, 0x00, 0x60, 0x08, 0x15, 0x9B, 0x0C } }

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

@ -3,6 +3,11 @@
<HEAD>
<SCRIPT>
var count = 1;
function genName(prefix) {
return "X" + count++ + "\n";
}
function insertCaption() {
var table = document.getElementsByTagName("TABLE")[0];
var caption = document.createElement("CAPTION", null);
@ -136,8 +141,6 @@ function changeRowGroupStyle() {
dump("SCRIPT: changed default align for first ROWGROUP to right\n");
}
function insertRow() {
var rg = document.getElementsByTagName("TBODY")[0];
var refRow = document.getElementsByTagName("TR")[0];
@ -158,17 +161,42 @@ function appendRowWithContent() {
var rg = document.getElementsByTagName("TBODY")[0];
var row = document.createElement("TR", null);
var cell = document.createElement("TD", null);
var text = document.createTextNode("x\n");
var text = document.createTextNode(genName());
cell.appendChild(text);
row.appendChild(cell);
rg.appendChild(row);
dump("SCRIPT: appended ROW with 1 cell in first ROWGROUP\n");
}
function insertRowWithContent() {
dump("\nSCRIPT: starting appendRowWithContent\n");
var rg = document.getElementsByTagName("TBODY")[0];
var cell = document.createElement("TD", null);
var text = document.createTextNode(genName());
cell.appendChild(text);
row = rg.insertRow(0);
row.appendChild(cell);
dump("SCRIPT: inserted ROW with 1 cell in first ROWGROUP\n");
}
function setRowIndex() {
dump("\nSCRIPT: starting setRowIndex\n");
var row = document.getElementsByTagName("TR")[0];
row.setRowIndex(99);
dump("SCRIPT: ending setRowindex - placed 1st row at end\n");
}
function setSectionRowIndex() {
dump("\nSCRIPT: starting setSectionRowIndex\n");
var row = document.getElementsByTagName("TR")[0];
row.setSectionRowIndex(99);
dump("SCRIPT: ending setSectionRowindex - placed 1st row at end\n");
}
function deleteRow() {
var rg = document.getElementsByTagName("TBODY")[0];
var row = document.getElementsByTagName("TR")[0];
rg.removeChild(row);
//var row = document.getElementsByTagName("TR")[0];
rg.deleteRow(0);
dump("SCRIPT: deleted first ROW in first ROWGROUP\n");
}
@ -178,12 +206,20 @@ function changeRowStyle() {
dump("SCRIPT: changed default align for first ROW to right\n");
}
// why doesn't this cell show up
function insertCellNew() {
var row = document.getElementsByTagName("TR")[0];
var cell = row.insertCell(0);
var text = document.createTextNode(genName());
cell.appendChild(text);
dump("SCRIPT: inserted CELL as first cell in first row\n");
}
function insertCell() {
var row = document.getElementsByTagName("TR")[0];
var refCell = document.getElementsByTagName("TD")[0];
var cell = document.createElement("TD", null);
var text = document.createTextNode("inserted Cell");
var text = document.createTextNode(genName());
cell.colSpan=2;
cell.appendChild(text);
row.insertBefore(cell, refCell);
@ -193,13 +229,19 @@ function insertCell() {
function appendCell() {
var row = document.getElementsByTagName("TR")[0];
var cell = document.createElement("TD", null);
var text = document.createTextNode("appended Cell");
var text = document.createTextNode(genName());
cell.appendChild(text);
row.appendChild(cell);
dump("SCRIPT: appended CELL in first ROW\n");
}
function deleteCell() {
var row = document.getElementsByTagName("TR")[0];
row.deleteCell(0);
dump("SCRIPT: deleted first CELL in first ROW\n");
}
function deleteCellBack() {
var row = document.getElementsByTagName("TR")[0];
var cell = document.getElementsByTagName("TD")[0];
row.removeChild(cell);
@ -248,7 +290,7 @@ delete removes the first object of [type].
<table width=150 border>
<tbody>
<tr>
<td>cell content</td>
<td>existing cell</td>
</tr>
</tbody>
</table>
@ -276,6 +318,9 @@ delete removes the first object of [type].
<INPUT TYPE="button" NAME="App Row" VALUE="AppendRow" onClick="appendRow()" width=100>
<INPUT TYPE="button" NAME="Del Row" VALUE="DeleteRow" onClick="deleteRow()" width=100>
<INPUT TYPE="button" NAME="App Row with content" VALUE="AppendRow with content" onClick="appendRowWithContent()" width=100>
<INPUT TYPE="button" NAME="App Row with content" VALUE="InsertRow with content" onClick="insertRowWithContent()" width=100>
<INPUT TYPE="button" NAME="Set Row Index" VALUE="Set Row Index" onClick="setRowIndex()">
<INPUT TYPE="button" NAME="Set Section Row Index" VALUE="Set Section Row Index" onClick="setSectionRowIndex()">
<br>
<INPUT TYPE="button" NAME="Ins Cell" VALUE="InsertCell" onClick="insertCell()" width=100>
<INPUT TYPE="button" NAME="App Cell" VALUE="AppendCell" onClick="appendCell()" width=100>