Allow Composer's users to remove named anchors w/o having to use Source View; b=80742; r=brade, r=jfrancis, sr=kin, a=asa
git-svn-id: svn://10.0.0.236/trunk@118746 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -86,6 +86,7 @@ public:
|
||||
static nsIAtom *font;
|
||||
static nsIAtom *a;
|
||||
static nsIAtom *href;
|
||||
static nsIAtom *name;
|
||||
static nsIAtom *img;
|
||||
static nsIAtom *object;
|
||||
static nsIAtom *br;
|
||||
|
||||
@@ -73,6 +73,7 @@ nsIAtom * nsIEditProperty::acronym;
|
||||
nsIAtom * nsIEditProperty::font;
|
||||
nsIAtom * nsIEditProperty::a;
|
||||
nsIAtom * nsIEditProperty::href;
|
||||
nsIAtom * nsIEditProperty::name;
|
||||
nsIAtom * nsIEditProperty::img;
|
||||
nsIAtom * nsIEditProperty::object;
|
||||
nsIAtom * nsIEditProperty::br;
|
||||
@@ -204,6 +205,7 @@ nsEditProperty::nsEditProperty()
|
||||
nsIEditProperty::font = NS_NewAtom("font");
|
||||
nsIEditProperty::a = NS_NewAtom("a");
|
||||
nsIEditProperty::href = NS_NewAtom("href"); // Use to differentiate between "a" for link, "a" for named anchor
|
||||
nsIEditProperty::name = NS_NewAtom("name");
|
||||
nsIEditProperty::img = NS_NewAtom("img");
|
||||
nsIEditProperty::object = NS_NewAtom("object");
|
||||
nsIEditProperty::br = NS_NewAtom("br");
|
||||
@@ -319,6 +321,7 @@ nsEditProperty::~nsEditProperty()
|
||||
NS_IF_RELEASE(nsIEditProperty::font);
|
||||
NS_IF_RELEASE(nsIEditProperty::a);
|
||||
NS_IF_RELEASE(nsIEditProperty::href);
|
||||
NS_IF_RELEASE(nsIEditProperty::name);
|
||||
NS_IF_RELEASE(nsIEditProperty::img);
|
||||
NS_IF_RELEASE(nsIEditProperty::object);
|
||||
NS_IF_RELEASE(nsIEditProperty::br);
|
||||
|
||||
@@ -676,6 +676,7 @@ protected:
|
||||
const nsAString *aValue);
|
||||
|
||||
nsresult PromoteInlineRange(nsIDOMRange *inRange);
|
||||
nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange);
|
||||
nsresult SplitStyleAboveRange(nsIDOMRange *aRange,
|
||||
nsIAtom *aProperty,
|
||||
const nsAString *aAttribute);
|
||||
|
||||
@@ -646,7 +646,8 @@ nsresult nsHTMLEditor::RemoveStyleInside(nsIDOMNode *aNode,
|
||||
// then process the node itself
|
||||
if ( !aChildrenOnly &&
|
||||
(aProperty && NodeIsType(aNode, aProperty) || // node is prop we asked for
|
||||
(aProperty == nsIEditProperty::href && nsHTMLEditUtils::IsLink(aNode))) || // but check for link (<a href=...)
|
||||
(aProperty == nsIEditProperty::href && nsHTMLEditUtils::IsLink(aNode)) || // but check for link (<a href=...)
|
||||
(aProperty == nsIEditProperty::name && nsHTMLEditUtils::IsNamedAnchor(aNode))) || // and for named anchors
|
||||
(!aProperty && NodeIsProperty(aNode))) // or node is any prop and we asked for that
|
||||
{
|
||||
// if we weren't passed an attribute, then we want to
|
||||
@@ -791,6 +792,63 @@ PRBool nsHTMLEditor::HasAttrVal(nsIDOMNode *aNode,
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange)
|
||||
{
|
||||
if (!inRange) return NS_ERROR_NULL_POINTER;
|
||||
nsresult res;
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode, parent, tmp;
|
||||
PRInt32 startOffset, endOffset, tmpOffset;
|
||||
|
||||
res = inRange->GetStartContainer(getter_AddRefs(startNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = inRange->GetStartOffset(&startOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = inRange->GetEndContainer(getter_AddRefs(endNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = inRange->GetEndOffset(&endOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
tmp = startNode;
|
||||
while ( tmp &&
|
||||
!nsTextEditUtils::IsBody(tmp) &&
|
||||
!nsHTMLEditUtils::IsNamedAnchor(tmp))
|
||||
{
|
||||
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
tmp = parent;
|
||||
}
|
||||
if (!tmp) return NS_ERROR_NULL_POINTER;
|
||||
if (nsHTMLEditUtils::IsNamedAnchor(tmp))
|
||||
{
|
||||
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
startNode = parent;
|
||||
startOffset = tmpOffset;
|
||||
}
|
||||
|
||||
tmp = endNode;
|
||||
while ( tmp &&
|
||||
!nsTextEditUtils::IsBody(tmp) &&
|
||||
!nsHTMLEditUtils::IsNamedAnchor(tmp))
|
||||
{
|
||||
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
tmp = parent;
|
||||
}
|
||||
if (!tmp) return NS_ERROR_NULL_POINTER;
|
||||
if (nsHTMLEditUtils::IsNamedAnchor(tmp))
|
||||
{
|
||||
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
endNode = parent;
|
||||
endOffset = tmpOffset + 1;
|
||||
}
|
||||
|
||||
res = inRange->SetStart(startNode, startOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = inRange->SetEnd(endNode, endOffset);
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
|
||||
{
|
||||
@@ -1161,7 +1219,8 @@ nsresult nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom *aProperty, const nsAStr
|
||||
// manipulating text attributes on a collapsed selection only sets state for the next text insertion
|
||||
|
||||
// For links, aProperty uses "href", use "a" instead
|
||||
if (aProperty == nsIEditProperty::href)
|
||||
if (aProperty == nsIEditProperty::href ||
|
||||
aProperty == nsIEditProperty::name)
|
||||
aProperty = nsIEditProperty::a;
|
||||
|
||||
if (aProperty) return mTypeInState->ClearProp(aProperty, nsAutoString(*aAttribute));
|
||||
@@ -1195,10 +1254,18 @@ nsresult nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom *aProperty, const nsAStr
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
||||
|
||||
// adjust range to include any ancestors who's children are entirely selected
|
||||
res = PromoteInlineRange(range);
|
||||
if (aProperty == nsIEditProperty::name)
|
||||
{
|
||||
// promote range if it starts or end in a named anchor and we
|
||||
// want to remove named anchors
|
||||
res = PromoteRangeIfStartsOrEndsInNamedAnchor(range);
|
||||
}
|
||||
else {
|
||||
// adjust range to include any ancestors who's children are entirely selected
|
||||
res = PromoteInlineRange(range);
|
||||
}
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
|
||||
// remove this style from ancestors of our range endpoints,
|
||||
// splitting them as appropriate
|
||||
res = SplitStyleAboveRange(range, aProperty, aAttribute);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* Simon Fraser (sfraser@netscape.com)
|
||||
* Ryan Cassin (rcassin@supernova.org)
|
||||
* Kathleen Brade (brade@netscape.com)
|
||||
* Daniel Glazman (glazman@netscape.com)
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
@@ -62,6 +63,7 @@ function SetupHTMLEditorCommands()
|
||||
controller.registerCommand("cmd_advancedProperties", nsAdvancedPropertiesCommand);
|
||||
controller.registerCommand("cmd_objectProperties", nsObjectPropertiesCommand);
|
||||
controller.registerCommand("cmd_removeLinks", nsRemoveLinksCommand);
|
||||
controller.registerCommand("cmd_removeNamedAnchors", nsRemoveNamedAnchorsCommand);
|
||||
controller.registerCommand("cmd_editLink", nsEditLinkCommand);
|
||||
|
||||
controller.registerCommand("cmd_form", nsFormCommand);
|
||||
@@ -2714,6 +2716,22 @@ var nsRemoveLinksCommand =
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
var nsRemoveNamedAnchorsCommand =
|
||||
{
|
||||
isCommandEnabled: function(aCommand, dummy)
|
||||
{
|
||||
// We could see if there's any link in selection, but it doesn't seem worth the work!
|
||||
return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
|
||||
},
|
||||
doCommand: function(aCommand)
|
||||
{
|
||||
window.editorShell.RemoveTextProperty("name", "");
|
||||
window._content.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
var nsEditLinkCommand =
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ function EditorFillContextMenu(event, contextMenuNode)
|
||||
// Setup object property menuitem
|
||||
var objectName = InitObjectPropertiesMenuitem("objectProperties_cm");
|
||||
|
||||
InitRemoveStylesMenuitems("removeStylesMenuitem_cm", "removeLinksMenuitem_cm");
|
||||
InitRemoveStylesMenuitems("removeStylesMenuitem_cm", "removeLinksMenuitem_cm", "removeNamedAnchorsMenuitem_cm");
|
||||
|
||||
// This item is present only in context menu:
|
||||
DisableItem("editLink_cm", objectName != "href");
|
||||
@@ -76,7 +76,8 @@ function EditorFillContextMenu(event, contextMenuNode)
|
||||
var haveStyle =
|
||||
IsMenuItemShowing("removeStylesMenuitem_cm") ||
|
||||
IsMenuItemShowing("createLink_cm") ||
|
||||
IsMenuItemShowing("removeLinksMenuitem_cm");
|
||||
IsMenuItemShowing("removeLinksMenuitem_cm") ||
|
||||
IsMenuItemShowing("removeNamedAnchorsMenuitem_cm");
|
||||
|
||||
var havePropsOrImage =
|
||||
IsMenuItemShowing("objectProperties_cm") ||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Daniel Glazman (glazman@netscape.com)
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://editor/locale/editorOverlay.dtd">
|
||||
@@ -53,6 +54,8 @@
|
||||
observes="cmd_link" />
|
||||
<!-- label and accesskey set at runtime from strings -->
|
||||
<menuitem id="removeLinksMenuitem_cm" observes="cmd_removeLinks"/>
|
||||
<menuitem id="removeNamedAnchorsMenuitem_cm" label="&formatRemoveNamedAnchors.label;"
|
||||
observes="cmd_removeNamedAnchors"/>
|
||||
<menuseparator id="styles-separator"/>
|
||||
|
||||
<!-- label and accesskey are set in InitObjectProperties -->
|
||||
|
||||
@@ -1754,7 +1754,7 @@ function EditorInitFormatMenu()
|
||||
{
|
||||
try {
|
||||
InitObjectPropertiesMenuitem("objectProperties");
|
||||
InitRemoveStylesMenuitems("removeStylesMenuitem", "removeLinksMenuitem");
|
||||
InitRemoveStylesMenuitems("removeStylesMenuitem", "removeLinksMenuitem", "removeNamedAnchorsMenuitem");
|
||||
} catch(ex) {}
|
||||
// Set alignment check
|
||||
}
|
||||
@@ -2358,11 +2358,12 @@ function InitJoinCellMenuitem(id)
|
||||
menuItem.setAttribute("accesskey",GetString("JoinCellAccesskey"));
|
||||
}
|
||||
|
||||
function InitRemoveStylesMenuitems(removeStylesId, removeLinksId)
|
||||
function InitRemoveStylesMenuitems(removeStylesId, removeLinksId, removeNamedAnchorsId)
|
||||
{
|
||||
// Change wording of menuitems depending on selection
|
||||
var stylesItem = document.getElementById(removeStylesId);
|
||||
var linkItem = document.getElementById(removeLinksId);
|
||||
var namedAnchorsItem = document.getElementById(removeNamedAnchorsId);
|
||||
|
||||
var isCollapsed = editorShell.editorSelection.isCollapsed;
|
||||
if (stylesItem)
|
||||
@@ -2380,6 +2381,11 @@ function InitRemoveStylesMenuitems(removeStylesId, removeLinksId)
|
||||
// if selection isn't collapsed since we only look at anchor node
|
||||
DisableItem(removeLinksId, isCollapsed && !window.editorShell.GetElementOrParentByTagName("href", null));
|
||||
}
|
||||
if (namedAnchorsItem)
|
||||
{
|
||||
// Disable if selection is collapsed
|
||||
DisableItem(removeNamedAnchorsId, isCollapsed);
|
||||
}
|
||||
}
|
||||
|
||||
function goUpdateTableMenuItems(commandset)
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
|
||||
<key id="removestyleskb" key="&formatremovestyles.keybinding;" observes="cmd_removeStyles" modifiers="accel, shift"/>
|
||||
<key id="removelinkskb" key="&formatremovelinks.keybinding;" observes="cmd_removeLinks" modifiers="accel, shift"/>
|
||||
<key id="removenamedanchorskb" key="&formatremovenamedanchors.keybinding;" observes="cmd_removeNamedAnchors" modifiers="accel, shift"/>
|
||||
<key id="decreasefontsizekb" key="&decreaseFontSize.keybinding;" observes="cmd_decreaseFont" modifiers="accel"/>
|
||||
<key id="increasefontsizekb" key="&increaseFontSize.keybinding;" observes="cmd_increaseFont" modifiers="accel"/>
|
||||
|
||||
@@ -224,6 +225,7 @@
|
||||
|
||||
<command id="cmd_removeStyles" oncommand="goDoCommand('cmd_removeStyles')"/>
|
||||
<command id="cmd_removeLinks" oncommand="goDoCommand('cmd_removeLinks')"/>
|
||||
<command id="cmd_removeNamedAnchors" oncommand="goDoCommand('cmd_removeNamedAnchors')"/>
|
||||
</commandset>
|
||||
|
||||
<!-- commands updated only when the menu gets created -->
|
||||
@@ -483,7 +485,12 @@
|
||||
<menuitem id="removeLinksMenuitem" key="removelinkskb"
|
||||
observes="cmd_removeLinks"
|
||||
position="7"/>
|
||||
<menuseparator position="8"/>
|
||||
<menuitem id="removeNamedAnchorsMenuitem" label="&formatRemoveNamedAnchors.label;"
|
||||
key="removenamedanchorskb"
|
||||
accesskey="&formatRemoveNamedAnchors.accesskey;"
|
||||
observes="cmd_removeNamedAnchors"
|
||||
position="8"/>
|
||||
<menuseparator position="9"/>
|
||||
|
||||
<!-- Note: the 'Init' menu methods for Paragraph, List, and Align
|
||||
assume that the id = 'menu_'+tagName (the 'value' label),
|
||||
@@ -492,7 +499,7 @@
|
||||
<!-- Paragraph Style submenu -->
|
||||
<menu id="paragraphMenu" label="¶graphMenu.label;"
|
||||
accesskey="&formatparagraphmenu.accesskey;"
|
||||
position="9" onpopupshowing="InitParagraphMenu()">
|
||||
position="10" onpopupshowing="InitParagraphMenu()">
|
||||
<menupopup oncommand="doStatefulCommand('cmd_paragraphState', event.target.getAttribute('value'))">
|
||||
<menuitem id="menu_bodyText" type="radio" name="1" label="&bodyTextCmd.label;" accesskey="&bodytext.accesskey;" value="" observes="cmd_renderedHTMLEnabler"/>
|
||||
<menuitem id="menu_p" type="radio" name="1" label="¶graphParagraphCmd.label;" accesskey="¶graphparagraph.accesskey;" value="p" observes="cmd_renderedHTMLEnabler"/>
|
||||
@@ -512,7 +519,7 @@
|
||||
<!-- List Style submenu -->
|
||||
<menu id="listMenu" label="&formatlistMenu.label;"
|
||||
accesskey="&formatlistmenu.accesskey;"
|
||||
position="10" onpopupshowing="InitListMenu()">
|
||||
position="11" onpopupshowing="InitListMenu()">
|
||||
<menupopup>
|
||||
<menuitem id="menu_noList" type="radio" name="1" label="&noneCmd.label;" accesskey="&none.accesskey;" observes="cmd_removeList"/>
|
||||
<menuitem id="menu_ul" type="radio" name="1" label="&listBulletCmd.label;" accesskey="&listbullet.accesskey;" observes="cmd_ul"/>
|
||||
@@ -523,16 +530,16 @@
|
||||
<menuitem id="listProps" label="&listProps.label;" accesskey="&listprops.accesskey;" observes="cmd_listProperties"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator position="11"/>
|
||||
<menuseparator position="12"/>
|
||||
|
||||
<menuitem id="increaseIndent" label="&increaseIndent.label;" accesskey="&increaseindent.accesskey;" key="increaseindentkb"
|
||||
observes="cmd_indent" position="12"/>
|
||||
observes="cmd_indent" position="13"/>
|
||||
<menuitem id="decreaseIndent" label="&decreaseIndent.label;" accesskey="&decreaseindent.accesskey;" key="decreaseindentkb"
|
||||
observes="cmd_outdent" position="13"/>
|
||||
observes="cmd_outdent" position="14"/>
|
||||
|
||||
<menu id="alignMenu" label="&alignMenu.label;" accesskey="&formatalignmenu.accesskey;"
|
||||
onpopupshowing="InitAlignMenu()"
|
||||
position="14">
|
||||
position="15">
|
||||
<!-- Align submenu -->
|
||||
<menupopup oncommand="doStatefulCommand('cmd_align', event.target.getAttribute('value'))">
|
||||
<menuitem id="menu_left" label="&alignLeft.label;" accesskey="&alignleft.accesskey;" type="radio" name="1" value="left" observes="cmd_renderedHTMLEnabler"/>
|
||||
@@ -541,7 +548,7 @@
|
||||
<menuitem id="menu_justify" label="&alignJustify.label;" accesskey="&alignjustify.accesskey;" type="radio" name="1" value="justify" observes="cmd_renderedHTMLEnabler"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator position="15"/>
|
||||
<menuseparator position="16"/>
|
||||
<!-- Merge Table Menu and separator in Messenger Composer here -->
|
||||
<!-- Merge property items here -->
|
||||
</menupopup>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
- Sammy Ford
|
||||
- Blake Ross
|
||||
- Ryan Cassin (rcassin@supernova.org)
|
||||
- Daniel Glazman (glazman@netscape.com)
|
||||
-->
|
||||
|
||||
<!-- Attn: Localization - some of the menus in this dialog directly affect mail also. -->
|
||||
@@ -404,6 +405,9 @@
|
||||
|
||||
<!ENTITY formatremovestyles.keybinding "y">
|
||||
<!ENTITY formatremovelinks.keybinding "k">
|
||||
<!ENTITY formatRemoveNamedAnchors.label "Remove Named Anchors">
|
||||
<!ENTITY formatRemoveNamedAnchors.accesskey "d">
|
||||
<!ENTITY formatremovenamedanchors.keybinding "a">
|
||||
|
||||
<!ENTITY formatindent.keybinding "]">
|
||||
<!ENTITY formatoutdent.keybinding "[">
|
||||
|
||||
Reference in New Issue
Block a user