зеркало из https://github.com/mozilla/gecko-dev.git
More table editing work (bug 20973) and Page Properies dialog work (bug 14344). Added missing 'tbody' to nsIAtoms list. r=mjudge
This commit is contained in:
Родитель
c464f6f9f3
Коммит
894a83b297
|
@ -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<nsIDOMNode> cellParent;
|
||||
|
@ -91,29 +95,68 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMNode> &aNode)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsCOMPtr<nsIContent> 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<nsIDOMElement> &aTable, PRInt32 rowIndex, nsCOMPtr<nsIDOMElement> &aRow)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
|
||||
{
|
||||
aRow = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> tableElement;
|
||||
nsresult res = GetElementOrParentByTagName("table", aTableElement, getter_AddRefs(tableElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!tableElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode>tableNode = do_QueryInterface(tableElement);
|
||||
if (!tableNode) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> tableChild;
|
||||
res = tableNode->GetFirstChild(getter_AddRefs(tableChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
while (tableChild)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(tableChild);
|
||||
if (content)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
content->GetTag(*getter_AddRefs(atom));
|
||||
if (atom.get() == nsIEditProperty::tr)
|
||||
{
|
||||
// Found a row directly under <table>
|
||||
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<nsIDOMNode> 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<nsIDOMElement> nextRow;
|
||||
PRInt32 index = 0;
|
||||
nsAutoString tagName("tr");
|
||||
|
||||
nsresult res = GetNextElementByTagName(aTable, &tagName, getter_AddRefs(nextRow));
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMElement> parentTable;
|
||||
res = GetElementOrParentByTagName("table", nextRow, getter_AddRefs(parentTable));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!parentTable) return NS_ERROR_NULL_POINTER;
|
||||
nsCOMPtr<nsIDOMNode> rowNode = do_QueryInterface(rowElement);
|
||||
if (!rowNode) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> nextRow;
|
||||
nsCOMPtr<nsIDOMNode> rowParent;
|
||||
nsCOMPtr<nsIDOMNode> parentSibling;
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMElement> 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<nsIDOMNode> lastCell;
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMElement> 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<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMSelection> &aSelection)
|
||||
{
|
||||
|
@ -467,12 +648,9 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMElement> 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<nsIDOMElement> 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<nsIDOMSelection> selection;
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMElement> 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<nsIDOMNode> parentNode = do_QueryInterface(cellParent);
|
||||
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
|
||||
nsCOMPtr<nsIDOMNode> cellNode2 = do_QueryInterface(cell2);
|
||||
if(cellNode && cellNode2 && parentNode)
|
||||
{
|
||||
PRInt32 insertIndex = 0;
|
||||
|
||||
// Get index of last child in target cell
|
||||
nsCOMPtr<nsIDOMNodeList> 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<nsIDOMNode> cellChild;
|
||||
res = cell2->GetFirstChild(getter_AddRefs(cellChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
while (cellChild)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMElement> 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<nsIDOMElement> 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<nsIDOMElement> 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<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName("table", nsnull, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (table)
|
||||
aTable = table;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMElement> &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
||||
{
|
||||
aTableElement = nsnull;
|
||||
aTagName = "";
|
||||
|
@ -1145,50 +1493,57 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsCOMPtr<nsIDOMElement> &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<nsIDOMNode> anchorNode;
|
||||
|
||||
// Find the first selected cell
|
||||
// TODO: Handle multiple cells selected!
|
||||
nsCOMPtr<nsIDOMElement> firstCell;
|
||||
res = GetFirstSelectedCell(aTableElement);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMNode> 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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<nsITableEditor> 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<nsITableEditor> 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<nsITableEditor> 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
|
||||
|
|
|
@ -2990,7 +2990,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
|||
nsCOMPtr<nsIDOMElement> 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<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (content)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
// This MUST succeed if IsElementInBody was TRUE
|
||||
node->GetParentNode(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIDOMNode>firstChild;
|
||||
// Find deepest child
|
||||
PRBool hasChild;
|
||||
while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild)
|
||||
nsCOMPtr<nsIAtom> 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<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
// This MUST succeed if IsElementInBody was TRUE
|
||||
node->GetParentNode(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIDOMNode>firstChild;
|
||||
// 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;
|
||||
nsCOMPtr<nsIDOMNode>lastChild;
|
||||
res = parent->GetLastChild(getter_AddRefs(lastChild));
|
||||
if (NS_SUCCEEDED(res) && lastChild && node != lastChild)
|
||||
{
|
||||
if (node == lastChild)
|
||||
PRInt32 offset = 0;
|
||||
nsCOMPtr<nsIDOMNode>lastChild;
|
||||
res = parent->GetLastChild(getter_AddRefs(lastChild));
|
||||
if (NS_SUCCEEDED(res) && lastChild && node != lastChild)
|
||||
{
|
||||
// Check if node is text and has more than just a  
|
||||
nsCOMPtr<nsIDOMCharacterData>textNode = 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  
|
||||
nsCOMPtr<nsIDOMCharacterData>textNode = 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<nsIDOMSelection> 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<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_SUCCEEDED(res) && selection && firstChild)
|
||||
{
|
||||
res = selection->Collapse(firstChild, 0);
|
||||
if (NS_SUCCEEDED(res))
|
||||
caretIsSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<nsIDOMElement> &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<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMSelection> &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<nsIDOMElement> &aTable, PRInt32 rowIndex, nsCOMPtr<nsIDOMElement> &aRow);
|
||||
|
||||
// Most insert methods need to get the same basic context data
|
||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<nsITableEditor> 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<nsITableEditor> 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<nsITableEditor> 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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -2990,7 +2990,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
|||
nsCOMPtr<nsIDOMElement> 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<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (content)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
// This MUST succeed if IsElementInBody was TRUE
|
||||
node->GetParentNode(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIDOMNode>firstChild;
|
||||
// Find deepest child
|
||||
PRBool hasChild;
|
||||
while (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild)
|
||||
nsCOMPtr<nsIAtom> 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<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
// This MUST succeed if IsElementInBody was TRUE
|
||||
node->GetParentNode(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIDOMNode>firstChild;
|
||||
// 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;
|
||||
nsCOMPtr<nsIDOMNode>lastChild;
|
||||
res = parent->GetLastChild(getter_AddRefs(lastChild));
|
||||
if (NS_SUCCEEDED(res) && lastChild && node != lastChild)
|
||||
{
|
||||
if (node == lastChild)
|
||||
PRInt32 offset = 0;
|
||||
nsCOMPtr<nsIDOMNode>lastChild;
|
||||
res = parent->GetLastChild(getter_AddRefs(lastChild));
|
||||
if (NS_SUCCEEDED(res) && lastChild && node != lastChild)
|
||||
{
|
||||
// Check if node is text and has more than just a  
|
||||
nsCOMPtr<nsIDOMCharacterData>textNode = 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  
|
||||
nsCOMPtr<nsIDOMCharacterData>textNode = 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<nsIDOMSelection> 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<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_SUCCEEDED(res) && selection && firstChild)
|
||||
{
|
||||
res = selection->Collapse(firstChild, 0);
|
||||
if (NS_SUCCEEDED(res))
|
||||
caretIsSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<nsIDOMElement> &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<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMSelection> &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<nsIDOMElement> &aTable, PRInt32 rowIndex, nsCOMPtr<nsIDOMElement> &aRow);
|
||||
|
||||
// Most insert methods need to get the same basic context data
|
||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||
|
|
|
@ -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<nsIDOMElement> &aTableElement, nsString& aTagName, PRBool &aIsSelected)=0;
|
||||
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)=0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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<nodeList.length; i++)
|
||||
{
|
||||
if (nodeList.item(i) == child)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function AppendNodeToSelection(selection, node)
|
||||
{
|
||||
if (selection && node)
|
||||
{
|
||||
var parent = node.parentNode;
|
||||
var offset = GetChildOffset(parent,node);
|
||||
if (offset)
|
||||
{
|
||||
var range = editorShell.editorDocument.createRange();
|
||||
if (range)
|
||||
{
|
||||
range.setStart(parent,offset);
|
||||
range.setEnd(parent,offset+1);
|
||||
selection.addRange(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function EditorSelectTableCell()
|
||||
{
|
||||
var selection = editorShell.editorSelection;
|
||||
if (selection)
|
||||
{
|
||||
var cellNode = editorShell.GetElementOrParentByTagName("td",selection.anchorNode);
|
||||
if (cellNode)
|
||||
{
|
||||
selection.clearSelection();
|
||||
AppendNodeToSelection(selection, cellNode);
|
||||
}
|
||||
}
|
||||
contentWindow.focus();
|
||||
}
|
||||
|
||||
function EditorSelectTable()
|
||||
{
|
||||
var selection = editorShell.editorSelection;
|
||||
if (selection)
|
||||
{
|
||||
var tableNode = editorShell.GetElementOrParentByTagName("table",selection.anchorNode);
|
||||
if (tableNode)
|
||||
{
|
||||
selection.clearSelection();
|
||||
AppendNodeToSelection(selection, tableNode);
|
||||
}
|
||||
}
|
||||
contentWindow.focus();
|
||||
}
|
||||
|
||||
function EditorSelectTableRow()
|
||||
{
|
||||
var tagNameObj = new Object();
|
||||
var isSelectedObj = new Object();
|
||||
var tagName;
|
||||
var isSelected;
|
||||
var tableElement = editorShell.GetSelectedOrParentTableElement(tagNameObj,isSelectedObj);
|
||||
tagName = tagNameObj.value;
|
||||
isSelected = isSelectedObj.value;
|
||||
dump("Table element="+tableElement+" Tagname="+tagName+" IsSelected="+isSelected+"\n");
|
||||
|
||||
//TODO: FINISH THIS!
|
||||
contentWindow.focus();
|
||||
}
|
||||
|
||||
function EditorSelectTableColumn()
|
||||
{
|
||||
//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 EditorNormalizeTable()
|
||||
{
|
||||
editorShell.NormalizeTable(null);
|
||||
contentWindow.focus();
|
||||
}
|
||||
|
||||
function EditorJoinTableCells()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -81,8 +81,8 @@
|
|||
<menupopup id="menu_View_Popup">
|
||||
<menu id="viewToolbar"/>
|
||||
|
||||
<!-- menuseparator /> Put this back when it works.
|
||||
<menuitem id="viewSourceMenuitem"/ -->
|
||||
<menuseparator/>
|
||||
<menuitem id="viewSourceMenuitem"/>
|
||||
<menuseparator />
|
||||
<menu id="charsetMenu"/>
|
||||
<menu id="charsetMenu1"/>
|
||||
|
|
|
@ -486,8 +486,6 @@
|
|||
accesskey="&formatstylesheetmenu.accesskey;"
|
||||
position="13">
|
||||
<menupopup>
|
||||
<menuitem value="&stylesheetEditorOneCmd.label;" accesskey="&sseditor1.accesskey;" oncommand="EditorApplyStyleSheet('chrome://editor/content/EditorStyles1.css')"/>
|
||||
<menuseparator />
|
||||
<menuitem value="&stylesheetOldstyleCmd.label;" accesskey="&ssoldstyle.accesskey;" oncommand="EditorApplyStyleSheet('http://www.w3.org/StyleSheets/Core/Oldstyle')"/>
|
||||
<menuitem value="&stylesheetModernistCmd.label;" accesskey="&ssmodernist.accesskey;" oncommand="EditorApplyStyleSheet('http://www.w3.org/StyleSheets/Core/Modernist')"/>
|
||||
<menuitem value="&stylesheetMidnightCmd.label;" accesskey="&ssmidnight.accesskey;" oncommand="EditorApplyStyleSheet('http://www.w3.org/StyleSheets/Core/Midnight')"/>
|
||||
|
@ -527,14 +525,14 @@
|
|||
position="19"/>
|
||||
<menuitem id="colorsAndBackground" value="&colorsAndBackground.label;"
|
||||
accesskey="&colorsandbackground.accesskey;"
|
||||
oncommand="EditorPageProperties('1')"
|
||||
oncommand="EditorPageProperties('ColorTab')"
|
||||
position="20"/>
|
||||
<!-- Merge page property items here -->
|
||||
</menupopup>
|
||||
|
||||
<menuitem id="pageProperties" value="&pageProperties.label;"
|
||||
accesskey="&pageproperties.accesskey;"
|
||||
oncommand="EditorPageProperties('0')"/>
|
||||
oncommand="EditorPageProperties('GeneralTab')"/>
|
||||
|
||||
<menu id="tableMenu" value="&tableMenu.label;" accesskey="&tablemenu.accesskey;">
|
||||
<menupopup>
|
||||
|
@ -570,6 +568,7 @@
|
|||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator />
|
||||
<menuitem id="tableFixupMenuitem" value="&tableFixup.label;" accesskey="&tablefixup.accesskey;" oncommand="EditorNormalizeTable()"/>
|
||||
<menuitem id="tableJoinCellsMenuitem" value="&tableJoinCells.label;" accesskey="&tablejoin.accesskey;" oncommand="EditorJoinTableCells()"/>
|
||||
<menuitem id="tablePropertiesMenuitem" value="&properties.label;" accesskey="&properties.accesskey;" oncommand="EditorInsertOrEditTable(false)"/>
|
||||
</menupopup>
|
||||
|
@ -579,6 +578,7 @@
|
|||
<html:div id="TextColorCaption" class="color-caption" align="center">&textColorCaption.label;</html:div>
|
||||
<!-- TODO: Add "Last color picked" button and text -->
|
||||
<colorpicker id="TextColorPicker" palettename="standard" onclick="EditorSelectTextColor('TextColorPicker','TextColorPopupButton'); parentNode.closePopup();"/>
|
||||
<titledbutton class="push" value="&formatToolbar.colorPicker.default.label;" onclick="EditorRemoveTextColor('TextColorPopupButton'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
|
||||
<popup id="BackColorPopup" popupanchor="bottomleft">
|
||||
|
@ -586,6 +586,7 @@
|
|||
<!-- TODO: Add "Last color picked" button and text -->
|
||||
<html:div id="BackColorCaption" class="color-caption" align="center">Background Color</html:div>
|
||||
<colorpicker id="BackColorPicker" palettename="standard" onclick="EditorSelectBackColor('BackColorPicker','BackColorPopupButton'); parentNode.closePopup();"/>
|
||||
<titledbutton class="push" value="&formatToolbar.colorPicker.default.label;" onclick="EditorRemoveBackColor('BackColorPopupButton'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
|
||||
<menupopup id="AlignmentPopup">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
<!ENTITY showFormattingToolbarCmd.label ".Show Format Toolbar">
|
||||
<!ENTITY showTaskbarCmd.label "Show Taskbar">
|
||||
<!ENTITY showTaskbarCmd.accesskey "t">
|
||||
<!ENTITY viewPageSource.label "View Page Source">
|
||||
<!ENTITY viewPageSource.label "Page Source">
|
||||
<!ENTITY viewpagesource.accesskey "s">
|
||||
|
||||
|
||||
|
@ -374,8 +374,6 @@
|
|||
<!-- Style Sheet submenu -->
|
||||
<!ENTITY stylesheetMenu.label "Apply Style Sheet">
|
||||
<!ENTITY formatstylesheetmenu.accesskey "e">
|
||||
<!ENTITY stylesheetEditorOneCmd.label "Editor Styles 1">
|
||||
<!ENTITY sseditor1.accesskey "1">
|
||||
<!ENTITY stylesheetOldstyleCmd.label "Oldstyle">
|
||||
<!ENTITY ssoldstyle.accesskey "o">
|
||||
<!ENTITY stylesheetModernistCmd.label "Modernist">
|
||||
|
@ -445,7 +443,9 @@
|
|||
<!ENTITY tableDeleteMenu.label "Delete">
|
||||
<!ENTITY tabledeletemenu.accesskey "d">
|
||||
|
||||
<!ENTITY tableJoinCells.label ".Join Cells">
|
||||
<!ENTITY tableFixup.label "Fixup table layout">
|
||||
<!ENTITY tablefixup.accesskey "f">
|
||||
<!ENTITY tableJoinCells.label "Join Cells">
|
||||
<!ENTITY tablejoin.accesskey "j">
|
||||
<!-- These may be shared in other menus -->
|
||||
<!ENTITY properties.label "Properties...">
|
||||
|
@ -505,6 +505,7 @@
|
|||
<!ENTITY formatToolbar.boldChar "B">
|
||||
<!ENTITY formatToolbar.italicChar "I">
|
||||
<!ENTITY formatToolbar.underlineChar "U">
|
||||
<!ENTITY formatToolbar.colorPicker.default.label "Don't Specify Color">
|
||||
|
||||
<!ENTITY tempNotification.label "[status message]">
|
||||
<!ENTITY tempDoneLoading.label "[Document loading message]">
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
||||
|
|
|
@ -45,14 +45,14 @@
|
|||
<keyset id="keyset"/>
|
||||
<tabcontrol align="vertical">
|
||||
<tabbox align="horizontal" flex="100%">
|
||||
<tab>&generalTab.label;</tab>
|
||||
<tab>&backgroundTab.label;</tab>
|
||||
<tab>&metaTagsTab.label;</tab>
|
||||
<tab id="GeneralTab">&generalTab.label;</tab>
|
||||
<tab id="ColorTab">&backgroundTab.label;</tab>
|
||||
<tab id="MetaTab">&metaTagsTab.label;</tab>
|
||||
</tabbox>
|
||||
|
||||
<tabpanel flex="100%">
|
||||
<!-- general tab -->
|
||||
<box align="vertical">
|
||||
<tabpanel id="tabPanel" flex="100%">
|
||||
<!-- ***** general tab ***** -->
|
||||
<box id="panel1" align="vertical">
|
||||
<html:table>
|
||||
<html:tr>
|
||||
<html:td>
|
||||
|
@ -97,85 +97,127 @@
|
|||
</html:table>
|
||||
</box>
|
||||
|
||||
<!-- colors/background tab -->
|
||||
<box align="vertical">
|
||||
<!-- **** colors/background tab **** -->
|
||||
<box id="panel2" align="vertical">
|
||||
<html:fieldset><html:legend class = "dialog" align = "left">&pageColors.label;</html:legend>
|
||||
<html:input type="radio" name="ColorMode" id="DefaultColorsRadio"/>
|
||||
<html:label for="DefaultColorsRadio">&defaultColorsRadio.label;</html:label>
|
||||
<html:br/>
|
||||
<html:input type="radio" name="ColorMode" id="CustomColorsRadio"/>
|
||||
<html:label for="CustomColorsRadio">&customColorsRadio.label;</html:label>
|
||||
<html:br/>
|
||||
<html:div>
|
||||
<html:label for="ColorScheme">&colorScheme.label;</html:label>
|
||||
<!-- TODO: COLOR SCHEME SELECT LIST -->
|
||||
</html:div>
|
||||
<html:br/>
|
||||
<box align="horizontal" flex="100%">
|
||||
<box align="vertical" flex="100%">
|
||||
<html:div class="middle-align">
|
||||
<titledbutton class="color-well" id="textCW" popup="textPopup"/>
|
||||
<titledbutton value="&normalText.label;" class="push dialog popup" align="right" popup="textPopup"/>
|
||||
</html:div>
|
||||
<html:div class="middle-align">
|
||||
<titledbutton class="color-well" id="linkCW" popup="linkPopup"/>
|
||||
<titledbutton value="&linkText.label;" class="push dialog popup" align="right" popup="linkPopup"/>
|
||||
</html:div>
|
||||
<html:div class="middle-align">
|
||||
<titledbutton class="color-well" id="activeCW" popup="activePopup"/>
|
||||
<titledbutton value="&activeLinkText.label;" class="push dialog popup" align="right" popup="activePopup"/>
|
||||
</html:div>
|
||||
<html:div class="middle-align">
|
||||
<titledbutton class="color-well" id="followedCW" popup="followedPopup"/>
|
||||
<titledbutton value="&followedLinkText.label;" class="push dialog popup" align="right" popup="followedPopup"/>
|
||||
</html:div>
|
||||
<html:div class="middle-align">
|
||||
<titledbutton class="color-well" id="backgroundCW" popup="backgroundPopup"/>
|
||||
<titledbutton value="&background.label;" class="push dialog popup" align="right" popup="backgroundPopup"/>
|
||||
</html:div>
|
||||
<html:input type="radio" name="ColorMode" id="DefaultColorsRadio"/>
|
||||
<html:label for="DefaultColorsRadio">&defaultColorsRadio.label;</html:label>
|
||||
<html:br/>
|
||||
<html:input type="radio" name="ColorMode" id="CustomColorsRadio"/>
|
||||
<html:label for="CustomColorsRadio">&customColorsRadio.label;</html:label>
|
||||
<html:br/>
|
||||
<html:div>
|
||||
<spring class="bigspacer"/>
|
||||
<box flex="1">
|
||||
<html:label> &colorScheme.label;
|
||||
<html:select id="ColorScheme" size="1" style="min-width: 10em">
|
||||
<html:option> Black on White </html:option>
|
||||
<html:option> Blue on White </html:option>
|
||||
<html:option> White on Black </html:option>
|
||||
</html:select>
|
||||
</html:label>
|
||||
</box>
|
||||
<!-- TODO: COLOR SCHEME SELECT LIST -->
|
||||
</html:div>
|
||||
<spring class="bigspacer"/>
|
||||
<box align="horizontal">
|
||||
<spring class="bigspacer"/>
|
||||
<box align="vertical" flex="100%">
|
||||
<box>
|
||||
<html:label class="margin-both"> &normalText.label; </html:label>
|
||||
<spring flex="100%"/>
|
||||
<menu class="colorpicker">
|
||||
<html:div id="textCW" class="color-well"/>
|
||||
<titledbutton class="popup" align="right" flex="100%" onclick="GetColor('textCP','textCW');"/>
|
||||
<menupopup id="normalMenuPopup">
|
||||
<colorpicker id="textCP" palettename="standard" onclick="GetColor('textCP','textCW');"/>
|
||||
<titledbutton class="push" value="&colorPicker.default.label;" onclick="GetColor('textCP','textCW');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<box>
|
||||
<html:label class="margin-both"> &linkText.label; </html:label>
|
||||
<spring flex="100%"/>
|
||||
<menu class="colorpicker">
|
||||
<html:div id="linkCW" class="color-well"/>
|
||||
<titledbutton class="popup" align="right" flex="100%"/>
|
||||
<menupopup>
|
||||
<colorpicker id="linkCP" palettename="standard" onclick="GetColor('linkCP','linkCW');"/>
|
||||
<titledbutton class="push" value="&colorPicker.default.label;" onclick="RemoveColor('linkCW');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<box>
|
||||
<html:label class="margin-both"> &activeLinkText.label; </html:label>
|
||||
<spring flex="100%"/>
|
||||
<menu class="colorpicker">
|
||||
<html:div id="activeCW" class="color-well"/>
|
||||
<titledbutton class="popup" align="right" flex="100%"/>
|
||||
<menupopup>
|
||||
<colorpicker id="activeCP" palettename="standard" onclick="GetColor('activeCP','activeCW');"/>
|
||||
<titledbutton class="push" value="&colorPicker.default.label;" onclick="RemoveColor('activeCW');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<box>
|
||||
<html:label class="margin-both"> &followedLinkText.label; </html:label>
|
||||
<spring flex="100%"/>
|
||||
<menu class="colorpicker">
|
||||
<html:div id="followedCW" class="color-well"/>
|
||||
<titledbutton class="popup" align="right" flex="100%"/>
|
||||
<menupopup>
|
||||
<colorpicker id="followedCP" palettename="standard" onclick="GetColor('followedCP','followedCW');"/>
|
||||
<titledbutton class="push" value="&colorPicker.default.label;" onclick="RemoveColor('followedCW');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<box>
|
||||
<html:label class="margin-both"> &background.label; </html:label>
|
||||
<spring flex="100%"/>
|
||||
<menu class="colorpicker">
|
||||
<html:div id="backgroundCW" class="color-well"/>
|
||||
<titledbutton class="popup" align="right" flex="100%"/>
|
||||
<menupopup>
|
||||
<colorpicker id="backgroundCP" palettename="standard" onclick="GetColor('backgroundCP','backgroundCW');"/>
|
||||
<titledbutton class="push" value="&colorPicker.default.label;" onclick="RemoveColor('backgroundCW');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</box>
|
||||
<!-- SAMPLE WINDOW -->
|
||||
<div id="TextSampleWindow"/>
|
||||
</box>
|
||||
<spring class="bigspacer"/>
|
||||
<box align="vertical" flex="100%" id="ColorPreview">
|
||||
<!-- basestyle="min-height:50px; width: 100%; border: 1px inset #CCCCCC; padding: 5px; " style="min-height:50px; width: 100%; border: 1px inset #CCCCCC; padding: 5px; "-->
|
||||
<html:div id="NormalText">&normalText.label;</html:div>
|
||||
<spring class="spacer"/>
|
||||
<html:div id="LinkText">&linkText.label;</html:div>
|
||||
<spring class="spacer"/>
|
||||
<html:div id="ActiveLinkText">&activeLinkText.label;</html:div>
|
||||
<spring class="spacer"/>
|
||||
<html:div id="FollowedLinkText">&followedLinkText.label;</html:div>
|
||||
</box>
|
||||
</box>
|
||||
</html:fieldset>
|
||||
<box align="horizontal">
|
||||
<html:input type="checkbox" id="BackgroundImageCheckbox"/>
|
||||
<html:label for="BackgroundImageCheckbox">
|
||||
&backgroundImage.label;
|
||||
</html:label>
|
||||
<html:label for="BackgroundImageCheckbox"> &backgroundImage.label; </html:label>
|
||||
</box>
|
||||
<box align="horizontal">
|
||||
<html:input type="text" id="BackgroundImageInput" size="10"/>
|
||||
<html:input type="text" class="SizeToParent" id="BackgroundImageInput" size="20"/>
|
||||
<spring class="spacer"/>
|
||||
<!-- from EdDialogOverlay.xul -->
|
||||
<titledbutton id="ChooseFile"/>
|
||||
</box>
|
||||
</box> <!-- end of colors tab -->
|
||||
|
||||
<!-- meta tags tab -->
|
||||
<box align="vertical">
|
||||
<!-- **** meta tags tab **** -->
|
||||
<box id="panel3" align="vertical">
|
||||
</box>
|
||||
</tabpanel>
|
||||
</tabcontrol>
|
||||
<html:div class="separator" align="horizontal"/>
|
||||
<box id="okCancelButtons"/>
|
||||
|
||||
<popupset>
|
||||
<popup id="textPopup">
|
||||
<colorpicker id="textCP" palettename="standard" onclick="getColor('textCP', 'textCW'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
<popup id="linkPopup">
|
||||
<colorpicker id="linkCP" palettename="standard" onclick="getColor('linkCP', 'linkCW'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
<popup id="activePopup">
|
||||
<colorpicker id="activeCP" palettename="standard" onclick="getColor('activeCP', 'activeCW'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
<popup id="followedPopup">
|
||||
<colorpicker id="followedCP" palettename="standard" onclick="getColor('followedCP', 'followedCW'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
<popup id="backgroundPopup">
|
||||
<colorpicker id="backgroundCP" palettename="standard" onclick="getColor('backgroundCP', 'backgroundCW'); parentNode.closePopup();"/>
|
||||
</popup>
|
||||
</popupset>
|
||||
|
||||
</window>
|
||||
|
|
|
@ -32,11 +32,12 @@
|
|||
<!ENTITY descriptionInput.label "Description">
|
||||
<!ENTITY pageColors.label "Page Colors">
|
||||
<!ENTITY defaultColorsRadio.label "Don't specify colors">
|
||||
<!ENTITY customColorsRadio.label "Use custom colors">
|
||||
<!ENTITY colorScheme.label "Color Schemes">
|
||||
<!ENTITY normalText.label "Normal text">
|
||||
<!ENTITY linkText.label "Link text">
|
||||
<!ENTITY activeLinkText.label "Active link text">
|
||||
<!ENTITY followedLinkText.label "Followed link text">
|
||||
<!ENTITY background.label "Background">
|
||||
<!ENTITY backgroundImage.label "Background Image">
|
||||
<!ENTITY customColorsRadio.label "Use custom colors:">
|
||||
<!ENTITY colorScheme.label "Color Schemes:">
|
||||
<!ENTITY normalText.label "Normal text:">
|
||||
<!ENTITY linkText.label "Link text:">
|
||||
<!ENTITY activeLinkText.label "Active link text:">
|
||||
<!ENTITY followedLinkText.label "Followed link text:">
|
||||
<!ENTITY background.label "Background:">
|
||||
<!ENTITY backgroundImage.label "Background Image:">
|
||||
<!ENTITY colorPicker.default.label "Don't Specify Color">
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче