mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
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:
parent
67761ee6a7
commit
18d72537a9
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -167,6 +167,7 @@ public:
|
||||
static nsIAtom *cssVerticalAlign;
|
||||
static nsIAtom *cssWhitespace;
|
||||
static nsIAtom *cssWidth;
|
||||
static nsIAtom *cssMozUserSelect;
|
||||
|
||||
|
||||
static nsIAtom *cssPxUnit;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -251,7 +251,6 @@ protected:
|
||||
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mFocusListenerP;
|
||||
PRBool mIsComposing;
|
||||
PRBool mWrapToWindow;
|
||||
PRInt32 mWrapColumn;
|
||||
PRInt32 mMaxTextLength;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user