зеркало из 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;
|
||||
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?
|
||||
destElement->RemoveAttribute(sourceAttrName);
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
@ -5014,19 +5013,11 @@ nsEditor::GetFirstNodeInRange(nsIDOMRange *aRange, nsIDOMNode **aNode)
|
|||
if (NS_FAILED(res)) return res;
|
||||
if (!startParent) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
PRInt32 offset;
|
||||
res = aRange->GetStartOffset(&offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
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;
|
||||
nsCOMPtr<nsIDOMNode> child = GetChildAt(startParent, offset);
|
||||
if (!child) return NS_ERROR_FAILURE;
|
||||
|
||||
*aNode = child.get();
|
||||
|
|
|
@ -2847,6 +2847,59 @@ nsEditorShell::GetSelectedElement(const PRUnichar *aInTagName, nsIDOMElement **a
|
|||
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
|
||||
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
||||
{
|
||||
|
@ -3537,9 +3590,9 @@ nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
nsresult result = NS_NOINTERFACE;
|
||||
|
@ -3550,7 +3603,7 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
|||
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||
nsAutoString TagName(*aTagName);
|
||||
if (tableEditor)
|
||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected);
|
||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aSelectedCount);
|
||||
*aTagName = TagName.ToNewUnicode();
|
||||
}
|
||||
break;
|
||||
|
@ -3560,6 +3613,28 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
|||
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 */
|
||||
|
||||
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
|
||||
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
static PRBool IsHeader(nsIDOMNode *aNode);
|
||||
static PRBool IsParagraph(nsIDOMNode *aNode);
|
||||
static PRBool IsListItem(nsIDOMNode *aNode);
|
||||
static PRBool IsTable(nsIDOMNode *aNode);
|
||||
static PRBool IsTableRow(nsIDOMNode *aNode);
|
||||
static PRBool IsTableCell(nsIDOMNode *aNode);
|
||||
static PRBool IsList(nsIDOMNode *aNode);
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include "nsIDOMSelection.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
|
@ -196,11 +196,10 @@ static PRBool IsCellNode(nsIDOMNode *aNode)
|
|||
nsAutoString tagName;
|
||||
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
||||
{
|
||||
tagName.ToLowerCase();
|
||||
// With only 3 tests, it doesn't
|
||||
// With only 2 tests, it doesn't
|
||||
// seem worth using nsAtoms
|
||||
if (tagName.Equals("td") ||
|
||||
tagName.Equals("th"))
|
||||
if (tagName.EqualsIgnoreCase("td") ||
|
||||
tagName.EqualsIgnoreCase("th"))
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ nsHTMLEditor::nsHTMLEditor()
|
|||
, mRules(nsnull)
|
||||
, mIsComposing(PR_FALSE)
|
||||
, mMaxTextLength(-1)
|
||||
, mSelectingTableCells(PR_FALSE)
|
||||
, mSelectedCellIndex(0)
|
||||
{
|
||||
// Done in nsEditor
|
||||
// NS_INIT_REFCNT();
|
||||
|
@ -2620,11 +2619,10 @@ nsHTMLEditor::GetElementOrParentByTagName(const nsString &aTagName, nsIDOMNode *
|
|||
res = selection->GetAnchorOffset(&offset);
|
||||
if(NS_FAILED(res)) return res;
|
||||
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;
|
||||
|
@ -3053,14 +3051,30 @@ nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
|||
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
||||
|
||||
// Find a selected or enclosing table element to set background on
|
||||
// TODO: Handle case of > 1 table cell or row selected
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
PRBool isSelected;
|
||||
PRInt32 selectedCount;
|
||||
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 (!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
|
||||
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -5826,7 +5840,7 @@ nsHTMLEditor::IsTableCell(nsIDOMNode *node)
|
|||
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
if (tag == "td")
|
||||
if (tag == "td" || tag == "th")
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -7844,4 +7858,3 @@ nsHTMLEditor::InsertContainerAbove(nsIDOMNode *inNode,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,15 @@ public:
|
|||
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
||||
NS_IMETHOD GetSelectedOrParentTableElement(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
|
||||
|
@ -348,6 +356,9 @@ protected:
|
|||
// Needed to do appropriate deleting when last cell or row is about to be deleted
|
||||
// This doesn't count cells that don't start in the given row (are spanning from row above)
|
||||
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
||||
// 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
|
||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||
|
@ -355,17 +366,13 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
||||
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
|
||||
// failed to set selection to some other content in the document
|
||||
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
||||
|
||||
// end of table editing utilities
|
||||
|
||||
// End of Table Editing utilities
|
||||
|
||||
|
||||
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
||||
nsString &aParentTag,
|
||||
|
@ -607,13 +614,8 @@ protected:
|
|||
PRBool mCachedUnderlineStyle;
|
||||
nsString mCachedFontName;
|
||||
|
||||
// True when selection consists of table cell(s)
|
||||
PRBool mSelectingTableCells;
|
||||
|
||||
// Used to monitor block of cells selected
|
||||
// by dragging mouse across the table
|
||||
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
|
||||
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
|
||||
// Used by GetFirstSelectedCell and GetNextSelectedCell
|
||||
PRInt32 mSelectedCellIndex;
|
||||
|
||||
public:
|
||||
static nsIAtom *gTypingTxnName;
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "nsITableCellLayout.h" // For efficient access to table cell
|
||||
#include "nsITableLayout.h" // data owned by the table and cell frames
|
||||
#include "nsHTMLEditor.h"
|
||||
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsEditorUtils.h"
|
||||
|
||||
|
@ -799,7 +801,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
|||
if (curCell)
|
||||
{
|
||||
// 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
|
||||
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
||||
|
@ -1643,13 +1645,9 @@ nsHTMLEditor::GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
|||
if (NS_FAILED(res)) return res;
|
||||
if (!aSelection) return NS_ERROR_FAILURE;
|
||||
|
||||
// Find the first selected cell
|
||||
// res = GetFirstSelectedCell(getter_AddRefs(aCell));
|
||||
if (!aCell)
|
||||
{
|
||||
//If a cell wasn't selected, then assume the selection is INSIDE
|
||||
// and use anchor node to search up to the containing cell
|
||||
// Test if selected node (from anchor node) is a cell
|
||||
// Get cell if it's the child of selection anchor node,
|
||||
// or get the enclosing by a cell
|
||||
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -1683,78 +1681,109 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell)
|
|||
if (NS_FAILED(res)) return res;
|
||||
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;
|
||||
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
if (NS_FAILED(res)) return res;
|
||||
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;
|
||||
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
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();
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1842,11 +1871,11 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt3
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount)
|
||||
{
|
||||
aTableElement = nsnull;
|
||||
aTagName = "";
|
||||
aIsSelected = PR_FALSE;
|
||||
aSelectedCount = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1858,52 +1887,218 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
|||
nsAutoString tdName("td");
|
||||
|
||||
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));
|
||||
if(NS_FAILED(res)) return res;
|
||||
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));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableElement)
|
||||
{
|
||||
aTagName = tdName;
|
||||
SET_RETURN_ELEMENT:
|
||||
}
|
||||
if (tableElement)
|
||||
{
|
||||
aTableElement = tableElement.get();
|
||||
NS_ADDREF(aTableElement);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
nsEditorShell::GetElementOrParentByTagName(const PRUnichar *aInTagName, nsIDOMNode *node, nsIDOMElement **aOutElement)
|
||||
{
|
||||
|
@ -3537,9 +3590,9 @@ nsEditorShell::GetNextRow(nsIDOMElement *aCurrentRow, nsIDOMElement **_retval)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
nsresult result = NS_NOINTERFACE;
|
||||
|
@ -3550,7 +3603,7 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
|||
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
|
||||
nsAutoString TagName(*aTagName);
|
||||
if (tableEditor)
|
||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aIsSelected);
|
||||
result = tableEditor->GetSelectedOrParentTableElement(*_retval, TagName, *aSelectedCount);
|
||||
*aTagName = TagName.ToNewUnicode();
|
||||
}
|
||||
break;
|
||||
|
@ -3560,6 +3613,28 @@ nsEditorShell::GetSelectedOrParentTableElement(PRUnichar **aTagName, PRBool *aIs
|
|||
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 */
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -60,14 +60,6 @@ interface nsIEditorShell : nsISupports
|
|||
eDisplayModeEdit,
|
||||
eDisplayModeBrowserPreview
|
||||
};
|
||||
|
||||
enum {
|
||||
eTable,
|
||||
eTableRow,
|
||||
eTableColumn,
|
||||
eTableCell,
|
||||
eTableCaption
|
||||
};
|
||||
%}
|
||||
readonly attribute boolean documentModified;
|
||||
readonly attribute boolean documentIsEmpty;
|
||||
|
@ -201,6 +193,22 @@ interface nsIEditorShell : nsISupports
|
|||
*/
|
||||
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,
|
||||
* starting the search at the supplied node.
|
||||
* An example of use is for testing if a node is in a table cell
|
||||
|
@ -368,12 +376,34 @@ interface nsIEditorShell : nsISupports
|
|||
*
|
||||
* Returns:
|
||||
* 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
|
||||
* Note that "td" will be returned if name is actually "th"
|
||||
* isSelected Tells if element returned is a selected element
|
||||
* (false if element is a parent cell of selection)
|
||||
* selectedCount How many table elements were selected
|
||||
* 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 *****/
|
||||
|
||||
|
|
|
@ -1857,7 +1857,6 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
|
|||
{
|
||||
nsCOMPtr<nsIDOMAttr> 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?
|
||||
destElement->RemoveAttribute(sourceAttrName);
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
@ -5014,19 +5013,11 @@ nsEditor::GetFirstNodeInRange(nsIDOMRange *aRange, nsIDOMNode **aNode)
|
|||
if (NS_FAILED(res)) return res;
|
||||
if (!startParent) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
PRInt32 offset;
|
||||
res = aRange->GetStartOffset(&offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
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;
|
||||
nsCOMPtr<nsIDOMNode> child = GetChildAt(startParent, offset);
|
||||
if (!child) return NS_ERROR_FAILURE;
|
||||
|
||||
*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
|
||||
nsHTMLEditUtils::IsTableRow(nsIDOMNode *node)
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
static PRBool IsHeader(nsIDOMNode *aNode);
|
||||
static PRBool IsParagraph(nsIDOMNode *aNode);
|
||||
static PRBool IsListItem(nsIDOMNode *aNode);
|
||||
static PRBool IsTable(nsIDOMNode *aNode);
|
||||
static PRBool IsTableRow(nsIDOMNode *aNode);
|
||||
static PRBool IsTableCell(nsIDOMNode *aNode);
|
||||
static PRBool IsList(nsIDOMNode *aNode);
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include "nsIDOMSelection.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
|
@ -196,11 +196,10 @@ static PRBool IsCellNode(nsIDOMNode *aNode)
|
|||
nsAutoString tagName;
|
||||
if (NS_SUCCEEDED(element->GetTagName(tagName)))
|
||||
{
|
||||
tagName.ToLowerCase();
|
||||
// With only 3 tests, it doesn't
|
||||
// With only 2 tests, it doesn't
|
||||
// seem worth using nsAtoms
|
||||
if (tagName.Equals("td") ||
|
||||
tagName.Equals("th"))
|
||||
if (tagName.EqualsIgnoreCase("td") ||
|
||||
tagName.EqualsIgnoreCase("th"))
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ nsHTMLEditor::nsHTMLEditor()
|
|||
, mRules(nsnull)
|
||||
, mIsComposing(PR_FALSE)
|
||||
, mMaxTextLength(-1)
|
||||
, mSelectingTableCells(PR_FALSE)
|
||||
, mSelectedCellIndex(0)
|
||||
{
|
||||
// Done in nsEditor
|
||||
// NS_INIT_REFCNT();
|
||||
|
@ -2620,11 +2619,10 @@ nsHTMLEditor::GetElementOrParentByTagName(const nsString &aTagName, nsIDOMNode *
|
|||
res = selection->GetAnchorOffset(&offset);
|
||||
if(NS_FAILED(res)) return res;
|
||||
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;
|
||||
|
@ -3053,14 +3051,30 @@ nsHTMLEditor::SetBackgroundColor(const nsString& aColor)
|
|||
NS_PRECONDITION(mDocWeak, "Missing Editor DOM Document");
|
||||
|
||||
// Find a selected or enclosing table element to set background on
|
||||
// TODO: Handle case of > 1 table cell or row selected
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
PRBool isSelected;
|
||||
PRInt32 selectedCount;
|
||||
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 (!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
|
||||
res = nsEditor::GetBodyElement(getter_AddRefs(element));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -5826,7 +5840,7 @@ nsHTMLEditor::IsTableCell(nsIDOMNode *node)
|
|||
NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell");
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
if (tag == "td")
|
||||
if (tag == "td" || tag == "th")
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -7844,4 +7858,3 @@ nsHTMLEditor::InsertContainerAbove(nsIDOMNode *inNode,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,15 @@ public:
|
|||
NS_IMETHOD GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||
NS_IMETHOD GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow);
|
||||
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt32 aCol, PRInt32 aDirection);
|
||||
NS_IMETHOD GetSelectedOrParentTableElement(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
|
||||
|
@ -348,6 +356,9 @@ protected:
|
|||
// Needed to do appropriate deleting when last cell or row is about to be deleted
|
||||
// This doesn't count cells that don't start in the given row (are spanning from row above)
|
||||
PRInt32 GetNumberOfCellsInRow(nsIDOMElement* aTable, PRInt32 rowIndex);
|
||||
// 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
|
||||
NS_IMETHOD GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
||||
|
@ -355,17 +366,13 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
|
||||
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
|
||||
// failed to set selection to some other content in the document
|
||||
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
|
||||
|
||||
// end of table editing utilities
|
||||
|
||||
// End of Table Editing utilities
|
||||
|
||||
|
||||
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
|
||||
nsString &aParentTag,
|
||||
|
@ -607,13 +614,8 @@ protected:
|
|||
PRBool mCachedUnderlineStyle;
|
||||
nsString mCachedFontName;
|
||||
|
||||
// True when selection consists of table cell(s)
|
||||
PRBool mSelectingTableCells;
|
||||
|
||||
// Used to monitor block of cells selected
|
||||
// by dragging mouse across the table
|
||||
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
|
||||
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
|
||||
// Used by GetFirstSelectedCell and GetNextSelectedCell
|
||||
PRInt32 mSelectedCellIndex;
|
||||
|
||||
public:
|
||||
static nsIAtom *gTypingTxnName;
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "nsITableCellLayout.h" // For efficient access to table cell
|
||||
#include "nsITableLayout.h" // data owned by the table and cell frames
|
||||
#include "nsHTMLEditor.h"
|
||||
#include "nsIFrameSelection.h" // For TABLESELECTION_ defines
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsEditorUtils.h"
|
||||
|
||||
|
@ -799,7 +801,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
|||
if (curCell)
|
||||
{
|
||||
// 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
|
||||
if (curStartColIndex < startColIndex || colSpan > 1 || colSpan == 0)
|
||||
|
@ -1643,13 +1645,9 @@ nsHTMLEditor::GetCellContext(nsCOMPtr<nsIDOMSelection> &aSelection,
|
|||
if (NS_FAILED(res)) return res;
|
||||
if (!aSelection) return NS_ERROR_FAILURE;
|
||||
|
||||
// Find the first selected cell
|
||||
// res = GetFirstSelectedCell(getter_AddRefs(aCell));
|
||||
if (!aCell)
|
||||
{
|
||||
//If a cell wasn't selected, then assume the selection is INSIDE
|
||||
// and use anchor node to search up to the containing cell
|
||||
// Test if selected node (from anchor node) is a cell
|
||||
// Get cell if it's the child of selection anchor node,
|
||||
// or get the enclosing by a cell
|
||||
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(aCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -1683,78 +1681,109 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell)
|
|||
if (NS_FAILED(res)) return res;
|
||||
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;
|
||||
res = selection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
if (NS_FAILED(res)) return res;
|
||||
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;
|
||||
res = GetFirstNodeInRange(firstRange, getter_AddRefs(cellNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
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();
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1842,11 +1871,11 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PRInt3
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRBool &aIsSelected)
|
||||
nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsString& aTagName, PRInt32 &aSelectedCount)
|
||||
{
|
||||
aTableElement = nsnull;
|
||||
aTagName = "";
|
||||
aIsSelected = PR_FALSE;
|
||||
aSelectedCount = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1858,52 +1887,218 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
|||
nsAutoString tdName("td");
|
||||
|
||||
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));
|
||||
if(NS_FAILED(res)) return res;
|
||||
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));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableElement)
|
||||
{
|
||||
aTagName = tdName;
|
||||
SET_RETURN_ELEMENT:
|
||||
}
|
||||
if (tableElement)
|
||||
{
|
||||
aTableElement = tableElement.get();
|
||||
NS_ADDREF(aTableElement);
|
||||
}
|
||||
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 aTagName The tagname of returned element
|
||||
* Note that "td" will be returned if name is actually "th"
|
||||
* @param aIsSelected Tells if element returned is a selected element
|
||||
* (false if element is a parent cell of selection)
|
||||
* @param aSelectedCount How many table elements were selected
|
||||
* 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)
|
||||
*/
|
||||
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__
|
||||
|
|
|
@ -1153,9 +1153,9 @@ function SetBackColorString(xulElementID)
|
|||
if (xulElement)
|
||||
{
|
||||
var textVal;
|
||||
var isSelectedObj = new Object();
|
||||
var selectedCountObj = new Object();
|
||||
var tagNameObj = new Object();
|
||||
var element = editorShell.GetSelectedOrParentTableElement(tagNameObj, isSelectedObj);
|
||||
var element = editorShell.GetSelectedOrParentTableElement(tagNameObj, selectedCountObj);
|
||||
|
||||
if (tagNameObj.value == "table")
|
||||
textVal = editorShell.GetString("TableBackColor");
|
||||
|
@ -1564,6 +1564,7 @@ function EditorInsertOrEditTable(insertAllowed)
|
|||
|
||||
function EditorTableCellProperties()
|
||||
{
|
||||
dump("*** EditorTableCellProperties\n");
|
||||
var cell = editorShell.GetElementOrParentByTagName("td", null);
|
||||
if (cell) {
|
||||
// Start Table Properties dialog on the "Cell" panel
|
||||
|
|
|
@ -107,6 +107,18 @@ function EditorTestSelection()
|
|||
|
||||
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);
|
||||
if (!table) {
|
||||
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/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">
|
||||
<commandset id="globalEditMenuItems"/>
|
||||
|
|
|
@ -50,6 +50,7 @@ var bgcolor = "bgcolor";
|
|||
var CellIsHeader = false;
|
||||
var rowCount = 1;
|
||||
var colCount = 1;
|
||||
var selectedCellCount = 0;
|
||||
var error = 0;
|
||||
|
||||
// dialog initialization code
|
||||
|
@ -81,7 +82,11 @@ function Startup()
|
|||
// dialog.TableLeaveLocCheck = document.getElementById("TableLeaveLocCheck");
|
||||
|
||||
// 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.CellHeightUnits = document.getElementById("CellHeightUnits");
|
||||
dialog.CellWidthInput = document.getElementById("CellWidthInput");
|
||||
|
@ -98,14 +103,28 @@ function Startup()
|
|||
// dialog.CellLeaveLocCheck = document.getElementById("CellLeaveLocCheck");
|
||||
|
||||
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)
|
||||
{
|
||||
dump("Failed to get selected element or create a new one!\n");
|
||||
window.close();
|
||||
}
|
||||
// We allow a missing cell -- see below
|
||||
|
||||
TabPanel = document.getElementById("TabPanel");
|
||||
var TableTab = document.getElementById("TableTab");
|
||||
|
@ -123,6 +142,7 @@ function Startup()
|
|||
// Activate the Cell Panel if requested
|
||||
if (currentPanel == CellPanel)
|
||||
{
|
||||
dump("*** Requested CellPanel for Table Properties dialog.\n");
|
||||
// We must have a cell element to start in this panel
|
||||
if(!CellElement)
|
||||
{
|
||||
|
@ -156,11 +176,17 @@ function Startup()
|
|||
|
||||
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;
|
||||
InitDialog();
|
||||
|
||||
// Should be dialog.TableRowsInput, or
|
||||
// SelectionSelect in cel panenl,
|
||||
// SelectionList in cel panenl,
|
||||
// but this is disabled for Beta1disabled for Beta1
|
||||
if (currentPanel == CellPanel)
|
||||
dialog.CellHeightInput.focus();
|
||||
|
@ -172,19 +198,8 @@ function Startup()
|
|||
function InitDialog()
|
||||
{
|
||||
// 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;
|
||||
colCount = editorShell.GetTableColumnCount(tableGlobatlElement);
|
||||
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.TableWidthInput.value = InitPixelOrPercentCombobox(globalTableElement, "width", "TableWidthUnits");
|
||||
dialog.BorderWidthInput.value = globalTableElement.border;
|
||||
|
@ -220,12 +235,25 @@ dump("Caption Element = "+captionElement+"\n");
|
|||
// Get cell attributes
|
||||
if (globalCellElement)
|
||||
{
|
||||
//TODO: Test if all cells in selection are in a row or column,
|
||||
// and set dialog.SelectionSelect.selectedIndex appropriately
|
||||
// Test if entire rows or columns are selected and set menu 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.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");
|
||||
|
||||
dialog.RowSpanInput.value = globalCellElement.getAttribute("rowspan");
|
||||
|
@ -584,12 +612,22 @@ function onOK()
|
|||
{
|
||||
if (ValidateData())
|
||||
{
|
||||
editorShell.BeginBatchChanges();
|
||||
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,
|
||||
// Switch cell type to TH -- involves removing TD and replacing with TD
|
||||
// Creating and moving CAPTION element
|
||||
|
||||
editorShell.EndBatchChanges();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -172,11 +172,13 @@
|
|||
<titledbox class="NoTopMargin NoTopPadding NoBottomPad" autostretch="never" valign="middle">
|
||||
<title><text align="left" value="&cellSelection.label;"/></title>
|
||||
<spring class="spacer"/>
|
||||
<html:select class="MinWidth50" id="SelectionSelect" disabled="true">
|
||||
<html:option>&cellSelectionCell.label;</html:option>
|
||||
<html:option>&cellSelectionRow.label;</html:option>
|
||||
<html:option>&cellSelectionColumn.label;</html:option>
|
||||
</html:select>
|
||||
<menulist class="MinWidth50" id="SelectionList">
|
||||
<menupopup>
|
||||
<menuitem data="1" id="SelectCellItem" value="&cellSelectionCell.label;"/>
|
||||
<menuitem data="2" id="SelectRowItem" value="&cellSelectionRow.label;"/>
|
||||
<menuitem data="3" id="SelectColumnItem" value="&cellSelectionColumn.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<spring class="bigspacer"/>
|
||||
<titledbutton class="push MinWidth50" value="&cellSelectionPrevious.label;" onclick="SelectPrevious()" disabled="true"/>
|
||||
<spring class="bigspacer"/>
|
||||
|
|
|
@ -45,8 +45,8 @@ tr {
|
|||
input {
|
||||
height: 1em;
|
||||
max-height: 1em;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче