зеркало из https://github.com/mozilla/pjs.git
Finished implementation of menu-driven table selection. Implemented detection of row or column selection. r=mjudge
This commit is contained in:
Родитель
89f6311468
Коммит
e3ef5768c7
|
@ -1857,7 +1857,6 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMAttr> resultAttribute;
|
nsCOMPtr<nsIDOMAttr> resultAttribute;
|
||||||
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
|
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
|
||||||
// Is the resultAttribute deleted automagically?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1881,7 +1880,7 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
|
||||||
// Do we ever get here?
|
// Do we ever get here?
|
||||||
destElement->RemoveAttribute(sourceAttrName);
|
destElement->RemoveAttribute(sourceAttrName);
|
||||||
#if DEBUG_cmanske
|
#if DEBUG_cmanske
|
||||||
printf("Attribute in NamedNodeMap has empty value in nsEditor::CloneAttributes()\n");
|
printf("Attribute in sourceAttribute has empty value in nsEditor::CloneAttributes()\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5014,19 +5013,11 @@ nsEditor::GetFirstNodeInRange(nsIDOMRange *aRange, nsIDOMNode **aNode)
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!startParent) return NS_ERROR_FAILURE;
|
if (!startParent) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> startNode;
|
|
||||||
PRInt32 offset;
|
PRInt32 offset;
|
||||||
res = aRange->GetStartOffset(&offset);
|
res = aRange->GetStartOffset(&offset);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
nsCOMPtr<nsIDOMNode> child = GetChildAt(startParent, offset);
|
||||||
res = startParent->GetChildNodes(getter_AddRefs(nodeList));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!nodeList) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> child;
|
|
||||||
res = nodeList->Item(offset,getter_AddRefs(child));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!child) return NS_ERROR_FAILURE;
|
if (!child) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
*aNode = child.get();
|
*aNode = child.get();
|
||||||
|
|
|
@ -2847,6 +2847,59 @@ nsEditorShell::GetSelectedElement(const PRUnichar *aInTagName, nsIDOMElement **a
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetFirstSelectedCell(nsIDOMElement **aOutElement)
|
||||||
|
{
|
||||||
|
if (!aOutElement)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetFirstSelectedCell(aOutElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ePlainTextEditorType:
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetNextSelectedCell(nsIDOMElement **aOutElement)
|
||||||
|
{
|
||||||
|
if (!aOutElement)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetNextSelectedCell(aOutElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ePlainTextEditorType:
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
||||||
{
|
{
|
||||||
|
@ -3537,9 +3590,9 @@ nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIsSelected, nsIDOMElement **_retval)
|
nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRInt32 *aSelectedCount, nsIDOMElement **_retval)
|
||||||
{
|
{
|
||||||
if (!_retval || !aTagName || !aIsSelected)
|
if (!_retval || !aTagName || !aSelectedCount)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
nsresult result = NS_NOINTERFACE;
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
@ -3550,7 +3603,7 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
||||||
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
nsAutoString TagName(*aTagName);
|
nsAutoString TagName(*aTagName);
|
||||||
if (tableEditor)
|
if (tableEditor)
|
||||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected);
|
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aSelectedCount);
|
||||||
*aTagName = TagName.ToNewUnicode();
|
*aTagName = TagName.ToNewUnicode();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3560,6 +3613,28 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 *_retval)
|
||||||
|
{
|
||||||
|
if (!_retval)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetSelectedCellsType(aElement, *_retval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* end of table editing */
|
/* end of table editing */
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -224,7 +224,22 @@ nsHTMLEditUtils::IsListItem(nsIDOMNode *node)
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// IsTableCell: true if node an html td or th
|
// IsTable: true if node an html table
|
||||||
|
//
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditUtils::IsTable(nsIDOMNode *node)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTable");
|
||||||
|
nsAutoString tag;
|
||||||
|
nsEditor::GetTagString(node,tag);
|
||||||
|
if (tag == "table")
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// IsTableRow: true if node an html tr
|
||||||
//
|
//
|
||||||
PRBool
|
PRBool
|
||||||
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
static PRBool IsHeader(nsIDOMNode *aNode);
|
static PRBool IsHeader(nsIDOMNode *aNode);
|
||||||
static PRBool IsParagraph(nsIDOMNode *aNode);
|
static PRBool IsParagraph(nsIDOMNode *aNode);
|
||||||
static PRBool IsListItem(nsIDOMNode *aNode);
|
static PRBool IsListItem(nsIDOMNode *aNode);
|
||||||
|
static PRBool IsTable(nsIDOMNode *aNode);
|
||||||
static PRBool IsTableRow(nsIDOMNode *aNode);
|
static PRBool IsTableRow(nsIDOMNode *aNode);
|
||||||
static PRBool IsTableCell(nsIDOMNode *aNode);
|
static PRBool IsTableCell(nsIDOMNode *aNode);
|
||||||
static PRBool IsList(nsIDOMNode *aNode);
|
static PRBool IsList(nsIDOMNode *aNode);
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
#include "nsIDOMSelection.h"
|
#include "nsIDOMSelection.h"
|
||||||
#include "nsIDOMHTMLAnchorElement.h"
|
#include "nsIDOMHTMLAnchorElement.h"
|
||||||
#include "nsIDOMHTMLImageElement.h"
|
#include "nsIDOMHTMLImageElement.h"
|
||||||
|
|
||||||
#include "nsISelectionController.h"
|
#include "nsISelectionController.h"
|
||||||
|
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||||
|
|
||||||
#include "nsICSSLoader.h"
|
#include "nsICSSLoader.h"
|
||||||
#include "nsICSSStyleSheet.h"
|
#include "nsICSSStyleSheet.h"
|
||||||
|
@ -196,11 +196,10 @@ static PRBool IsCellNode(nsIDOMNode *aNode)
|
||||||
nsAutoString tagName;
|
nsAutoString tagName;
|
||||||
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
||||||
{
|
{
|
||||||
tagName.ToLowerCase();
|
// With only 2 tests, it doesn't
|
||||||
// With only 3 tests, it doesn't
|
|
||||||
// seem worth using nsAtoms
|
// seem worth using nsAtoms
|
||||||
if (tagName.Equals("td") ||
|
if (tagName.EqualsIgnoreCase("td") ||
|
||||||
tagName.Equals("th"))
|
tagName.EqualsIgnoreCase("th"))
|
||||||
{
|
{
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +216,7 @@ nsHTMLEditor::nsHTMLEditor()
|
||||||
, mRules(nsnull)
|
, mRules(nsnull)
|
||||||
, mIsComposing(PR_FALSE)
|
, mIsComposing(PR_FALSE)
|
||||||
, mMaxTextLength(-1)
|
, mMaxTextLength(-1)
|
||||||
, mSelectingTableCells(PR_FALSE)
|
, mSelectedCellIndex(0)
|
||||||
{
|
{
|
||||||
// Done in nsEditor
|
// Done in nsEditor
|
||||||
// NS_INIT_REFCNT();
|
// NS_INIT_REFCNT();
|
||||||
|
@ -2620,11 +2619,10 @@ nsHTMLEditor::GetElementOrParentByTagName(const nsString &aTagName, nsIDOMNode *
|
||||||
res = selection->GetAnchorOffset(&offset);
|
res = selection->GetAnchorOffset(&offset);
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
currentNode = nsEditor::GetChildAt(anchorNode, offset);
|
currentNode = nsEditor::GetChildAt(anchorNode, offset);
|
||||||
if (!currentNode) return NS_ERROR_FAILURE;
|
|
||||||
} else {
|
|
||||||
// anchor node is probably a text node - just use that
|
|
||||||
currentNode = anchorNode;
|
|
||||||
}
|
}
|
||||||
|
// anchor node is probably a text node - just use that
|
||||||
|
if (!currentNode)
|
||||||
|
currentNode = anchorNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString TagName = aTagName;
|
nsAutoString TagName = aTagName;
|
||||||
|
@ -3053,14 +3051,30 @@ nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
||||||
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
||||||
|
|
||||||
// Find a selected or enclosing table element to set background on
|
// Find a selected or enclosing table element to set background on
|
||||||
// TODO: Handle case of > 1 table cell or row selected
|
|
||||||
nsCOMPtr<nsIDOMElement> element;
|
nsCOMPtr<nsIDOMElement> element;
|
||||||
PRBool isSelected;
|
PRInt32 selectedCount;
|
||||||
nsAutoString tagName;
|
nsAutoString tagName;
|
||||||
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, isSelected);
|
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, selectedCount);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!element)
|
if (element)
|
||||||
{
|
{
|
||||||
|
if (selectedCount > 0)
|
||||||
|
{
|
||||||
|
// Traverse all selected cells
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(cell));
|
||||||
|
if (NS_SUCCEEDED(res) && cell)
|
||||||
|
{
|
||||||
|
while(cell)
|
||||||
|
{
|
||||||
|
SetAttribute(cell, "bgcolor", aColor);
|
||||||
|
GetNextSelectedCell(getter_AddRefs(cell));
|
||||||
|
};
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we failed to find a cell, fall through to use originally-found element
|
||||||
|
} else {
|
||||||
// No table element -- set the background color on the body tag
|
// No table element -- set the background color on the body tag
|
||||||
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
@ -5826,7 +5840,7 @@ nsHTMLEditor::IsTableCell(nsIDOMNode *node)
|
||||||
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
||||||
nsAutoString tag;
|
nsAutoString tag;
|
||||||
nsEditor::GetTagString(node,tag);
|
nsEditor::GetTagString(node,tag);
|
||||||
if (tag == "td")
|
if (tag == "td" || tag == "th")
|
||||||
{
|
{
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -7844,4 +7858,3 @@ nsHTMLEditor::InsertContainerAbove(nsIDOMNode *inNode,
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,15 @@ public:
|
||||||
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||||
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||||
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
||||||
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected);
|
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount);
|
||||||
|
NS_IMETHOD GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelectionType);
|
||||||
|
// Finds the first selected cell in first range of selection
|
||||||
|
// This is in the *order of selection*, not order in the table
|
||||||
|
// (i.e., each cell added to selection is added in another range
|
||||||
|
// in the selection's rangelist, independent of location in table)
|
||||||
|
NS_IMETHOD GetFirstSelectedCell(nsIDOMElement **aCell);
|
||||||
|
// Get next cell until no more are found. Always use GetFirstSelected cell first
|
||||||
|
NS_IMETHOD GetNextSelectedCell(nsIDOMElement **aCell);
|
||||||
|
|
||||||
|
|
||||||
// Selection and navigation
|
// Selection and navigation
|
||||||
|
@ -348,6 +356,9 @@ protected:
|
||||||
// Needed to do appropriate deleting when last cell or row is about to be deleted
|
// 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)
|
// This doesn't count cells that don't start in the given row (are spanning from row above)
|
||||||
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
||||||
|
// Test if all cells in row or column at given index are selected
|
||||||
|
PRBool AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns);
|
||||||
|
PRBool AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows);
|
||||||
|
|
||||||
// Most insert methods need to get the same basic context data
|
// Most insert methods need to get the same basic context data
|
||||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||||
|
@ -355,17 +366,13 @@ protected:
|
||||||
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
||||||
PRInt32& aRow, PRInt32& aCol);
|
PRInt32& aRow, PRInt32& aCol);
|
||||||
|
|
||||||
// Finds the first selected cell in first range of selection
|
|
||||||
// This is in the *order of selection*, not order in the table
|
|
||||||
// (i.e., each cell added to selection is added in another range
|
|
||||||
// in the selection's rangelist, independent of location in table)
|
|
||||||
NS_IMETHOD GetFirstSelectedCell(nsIDOMElement **aCell);
|
|
||||||
|
|
||||||
// Fallback method: Call this after using ClearSelection() and you
|
// Fallback method: Call this after using ClearSelection() and you
|
||||||
// failed to set selection to some other content in the document
|
// failed to set selection to some other content in the document
|
||||||
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
||||||
|
|
||||||
// end of table editing utilities
|
|
||||||
|
// End of Table Editing utilities
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
||||||
nsString &aParentTag,
|
nsString &aParentTag,
|
||||||
|
@ -607,13 +614,8 @@ protected:
|
||||||
PRBool mCachedUnderlineStyle;
|
PRBool mCachedUnderlineStyle;
|
||||||
nsString mCachedFontName;
|
nsString mCachedFontName;
|
||||||
|
|
||||||
// True when selection consists of table cell(s)
|
// Used by GetFirstSelectedCell and GetNextSelectedCell
|
||||||
PRBool mSelectingTableCells;
|
PRInt32 mSelectedCellIndex;
|
||||||
|
|
||||||
// Used to monitor block of cells selected
|
|
||||||
// by dragging mouse across the table
|
|
||||||
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
|
|
||||||
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static nsIAtom *gTypingTxnName;
|
static nsIAtom *gTypingTxnName;
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "nsITableCellLayout.h" // For efficient access to table cell
|
#include "nsITableCellLayout.h" // For efficient access to table cell
|
||||||
#include "nsITableLayout.h" // data owned by the table and cell frames
|
#include "nsITableLayout.h" // data owned by the table and cell frames
|
||||||
#include "nsHTMLEditor.h"
|
#include "nsHTMLEditor.h"
|
||||||
|
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
|
||||||
#include "nsEditorUtils.h"
|
#include "nsEditorUtils.h"
|
||||||
|
|
||||||
|
@ -799,7 +801,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
||||||
if (curCell)
|
if (curCell)
|
||||||
{
|
{
|
||||||
// This must always be >= 1
|
// This must always be >= 1
|
||||||
NS_ASSERTION((actualRowSpan > 0),"Effective ROWSPAN = 0 in DeleteTableColumn");
|
NS_ASSERTION((actualRowSpan > 0),"Actual ROWSPAN = 0 in DeleteTableColumn");
|
||||||
|
|
||||||
// Find cells that don't start in column we are deleting
|
// Find cells that don't start in column we are deleting
|
||||||
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
||||||
|
@ -1643,13 +1645,9 @@ nsHTMLEditor::GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!aSelection) return NS_ERROR_FAILURE;
|
if (!aSelection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// Find the first selected cell
|
|
||||||
// res = GetFirstSelectedCell(getter_AddRefs(aCell));
|
|
||||||
if (!aCell)
|
if (!aCell)
|
||||||
{
|
{
|
||||||
//If a cell wasn't selected, then assume the selection is INSIDE
|
// Get cell if it's the child of selection anchor node,
|
||||||
// and use anchor node to search up to the containing cell
|
|
||||||
// Test if selected node (from anchor node) is a cell
|
|
||||||
// or get the enclosing by a cell
|
// or get the enclosing by a cell
|
||||||
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
@ -1683,78 +1681,109 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell)
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!selection) return NS_ERROR_FAILURE;
|
if (!selection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
//TODO: Replace this with code below new "table cell mode" flag is implemented
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEnumerator> enumerator;
|
|
||||||
res = selection->GetEnumerator(getter_AddRefs(enumerator));
|
|
||||||
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!enumerator) return NS_ERROR_FAILURE;
|
|
||||||
enumerator->First();
|
|
||||||
nsCOMPtr<nsISupports> currentItem;
|
|
||||||
res = enumerator->CurrentItem(getter_AddRefs(currentItem));
|
|
||||||
if ((NS_SUCCEEDED(res)) && currentItem)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
|
||||||
nsCOMPtr<nsIContentIterator> iter;
|
|
||||||
res = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
|
||||||
NS_GET_IID(nsIContentIterator),
|
|
||||||
getter_AddRefs(iter));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!iter) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
iter->Init(range);
|
|
||||||
// loop through the content iterator for each content node
|
|
||||||
nsCOMPtr<nsIContent> content;
|
|
||||||
|
|
||||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
|
||||||
{
|
|
||||||
res = iter->CurrentNode(getter_AddRefs(content));
|
|
||||||
// Not likely!
|
|
||||||
if (NS_FAILED(res)) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAtom> atom;
|
|
||||||
content->GetTag(*getter_AddRefs(atom));
|
|
||||||
if (atom.get() == nsIEditProperty::td ||
|
|
||||||
atom.get() == nsIEditProperty::th )
|
|
||||||
{
|
|
||||||
// We found a cell
|
|
||||||
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(content);
|
|
||||||
if (cellElement)
|
|
||||||
{
|
|
||||||
*aCell = cellElement.get();
|
|
||||||
NS_ADDREF(*aCell);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
iter->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//TODO: Do this only after checking the new "table cell mode" flag
|
|
||||||
// The first cell is the starting node in the first selection range
|
|
||||||
nsCOMPtr<nsIDOMRange> firstRange;
|
nsCOMPtr<nsIDOMRange> firstRange;
|
||||||
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!firstRange) return NS_ERROR_FAILURE;
|
if (!firstRange) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
#ifdef DEBUG_cmanske
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||||
|
PRInt32 anchorOffset = -1;
|
||||||
|
selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||||
|
selection->GetAnchorOffset(&anchorOffset);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> focusNode;
|
||||||
|
res = selection->GetFocusNode(getter_AddRefs(focusNode));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
PRInt32 focusOffset = -1;
|
||||||
|
selection->GetFocusOffset(&focusOffset);
|
||||||
|
|
||||||
|
nsAutoString name;
|
||||||
|
anchorNode->GetNodeName(name);
|
||||||
|
printf("GetFirstSelectedCell: Anchor node of selection: ");
|
||||||
|
wprintf(name.GetUnicode());
|
||||||
|
printf(" Offset: %d\n", anchorOffset);
|
||||||
|
focusNode->GetNodeName(name);
|
||||||
|
printf("Focus node of selection: ");
|
||||||
|
wprintf(name.GetUnicode());
|
||||||
|
printf(" Offset: %x\n", focusOffset);
|
||||||
|
|
||||||
|
PRInt32 rangeCount;
|
||||||
|
res = selection->GetRangeCount(&rangeCount);
|
||||||
|
printf(" RangeCount: %d\n", rangeCount);
|
||||||
|
printf(" Range pointer = %d\n", firstRange);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This is failing -- range doesn't match that set when selecting cell!
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> cellNode;
|
nsCOMPtr<nsIDOMNode> cellNode;
|
||||||
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!cellNode) return NS_ERROR_FAILURE;
|
if (!cellNode) return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
|
||||||
|
|
||||||
if (cellElement)
|
if (IsTableCell(cellNode))
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
||||||
*aCell = cellElement.get();
|
*aCell = cellElement.get();
|
||||||
NS_ADDREF(*aCell);
|
NS_ADDREF(*aCell);
|
||||||
}
|
}
|
||||||
else res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
else
|
||||||
|
res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
|
||||||
|
mSelectedCellIndex = 1;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell)
|
||||||
|
{
|
||||||
|
if (!aCell) return NS_ERROR_NULL_POINTER;
|
||||||
|
*aCell = nsnull;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSelection> selection;
|
||||||
|
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!selection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRInt32 rangeCount;
|
||||||
|
res = selection->GetRangeCount(&rangeCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// Don't even try if index exceeds range count
|
||||||
|
if (mSelectedCellIndex >= rangeCount)
|
||||||
|
{
|
||||||
|
// Should we reset index?
|
||||||
|
// Maybe better to force recalling GetFirstSelectedCell()
|
||||||
|
//mSelectedCellIndex = 0;
|
||||||
|
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first node in first range of selection - test if it's a cell
|
||||||
|
nsCOMPtr<nsIDOMRange> range;
|
||||||
|
res = selection->GetRangeAt(mSelectedCellIndex, getter_AddRefs(range));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!range) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> cellNode;
|
||||||
|
res = nsEditor::GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!cellNode) return NS_ERROR_FAILURE;
|
||||||
|
if (IsTableCell(cellNode))
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
||||||
|
*aCell = cellElement.get();
|
||||||
|
NS_ADDREF(*aCell);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
|
||||||
|
// Setup for next cell
|
||||||
|
mSelectedCellIndex++;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1842,11 +1871,11 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt3
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount)
|
||||||
{
|
{
|
||||||
aTableElement = nsnull;
|
aTableElement = nsnull;
|
||||||
aTagName = "";
|
aTagName = "";
|
||||||
aIsSelected = PR_FALSE;
|
aSelectedCount = 0;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSelection> selection;
|
nsCOMPtr<nsIDOMSelection> selection;
|
||||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||||
|
@ -1858,52 +1887,218 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
||||||
nsAutoString tdName("td");
|
nsAutoString tdName("td");
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||||
|
|
||||||
// Find the first selected cell
|
|
||||||
// TODO: Handle multiple cells selected!
|
|
||||||
nsCOMPtr<nsIDOMElement> firstCell;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMElement> tableElement;
|
|
||||||
res = GetFirstSelectedCell(getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = tdName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if table or row is selected
|
|
||||||
res = GetSelectedElement(tableName, getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = tableName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
res = GetSelectedElement(trName, getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = trName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for a table cell parent
|
|
||||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMElement> tableElement;
|
||||||
|
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||||
|
|
||||||
|
// Get child of anchor node, if exists
|
||||||
|
PRBool hasChildren;
|
||||||
|
anchorNode->HasChildNodes(&hasChildren);
|
||||||
|
|
||||||
|
if (hasChildren)
|
||||||
|
{
|
||||||
|
PRInt32 anchorOffset;
|
||||||
|
res = selection->GetAnchorOffset(&anchorOffset);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
selectedNode = nsEditor::GetChildAt(anchorNode, anchorOffset);
|
||||||
|
if (!selectedNode)
|
||||||
|
selectedNode = anchorNode;
|
||||||
|
|
||||||
|
nsAutoString tag;
|
||||||
|
nsEditor::GetTagString(selectedNode,tag);
|
||||||
|
|
||||||
|
if (tag == tdName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = tdName;
|
||||||
|
// Each cell is in its own selection range,
|
||||||
|
// so count signals multiple-cell selection
|
||||||
|
res = selection->GetRangeCount(&aSelectedCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
}
|
||||||
|
else if(tag == tableName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = tableName;
|
||||||
|
aSelectedCount = 1;
|
||||||
|
}
|
||||||
|
else if(tag == trName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = trName;
|
||||||
|
aSelectedCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tableElement)
|
||||||
|
{
|
||||||
|
// Didn't find a table element -- find a cell parent
|
||||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
if (tableElement)
|
if (tableElement)
|
||||||
{
|
|
||||||
aTagName = tdName;
|
aTagName = tdName;
|
||||||
SET_RETURN_ELEMENT:
|
}
|
||||||
|
if (tableElement)
|
||||||
|
{
|
||||||
aTableElement = tableElement.get();
|
aTableElement = tableElement.get();
|
||||||
NS_ADDREF(aTableElement);
|
NS_ADDREF(aTableElement);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool IndexNotTested(nsVoidArray *aArray, PRInt32 aIndex)
|
||||||
|
{
|
||||||
|
if (aArray)
|
||||||
|
{
|
||||||
|
PRInt32 count = aArray->Count();
|
||||||
|
for (PRInt32 i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if(aIndex == (PRInt32)(aArray->ElementAt(i)))
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEditor::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelectionType)
|
||||||
|
{
|
||||||
|
aSelectionType = 0;
|
||||||
|
|
||||||
|
// Be sure we have a table element
|
||||||
|
// (if aElement is null, this uses selection's anchor node)
|
||||||
|
nsCOMPtr<nsIDOMElement> table;
|
||||||
|
|
||||||
|
nsresult res = GetElementOrParentByTagName("table", aElement, getter_AddRefs(table));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
PRInt32 rowCount, colCount;
|
||||||
|
res = GetTableSize(table, rowCount, colCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// Traverse all selected cells
|
||||||
|
// (Failure here may indicate that aCellElement wasn't really a cell)
|
||||||
|
nsCOMPtr<nsIDOMElement> selectedCell;
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// We have at least one selected cell, so set return value
|
||||||
|
aSelectionType = TABLESELECTION_CELL;
|
||||||
|
|
||||||
|
// Store indexes of each row/col to avoid duplication of searches
|
||||||
|
nsVoidArray indexArray;
|
||||||
|
|
||||||
|
PRBool allCellsInRowAreSelected = PR_TRUE;
|
||||||
|
PRBool allCellsInColAreSelected = PR_FALSE;
|
||||||
|
while (NS_SUCCEEDED(res) && selectedCell)
|
||||||
|
{
|
||||||
|
// Get the cell's location in the cellmap
|
||||||
|
PRInt32 startRowIndex, startColIndex;
|
||||||
|
res = GetCellIndexes(selectedCell, startRowIndex, startColIndex);
|
||||||
|
if(NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
if (IndexNotTested(&indexArray, startColIndex))
|
||||||
|
{
|
||||||
|
indexArray.AppendElement((void*)startColIndex);
|
||||||
|
allCellsInRowAreSelected = AllCellsInRowSelected(table, startRowIndex, colCount);
|
||||||
|
// We're done as soon as we fail for any row
|
||||||
|
if (!allCellsInRowAreSelected) break;
|
||||||
|
}
|
||||||
|
res = GetNextSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCellsInRowAreSelected)
|
||||||
|
{
|
||||||
|
aSelectionType = TABLESELECTION_ROW;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
// Test for columns
|
||||||
|
|
||||||
|
// Empty the indexArray
|
||||||
|
indexArray.Clear();
|
||||||
|
|
||||||
|
// Start at first cell again
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
while (NS_SUCCEEDED(res) && selectedCell)
|
||||||
|
{
|
||||||
|
// Get the cell's location in the cellmap
|
||||||
|
PRInt32 startRowIndex, startColIndex;
|
||||||
|
res = GetCellIndexes(selectedCell, startRowIndex, startColIndex);
|
||||||
|
if(NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
if (IndexNotTested(&indexArray, startRowIndex))
|
||||||
|
{
|
||||||
|
indexArray.AppendElement((void*)startColIndex);
|
||||||
|
allCellsInColAreSelected = AllCellsInColumnSelected(table, startColIndex, colCount);
|
||||||
|
// We're done as soon as we fail for any column
|
||||||
|
if (!allCellsInRowAreSelected) break;
|
||||||
|
}
|
||||||
|
res = GetNextSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
}
|
||||||
|
if (allCellsInColAreSelected)
|
||||||
|
aSelectionType = TABLESELECTION_COLUMN;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditor::AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns)
|
||||||
|
{
|
||||||
|
if (!aTable) return PR_FALSE;
|
||||||
|
|
||||||
|
PRInt32 curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||||
|
PRBool isSelected;
|
||||||
|
|
||||||
|
for( PRInt32 col = 0; col < aNumberOfColumns; col += actualColSpan)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
nsresult res = GetCellDataAt(aTable, aRowIndex, col, *getter_AddRefs(cell),
|
||||||
|
curStartRowIndex, curStartColIndex, rowSpan, colSpan,
|
||||||
|
actualRowSpan, actualColSpan, isSelected);
|
||||||
|
|
||||||
|
if (NS_FAILED(res)) return PR_FALSE;
|
||||||
|
// Skip cell spanning into this location from a row above
|
||||||
|
if (curStartRowIndex == aRowIndex)
|
||||||
|
{
|
||||||
|
// If no cell, we may have a "ragged" right edge,
|
||||||
|
// so return TRUE only if we already found a cell in the row
|
||||||
|
if (!cell) return (col > 0) ? PR_TRUE : PR_FALSE;
|
||||||
|
// Return as soon as a non-selected cell is found
|
||||||
|
if (!isSelected) return PR_FALSE;
|
||||||
|
}
|
||||||
|
NS_ASSERTION((actualColSpan > 0),"ActualColSpan = 0 in AllCellsInRowSelected");
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditor::AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows)
|
||||||
|
{
|
||||||
|
if (!aTable) return PR_FALSE;
|
||||||
|
|
||||||
|
PRInt32 curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||||
|
PRBool isSelected;
|
||||||
|
|
||||||
|
for( PRInt32 row = 0; row < aNumberOfRows; row += actualRowSpan)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
nsresult res = GetCellDataAt(aTable, row, aColIndex, *getter_AddRefs(cell),
|
||||||
|
curStartRowIndex, curStartColIndex, rowSpan, colSpan,
|
||||||
|
actualRowSpan, actualColSpan, isSelected);
|
||||||
|
|
||||||
|
if (NS_FAILED(res)) return PR_FALSE;
|
||||||
|
// Skip cell spanning into this location from a column to the left
|
||||||
|
if (curStartColIndex == aColIndex)
|
||||||
|
{
|
||||||
|
// If no cell, we must have a "ragged" right edge on the last column
|
||||||
|
// so return TRUE only if we already found a cell in the row
|
||||||
|
if (!cell) return (row > 0) ? PR_TRUE : PR_FALSE;
|
||||||
|
// Return as soon as a non-selected cell is found
|
||||||
|
if (!isSelected) return PR_FALSE;
|
||||||
|
}
|
||||||
|
NS_ASSERTION((actualRowSpan > 0),"ActualRowSpan = 0 in AllCellsInColumnSelected");
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -2847,6 +2847,59 @@ nsEditorShell::GetSelectedElement(const PRUnichar *aInTagName, nsIDOMElement **a
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetFirstSelectedCell(nsIDOMElement **aOutElement)
|
||||||
|
{
|
||||||
|
if (!aOutElement)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetFirstSelectedCell(aOutElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ePlainTextEditorType:
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetNextSelectedCell(nsIDOMElement **aOutElement)
|
||||||
|
{
|
||||||
|
if (!aOutElement)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetNextSelectedCell(aOutElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ePlainTextEditorType:
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
||||||
{
|
{
|
||||||
|
@ -3537,9 +3590,9 @@ nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIsSelected, nsIDOMElement **_retval)
|
nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRInt32 *aSelectedCount, nsIDOMElement **_retval)
|
||||||
{
|
{
|
||||||
if (!_retval || !aTagName || !aIsSelected)
|
if (!_retval || !aTagName || !aSelectedCount)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
nsresult result = NS_NOINTERFACE;
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
@ -3550,7 +3603,7 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
||||||
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
nsAutoString TagName(*aTagName);
|
nsAutoString TagName(*aTagName);
|
||||||
if (tableEditor)
|
if (tableEditor)
|
||||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected);
|
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aSelectedCount);
|
||||||
*aTagName = TagName.ToNewUnicode();
|
*aTagName = TagName.ToNewUnicode();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3560,6 +3613,28 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEditorShell::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 *_retval)
|
||||||
|
{
|
||||||
|
if (!_retval)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult result = NS_NOINTERFACE;
|
||||||
|
switch (mEditorType)
|
||||||
|
{
|
||||||
|
case eHTMLTextEditorType:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||||
|
if (tableEditor)
|
||||||
|
result = tableEditor->GetSelectedCellsType(aElement, *_retval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* end of table editing */
|
/* end of table editing */
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -60,14 +60,6 @@ interface nsIEditorShell : nsISupports
|
||||||
eDisplayModeEdit,
|
eDisplayModeEdit,
|
||||||
eDisplayModeBrowserPreview
|
eDisplayModeBrowserPreview
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
eTable,
|
|
||||||
eTableRow,
|
|
||||||
eTableColumn,
|
|
||||||
eTableCell,
|
|
||||||
eTableCaption
|
|
||||||
};
|
|
||||||
%}
|
%}
|
||||||
readonly attribute boolean documentModified;
|
readonly attribute boolean documentModified;
|
||||||
readonly attribute boolean documentIsEmpty;
|
readonly attribute boolean documentIsEmpty;
|
||||||
|
@ -201,6 +193,22 @@ interface nsIEditorShell : nsISupports
|
||||||
*/
|
*/
|
||||||
nsIDOMElement GetSelectedElement(in wstring tagName);
|
nsIDOMElement GetSelectedElement(in wstring tagName);
|
||||||
|
|
||||||
|
/** Get first selected node from first selection range.
|
||||||
|
* Assumes cell-selection model where each cell
|
||||||
|
* is in a separate range (selection parent node is table row)
|
||||||
|
* Returns null if ranges don't contain cell selections
|
||||||
|
*/
|
||||||
|
nsIDOMElement GetFirstSelectedCell();
|
||||||
|
|
||||||
|
/** Get next selected cell element from first selection range.
|
||||||
|
* Assumes cell-selection model where each cell
|
||||||
|
* is in a separate range (selection parent node is table row)
|
||||||
|
* Always call GetFirstSelectedCell() to initialize stored index of "next" cell
|
||||||
|
* Returns null if after last cell or
|
||||||
|
* ranges don't contain cell selections
|
||||||
|
*/
|
||||||
|
nsIDOMElement GetNextSelectedCell();
|
||||||
|
|
||||||
/** Return the input node or a parent matching the given aTagName,
|
/** Return the input node or a parent matching the given aTagName,
|
||||||
* starting the search at the supplied node.
|
* starting the search at the supplied node.
|
||||||
* An example of use is for testing if a node is in a table cell
|
* An example of use is for testing if a node is in a table cell
|
||||||
|
@ -368,12 +376,34 @@ interface nsIEditorShell : nsISupports
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* The table element (table, row, or cell) found
|
* The table element (table, row, or cell) found
|
||||||
|
* If multiple table cells are selected, this is the "focus" cell (last cell selected)
|
||||||
|
*
|
||||||
* tagName The tagname of returned element
|
* tagName The tagname of returned element
|
||||||
* Note that "td" will be returned if name is actually "th"
|
* Note that "td" will be returned if name is actually "th"
|
||||||
* isSelected Tells if element returned is a selected element
|
* selectedCount How many table elements were selected
|
||||||
* (false if element is a parent cell of selection)
|
* This tells us if we have multiple cells selected
|
||||||
|
* (0 if element is a parent cell of selection)
|
||||||
*/
|
*/
|
||||||
nsIDOMElement GetSelectedOrParentTableElement(out wstring tagName, out boolean isSelected);
|
nsIDOMElement GetSelectedOrParentTableElement(out wstring tagName, out PRInt32 selectedCount);
|
||||||
|
|
||||||
|
/** Generally used after GetSelectedOrParentTableElement
|
||||||
|
* to test if selected cells are complete rows or columns
|
||||||
|
*
|
||||||
|
* cellElement Any table, cell, or element inside a table
|
||||||
|
* Used to get enclosing table.
|
||||||
|
* If null, selection's focusNode is used
|
||||||
|
*
|
||||||
|
* Returns: (defines are from nsIFrameSelection.h)
|
||||||
|
* 0 cellElement was not a cell
|
||||||
|
* 1 (TABLESELECTION_CELL) There are 1 or more cells selected
|
||||||
|
* but complete rows or columns are not selected
|
||||||
|
* 2 (TABLESELECTION_ROW) All cells are in 1 or more rows
|
||||||
|
* and in each row, all cells selected
|
||||||
|
* Note: This is the value if all rows (thus all cells) are selected
|
||||||
|
* 3 (TABLESELECTION_COLUMN) All cells are in 1 or more columns
|
||||||
|
* and in each column, all cells are selected
|
||||||
|
*/
|
||||||
|
PRUint32 GetSelectedCellsType(in nsIDOMElement element);
|
||||||
|
|
||||||
/**** end of table editing *****/
|
/**** end of table editing *****/
|
||||||
|
|
||||||
|
|
|
@ -1857,7 +1857,6 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMAttr> resultAttribute;
|
nsCOMPtr<nsIDOMAttr> resultAttribute;
|
||||||
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
|
destElement->RemoveAttributeNode(destAttribute, getter_AddRefs(resultAttribute));
|
||||||
// Is the resultAttribute deleted automagically?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1881,7 +1880,7 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
|
||||||
// Do we ever get here?
|
// Do we ever get here?
|
||||||
destElement->RemoveAttribute(sourceAttrName);
|
destElement->RemoveAttribute(sourceAttrName);
|
||||||
#if DEBUG_cmanske
|
#if DEBUG_cmanske
|
||||||
printf("Attribute in NamedNodeMap has empty value in nsEditor::CloneAttributes()\n");
|
printf("Attribute in sourceAttribute has empty value in nsEditor::CloneAttributes()\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5014,19 +5013,11 @@ nsEditor::GetFirstNodeInRange(nsIDOMRange *aRange, nsIDOMNode **aNode)
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!startParent) return NS_ERROR_FAILURE;
|
if (!startParent) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> startNode;
|
|
||||||
PRInt32 offset;
|
PRInt32 offset;
|
||||||
res = aRange->GetStartOffset(&offset);
|
res = aRange->GetStartOffset(&offset);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
nsCOMPtr<nsIDOMNode> child = GetChildAt(startParent, offset);
|
||||||
res = startParent->GetChildNodes(getter_AddRefs(nodeList));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!nodeList) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> child;
|
|
||||||
res = nodeList->Item(offset,getter_AddRefs(child));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!child) return NS_ERROR_FAILURE;
|
if (!child) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
*aNode = child.get();
|
*aNode = child.get();
|
||||||
|
|
|
@ -224,7 +224,22 @@ nsHTMLEditUtils::IsListItem(nsIDOMNode *node)
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// IsTableCell: true if node an html td or th
|
// IsTable: true if node an html table
|
||||||
|
//
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditUtils::IsTable(nsIDOMNode *node)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTable");
|
||||||
|
nsAutoString tag;
|
||||||
|
nsEditor::GetTagString(node,tag);
|
||||||
|
if (tag == "table")
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// IsTableRow: true if node an html tr
|
||||||
//
|
//
|
||||||
PRBool
|
PRBool
|
||||||
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
static PRBool IsHeader(nsIDOMNode *aNode);
|
static PRBool IsHeader(nsIDOMNode *aNode);
|
||||||
static PRBool IsParagraph(nsIDOMNode *aNode);
|
static PRBool IsParagraph(nsIDOMNode *aNode);
|
||||||
static PRBool IsListItem(nsIDOMNode *aNode);
|
static PRBool IsListItem(nsIDOMNode *aNode);
|
||||||
|
static PRBool IsTable(nsIDOMNode *aNode);
|
||||||
static PRBool IsTableRow(nsIDOMNode *aNode);
|
static PRBool IsTableRow(nsIDOMNode *aNode);
|
||||||
static PRBool IsTableCell(nsIDOMNode *aNode);
|
static PRBool IsTableCell(nsIDOMNode *aNode);
|
||||||
static PRBool IsList(nsIDOMNode *aNode);
|
static PRBool IsList(nsIDOMNode *aNode);
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
#include "nsIDOMSelection.h"
|
#include "nsIDOMSelection.h"
|
||||||
#include "nsIDOMHTMLAnchorElement.h"
|
#include "nsIDOMHTMLAnchorElement.h"
|
||||||
#include "nsIDOMHTMLImageElement.h"
|
#include "nsIDOMHTMLImageElement.h"
|
||||||
|
|
||||||
#include "nsISelectionController.h"
|
#include "nsISelectionController.h"
|
||||||
|
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||||
|
|
||||||
#include "nsICSSLoader.h"
|
#include "nsICSSLoader.h"
|
||||||
#include "nsICSSStyleSheet.h"
|
#include "nsICSSStyleSheet.h"
|
||||||
|
@ -196,11 +196,10 @@ static PRBool IsCellNode(nsIDOMNode *aNode)
|
||||||
nsAutoString tagName;
|
nsAutoString tagName;
|
||||||
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
||||||
{
|
{
|
||||||
tagName.ToLowerCase();
|
// With only 2 tests, it doesn't
|
||||||
// With only 3 tests, it doesn't
|
|
||||||
// seem worth using nsAtoms
|
// seem worth using nsAtoms
|
||||||
if (tagName.Equals("td") ||
|
if (tagName.EqualsIgnoreCase("td") ||
|
||||||
tagName.Equals("th"))
|
tagName.EqualsIgnoreCase("th"))
|
||||||
{
|
{
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +216,7 @@ nsHTMLEditor::nsHTMLEditor()
|
||||||
, mRules(nsnull)
|
, mRules(nsnull)
|
||||||
, mIsComposing(PR_FALSE)
|
, mIsComposing(PR_FALSE)
|
||||||
, mMaxTextLength(-1)
|
, mMaxTextLength(-1)
|
||||||
, mSelectingTableCells(PR_FALSE)
|
, mSelectedCellIndex(0)
|
||||||
{
|
{
|
||||||
// Done in nsEditor
|
// Done in nsEditor
|
||||||
// NS_INIT_REFCNT();
|
// NS_INIT_REFCNT();
|
||||||
|
@ -2620,11 +2619,10 @@ nsHTMLEditor::GetElementOrParentByTagName(const nsString &aTagName, nsIDOMNode *
|
||||||
res = selection->GetAnchorOffset(&offset);
|
res = selection->GetAnchorOffset(&offset);
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
currentNode = nsEditor::GetChildAt(anchorNode, offset);
|
currentNode = nsEditor::GetChildAt(anchorNode, offset);
|
||||||
if (!currentNode) return NS_ERROR_FAILURE;
|
|
||||||
} else {
|
|
||||||
// anchor node is probably a text node - just use that
|
|
||||||
currentNode = anchorNode;
|
|
||||||
}
|
}
|
||||||
|
// anchor node is probably a text node - just use that
|
||||||
|
if (!currentNode)
|
||||||
|
currentNode = anchorNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString TagName = aTagName;
|
nsAutoString TagName = aTagName;
|
||||||
|
@ -3053,14 +3051,30 @@ nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
||||||
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
||||||
|
|
||||||
// Find a selected or enclosing table element to set background on
|
// Find a selected or enclosing table element to set background on
|
||||||
// TODO: Handle case of > 1 table cell or row selected
|
|
||||||
nsCOMPtr<nsIDOMElement> element;
|
nsCOMPtr<nsIDOMElement> element;
|
||||||
PRBool isSelected;
|
PRInt32 selectedCount;
|
||||||
nsAutoString tagName;
|
nsAutoString tagName;
|
||||||
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, isSelected);
|
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(element), tagName, selectedCount);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!element)
|
if (element)
|
||||||
{
|
{
|
||||||
|
if (selectedCount > 0)
|
||||||
|
{
|
||||||
|
// Traverse all selected cells
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(cell));
|
||||||
|
if (NS_SUCCEEDED(res) && cell)
|
||||||
|
{
|
||||||
|
while(cell)
|
||||||
|
{
|
||||||
|
SetAttribute(cell, "bgcolor", aColor);
|
||||||
|
GetNextSelectedCell(getter_AddRefs(cell));
|
||||||
|
};
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we failed to find a cell, fall through to use originally-found element
|
||||||
|
} else {
|
||||||
// No table element -- set the background color on the body tag
|
// No table element -- set the background color on the body tag
|
||||||
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
@ -5826,7 +5840,7 @@ nsHTMLEditor::IsTableCell(nsIDOMNode *node)
|
||||||
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
||||||
nsAutoString tag;
|
nsAutoString tag;
|
||||||
nsEditor::GetTagString(node,tag);
|
nsEditor::GetTagString(node,tag);
|
||||||
if (tag == "td")
|
if (tag == "td" || tag == "th")
|
||||||
{
|
{
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -7844,4 +7858,3 @@ nsHTMLEditor::InsertContainerAbove(nsIDOMNode *inNode,
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,15 @@ public:
|
||||||
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||||
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||||
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
||||||
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected);
|
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount);
|
||||||
|
NS_IMETHOD GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelectionType);
|
||||||
|
// Finds the first selected cell in first range of selection
|
||||||
|
// This is in the *order of selection*, not order in the table
|
||||||
|
// (i.e., each cell added to selection is added in another range
|
||||||
|
// in the selection's rangelist, independent of location in table)
|
||||||
|
NS_IMETHOD GetFirstSelectedCell(nsIDOMElement **aCell);
|
||||||
|
// Get next cell until no more are found. Always use GetFirstSelected cell first
|
||||||
|
NS_IMETHOD GetNextSelectedCell(nsIDOMElement **aCell);
|
||||||
|
|
||||||
|
|
||||||
// Selection and navigation
|
// Selection and navigation
|
||||||
|
@ -348,6 +356,9 @@ protected:
|
||||||
// Needed to do appropriate deleting when last cell or row is about to be deleted
|
// 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)
|
// This doesn't count cells that don't start in the given row (are spanning from row above)
|
||||||
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
||||||
|
// Test if all cells in row or column at given index are selected
|
||||||
|
PRBool AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns);
|
||||||
|
PRBool AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows);
|
||||||
|
|
||||||
// Most insert methods need to get the same basic context data
|
// Most insert methods need to get the same basic context data
|
||||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||||
|
@ -355,17 +366,13 @@ protected:
|
||||||
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
||||||
PRInt32& aRow, PRInt32& aCol);
|
PRInt32& aRow, PRInt32& aCol);
|
||||||
|
|
||||||
// Finds the first selected cell in first range of selection
|
|
||||||
// This is in the *order of selection*, not order in the table
|
|
||||||
// (i.e., each cell added to selection is added in another range
|
|
||||||
// in the selection's rangelist, independent of location in table)
|
|
||||||
NS_IMETHOD GetFirstSelectedCell(nsIDOMElement **aCell);
|
|
||||||
|
|
||||||
// Fallback method: Call this after using ClearSelection() and you
|
// Fallback method: Call this after using ClearSelection() and you
|
||||||
// failed to set selection to some other content in the document
|
// failed to set selection to some other content in the document
|
||||||
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
||||||
|
|
||||||
// end of table editing utilities
|
|
||||||
|
// End of Table Editing utilities
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
||||||
nsString &aParentTag,
|
nsString &aParentTag,
|
||||||
|
@ -607,13 +614,8 @@ protected:
|
||||||
PRBool mCachedUnderlineStyle;
|
PRBool mCachedUnderlineStyle;
|
||||||
nsString mCachedFontName;
|
nsString mCachedFontName;
|
||||||
|
|
||||||
// True when selection consists of table cell(s)
|
// Used by GetFirstSelectedCell and GetNextSelectedCell
|
||||||
PRBool mSelectingTableCells;
|
PRInt32 mSelectedCellIndex;
|
||||||
|
|
||||||
// Used to monitor block of cells selected
|
|
||||||
// by dragging mouse across the table
|
|
||||||
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
|
|
||||||
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static nsIAtom *gTypingTxnName;
|
static nsIAtom *gTypingTxnName;
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "nsITableCellLayout.h" // For efficient access to table cell
|
#include "nsITableCellLayout.h" // For efficient access to table cell
|
||||||
#include "nsITableLayout.h" // data owned by the table and cell frames
|
#include "nsITableLayout.h" // data owned by the table and cell frames
|
||||||
#include "nsHTMLEditor.h"
|
#include "nsHTMLEditor.h"
|
||||||
|
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
|
||||||
#include "nsEditorUtils.h"
|
#include "nsEditorUtils.h"
|
||||||
|
|
||||||
|
@ -799,7 +801,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
||||||
if (curCell)
|
if (curCell)
|
||||||
{
|
{
|
||||||
// This must always be >= 1
|
// This must always be >= 1
|
||||||
NS_ASSERTION((actualRowSpan > 0),"Effective ROWSPAN = 0 in DeleteTableColumn");
|
NS_ASSERTION((actualRowSpan > 0),"Actual ROWSPAN = 0 in DeleteTableColumn");
|
||||||
|
|
||||||
// Find cells that don't start in column we are deleting
|
// Find cells that don't start in column we are deleting
|
||||||
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
||||||
|
@ -1643,13 +1645,9 @@ nsHTMLEditor::GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!aSelection) return NS_ERROR_FAILURE;
|
if (!aSelection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// Find the first selected cell
|
|
||||||
// res = GetFirstSelectedCell(getter_AddRefs(aCell));
|
|
||||||
if (!aCell)
|
if (!aCell)
|
||||||
{
|
{
|
||||||
//If a cell wasn't selected, then assume the selection is INSIDE
|
// Get cell if it's the child of selection anchor node,
|
||||||
// and use anchor node to search up to the containing cell
|
|
||||||
// Test if selected node (from anchor node) is a cell
|
|
||||||
// or get the enclosing by a cell
|
// or get the enclosing by a cell
|
||||||
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
@ -1683,78 +1681,109 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell)
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!selection) return NS_ERROR_FAILURE;
|
if (!selection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
//TODO: Replace this with code below new "table cell mode" flag is implemented
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEnumerator> enumerator;
|
|
||||||
res = selection->GetEnumerator(getter_AddRefs(enumerator));
|
|
||||||
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!enumerator) return NS_ERROR_FAILURE;
|
|
||||||
enumerator->First();
|
|
||||||
nsCOMPtr<nsISupports> currentItem;
|
|
||||||
res = enumerator->CurrentItem(getter_AddRefs(currentItem));
|
|
||||||
if ((NS_SUCCEEDED(res)) && currentItem)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
|
||||||
nsCOMPtr<nsIContentIterator> iter;
|
|
||||||
res = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
|
||||||
NS_GET_IID(nsIContentIterator),
|
|
||||||
getter_AddRefs(iter));
|
|
||||||
if (NS_FAILED(res)) return res;
|
|
||||||
if (!iter) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
iter->Init(range);
|
|
||||||
// loop through the content iterator for each content node
|
|
||||||
nsCOMPtr<nsIContent> content;
|
|
||||||
|
|
||||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
|
||||||
{
|
|
||||||
res = iter->CurrentNode(getter_AddRefs(content));
|
|
||||||
// Not likely!
|
|
||||||
if (NS_FAILED(res)) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAtom> atom;
|
|
||||||
content->GetTag(*getter_AddRefs(atom));
|
|
||||||
if (atom.get() == nsIEditProperty::td ||
|
|
||||||
atom.get() == nsIEditProperty::th )
|
|
||||||
{
|
|
||||||
// We found a cell
|
|
||||||
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(content);
|
|
||||||
if (cellElement)
|
|
||||||
{
|
|
||||||
*aCell = cellElement.get();
|
|
||||||
NS_ADDREF(*aCell);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
iter->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//TODO: Do this only after checking the new "table cell mode" flag
|
|
||||||
// The first cell is the starting node in the first selection range
|
|
||||||
nsCOMPtr<nsIDOMRange> firstRange;
|
nsCOMPtr<nsIDOMRange> firstRange;
|
||||||
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!firstRange) return NS_ERROR_FAILURE;
|
if (!firstRange) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
#ifdef DEBUG_cmanske
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||||
|
PRInt32 anchorOffset = -1;
|
||||||
|
selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||||
|
selection->GetAnchorOffset(&anchorOffset);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> focusNode;
|
||||||
|
res = selection->GetFocusNode(getter_AddRefs(focusNode));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
PRInt32 focusOffset = -1;
|
||||||
|
selection->GetFocusOffset(&focusOffset);
|
||||||
|
|
||||||
|
nsAutoString name;
|
||||||
|
anchorNode->GetNodeName(name);
|
||||||
|
printf("GetFirstSelectedCell: Anchor node of selection: ");
|
||||||
|
wprintf(name.GetUnicode());
|
||||||
|
printf(" Offset: %d\n", anchorOffset);
|
||||||
|
focusNode->GetNodeName(name);
|
||||||
|
printf("Focus node of selection: ");
|
||||||
|
wprintf(name.GetUnicode());
|
||||||
|
printf(" Offset: %x\n", focusOffset);
|
||||||
|
|
||||||
|
PRInt32 rangeCount;
|
||||||
|
res = selection->GetRangeCount(&rangeCount);
|
||||||
|
printf(" RangeCount: %d\n", rangeCount);
|
||||||
|
printf(" Range pointer = %d\n", firstRange);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This is failing -- range doesn't match that set when selecting cell!
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> cellNode;
|
nsCOMPtr<nsIDOMNode> cellNode;
|
||||||
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
if (!cellNode) return NS_ERROR_FAILURE;
|
if (!cellNode) return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
|
||||||
|
|
||||||
if (cellElement)
|
if (IsTableCell(cellNode))
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
||||||
*aCell = cellElement.get();
|
*aCell = cellElement.get();
|
||||||
NS_ADDREF(*aCell);
|
NS_ADDREF(*aCell);
|
||||||
}
|
}
|
||||||
else res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
else
|
||||||
|
res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
|
||||||
|
mSelectedCellIndex = 1;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell)
|
||||||
|
{
|
||||||
|
if (!aCell) return NS_ERROR_NULL_POINTER;
|
||||||
|
*aCell = nsnull;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMSelection> selection;
|
||||||
|
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!selection) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRInt32 rangeCount;
|
||||||
|
res = selection->GetRangeCount(&rangeCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// Don't even try if index exceeds range count
|
||||||
|
if (mSelectedCellIndex >= rangeCount)
|
||||||
|
{
|
||||||
|
// Should we reset index?
|
||||||
|
// Maybe better to force recalling GetFirstSelectedCell()
|
||||||
|
//mSelectedCellIndex = 0;
|
||||||
|
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first node in first range of selection - test if it's a cell
|
||||||
|
nsCOMPtr<nsIDOMRange> range;
|
||||||
|
res = selection->GetRangeAt(mSelectedCellIndex, getter_AddRefs(range));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!range) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> cellNode;
|
||||||
|
res = nsEditor::GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
if (!cellNode) return NS_ERROR_FAILURE;
|
||||||
|
if (IsTableCell(cellNode))
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(cellNode);
|
||||||
|
*aCell = cellElement.get();
|
||||||
|
NS_ADDREF(*aCell);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||||
|
|
||||||
|
// Setup for next cell
|
||||||
|
mSelectedCellIndex++;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1842,11 +1871,11 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt3
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount)
|
||||||
{
|
{
|
||||||
aTableElement = nsnull;
|
aTableElement = nsnull;
|
||||||
aTagName = "";
|
aTagName = "";
|
||||||
aIsSelected = PR_FALSE;
|
aSelectedCount = 0;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMSelection> selection;
|
nsCOMPtr<nsIDOMSelection> selection;
|
||||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||||
|
@ -1858,52 +1887,218 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
||||||
nsAutoString tdName("td");
|
nsAutoString tdName("td");
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||||
|
|
||||||
// Find the first selected cell
|
|
||||||
// TODO: Handle multiple cells selected!
|
|
||||||
nsCOMPtr<nsIDOMElement> firstCell;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMElement> tableElement;
|
|
||||||
res = GetFirstSelectedCell(getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = tdName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if table or row is selected
|
|
||||||
res = GetSelectedElement(tableName, getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = tableName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
res = GetSelectedElement(trName, getter_AddRefs(tableElement));
|
|
||||||
if(NS_FAILED(res)) return res;
|
|
||||||
if (tableElement)
|
|
||||||
{
|
|
||||||
aTagName = trName;
|
|
||||||
aIsSelected = PR_TRUE;
|
|
||||||
goto SET_RETURN_ELEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for a table cell parent
|
|
||||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMElement> tableElement;
|
||||||
|
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||||
|
|
||||||
|
// Get child of anchor node, if exists
|
||||||
|
PRBool hasChildren;
|
||||||
|
anchorNode->HasChildNodes(&hasChildren);
|
||||||
|
|
||||||
|
if (hasChildren)
|
||||||
|
{
|
||||||
|
PRInt32 anchorOffset;
|
||||||
|
res = selection->GetAnchorOffset(&anchorOffset);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
selectedNode = nsEditor::GetChildAt(anchorNode, anchorOffset);
|
||||||
|
if (!selectedNode)
|
||||||
|
selectedNode = anchorNode;
|
||||||
|
|
||||||
|
nsAutoString tag;
|
||||||
|
nsEditor::GetTagString(selectedNode,tag);
|
||||||
|
|
||||||
|
if (tag == tdName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = tdName;
|
||||||
|
// Each cell is in its own selection range,
|
||||||
|
// so count signals multiple-cell selection
|
||||||
|
res = selection->GetRangeCount(&aSelectedCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
}
|
||||||
|
else if(tag == tableName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = tableName;
|
||||||
|
aSelectedCount = 1;
|
||||||
|
}
|
||||||
|
else if(tag == trName)
|
||||||
|
{
|
||||||
|
tableElement = do_QueryInterface(anchorNode);
|
||||||
|
aTagName = trName;
|
||||||
|
aSelectedCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tableElement)
|
||||||
|
{
|
||||||
|
// Didn't find a table element -- find a cell parent
|
||||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
||||||
if(NS_FAILED(res)) return res;
|
if(NS_FAILED(res)) return res;
|
||||||
if (tableElement)
|
if (tableElement)
|
||||||
{
|
|
||||||
aTagName = tdName;
|
aTagName = tdName;
|
||||||
SET_RETURN_ELEMENT:
|
}
|
||||||
|
if (tableElement)
|
||||||
|
{
|
||||||
aTableElement = tableElement.get();
|
aTableElement = tableElement.get();
|
||||||
NS_ADDREF(aTableElement);
|
NS_ADDREF(aTableElement);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool IndexNotTested(nsVoidArray *aArray, PRInt32 aIndex)
|
||||||
|
{
|
||||||
|
if (aArray)
|
||||||
|
{
|
||||||
|
PRInt32 count = aArray->Count();
|
||||||
|
for (PRInt32 i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if(aIndex == (PRInt32)(aArray->ElementAt(i)))
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEditor::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelectionType)
|
||||||
|
{
|
||||||
|
aSelectionType = 0;
|
||||||
|
|
||||||
|
// Be sure we have a table element
|
||||||
|
// (if aElement is null, this uses selection's anchor node)
|
||||||
|
nsCOMPtr<nsIDOMElement> table;
|
||||||
|
|
||||||
|
nsresult res = GetElementOrParentByTagName("table", aElement, getter_AddRefs(table));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
PRInt32 rowCount, colCount;
|
||||||
|
res = GetTableSize(table, rowCount, colCount);
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// Traverse all selected cells
|
||||||
|
// (Failure here may indicate that aCellElement wasn't really a cell)
|
||||||
|
nsCOMPtr<nsIDOMElement> selectedCell;
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
// We have at least one selected cell, so set return value
|
||||||
|
aSelectionType = TABLESELECTION_CELL;
|
||||||
|
|
||||||
|
// Store indexes of each row/col to avoid duplication of searches
|
||||||
|
nsVoidArray indexArray;
|
||||||
|
|
||||||
|
PRBool allCellsInRowAreSelected = PR_TRUE;
|
||||||
|
PRBool allCellsInColAreSelected = PR_FALSE;
|
||||||
|
while (NS_SUCCEEDED(res) && selectedCell)
|
||||||
|
{
|
||||||
|
// Get the cell's location in the cellmap
|
||||||
|
PRInt32 startRowIndex, startColIndex;
|
||||||
|
res = GetCellIndexes(selectedCell, startRowIndex, startColIndex);
|
||||||
|
if(NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
if (IndexNotTested(&indexArray, startColIndex))
|
||||||
|
{
|
||||||
|
indexArray.AppendElement((void*)startColIndex);
|
||||||
|
allCellsInRowAreSelected = AllCellsInRowSelected(table, startRowIndex, colCount);
|
||||||
|
// We're done as soon as we fail for any row
|
||||||
|
if (!allCellsInRowAreSelected) break;
|
||||||
|
}
|
||||||
|
res = GetNextSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCellsInRowAreSelected)
|
||||||
|
{
|
||||||
|
aSelectionType = TABLESELECTION_ROW;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
// Test for columns
|
||||||
|
|
||||||
|
// Empty the indexArray
|
||||||
|
indexArray.Clear();
|
||||||
|
|
||||||
|
// Start at first cell again
|
||||||
|
res = GetFirstSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
while (NS_SUCCEEDED(res) && selectedCell)
|
||||||
|
{
|
||||||
|
// Get the cell's location in the cellmap
|
||||||
|
PRInt32 startRowIndex, startColIndex;
|
||||||
|
res = GetCellIndexes(selectedCell, startRowIndex, startColIndex);
|
||||||
|
if(NS_FAILED(res)) return res;
|
||||||
|
|
||||||
|
if (IndexNotTested(&indexArray, startRowIndex))
|
||||||
|
{
|
||||||
|
indexArray.AppendElement((void*)startColIndex);
|
||||||
|
allCellsInColAreSelected = AllCellsInColumnSelected(table, startColIndex, colCount);
|
||||||
|
// We're done as soon as we fail for any column
|
||||||
|
if (!allCellsInRowAreSelected) break;
|
||||||
|
}
|
||||||
|
res = GetNextSelectedCell(getter_AddRefs(selectedCell));
|
||||||
|
}
|
||||||
|
if (allCellsInColAreSelected)
|
||||||
|
aSelectionType = TABLESELECTION_COLUMN;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditor::AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns)
|
||||||
|
{
|
||||||
|
if (!aTable) return PR_FALSE;
|
||||||
|
|
||||||
|
PRInt32 curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||||
|
PRBool isSelected;
|
||||||
|
|
||||||
|
for( PRInt32 col = 0; col < aNumberOfColumns; col += actualColSpan)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
nsresult res = GetCellDataAt(aTable, aRowIndex, col, *getter_AddRefs(cell),
|
||||||
|
curStartRowIndex, curStartColIndex, rowSpan, colSpan,
|
||||||
|
actualRowSpan, actualColSpan, isSelected);
|
||||||
|
|
||||||
|
if (NS_FAILED(res)) return PR_FALSE;
|
||||||
|
// Skip cell spanning into this location from a row above
|
||||||
|
if (curStartRowIndex == aRowIndex)
|
||||||
|
{
|
||||||
|
// If no cell, we may have a "ragged" right edge,
|
||||||
|
// so return TRUE only if we already found a cell in the row
|
||||||
|
if (!cell) return (col > 0) ? PR_TRUE : PR_FALSE;
|
||||||
|
// Return as soon as a non-selected cell is found
|
||||||
|
if (!isSelected) return PR_FALSE;
|
||||||
|
}
|
||||||
|
NS_ASSERTION((actualColSpan > 0),"ActualColSpan = 0 in AllCellsInRowSelected");
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsHTMLEditor::AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows)
|
||||||
|
{
|
||||||
|
if (!aTable) return PR_FALSE;
|
||||||
|
|
||||||
|
PRInt32 curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||||
|
PRBool isSelected;
|
||||||
|
|
||||||
|
for( PRInt32 row = 0; row < aNumberOfRows; row += actualRowSpan)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMElement> cell;
|
||||||
|
nsresult res = GetCellDataAt(aTable, row, aColIndex, *getter_AddRefs(cell),
|
||||||
|
curStartRowIndex, curStartColIndex, rowSpan, colSpan,
|
||||||
|
actualRowSpan, actualColSpan, isSelected);
|
||||||
|
|
||||||
|
if (NS_FAILED(res)) return PR_FALSE;
|
||||||
|
// Skip cell spanning into this location from a column to the left
|
||||||
|
if (curStartColIndex == aColIndex)
|
||||||
|
{
|
||||||
|
// If no cell, we must have a "ragged" right edge on the last column
|
||||||
|
// so return TRUE only if we already found a cell in the row
|
||||||
|
if (!cell) return (row > 0) ? PR_TRUE : PR_FALSE;
|
||||||
|
// Return as soon as a non-selected cell is found
|
||||||
|
if (!isSelected) return PR_FALSE;
|
||||||
|
}
|
||||||
|
NS_ASSERTION((actualRowSpan > 0),"ActualRowSpan = 0 in AllCellsInColumnSelected");
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -237,13 +237,48 @@ public:
|
||||||
* @param aTableElement The table element (table, row, or cell) returned
|
* @param aTableElement The table element (table, row, or cell) returned
|
||||||
* @param aTagName The tagname of returned element
|
* @param aTagName The tagname of returned element
|
||||||
* Note that "td" will be returned if name is actually "th"
|
* Note that "td" will be returned if name is actually "th"
|
||||||
* @param aIsSelected Tells if element returned is a selected element
|
* @param aSelectedCount How many table elements were selected
|
||||||
* (false if element is a parent cell of selection)
|
* This tells us if we have multiple cells selected
|
||||||
|
* (0 if element is a parent cell of selection)
|
||||||
|
*
|
||||||
* Returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found (passes NS_SUCCEEDED macro)
|
* Returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found (passes NS_SUCCEEDED macro)
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)=0;
|
NS_IMETHOD GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount)=0;
|
||||||
|
|
||||||
|
/** Generally used after GetSelectedOrParentTableElement
|
||||||
|
* to test if selected cells are complete rows or columns
|
||||||
|
*
|
||||||
|
* @param aElement Any table or cell element or any element inside a table
|
||||||
|
* Used to get enclosing table.
|
||||||
|
* If null, selection's anchorNode is used
|
||||||
|
*
|
||||||
|
* @param aSelectionType Returns:
|
||||||
|
* 0 aCellElement was not a cell (returned result = NS_ERROR_FAILURE)
|
||||||
|
* TABLESELECTION_CELL There are 1 or more cells selected
|
||||||
|
* but complete rows or columns are not selected
|
||||||
|
* TABLESELECTION_ROW All cells are in 1 or more rows
|
||||||
|
* and in each row, all cells selected
|
||||||
|
* Note: This is the value if all rows (thus all cells) are selected
|
||||||
|
* TABLESELECTION_COLUMN All cells are in 1 or more columns
|
||||||
|
* and in each column, all cells are selected
|
||||||
|
*/
|
||||||
|
NS_IMETHOD GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelectionType)=0;
|
||||||
|
|
||||||
|
/** Get first selected element from first selection range.
|
||||||
|
* Assumes cell-selection model where each cell
|
||||||
|
* is in a separate range (selection parent node is table row)
|
||||||
|
* @param aCell Selected cell or null if ranges don't contain cell selections
|
||||||
|
*/
|
||||||
|
NS_IMETHOD GetFirstSelectedCell(nsIDOMElement **aCell)=0;
|
||||||
|
|
||||||
|
/** Get next selected cell element from first selection range.
|
||||||
|
* Assumes cell-selection model where each cell
|
||||||
|
* is in a separate range (selection parent node is table row)
|
||||||
|
* Always call GetFirstSelectedCell() to initialize stored index of "next" cell
|
||||||
|
* @param aCell Selected cell or null if no more selected cells
|
||||||
|
* or ranges don't contain cell selections
|
||||||
|
*/
|
||||||
|
NS_IMETHOD GetNextSelectedCell(nsIDOMElement **aCell)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // nsITableEditor_h__
|
#endif // nsITableEditor_h__
|
||||||
|
|
|
@ -1153,9 +1153,9 @@ function SetBackColorString(xulElementID)
|
||||||
if (xulElement)
|
if (xulElement)
|
||||||
{
|
{
|
||||||
var textVal;
|
var textVal;
|
||||||
var isSelectedObj = new Object();
|
var selectedCountObj = new Object();
|
||||||
var tagNameObj = new Object();
|
var tagNameObj = new Object();
|
||||||
var element = editorShell.GetSelectedOrParentTableElement(tagNameObj, isSelectedObj);
|
var element = editorShell.GetSelectedOrParentTableElement(tagNameObj, selectedCountObj);
|
||||||
|
|
||||||
if (tagNameObj.value == "table")
|
if (tagNameObj.value == "table")
|
||||||
textVal = editorShell.GetString("TableBackColor");
|
textVal = editorShell.GetString("TableBackColor");
|
||||||
|
@ -1564,6 +1564,7 @@ function EditorInsertOrEditTable(insertAllowed)
|
||||||
|
|
||||||
function EditorTableCellProperties()
|
function EditorTableCellProperties()
|
||||||
{
|
{
|
||||||
|
dump("*** EditorTableCellProperties\n");
|
||||||
var cell = editorShell.GetElementOrParentByTagName("td", null);
|
var cell = editorShell.GetElementOrParentByTagName("td", null);
|
||||||
if (cell) {
|
if (cell) {
|
||||||
// Start Table Properties dialog on the "Cell" panel
|
// Start Table Properties dialog on the "Cell" panel
|
||||||
|
|
|
@ -107,6 +107,18 @@ function EditorTestSelection()
|
||||||
|
|
||||||
function EditorTestTableLayout()
|
function EditorTestTableLayout()
|
||||||
{
|
{
|
||||||
|
dump("\n\n\n************ Dump Selection Ranges ************\n");
|
||||||
|
var selection = editorShell.editorSelection;
|
||||||
|
for (i = 0; i < selection.rangeCount; i++)
|
||||||
|
{
|
||||||
|
var range = selection.getRangeAt(i);
|
||||||
|
if (range)
|
||||||
|
{
|
||||||
|
dump("Range "+i+": StartParent="+range.startParent+", offset="+range.startOffset+"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dump("\n\n");
|
||||||
|
|
||||||
var table = editorShell.GetElementOrParentByTagName("table", null);
|
var table = editorShell.GetElementOrParentByTagName("table", null);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
dump("Enclosing Table not found: Place caret in a table cell to do this test\n\n");
|
dump("Enclosing Table not found: Place caret in a table cell to do this test\n\n");
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
<html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js"/>
|
<html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js"/>
|
||||||
<html:script language="JavaScript" src="chrome://editor/content/EditorCommandsDebug.js"/>
|
<html:script language="JavaScript" src="chrome://editor/content/EditorCommandsDebug.js"/>
|
||||||
|
<html:script language="JavaScript" src="chrome://editor/content/EditorCommandsDebug.js"/>
|
||||||
|
<html:script language="javascript" src="chrome://global/content/strres.js"/>
|
||||||
|
|
||||||
<commands id="commands">
|
<commands id="commands">
|
||||||
<commandset id="globalEditMenuItems"/>
|
<commandset id="globalEditMenuItems"/>
|
||||||
|
|
|
@ -50,6 +50,7 @@ var bgcolor = "bgcolor";
|
||||||
var CellIsHeader = false;
|
var CellIsHeader = false;
|
||||||
var rowCount = 1;
|
var rowCount = 1;
|
||||||
var colCount = 1;
|
var colCount = 1;
|
||||||
|
var selectedCellCount = 0;
|
||||||
var error = 0;
|
var error = 0;
|
||||||
|
|
||||||
// dialog initialization code
|
// dialog initialization code
|
||||||
|
@ -81,7 +82,11 @@ function Startup()
|
||||||
// dialog.TableLeaveLocCheck = document.getElementById("TableLeaveLocCheck");
|
// dialog.TableLeaveLocCheck = document.getElementById("TableLeaveLocCheck");
|
||||||
|
|
||||||
// Cell Panel
|
// Cell Panel
|
||||||
dialog.SelectionSelect = document.getElementById("SelectionSelect");
|
dialog.SelectionList = document.getElementById("SelectionList");
|
||||||
|
dialog.SelectCellItem = document.getElementById("SelectCellItem");
|
||||||
|
dialog.SelectRowItem = document.getElementById("SelectRowItem");
|
||||||
|
dialog.SelectColumnItem = document.getElementById("SelectColumnItem");
|
||||||
|
|
||||||
dialog.CellHeightInput = document.getElementById("CellHeightInput");
|
dialog.CellHeightInput = document.getElementById("CellHeightInput");
|
||||||
dialog.CellHeightUnits = document.getElementById("CellHeightUnits");
|
dialog.CellHeightUnits = document.getElementById("CellHeightUnits");
|
||||||
dialog.CellWidthInput = document.getElementById("CellWidthInput");
|
dialog.CellWidthInput = document.getElementById("CellWidthInput");
|
||||||
|
@ -98,14 +103,28 @@ function Startup()
|
||||||
// dialog.CellLeaveLocCheck = document.getElementById("CellLeaveLocCheck");
|
// dialog.CellLeaveLocCheck = document.getElementById("CellLeaveLocCheck");
|
||||||
|
|
||||||
TableElement = editorShell.GetElementOrParentByTagName("table", null);
|
TableElement = editorShell.GetElementOrParentByTagName("table", null);
|
||||||
CellElement = editorShell.GetElementOrParentByTagName("td", null);
|
var tagNameObj = new Object;
|
||||||
|
var countObj = new Object;
|
||||||
|
var element = editorShell.GetSelectedOrParentTableElement(tagNameObj, countObj);
|
||||||
|
var tagName = tagNameObj.value;
|
||||||
|
|
||||||
|
if (tagNameObj.value == "td")
|
||||||
|
{
|
||||||
|
dump("*** Found cell around selection\n");
|
||||||
|
CellElement = element;
|
||||||
|
}
|
||||||
|
selectedCellCount = countObj.value;
|
||||||
|
|
||||||
|
// If the count is 0, then we are inside the cell, so select it
|
||||||
|
if (selectedCellCount == 0)
|
||||||
|
editorShell.SelectCell();
|
||||||
|
|
||||||
// We allow a missing cell -- see below
|
|
||||||
if(!TableElement)
|
if(!TableElement)
|
||||||
{
|
{
|
||||||
dump("Failed to get selected element or create a new one!\n");
|
dump("Failed to get selected element or create a new one!\n");
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
// We allow a missing cell -- see below
|
||||||
|
|
||||||
TabPanel = document.getElementById("TabPanel");
|
TabPanel = document.getElementById("TabPanel");
|
||||||
var TableTab = document.getElementById("TableTab");
|
var TableTab = document.getElementById("TableTab");
|
||||||
|
@ -123,6 +142,7 @@ function Startup()
|
||||||
// Activate the Cell Panel if requested
|
// Activate the Cell Panel if requested
|
||||||
if (currentPanel == CellPanel)
|
if (currentPanel == CellPanel)
|
||||||
{
|
{
|
||||||
|
dump("*** Requested CellPanel for Table Properties dialog.\n");
|
||||||
// We must have a cell element to start in this panel
|
// We must have a cell element to start in this panel
|
||||||
if(!CellElement)
|
if(!CellElement)
|
||||||
{
|
{
|
||||||
|
@ -156,11 +176,17 @@ function Startup()
|
||||||
|
|
||||||
doSetOKCancel(onOK, null);
|
doSetOKCancel(onOK, null);
|
||||||
|
|
||||||
|
// Note: we must use TableElement, not globalTableElement for these,
|
||||||
|
// thus we should not put this in InitDialog.
|
||||||
|
// Instead, monitor desired counts with separate globals
|
||||||
|
rowCount = editorShell.GetTableRowCount(TableElement);
|
||||||
|
colCount = editorShell.GetTableColumnCount(TableElement);
|
||||||
|
|
||||||
// This uses values set on global Elements;
|
// This uses values set on global Elements;
|
||||||
InitDialog();
|
InitDialog();
|
||||||
|
|
||||||
// Should be dialog.TableRowsInput, or
|
// Should be dialog.TableRowsInput, or
|
||||||
// SelectionSelect in cel panenl,
|
// SelectionList in cel panenl,
|
||||||
// but this is disabled for Beta1disabled for Beta1
|
// but this is disabled for Beta1disabled for Beta1
|
||||||
if (currentPanel == CellPanel)
|
if (currentPanel == CellPanel)
|
||||||
dialog.CellHeightInput.focus();
|
dialog.CellHeightInput.focus();
|
||||||
|
@ -172,19 +198,8 @@ function Startup()
|
||||||
function InitDialog()
|
function InitDialog()
|
||||||
{
|
{
|
||||||
// Get Table attributes
|
// Get Table attributes
|
||||||
try {
|
|
||||||
// For some strange reason, we are failing to the "layoutObject" for the table!
|
|
||||||
rowCount = editorShell.GetTableRowCount(globalTableElement);
|
|
||||||
dialog.TableRowsInput.value = rowCount;
|
dialog.TableRowsInput.value = rowCount;
|
||||||
colCount = editorShell.GetTableColumnCount(tableGlobatlElement);
|
|
||||||
dialog.TableColumnsInput.value = colCount;
|
dialog.TableColumnsInput.value = colCount;
|
||||||
}
|
|
||||||
catch (ex) {
|
|
||||||
dump("Failed to get table rows and/or columns count\n");
|
|
||||||
dialog.TableRowsInput.value = "";
|
|
||||||
dialog.TableColumnsInput.value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog.TableHeightInput.value = InitPixelOrPercentCombobox(globalTableElement, "height", "TableHeightUnits");
|
dialog.TableHeightInput.value = InitPixelOrPercentCombobox(globalTableElement, "height", "TableHeightUnits");
|
||||||
dialog.TableWidthInput.value = InitPixelOrPercentCombobox(globalTableElement, "width", "TableWidthUnits");
|
dialog.TableWidthInput.value = InitPixelOrPercentCombobox(globalTableElement, "width", "TableWidthUnits");
|
||||||
dialog.BorderWidthInput.value = globalTableElement.border;
|
dialog.BorderWidthInput.value = globalTableElement.border;
|
||||||
|
@ -220,12 +235,25 @@ dump("Caption Element = "+captionElement+"\n");
|
||||||
// Get cell attributes
|
// Get cell attributes
|
||||||
if (globalCellElement)
|
if (globalCellElement)
|
||||||
{
|
{
|
||||||
//TODO: Test if all cells in selection are in a row or column,
|
// Test if entire rows or columns are selected and set menu appropriately
|
||||||
// and set dialog.SelectionSelect.selectedIndex appropriately
|
var SelectionType = editorShell.GetSelectedCellsType(TableElement);
|
||||||
|
dump("SelectionList.selectedIndex = "+dialog.SelectionList.selectedIndex+"\n");
|
||||||
|
switch (SelectionType)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
dialog.SelectionList.selectedItem = dialog.SelectRowItem;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dialog.SelectionList.selectedItem = dialog.SelectColumnItem;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dialog.SelectionList.selectedItem = dialog.SelectCellItem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
dialog.CellHeightInput.value = InitPixelOrPercentCombobox(globalCellElement, "height", "CellHeightUnits");
|
dialog.CellHeightInput.value = InitPixelOrPercentCombobox(globalCellElement, "height", "CellHeightUnits");
|
||||||
dialog.CellWidthInput.value = InitPixelOrPercentCombobox(globalCellElement, "width", "CellWidthUnits");
|
dialog.CellWidthInput.value = InitPixelOrPercentCombobox(globalCellElement, "width", "CellWidthUnits");
|
||||||
|
|
||||||
//BUG: We don't suppor "rowSpan" or "colSpan" JS attributes?
|
//BUG: We don't support "rowSpan" or "colSpan" JS attributes?
|
||||||
dump("RowSpan="+globalCellElement.rowSpan+" ColSpan="+globalCellElement.colSpan+"\n");
|
dump("RowSpan="+globalCellElement.rowSpan+" ColSpan="+globalCellElement.colSpan+"\n");
|
||||||
|
|
||||||
dialog.RowSpanInput.value = globalCellElement.getAttribute("rowspan");
|
dialog.RowSpanInput.value = globalCellElement.getAttribute("rowspan");
|
||||||
|
@ -584,12 +612,22 @@ function onOK()
|
||||||
{
|
{
|
||||||
if (ValidateData())
|
if (ValidateData())
|
||||||
{
|
{
|
||||||
|
editorShell.BeginBatchChanges();
|
||||||
editorShell.CloneAttributes(TableElement, globalTableElement);
|
editorShell.CloneAttributes(TableElement, globalTableElement);
|
||||||
editorShell.CloneAttributes(CellElement, globalCellElement);
|
// Apply changes to all selected cells
|
||||||
|
var selectedCell = editorShell.GetFirstSelectedCell();
|
||||||
|
while (selectedCell)
|
||||||
|
{
|
||||||
|
// TODO: We need to change this to set only particular attributes
|
||||||
|
// Set an "ignore" attribute on the attribute node?
|
||||||
|
editorShell.CloneAttributes(selectedCell,globalCellElement);
|
||||||
|
selectedCell = editorShell.GetNextSelectedCell();
|
||||||
|
}
|
||||||
//TODO: DOM manipulation to add/remove table rows/columns,
|
//TODO: DOM manipulation to add/remove table rows/columns,
|
||||||
// Switch cell type to TH -- involves removing TD and replacing with TD
|
// Switch cell type to TH -- involves removing TD and replacing with TD
|
||||||
// Creating and moving CAPTION element
|
// Creating and moving CAPTION element
|
||||||
|
|
||||||
|
editorShell.EndBatchChanges();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -172,11 +172,13 @@
|
||||||
<titledbox class="NoTopMargin NoTopPadding NoBottomPad" autostretch="never" valign="middle">
|
<titledbox class="NoTopMargin NoTopPadding NoBottomPad" autostretch="never" valign="middle">
|
||||||
<title><text align="left" value="&cellSelection.label;"/></title>
|
<title><text align="left" value="&cellSelection.label;"/></title>
|
||||||
<spring class="spacer"/>
|
<spring class="spacer"/>
|
||||||
<html:select class="MinWidth50" id="SelectionSelect" disabled="true">
|
<menulist class="MinWidth50" id="SelectionList">
|
||||||
<html:option>&cellSelectionCell.label;</html:option>
|
<menupopup>
|
||||||
<html:option>&cellSelectionRow.label;</html:option>
|
<menuitem data="1" id="SelectCellItem" value="&cellSelectionCell.label;"/>
|
||||||
<html:option>&cellSelectionColumn.label;</html:option>
|
<menuitem data="2" id="SelectRowItem" value="&cellSelectionRow.label;"/>
|
||||||
</html:select>
|
<menuitem data="3" id="SelectColumnItem" value="&cellSelectionColumn.label;"/>
|
||||||
|
</menupopup>
|
||||||
|
</menulist>
|
||||||
<spring class="bigspacer"/>
|
<spring class="bigspacer"/>
|
||||||
<titledbutton class="push MinWidth50" value="&cellSelectionPrevious.label;" onclick="SelectPrevious()" disabled="true"/>
|
<titledbutton class="push MinWidth50" value="&cellSelectionPrevious.label;" onclick="SelectPrevious()" disabled="true"/>
|
||||||
<spring class="bigspacer"/>
|
<spring class="bigspacer"/>
|
||||||
|
|
|
@ -45,8 +45,8 @@ tr {
|
||||||
input {
|
input {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
max-height: 1em;
|
max-height: 1em;
|
||||||
padding-top: 5px;
|
padding-top: 2px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 2px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче