From 2ce1bef073562fe2e370a6e8636e2441cc418f4e Mon Sep 17 00:00:00 2001 From: "cmanske%netscape.com" Date: Thu, 3 Feb 2000 02:06:10 +0000 Subject: [PATCH] More table editing work (bug 20973) and Page Properies dialog work (bug 14344). Added missing 'tbody' to nsIAtoms list. r=mjudge git-svn-id: svn://10.0.0.236/trunk@59605 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/editor/base/EditTable.cpp | 639 ++++++++++++++---- mozilla/editor/base/nsEditProperty.cpp | 7 +- mozilla/editor/base/nsEditor.cpp | 1 + mozilla/editor/base/nsEditorShell.cpp | 70 ++ mozilla/editor/base/nsHTMLEditor.cpp | 101 +-- mozilla/editor/base/nsHTMLEditor.h | 14 +- mozilla/editor/base/nsIEditProperty.h | 1 + mozilla/editor/composer/src/nsEditorShell.cpp | 70 ++ mozilla/editor/idl/nsIEditorShell.idl | 24 + mozilla/editor/libeditor/base/nsEditor.cpp | 1 + .../editor/libeditor/base/nsIEditProperty.h | 1 + .../editor/libeditor/html/nsEditProperty.cpp | 7 +- .../editor/libeditor/html/nsHTMLEditor.cpp | 101 +-- mozilla/editor/libeditor/html/nsHTMLEditor.h | 14 +- mozilla/editor/public/nsITableEditor.h | 26 +- .../ui/composer/content/EditorCommands.js | 308 ++++++--- mozilla/editor/ui/composer/content/editor.xul | 4 +- .../ui/composer/content/editorOverlay.xul | 9 +- .../editor/ui/composer/content/makefile.win | 2 - .../composer/locale/en-US/editorOverlay.dtd | 9 +- .../editor/ui/dialogs/content/EdPageProps.js | 87 ++- .../editor/ui/dialogs/content/EdPageProps.xul | 178 +++-- .../locale/en-US/EditorPageProperties.dtd | 17 +- .../editor/ui/dialogs/skin/EditorDialog.css | 39 +- 24 files changed, 1258 insertions(+), 472 deletions(-) diff --git a/mozilla/editor/base/EditTable.cpp b/mozilla/editor/base/EditTable.cpp index 57e64119525..89bb7f6ebf7 100644 --- a/mozilla/editor/base/EditTable.cpp +++ b/mozilla/editor/base/EditTable.cpp @@ -75,10 +75,14 @@ class nsSetCaretAfterTableEdit void CancelSetCaret() {mEd = nsnull; mTable = nsnull;} }; +// Table Editing helper utilities (not exposed in IDL) + NS_IMETHODIMP -nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, PRBool aAfter) +nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, + PRBool aAfter, nsIDOMElement **aNewCell) { if (!aCell) return NS_ERROR_NULL_POINTER; + if (aNewCell) *aNewCell = nsnull; // And the parent and offsets needed to do an insert nsCOMPtr cellParent; @@ -91,29 +95,68 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa { nsCOMPtr newCell; res = CreateElementWithDefaults("td", getter_AddRefs(newCell)); - if (NS_SUCCEEDED(res) && newCell) + if(NS_FAILED(res)) return res; + if(!newCell) return NS_ERROR_FAILURE; + + //Optional: return new cell created + if (aNewCell) { - if( aRowSpan > 1) - { - nsAutoString newRowSpan(aRowSpan); - //newRowSpan.Append(aRowSpan, 10); - // Note: Do NOT use editor txt for this - newCell->SetAttribute("rowspan", newRowSpan); - } - if( aColSpan > 1) - { - nsAutoString newColSpan(aColSpan); - // Note: Do NOT use editor txt for this - newCell->SetAttribute("colspan", newColSpan); - } - if(aAfter) cellOffset++; - res = InsertNode(newCell, cellParent, cellOffset); + *aNewCell = newCell.get(); + NS_ADDREF(*aNewCell); } + if( aRowSpan > 1) + { + nsAutoString newRowSpan(aRowSpan); + // Note: Do NOT use editor txt for this + newCell->SetAttribute("rowspan", newRowSpan); + } + if( aColSpan > 1) + { + nsAutoString newColSpan(aColSpan); + // Note: Do NOT use editor txt for this + newCell->SetAttribute("colspan", newColSpan); + } + if(aAfter) cellOffset++; + + //Don't let Rules System change the selection + nsAutoTxnsConserveSelection dontChangeSelection(this); + res = nsEditor::InsertNode(newCell, cellParent, cellOffset); } } return res; } +PRBool IsRowNode(nsCOMPtr &aNode) +{ + nsCOMPtr atom; + nsCOMPtr content = do_QueryInterface(aNode); + if (content) + { + content->GetTag(*getter_AddRefs(atom)); + if (atom && atom.get() == nsIEditProperty::tr) + return PR_TRUE; + } + return PR_FALSE; +} + +NS_IMETHODIMP nsHTMLEditor::SetColSpan(nsIDOMElement *aCell, PRInt32 aColSpan) +{ + if (!aCell) return NS_ERROR_NULL_POINTER; + nsAutoString newSpan; + newSpan.Append(aColSpan, 10); + nsAutoString colSpan("colspan"); + return SetAttribute(aCell, colSpan, newSpan); +} + +NS_IMETHODIMP nsHTMLEditor::SetRowSpan(nsIDOMElement *aCell, PRInt32 aRowSpan) +{ + if (!aCell) return NS_ERROR_NULL_POINTER; + nsAutoString newSpan; + newSpan.Append(aRowSpan, 10); + nsAutoString rowSpan("rowspan"); + return SetAttribute(aCell, rowSpan, newSpan); +} + /****************************************************************/ // Table Editing interface methods @@ -138,7 +181,10 @@ nsHTMLEditor::InsertTableCell(PRInt32 aNumber, PRBool aAfter) if (NS_FAILED(res)) return res; if (!curCell) return NS_ERROR_FAILURE; PRInt32 newCellIndex = aAfter ? (startColIndex+colSpan) : startColIndex; + //We control selection resetting after the insert... nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, newCellIndex, ePreviousColumn); + //...so suppress Rules System selection munging + nsAutoTxnsConserveSelection dontChangeSelection(this); PRInt32 i; for (i = 0; i < aNumber; i++) @@ -148,32 +194,136 @@ nsHTMLEditor::InsertTableCell(PRInt32 aNumber, PRBool aAfter) if (NS_SUCCEEDED(res) && newCell) { if (aAfter) cellOffset++; - res = InsertNode(newCell, cellParent, cellOffset); + res = nsEditor::InsertNode(newCell, cellParent, cellOffset); if(NS_FAILED(res)) break; } } return res; } -nsresult nsHTMLEditor::GetRowAt(nsCOMPtr &aTable, PRInt32 rowIndex, nsCOMPtr &aRow) +NS_IMETHODIMP +nsHTMLEditor::GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow) +{ + aRow = nsnull; + + nsCOMPtr tableElement; + nsresult res = GetElementOrParentByTagName("table", aTableElement, getter_AddRefs(tableElement)); + if (NS_FAILED(res)) return res; + if (!tableElement) return NS_ERROR_NULL_POINTER; + + nsCOMPtrtableNode = do_QueryInterface(tableElement); + if (!tableNode) return NS_ERROR_NULL_POINTER; + + nsCOMPtr tableChild; + res = tableNode->GetFirstChild(getter_AddRefs(tableChild)); + if (NS_FAILED(res)) return res; + + while (tableChild) + { + nsCOMPtr content = do_QueryInterface(tableChild); + if (content) + { + nsCOMPtr element; + nsCOMPtr atom; + content->GetTag(*getter_AddRefs(atom)); + if (atom.get() == nsIEditProperty::tr) + { + // Found a row directly under + element = do_QueryInterface(tableChild); + if(element) + { + aRow = element.get(); + NS_ADDREF(aRow); + } + return NS_OK; + } + // Look for row in one of the row container elements + if (atom.get() == nsIEditProperty::tbody || + atom.get() == nsIEditProperty::thead || + atom.get() == nsIEditProperty::tfoot ) + { + nsCOMPtr rowNode; + // All children should be rows + res = tableChild->GetFirstChild(getter_AddRefs(rowNode)); + if (NS_FAILED(res)) return res; + if (rowNode && IsRowNode(rowNode)) + { + element = do_QueryInterface(rowNode); + if(element) + { + aRow = element.get(); + NS_ADDREF(aRow); + } + return NS_OK; + } + } + } + // Here if table child was a CAPTION or COLGROUP + // or child of a row-conainer wasn't a row (bad HTML) + // Look in next table child + res = tableChild->GetNextSibling(getter_AddRefs(tableChild)); + }; + return res; +} + +NS_IMETHODIMP +nsHTMLEditor::GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow) { aRow = nsnull; - nsCOMPtr nextRow; - PRInt32 index = 0; - nsAutoString tagName("tr"); - nsresult res = GetNextElementByTagName(aTable, &tagName, getter_AddRefs(nextRow)); + nsCOMPtr rowElement; + nsresult res = GetElementOrParentByTagName("tr", aTableElement, getter_AddRefs(rowElement)); if (NS_FAILED(res)) return res; - if (!nextRow) return NS_OK; + if (!rowElement) return NS_ERROR_NULL_POINTER; - nsCOMPtr parentTable; - res = GetElementOrParentByTagName("table", nextRow, getter_AddRefs(parentTable)); - if (NS_FAILED(res)) return res; - if (!parentTable) return NS_ERROR_NULL_POINTER; + nsCOMPtr rowNode = do_QueryInterface(rowElement); + if (!rowNode) return NS_ERROR_NULL_POINTER; + + nsCOMPtr nextRow; + nsCOMPtr rowParent; + nsCOMPtr parentSibling; + nsCOMPtr element; - if (parentTable == aTable) - aRow = nextRow; + rowNode->GetNextSibling(getter_AddRefs(nextRow)); + if(nextRow) + { + element = do_QueryInterface(nextRow); + if(element) + { + aRow = element.get(); + NS_ADDREF(aRow); + } + return NS_OK; + } + // No row found, search for rows in other table sections + res = rowNode->GetParentNode(getter_AddRefs(rowParent)); + if(NS_FAILED(res)) return res; + if (!rowParent) return NS_ERROR_NULL_POINTER; + res = rowParent->GetNextSibling(getter_AddRefs(parentSibling)); + if(NS_FAILED(res)) return res; + + while (parentSibling) + { + res = parentSibling->GetFirstChild(getter_AddRefs(nextRow)); + if(NS_FAILED(res)) return res; + if (nextRow && IsRowNode(nextRow)) + { + element = do_QueryInterface(nextRow); + if(element) + { + aRow = element.get(); + NS_ADDREF(aRow); + } + return NS_OK; + } +#ifdef DEBUG + printf("GetNextRow: firstChild of row's parent's sibling is not a TR!\n"); +#endif + // We arrive here only if a table section has no children + // or first child of section is not a row (bad HTML!) + res = parentSibling->GetNextSibling(getter_AddRefs(parentSibling)); + } return res; } @@ -197,25 +347,38 @@ nsHTMLEditor::InsertTableColumn(PRInt32 aNumber, PRBool aAfter) if (NS_FAILED(res)) return res; if (!curCell) return NS_ERROR_FAILURE; + nsAutoEditBatch beginBatching(this); + // Use column after current cell if requested if (aAfter) + { startColIndex += colSpan; + //Detect when user is adding after a COLSPAN=0 case + // Assume they want to stop the "0" behavior and + // really add a new column. Thus we set the + // colspan to its true value + if (colSpan == 0) + SetColSpan(curCell, actualColSpan); + } - PRInt32 rowCount, colCount, row; + PRInt32 rowCount, colCount, rowIndex; res = GetTableSize(table, rowCount, colCount); if (NS_FAILED(res)) return res; PRInt32 lastColumn = colCount - 1; - nsAutoEditBatch beginBatching(this); + //We reset caret in destructor... nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, startColIndex, ePreviousRow); + //.. so suppress Rules System selection munging + nsAutoTxnsConserveSelection dontChangeSelection(this); - for ( row = 0; row < rowCount; row++) + nsCOMPtr rowElement; + for ( rowIndex = 0; rowIndex < rowCount; rowIndex++) { if (startColIndex < colCount) { // We are inserting before an existing column - res = GetCellDataAt(table, row, startColIndex, *getter_AddRefs(curCell), + res = GetCellDataAt(table, rowIndex, startColIndex, *getter_AddRefs(curCell), curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan, isSelected); if (NS_FAILED(res)) return res; @@ -226,16 +389,12 @@ nsHTMLEditor::InsertTableColumn(PRInt32 aNumber, PRBool aAfter) { if (curStartColIndex < startColIndex) { - if (colSpan > 0) - { - // We have a cell spanning this location - // Simply increase its colspan to keep table rectangular - nsAutoString newColSpan; - newColSpan.Append(colSpan+aNumber, 10); - SetAttribute(curCell, "colspan", newColSpan); - } + // We have a cell spanning this location + // Simply increase its colspan to keep table rectangular // Note: we do nothing if colsSpan=0, // since it should automatically span the new column + if (colSpan > 0) + SetColSpan(curCell, colSpan+aNumber); } else { // Simply set selection to the current cell // so we can let InsertTableCell() do the work @@ -246,18 +405,31 @@ nsHTMLEditor::InsertTableColumn(PRInt32 aNumber, PRBool aAfter) } } else { // We are inserting after all existing columns - - //TODO: A better strategy is to get the row at index "row" - // and append a cell to the end of it. - // Need to write "GetRowAt()" to do this - - // Get last cell in row and insert new cell after it - res = GetCellDataAt(table, row, lastColumn, *getter_AddRefs(curCell), - curStartRowIndex, curStartColIndex, rowSpan, colSpan, - actualRowSpan, actualColSpan, isSelected); + //TODO: Make sure table is "well formed" (call NormalizeTable) + // before appending new column + + // Get current row and append new cells after last cell in row + if(rowIndex == 0) + res = GetFirstRow(table.get(), *getter_AddRefs(rowElement)); + else + res = GetNextRow(rowElement.get(), *getter_AddRefs(rowElement)); if (NS_FAILED(res)) return res; + + nsCOMPtr lastCell; + nsCOMPtr rowNode = do_QueryInterface(rowElement); + if (!rowElement) return NS_ERROR_FAILURE; + + res = rowElement->GetLastChild(getter_AddRefs(lastCell)); + if (NS_FAILED(res)) return res; + if (!lastCell) return NS_ERROR_FAILURE; + curCell = do_QueryInterface(lastCell); if (curCell) { + // Simply add same number of cells to each row + // Although tempted to check cell indexes for curCell, + // the effects of COLSPAN>1 in some cells makes this futile! + // We must use NormalizeTable first to assure proper + // that there are cells in each cellmap location selection->Collapse(curCell, 0); res = InsertTableCell(aNumber, PR_TRUE); } @@ -287,7 +459,8 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter) if (!curCell) return NS_ERROR_FAILURE; nsCOMPtr parentRow; - GetElementOrParentByTagName("tr", curCell, getter_AddRefs(parentRow)); + res = GetElementOrParentByTagName("tr", curCell, getter_AddRefs(parentRow)); + if (NS_FAILED(res)) return res; if (!parentRow) return NS_ERROR_NULL_POINTER; PRInt32 rowCount, colCount; @@ -303,16 +476,27 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter) if (NS_FAILED(res)) return res; if (!parentOfRow) return NS_ERROR_NULL_POINTER; + nsAutoEditBatch beginBatching(this); + if (aAfter) { // Use row after current cell startRowIndex += actualRowSpan; // offset to use for new row insert newRowOffset += actualRowSpan; + + //Detect when user is adding after a ROWSPAN=0 case + // Assume they want to stop the "0" behavior and + // really add a new row. Thus we set the + // rowspan to its true value + if (rowSpan == 0) + SetRowSpan(curCell, actualRowSpan); } - nsAutoEditBatch beginBatching(this); + //We control selection resetting after the insert... nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, startColIndex, ePreviousColumn); + //...so suppress Rules System selection munging + nsAutoTxnsConserveSelection dontChangeSelection(this); PRInt32 cellsInRow = 0; if (startRowIndex < rowCount) @@ -331,16 +515,12 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter) { if (curStartRowIndex < startRowIndex) { - if (rowSpan > 0) - { - // We have a cell spanning this location - // Simply increase its rowspan - nsAutoString newRowSpan; - newRowSpan.Append(rowSpan+aNumber, 10); - SetAttribute(curCell, "rowspan", newRowSpan); - } + // We have a cell spanning this location + // Simply increase its rowspan //Note that if rowSpan == 0, we do nothing, // since that cell should automatically extend into the new row + if (rowSpan > 0) + SetRowSpan(curCell, rowSpan+aNumber); } else { // Count the number of cells we need to add to the new row cellsInRow += actualColSpan; @@ -366,8 +546,9 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter) { if (rowSpan == 0) cellsInRow -= actualColSpan; + + tempColIndex += actualColSpan; } - tempColIndex += actualColSpan; } if (cellsInRow > 0) @@ -403,7 +584,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter) return res; } -// This is an internal helper (not exposed in IDL) +// Editor helper only NS_IMETHODIMP nsHTMLEditor::DeleteTable(nsCOMPtr &aTable, nsCOMPtr &aSelection) { @@ -467,12 +648,9 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber) { nsCOMPtr parentRow; res = GetElementOrParentByTagName("tr", cell, getter_AddRefs(parentRow)); - if (!parentRow) - { - res = NS_ERROR_NULL_POINTER; - break; - } if (NS_FAILED(res)) return res; + if (!parentRow) return NS_ERROR_NULL_POINTER; + // We should delete the row instead, // but first check if its the only row left // so we can delete the entire table @@ -483,9 +661,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber) if (rowCount == 1) return DeleteTable(table, selection); - // Delete the row by placing caret in cell we were to delete // We need to call DeleteTableRow to handle cells with rowspan - selection->Collapse(cell,0); res = DeleteTableRow(1); if (NS_FAILED(res)) return res; } @@ -497,6 +673,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber) // The setCaret object will call SetCaretAfterTableEdit in it's destructor selection->ClearSelection(); nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, startColIndex, ePreviousColumn); + nsAutoTxnsConserveSelection dontChangeSelection(this); res = DeleteNode(cell); // If we fail, don't try to delete any more cells??? @@ -524,6 +701,8 @@ nsHTMLEditor::DeleteTableCellContents() // We clear the selection to avoid problems when nodes in the selection are deleted, selection->ClearSelection(); nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, startColIndex, ePreviousColumn); + //Don't let Rules System change the selection + nsAutoTxnsConserveSelection dontChangeSelection(this); nsAutoEditBatch beginBatching(this); @@ -575,9 +754,6 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) // Check for counts too high aNumber = PR_MIN(aNumber,(colCount-startColIndex)); - selection->ClearSelection(); - nsSetCaretAfterTableEdit setCaret(this, table, startRowIndex, startColIndex, ePreviousColumn); - // Scan through cells in row to do rowspan adjustments nsCOMPtr curCell; PRInt32 curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan; @@ -593,11 +769,11 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) if (NS_FAILED(res)) return res; - NS_ASSERTION((actualColSpan > 0),"Effective COLSPAN = 0 in DeleteTableColumn"); - NS_ASSERTION((actualRowSpan > 0),"Effective ROWSPAN = 0 in DeleteTableColumn"); - if (curCell) { + // This must always be >= 1 + NS_ASSERTION((actualRowSpan > 0),"Effective ROWSPAN = 0 in DeleteTableColumn"); + // Find cells that don't start in column we are deleting if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0) { @@ -607,15 +783,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) if (colSpan > 0) { NS_ASSERTION((colSpan > 1),"Bad COLSPAN in DeleteTableColumn"); - nsAutoString newColSpan; - //This calculates final span for all columns deleted, - // but we are iterating aNumber times through here so - // just decrement current value by 1 - //PRInt32 minSpan = startColIndex - curStartColIndex; - //PRInt32 newSpan = PR_MAX(minSpan, colSpan - aNumber); - //newColSpan.Append(newSpan, 10); - newColSpan.Append(colSpan-1, 10); - SetAttribute(curCell, "colspan", newColSpan); + SetColSpan(curCell,colSpan-1); } if (curStartColIndex == startColIndex) { @@ -630,13 +798,13 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) // Delete the cell if (1 == GetNumberOfCellsInRow(table, rowIndex)) { + // Only 1 cell in row - delete the row nsCOMPtr parentRow; res = GetElementOrParentByTagName("tr", cell, getter_AddRefs(parentRow)); if (NS_FAILED(res)) return res; if(!parentRow) return NS_ERROR_NULL_POINTER; - // We should delete the row instead, - // but first check if its the only row left + // But first check if its the only row left // so we can delete the entire table // (This should never happen but it's the safe thing to do) PRInt32 rowCount, colCount; @@ -656,6 +824,12 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) // since a row was deleted and "next" // row now has current rowIndex } else { + + selection->ClearSelection(); + nsSetCaretAfterTableEdit setCaret(this, table, curStartRowIndex, curStartColIndex, ePreviousColumn); + //Don't let Rules System change the selection + nsAutoTxnsConserveSelection dontChangeSelection(this); + res = DeleteNode(curCell); if (NS_FAILED(res)) return res; @@ -663,11 +837,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber) rowIndex += actualRowSpan; } } - } else { - // No curCell, we've reached end of row - rowIndex++; } - } while (curCell); } return res; @@ -713,13 +883,15 @@ nsHTMLEditor::DeleteTableRow(PRInt32 aNumber) res = GetCellDataAt(table, startRowIndex, colIndex, *getter_AddRefs(curCell), curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan, isSelected); - - NS_ASSERTION((actualColSpan > 0),"Effective COLSPAN = 0 in DeleteTableRow"); - NS_ASSERTION((actualRowSpan > 0),"Effective ROWSPAN = 0 in DeleteTableRow"); + + // We don't fail if we don't find a cell, so this must be real bad + if(NS_FAILED(res)) return res; // Find cells that don't start in row we are deleting - if (NS_SUCCEEDED(res) && curCell) + if (curCell) { + //Real colspan must always be >= 1 + NS_ASSERTION((actualColSpan > 0),"Effective COLSPAN = 0 in DeleteTableRow"); if (curStartRowIndex < startRowIndex) { // We have a cell spanning this location @@ -727,20 +899,12 @@ nsHTMLEditor::DeleteTableRow(PRInt32 aNumber) // but we don't need to do this if rowspan=0, // since it will automatically adjust if (rowSpan > 0) - { - nsAutoString newRowSpan; - PRInt32 newSpan = PR_MAX((startRowIndex - curStartRowIndex), actualRowSpan - aNumber); - newRowSpan.Append(newSpan, 10); - SetAttribute(curCell, "rowspan", newRowSpan); - } + SetRowSpan(curCell, PR_MAX((startRowIndex - curStartRowIndex), actualRowSpan - aNumber)); } // Skip over locations spanned by this cell colIndex += actualColSpan; } - else - colIndex++; - - } while (curCell); + } while (curCell); for (PRInt32 i = 0; i < aNumber; i++) { @@ -767,13 +931,201 @@ nsHTMLEditor::DeleteTableRow(PRInt32 aNumber) NS_IMETHODIMP nsHTMLEditor::JoinTableCells() { - return NS_ERROR_NOT_IMPLEMENTED; + nsCOMPtr selection; + nsCOMPtr table; + nsCOMPtr cell; + nsCOMPtr cellParent; + PRInt32 cellOffset, startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan; + PRBool isSelected; + + PRInt32 rowCount, colCount; + nsresult res = GetTableSize(table, rowCount, colCount); + if (NS_FAILED(res)) return res; + + res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex); + if (NS_FAILED(res)) return res; + if(!cell) return NS_ERROR_NULL_POINTER; + + res = GetCellDataAt(table, startRowIndex, startColIndex, *getter_AddRefs(cell), + startRowIndex, startColIndex, rowSpan, colSpan, + actualRowSpan, actualColSpan, isSelected); + if (NS_FAILED(res)) return res; + if(!cell) return NS_ERROR_NULL_POINTER; + + //*** Initial test: just merge with cell to the right + + nsCOMPtr cell2; + PRInt32 startRowIndex2, startColIndex2, rowSpan2, colSpan2, actualRowSpan2, actualColSpan2; + PRBool isSelected2; + res = GetCellDataAt(table, startRowIndex, startColIndex+actualColSpan, *getter_AddRefs(cell2), + startRowIndex2, startColIndex2, rowSpan2, colSpan2, + actualRowSpan2, actualColSpan2, isSelected2); + if (NS_FAILED(res)) return res; + + nsAutoEditBatch beginBatching(this); + //Don't let Rules System change the selection + nsAutoTxnsConserveSelection dontChangeSelection(this); + + nsCOMPtr parentNode = do_QueryInterface(cellParent); + nsCOMPtr cellNode = do_QueryInterface(cell); + nsCOMPtr cellNode2 = do_QueryInterface(cell2); + if(cellNode && cellNode2 && parentNode) + { + PRInt32 insertIndex = 0; + + // Get index of last child in target cell + nsCOMPtr childNodes; + res = cellNode->GetChildNodes(getter_AddRefs(childNodes)); + if ((NS_SUCCEEDED(res)) && (childNodes)) + { + // Start inserting just after last child + PRUint32 len; + res = childNodes->GetLength(&len); + if (NS_FAILED(res)) return res; + insertIndex = (PRInt32)len; + } + + // Move content from cell2 to cell + nsCOMPtr cellChild; + res = cell2->GetFirstChild(getter_AddRefs(cellChild)); + if (NS_FAILED(res)) return res; + while (cellChild) + { + nsCOMPtr nextChild; + res = cellChild->GetNextSibling(getter_AddRefs(nextChild)); + if (NS_FAILED(res)) return res; + + res = DeleteNode(cellChild); + if (NS_FAILED(res)) return res; + + res = nsEditor::InsertNode(cellChild, cellNode, insertIndex); + if (NS_FAILED(res)) return res; + + cellChild = nextChild; + insertIndex++; + } + // Reset target cell's spans + res = SetColSpan(cell, actualColSpan+actualColSpan2); + if (NS_FAILED(res)) return res; + + // Delete cells whose contents were moved + res = DeleteNode(cell2); + if (NS_FAILED(res)) return res; + + } + return res; } NS_IMETHODIMP nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable) { - return NS_ERROR_NOT_IMPLEMENTED; + nsCOMPtr table; + nsresult res = NS_ERROR_FAILURE; + res = GetElementOrParentByTagName("table", aTable, getter_AddRefs(table)); + if (NS_FAILED(res)) return res; + // Don't fail if we didn't find a table + if (!table) return NS_OK; + + PRInt32 rowCount, colCount, rowIndex, colIndex; + res = GetTableSize(table, rowCount, colCount); + if (NS_FAILED(res)) return res; + + nsAutoEditBatch beginBatching(this); + + nsCOMPtr cell; + PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan; + PRBool isSelected; + +#if 0 +// This isn't working yet -- layout errors contribute! + + // First scan all cells in row to detect bad rowspan values + for(rowIndex = 0; rowIndex < rowCount; rowIndex++) + { + PRInt32 minRowSpan = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32 + for(colIndex = 0; colIndex < colCount; colIndex++) + { + res = GetCellDataAt(aTable, rowIndex, colIndex, *getter_AddRefs(cell), + startRowIndex, startColIndex, rowSpan, colSpan, + actualRowSpan, actualColSpan, isSelected); + // NOTE: This is a *real* failure. + // GetCellDataAt passes if cell is missing from cellmap + if(NS_FAILED(res)) return res; + if(cell && rowSpan > 0 && rowSpan < minRowSpan) + minRowSpan = rowSpan; + } + if(minRowSpan > 1) + { + PRInt32 spanDiff = minRowSpan - 1; + for(colIndex = 0; colIndex < colCount; colIndex++) + { + res = GetCellDataAt(aTable, rowIndex, colIndex, *getter_AddRefs(cell), + startRowIndex, startColIndex, rowSpan, colSpan, + actualRowSpan, actualColSpan, isSelected); + // NOTE: This is a *real* failure. + // GetCellDataAt passes if cell is missing from cellmap + if(NS_FAILED(res)) return res; + // Fixup rowspans for cells starting in current row + if(cell && rowSpan > 0 && + startRowIndex == rowIndex && + startColIndex == colIndex ) + { + // Set rowspan so there's at least one cell with ROWSPAN=1 + SetRowSpan(cell, rowSpan-spanDiff); + } + } + } + } + // Get Table size again in case above changed anything + res = GetTableSize(table, rowCount, colCount); + if (NS_FAILED(res)) return res; +#endif + + // Fill in missing cellmap locations with empty cells + for(rowIndex = 0; rowIndex < rowCount; rowIndex++) + { + nsCOMPtr previousCellInRow; + + for(colIndex = 0; colIndex < colCount; colIndex++) + { + res = GetCellDataAt(aTable, rowIndex, colIndex, *getter_AddRefs(cell), + startRowIndex, startColIndex, rowSpan, colSpan, + actualRowSpan, actualColSpan, isSelected); + // NOTE: This is a *real* failure. + // GetCellDataAt passes if cell is missing from cellmap + if(NS_FAILED(res)) return res; + if (!cell) + { + //We are missing a cell at a cellmap location +#ifdef DEBUG + printf("NormalizeTable found missing cell at row=%d, col=%d\n", rowIndex, colIndex); +#endif + // Add a cell after the previous Cell in the current row + if(previousCellInRow) + { + // Insert a new cell after (PR_TRUE), and return the new cell to us + res = InsertCell(previousCellInRow, 1, 1, PR_TRUE, getter_AddRefs(cell)); + if (NS_FAILED(res)) return res; + + // Set this so we use returned new "cell" to set previousCellInRow below + if(cell) + startRowIndex = rowIndex; + } else { + // We don't have any cells in this row -- We are really messed up! +#ifdef DEBUG + printf("NormalizeTable found no cells in row=%d, col=%d\n", rowIndex, colIndex); +#endif + return NS_ERROR_FAILURE; + } + } + // Save the last cell found in the same row we are scanning + if(startRowIndex == rowIndex) + { + previousCellInRow = cell; + } + } + } + return res; } NS_IMETHODIMP @@ -861,28 +1213,24 @@ PRBool nsHTMLEditor::GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowInd return cellCount; } -/* Not scriptable: For convenience in C++ */ +/* Not scriptable: For convenience in C++ + Use GetTableRowCount and GetTableColumnCount from JavaScript +*/ NS_IMETHODIMP nsHTMLEditor::GetTableSize(nsIDOMElement *aTable, PRInt32& aRowCount, PRInt32& aColCount) { - nsresult res=NS_ERROR_FAILURE; + nsresult res = NS_ERROR_FAILURE; aRowCount = 0; aColCount = 0; - if (!aTable) - { - // Get the selected talbe or the table enclosing the selection anchor - nsCOMPtr table; - res = GetElementOrParentByTagName("table", nsnull, getter_AddRefs(table)); - if (NS_FAILED(res)) return res; - if (table) - aTable = table; - else - return NS_ERROR_FAILURE; - } + nsCOMPtr table; + // Get the selected talbe or the table enclosing the selection anchor + res = GetElementOrParentByTagName("table", aTable, getter_AddRefs(table)); + if (NS_FAILED(res)) return res; + if (!table) return NS_ERROR_FAILURE; // frames are not ref counted, so don't use an nsCOMPtr nsITableLayout *tableLayoutObject; - res = GetTableLayoutObject(aTable, &tableLayoutObject); + res = GetTableLayoutObject(table.get(), &tableLayoutObject); if (NS_FAILED(res)) return res; if (!tableLayoutObject) return NS_ERROR_FAILURE; @@ -1134,7 +1482,7 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt3 } NS_IMETHODIMP -nsHTMLEditor::GetSelectedOrParentTableElement(nsCOMPtr &aTableElement, nsString& aTagName, PRBool &aIsSelected) +nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected) { aTableElement = nsnull; aTagName = ""; @@ -1145,50 +1493,57 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsCOMPtr &aTableEle if (NS_FAILED(res)) return res; if (!selection) return NS_ERROR_FAILURE; - nsAutoString table("table"); - nsAutoString tr("tr"); - nsAutoString td("td"); + nsAutoString tableName("table"); + nsAutoString trName("tr"); + nsAutoString tdName("td"); + + nsCOMPtr anchorNode; // Find the first selected cell // TODO: Handle multiple cells selected! nsCOMPtr firstCell; - res = GetFirstSelectedCell(aTableElement); + + nsCOMPtr tableElement; + res = GetFirstSelectedCell(tableElement); if(NS_FAILED(res)) return res; - if (aTableElement) + if (tableElement) { - aTagName = td; + aTagName = tdName; aIsSelected = PR_TRUE; - return NS_OK; + goto SET_RETURN_ELEMENT; } // See if table or row is selected - res = GetSelectedElement(table, getter_AddRefs(aTableElement)); + res = GetSelectedElement(tableName, getter_AddRefs(tableElement)); if(NS_FAILED(res)) return res; - if (aTableElement) + if (tableElement) { - aTagName = table; + aTagName = tableName; aIsSelected = PR_TRUE; - return NS_OK; + goto SET_RETURN_ELEMENT; } - res = GetSelectedElement(tr, getter_AddRefs(aTableElement)); + res = GetSelectedElement(trName, getter_AddRefs(tableElement)); if(NS_FAILED(res)) return res; - if (aTableElement) + if (tableElement) { - aTagName = tr; + aTagName = trName; aIsSelected = PR_TRUE; - return NS_OK; + goto SET_RETURN_ELEMENT; } // Look for a table cell parent - nsCOMPtr anchorNode; res = selection->GetAnchorNode(getter_AddRefs(anchorNode)); if (NS_FAILED(res)) return res; if (!anchorNode) return NS_ERROR_FAILURE; - res = GetElementOrParentByTagName(td, anchorNode, getter_AddRefs(aTableElement)); + res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement)); if(NS_FAILED(res)) return res; - if (aTableElement) - aTagName = td; - + if (tableElement) + { + aTagName = tdName; +SET_RETURN_ELEMENT: + aTableElement = tableElement.get(); + NS_ADDREF(aTableElement); + } return res; } diff --git a/mozilla/editor/base/nsEditProperty.cpp b/mozilla/editor/base/nsEditProperty.cpp index 6640482284f..ba97295effb 100644 --- a/mozilla/editor/base/nsEditProperty.cpp +++ b/mozilla/editor/base/nsEditProperty.cpp @@ -94,8 +94,9 @@ nsIAtom * nsIEditProperty::th; nsIAtom * nsIEditProperty::caption; nsIAtom * nsIEditProperty::col; nsIAtom * nsIEditProperty::colgroup; -nsIAtom * nsIEditProperty::thead; -nsIAtom * nsIEditProperty::tfoot; +nsIAtom * nsIEditProperty::tbody; +nsIAtom * nsIEditProperty::thead; +nsIAtom * nsIEditProperty::tfoot; nsIAtom * nsIEditProperty::li; nsIAtom * nsIEditProperty::dt; nsIAtom * nsIEditProperty::dd; @@ -195,6 +196,7 @@ nsEditProperty::nsEditProperty() nsIEditProperty::caption = NS_NewAtom("caption"); nsIEditProperty::col = NS_NewAtom("col"); nsIEditProperty::colgroup = NS_NewAtom("colgroup"); + nsIEditProperty::tbody = NS_NewAtom("tbody"); nsIEditProperty::thead = NS_NewAtom("thead"); nsIEditProperty::tfoot = NS_NewAtom("tfoot"); nsIEditProperty::li = NS_NewAtom("li"); @@ -274,6 +276,7 @@ nsEditProperty::~nsEditProperty() NS_IF_RELEASE(nsIEditProperty::caption); NS_IF_RELEASE(nsIEditProperty::col); NS_IF_RELEASE(nsIEditProperty::colgroup); + NS_IF_RELEASE(nsIEditProperty::tbody); NS_IF_RELEASE(nsIEditProperty::thead); NS_IF_RELEASE(nsIEditProperty::tfoot); NS_IF_RELEASE(nsIEditProperty::li); diff --git a/mozilla/editor/base/nsEditor.cpp b/mozilla/editor/base/nsEditor.cpp index 124fed3fe73..aa7a366cfa1 100644 --- a/mozilla/editor/base/nsEditor.cpp +++ b/mozilla/editor/base/nsEditor.cpp @@ -2758,6 +2758,7 @@ nsEditor::IsNodeBlock(nsIDOMNode *aNode, PRBool &aIsBlock) tagAtom==nsIEditProperty::caption || tagAtom==nsIEditProperty::col || tagAtom==nsIEditProperty::colgroup || + tagAtom==nsIEditProperty::tbody || tagAtom==nsIEditProperty::thead || tagAtom==nsIEditProperty::tfoot || tagAtom==nsIEditProperty::li || diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp index 062b72aa759..b0ae48a182e 100644 --- a/mozilla/editor/base/nsEditorShell.cpp +++ b/mozilla/editor/base/nsEditorShell.cpp @@ -3291,6 +3291,76 @@ nsEditorShell::GetCellDataAt(nsIDOMElement *tableElement, PRInt32 rowIndex, PRIn return result; } +NS_IMETHODIMP +nsEditorShell::GetFirstRow(nsIDOMElement *aTableElement, nsIDOMElement **_retval) +{ + if (!_retval || !aTableElement) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + if (tableEditor) + result = tableEditor->GetFirstRow(aTableElement, *_retval); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + +NS_IMETHODIMP +nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval) +{ + if (!_retval || !*_retval || !aCurrentRow) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + if (tableEditor) + result = tableEditor->GetNextRow(aCurrentRow, *_retval); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + +NS_IMETHODIMP +nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIsSelected, nsIDOMElement **_retval) +{ + if (!_retval || !aTagName || !aIsSelected) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + nsAutoString TagName(*aTagName); + if (tableEditor) + result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected); + // Need an ugly cast to get around "const" return value + *aTagName = (PRUnichar*)TagName.GetUnicode(); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + /* end of table editing */ NS_IMETHODIMP diff --git a/mozilla/editor/base/nsHTMLEditor.cpp b/mozilla/editor/base/nsHTMLEditor.cpp index 254d5836182..72aa7bd0148 100644 --- a/mozilla/editor/base/nsHTMLEditor.cpp +++ b/mozilla/editor/base/nsHTMLEditor.cpp @@ -2990,7 +2990,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBackgroundColor(const nsString& aColor) nsCOMPtr element; PRBool isSelected; nsAutoString tagName; - nsresult res = GetSelectedOrParentTableElement(element, tagName, isSelected); + nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, isSelected); if (NS_FAILED(res)) return res; if (!element) { @@ -5570,66 +5570,71 @@ nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement) if (aElement && IsElementInBody(aElement)) { nsresult res = NS_OK; - nsAutoString tagName; - aElement->GetNodeName(tagName); - tagName.ToLowerCase(); - if (tagName == "table" || tagName == "tr" || - tagName == "td" || tagName == "th" || - tagName == "thead" || tagName == "tfoot" || - tagName == "tbody" || tagName == "caption") + nsCOMPtr content = do_QueryInterface(aElement); + if (content) { - nsCOMPtr node = do_QueryInterface(aElement); - nsCOMPtr parent; - // This MUST succeed if IsElementInBody was TRUE - node->GetParentNode(getter_AddRefs(parent)); - nsCOMPtrfirstChild; - // Find deepest child - PRBool hasChild; - while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild) + nsCOMPtr atom; + content->GetTag(*getter_AddRefs(atom)); + if (atom.get() == nsIEditProperty::table || + atom.get() == nsIEditProperty::tbody || + atom.get() == nsIEditProperty::thead || + atom.get() == nsIEditProperty::tfoot || + atom.get() == nsIEditProperty::caption || + atom.get() == nsIEditProperty::tr || + atom.get() == nsIEditProperty::td ) { - if (NS_SUCCEEDED(node->GetFirstChild(getter_AddRefs(firstChild)))) + nsCOMPtr node = do_QueryInterface(aElement); + nsCOMPtr parent; + // This MUST succeed if IsElementInBody was TRUE + node->GetParentNode(getter_AddRefs(parent)); + nsCOMPtrfirstChild; + // Find deepest child + PRBool hasChild; + while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild) { - parent = node; - node = firstChild; + if (NS_SUCCEEDED(node->GetFirstChild(getter_AddRefs(firstChild)))) + { + parent = node; + node = firstChild; + } } - } # if 0 // I've ifdef'd this out because it isn't finished and I'm not sure what the intent is. - PRInt32 offset = 0; - nsCOMPtrlastChild; - res = parent->GetLastChild(getter_AddRefs(lastChild)); - if (NS_SUCCEEDED(res) && lastChild && node != lastChild) - { - if (node == lastChild) + PRInt32 offset = 0; + nsCOMPtrlastChild; + res = parent->GetLastChild(getter_AddRefs(lastChild)); + if (NS_SUCCEEDED(res) && lastChild && node != lastChild) { - // Check if node is text and has more than just a   - nsCOMPtrtextNode = do_QueryInterface(node); - nsAutoString text; - PRUnichar nbspStr[2] = {nbsp, 0}; - if (textNode && textNode->GetData(text)) + if (node == lastChild) { - // Set selection relative to the text node - parent = node; - PRInt32 len = text.Length(); - if (len > 1 || text != nbspStr) + // Check if node is text and has more than just a   + nsCOMPtrtextNode = do_QueryInterface(node); + nsAutoString text; + PRUnichar nbspStr[2] = {nbsp, 0}; + if (textNode && textNode->GetData(text)) { - offset = len; + // Set selection relative to the text node + parent = node; + PRInt32 len = text.Length(); + if (len > 1 || text != nbspStr) + { + offset = len; + } } + } else { + // We have > 1 node, so set to end of content } - } else { - // We have > 1 node, so set to end of content } - } #endif - // Set selection at beginning of deepest node - // Should we set - nsCOMPtr selection; - res = GetSelection(getter_AddRefs(selection)); - if (NS_SUCCEEDED(res) && selection && firstChild) - { - res = selection->Collapse(firstChild, 0); - if (NS_SUCCEEDED(res)) - caretIsSet = PR_TRUE; + // Set selection at beginning of deepest node + nsCOMPtr selection; + res = GetSelection(getter_AddRefs(selection)); + if (NS_SUCCEEDED(res) && selection && firstChild) + { + res = selection->Collapse(firstChild, 0); + if (NS_SUCCEEDED(res)) + caretIsSet = PR_TRUE; + } } } } diff --git a/mozilla/editor/base/nsHTMLEditor.h b/mozilla/editor/base/nsHTMLEditor.h index 231c3cf8ca3..dd6b98b4d18 100644 --- a/mozilla/editor/base/nsHTMLEditor.h +++ b/mozilla/editor/base/nsHTMLEditor.h @@ -190,8 +190,10 @@ public: PRInt32& aRowSpan, PRInt32& aColSpan, PRInt32& aActualRowSpan, PRInt32& aActualColSpan, PRBool& aIsSelected); + NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow); + NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow); NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection); - NS_IMETHOD GetSelectedOrParentTableElement(nsCOMPtr &aTableElement, nsString& aTagName, PRBool &aIsSelected); + NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected); // Selection and navigation @@ -321,14 +323,20 @@ protected: // Table utilities - NS_IMETHOD InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, PRBool aAfter); + // Insert a new cell after or before supplied aCell. + // Optional: If aNewCell supplied, returns the newly-created cell (addref'd, of course) + // This doesn't change or use the current selection + NS_IMETHOD InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, + PRBool aAfter, nsIDOMElement **aNewCell); NS_IMETHOD DeleteTable(nsCOMPtr &aTable, nsCOMPtr &aSelection); + NS_IMETHOD SetColSpan(nsIDOMElement *aCell, PRInt32 aColSpan); + NS_IMETHOD SetRowSpan(nsIDOMElement *aCell, PRInt32 aRowSpan); + // Helper used to get nsITableLayout interface for methods implemented in nsTableFrame NS_IMETHOD GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject); // Needed to do appropriate deleting when last cell or row is about to be deleted // This doesn't count cells that don't start in the given row (are spanning from row above) PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex); - nsresult GetRowAt(nsCOMPtr &aTable, PRInt32 rowIndex, nsCOMPtr &aRow); // Most insert methods need to get the same basic context data NS_IMETHOD GetCellContext(nsCOMPtr &aSelection, diff --git a/mozilla/editor/base/nsIEditProperty.h b/mozilla/editor/base/nsIEditProperty.h index 5dba2beeddc..a834a0bf836 100644 --- a/mozilla/editor/base/nsIEditProperty.h +++ b/mozilla/editor/base/nsIEditProperty.h @@ -109,6 +109,7 @@ public: static nsIAtom *caption; static nsIAtom *col; static nsIAtom *colgroup; + static nsIAtom *tbody; static nsIAtom *thead; static nsIAtom *tfoot; static nsIAtom *li; diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index 062b72aa759..b0ae48a182e 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -3291,6 +3291,76 @@ nsEditorShell::GetCellDataAt(nsIDOMElement *tableElement, PRInt32 rowIndex, PRIn return result; } +NS_IMETHODIMP +nsEditorShell::GetFirstRow(nsIDOMElement *aTableElement, nsIDOMElement **_retval) +{ + if (!_retval || !aTableElement) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + if (tableEditor) + result = tableEditor->GetFirstRow(aTableElement, *_retval); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + +NS_IMETHODIMP +nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval) +{ + if (!_retval || !*_retval || !aCurrentRow) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + if (tableEditor) + result = tableEditor->GetNextRow(aCurrentRow, *_retval); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + +NS_IMETHODIMP +nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIsSelected, nsIDOMElement **_retval) +{ + if (!_retval || !aTagName || !aIsSelected) + return NS_ERROR_NULL_POINTER; + + nsresult result = NS_NOINTERFACE; + switch (mEditorType) + { + case eHTMLTextEditorType: + { + nsCOMPtr tableEditor = do_QueryInterface(mEditor); + nsAutoString TagName(*aTagName); + if (tableEditor) + result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected); + // Need an ugly cast to get around "const" return value + *aTagName = (PRUnichar*)TagName.GetUnicode(); + } + break; + default: + result = NS_ERROR_NOT_IMPLEMENTED; + } + return result; +} + /* end of table editing */ NS_IMETHODIMP diff --git a/mozilla/editor/idl/nsIEditorShell.idl b/mozilla/editor/idl/nsIEditorShell.idl index 3651202b25c..b6c7030fc45 100644 --- a/mozilla/editor/idl/nsIEditorShell.idl +++ b/mozilla/editor/idl/nsIEditorShell.idl @@ -337,6 +337,30 @@ interface nsIEditorShell : nsISupports out PRInt32 actualRowSpan, out PRInt32 actualColSpan, out boolean isSelected); + /* Get the first row element in a table + tableElement may be a table or any child element a table + */ + nsIDOMElement GetFirstRow(in nsIDOMElement tableElement); + + /* Get the next row element in a table after currentRow + * currentRow may be a row or any child element of a row + */ + nsIDOMElement GetNextRow(in nsIDOMElement currentRow); + + /** Examine the current selection and find + * a selected TABLE, TD or TH, or TR element. + * or return the parent TD or TH if selection anchor is inside a table cell + * Returns null if no table element is found. + * + * Returns: + * The table element (table, row, or cell) found + * tagName The tagname of returned element + * Note that "td" will be returned if name is actually "th" + * isSelected Tells if element returned is a selected element + * (false if element is a parent cell of selection) + */ + nsIDOMElement GetSelectedOrParentTableElement(out wstring tagName, out boolean isSelected); + /**** end of table editing *****/ /* Get list of embedded objects, e.g. for mail compose */ diff --git a/mozilla/editor/libeditor/base/nsEditor.cpp b/mozilla/editor/libeditor/base/nsEditor.cpp index 124fed3fe73..aa7a366cfa1 100644 --- a/mozilla/editor/libeditor/base/nsEditor.cpp +++ b/mozilla/editor/libeditor/base/nsEditor.cpp @@ -2758,6 +2758,7 @@ nsEditor::IsNodeBlock(nsIDOMNode *aNode, PRBool &aIsBlock) tagAtom==nsIEditProperty::caption || tagAtom==nsIEditProperty::col || tagAtom==nsIEditProperty::colgroup || + tagAtom==nsIEditProperty::tbody || tagAtom==nsIEditProperty::thead || tagAtom==nsIEditProperty::tfoot || tagAtom==nsIEditProperty::li || diff --git a/mozilla/editor/libeditor/base/nsIEditProperty.h b/mozilla/editor/libeditor/base/nsIEditProperty.h index 5dba2beeddc..a834a0bf836 100644 --- a/mozilla/editor/libeditor/base/nsIEditProperty.h +++ b/mozilla/editor/libeditor/base/nsIEditProperty.h @@ -109,6 +109,7 @@ public: static nsIAtom *caption; static nsIAtom *col; static nsIAtom *colgroup; + static nsIAtom *tbody; static nsIAtom *thead; static nsIAtom *tfoot; static nsIAtom *li; diff --git a/mozilla/editor/libeditor/html/nsEditProperty.cpp b/mozilla/editor/libeditor/html/nsEditProperty.cpp index 6640482284f..ba97295effb 100644 --- a/mozilla/editor/libeditor/html/nsEditProperty.cpp +++ b/mozilla/editor/libeditor/html/nsEditProperty.cpp @@ -94,8 +94,9 @@ nsIAtom * nsIEditProperty::th; nsIAtom * nsIEditProperty::caption; nsIAtom * nsIEditProperty::col; nsIAtom * nsIEditProperty::colgroup; -nsIAtom * nsIEditProperty::thead; -nsIAtom * nsIEditProperty::tfoot; +nsIAtom * nsIEditProperty::tbody; +nsIAtom * nsIEditProperty::thead; +nsIAtom * nsIEditProperty::tfoot; nsIAtom * nsIEditProperty::li; nsIAtom * nsIEditProperty::dt; nsIAtom * nsIEditProperty::dd; @@ -195,6 +196,7 @@ nsEditProperty::nsEditProperty() nsIEditProperty::caption = NS_NewAtom("caption"); nsIEditProperty::col = NS_NewAtom("col"); nsIEditProperty::colgroup = NS_NewAtom("colgroup"); + nsIEditProperty::tbody = NS_NewAtom("tbody"); nsIEditProperty::thead = NS_NewAtom("thead"); nsIEditProperty::tfoot = NS_NewAtom("tfoot"); nsIEditProperty::li = NS_NewAtom("li"); @@ -274,6 +276,7 @@ nsEditProperty::~nsEditProperty() NS_IF_RELEASE(nsIEditProperty::caption); NS_IF_RELEASE(nsIEditProperty::col); NS_IF_RELEASE(nsIEditProperty::colgroup); + NS_IF_RELEASE(nsIEditProperty::tbody); NS_IF_RELEASE(nsIEditProperty::thead); NS_IF_RELEASE(nsIEditProperty::tfoot); NS_IF_RELEASE(nsIEditProperty::li); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 254d5836182..72aa7bd0148 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -2990,7 +2990,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBackgroundColor(const nsString& aColor) nsCOMPtr element; PRBool isSelected; nsAutoString tagName; - nsresult res = GetSelectedOrParentTableElement(element, tagName, isSelected); + nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, isSelected); if (NS_FAILED(res)) return res; if (!element) { @@ -5570,66 +5570,71 @@ nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement) if (aElement && IsElementInBody(aElement)) { nsresult res = NS_OK; - nsAutoString tagName; - aElement->GetNodeName(tagName); - tagName.ToLowerCase(); - if (tagName == "table" || tagName == "tr" || - tagName == "td" || tagName == "th" || - tagName == "thead" || tagName == "tfoot" || - tagName == "tbody" || tagName == "caption") + nsCOMPtr content = do_QueryInterface(aElement); + if (content) { - nsCOMPtr node = do_QueryInterface(aElement); - nsCOMPtr parent; - // This MUST succeed if IsElementInBody was TRUE - node->GetParentNode(getter_AddRefs(parent)); - nsCOMPtrfirstChild; - // Find deepest child - PRBool hasChild; - while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild) + nsCOMPtr atom; + content->GetTag(*getter_AddRefs(atom)); + if (atom.get() == nsIEditProperty::table || + atom.get() == nsIEditProperty::tbody || + atom.get() == nsIEditProperty::thead || + atom.get() == nsIEditProperty::tfoot || + atom.get() == nsIEditProperty::caption || + atom.get() == nsIEditProperty::tr || + atom.get() == nsIEditProperty::td ) { - if (NS_SUCCEEDED(node->GetFirstChild(getter_AddRefs(firstChild)))) + nsCOMPtr node = do_QueryInterface(aElement); + nsCOMPtr parent; + // This MUST succeed if IsElementInBody was TRUE + node->GetParentNode(getter_AddRefs(parent)); + nsCOMPtrfirstChild; + // Find deepest child + PRBool hasChild; + while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild) { - parent = node; - node = firstChild; + if (NS_SUCCEEDED(node->GetFirstChild(getter_AddRefs(firstChild)))) + { + parent = node; + node = firstChild; + } } - } # if 0 // I've ifdef'd this out because it isn't finished and I'm not sure what the intent is. - PRInt32 offset = 0; - nsCOMPtrlastChild; - res = parent->GetLastChild(getter_AddRefs(lastChild)); - if (NS_SUCCEEDED(res) && lastChild && node != lastChild) - { - if (node == lastChild) + PRInt32 offset = 0; + nsCOMPtrlastChild; + res = parent->GetLastChild(getter_AddRefs(lastChild)); + if (NS_SUCCEEDED(res) && lastChild && node != lastChild) { - // Check if node is text and has more than just a   - nsCOMPtrtextNode = do_QueryInterface(node); - nsAutoString text; - PRUnichar nbspStr[2] = {nbsp, 0}; - if (textNode && textNode->GetData(text)) + if (node == lastChild) { - // Set selection relative to the text node - parent = node; - PRInt32 len = text.Length(); - if (len > 1 || text != nbspStr) + // Check if node is text and has more than just a   + nsCOMPtrtextNode = do_QueryInterface(node); + nsAutoString text; + PRUnichar nbspStr[2] = {nbsp, 0}; + if (textNode && textNode->GetData(text)) { - offset = len; + // Set selection relative to the text node + parent = node; + PRInt32 len = text.Length(); + if (len > 1 || text != nbspStr) + { + offset = len; + } } + } else { + // We have > 1 node, so set to end of content } - } else { - // We have > 1 node, so set to end of content } - } #endif - // Set selection at beginning of deepest node - // Should we set - nsCOMPtr selection; - res = GetSelection(getter_AddRefs(selection)); - if (NS_SUCCEEDED(res) && selection && firstChild) - { - res = selection->Collapse(firstChild, 0); - if (NS_SUCCEEDED(res)) - caretIsSet = PR_TRUE; + // Set selection at beginning of deepest node + nsCOMPtr selection; + res = GetSelection(getter_AddRefs(selection)); + if (NS_SUCCEEDED(res) && selection && firstChild) + { + res = selection->Collapse(firstChild, 0); + if (NS_SUCCEEDED(res)) + caretIsSet = PR_TRUE; + } } } } diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 231c3cf8ca3..dd6b98b4d18 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -190,8 +190,10 @@ public: PRInt32& aRowSpan, PRInt32& aColSpan, PRInt32& aActualRowSpan, PRInt32& aActualColSpan, PRBool& aIsSelected); + NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow); + NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow); NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection); - NS_IMETHOD GetSelectedOrParentTableElement(nsCOMPtr &aTableElement, nsString& aTagName, PRBool &aIsSelected); + NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected); // Selection and navigation @@ -321,14 +323,20 @@ protected: // Table utilities - NS_IMETHOD InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, PRBool aAfter); + // Insert a new cell after or before supplied aCell. + // Optional: If aNewCell supplied, returns the newly-created cell (addref'd, of course) + // This doesn't change or use the current selection + NS_IMETHOD InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpan, + PRBool aAfter, nsIDOMElement **aNewCell); NS_IMETHOD DeleteTable(nsCOMPtr &aTable, nsCOMPtr &aSelection); + NS_IMETHOD SetColSpan(nsIDOMElement *aCell, PRInt32 aColSpan); + NS_IMETHOD SetRowSpan(nsIDOMElement *aCell, PRInt32 aRowSpan); + // Helper used to get nsITableLayout interface for methods implemented in nsTableFrame NS_IMETHOD GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject); // Needed to do appropriate deleting when last cell or row is about to be deleted // This doesn't count cells that don't start in the given row (are spanning from row above) PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex); - nsresult GetRowAt(nsCOMPtr &aTable, PRInt32 rowIndex, nsCOMPtr &aRow); // Most insert methods need to get the same basic context data NS_IMETHOD GetCellContext(nsCOMPtr &aSelection, diff --git a/mozilla/editor/public/nsITableEditor.h b/mozilla/editor/public/nsITableEditor.h index b595d162637..86355b6ca43 100644 --- a/mozilla/editor/public/nsITableEditor.h +++ b/mozilla/editor/public/nsITableEditor.h @@ -93,6 +93,9 @@ public: * a collection of cells that extend past the * previous size of the table * If aTable is null, it uses table enclosing the selection anchor + * This doesn't doesn't change the selection, + * thus it can be used to fixup all tables + * in a page independant of the selection */ NS_IMETHOD NormalizeTable(nsIDOMElement *aTable)=0; @@ -156,7 +159,28 @@ public: PRInt32& aActualRowSpan, PRInt32& aActualColSpan, PRBool& aIsSelected)=0; + /** Get the first row element in a table + * + * @param aTableElement Any TABLE or child-of-table element in the document + * @param aRowIndex The 0-based index of the row + * + * Returns: + * @param aRow The row at the requested index + * Returns null if there are no rows in table + */ + NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)=0; + /** Get the next row element starting the search from aTableElement + * + * @param aTableElement Any TR or child-of-TR element in the document + * + * Returns: + * @param aRow The row to start search from + * and the row returned from the search + * Returns null if there isn't another row + */ + NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)=0; + /** Preferred direction to search for neighboring cell * when trying to locate a cell to place caret in after * a table editing action. @@ -196,7 +220,7 @@ public: * @param aIsSelected Tells if element returned is a selected element * (false if element is a parent cell of selection) */ - NS_IMETHOD GetSelectedOrParentTableElement(nsCOMPtr &aTableElement, nsString& aTagName, PRBool &aIsSelected)=0; + NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)=0; }; diff --git a/mozilla/editor/ui/composer/content/EditorCommands.js b/mozilla/editor/ui/composer/content/EditorCommands.js index 23bdfeb08db..1c81bed6973 100644 --- a/mozilla/editor/ui/composer/content/EditorCommands.js +++ b/mozilla/editor/ui/composer/content/EditorCommands.js @@ -420,7 +420,15 @@ function EditorShowClipboard() function EditorViewSource() { - window.openDialog( "chrome://editor/content/viewsource.xul", "_blank", "all,dialog=no", window.content.location ); + // *** THIS IS NOT CORRECT - It simply loads the content from original URL, + // which will now show current editor document changes. + + // Use a browser window to view source + window.openDialog( "chrome://navigator/content/", + "_blank", + "chrome,menubar,status,dialog=no,resizable", + window.content.location, + "view-source" ); } @@ -629,6 +637,20 @@ function EditorSelectBackColor(ColorPickerID, ColorWellID) EditorSetBackgroundColor(color); } +function EditorRemoveTextColor(ColorWellID) +{ + //TODO: Set colorwell to browser's default color + editorShell.SetTextProperty("font", "color", ""); + contentWindow.focus(); +} + +function EditorRemoveBackColor(ColorWellID) +{ + //TODO: Set colorwell to browser's default color + editorShell.SetBackgroundColor(""); + contentWindow.focus(); +} + function EditorSetFontColor(color) { editorShell.SetTextProperty("font", "color", color); @@ -731,7 +753,7 @@ function EditorListProperties() function EditorPageProperties(startTab) { - window.openDialog("chrome://editor/content/EdPageProps.xul","_blank", "chrome,close,titlebar,modal", startTab); + window.openDialog("chrome://editor/content/EdPageProps.xul","_blank", "chrome,close,titlebar,modal", "", startTab); contentWindow.focus(); } @@ -869,112 +891,6 @@ function EditorIndent(indent) contentWindow.focus(); } -// Call this with insertAllowed = true to allow inserting if not in existing table, -// else use false to do nothing if not in a table -function EditorInsertOrEditTable(insertAllowed) -{ - var table = editorShell.GetElementOrParentByTagName("table", null); - if (table) { - // Edit properties of existing table - dump("Existing table found ... Editing its properties\n"); - - window.openDialog("chrome://editor/content/EdTableProps.xul", "_blank", "chrome,close,titlebar,modal", ""); - contentWindow.focus(); - } else if(insertAllowed) { - EditorInsertTable(); - } -} - -function EditorSelectTable() -{ - //TODO: FINISH THIS! - contentWindow.focus(); -} - -function EditorSelectTableRow() -{ - //TODO: FINISH THIS! - contentWindow.focus(); -} - -function EditorSelectTableColumn() -{ - //TODO: FINISH THIS! - contentWindow.focus(); -} - -function EditorSelectTableCell() -{ - //TODO: FINISH THIS! - contentWindow.focus(); -} - -function EditorInsertTable() -{ - // Insert a new table - window.openDialog("chrome://editor/content/EdInsertTable.xul", "_blank", "chrome,close,titlebar,modal", ""); - contentWindow.focus(); -} - -function EditorInsertTableCell(after) -{ - editorShell.InsertTableCell(1,after); - contentWindow.focus(); -} - -function EditorInsertTableRow(below) -{ - editorShell.InsertTableRow(1,below); - contentWindow.focus(); -} - -function EditorInsertTableColumn(after) -{ - editorShell.InsertTableColumn(1,after); - contentWindow.focus(); -} - -function JoinTableCells() -{ - editorShell.JoinTableCells(); - contentWindow.focus(); -} - -function EditorDeleteTable() -{ - editorShell.DeleteTable(); - contentWindow.focus(); -} - -function EditorDeleteTableRow() -{ - // TODO: Get the number of rows to delete from the selection - editorShell.DeleteTableRow(1); - contentWindow.focus(); -} - -function EditorDeleteTableColumn() -{ - // TODO: Get the number of cols to delete from the selection - editorShell.DeleteTableColumn(1); - contentWindow.focus(); -} - - -function EditorDeleteTableCell() -{ - // TODO: Get the number of cells to delete from the selection - editorShell.DeleteTableCell(1); - contentWindow.focus(); -} - -function EditorDeleteTableCellContents() -{ - // TODO: Get the number of cells to delete from the selection - editorShell.DeleteTableCellContents(); - contentWindow.focus(); -} - function EditorMakeOrChangeList(listType) { // check the observer node, @@ -1382,3 +1298,179 @@ function getColorAndSetColorWell(ColorPickerID, ColorWellID) return color; } + +// Call this with insertAllowed = true to allow inserting if not in existing table, +// else use false to do nothing if not in a table +function EditorInsertOrEditTable(insertAllowed) +{ + var table = editorShell.GetElementOrParentByTagName("table", null); + if (table) { + // Edit properties of existing table + dump("Existing table found ... Editing its properties\n"); + + window.openDialog("chrome://editor/content/EdTableProps.xul", "_blank", "chrome,close,titlebar,modal", ""); + contentWindow.focus(); + } else if(insertAllowed) { + EditorInsertTable(); + } +} + +function GetChildOffset(parent,child) +{ + if (!parent || !child) + return null; + + var nodeList = parent.childNodes; + var i; + if (nodeList) + { + for ( i = 0; i - + + diff --git a/mozilla/editor/ui/composer/content/editorOverlay.xul b/mozilla/editor/ui/composer/content/editorOverlay.xul index 9707ec1c405..348b758bc03 100644 --- a/mozilla/editor/ui/composer/content/editorOverlay.xul +++ b/mozilla/editor/ui/composer/content/editorOverlay.xul @@ -486,8 +486,6 @@ accesskey="&formatstylesheetmenu.accesskey;" position="13"> - - @@ -527,14 +525,14 @@ position="19"/> + oncommand="EditorPageProperties('GeneralTab')"/> @@ -570,6 +568,7 @@ + @@ -579,6 +578,7 @@ &textColorCaption.label; + @@ -586,6 +586,7 @@ Background Color + diff --git a/mozilla/editor/ui/composer/content/makefile.win b/mozilla/editor/ui/composer/content/makefile.win index 1adff941746..3b57d301922 100644 --- a/mozilla/editor/ui/composer/content/makefile.win +++ b/mozilla/editor/ui/composer/content/makefile.win @@ -30,7 +30,6 @@ install:: $(MAKE_INSTALL) EditorCommandsDebug.js $(DIST)\bin\chrome\editor\content\default $(MAKE_INSTALL) EditorInitPage.html $(DIST)\bin\chrome\editor\content\default $(MAKE_INSTALL) EditorInitPagePlain.html $(DIST)\bin\chrome\editor\content\default - $(MAKE_INSTALL) EditorStyles1.css $(DIST)\bin\chrome\editor\content\default $(MAKE_INSTALL) EditorContent.css $(DIST)\bin\chrome\editor\content\default $(MAKE_INSTALL) EditorOverride.css $(DIST)\bin\chrome\editor\content\default $(MAKE_INSTALL) sidebar-editor.rdf $(DIST)\bin\chrome\editor\content\default @@ -53,7 +52,6 @@ clobber:: rm -f $(DIST)\bin\chrome\editor\content\default\EditorCommandsDebug.js rm -f $(DIST)\bin\chrome\editor\content\default\EditorInitPage.html rm -f $(DIST)\bin\chrome\editor\content\default\EditorInitPagePlain.html - rm -f $(DIST)\bin\chrome\editor\content\default\EditorStyles1.css rm -f $(DIST)\bin\chrome\editor\content\default\EditorContent.css rm -f $(DIST)\bin\chrome\editor\content\default\EditorOverride.css rm -f $(DIST)\bin\chrome\editor\content\default\sidebar-editor.rdf diff --git a/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd b/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd index 58b3a01bcb3..af31ac37694 100644 --- a/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd +++ b/mozilla/editor/ui/composer/locale/en-US/editorOverlay.dtd @@ -101,7 +101,7 @@ - + @@ -374,8 +374,6 @@ - - @@ -445,7 +443,9 @@ - + + + @@ -505,6 +505,7 @@ + diff --git a/mozilla/editor/ui/dialogs/content/EdPageProps.js b/mozilla/editor/ui/dialogs/content/EdPageProps.js index 6369a8019da..83654928b9a 100644 --- a/mozilla/editor/ui/dialogs/content/EdPageProps.js +++ b/mozilla/editor/ui/dialogs/content/EdPageProps.js @@ -20,11 +20,10 @@ * Contributor(s): */ -var textColor; -var linkColor; -var followedLinkColor; -var activeLinkColor; -var backgroundColor; +var tabPanel; +var currentTab; +var colorPage; +var colorIndex = 0; //Cancel() is in EdDialogCommon.js // dialog initialization code @@ -33,10 +32,54 @@ function Startup() if (!InitEditorShell()) return; + colorPage = new Object; + if (!colorPage) + { + dump("Failed to create colorPage object!!!\n"); + window.close(); + } + + colorPage.ColorPreview = document.getElementById("ColorPreview"); + colorPage.NormalText = document.getElementById("NormalText"); + colorPage.LinkText = document.getElementById("LinkText"); + colorPage.ActiveLinkText = document.getElementById("ActiveLinkText"); + colorPage.FollowedLinkText = document.getElementById("FollowedLinkText"); + +// colorPage. = documentgetElementById(""); + + tabPanel = document.getElementById("tabPanel"); + + // Set the starting Tab: + var tabName = window.arguments[1]; + currentTab = document.getElementById(tabName); + if (!currentTab) + currentTab = document.getElementById("GeneralTab"); + + if (!tabPanel || !currentTab) + { + dump("Not all dialog controls were found!!!\n"); + window.close; + } + + // Trigger setting of style for the selected tab widget + currentTab.setAttribute("selected", "true"); + // Activate the corresponding panel + var index = 0; + switch(tabName) + { + case "ColorTab": + index = 1; + break; + case "MetaTab": + index = 2; + break; + } + tabPanel.setAttribute("index",index); + doSetOKCancel(onOK, null); - initDialog(); - + InitDialog(); + //.focus(); } @@ -44,29 +87,47 @@ function InitDialog() { } -function getColor(ColorPickerID, ColorWellID) +function GetColor(ColorPickerID, ColorWellID) { var color = getColorAndSetColorWell(ColorPickerID, ColorWellID); +dump("GetColor, color="+color+"\n"); + if (!color) + { + // No color was clicked on, + // so user clicked on "Don't Specify Color" button + color = "inherit"; + dump("Don't specify color\n"); + } + var colorString = "color:"+color; switch( ColorPickerID ) { case "textCP": - textColor = color; + colorPage.textColor = color; + colorPage.NormalText.setAttribute("style",colorString); break; case "linkCP": - linkColor = color; + colorPage.linkColor = color; + colorPage.LinkText.setAttribute("style",colorString); break; case "followedCP": - followedLinkColor = color; + colorPage.followedLinkColor = color; + colorPage.FollowedLinkText.setAttribute("style",colorString); break; case "activeCP": - activeLinkColor = color; + colorPage.activeLinkColor = color; + colorPage.ActiveLinkText.setAttribute("style",colorString); break; case "backgroundCP": - backgroundColor = color; + colorPage.backgroundColor = color; + colorPage.ColorPreview.setAttribute("bgcolor",color); break; } } +function RemoveColor(ColorWellID) +{ +} + function onOK() { diff --git a/mozilla/editor/ui/dialogs/content/EdPageProps.xul b/mozilla/editor/ui/dialogs/content/EdPageProps.xul index 0f0ddcfc84f..4f45f9cb36c 100644 --- a/mozilla/editor/ui/dialogs/content/EdPageProps.xul +++ b/mozilla/editor/ui/dialogs/content/EdPageProps.xul @@ -45,14 +45,14 @@ - &generalTab.label; - &backgroundTab.label; - &metaTagsTab.label; + &generalTab.label; + &backgroundTab.label; + &metaTagsTab.label; - - - + + + @@ -97,85 +97,127 @@ - - + + &pageColors.label; - - &defaultColorsRadio.label; - - - &customColorsRadio.label; - - - &colorScheme.label; - - - - - - - - - - - - - - - - - - - - - - - - - + + &defaultColorsRadio.label; + + + &customColorsRadio.label; + + + + + &colorScheme.label; + + Black on White + Blue on White + White on Black + + + + + + + + + + + &normalText.label; + + + + + + + + + + + + + &linkText.label; + + + + + + + + + + + + + &activeLinkText.label; + + + + + + + + + + + + + &followedLinkText.label; + + + + + + + + + + + + + &background.label; + + + + + + + + + - -
+ + + + &normalText.label; + + &linkText.label; + + &activeLinkText.label; + + &followedLinkText.label; + + - - &backgroundImage.label; - + &backgroundImage.label; - + - - + + - - - - - - - - - - - - - - - - - - - diff --git a/mozilla/editor/ui/dialogs/locale/en-US/EditorPageProperties.dtd b/mozilla/editor/ui/dialogs/locale/en-US/EditorPageProperties.dtd index 5a4c45d03a4..41dd1846474 100644 --- a/mozilla/editor/ui/dialogs/locale/en-US/EditorPageProperties.dtd +++ b/mozilla/editor/ui/dialogs/locale/en-US/EditorPageProperties.dtd @@ -32,11 +32,12 @@ - - - - - - - - + + + + + + + + + diff --git a/mozilla/editor/ui/dialogs/skin/EditorDialog.css b/mozilla/editor/ui/dialogs/skin/EditorDialog.css index ed7d6a0ddac..c89fa5df276 100644 --- a/mozilla/editor/ui/dialogs/skin/EditorDialog.css +++ b/mozilla/editor/ui/dialogs/skin/EditorDialog.css @@ -55,25 +55,31 @@ div#message { margin-left: 10px; } -div.color-well { - width:30px; - border: 1px inset white; - /* Background color is set at runtime */ - background-color:white; -} - -div#TextSampleWindow { - border: 1px inset white; - width: 100px; - height: 100px; - background-color:white; -} - div.middle-align { vertical-align: middle; } +label.margin-both { + margin-left: 10px; + margin-right: 5px; +} + +div.color-well { + width:20px; + border: 1px inset #CCCCCC; + /* Background color is set at runtime */ + background-color: red; +} + /* XUL ELEMENTS */ +box#ColorPreview { + border: 1px inset #CCCCCC; + padding: 5px; + width: 100%; + min-height: 50px; + height: 100px; + background-color: white; +} /* values = margin, padding. Padding doesn't work yet */ @@ -116,6 +122,11 @@ titledbutton#MisspelledWord { font-weight: bold; } +/* need rule for outset shape */ +menu.colorpicker { + border: 1px outset #CCCCCC; +} + titledbutton.color-well { list-style-image:url("chrome://editor/skin/images/color.gif"); border: 1px solid #CCCCCC;