Finished fix for 13695 (r=danm), basic table editing (bug 6256): cpp r=mjudge, related UI work r=brade

This commit is contained in:
cmanske%netscape.com 1999-12-04 01:46:23 +00:00
parent 46ed13c843
commit 6e3e75173d
11 changed files with 435 additions and 223 deletions

View File

@ -43,6 +43,87 @@
#include "nsEditorUtils.h"
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
PRBool nsHTMLEditor::IsOnlyCellInRow(nsCOMPtr<nsIDOMElement> &aCell, nsIDOMElement** aParentRow)
{
if (!aParentRow) return NS_ERROR_NULL_POINTER;
PRBool oneCellFound = PR_FALSE;
nsresult res = GetElementOrParentByTagName("tr", aCell, aParentRow);
if (NS_SUCCEEDED(res) && aParentRow)
{
PRBool done = PR_FALSE;
do {
nsCOMPtr<nsIDOMNode> resultNode;
// Scan through all nodes starting at the row we are interested in,
// and count the cells we run into.
res = GetNextNode(*aParentRow, PR_TRUE, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(res) && resultNode)
{
//Test if it's a cell and parent is = aParentRow
//Continue and count cells encountered until we leave the row
nsCOMPtr<nsIDOMElement> parent;
res = GetElementOrParentByTagName("tr", resultNode, getter_AddRefs(parent));
if(NS_SUCCEEDED(res) && parent && (parent == *aParentRow))
{
if (oneCellFound)
{
// We found more than one cell, so we're done
return PR_FALSE;
} else {
oneCellFound = PR_TRUE;
}
} else {
// We are outside of the row, so we're done
done = PR_TRUE;
}
} else {
// Should never happen!
return PR_FALSE;
}
} while(!done);
// We should always find one cell - the one we started with!
//NS_ASSERTION(oneCellFound, "Cell Not Found!");
}
return oneCellFound;
}
PRBool nsHTMLEditor::IsOnlyRowInTable(nsCOMPtr<nsIDOMElement> &aRow, nsCOMPtr<nsIDOMElement> &aTable)
{
PRBool oneRowFound = PR_FALSE;
PRBool done = PR_FALSE;
do {
nsCOMPtr<nsIDOMNode> resultNode;
// Scan through all nodes starting at the row we are interested in
nsresult res = GetNextNode(aTable, PR_TRUE, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(res))
{
//Test if it's a row and parent is same as table we are in
nsCOMPtr<nsIDOMElement> parent;
res = GetElementOrParentByTagName("table", resultNode, getter_AddRefs(parent));
if(NS_SUCCEEDED(res) && parent && (parent == aTable))
{
if (oneRowFound)
{
// We found more than one row, so we're done
return PR_FALSE;
} else {
oneRowFound = PR_TRUE;
}
} else {
// We are outside of the table, so we're done
done = PR_TRUE;
}
} else {
// Should never happen!
return PR_FALSE;
}
} while(!done);
// We should always find one row - the one we started with!
NS_ASSERTION(oneRowFound, "Row Not Found!");
return oneRowFound;
}
// Table Editing methods
@ -268,6 +349,27 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
return res;
}
// This is an internal helper (not exposed in IDL)
NS_IMETHODIMP
nsHTMLEditor::DeleteTable(nsCOMPtr<nsIDOMElement> &table, nsCOMPtr<nsIDOMSelection> &selection)
{
nsCOMPtr<nsIDOMNode> tableParent;
PRInt32 tableOffset;
if(NS_FAILED(table->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
return NS_ERROR_FAILURE;
// Save offset we need to restore the selection
if(NS_FAILED(GetChildOffset(table, tableParent, tableOffset)))
return NS_ERROR_FAILURE;
nsresult res = DeleteNode(table);
// Place selection just before the table
selection->Collapse(tableParent, tableOffset);
return res;
}
NS_IMETHODIMP
nsHTMLEditor::DeleteTable()
{
@ -281,19 +383,7 @@ nsHTMLEditor::DeleteTable()
if (NS_SUCCEEDED(res))
{
nsAutoEditBatch beginBatching(this);
// Save where we need to restore the selection
nsCOMPtr<nsIDOMNode> tableParent;
PRInt32 tableOffset;
if(NS_FAILED(table->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
return NS_ERROR_FAILURE;
if(NS_FAILED(GetChildOffset(table, tableParent, tableOffset)))
return NS_ERROR_FAILURE;
res = DeleteNode(table);
// Place selection just before the table
selection->Collapse(tableParent, tableOffset);
res = DeleteTable(table, selection);
}
return res;
}
@ -306,24 +396,43 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
nsCOMPtr<nsIDOMElement> cell;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRow, startCol;
nsresult res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRow, startCol);
if (NS_SUCCEEDED(res))
{
nsAutoEditBatch beginBatching(this);
nsresult res = NS_OK;
// We clear the selection to avoid problems when nodes in the selection are deleted,
// Be sure to set it correctly later (in SetCaretAfterTableEdit)!
selection->ClearSelection();
PRInt32 i;
for (i = 0; i < aNumber; i++)
nsAutoEditBatch beginBatching(this);
for (PRInt32 i = 0; i < aNumber; i++)
{
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRow, startCol);
if (NS_SUCCEEDED(res) && cell)
{
//TODO: FINISH ME!
if (NS_FAILED(DeleteNode(cell)))
// We clear the selection to avoid problems when nodes in the selection are deleted,
// Be sure to set it correctly later (in SetCaretAfterTableEdit)!
selection->ClearSelection();
nsCOMPtr<nsIDOMElement> parentRow;
if (IsOnlyCellInRow(cell, getter_AddRefs(parentRow)))
{
// We should delete the row instead,
// but first check if its the only row left
// so we can delete the entire table
if (IsOnlyRowInTable(parentRow, table))
return DeleteTable(table, selection);
// Delete the row
res = DeleteNode(parentRow);
} else {
res = DeleteNode(cell);
// If we fail, don't try to delete any more cells???
if (NS_FAILED(res)) break;
}
if NS_FAILED(SetCaretAfterTableEdit(table, startRow, startCol, eNoSearch))
{
break;
}
}
SetCaretAfterTableEdit(table, startRow, startCol, ePreviousColumn);
}
SetCaretAfterTableEdit(table, startRow, startCol, ePreviousColumn);
return res;
}
@ -598,12 +707,18 @@ nsHTMLEditor::SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aCol, PRInt3
nsCOMPtr<nsIDOMElement> cell;
res = GetCellAt(aTable, aCol, aRow, *getter_AddRefs(cell));
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (NS_SUCCEEDED(res) && cell)
if (NS_SUCCEEDED(res))
{
// Set the caret to just before the first child of the cell?
// TODO: Should we really be placing the caret at the END
// of the cell content?
selection->Collapse(cell, 0);
if (cell)
{
// Set the caret to just before the first child of the cell?
// TODO: Should we really be placing the caret at the END
// of the cell content?
selection->Collapse(cell, 0);
} else {
res = NS_ERROR_FAILURE;
}
}
//TODO: SEARCH FOR NEAREST CELL TO PLACE CARET INTO
return res;

View File

@ -2820,28 +2820,6 @@ nsEditorShell::SetSelectionAfterElement(nsIDOMElement* aElement)
}
/* Table Editing */
NS_IMETHODIMP
nsEditorShell::InsertTableCell(PRInt32 aNumber, PRBool bAfter)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->InsertTableCell(aNumber, bAfter);
}
break;
case ePlainTextEditorType:
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::InsertTableRow(PRInt32 aNumber, PRBool bAfter)
{
@ -2882,6 +2860,27 @@ nsEditorShell::InsertTableColumn(PRInt32 aNumber, PRBool bAfter)
return result;
}
NS_IMETHODIMP
nsEditorShell::InsertTableCell(PRInt32 aNumber, PRBool bAfter)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->InsertTableCell(aNumber, bAfter);
}
break;
case ePlainTextEditorType:
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::DeleteTable()
{

View File

@ -260,8 +260,9 @@ protected:
// Return TRUE if aElement is a table-related elemet and caret was set
PRBool SetCaretInTableCell(nsIDOMElement* aElement);
PRBool IsElementInBody(nsIDOMElement* aElement);
PRBool SetCaretInTableCell(nsIDOMElement* aElement);
PRBool IsElementInBody(nsIDOMElement* aElement);
// key event helpers
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
@ -270,12 +271,16 @@ protected:
// Table Editing (implemented in EditTable.cpp)
// Table utilities
NS_IMETHOD DeleteTable(nsCOMPtr<nsIDOMElement> &table, nsCOMPtr<nsIDOMSelection> &selection);
// Helper used to get nsITableLayout interface for methods implemented in nsTableFrame
NS_IMETHOD GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject);
// Table utilities
// Helpers to do appropriate deleting when last cell or row is about to be deleted
PRBool IsOnlyCellInRow(nsCOMPtr<nsIDOMElement> &aCell, nsIDOMElement** aParentRow);
PRBool IsOnlyRowInTable(nsCOMPtr<nsIDOMElement> &aRow, nsCOMPtr<nsIDOMElement> &aTable);
// All of the above 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,
nsCOMPtr<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMElement> &aCell,
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
@ -284,9 +289,10 @@ protected:
// Use the selection iterator to find the first cell in the selection
NS_IMETHOD GetFirstSelectedCell(nsCOMPtr<nsIDOMElement> &aCell);
// Setting caret to a logical place can get tricky,
// especially after deleting table stuff
typedef enum { ePreviousColumn, ePreviousRow } SetCaretSearchDirection;
typedef enum { eNoSearch, ePreviousColumn, ePreviousRow } SetCaretSearchDirection;
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aCol, PRInt32 aRow, SetCaretSearchDirection aDirection);

View File

@ -2820,28 +2820,6 @@ nsEditorShell::SetSelectionAfterElement(nsIDOMElement* aElement)
}
/* Table Editing */
NS_IMETHODIMP
nsEditorShell::InsertTableCell(PRInt32 aNumber, PRBool bAfter)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->InsertTableCell(aNumber, bAfter);
}
break;
case ePlainTextEditorType:
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::InsertTableRow(PRInt32 aNumber, PRBool bAfter)
{
@ -2882,6 +2860,27 @@ nsEditorShell::InsertTableColumn(PRInt32 aNumber, PRBool bAfter)
return result;
}
NS_IMETHODIMP
nsEditorShell::InsertTableCell(PRInt32 aNumber, PRBool bAfter)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->InsertTableCell(aNumber, bAfter);
}
break;
case ePlainTextEditorType:
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::DeleteTable()
{

View File

@ -60,6 +60,14 @@ interface nsIEditorShell : nsISupports
eDisplayModeEdit,
eDisplayModeBrowserPreview
};
enum {
eTable,
eTableRow,
eTableColumn,
eTableCell,
eTableCaption
};
%}
readonly attribute boolean documentModified;
readonly attribute boolean documentIsEmpty;
@ -274,7 +282,7 @@ interface nsIEditorShell : nsISupports
void SelectElement(in nsIDOMElement element);
void SetSelectionAfterElement(in nsIDOMElement element);
/** Table insert and delete methods. Done relative to selected cell or
* cell containing the selection anchor.
*/

View File

@ -260,8 +260,9 @@ protected:
// Return TRUE if aElement is a table-related elemet and caret was set
PRBool SetCaretInTableCell(nsIDOMElement* aElement);
PRBool IsElementInBody(nsIDOMElement* aElement);
PRBool SetCaretInTableCell(nsIDOMElement* aElement);
PRBool IsElementInBody(nsIDOMElement* aElement);
// key event helpers
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
@ -270,12 +271,16 @@ protected:
// Table Editing (implemented in EditTable.cpp)
// Table utilities
NS_IMETHOD DeleteTable(nsCOMPtr<nsIDOMElement> &table, nsCOMPtr<nsIDOMSelection> &selection);
// Helper used to get nsITableLayout interface for methods implemented in nsTableFrame
NS_IMETHOD GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject);
// Table utilities
// Helpers to do appropriate deleting when last cell or row is about to be deleted
PRBool IsOnlyCellInRow(nsCOMPtr<nsIDOMElement> &aCell, nsIDOMElement** aParentRow);
PRBool IsOnlyRowInTable(nsCOMPtr<nsIDOMElement> &aRow, nsCOMPtr<nsIDOMElement> &aTable);
// All of the above 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,
nsCOMPtr<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMElement> &aCell,
nsCOMPtr<nsIDOMNode> &aCellParent, PRInt32& aCellOffset,
@ -284,9 +289,10 @@ protected:
// Use the selection iterator to find the first cell in the selection
NS_IMETHOD GetFirstSelectedCell(nsCOMPtr<nsIDOMElement> &aCell);
// Setting caret to a logical place can get tricky,
// especially after deleting table stuff
typedef enum { ePreviousColumn, ePreviousRow } SetCaretSearchDirection;
typedef enum { eNoSearch, ePreviousColumn, ePreviousRow } SetCaretSearchDirection;
NS_IMETHOD SetCaretAfterTableEdit(nsIDOMElement* aTable, PRInt32 aCol, PRInt32 aRow, SetCaretSearchDirection aDirection);

View File

@ -369,12 +369,6 @@ function EditorNewPlaintext()
"chrome://editor/content/EditorInitPagePlain.html");
}
// returns wasSavedSuccessfully
function EditorCheckAndSaveDocument(reasonToSaveString)
{
}
// returns wasSavedSuccessfully
function EditorSaveDocument(doSaveAs, doSaveCopy)
{
@ -411,6 +405,14 @@ function EditorClose()
//window.close();
}
// Check for changes to document and allow saving before closing
// This is hooked up to the OS's window close widget (e.g., "X" for Windows)
function EditorCanClose()
{
// Returns FALSE only if user cancels save action
return editorShell.CheckAndSaveDocument(editorShell.GetString("BeforeClosing"));
}
// --------------------------- Edit menu ---------------------------
function EditorUndo()
@ -745,6 +747,44 @@ function EditorRemoveLinks()
contentWindow.focus();
}
/*TODO: We need an oncreate hook to do enabling/disabling for the
Format menu. There should be code like this for the
object-specific "Properties..." item
*/
function EditorObjectProperties()
{
var element = editorShell.GetSelectedElement("");
dump("EditorObjectProperties: element="+element+"\n");
if (element)
{
dump("TagName="+element.nodeName+"\n");
switch (element.nodeName)
{
case 'IMG':
EditorInsertOrEditImage();
break;
case 'HR':
EditorInsertOrEditHLine();
break;
case 'TABLE':
EditorInsertOrEditTable(false);
break;
case 'A':
if(element.href)
EditorInsertOrEditLink();
else if (element.name)
EditorInsertOrEditNamedAnchor();
break;
}
} else {
// We get a partially-selected link if asked for specifically
element = editorShell.GetSelectedElement("href");
if (element)
EditorInsertOrEditLink();
}
}
function EditorListProperties()
{
window.openDialog("chrome://editor/content/EdListProps.xul","_blank", "chrome,close,titlebar,modal");
@ -827,19 +867,19 @@ function EditorInsertHTML()
contentWindow.focus();
}
function EditorInsertLink()
function EditorInsertOrEditLink()
{
window.openDialog("chrome://editor/content/EdLinkProps.xul","_blank", "chrome,close,titlebar,modal");
contentWindow.focus();
}
function EditorInsertImage()
function EditorInsertOrEditImage()
{
window.openDialog("chrome://editor/content/EdImageProps.xul","_blank", "chrome,close,titlebar,modal");
contentWindow.focus();
}
function EditorInsertHLine()
function EditorInsertOrEditHLine()
{
// Inserting an HLine is different in that we don't use properties dialog
// unless we are editing an existing line's attributes
@ -918,7 +958,7 @@ function EditorInsertHLine()
contentWindow.focus();
}
function EditorInsertNamedAnchor()
function EditorInsertOrEditNamedAnchor()
{
window.openDialog("chrome://editor/content/EdNamedAnchorProps.xul", "_blank", "chrome,close,titlebar,modal", "");
contentWindow.focus();
@ -947,6 +987,30 @@ function EditorInsertOrEditTable(insertAllowed)
}
}
function EditorSelectTable()
{
//TODO: FINISH THIS!
contentWindow.focus();
}
function EditorSelectTableRow()
{
//TODO: FINISH THIS!
contentWindow.focus();
}
function EditorSelectTableColumn()
{
//TODO: FINISH THIS!
contentWindow.focus();
}
function EditorSelectTableCell()
{
//TODO: FINISH THIS!
contentWindow.focus();
}
function EditorInsertTable()
{
// Insert a new table
@ -986,20 +1050,23 @@ function EditorDeleteTable()
function EditorDeleteTableRow()
{
editorShell.DeleteTableRow();
// TODO: Get the number of rows to delete from the selection
editorShell.DeleteTableRow(1);
contentWindow.focus();
}
function EditorDeleteTableColumn()
{
editorShell.DeleteTableColumn();
// TODO: Get the number of cols to delete from the selection
editorShell.DeleteTableColumn(1);
contentWindow.focus();
}
function EditorDeleteTableCell()
{
editorShell.DeleteTableCell();
// TODO: Get the number of cells to delete from the selection
editorShell.DeleteTableCell(1);
contentWindow.focus();
}

View File

@ -38,6 +38,7 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="EditorOnLoad()"
onunload="EditorShutdown()"
onclose="return EditorCanClose()"
titlemodifier="&editorWindow.titlemodifier;"
titlemenuseparator="&editorWindow.titlemodifiermenuseparator;"
windowtype="composer:html"
@ -91,44 +92,15 @@
<menu id="insertMenu"/>
<menu value="&formatMenu.label;" accesskey="&formatmenu.accesskey;">
<menupopup>
<menu id="fontFaceMenu"/>
<menu id="fontSizeMenu"/>
<menu id="fontStyleMenu"/>
<menu id="fontColorMenu"/>
<menu id="backgroundColorMenu"/>
<menuitem id="removeAllStylesMenuitem"/>
<menuitem id="removeLinksMenuitem"/>
<menuseparator />
<menu id="headingMenu"/>
<menu id="paragraphMenu"/>
<menuitem id="listProps"/>
<menuseparator />
<menu id="stylesheetMenu"/>
<menu id="alignMenu"/>
<menuseparator />
<menuitem id="increaseIndent"/>
<menuitem id="decreaseIndent"/>
<menuseparator />
<!-- PROPERTY ITEMS HERE -->
<menuitem id="pageProperties"/>
<menuitem id="colorsAndBackground"/>
</menupopup>
</menu>
<menu value="&tableMenu.label;" accesskey="&tablemenu.accesskey;">
<menupopup>
<menu id="tableInsertMenu"/>
<menu id="tableDeleteMenu"/>
<menuseparator />
<menuitem id="tableJoinCellsMenuitem"/>
<menuitem id="tablePropertiesMenuitem"/>
<menu id="formatMenu" value="&formatMenu.label;" accesskey="&formatmenu.accesskey;">
<menupopup id="formatMenuPopup">
<!-- Property items that are only in web composer -->
<menuitem id="pageProperties"/>
</menupopup>
</menu>
<menu id="tableMenu"/>
<!-- tasks menu filled from tasksOverlay -->
<menu id="tasksMenu" accesskey="t"/>

View File

@ -160,10 +160,10 @@
<broadcaster id="Editor:ToggleCompositionToolbar" value="&hideCompositionToolbarCmd.label;" showing="true" oncommand="_EditorNotImplemented()"/>
<broadcaster id="Editor:ToggleFormattingToolbar" value="&hideFormattingToolbarCmd.label;" showing="true" oncommand="_EditorNotImplemented()"/>
<broadcaster id="Editor:InsertLink" value="&insertLinkCmd.label;" oncommand="EditorInsertLink()"/>
<broadcaster id="Editor:InsertAnchor" value="&insertAnchorCmd.label;" oncommand="EditorInsertNamedAnchor()"/>
<broadcaster id="Editor:InsertImage" value="&insertImageCmd.label;" oncommand="EditorInsertImage()"/>
<broadcaster id="Editor:InsertHLine" value="&insertHLineCmd.label;" oncommand="EditorInsertHLine()"/>
<broadcaster id="Editor:InsertLink" value="&insertLinkCmd.label;" oncommand="EditorInsertOrEditLink()"/>
<broadcaster id="Editor:InsertAnchor" value="&insertAnchorCmd.label;" oncommand="EditorInsertOrEditNamedAnchor()"/>
<broadcaster id="Editor:InsertImage" value="&insertImageCmd.label;" oncommand="EditorInsertOrEditImage()"/>
<broadcaster id="Editor:InsertHLine" value="&insertHLineCmd.label;" oncommand="EditorInsertOrEditHLine()"/>
<broadcaster id="Editor:InsertTable" value="&insertTableCmd.label;" oncommand="EditorInsertTable()"/>
<broadcaster id="Editor:InsertHTML" value="&insertHTMLSourceCmd.label;" oncommand="EditorInsertHTML()"/>
<broadcaster id="Editor:InsertBreak" value="&insertLineBreakCmd.label;" oncommand="_EditorNotImplemented()"/>
@ -330,29 +330,35 @@
<menuitem accesskey="&insertbreak.accesskey;" observes="Editor:InsertBreakAll"/>
</menupopup>
</menu>
<!-- random format menu items -->
<menuitem id="removeAllStylesMenuitem" value="&removeAllStylesCmd.label;"
accesskey="&formatremovestyles.accesskey;" key="removestyleskb"
oncommand="EditorRemoveStyle('all')"/>
<menuitem id="removeLinksMenuitem" value="&removeLinksCmd.label;"
accesskey="&formatremovelinks.accesskey;"
oncommand="EditorRemoveLinks()"/>
<!-- Format Menu -->
<menupopup id="formatMenuPopup">
<!-- Font face submenu -->
<menu id="fontFaceMenu" value="&fontfaceMenu.label;" accesskey="&formatfontmenu.accesskey;">
<menu id="fontFaceMenu" value="&fontfaceMenu.label;"
accesskey="&formatfontmenu.accesskey;" position="1">
<menupopup>
<menuitem value="&defaultVariableWidthCmd.label;" accesskey="&fontvarwidth.accesskey;" oncommand="EditorSetFontFace('')"/>
<menuitem value="&defaultFixedWidthCmd.label;" oncommand="EditorSetFontFace('tt')"/>
<menuitem value="&defaultVariableWidthCmd.label;"
accesskey="&fontvarwidth.accesskey;"
oncommand="EditorSetFontFace('')"/>
<menuitem value="&defaultFixedWidthCmd.label;"
oncommand="EditorSetFontFace('tt')"/>
<menuseparator/>
<menuitem value="&arialHelveticaFont.label;" accesskey="&fonthelvetica.accesskey;" oncommand="EditorSetFontFace('Arial, Helvetica, sans-serif')"/>
<menuitem value="&timesFont.label;" accesskey="&fonttimes.accesskey;" oncommand="EditorSetFontFace('Times New Roman, Times, serif')"/>
<menuitem value="&courierFont.label;" accesskey="&fontcourier.accesskey;" oncommand="EditorSetFontFace('Courier New, Courier, mono')"/>
<menuitem value="&arialHelveticaFont.label;"
accesskey="&fonthelvetica.accesskey;"
oncommand="EditorSetFontFace('Arial, Helvetica, sans-serif')"/>
<menuitem value="&timesFont.label;"
accesskey="&fonttimes.accesskey;"
oncommand="EditorSetFontFace('Times New Roman, Times, serif')"/>
<menuitem value="&courierFont.label;"
accesskey="&fontcourier.accesskey;"
oncommand="EditorSetFontFace('Courier New, Courier, mono')"/>
</menupopup>
</menu>
<!-- Font size submenu -->
<menu id="fontSizeMenu" value="&fontsizeMenu.label;" accesskey="&formatsizemenu.accesskey;">
<menu id="fontSizeMenu" value="&fontsizeMenu.label;"
accesskey="&formatsizemenu.accesskey;"
position="2">
<menupopup>
<menuitem value="&size-2Cmd.label;" accesskey="&size-2.accesskey;" oncommand="EditorSetFontSize('-2')"/>
<menuitem value="&size-1Cmd.label;" accesskey="&size-1.accesskey;" oncommand="EditorSetFontSize('-1')"/>
@ -365,7 +371,9 @@
</menu>
<!-- Font style submenu -->
<menu id="fontStyleMenu" value="&fontStyleMenu.label;" accesskey="&formatstylemenu.accesskey;">
<menu id="fontStyleMenu" value="&fontStyleMenu.label;"
accesskey="&formatstylemenu.accesskey;"
position="3">
<menupopup>
<menuitem value="&styleBoldCmd.label;" accesskey="&stylebold.accesskey;" key="boldkb" observes="Editor:Bold"/>
<menuitem value="&styleItalicCmd.label;" accesskey="&styleitalic.accesskey;" key="italickb" observes="Editor:Italic"/>
@ -377,9 +385,12 @@
<menuitem value="&styleNonbreakingCmd.label;" accesskey="&stylenonbreaking.accesskey;" oncommand="EditorApplyStyle('nobr')"/>
</menupopup>
</menu>
<!-- Font color submenu -->
<menu id="fontColorMenu" value="&fontColorMenu.label;" accesskey="&formatcolormenu.accesskey;">
<!-- TODO: REPLACE WITH COLORPICKER -->
<!-- Font color submenu -->
<menu id="fontColorMenu" value="&fontColorMenu.label;"
accesskey="&formatcolormenu.accesskey;"
position="4">
<menupopup>
<menuitem value="&colorBlackCmd.label;" accesskey="&colorblack.accesskey;" oncommand="EditorSetFontColor('black')"/>
<menuitem value="&colorGrayCmd.label;" accesskey="&colorgray.accesskey;" oncommand="EditorSetFontColor('gray')"/>
@ -393,9 +404,10 @@
<menuitem value="&colorMagentaCmd.label;" accesskey="&colormagenta.accesskey;" oncommand="EditorSetFontColor('magenta')"/>
</menupopup>
</menu>
<!-- Background color submenu -->
<menu id="backgroundColorMenu" value="&backgroundColorMenu.label;" accesskey="&formatbkgdcolormenu.accesskey;">
<!-- Background color submenu -->
<menu id="backgroundColorMenu" value="&backgroundColorMenu.label;"
accesskey="&formatbkgdcolormenu.accesskey;"
position="5">
<menupopup>
<menuitem value="&colorBlackCmd.label;" accesskey="&colorblack.accesskey;" oncommand="EditorSetBackgroundColor('black')"/>
<menuitem value="&colorGrayCmd.label;" accesskey="&colorgray.accesskey;" oncommand="EditorSetBackgroundColor('gray')"/>
@ -410,8 +422,18 @@
</menupopup>
</menu>
<menuitem id="removeAllStylesMenuitem" value="&removeAllStylesCmd.label;"
accesskey="&formatremovestyles.accesskey;" key="removestyleskb"
oncommand="EditorRemoveStyle('all')" position="6"/>
<menuitem id="removeLinksMenuitem" value="&removeLinksCmd.label;"
accesskey="&formatremovelinks.accesskey;"
oncommand="EditorRemoveLinks()" position="7"/>
<menuseparator position="8"/>
<!-- Heading submenu -->
<menu id="headingMenu" value="&headingMenu.label;" accesskey="&formatheadingmenu.accesskey;">
<menu id="headingMenu" value="&headingMenu.label;"
accesskey="&formatheadingmenu.accesskey;"
position="9">
<menupopup>
<menuitem value="&headingNormalCmd.label;" accesskey="&headingnone.accesskey;" oncommand="EditorSetParagraphFormat('normal')"/>
<menuitem value="&heading1Cmd.label;" accesskey="&heading1.accesskey;" oncommand="EditorSetParagraphFormat('h1')"/>
@ -424,7 +446,9 @@
</menu>
<!-- Paragraph Style submenu -->
<menu id="paragraphMenu" value="&paragraphMenu.label;" accesskey="&formatparagraphmenu.accesskey;">
<menu id="paragraphMenu" value="&paragraphMenu.label;"
accesskey="&formatparagraphmenu.accesskey;"
position="10">
<menupopup>
<menuitem value="&paragraphNormalCmd.label;" accesskey="&paragraphnormal.accesskey;" oncommand="EditorSetParagraphFormat('normal')"/>
<menuitem value="&paragraphParagraphCmd.label;" accesskey="&paragraphparagraph.accesskey;" oncommand="EditorSetParagraphFormat('p')"/>
@ -437,10 +461,16 @@
</menu>
<!-- List Style (opens dialog) -->
<menuitem id="listProps" value="&listProps.label;" accesskey="&formatlistmenu.accesskey;" oncommand="EditorListProperties()"/>
<menuitem id="listProps" value="&listProps.label;"
accesskey="&formatlistmenu.accesskey;"
oncommand="EditorListProperties()"
position="11"/>
<menuseparator position="12"/>
<!-- Stylesheet submenu -->
<menu id="stylesheetMenu" value="&stylesheetMenu.label;" accesskey="&formatstylesheetmenu.accesskey;">
<menu id="stylesheetMenu" value="&stylesheetMenu.label;"
accesskey="&formatstylesheetmenu.accesskey;"
position="13">
<menupopup>
<menuitem value="&stylesheetEditorOneCmd.label;" accesskey="&sseditor1.accesskey;" oncommand="EditorApplyStyleSheet('chrome://editor/content/EditorStyles1.css')"/>
<menuseparator />
@ -454,7 +484,9 @@
</menu>
<!-- Align submenu -->
<menu id="alignMenu" value="&alignMenu.label;" accesskey="&formatalignmenu.accesskey;">
<menu id="alignMenu" value="&alignMenu.label;"
accesskey="&formatalignmenu.accesskey;"
position="14">
<menupopup>
<menuitem value="&alignLeft.label;" accesskey="&alignleft.accesskey;" oncommand="EditorAlign('left')"/>
<menuitem value="&alignCenter.label;" accesskey="&aligncenter.accesskey;" oncommand="EditorAlign('center')"/>
@ -462,18 +494,45 @@
<menuitem value="&alignJustify.label;" accesskey="&alignjustify.accesskey;" oncommand="EditorAlign('justify')"/>
</menupopup>
</menu>
<menuseparator position="15"/>
<menuitem id="increaseIndent" value="&increaseIndent.label;" accesskey="&increaseindent.accesskey;" key="increaseindentkb" oncommand="EditorIndent('indent')"/>
<menuitem id="decreaseIndent" value="&decreaseIndent.label;" accesskey="&decreaseindent.accesskey;" key="decreaseindentkb" oncommand="EditorIndent('outdent')"/>
<menuitem id="increaseIndent" value="&increaseIndent.label;"
accesskey="&increaseindent.accesskey;"
key="increaseindentkb"
oncommand="EditorIndent('indent')"
position="16"/>
<menuitem id="decreaseIndent" value="&decreaseIndent.label;"
accesskey="&decreaseindent.accesskey;"
key="decreaseindentkb"
oncommand="EditorIndent('outdent')"
position="17"/>
<menuseparator position="18"/>
<menuitem id="objectProperties" value="&properties.label;"
accesskey="&properties.accesskey;"
oncommand="EditorObjectProperties()"
position="19"/>
<menuitem id="colorsAndBackground" value="&colorsAndBackground.label;"
accesskey="&colorsandbackground.accesskey;"
oncommand="EditorPageProperties('1')"
position="20"/>
<!-- Merge page property items here -->
</menupopup>
<menuitem id="pageProperties" value="&pageProperties.label;" accesskey="&pageproperties.accesskey;" oncommand="EditorPageProperties('0')"/>
<menuitem id="colorsAndBackground" value="&colorsAndBackground.label;" accesskey="&colorsandbackground.accesskey;" oncommand="EditorPageProperties('1')"/>
<menuitem id="pageProperties" value="&pageProperties.label;"
accesskey="&pageproperties.accesskey;"
oncommand="EditorPageProperties('0')"/>
<!-- Random table menu items -->
<menuitem id="tableJoinCellsMenuitem" value="&tableJoinCells.label;" accesskey="&tablejoin.accesskey;" oncommand="EditorJoinTableCells()"/>
<menuitem id="tablePropertiesMenuitem" value="&properties.label;" accesskey="&properties.accesskey;" oncommand="EditorInsertOrEditTable(false)"/>
<!-- Table insert submenu TODO: Should we use "above", "below"; "before", "after" versions for rows and cols? -->
<menu id="tableMenu" value="&tableMenu.label;" accesskey="&tablemenu.accesskey;">
<menupopup>
<menu id="tableSelectMenu" value="&tableSelectMenu.label;"
accesskey="&tableselectmenu.accesskey;">
<menupopup>
<menuitem value="&tableTable.label;" accesskey="&tabletable.accesskey;" oncommand="EditorSelectTable()"/>
<menuitem value="&tableRow.label;" accesskey="&tablerow.accesskey;" oncommand="EditorSelectTableRow()"/>
<menuitem value="&tableColumn.label;" accesskey="&tablecolumn.accesskey;" oncommand="EditorSelectTableColumn()"/>
<menuitem value="&tableCell.label;" accesskey="&tablecell.accesskey;" oncommand="EditorSelectTableCell()"/>
</menupopup>
</menu>
<menu id="tableInsertMenu" value="&tableInsertMenu.label;" accesskey="&tableinsertmenu.accesskey;">
<menupopup>
<menuitem value="&tableTable.label;" accesskey="&tabletable.accesskey;" oncommand="EditorInsertTable()"/>
@ -488,50 +547,26 @@
<menuitem value="&tableCellAfter.label;" accesskey="&tablecellafter.accesskey;" oncommand="EditorInsertTableCell(true)"/>
</menupopup>
</menu>
<!-- Table delete submenu -->
<menu id="tableDeleteMenu" value="&tableDeleteMenu.label;" accesskey="&tabledeletemenu.accesskey;">
<menupopup>
<menuitem value="&tableTable.label;" accesskey="&tabletable.accesskey;" oncommand="EditorDeleteTable()"/>
<menuitem value="&tableRow.label;" accesskey="&tablerow.accesskey;" oncommand="EditorDeleteTableRow()"/>
<menuitem value="&tableColumn.label;" accesskey="&tablecolumn.accesskey;" oncommand="EditorDeleteTableColumn()"/>
<menuitem value="&tableCell.label;" accesskey="&tablecell.accesskey;" oncommand="EditorDeleteTableCell()"/>
<menuitem value="&tableRow.label;" accesskey="&tablerow.accesskey;" oncommand="EditorDeleteTableRow(1)"/>
<menuitem value="&tableColumn.label;" accesskey="&tablecolumn.accesskey;" oncommand="EditorDeleteTableColumn(1)"/>
<menuitem value="&tableCell.label;" accesskey="&tablecell.accesskey;" oncommand="EditorDeleteTableCell(1)"/>
</menupopup>
</menu>
<!-- Toolbar popups -->
<!-- TODO: REPLACE WITH COLOR WIDGET -->
<menupopup id="BackColorPopup">
<menuitem value="&colorBlackCmd.label;" oncommand="EditorSetBackgroundColor('black')"/>
<menuitem value="&colorGrayCmd.label;" oncommand="EditorSetBackgroundColor('gray')"/>
<menuitem value="&colorSilverCmd.label;" oncommand="EditorSetBackgroundColor('silver')"/>
<menuitem value="&colorWhiteCmd.label;" oncommand="EditorSetBackgroundColor('white')"/>
<menuitem value="&colorRedCmd.label;" oncommand="EditorSetBackgroundColor('red')"/>
<menuitem value="&colorBlueCmd.label;" oncommand="EditorSetBackgroundColor('blue')"/>
<menuitem value="&colorGreenCmd.label;" oncommand="EditorSetBackgroundColor('green')"/>
<menuitem value="&colorCyanCmd.label;" oncommand="EditorSetBackgroundColor('cyan')"/>
<menuitem value="&colorYellowCmd.label;" oncommand="EditorSetBackgroundColor('yellow')"/>
<menuitem value="&colorMagentaCmd.label;" oncommand="EditorSetBackgroundColor('magenta')"/>
</menupopup>
<menupopup id="TextColorPopup">
<menuitem value="&colorBlackCmd.label;" oncommand="EditorSetFontColor('black')"/>
<menuitem value="&colorGrayCmd.label;" oncommand="EditorSetFontColor('gray')"/>
<menuitem value="&colorSilverCmd.label;" oncommand="EditorSetFontColor('silver')"/>
<menuitem value="&colorWhiteCmd.label;" oncommand="EditorSetFontColor('white')"/>
<menuitem value="&colorRedCmd.label;" oncommand="EditorSetFontColor('red')"/>
<menuitem value="&colorBlueCmd.label;" oncommand="EditorSetFontColor('blue')"/>
<menuitem value="&colorGreenCmd.label;" oncommand="EditorSetFontColor('green')"/>
<menuitem value="&colorCyanCmd.label;" oncommand="EditorSetFontColor('cyan')"/>
<menuitem value="&colorYellowCmd.label;" oncommand="EditorSetFontColor('yellow')"/>
<menuitem value="&colorMagentaCmd.label;" oncommand="EditorSetFontColor('magenta')"/>
</menupopup>
<menuseparator />
<menuitem id="tableJoinCellsMenuitem" value="&tableJoinCells.label;" accesskey="&tablejoin.accesskey;" oncommand="EditorJoinTableCells()"/>
<menuitem id="tablePropertiesMenuitem" value="&properties.label;" accesskey="&properties.accesskey;" oncommand="EditorInsertOrEditTable(false)"/>
</menupopup>
</menu>
<popup id="TextColorPicker">
<html:div id="TextColorCaption" class="color-caption" align="center">&textColorCaption.label;</html:div>
<!-- TODO: Add "Last color picked" button and text -->
<colorpicker palettename="standard" onclick="EditorSelectTextColor(); window.close()"/>
</popup>
<popup id="BackColorPicker">
<!-- Text Caption is filled in at runtime -->
<!-- TODO: Add "Last color picked" button and text -->
@ -556,16 +591,16 @@
<!-- InsertPopup is used by messengercompose.xul -->
<menupopup id="InsertPopup">
<menuitem oncommand="EditorInsertLink()">
<menuitem oncommand="EditorInsertOrEditLink()">
<titledbutton id="linkButton-dark" darkcolor="true" align="left" value="&linkToolbarCmd.label;"/>
</menuitem>
<menuitem oncommand="EditorInsertNamedAnchor()">
<menuitem oncommand="EditorInsertOrEditNamedAnchor()">
<titledbutton id="namedAnchorButton-dark" align="left" value="&anchorToolbarCmd.label;"/>
</menuitem>
<menuitem oncommand="EditorInsertImage()">
<menuitem oncommand="EditorInsertOrEditImage()">
<titledbutton id="imageButton-dark" align="left" value="&imageToolbarCmd.label;"/>
</menuitem>
<menuitem oncommand="EditorInsertHLine()">
<menuitem oncommand="EditorInsertOrEditHLine()">
<titledbutton id="hlineButton-dark" align="left" value="&hruleToolbarCmd.label;"/>
</menuitem>
<menuitem oncommand="EditorInsertOrEditTable(true)">
@ -582,11 +617,11 @@
<titledbutton id="findButton" class="other28" observes="Editor:Find"/>
<titledbutton id="spellingButton" class="other28" value="&spellToolbarCmd.label;" onclick="CheckSpelling()"/>
<titledbutton id="imageButton" class="other28" value="&imageToolbarCmd.label;" onclick="EditorInsertImage()"/>
<titledbutton id="hlineButton" class="other28" value="&hruleToolbarCmd.label;" onclick="EditorInsertHLine()"/>
<titledbutton id="imageButton" class="other28" value="&imageToolbarCmd.label;" onclick="EditorInsertOrEditImage()"/>
<titledbutton id="hlineButton" class="other28" value="&hruleToolbarCmd.label;" onclick="EditorInsertOrEditHLine()"/>
<titledbutton id="tableButton" class="other28" value="&tableToolbarCmd.label;" onclick="EditorInsertOrEditTable(true)"/>
<titledbutton id="linkButton" class="other28" value="&linkToolbarCmd.label;" onclick="EditorInsertLink()"/>
<titledbutton id="namedAnchorButton" class="other28" value="&anchorToolbarCmd.label;" onclick="EditorInsertNamedAnchor()"/>
<titledbutton id="linkButton" class="other28" value="&linkToolbarCmd.label;" onclick="EditorInsertOrEditLink()"/>
<titledbutton id="namedAnchorButton" class="other28" value="&anchorToolbarCmd.label;" onclick="EditorInsertOrEditNamedAnchor()"/>
<!-- Formatting toolbar items -->
<html:select class="toolbar" id="ParagraphSelect" size="1" onchange="EditorSelectParagraphFormat()">

View File

@ -36,10 +36,6 @@
<!ENTITY formatMenu.label "Format">
<!ENTITY formatmenu.accesskey "o">
<!-- Table menu items -->
<!ENTITY tableMenu.label "Table">
<!ENTITY tablemenu.accesskey "t">
<!ENTITY helpMenu.label "Help">
<!ENTITY aboutCmd.label ".About">

View File

@ -235,6 +235,9 @@
<!ENTITY insertbreak.accesskey "b">
<!-- Format Menu -->
<!ENTITY formatMenu.label "Format">
<!ENTITY formatmenu.accesskey "o">
<!-- Font Face SubMenu -->
<!ENTITY fontfaceMenu.label "Font Face">
<!ENTITY formatfontmenu.accesskey "f">
@ -406,6 +409,12 @@
<!ENTITY colorsandbackground.accesskey "k">
<!-- Table Menu -->
<!ENTITY tableMenu.label "Table">
<!ENTITY tablemenu.accesskey "t">
<!-- Select submenu -->
<!ENTITY tableSelectMenu.label "Select">
<!ENTITY tableselectmenu.accesskey "s">
<!-- Insert SubMenu -->
<!ENTITY tableInsertMenu.label "Insert">
<!ENTITY tableinsertmenu.accesskey "i">
@ -437,7 +446,7 @@
<!ENTITY tablejoin.accesskey "j">
<!-- These may be shared in other menus -->
<!ENTITY properties.label "Properties...">
<!ENTITY properties.accesskey "p">
<!ENTITY properties.accesskey "o">
<!-- Tools Menu -->
<!ENTITY toolsmenu.accesskey "l">