editor fixes for:

180034 editor should respect the select_all style
183836 New list item should not reset inline styles
179384 Merging blocks via forward delete sends selection to front of document
98434 IME does not work correctly at the last characters in the text field  (patch courtesy of Shotaro Kamio)

r=jfrancis,brade,cmanske   sr=kin
This commit is contained in:
jfrancis%netscape.com 2002-12-22 01:51:14 +00:00
parent 67761ee6a7
commit 18d72537a9
16 changed files with 275 additions and 96 deletions

View File

@ -164,6 +164,7 @@ nsEditor::nsEditor()
, mAction(nsnull)
, mDirection(eNone)
, mInIMEMode(PR_FALSE)
, mIsIMEComposing(PR_FALSE)
, mIMETextRangeList(nsnull)
, mIMETextNode(nsnull)
, mIMETextOffset(0)
@ -1946,6 +1947,7 @@ nsEditor::EndComposition(void)
mIMETextOffset = 0;
mIMEBufferLength = 0;
mInIMEMode = PR_FALSE;
mIsIMEComposing = PR_FALSE;
// notify editor observers of action
NotifyEditorObservers();
@ -4482,6 +4484,49 @@ nsEditor::DeleteSelectionAndCreateNode(const nsAString& aTag,
/* Non-interface, protected methods */
nsresult
nsEditor::GetIMEBufferLength(PRInt32* length)
{
*length = mIMEBufferLength;
return NS_OK;
}
void
nsEditor::SetIsIMEComposing(){
// We set mIsIMEComposing according to mIMETextRangeList.
nsCOMPtr<nsIPrivateTextRange> rangePtr;
PRUint16 listlen, type;
mIsIMEComposing = PR_FALSE;
nsresult result = mIMETextRangeList->GetLength(&listlen);
if (NS_FAILED(result)) return;
for (PRUint16 i = 0; i < listlen; i++)
{
result = mIMETextRangeList->Item(i, getter_AddRefs(rangePtr));
if (NS_FAILED(result)) continue;
result = rangePtr->GetRangeType(&type);
if (NS_FAILED(result)) continue;
if ( type == nsIPrivateTextRange::TEXTRANGE_RAWINPUT ||
type == nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT ||
type == nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT ||
type == nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT )
{
mIsIMEComposing = PR_TRUE;
#ifdef DEBUG_IME
printf("nsEditor::mIsIMEComposing = PR_TRUE\n");
#endif
break;
}
}
return;
}
PRBool
nsEditor::IsIMEComposing() {
return mIsIMEComposing;
}
NS_IMETHODIMP
nsEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode)
{

View File

@ -489,6 +489,9 @@ public:
nsresult GetLastEditableNode(nsIDOMNode *aRoot, nsCOMPtr<nsIDOMNode> *outLastNode);
#endif
nsresult GetIMEBufferLength(PRInt32* length);
PRBool IsIMEComposing(); /* test if IME is in composition state */
void SetIsIMEComposing(); /* call this before |IsIMEComposing()| */
/** from html rules code - migration in progress */
static nsresult GetTagString(nsIDOMNode *aNode, nsAString& outString);
@ -564,11 +567,13 @@ protected:
EDirection mDirection; // the current direction of editor action
// data necessary to build IME transactions
PRBool mInIMEMode; // are we inside an IME composition?
nsIPrivateTextRangeList* mIMETextRangeList; // IME special selection ranges
nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node
PRUint32 mIMETextOffset; // offset in text node where IME comp string begins
PRUint32 mIMEBufferLength; // current length of IME comp string
PRBool mInIMEMode; // are we inside an IME composition?
nsIPrivateTextRangeList* mIMETextRangeList; // IME special selection ranges
nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node
PRUint32 mIMETextOffset; // offset in text node where IME comp string begins
PRUint32 mIMEBufferLength; // current length of IME comp string
PRBool mIsIMEComposing; // is IME in composition state?
// This is different from mInIMEMode. see Bug 98434.
// various listeners
nsVoidArray* mActionListeners; // listens to all low level actions on the doc

View File

@ -203,3 +203,47 @@ nsDOMSubtreeIterator::Init(nsIDOMNode* aNode)
return mIter->Init(content);
}
/******************************************************************************
* some general purpose editor utils
*****************************************************************************/
PRBool
nsEditorUtils::IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset)
{
if (!aNode && !aParent) return PR_FALSE;
if (aNode == aParent) return PR_FALSE;
nsCOMPtr<nsIDOMNode> parent, node = do_QueryInterface(aNode);
nsresult res;
do
{
res = node->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(res)) return PR_FALSE;
if (parent.get() == aParent)
{
if (aOffset)
{
nsCOMPtr<nsIContent> pCon(do_QueryInterface(parent));
nsCOMPtr<nsIContent> cCon(do_QueryInterface(node));
if (pCon && cCon)
{
pCon->IndexOf(cCon, *aOffset);
}
}
return PR_TRUE;
}
node = parent;
} while (parent);
return PR_FALSE;
}
PRBool
nsEditorUtils::IsLeafNode(nsIDOMNode *aNode)
{
if (!aNode) return PR_FALSE;
PRBool hasChildren = PR_FALSE;
aNode->HasChildNodes(&hasChildren);
return !hasChildren;
}

View File

@ -263,4 +263,11 @@ struct DOMPoint
};
class nsEditorUtils
{
public:
static PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset = 0);
static PRBool IsLeafNode(nsIDOMNode *aNode);
};
#endif // nsEditorUtils_h__

View File

@ -167,6 +167,7 @@ public:
static nsIAtom *cssVerticalAlign;
static nsIAtom *cssWhitespace;
static nsIAtom *cssWidth;
static nsIAtom *cssMozUserSelect;
static nsIAtom *cssPxUnit;

View File

@ -43,6 +43,7 @@
#include "nsISelection.h"
#include "nsEditor.h"
#include "nsLayoutCID.h"
#include "nsEditorUtils.h"
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
@ -308,6 +309,7 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
nsresult res = nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
// check for range endpoints that are after aNode and in the same parent
for (i=0; i<count; i++)
{
item = (nsRangeStore*)mArray.ElementAt(i);
@ -318,8 +320,35 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
if ((item->endNode.get() == parent) && (item->endOffset > offset))
item->endOffset--;
}
// MOOSE: also check inside of aNode, expensive. But in theory, we shouldn't
// actually hit this case in the usage i forsee for this.
// check for range endpoints that are in aNode
if (item->startNode == aNode)
{
item->startNode = parent;
item->startOffset = offset;
}
if (item->endNode == aNode)
{
item->endNode = parent;
item->endOffset = offset;
}
// check for range endpoints that are in descendants of aNode
nsCOMPtr<nsIDOMNode> oldStart;
if (nsEditorUtils::IsDescendantOf(item->startNode, aNode))
{
oldStart = item->startNode; // save for efficiency hack below.
item->startNode = parent;
item->startOffset = offset;
}
// avoid having to call IsDescendantOf() for common case of range startnode == range endnode.
if ((item->endNode == oldStart) || nsEditorUtils::IsDescendantOf(item->endNode, aNode))
{
item->endNode = parent;
item->endOffset = offset;
}
return NS_OK;
}
@ -427,6 +456,11 @@ nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode *aLeftNode,
item->startOffset += aOldLeftNodeLength;
if (item->endNode.get() == aRightNode)
item->endOffset += aOldLeftNodeLength;
// adjust endpoints in aLeftNode
if (item->startNode.get() == aLeftNode)
item->startNode = aRightNode;
if (item->endNode.get() == aLeftNode)
item->endNode = aRightNode;
}
return NS_OK;

View File

@ -144,6 +144,7 @@ nsIAtom * nsIEditProperty::cssTextDecoration;
nsIAtom * nsIEditProperty::cssVerticalAlign;
nsIAtom * nsIEditProperty::cssWhitespace;
nsIAtom * nsIEditProperty::cssWidth;
nsIAtom * nsIEditProperty::cssMozUserSelect;
nsIAtom * nsIEditProperty::cssPxUnit;
@ -282,6 +283,7 @@ nsEditProperty::nsEditProperty()
nsIEditProperty::cssVerticalAlign = NS_NewAtom("vertical-align");
nsIEditProperty::cssWhitespace = NS_NewAtom("white-space");
nsIEditProperty::cssWidth = NS_NewAtom("width");
nsIEditProperty::cssMozUserSelect = NS_NewAtom("-moz-user-select");
nsIEditProperty::cssPxUnit = NS_NewAtom("px");
@ -394,6 +396,7 @@ nsEditProperty::~nsEditProperty()
NS_IF_RELEASE(nsIEditProperty::cssVerticalAlign);
NS_IF_RELEASE(nsIEditProperty::cssWhitespace);
NS_IF_RELEASE(nsIEditProperty::cssWidth);
NS_IF_RELEASE(nsIEditProperty::cssMozUserSelect);
NS_IF_RELEASE(nsIEditProperty::cssPxUnit);
NS_IF_RELEASE(nsIEditProperty::cssEmUnit);

View File

@ -477,7 +477,7 @@ nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAString & aInputString,
{
// if we had to insert something higher up in the paste heirarchy, we want to
// skip any further paste nodes that descend from that. Else we will paste twice.
if (nsHTMLEditUtils::IsDescendantOf(curNode, insertedContextParent))
if (nsEditorUtils::IsDescendantOf(curNode, insertedContextParent))
continue;
}
@ -2425,7 +2425,7 @@ nsHTMLEditor::ReplaceOrphanedStructure(PRBool aEnd,
{
endpoint = GetArrayEndpoint(aEnd, aNodeArray);
if (!endpoint) break;
if (nsHTMLEditUtils::IsDescendantOf(endpoint, replaceNode))
if (nsEditorUtils::IsDescendantOf(endpoint, replaceNode))
aNodeArray.RemoveObject(endpoint);
else
break;

View File

@ -459,27 +459,13 @@ nsHTMLEditRules::AfterEditInner(PRInt32 action, nsIEditor::EDirection aDirection
res = AdjustWhitespace(selection);
if (NS_FAILED(res)) return res;
// also do this for original selection endpoints. The checks for the remembered
// selection endpoints are a performance fidgit. Otherwise
// nsRangeUpdater::SelAdjDeleteNode() would have to do much more expensive
// work (see comment in that routine in nsSelection.cpp)
nsCOMPtr<nsIDOMElement> bodyNode;
PRInt32 unused;
res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyNode));
if (NS_FAILED(res)) return res;
if (nsHTMLEditUtils::IsDescendantOf(mRangeItem.startNode, bodyNode, &unused))
{
nsWSRunObject(mHTMLEditor, mRangeItem.startNode, mRangeItem.startOffset).AdjustWhitespace();
}
// also do this for original selection endpoints.
nsWSRunObject(mHTMLEditor, mRangeItem.startNode, mRangeItem.startOffset).AdjustWhitespace();
// we only need to handle old selection endpoint if it was different from start
if ((mRangeItem.startNode != mRangeItem.endNode) || (mRangeItem.startOffset != mRangeItem.endOffset))
{
if (nsHTMLEditUtils::IsDescendantOf(mRangeItem.endNode, bodyNode, &unused))
{
nsWSRunObject(mHTMLEditor, mRangeItem.endNode, mRangeItem.endOffset).AdjustWhitespace();
}
nsWSRunObject(mHTMLEditor, mRangeItem.endNode, mRangeItem.endOffset).AdjustWhitespace();
}
}
// if we created a new block, make sure selection lands in it
@ -1693,7 +1679,7 @@ nsHTMLEditRules::SplitMailCites(nsISelection *aSelection, PRBool aPlaintext, PRB
{
// ok, we are just before a break. is it inside the mailquote?
PRInt32 unused;
if (nsHTMLEditUtils::IsDescendantOf(visNode, citeNode, &unused))
if (nsEditorUtils::IsDescendantOf(visNode, citeNode, &unused))
{
// it is. so lets reset our selection to be just after it.
res = mHTMLEditor->GetNodeLocation(visNode, address_of(selNode), &selOffset);
@ -1874,7 +1860,12 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
so--;
eo--;
}
return nsWSRunObject::PrepareToDeleteRange(mHTMLEditor, address_of(visNode), &so, address_of(visNode), &eo);
res = nsWSRunObject::PrepareToDeleteRange(mHTMLEditor, address_of(visNode), &so, address_of(visNode), &eo);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMCharacterData> nodeAsText(do_QueryInterface(visNode));
res = mHTMLEditor->DeleteText(nodeAsText,so,1);
*aHandled = PR_TRUE;
return res;
}
else if ( (wsType==nsWSRunObject::eSpecial) ||
(wsType==nsWSRunObject::eBreak) ||
@ -2240,8 +2231,8 @@ nsHTMLEditRules::JoinBlocks(nsCOMPtr<nsIDOMNode> *aLeftBlock,
// the other lists' items. Note that it is ok for them to be descendants
// of the other lists themselves, which is the usual case for sublists
// in our impllementation.
if (!nsHTMLEditUtils::IsDescendantOf(leftList, *aRightBlock, &theOffset) &&
!nsHTMLEditUtils::IsDescendantOf(rightList, *aLeftBlock, &theOffset))
if (!nsEditorUtils::IsDescendantOf(leftList, *aRightBlock, &theOffset) &&
!nsEditorUtils::IsDescendantOf(rightList, *aLeftBlock, &theOffset))
{
*aLeftBlock = leftList;
*aRightBlock = rightList;
@ -2260,7 +2251,7 @@ nsHTMLEditRules::JoinBlocks(nsCOMPtr<nsIDOMNode> *aLeftBlock,
// theOffset below is where you find yourself in aRightBlock when you traverse upwards
// from aLeftBlock
if (nsHTMLEditUtils::IsDescendantOf(*aLeftBlock, *aRightBlock, &rightOffset))
if (nsEditorUtils::IsDescendantOf(*aLeftBlock, *aRightBlock, &rightOffset))
{
// tricky case. left block is inside right block.
// Do ws adjustment. This just destroys non-visible ws at boundaries we will be joining.
@ -2297,7 +2288,7 @@ nsHTMLEditRules::JoinBlocks(nsCOMPtr<nsIDOMNode> *aLeftBlock,
}
// theOffset below is where you find yourself in aLeftBlock when you traverse upwards
// from aRightBlock
else if (nsHTMLEditUtils::IsDescendantOf(*aRightBlock, *aLeftBlock, &leftOffset))
else if (nsEditorUtils::IsDescendantOf(*aRightBlock, *aLeftBlock, &leftOffset))
{
// tricky case. right block is inside left block.
// Do ws adjustment. This just destroys non-visible ws at boundaries we will be joining.
@ -2643,7 +2634,7 @@ nsHTMLEditRules::WillMakeList(nsISelection *aSelection,
res = mHTMLEditor->GetTagString(curNode, existingListStr);
ToLowerCase(existingListStr);
// do we have a curList already?
if (curList && !nsHTMLEditUtils::IsDescendantOf(curNode, curList))
if (curList && !nsEditorUtils::IsDescendantOf(curNode, curList))
{
// move all of our children into curList.
// cheezy way to do it: move whole list and then
@ -2678,7 +2669,7 @@ nsHTMLEditRules::WillMakeList(nsISelection *aSelection,
// list item is in wrong type of list.
// if we dont have a curList, split the old list
// and make a new list of correct type.
if (!curList || nsHTMLEditUtils::IsDescendantOf(curNode, curList))
if (!curList || nsEditorUtils::IsDescendantOf(curNode, curList))
{
res = mHTMLEditor->SplitNode(curParent, offset, getter_AddRefs(newBlock));
if (NS_FAILED(res)) return res;
@ -3505,7 +3496,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
if (curBlockQuote)
{
// if so, is this node a descendant?
if (nsHTMLEditUtils::IsDescendantOf(curNode, curBlockQuote))
if (nsEditorUtils::IsDescendantOf(curNode, curBlockQuote))
{
lastBQChild = curNode;
continue; // then we dont need to do anything different for this node
@ -3614,7 +3605,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
nsCOMPtr<nsIDOMNode> sNode;
PRInt32 sOffset;
mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(sNode), &sOffset);
if ((sNode == rememberedLeftBQ) || nsHTMLEditUtils::IsDescendantOf(sNode, rememberedLeftBQ))
if ((sNode == rememberedLeftBQ) || nsEditorUtils::IsDescendantOf(sNode, rememberedLeftBQ))
{
// selection is inside rememberedLeftBQ - push it past it.
nsEditor::GetNodeLocation(rememberedLeftBQ, address_of(sNode), &sOffset);
@ -3623,7 +3614,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
}
// and pull selection before beginning of rememberedRightBQ
mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(sNode), &sOffset);
if ((sNode == rememberedRightBQ) || nsHTMLEditUtils::IsDescendantOf(sNode, rememberedRightBQ))
if ((sNode == rememberedRightBQ) || nsEditorUtils::IsDescendantOf(sNode, rememberedRightBQ))
{
// selection is inside rememberedRightBQ - push it before it.
nsEditor::GetNodeLocation(rememberedRightBQ, address_of(sNode), &sOffset);
@ -5984,20 +5975,46 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
res = CreateMozBR(prevItem, 0, address_of(brNode));
if (NS_FAILED(res)) return res;
}
else {
else
{
res = mHTMLEditor->IsEmptyNode(aListItem, &bIsEmptyNode, PR_TRUE);
if (NS_FAILED(res)) return res;
if (bIsEmptyNode) {
if (bIsEmptyNode)
{
nsCOMPtr<nsIDOMNode> brNode;
res = mHTMLEditor->CopyLastEditableChildStyles(prevItem, aListItem, getter_AddRefs(brNode));
if (NS_FAILED(res)) return res;
if (brNode) {
if (brNode)
{
nsCOMPtr<nsIDOMNode> brParent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(brNode, address_of(brParent), &offset);
return aSelection->Collapse(brParent, offset);
}
}
else
{
nsWSRunObject wsObj(mHTMLEditor, aListItem, 0);
nsCOMPtr<nsIDOMNode> visNode;
PRInt32 visOffset = 0;
PRInt16 wsType;
res = wsObj.NextVisibleNode(aListItem, 0, address_of(visNode), &visOffset, &wsType);
if (NS_FAILED(res)) return res;
if ( (wsType==nsWSRunObject::eSpecial) ||
(wsType==nsWSRunObject::eBreak) ||
nsHTMLEditUtils::IsHR(visNode) )
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(visNode, address_of(parent), &offset);
if (NS_FAILED(res)) return res;
return aSelection->Collapse(parent, offset);
}
else
{
return aSelection->Collapse(visNode, visOffset);
}
}
}
}
res = aSelection->Collapse(aListItem,0);
@ -6163,7 +6180,7 @@ nsHTMLEditRules::RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes)
if (curBlock)
{
// if so, is this node a descendant?
if (nsHTMLEditUtils::IsDescendantOf(curNode, curBlock))
if (nsEditorUtils::IsDescendantOf(curNode, curBlock))
{
lastNode = curNode;
continue; // then we dont need to do anything different for this node
@ -7162,7 +7179,7 @@ nsHTMLEditRules::SelectionEndpointInNode(nsIDOMNode *aNode, PRBool *aResult)
*aResult = PR_TRUE;
return NS_OK;
}
if (nsHTMLEditUtils::IsDescendantOf(startParent, aNode))
if (nsEditorUtils::IsDescendantOf(startParent, aNode))
{
*aResult = PR_TRUE;
return NS_OK;
@ -7177,7 +7194,7 @@ nsHTMLEditRules::SelectionEndpointInNode(nsIDOMNode *aNode, PRBool *aResult)
*aResult = PR_TRUE;
return NS_OK;
}
if (nsHTMLEditUtils::IsDescendantOf(endParent, aNode))
if (nsEditorUtils::IsDescendantOf(endParent, aNode))
{
*aResult = PR_TRUE;
return NS_OK;

View File

@ -394,47 +394,6 @@ nsHTMLEditUtils::IsFormWidget(nsIDOMNode *node)
return PR_FALSE;
}
PRBool
nsHTMLEditUtils::IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset)
{
if (!aNode && !aParent) return PR_FALSE;
if (aNode == aParent) return PR_FALSE;
nsCOMPtr<nsIDOMNode> parent, node = do_QueryInterface(aNode);
nsresult res;
do
{
res = node->GetParentNode(getter_AddRefs(parent));
if (NS_FAILED(res)) return PR_FALSE;
if (parent.get() == aParent)
{
if (aOffset)
{
nsCOMPtr<nsIContent> pCon(do_QueryInterface(parent));
nsCOMPtr<nsIContent> cCon(do_QueryInterface(node));
if (pCon && cCon)
{
pCon->IndexOf(cCon, *aOffset);
}
}
return PR_TRUE;
}
node = parent;
} while (parent);
return PR_FALSE;
}
PRBool
nsHTMLEditUtils::IsLeafNode(nsIDOMNode *aNode)
{
if (!aNode) return PR_FALSE;
PRBool hasChildren = PR_FALSE;
aNode->HasChildNodes(&hasChildren);
return !hasChildren;
}
PRBool
nsHTMLEditUtils::SupportsAlignAttr(nsIDOMNode * aNode)
{

View File

@ -75,8 +75,6 @@ public:
static PRBool IsMozDiv(nsIDOMNode *aNode);
static PRBool IsMailCite(nsIDOMNode *aNode);
static PRBool IsFormWidget(nsIDOMNode *aNode);
static PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset = 0);
static PRBool IsLeafNode(nsIDOMNode *aNode);
static PRBool SupportsAlignAttr(nsIDOMNode *aNode);
};

View File

@ -3947,7 +3947,61 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList)
#pragma mark -
#endif
// Undo, Redo, Cut, CanCut, Copy, CanCopy, all inherited from nsPlaintextEditor
NS_IMETHODIMP nsHTMLEditor::DeleteNode(nsIDOMNode * aNode)
{
nsCOMPtr<nsIDOMNode> selectAllNode = FindUserSelectAllNode(aNode);
if (selectAllNode)
{
return nsEditor::DeleteNode(selectAllNode);
}
return nsEditor::DeleteNode(aNode);
}
NS_IMETHODIMP nsHTMLEditor::DeleteText(nsIDOMCharacterData *aTextNode,
PRUint32 aOffset,
PRUint32 aLength)
{
nsCOMPtr<nsIDOMNode> selectAllNode = FindUserSelectAllNode(aTextNode);
if (selectAllNode)
{
return nsEditor::DeleteNode(selectAllNode);
}
return nsEditor::DeleteText(aTextNode, aOffset, aLength);
}
#ifdef XP_MAC
#pragma mark -
#pragma mark support utils
#pragma mark -
#endif
/* This routine examines aNode and it's ancestors looking for any node which has the
-moz-user-select: all style lit. Return the ighest such ancestor. */
nsCOMPtr<nsIDOMNode> nsHTMLEditor::FindUserSelectAllNode(nsIDOMNode *aNode)
{
nsCOMPtr<nsIDOMNode> resultNode; // starts out empty
nsCOMPtr<nsIDOMNode> node = aNode;
// retrieve the computed style of -moz-user-select for aNode
nsAutoString mozUserSelectValue;
while (node)
{
mHTMLCSSUtils->GetComputedProperty(node, nsIEditProperty::cssMozUserSelect, mozUserSelectValue);
if (!mozUserSelectValue.Equals(NS_LITERAL_STRING("all")))
{
return resultNode;
}
resultNode = node;
nsCOMPtr<nsIDOMNode> tmp;
node->GetParentNode(getter_AddRefs(tmp));
node = tmp;
}
return resultNode;
}
static nsresult SetSelectionAroundHeadChildren(nsCOMPtr<nsISelection> aSelection, nsWeakPtr aDocWeak)
{
@ -5186,7 +5240,7 @@ nsHTMLEditor::GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOu
nsCOMPtr<nsIDOMNode> child;
nsresult res = NS_OK;
child = GetLeftmostChild(aNode);
while (child && (!IsEditable(child) || !nsHTMLEditUtils::IsLeafNode(child)))
while (child && (!IsEditable(child) || !nsEditorUtils::IsLeafNode(child)))
{
nsCOMPtr<nsIDOMNode> tmp;
res = GetNextHTMLNode(child, address_of(tmp));
@ -5194,7 +5248,7 @@ nsHTMLEditor::GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOu
if (!tmp) return NS_ERROR_FAILURE;
// only accept nodes that are descendants of aNode
if (nsHTMLEditUtils::IsDescendantOf(tmp, aNode))
if (nsEditorUtils::IsDescendantOf(tmp, aNode))
child = tmp;
else
{
@ -5220,7 +5274,7 @@ nsHTMLEditor::GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOut
nsCOMPtr<nsIDOMNode> child;
nsresult res = NS_OK;
child = GetRightmostChild(aNode, PR_FALSE);
while (child && (!IsEditable(child) || !nsHTMLEditUtils::IsLeafNode(child)))
while (child && (!IsEditable(child) || !nsEditorUtils::IsLeafNode(child)))
{
nsCOMPtr<nsIDOMNode> tmp;
res = GetPriorHTMLNode(child, address_of(tmp));
@ -5228,7 +5282,7 @@ nsHTMLEditor::GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOut
if (!tmp) return NS_ERROR_FAILURE;
// only accept nodes that are descendants of aNode
if (nsHTMLEditUtils::IsDescendantOf(tmp, aNode))
if (nsEditorUtils::IsDescendantOf(tmp, aNode))
child = tmp;
else
{
@ -5413,7 +5467,7 @@ nsHTMLEditor::IsEmptyNodeImpl( nsIDOMNode *aNode,
return NS_OK;
}
PRBool isEmptyNode;
PRBool isEmptyNode = PR_TRUE;
res = IsEmptyNodeImpl(node, &isEmptyNode, aSingleBRDoesntCount,
aListOrCellNotEmpty, aSafeToAskFrames, aSeenBR);
if (NS_FAILED(res)) return res;

View File

@ -416,6 +416,11 @@ public:
virtual PRBool NodesSameType(nsIDOMNode *aNode1, nsIDOMNode *aNode2);
NS_IMETHODIMP DeleteNode(nsIDOMNode * aNode);
NS_IMETHODIMP DeleteText(nsIDOMCharacterData *aTextNode,
PRUint32 aOffset,
PRUint32 aLength);
/* ------------ nsICSSLoaderObserver -------------- */
NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify);
@ -425,6 +430,7 @@ public:
nsCOMPtr<nsIDOMNode> *ioParent,
PRInt32 *ioOffset,
PRBool aNoEmptyNodes);
nsCOMPtr<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode *aNode);
/** returns the absolute position of the end points of aSelection

View File

@ -134,7 +134,6 @@ nsPlaintextEditor::nsPlaintextEditor()
: nsEditor()
, mIgnoreSpuriousDragEvent(PR_FALSE)
, mRules(nsnull)
, mIsComposing(PR_FALSE)
, mWrapToWindow(PR_FALSE)
, mWrapColumn(0)
, mMaxTextLength(-1)
@ -1974,6 +1973,8 @@ nsPlaintextEditor::SetCompositionString(const nsAString& aCompositionString, nsI
{
nsAutoPlaceHolderBatch batch(this, gIMETxnName);
SetIsIMEComposing(); // We set mIsIMEComposing properly.
result = InsertText(aCompositionString);
mIMEBufferLength = aCompositionString.Length();

View File

@ -251,7 +251,6 @@ protected:
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
nsCOMPtr<nsIDOMEventListener> mFocusListenerP;
PRBool mIsComposing;
PRBool mWrapToWindow;
PRInt32 mWrapColumn;
PRInt32 mMaxTextLength;

View File

@ -1304,7 +1304,8 @@ nsTextEditRules::TruncateInsertionIfNeeded(nsISelection *aSelection,
nsresult res = NS_OK;
*aOutString = *aInString;
if ((-1 != aMaxLength) && (mFlags & nsIPlaintextEditor::eEditorPlaintextMask))
if ((-1 != aMaxLength) && (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
&& !mEditor->IsIMEComposing() )
{
// Get the current text length.
// Get the length of inString.
@ -1313,6 +1314,8 @@ nsTextEditRules::TruncateInsertionIfNeeded(nsISelection *aSelection,
// Subtract the length of the selection from the len(doc)
// since we'll delete the selection on insert.
// This is resultingDocLength.
// Get old length of IME composing string
// which will be replaced by new one.
// If (resultingDocLength) is at or over max, cancel the insert
// If (resultingDocLength) + (length of input) > max,
// set aOutString to subset of inString so length = max
@ -1324,7 +1327,10 @@ nsTextEditRules::TruncateInsertionIfNeeded(nsISelection *aSelection,
if (NS_FAILED(res)) { return res; }
PRInt32 selectionLength = end-start;
if (selectionLength<0) { selectionLength *= (-1); }
PRInt32 resultingDocLength = docLength - selectionLength;
PRInt32 oldCompStrLength;
res = mEditor->GetIMEBufferLength(&oldCompStrLength);
if (NS_FAILED(res)) { return res; }
PRInt32 resultingDocLength = docLength - selectionLength - oldCompStrLength;
if (resultingDocLength >= aMaxLength)
{
aOutString->SetLength(0);