editor cleanup; r=jfrancis, sr=blizzard, bug=209548

This commit is contained in:
brade%netscape.com 2003-07-18 14:12:51 +00:00
parent 3b47d61cef
commit d36b4b2d9b
8 changed files with 160 additions and 229 deletions

View File

@ -232,9 +232,9 @@ nsEditorUtils::IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *a
PRBool
nsEditorUtils::IsLeafNode(nsIDOMNode *aNode)
{
if (!aNode) return PR_FALSE;
PRBool hasChildren = PR_FALSE;
aNode->HasChildNodes(&hasChildren);
if (aNode)
aNode->HasChildNodes(&hasChildren);
return !hasChildren;
}

View File

@ -105,7 +105,7 @@ nsresult
nsSelectionState::RestoreSelection(nsISelection *aSel)
{
if (!aSel) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
nsresult res;
PRInt32 i, arrayCount = mArray.Count();
nsRangeStore *item;
@ -214,7 +214,6 @@ nsRangeUpdater::RegisterRangeItem(nsRangeStore *aRangeItem)
return; // don't register it again. It would get doubly adjusted.
}
mArray.AppendElement(aRangeItem);
return;
}
void
@ -222,7 +221,6 @@ nsRangeUpdater::DropRangeItem(nsRangeStore *aRangeItem)
{
if (!aRangeItem) return;
mArray.RemoveElement(aRangeItem);
return;
}
nsresult

View File

@ -38,50 +38,37 @@
* ***** END LICENSE BLOCK ***** */
#include "nsEditorEventListeners.h"
#include "nsEditor.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIDOMEvent.h"
#include "nsIDOMNSEvent.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIDOMElement.h"
#include "nsISelection.h"
#include "nsISelectionController.h"
#include "nsIDOMCharacterData.h"
#include "nsISupportsArray.h"
#include "nsIStringStream.h"
#include "nsIDOMKeyEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIPrivateTextEvent.h"
#include "nsIPrivateCompositionEvent.h"
#include "nsIEditorMailSupport.h"
#include "nsIDocumentEncoder.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsILookAndFeel.h"
#include "nsIPresContext.h"
#include "nsGUIEvent.h"
#include "nsICaret.h"
#ifdef USE_HACK_REPAINT
// for repainting hack only
#include "nsIView.h"
#include "nsIViewManager.h"
// end repainting hack only
#endif
// Drag & Drop, Clipboard
#include "nsIServiceManager.h"
#include "nsIClipboard.h"
#include "nsIDragService.h"
#include "nsIDragSession.h"
#include "nsITransferable.h"
#include "nsIFormatConverter.h"
#include "nsIContentIterator.h"
#include "nsIContent.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIDOMNSRange.h"
#include "nsEditorUtils.h"
@ -134,17 +121,9 @@ nsTextEditorKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult
nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMKeyEvent>keyEvent;
keyEvent = do_QueryInterface(aKeyEvent);
if (!keyEvent)
{
//non-key event passed to keydown. bad things.
return NS_OK;
}
// DOM event handling happens in two passes, the client pass and the system
// pass. We do all of our processing in the system pass, to allow client
// handlers the opporunity to cancel events and prevent typing in the editor.
// handlers the opportunity to cancel events and prevent typing in the editor.
// If the client pass cancelled the event, defaultPrevented will be true
// below.
@ -157,15 +136,22 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
return NS_OK;
}
nsCOMPtr<nsIDOMKeyEvent>keyEvent = do_QueryInterface(aKeyEvent);
if (!keyEvent)
{
//non-key event passed to keypress. bad things.
return NS_OK;
}
// we should check a flag here to see if we should be using built-in key bindings
// mEditor->GetFlags(&flags);
// if (flags & ...)
PRUint32 keyCode;
PRUint32 flags;
keyEvent->GetKeyCode(&keyCode);
// if we are readonly or disabled, then do nothing.
PRUint32 flags;
if (NS_SUCCEEDED(mEditor->GetFlags(&flags)))
{
if (flags & nsIPlaintextEditor::eEditorReadonlyMask ||
@ -266,14 +252,6 @@ nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
nsresult
nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
{
aProcessed=PR_FALSE;
return NS_OK;
}
/*
* nsTextEditorMouseListener implementation
*/
@ -303,23 +281,20 @@ nsTextEditorMouseListener::HandleEvent(nsIDOMEvent* aEvent)
nsresult
nsTextEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
{
if (!aMouseEvent)
return NS_OK; // NS_OK means "we didn't process the event". Go figure.
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
if (!mouseEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
if (!editor) { return NS_OK; }
// If we got a mouse down inside the editing area, we should force the
// IME to commit before we change the cursor position
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(mEditor);
if(imeEditor)
imeEditor->ForceCompositionEnd();
nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor));
if (!editor) { return NS_OK; }
if (imeEditor)
imeEditor->ForceCompositionEnd();
PRUint16 button = (PRUint16)-1;
mouseEvent->GetButton(&button);
@ -337,7 +312,6 @@ nsTextEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
{
// Set the selection to the point under the mouse cursor:
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
if (!nsuiEvent)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
@ -353,10 +327,10 @@ nsTextEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
// If the ctrl key is pressed, we'll do paste as quotation.
// Would've used the alt key, but the kde wmgr treats alt-middle specially.
nsCOMPtr<nsIEditorMailSupport> mailEditor;
mouseEvent = do_QueryInterface(aMouseEvent);
PRBool ctrlKey = PR_FALSE;
mouseEvent->GetCtrlKey(&ctrlKey);
nsCOMPtr<nsIEditorMailSupport> mailEditor;
if (ctrlKey)
mailEditor = do_QueryInterface(mEditor);
@ -387,8 +361,8 @@ nsTextEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
}
}
return NS_OK;
}
return NS_OK;
}
nsresult
@ -462,18 +436,17 @@ nsTextEditorTextListener::HandleText(nsIDOMEvent* aTextEvent)
#ifdef DEBUG_IME
printf("nsTextEditorTextListener::HandleText\n");
#endif
nsAutoString composedText;
nsresult result = NS_OK;
nsCOMPtr<nsIPrivateTextEvent> textEvent;
nsIPrivateTextRangeList *textRangeList;
nsTextEventReply *textEventReply;
textEvent = do_QueryInterface(aTextEvent);
nsCOMPtr<nsIPrivateTextEvent> textEvent = do_QueryInterface(aTextEvent);
if (!textEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
nsAutoString composedText;
nsresult result;
nsIPrivateTextRangeList *textRangeList;
nsTextEventReply *textEventReply;
textEvent->GetText(composedText);
textEvent->GetInputRange(&textRangeList);
textEvent->GetEventReply(&textEventReply);
@ -523,11 +496,11 @@ nsTextEditorDragListener::HandleEvent(nsIDOMEvent* aEvent)
nsresult
nsTextEditorDragListener::DragGesture(nsIDOMEvent* aDragEvent)
{
PRBool canDrag = PR_FALSE;
if ( !mEditor )
return NS_ERROR_NULL_POINTER;
// ...figure out if a drag should be started...
PRBool canDrag;
nsresult rv = mEditor->CanDrag(aDragEvent, &canDrag);
if ( NS_SUCCEEDED(rv) && canDrag )
rv = mEditor->DoDrag(aDragEvent);
@ -627,10 +600,9 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
nsresult
nsTextEditorDragListener::DragExit(nsIDOMEvent* aDragEvent)
{
if (mCaret)
if (mCaret && mCaretDrawn)
{
if (mCaretDrawn)
mCaret->EraseCaret();
mCaret->EraseCaret();
mCaretDrawn = PR_FALSE;
}
@ -645,8 +617,10 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
if (mCaret)
{
if (mCaretDrawn)
{
mCaret->EraseCaret();
mCaretDrawn = PR_FALSE;
mCaretDrawn = PR_FALSE;
}
mCaret->SetCaretVisible(PR_FALSE); // hide it, so that it turns off its timer
mCaret = nsnull; // release it
}
@ -665,9 +639,9 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
(flags & nsIPlaintextEditor::eEditorReadonlyMask)) )
{
// it was decided to "eat" the event as this is the "least surprise"
// since someone else handling it might be unintentional and the
// user could probably re-drag to be not over the disabled/readonly
// editfields if that is what is desired.
// since someone else handling it might be unintentional and the
// user could probably re-drag to be not over the disabled/readonly
// editfields if that is what is desired.
return aMouseEvent->StopPropagation();
}
return NS_OK;
@ -686,9 +660,9 @@ PRBool
nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
{
// if the target doc is read-only, we can't drop
PRUint32 flags = 0;
nsresult rv = mEditor->GetFlags(&flags);
if (NS_FAILED(rv)) return PR_FALSE;
PRUint32 flags;
if (NS_FAILED(mEditor->GetFlags(&flags)))
return PR_FALSE;
if ((flags & nsIPlaintextEditor::eEditorDisabledMask) ||
(flags & nsIPlaintextEditor::eEditorReadonlyMask)) {
@ -696,12 +670,13 @@ nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
}
// XXX cache this between drag events?
nsresult rv;
nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
if (!dragService) return PR_FALSE;
// does the drag have flavors we can accept?
nsCOMPtr<nsIDragSession> dragSession;
dragService->GetCurrentSession(getter_AddRefs(dragSession));
if (dragService)
dragService->GetCurrentSession(getter_AddRefs(dragSession));
if (!dragSession) return PR_FALSE;
PRBool flavorSupported = PR_FALSE;
@ -723,11 +698,6 @@ nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
if (!flavorSupported)
return PR_FALSE;
nsCOMPtr<nsISelection> selection;
rv = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv) || !selection)
return PR_FALSE;
nsCOMPtr<nsIDOMDocument> domdoc;
rv = mEditor->GetDocument(getter_AddRefs(domdoc));
if (NS_FAILED(rv)) return PR_FALSE;
@ -737,6 +707,11 @@ nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
if (NS_FAILED(rv)) return PR_FALSE;
if (domdoc == sourceDoc) // source and dest are the same document; disallow drops within the selection
{
nsCOMPtr<nsISelection> selection;
rv = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv) || !selection)
return PR_FALSE;
PRBool isCollapsed;
rv = selection->GetIsCollapsed(&isCollapsed);
if (NS_FAILED(rv)) return PR_FALSE;
@ -763,12 +738,9 @@ nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue; //dont bail yet, iterate through them all
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
if (NS_FAILED(rv) || !nsrange)
continue; //dont bail yet, iterate through them all
continue; //don't bail yet, iterate through them all
PRBool inRange = PR_TRUE;
(void)nsrange->IsPointInRange(parent, offset, &inRange);
@ -817,10 +789,9 @@ nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositio
printf("nsTextEditorCompositionListener::HandleStartComposition\n");
#endif
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
nsTextEventReply* eventReply;
if (!pCompositionEvent) return NS_ERROR_FAILURE;
nsTextEventReply* eventReply;
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
if (NS_FAILED(rv)) return rv;
@ -833,10 +804,9 @@ nsTextEditorCompositionListener::HandleQueryComposition(nsIDOMEvent* aCompositio
printf("nsTextEditorCompositionListener::HandleQueryComposition\n");
#endif
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
nsTextEventReply* eventReply;
if (!pCompositionEvent) return NS_ERROR_FAILURE;
nsTextEventReply* eventReply;
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
if (NS_FAILED(rv)) return rv;
@ -860,11 +830,10 @@ nsTextEditorCompositionListener::HandleQueryReconversion(nsIDOMEvent* aReconvers
printf("nsTextEditorCompositionListener::HandleQueryReconversion\n");
#endif
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aReconversionEvent);
nsReconversionEventReply* eventReply;
if (!pCompositionEvent)
return NS_ERROR_FAILURE;
nsReconversionEventReply* eventReply;
nsresult rv = pCompositionEvent->GetReconversionReply(&eventReply);
if (NS_FAILED(rv))
return rv;
@ -959,7 +928,7 @@ NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult,
return NS_ERROR_OUT_OF_MEMORY;
}
it->SetEditor(aEditor);
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
}
@ -1043,14 +1012,12 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
// turn on selection and caret
if (mEditor)
{
PRUint32 flags;
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
if (nsevent) {
nsevent->PreventBubble();
}
PRUint32 flags;
mEditor->GetFlags(&flags);
if (! (flags & nsIPlaintextEditor::eEditorDisabledMask))
{ // only enable caret and selection if the editor is not disabled
@ -1063,24 +1030,24 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
{
if (! (flags & nsIPlaintextEditor::eEditorReadonlyMask))
{ // only enable caret if the editor is not readonly
PRInt32 pixelWidth;
nsresult result;
nsCOMPtr<nsILookAndFeel> look =
do_GetService("@mozilla.org/widget/lookandfeel;1", &result);
if (NS_SUCCEEDED(result) && look)
{
PRInt32 pixelWidth;
if(flags & nsIPlaintextEditor::eEditorSingleLineMask)
look->GetMetric(nsILookAndFeel::eMetric_SingleLineCaretWidth, pixelWidth);
else
look->GetMetric(nsILookAndFeel::eMetric_MultiLineCaretWidth, pixelWidth);
selCon->SetCaretWidth(pixelWidth);
}
selCon->SetCaretWidth(pixelWidth);
selCon->SetCaretEnabled(PR_TRUE);
}
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
#ifdef USE_HACK_REPAINT
// begin hack repaint
@ -1110,23 +1077,18 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
// turn off selection and caret
if (mEditor)
{
PRUint32 flags;
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
if (nsevent) {
nsevent->PreventBubble();
}
mEditor->GetFlags(&flags);
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
// when imeEditor exists, call ForceCompositionEnd() to tell
// the input focus is leaving first
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(mEditor);
if (imeEditor)
imeEditor->ForceCompositionEnd();
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
if (editor)
{
nsCOMPtr<nsISelectionController>selCon;
@ -1134,6 +1096,9 @@ nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
if (selCon)
{
selCon->SetCaretEnabled(PR_FALSE);
PRUint32 flags;
mEditor->GetFlags(&flags);
if((flags & nsIPlaintextEditor::eEditorWidgetMask) ||
(flags & nsIPlaintextEditor::eEditorPasswordMask) ||
(flags & nsIPlaintextEditor::eEditorReadonlyMask) ||

View File

@ -75,7 +75,7 @@ public:
/*interfaces for addref and release and queryinterface*/
NS_DECL_ISUPPORTS
/*BEGIN interfaces in to the keylister base interface. must be supplied to handle pure virtual interfaces
/*BEGIN interfaces in to the keylistener base interface. must be supplied to handle pure virtual interfaces
see the nsIDOMKeyListener interface implementation for details
*/
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
@ -84,9 +84,6 @@ public:
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
/*END interfaces from nsIDOMKeyListener*/
protected:
virtual nsresult ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed);
protected:
nsIEditor* mEditor; // weak reference
};

View File

@ -165,9 +165,9 @@ nsInternetCiter::StripCites(const nsAString& aInString, nsAString& aOutString)
static void AddCite(nsAString& aOutString, PRInt32 citeLevel)
{
for (PRInt32 i = 0; i < citeLevel; ++i)
aOutString.Append(PRUnichar(gt));
aOutString.Append(gt);
if (citeLevel > 0)
aOutString.Append(PRUnichar(space));
aOutString.Append(space);
}
static inline void
@ -180,7 +180,8 @@ BreakLine(nsAString& aOutString, PRUint32& outStringCol,
AddCite(aOutString, citeLevel);
outStringCol = citeLevel + 1;
}
else outStringCol = 0;
else
outStringCol = 0;
}
static inline PRBool IsSpace(PRUnichar c)
@ -201,6 +202,8 @@ nsInternetCiter::Rewrap(const nsAString& aInString,
NS_ASSERTION((cr < 0), "Rewrap: CR in string gotten from DOM!\n");
#endif /* DEBUG */
aOutString.Truncate();
nsCOMPtr<nsILineBreaker> lineBreaker;
nsILineBreakerFactory *lf;
nsresult rv;
@ -214,8 +217,6 @@ nsInternetCiter::Rewrap(const nsAString& aInString,
nsServiceManager::ReleaseService(NS_LWBRK_CONTRACTID, lf);
}
aOutString.Truncate();
// Loop over lines in the input string, rewrapping each one.
PRUint32 length = aInString.Length();
PRUint32 posInString = 0;
@ -363,10 +364,10 @@ nsInternetCiter::Rewrap(const nsAString& aInString,
}
PRUint32 breakPt;
PRBool needMore;
rv = NS_ERROR_BASE;
if (lineBreaker)
{
PRBool needMore;
rv = lineBreaker->Prev(tString.get() + posInString,
length - posInString,
eol + 1 - posInString, &breakPt, &needMore);

View File

@ -54,17 +54,14 @@
#include "nsIDOMCharacterData.h"
#include "nsIContent.h"
#include "nsIContentIterator.h"
#include "nsIEnumerator.h"
#include "nsEditorUtils.h"
#include "EditTxn.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsISupportsArray.h"
#include "nsUnicharUtils.h"
// for IBMBIDI
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
if ((mFlags & nsIPlaintextEditor::eEditorReadonlyMask) || (mFlags & nsIPlaintextEditor::eEditorDisabledMask)) \
@ -145,7 +142,7 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
{
// insure trailing br node
// ensure trailing br node
res = CreateTrailingBRIfNeeded();
if (NS_FAILED(res)) return res;
}
@ -156,17 +153,18 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
wholeDoc->SetStart(mBody,0);
nsCOMPtr<nsIDOMNodeList> list;
res = mBody->GetChildNodes(getter_AddRefs(list));
if (NS_FAILED(res) || !list) return res?res:NS_ERROR_FAILURE;
if (NS_FAILED(res)) return res;
if (!list) return NS_ERROR_FAILURE;
PRUint32 listCount;
res = list->GetLength(&listCount);
if (NS_FAILED(res)) return res;
res = wholeDoc->SetEnd(mBody,listCount);
res = wholeDoc->SetEnd(mBody, listCount);
if (NS_FAILED(res)) return res;
// replace newlines in that range with breaks
res = ReplaceNewlines(wholeDoc);
return res;
return ReplaceNewlines(wholeDoc);
}
NS_IMETHODIMP
@ -308,7 +306,7 @@ NS_IMETHODIMP
nsTextEditRules::DidDoAction(nsISelection *aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
// dont let any txns in here move the selection around behind our back.
// don't let any txns in here move the selection around behind our back.
// Note that this won't prevent explicit selection setting from working.
nsAutoTxnsConserveSelection dontSpazMySelection(mEditor);
@ -430,35 +428,38 @@ nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult)
// a special mozBR following the normal br, and then set the
// selection to stick to the mozBR.
PRInt32 selOffset;
nsCOMPtr<nsIDOMNode> nearNode, selNode, root, temp;
nsCOMPtr<nsIDOMElement> rootElem;
nsCOMPtr<nsIDOMNode> selNode;
nsresult res;
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
// confirm we are at end of document
if (selOffset == 0) return NS_OK; // cant be after a br if we are at offset 0
nsCOMPtr<nsIDOMElement> rootElem;
res = mEditor->GetRootElement(getter_AddRefs(rootElem));
if (NS_FAILED(res)) return res;
root = do_QueryInterface(rootElem);
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem);
if (!root) return NS_ERROR_NULL_POINTER;
if (selNode != root) return NS_OK; // must be inside text node or somewhere other than end of root
temp = mEditor->GetChildAt(selNode, selOffset);
if (temp) return NS_OK; // cant be at end of there is a node after us.
nearNode = mEditor->GetChildAt(selNode, selOffset-1);
nsCOMPtr<nsIDOMNode> temp = mEditor->GetChildAt(selNode, selOffset);
if (temp) return NS_OK; // can't be at end if there is a node after us.
nsCOMPtr<nsIDOMNode> nearNode = mEditor->GetChildAt(selNode, selOffset-1);
if (nearNode && nsTextEditUtils::IsBreak(nearNode) && !nsTextEditUtils::IsMozBR(nearNode))
{
nsCOMPtr<nsISelection> sel(aSelection);
nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(sel));
nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
// need to insert special moz BR. Why? Because if we don't
// the user will see no new line for the break. Also, things
// like table cells won't grow in height.
nsCOMPtr<nsIDOMNode> brNode;
res = CreateMozBR(selNode, selOffset, address_of(brNode));
if (NS_FAILED(res)) return res;
res = nsEditor::GetNodeLocation(brNode, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
selPrivate->SetInterlinePosition(PR_TRUE);
res = aSelection->Collapse(selNode,selOffset);
res = aSelection->Collapse(selNode, selOffset);
if (NS_FAILED(res)) return res;
}
return res;
@ -491,16 +492,15 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
// initialize out param
*aCancel = PR_FALSE;
*aHandled = PR_TRUE;
nsresult res;
nsCOMPtr<nsIDOMNode> selNode;
PRInt32 selOffset;
PRInt32 start=0; PRInt32 end=0;
// handle docs with a max length
// NOTE, this function copies inString into outString for us.
res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength);
nsresult res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength);
if (NS_FAILED(res)) return res;
PRInt32 start = 0;
PRInt32 end = 0;
// handle password field docs
if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
{
@ -549,12 +549,11 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
eReplaceWithSpaces = 2, eStripNewlines = 3
};
PRInt32 singleLineNewlineBehavior = 1;
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && prefBranch)
rv = prefBranch->GetIntPref("editor.singleLine.pasteNewlines",
&singleLineNewlineBehavior);
do_GetService(NS_PREFSERVICE_CONTRACTID, &res);
if (NS_SUCCEEDED(res) && prefBranch)
res = prefBranch->GetIntPref("editor.singleLine.pasteNewlines",
&singleLineNewlineBehavior);
if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags)
{
@ -588,12 +587,13 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
}
// get the (collapsed) selection location
nsCOMPtr<nsIDOMNode> selNode;
PRInt32 selOffset;
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
// dont put text in places that cant have it
nsAutoString textTag(NS_LITERAL_STRING("__moz_text"));
if (!mEditor->IsTextNode(selNode) && !mEditor->CanContainTag(selNode, textTag))
// don't put text in places that can't have it
if (!mEditor->IsTextNode(selNode) && !mEditor->CanContainTag(selNode, NS_LITERAL_STRING("__moz_text")))
return NS_ERROR_FAILURE;
// we need to get the doc
@ -612,26 +612,25 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
// find where we are
nsCOMPtr<nsIDOMNode> curNode = selNode;
PRInt32 curOffset = selOffset;
// is our text going to be PREformatted?
// We remember this so that we know how to handle tabs.
PRBool isPRE;
res = mEditor->IsPreformatted(selNode, &isPRE);
if (NS_FAILED(res)) return res;
// dont spaz my selection in subtransactions
// don't spaz my selection in subtransactions
nsAutoTxnsConserveSelection dontSpazMySelection(mEditor);
nsString tString(*outString);
const PRUnichar *unicodeBuf = tString.get();
nsCOMPtr<nsIDOMNode> unused;
PRInt32 pos = 0;
// for efficiency, break out the pre case separately. This is because
// its a lot cheaper to search the input string for only newlines than
// it's a lot cheaper to search the input string for only newlines than
// it is to search for both tabs and newlines.
if (isPRE)
{
NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
{
PRInt32 oldPos = pos;
@ -654,7 +653,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
nsDependentSubstring subStr(tString, oldPos, subStrLen);
// is it a return?
if (subStr.Equals(newlineStr))
if (subStr.Equals(NS_LITERAL_STRING(LFSTR)))
{
if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags)
{
@ -699,10 +698,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
}
else
{
NS_NAMED_LITERAL_STRING(tabStr, "\t");
NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
char specialChars[] = {TAB, nsCRT::LF, 0};
nsAutoString tabString(NS_LITERAL_STRING(" "));
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < tString.Length()))
{
PRInt32 oldPos = pos;
@ -725,13 +721,13 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
nsDependentSubstring subStr(tString, oldPos, subStrLen);
// is it a tab?
if (subStr.Equals(tabStr))
if (subStr.Equals(NS_LITERAL_STRING("\t")))
{
res = mEditor->InsertTextImpl(tabString, address_of(curNode), &curOffset, doc);
res = mEditor->InsertTextImpl(NS_LITERAL_STRING(" "), address_of(curNode), &curOffset, doc);
pos++;
}
// is it a return?
else if (subStr.Equals(newlineStr))
else if (subStr.Equals(NS_LITERAL_STRING(LFSTR)))
{
res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
pos++;
@ -765,13 +761,12 @@ nsTextEditRules::WillSetTextProperty(nsISelection *aSelection, PRBool *aCancel,
{
if (!aSelection || !aCancel || !aHandled)
{ return NS_ERROR_NULL_POINTER; }
nsresult res = NS_OK;
// XXX: should probably return a success value other than NS_OK that means "not allowed"
if (nsIPlaintextEditor::eEditorPlaintextMask & mFlags) {
*aCancel = PR_TRUE;
}
return res;
return NS_OK;
}
nsresult
@ -785,13 +780,12 @@ nsTextEditRules::WillRemoveTextProperty(nsISelection *aSelection, PRBool *aCance
{
if (!aSelection || !aCancel || !aHandled)
{ return NS_ERROR_NULL_POINTER; }
nsresult res = NS_OK;
// XXX: should probably return a success value other than NS_OK that means "not allowed"
if (nsIPlaintextEditor::eEditorPlaintextMask & mFlags) {
*aCancel = PR_TRUE;
}
return res;
return NS_OK;
}
nsresult
@ -818,11 +812,9 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
*aCancel = PR_TRUE;
return NS_OK;
}
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> startNode;
PRInt32 startOffset;
if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
{
// manage the password buffer
@ -844,16 +836,16 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
}
else
{
PRBool bCollapsed;
res = aSelection->GetIsCollapsed(&bCollapsed);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMNode> nextNode, selNode;
nsCOMPtr<nsIDOMNode> startNode;
PRInt32 startOffset;
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset);
if (NS_FAILED(res)) return res;
if (!startNode) return NS_ERROR_FAILURE;
PRBool bCollapsed;
res = aSelection->GetIsCollapsed(&bCollapsed);
if (NS_FAILED(res)) return res;
if (bCollapsed)
{
// Test for distance between caret and text that will be deleted
@ -876,10 +868,10 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
return NS_OK;
// remember where we are
selNode = startNode;
nsCOMPtr<nsIDOMNode> selNode = startNode;
res = nsEditor::GetNodeLocation(selNode, address_of(startNode), &startOffset);
if (NS_FAILED(res)) return res;
// delete this text node if empty
if (!strLength)
{
@ -902,7 +894,7 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
--startOffset;
res = content->ChildAt(startOffset, getter_AddRefs(child));
if (NS_FAILED(res)) return res;
nextNode = do_QueryInterface(child);
nsCOMPtr<nsIDOMNode> nextNode = do_QueryInterface(child);
// scan for next node, deleting empty text nodes on way
while (nextNode && mEditor->IsTextNode(nextNode))
@ -930,8 +922,8 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
// make sure it is not last node in editfield. If it is, cancel deletion.
if (nextNode && (aCollapsedAction == nsIEditor::eNext) && nsTextEditUtils::IsBreak(nextNode))
{
nsCOMPtr<nsIDOMNode> lastChild;
if (!mBody) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> lastChild;
res = mBody->GetLastChild(getter_AddRefs(lastChild));
if (lastChild == nextNode)
{
@ -950,11 +942,9 @@ nsTextEditRules::DidDeleteSelection(nsISelection *aSelection,
nsIEditor::EDirection aCollapsedAction,
nsresult aResult)
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> startNode;
PRInt32 startOffset;
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset);
nsresult res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset);
if (NS_FAILED(res)) return res;
if (!startNode) return NS_ERROR_FAILURE;
@ -1012,11 +1002,10 @@ nsTextEditRules:: DidUndo(nsISelection *aSelection, nsresult aResult)
else
{
nsCOMPtr<nsIDOMElement> theBody;
nsCOMPtr<nsIDOMNode> node;
res = mEditor->GetRootElement(getter_AddRefs(theBody));
if (NS_FAILED(res)) return res;
if (!theBody) return NS_ERROR_FAILURE;
node = mEditor->GetLeftmostChild(theBody);
nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theBody);
if (node && mEditor->IsMozEditorBogusNode(node))
mBogusNode = do_QueryInterface(node);
}
@ -1052,9 +1041,8 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
if (NS_FAILED(res)) return res;
if (!theBody) return NS_ERROR_FAILURE;
nsAutoString tagName(NS_LITERAL_STRING("div"));
nsCOMPtr<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
res = theBody->GetElementsByTagName(NS_LITERAL_STRING("div"), getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
if (nodeList)
{
@ -1112,7 +1100,6 @@ nsTextEditRules::DidOutputText(nsISelection *aSelection, nsresult aResult)
return NS_OK;
}
nsresult
nsTextEditRules::ReplaceNewlines(nsIDOMRange *aRange)
{
@ -1130,18 +1117,15 @@ nsTextEditRules::ReplaceNewlines(nsIDOMRange *aRange)
res = iter->Init(aRange);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsISupports> isupports;
PRInt32 nodeCount,j;
nsCOMArray<nsIDOMCharacterData> arrayOfNodes;
// gather up a list of editable preformatted text nodes
while (NS_ENUMERATOR_FALSE == iter->IsDone())
{
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsIContent> content;
res = iter->CurrentNode(getter_AddRefs(content));
if (NS_FAILED(res)) return res;
node = do_QueryInterface(content);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(content);
if (!node) return NS_ERROR_FAILURE;
if (mEditor->IsTextNode(node) && mEditor->IsEditable(node))
@ -1162,7 +1146,7 @@ nsTextEditRules::ReplaceNewlines(nsIDOMRange *aRange)
// replace newlines with breaks. have to do this left to right,
// since inserting the break can split the text node, and the
// original node becomes the righthand node.
nodeCount = arrayOfNodes.Count();
PRInt32 j, nodeCount = arrayOfNodes.Count();
for (j = 0; j < nodeCount; j++)
{
nsCOMPtr<nsIDOMNode> brNode;
@ -1204,19 +1188,20 @@ nsTextEditRules::CreateTrailingBRIfNeeded()
// but only if we aren't a single line edit field
if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask)
return NS_OK;
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> lastChild, unused;
if (!mBody) return NS_ERROR_NULL_POINTER;
res = mBody->GetLastChild(getter_AddRefs(lastChild));
nsCOMPtr<nsIDOMNode> lastChild;
nsresult res = mBody->GetLastChild(getter_AddRefs(lastChild));
// assuming CreateBogusNodeIfNeeded() has been called first
if (NS_FAILED(res)) return res;
if (!lastChild) return NS_ERROR_NULL_POINTER;
if (!nsTextEditUtils::IsBreak(lastChild))
{
nsAutoTxnsConserveSelection dontSpazMySelection(mEditor);
PRUint32 rootLen;
res = mEditor->GetLengthOfDOMNode(mBody, rootLen);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMNode> unused;
res = CreateMozBR(mBody, rootLen, address_of(unused));
}
return res;
@ -1254,17 +1239,11 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
if (needsBogusContent)
{
// create a br
nsCOMPtr<nsIDOMDocument> domDoc;
res = mEditor->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMElement>brElement;
nsCOMPtr<nsIContent> newContent;
nsString qualifiedTag(NS_LITERAL_STRING("br"));
res = mEditor->CreateHTMLContent(qualifiedTag, getter_AddRefs(newContent));
brElement = do_QueryInterface(newContent);
res = mEditor->CreateHTMLContent(NS_LITERAL_STRING("br"), getter_AddRefs(newContent));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement>brElement = do_QueryInterface(newContent);
// set mBogusNode to be the newly created <br>
mBogusNode = do_QueryInterface(brElement);
if (!mBogusNode) return NS_ERROR_NULL_POINTER;
@ -1274,11 +1253,11 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
kMOZEditorBogusNodeValue );
// put the node in the document
res = mEditor->InsertNode(mBogusNode,mBody,0);
res = mEditor->InsertNode(mBogusNode, mBody, 0);
if (NS_FAILED(res)) return res;
// set selection
aSelection->Collapse(mBody,0);
aSelection->Collapse(mBody, 0);
}
return res;
}
@ -1354,17 +1333,16 @@ nsTextEditRules::RemoveIMETextFromPWBuf(PRInt32 &aStart, nsAString *aIMEString)
}
// initialize PasswordIME
if (!mPasswordIMEText.Length()) {
if (mPasswordIMEText.IsEmpty()) {
mPasswordIMEIndex = aStart;
mPasswordIMEText.Assign(*aIMEString);
return NS_OK;
}
else {
// manage the password buffer
mPasswordText.Cut(mPasswordIMEIndex, mPasswordIMEText.Length());
aStart = mPasswordIMEIndex;
}
// manage the password buffer
mPasswordText.Cut(mPasswordIMEIndex, mPasswordIMEText.Length());
aStart = mPasswordIMEIndex;
mPasswordIMEText.Assign(*aIMEString);
return NS_OK;
}

View File

@ -53,10 +53,9 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode,
{
NS_ENSURE_ARG_POINTER(aCancel);
*aCancel = PR_FALSE;
nsresult res = NS_OK;
nsCOMPtr<nsIPresShell> shell;
res = mEditor->GetPresShell(getter_AddRefs(shell));
nsresult res = mEditor->GetPresShell(getter_AddRefs(shell));
if (NS_FAILED(res))
return res;
if (!shell)
@ -79,29 +78,25 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode,
return NS_ERROR_NULL_POINTER;
nsIFrame *primaryFrame;
nsIFrame *frameBefore;
nsIFrame *frameAfter;
PRInt32 frameOffset;
res = shell->GetPrimaryFrameFor(content, &primaryFrame);
if (NS_FAILED(res))
return res;
if (!primaryFrame)
return NS_ERROR_NULL_POINTER;
nsIFrame *frameBefore;
nsIFrame *frameAfter;
PRInt32 frameOffset;
res = primaryFrame->GetChildFrameContainingOffset(aSelOffset, PR_FALSE, &frameOffset, &frameBefore);
if (NS_FAILED(res))
return res;
if (!frameBefore)
return NS_ERROR_NULL_POINTER;
PRInt32 start, end;
PRUint8 currentCursorLevel;
PRUint8 levelAfter;
PRUint8 levelBefore;
PRUint8 levelOfDeletion;
nsCOMPtr<nsIAtom> embeddingLevel = getter_AddRefs(NS_NewAtom("EmbeddingLevel"));
nsCOMPtr<nsIAtom> baseLevel = getter_AddRefs(NS_NewAtom("BaseLevel"));
// Get the bidi level of the frame before the caret
res = frameBefore->GetBidiProperty(context, embeddingLevel, (void**)&levelBefore,sizeof(PRUint8));
@ -110,6 +105,7 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode,
// If the caret is at the end of the frame, get the bidi level of the
// frame after the caret
PRInt32 start, end;
frameBefore->GetOffsets(start, end);
if (aSelOffset == end
|| aSelOffset == -1)
@ -124,6 +120,7 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode,
{
// there was no frameAfter, i.e. the caret is at the end of the
// document -- use the base paragraph level
nsCOMPtr<nsIAtom> baseLevel = getter_AddRefs(NS_NewAtom("BaseLevel"));
res = frameBefore->GetBidiProperty(context, baseLevel, (void**)&levelAfter,sizeof(PRUint8));
if (NS_FAILED(res))
return res;
@ -139,9 +136,12 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode,
{
levelAfter = levelBefore;
}
PRUint8 currentCursorLevel;
res = shell->GetCaretBidiLevel(&currentCursorLevel);
if (NS_FAILED(res))
return res;
PRUint8 levelOfDeletion;
levelOfDeletion = (nsIEditor::eNext==aAction) ? levelAfter : levelBefore;
if (currentCursorLevel == levelOfDeletion)

View File

@ -42,13 +42,6 @@
#include "nsPlaintextEditor.h"
#include "nsEditProperty.h"
#include "nsString.h"
#include "nsUnicharUtils.h"
/********************************************************
* helper methods from nsTextEditRules
********************************************************/
///////////////////////////////////////////////////////////////////////////
// IsBody: true if node an html body node
//
@ -97,11 +90,9 @@ nsTextEditUtils::HasMozAttr(nsIDOMNode *node)
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
if (elem)
{
nsAutoString typeAttrName(NS_LITERAL_STRING("type"));
nsAutoString typeAttrVal;
nsresult res = elem->GetAttribute(typeAttrName, typeAttrVal);
ToLowerCase(typeAttrVal);
if (NS_SUCCEEDED(res) && (typeAttrVal.Equals(NS_LITERAL_STRING("_moz"))))
nsresult res = elem->GetAttribute(NS_LITERAL_STRING("type"), typeAttrVal);
if (NS_SUCCEEDED(res) && (typeAttrVal.EqualsIgnoreCase("_moz")))
return PR_TRUE;
}
return PR_FALSE;
@ -118,9 +109,10 @@ nsTextEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor)
{
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = editor->GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res) || !bodyElement)
return res?res:NS_ERROR_NULL_POINTER;
if (NS_FAILED(res))
return res;
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement);
if (!bodyNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsIDOMNode> p = node;
while (p && p!= bodyNode)