diff --git a/mozilla/editor/libeditor/base/nsEditor.cpp b/mozilla/editor/libeditor/base/nsEditor.cpp index fd0895cccec..e73e9ec5820 100644 --- a/mozilla/editor/libeditor/base/nsEditor.cpp +++ b/mozilla/editor/libeditor/base/nsEditor.cpp @@ -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 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 &parentSelectedNode, PRInt32& offsetOfNewNode) { diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h index c4348bf2f97..5a6ee34a7db 100644 --- a/mozilla/editor/libeditor/base/nsEditor.h +++ b/mozilla/editor/libeditor/base/nsEditor.h @@ -489,6 +489,9 @@ public: nsresult GetLastEditableNode(nsIDOMNode *aRoot, nsCOMPtr *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 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 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 diff --git a/mozilla/editor/libeditor/base/nsEditorUtils.cpp b/mozilla/editor/libeditor/base/nsEditorUtils.cpp index f07ec717b5c..b9ac4359008 100644 --- a/mozilla/editor/libeditor/base/nsEditorUtils.cpp +++ b/mozilla/editor/libeditor/base/nsEditorUtils.cpp @@ -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 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 pCon(do_QueryInterface(parent)); + nsCOMPtr 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; +} diff --git a/mozilla/editor/libeditor/base/nsEditorUtils.h b/mozilla/editor/libeditor/base/nsEditorUtils.h index c78918064b9..6c11b289269 100644 --- a/mozilla/editor/libeditor/base/nsEditorUtils.h +++ b/mozilla/editor/libeditor/base/nsEditorUtils.h @@ -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__ diff --git a/mozilla/editor/libeditor/base/nsIEditProperty.h b/mozilla/editor/libeditor/base/nsIEditProperty.h index 1440190016b..94e95a00762 100644 --- a/mozilla/editor/libeditor/base/nsIEditProperty.h +++ b/mozilla/editor/libeditor/base/nsIEditProperty.h @@ -167,6 +167,7 @@ public: static nsIAtom *cssVerticalAlign; static nsIAtom *cssWhitespace; static nsIAtom *cssWidth; + static nsIAtom *cssMozUserSelect; static nsIAtom *cssPxUnit; diff --git a/mozilla/editor/libeditor/base/nsSelectionState.cpp b/mozilla/editor/libeditor/base/nsSelectionState.cpp index c8f0db9265a..956d2598413 100644 --- a/mozilla/editor/libeditor/base/nsSelectionState.cpp +++ b/mozilla/editor/libeditor/base/nsSelectionState.cpp @@ -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; iendNode.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 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; diff --git a/mozilla/editor/libeditor/html/nsEditProperty.cpp b/mozilla/editor/libeditor/html/nsEditProperty.cpp index a40220f51ed..9ad88c3fc8f 100644 --- a/mozilla/editor/libeditor/html/nsEditProperty.cpp +++ b/mozilla/editor/libeditor/html/nsEditProperty.cpp @@ -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); diff --git a/mozilla/editor/libeditor/html/nsHTMLDataTransfer.cpp b/mozilla/editor/libeditor/html/nsHTMLDataTransfer.cpp index d9eabe31566..f8b298d9c36 100644 --- a/mozilla/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -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; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index f7fe9a87583..243ce59519f 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -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 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 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 *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 *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 *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 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 brNode; res = mHTMLEditor->CopyLastEditableChildStyles(prevItem, aListItem, getter_AddRefs(brNode)); if (NS_FAILED(res)) return res; - if (brNode) { + if (brNode) + { nsCOMPtr brParent; PRInt32 offset; res = nsEditor::GetNodeLocation(brNode, address_of(brParent), &offset); return aSelection->Collapse(brParent, offset); } } + else + { + nsWSRunObject wsObj(mHTMLEditor, aListItem, 0); + nsCOMPtr 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 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& 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; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditUtils.cpp b/mozilla/editor/libeditor/html/nsHTMLEditUtils.cpp index 5b9f6813e7f..ded7b69e454 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditUtils.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditUtils.cpp @@ -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 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 pCon(do_QueryInterface(parent)); - nsCOMPtr 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) { diff --git a/mozilla/editor/libeditor/html/nsHTMLEditUtils.h b/mozilla/editor/libeditor/html/nsHTMLEditUtils.h index 694b46b112b..52cc7dd0b92 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditUtils.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditUtils.h @@ -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); }; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 29445e1e758..899262fe842 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -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 selectAllNode = FindUserSelectAllNode(aNode); + + if (selectAllNode) + { + return nsEditor::DeleteNode(selectAllNode); + } + return nsEditor::DeleteNode(aNode); +} + +NS_IMETHODIMP nsHTMLEditor::DeleteText(nsIDOMCharacterData *aTextNode, + PRUint32 aOffset, + PRUint32 aLength) +{ + nsCOMPtr 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 nsHTMLEditor::FindUserSelectAllNode(nsIDOMNode *aNode) +{ + nsCOMPtr resultNode; // starts out empty + nsCOMPtr 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 tmp; + node->GetParentNode(getter_AddRefs(tmp)); + node = tmp; + } + + return resultNode; +} static nsresult SetSelectionAroundHeadChildren(nsCOMPtr aSelection, nsWeakPtr aDocWeak) { @@ -5186,7 +5240,7 @@ nsHTMLEditor::GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr *aOu nsCOMPtr child; nsresult res = NS_OK; child = GetLeftmostChild(aNode); - while (child && (!IsEditable(child) || !nsHTMLEditUtils::IsLeafNode(child))) + while (child && (!IsEditable(child) || !nsEditorUtils::IsLeafNode(child))) { nsCOMPtr tmp; res = GetNextHTMLNode(child, address_of(tmp)); @@ -5194,7 +5248,7 @@ nsHTMLEditor::GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr *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 *aOut nsCOMPtr 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 tmp; res = GetPriorHTMLNode(child, address_of(tmp)); @@ -5228,7 +5282,7 @@ nsHTMLEditor::GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr *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; diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index cb9c0001f1f..76236378276 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -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 *ioParent, PRInt32 *ioOffset, PRBool aNoEmptyNodes); + nsCOMPtr FindUserSelectAllNode(nsIDOMNode *aNode); /** returns the absolute position of the end points of aSelection diff --git a/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp b/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp index eff1009b673..06dbcbc125c 100644 --- a/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/mozilla/editor/libeditor/text/nsPlaintextEditor.cpp @@ -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(); diff --git a/mozilla/editor/libeditor/text/nsPlaintextEditor.h b/mozilla/editor/libeditor/text/nsPlaintextEditor.h index dbc1cac4543..8143ca477bb 100644 --- a/mozilla/editor/libeditor/text/nsPlaintextEditor.h +++ b/mozilla/editor/libeditor/text/nsPlaintextEditor.h @@ -251,7 +251,6 @@ protected: nsCOMPtr mCompositionListenerP; nsCOMPtr mDragListenerP; nsCOMPtr mFocusListenerP; - PRBool mIsComposing; PRBool mWrapToWindow; PRInt32 mWrapColumn; PRInt32 mMaxTextLength; diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index d7a3e3b35bc..07835dd23b9 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -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);