Fixing bug 92686. Return inserts line break, should insert paragraph break. Patch by daniel@glazman.org, r=brade@comcast.netbrade@comcast.net, sr=jst@mozilla.org

This commit is contained in:
jst%mozilla.jstenback.com 2005-01-12 19:11:48 +00:00
Родитель 50ae79dc39
Коммит 371985eba8
8 изменённых файлов: 150 добавлений и 178 удалений

Просмотреть файл

@ -51,7 +51,7 @@ interface nsIContentFilter;
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
%}
[scriptable, uuid(4b0fd0d0-1dd2-11b2-bf2e-ef20fbca2c88)]
[scriptable, uuid(afc36593-5787-4420-93d9-b2c0ccbf0cad)]
interface nsIHTMLEditor : nsISupports
{
@ -600,5 +600,13 @@ interface nsIHTMLEditor : nsISupports
void checkSelectionStateForAnonymousButtons(in nsISelection aSelection);
boolean isAnonymousElement(in nsIDOMElement aElement);
/**
* A boolean indicating if a return key pressed in a paragraph creates
* another paragraph or just inserts a <br> at the caret
*
* @return true if CR in a paragraph creates a new paragraph
*/
attribute boolean returnInParagraphCreatesNewParagraph;
};

Просмотреть файл

@ -6288,10 +6288,18 @@ nsHTMLEditRules::ReturnInParagraph(nsISelection *aSelection,
*aCancel = PR_FALSE;
*aHandled = PR_FALSE;
nsCOMPtr<nsIDOMNode> sibling;
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
nsresult res = nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
if (NS_FAILED(res)) return res;
PRBool doesCRCreateNewP;
res = mHTMLEditor->GetReturnInParagraphCreatesNewParagraph(&doesCRCreateNewP);
if (NS_FAILED(res)) return res;
PRBool newBRneeded = PR_FALSE;
nsCOMPtr<nsIDOMNode> sibling;
// easy case, in a text node:
if (mHTMLEditor->IsTextNode(aNode))
{
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aNode);
@ -6304,46 +6312,37 @@ nsHTMLEditRules::ReturnInParagraph(nsISelection *aSelection,
{
// is there a BR prior to it?
mHTMLEditor->GetPriorHTMLSibling(aNode, address_of(sibling));
if (!sibling)
if (!sibling ||
!mHTMLEditor->IsVisBreak(sibling) || nsTextEditUtils::HasMozAttr(sibling))
{
// no previous sib, so
// just fall out to default of inserting a BR
return res;
newBRneeded = PR_TRUE;
}
if (mHTMLEditor->IsVisBreak(sibling) && !nsTextEditUtils::HasMozAttr(sibling))
{
// split para
nsCOMPtr<nsIDOMNode> selNode = aNode;
*aHandled = PR_TRUE;
res = SplitParagraph(aPara, sibling, aSelection, address_of(selNode), &aOffset);
}
// else just fall out to default of inserting a BR
return res;
}
// at end of text node?
if (aOffset == (PRInt32)strLength)
else if (aOffset == (PRInt32)strLength)
{
// we're at the end of text node...
// is there a BR after to it?
res = mHTMLEditor->GetNextHTMLSibling(aNode, address_of(sibling));
if (!sibling)
if (!sibling ||
!mHTMLEditor->IsVisBreak(sibling) || nsTextEditUtils::HasMozAttr(sibling))
{
// no next sib, so
// just fall out to default of inserting a BR
return res;
newBRneeded = PR_TRUE;
offset++;
}
if (mHTMLEditor->IsVisBreak(sibling) && !nsTextEditUtils::HasMozAttr(sibling))
{
// split para
nsCOMPtr<nsIDOMNode> selNode = aNode;
*aHandled = PR_TRUE;
res = SplitParagraph(aPara, sibling, aSelection, address_of(selNode), &aOffset);
}
// else just fall out to default of inserting a BR
return res;
}
// inside text node
// just fall out to default of inserting a BR
return res;
else
{
if (doesCRCreateNewP)
{
nsCOMPtr<nsIDOMNode> tmp;
res = mEditor->SplitNode(aNode, aOffset, getter_AddRefs(tmp));
if (NS_FAILED(res)) return res;
aNode = tmp;
}
newBRneeded = PR_TRUE;
offset++;
}
}
else
{
@ -6359,18 +6358,26 @@ nsHTMLEditRules::ReturnInParagraph(nsISelection *aSelection,
if (NS_FAILED(res)) return res;
if (!nearNode || !mHTMLEditor->IsVisBreak(nearNode) || nsTextEditUtils::HasMozAttr(nearNode))
{
// just fall out to default of inserting a BR
return res;
newBRneeded = PR_TRUE;
}
}
// else split para
*aHandled = PR_TRUE;
res = SplitParagraph(aPara, nearNode, aSelection, address_of(selNode), &aOffset);
if (!newBRneeded)
sibling = nearNode;
}
return res;
}
if (newBRneeded)
{
// if CR does not create a new P, default to BR creation
if (!doesCRCreateNewP)
return NS_OK;
nsCOMPtr<nsIDOMNode> brNode;
res = mHTMLEditor->CreateBR(parent, offset, address_of(brNode));
sibling = brNode;
}
nsCOMPtr<nsIDOMNode> selNode = aNode;
*aHandled = PR_TRUE;
return SplitParagraph(aPara, sibling, aSelection, address_of(selNode), &aOffset);
}
///////////////////////////////////////////////////////////////////////////
// SplitParagraph: split a paragraph at selection point, possibly deleting a br

Просмотреть файл

@ -151,8 +151,9 @@ nsHTMLEditor::nsHTMLEditor()
: nsPlaintextEditor()
, mIgnoreSpuriousDragEvent(PR_FALSE)
, mTypeInState(nsnull)
, mSelectedCellIndex(0)
, mCRInParagraphCreatesParagraph(PR_FALSE)
, mHTMLCSSUtils(nsnull)
, mSelectedCellIndex(0)
, mIsObjectResizingEnabled(PR_TRUE)
, mIsResizing(PR_FALSE)
, mIsAbsolutelyPositioningEnabled(PR_TRUE)
@ -163,11 +164,6 @@ nsHTMLEditor::nsHTMLEditor()
, mIsInlineTableEditingEnabled(PR_TRUE)
, mGridSize(0)
{
mBoldAtom = do_GetAtom("b");
mItalicAtom = do_GetAtom("i");
mUnderlineAtom = do_GetAtom("u");
mFontAtom = do_GetAtom("font");
mLinkAtom = do_GetAtom("a");
}
nsHTMLEditor::~nsHTMLEditor()
@ -6114,3 +6110,16 @@ nsHTMLEditor::IsAnonymousElement(nsIDOMElement * aElement, PRBool * aReturn)
return NS_OK;
}
nsresult
nsHTMLEditor::SetReturnInParagraphCreatesNewParagraph(PRBool aCreatesNewParagraph)
{
mCRInParagraphCreatesParagraph = aCreatesNewParagraph;
return NS_OK;
}
nsresult
nsHTMLEditor::GetReturnInParagraphCreatesNewParagraph(PRBool *aCreatesNewParagraph)
{
*aCreatesNewParagraph = mCRInParagraphCreatesParagraph;
return NS_OK;
}

Просмотреть файл

@ -768,21 +768,12 @@ protected:
TypeInState* mTypeInState;
nsCOMPtr<nsIAtom> mBoldAtom;
nsCOMPtr<nsIAtom> mItalicAtom;
nsCOMPtr<nsIAtom> mUnderlineAtom;
nsCOMPtr<nsIAtom> mFontAtom;
nsCOMPtr<nsIAtom> mLinkAtom;
nsCOMPtr<nsIDOMNode> mCachedNode;
PRBool mCachedBoldStyle;
PRBool mCachedItalicStyle;
PRBool mCachedUnderlineStyle;
nsString mCachedFontName;
// Used to disable HTML formatting commands during HTML source editing
PRBool mCanEditHTML;
PRPackedBool mCRInParagraphCreatesParagraph;
PRPackedBool mCSSAware;
nsHTMLCSSUtils *mHTMLCSSUtils;
// Used by GetFirstSelectedCell and GetNextSelectedCell
PRInt32 mSelectedCellIndex;
@ -790,13 +781,9 @@ protected:
nsString mLastStyleSheetURL;
nsString mLastOverrideStyleSheetURL;
PRBool mCSSAware;
nsHTMLCSSUtils *mHTMLCSSUtils;
// Maintain a list of associated style sheets and their urls.
nsStringArray mStyleSheetURLs;
nsCOMArray<nsICSSStyleSheet> mStyleSheets;
PRInt32 mNumStyleSheets;
// an array for holding default style settings
nsVoidArray mDefaultStyles;

Просмотреть файл

@ -134,3 +134,5 @@ pref("editor.disable_spell_checker", false);
pref("editor.dont_lock_spell_files", true);
#endif
#endif
pref("editor.CR_creates_new_p", false);

Просмотреть файл

@ -78,6 +78,8 @@ var gColorObj = { LastTextColor:"", LastBackgroundColor:"", LastHighlightColor:"
var gDefaultTextColor = "";
var gDefaultBackgroundColor = "";
var gCSSPrefListener;
var gEditorToolbarPrefListener;
var gReturnInParagraphPrefListener;
var gPrefs;
var gLocalFonts = null;
@ -90,6 +92,8 @@ var gFontSizeNames = ["xx-small","x-small","small","medium","large","x-large","x
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const kEditorToolbarPrefs = "editor.toolbars.showbutton.";
const kUseCssPref = "editor.use_css";
const kCRInParagraphsPref = "editor.CR_creates_new_p";
function ShowHideToolbarSeparators(toolbar) {
var childNodes = toolbar.childNodes;
@ -123,55 +127,18 @@ function ShowHideToolbarButtons()
ShowHideToolbarSeparators(document.getElementById("FormatToolbar"));
}
function AddToolbarPrefListener()
function nsPrefListener(prefName)
{
try {
var pbi = GetPrefs().QueryInterface(Components.interfaces.nsIPrefBranchInternal);
pbi.addObserver(kEditorToolbarPrefs, gEditorToolbarPrefListener, false);
} catch(ex) {
dump("Failed to observe prefs: " + ex + "\n");
}
}
function RemoveToolbarPrefListener()
{
try {
var pbi = GetPrefs().QueryInterface(Components.interfaces.nsIPrefBranchInternal);
pbi.removeObserver(kEditorToolbarPrefs, gEditorToolbarPrefListener);
} catch(ex) {
dump("Failed to remove pref observer: " + ex + "\n");
}
}
// Pref listener constants
const gEditorToolbarPrefListener =
{
observe: function(subject, topic, prefName)
{
// verify that we're changing a button pref
if (topic != "nsPref:changed")
return;
var id = prefName.substr(kEditorToolbarPrefs.length) + "Button";
var button = document.getElementById(id);
if (button) {
button.hidden = !gPrefs.getBoolPref(prefName);
ShowHideToolbarSeparators(button.parentNode);
}
}
};
function nsButtonPrefListener()
{
this.startup();
this.startup(prefName);
}
// implements nsIObserver
nsButtonPrefListener.prototype =
nsPrefListener.prototype =
{
domain: "editor.use_css",
startup: function()
domain: "",
startup: function(prefName)
{
this.domain = prefName;
try {
var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
pbi.addObserver(this.domain, this, false);
@ -194,27 +161,45 @@ nsButtonPrefListener.prototype =
return;
// verify that we're changing a button pref
if (topic != "nsPref:changed") return;
if (prefName.substr(0, this.domain.length) != this.domain) return;
if (prefName.substr(0, kUseCssPref.length) == kUseCssPref)
{
var cmd = document.getElementById("cmd_highlight");
if (cmd) {
var prefs = GetPrefs();
var useCSS = prefs.getBoolPref(prefName);
var editor = GetCurrentEditor();
if (useCSS && editor) {
var mixedObj = {};
var state = editor.getHighlightColorState(mixedObj);
cmd.setAttribute("state", state);
cmd.collapsed = false;
}
else {
cmd.setAttribute("state", "transparent");
cmd.collapsed = true;
}
var cmd = document.getElementById("cmd_highlight");
if (cmd) {
var prefs = GetPrefs();
var useCSS = prefs.getBoolPref(prefName);
var editor = GetCurrentEditor();
if (useCSS && editor) {
var mixedObj = {};
var state = editor.getHighlightColorState(mixedObj);
cmd.setAttribute("state", state);
cmd.collapsed = false;
}
else {
cmd.setAttribute("state", "transparent");
cmd.collapsed = true;
if (editor)
editor.isCSSEnabled = useCSS;
}
}
else if (prefName.substr(0, kEditorToolbarPrefs.length) == kEditorToolbarPrefs)
{
var id = prefName.substr(kEditorToolbarPrefs.length) + "Button";
var button = document.getElementById(id);
if (button) {
button.hidden = !gPrefs.getBoolPref(prefName);
ShowHideToolbarSeparators(button.parentNode);
}
}
else if (prefName.substr(0, kCRInParagraphsPref.length) == kCRInParagraphsPref)
{
var crInParagraphCreatesParagraph = gPrefs.getBoolPref(prefName);
var editor = GetCurrentEditor();
if (editor)
editor.isCSSEnabled = useCSS;
}
editor.returnInParagraphCreatesNewParagraph = crInParagraphCreatesParagraph;
}
}
}
@ -418,6 +403,9 @@ var gEditorDocumentObserver =
// Things for just the Web Composer application
if (IsWebComposer())
{
var prefs = GetPrefs();
editor.returnInParagraphCreatesNewParagraph = prefs.getBoolPref(kCRInParagraphsPref);
// Set focus to content window if not a mail composer
// Race conditions prevent us from setting focus here
// when loading a url into blank window
@ -566,15 +554,17 @@ function EditorStartup()
SetupComposerWindowCommands();
ShowHideToolbarButtons();
AddToolbarPrefListener();
gEditorToolbarPrefListener = new nsPrefListener(kEditorToolbarPrefs);
gCSSPrefListener = new nsButtonPrefListener();
gCSSPrefListener = new nsPrefListener(kUseCssPref);
gReturnInParagraphPrefListener = new nsPrefListener(kCRInParagraphsPref);
// hide Highlight button if we are in an HTML editor with CSS mode off
// and tell the editor if a CR in a paragraph creates a new paragraph
var prefs = GetPrefs();
var cmd = document.getElementById("cmd_highlight");
if (cmd) {
var prefs = GetPrefs();
var useCSS = prefs.getBoolPref("editor.use_css");
var useCSS = prefs.getBoolPref(kUseCssPref);
if (!useCSS && is_HTMLEditor) {
cmd.collapsed = true;
}
@ -692,8 +682,9 @@ function EditorResetFontAndColorAttributes()
function EditorShutdown()
{
RemoveToolbarPrefListener();
gEditorToolbarPrefListener.shutdown();
gCSSPrefListener.shutdown();
gReturnInParagraphPrefListener.shutdown();
try {
var commandManager = GetCurrentCommandManager();
@ -1332,7 +1323,7 @@ function GetBackgroundElementWithColor()
else
{
var prefs = GetPrefs();
var IsCSSPrefChecked = prefs.getBoolPref("editor.use_css");
var IsCSSPrefChecked = prefs.getBoolPref(kUseCssPref);
if (IsCSSPrefChecked && IsHTMLEditor())
{
var selection = editor.selection;

Просмотреть файл

@ -49,7 +49,7 @@
<script type="application/x-javascript">
<!-- Add "shouldAutoSave", "autoSaveAmount" to _elementIDs when implemented -->
<![CDATA[
var _elementIDs = ["maintainTableStructure", "preserveFormatting", "saveAssociatedFiles", "showPublishDialog", "recentFiles", "useCSS"];
var _elementIDs = ["maintainTableStructure", "preserveFormatting", "saveAssociatedFiles", "showPublishDialog", "recentFiles", "useCSS", "crInPCreatesNewP"];
]]>
</script>
<script type="application/x-javascript" src="chrome://editor/content/EdDialogCommon.js"/>
@ -187,9 +187,18 @@
<groupbox>
<caption label="&cssEditing.label;"/>
<checkbox
label = "&useCSS.label;"
id = "useCSS"
prefstring= "editor.use_css"
label = "&useCSS.label;"
id = "useCSS"
prefstring = "editor.use_css"
/>
</groupbox>
<groupbox>
<caption label="&carriageReturns.label;"/>
<checkbox
label = "&crInPCreatesNewP.label;"
id = "crInPCreatesNewP"
prefstring = "editor.CR_creates_new_p"
/>
</groupbox>
</page>

Просмотреть файл

@ -1,41 +0,0 @@
<!-- extracted from content/pref-composer.xul -->
<!--LOCALIZATION NOTE : FILE 'Composer' prefs dialog. Similar to Communcator 4.x Document Properties/Colors and Background -->
<!--LOCALIZATION NOTE (title.label): DONT_TRANSLATE -->
<!ENTITY title.label "Composer">
<!ENTITY lHeader "Composer">
<!ENTITY rHeader "Settings for authoring of new Web pages">
<!ENTITY tableEditing.label "Table Editing">
<!ENTITY maintainTableStructure.label "Maintain table layout when inserting or deleting cells">
<!ENTITY maintainTableStructure.tooltip "Preserves table's rectangular shape by automatically adding cells after inserting or deleting cells">
<!ENTITY maintainStructure.accesskey "m">
<!ENTITY savingFiles.title "When Saving or Publishing Pages">
<!ENTITY preserveExistingFormatting "Retain original source formatting">
<!ENTITY preserveExistingFormatting.accesskey "o">
<!ENTITY preserveExistingFormatting.tooltip "Preserves line breaks and page's original formatting">
<!ENTITY reformat.label "Reformat HTML source">
<!ENTITY reformat.accesskey "r">
<!ENTITY reformat.tooltip "Reformat HTML tags using line breaks and indentation">
<!ENTITY saveAssociatedFiles.label "Save images and other associated files when saving pages">
<!ENTITY showPublishDialog.label "Always show Publish dialog when publishing pages">
<!ENTITY saving "Saving">
<!ENTITY AutoSaveCheck "Automatically save every">
<!ENTITY minText "minutes">
<!ENTITY exterLegend.label "External Editors">
<!ENTITY htmlSource "HTML Source:">
<!ENTITY imageeditor "Images:">
<!ENTITY chooseButton.label "Choose">
<!ENTITY recentFiles.title "Recent Pages Menu">
<!ENTITY documentsInMenu.accesskey "n">
<!ENTITY documentsInMenu "Maximum number of pages listed:">
<!ENTITY cssEditing.label "Cascading Style Sheets (CSS) Editing">
<!ENTITY useCSS.label "Use CSS styles instead of HTML elements and attributes">