зеркало из https://github.com/mozilla/pjs.git
revised rules system api to include "handled" parameter and ceased to overload the meaning of the "cancel" parameter; added TypedText() method to editor, editorshell, and logging, so that logging will work properly with typing; coallesce deletions for undo purposes r=buster@netscape.com
This commit is contained in:
Родитель
482cfdd0c9
Коммит
62652e2962
|
@ -112,8 +112,9 @@ NS_IMETHODIMP PlaceholderTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransact
|
|||
if (gNoisy) { printf("Placeholder txn assimilated %p\n", aTransaction); }
|
||||
}
|
||||
else
|
||||
{ // merge typing transactions if the selection matches
|
||||
if (mName.get() == nsHTMLEditor::gTypingTxnName)
|
||||
{ // merge typing or deletion transactions if the selection matches
|
||||
if ( (mName.get() == nsHTMLEditor::gTypingTxnName) ||
|
||||
(mName.get() == nsHTMLEditor::gDeleteTxnName) )
|
||||
{
|
||||
nsCOMPtr<nsIAbsorbingTransaction> plcTxn;// = do_QueryInterface(editTxn);
|
||||
// cant do_QueryInterface() above due to our broken transaction interfaces.
|
||||
|
@ -123,7 +124,7 @@ NS_IMETHODIMP PlaceholderTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransact
|
|||
{
|
||||
nsIAtom *atom;
|
||||
plcTxn->GetTxnName(&atom);
|
||||
if (atom && (atom == nsHTMLEditor::gTypingTxnName))
|
||||
if (atom && (atom == mName.get()))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> otherTxnStartNode;
|
||||
PRInt32 otherTxnStartOffset;
|
||||
|
@ -167,8 +168,9 @@ NS_IMETHODIMP PlaceholderTxn::EndPlaceHolderBatch()
|
|||
if (plcTxn) plcTxn->EndPlaceHolderBatch();
|
||||
}
|
||||
|
||||
// if we are a typing transaction, remember our selection state
|
||||
if (mName.get() == nsHTMLEditor::gTypingTxnName)
|
||||
// if we are a typing or deleting transaction, remember our selection state
|
||||
if ( (mName.get() == nsHTMLEditor::gTypingTxnName) ||
|
||||
(mName.get() == nsHTMLEditor::gDeleteTxnName) )
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
|
|
@ -44,7 +44,7 @@ class nsEditRules
|
|||
{
|
||||
public:
|
||||
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags)=0;
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel)=0;
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled)=0;
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags)=0;
|
||||
|
|
|
@ -563,7 +563,7 @@ nsEditor::BeginPlaceHolderTransaction(nsIAtom *aName)
|
|||
PRBool collapsed;
|
||||
res = selection->GetIsCollapsed(&collapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (collapsed) // we cant merge with previous typing if selection not collapsed
|
||||
if (collapsed) // we cant merge with previous typing/deleting if selection not collapsed
|
||||
{
|
||||
// need to remember colapsed selection point to Init the placeholder with later.
|
||||
// this is because we dont actually make the placeholder until we need it, and we
|
||||
|
|
|
@ -617,11 +617,11 @@ protected:
|
|||
nsCOMPtr<nsITransactionManager> mTxnMgr;
|
||||
nsCOMPtr<nsIEditProperty> mEditProperty;
|
||||
nsCOMPtr<nsICSSStyleSheet> mLastStyleSheet; // is owning this dangerous?
|
||||
nsWeakPtr mPlaceHolderTxn;
|
||||
nsIAtom *mPlaceHolderName;
|
||||
PRInt32 mPlaceHolderBatch;
|
||||
nsCOMPtr<nsIDOMNode> mTxnStartNode;
|
||||
PRInt32 mTxnStartOffset;
|
||||
nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes
|
||||
nsIAtom *mPlaceHolderName; // name of placeholder transaction
|
||||
PRInt32 mPlaceHolderBatch; // nesting count for batching
|
||||
nsCOMPtr<nsIDOMNode> mTxnStartNode; // saved selection info to pass to placeholder at init time
|
||||
PRInt32 mTxnStartOffset; // " " " "
|
||||
|
||||
//
|
||||
// data necessary to build IME transactions
|
||||
|
|
|
@ -1782,6 +1782,32 @@ nsEditorShell::DeleteSelection(PRInt32 action)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* This routine should only be called when playing back a log */
|
||||
NS_IMETHODIMP
|
||||
nsEditorShell::TypedText(const PRUnichar *aTextToInsert, PRInt32 aAction)
|
||||
{
|
||||
nsresult err = NS_NOINTERFACE;
|
||||
|
||||
nsAutoString textToInsert(aTextToInsert);
|
||||
|
||||
switch (mEditorType)
|
||||
{
|
||||
case ePlainTextEditorType:
|
||||
case eHTMLTextEditorType:
|
||||
{
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
if (htmlEditor)
|
||||
err = htmlEditor->TypedText(textToInsert, aAction);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err = NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorShell::InsertText(const PRUnichar *textToInsert)
|
||||
|
|
|
@ -72,12 +72,15 @@ nsHTMLEditRules::~nsHTMLEditRules()
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
nsRulesInfo *aInfo,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aInfo || !aCancel)
|
||||
if (!aInfo || !aCancel || !aHandled)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
@ -87,30 +90,31 @@ nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
aHandled,
|
||||
info->inString,
|
||||
info->outString,
|
||||
info->typeInState,
|
||||
info->maxLength);
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
return WillInsertBreak(aSelection, aCancel, aHandled);
|
||||
case kDeleteSelection:
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel);
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel, aHandled);
|
||||
case kMakeList:
|
||||
return WillMakeList(aSelection, info->bOrdered, aCancel);
|
||||
return WillMakeList(aSelection, info->bOrdered, aCancel, aHandled);
|
||||
case kIndent:
|
||||
return WillIndent(aSelection, aCancel);
|
||||
return WillIndent(aSelection, aCancel, aHandled);
|
||||
case kOutdent:
|
||||
return WillOutdent(aSelection, aCancel);
|
||||
return WillOutdent(aSelection, aCancel, aHandled);
|
||||
case kAlign:
|
||||
return WillAlign(aSelection, info->alignType, aCancel);
|
||||
return WillAlign(aSelection, info->alignType, aCancel, aHandled);
|
||||
case kMakeBasicBlock:
|
||||
return WillMakeBasicBlock(aSelection, info->blockType, aCancel);
|
||||
return WillMakeBasicBlock(aSelection, info->blockType, aCancel, aHandled);
|
||||
case kRemoveList:
|
||||
return WillRemoveList(aSelection, info->bOrdered, aCancel);
|
||||
return WillRemoveList(aSelection, info->bOrdered, aCancel, aHandled);
|
||||
case kInsertElement:
|
||||
return WillInsert(aSelection, aCancel);
|
||||
}
|
||||
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel);
|
||||
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel, aHandled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,14 +147,16 @@ nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection,
|
|||
nsresult
|
||||
nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
PRInt32 aMaxLength)
|
||||
{ if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
{ if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
nsresult res;
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
PRInt32 selOffset;
|
||||
|
@ -176,7 +182,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
|
||||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
// split any mailcites in the way
|
||||
if (mFlags & nsIHTMLEditor::eEditorMailMask)
|
||||
|
@ -277,23 +283,23 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
// is it a solo tab?
|
||||
if (partialString == "\t" )
|
||||
{
|
||||
res = InsertTab(aSelection,&bCancel,outString);
|
||||
res = InsertTab(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo space?
|
||||
else if (partialString == " ")
|
||||
{
|
||||
res = InsertSpace(aSelection,&bCancel,outString);
|
||||
res = InsertSpace(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo nbsp?
|
||||
else if (partialString == nbspStr)
|
||||
{
|
||||
res = InsertSpace(aSelection,&bCancel,outString);
|
||||
res = InsertSpace(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo return?
|
||||
else if (partialString == "\n")
|
||||
|
@ -302,7 +308,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
}
|
||||
else
|
||||
{
|
||||
res = DoTextInsertion(aSelection, aCancel, &partialString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, &partialString, typeInState);
|
||||
}
|
||||
if (NS_FAILED(res)) return res;
|
||||
pos = theString.FindCharInSet(specialChars);
|
||||
|
@ -312,11 +318,12 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsresult res;
|
||||
res = WillInsert(aSelection, aCancel);
|
||||
|
@ -372,7 +379,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
if (isPRE)
|
||||
{
|
||||
nsString theString = "\n";
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return mEditor->InsertTextImpl(theString);
|
||||
}
|
||||
|
||||
|
@ -415,7 +422,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
res = mEditor->SetAttribute(brElem, "type", "_moz");
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
else if (bIsMozDiv && AtStartOfBlock(node, offset, blockParent))
|
||||
{
|
||||
|
@ -442,21 +449,21 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
if (!newDiv || !IsMozDiv(newDiv)) return NS_ERROR_FAILURE;
|
||||
res = aSelection->Collapse(newDiv, 0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
|
||||
// headers: close (or split) header
|
||||
else if (IsHeader(blockParent))
|
||||
{
|
||||
res = ReturnInHeader(aSelection, blockParent, node, offset);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// paragraphs: special rules to look for <br>s
|
||||
else if (IsParagraph(blockParent))
|
||||
{
|
||||
res = ReturnInParagraph(aSelection, blockParent, node, offset, aCancel);
|
||||
res = ReturnInParagraph(aSelection, blockParent, node, offset, aCancel, aHandled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -464,7 +471,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
else if (IsListItem(blockParent))
|
||||
{
|
||||
res = ReturnInListItem(aSelection, blockParent, node, offset);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -474,11 +481,15 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aAction,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// if there is only bogus content, cancel the operation
|
||||
if (mBogusNode)
|
||||
|
@ -542,7 +553,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
nsCOMPtr<nsIDOMNode> topParent;
|
||||
leftParent->GetParentNode(getter_AddRefs(topParent));
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = JoinNodesSmart(leftParent,rightParent,&selNode,&selOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// fix up selection
|
||||
|
@ -582,7 +593,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
nsCOMPtr<nsIDOMNode> topParent;
|
||||
leftParent->GetParentNode(getter_AddRefs(topParent));
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = JoinNodesSmart(leftParent,rightParent,&selNode,&selOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// fix up selection
|
||||
|
@ -689,7 +700,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
if (IsParagraph(leftParent))
|
||||
{
|
||||
// first delete the selection
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = mEditor->DeleteSelectionImpl(aAction);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// then join para's, insert break
|
||||
|
@ -702,7 +713,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
if (IsListItem(leftParent) || IsHeader(leftParent))
|
||||
{
|
||||
// first delete the selection
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = mEditor->DeleteSelectionImpl(aAction);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// join blocks
|
||||
|
@ -723,9 +734,12 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection,
|
||||
PRBool aOrdered,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -733,6 +747,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsAutoString blockType("ul");
|
||||
if (aOrdered) blockType = "ol";
|
||||
|
@ -752,7 +767,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kMakeList);
|
||||
|
@ -964,11 +979,15 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection,
|
||||
PRBool aOrdered,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoString blockType("ul");
|
||||
if (aOrdered) blockType = "ol";
|
||||
|
@ -1053,11 +1072,15 @@ nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrdered, PR
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection,
|
||||
const nsString *aBlockType,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
PRBool makeEmpty;
|
||||
nsresult res = ShouldMakeEmptyBlock(aSelection, aBlockType, &makeEmpty);
|
||||
|
@ -1067,7 +1090,7 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString
|
|||
|
||||
// else it's not that easy...
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kMakeBasicBlock);
|
||||
|
@ -1086,16 +1109,17 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool * aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
|
||||
|
@ -1194,11 +1218,12 @@ nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
nsresult res = NS_OK;
|
||||
|
@ -1302,9 +1327,12 @@ nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection,
|
||||
const nsString *alignType,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -1312,7 +1340,8 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignTyp
|
|||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
|
||||
PRBool outMakeEmpty;
|
||||
|
@ -1325,7 +1354,7 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignTyp
|
|||
// this basically just expands the range to include the immediate
|
||||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kAlign);
|
||||
|
@ -2475,7 +2504,6 @@ nsHTMLEditRules::InsertContainerAbove(nsIDOMNode *inNode,
|
|||
//
|
||||
nsresult
|
||||
nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
nsString *outString)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
|
@ -2538,7 +2566,6 @@ nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
|
|||
//
|
||||
nsresult
|
||||
nsHTMLEditRules::InsertSpace(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
nsString *outString)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
|
@ -2650,10 +2677,13 @@ nsHTMLEditRules::ReturnInParagraph(nsIDOMSelection *aSelection,
|
|||
nsIDOMNode *aHeader,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aHeader || !aNode || !aCancel) return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aHeader || !aNode || !aCancel || !aHandled)
|
||||
{ return NS_ERROR_NULL_POINTER; }
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> sibling;
|
||||
nsresult res = NS_OK;
|
||||
|
@ -3308,6 +3338,7 @@ nsHTMLEditRules::CleanUpSelection(nsIDOMSelection *aSelection)
|
|||
isupports = do_QueryInterface(node);
|
||||
arrayOfNodes->AppendElement(isupports);
|
||||
}
|
||||
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual ~nsHTMLEditRules();
|
||||
|
||||
// nsEditRules methods
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
|
||||
protected:
|
||||
|
@ -49,24 +49,26 @@ protected:
|
|||
// nsHTMLEditRules implementation methods
|
||||
nsresult WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
PRInt32 aMaxLength);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction, PRBool *aCancel);
|
||||
nsresult WillMakeList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel);
|
||||
nsresult WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel);
|
||||
nsresult WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel);
|
||||
nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction,
|
||||
PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillMakeList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel, PRBool *aHandled);
|
||||
|
||||
nsresult InsertTab(nsIDOMSelection *aSelection, PRBool *aCancel, nsString *outString);
|
||||
nsresult InsertSpace(nsIDOMSelection *aSelection, PRBool *aCancel, nsString *outString);
|
||||
nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString);
|
||||
nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString);
|
||||
|
||||
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
|
||||
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel);
|
||||
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult ReturnInListItem(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
|
||||
|
||||
// helper methods
|
||||
|
|
|
@ -113,6 +113,7 @@ static char hrefText[] = "href";
|
|||
static char anchorTxt[] = "anchor";
|
||||
static char namedanchorText[] = "namedanchor";
|
||||
nsIAtom *nsHTMLEditor::gTypingTxnName;
|
||||
nsIAtom *nsHTMLEditor::gDeleteTxnName;
|
||||
|
||||
|
||||
#define IsLink(s) (s.EqualsIgnoreCase(hrefText))
|
||||
|
@ -211,6 +212,8 @@ nsHTMLEditor::nsHTMLEditor()
|
|||
// NS_INIT_REFCNT();
|
||||
if (!gTypingTxnName)
|
||||
gTypingTxnName = NS_NewAtom("Typing");
|
||||
if (!gDeleteTxnName)
|
||||
gDeleteTxnName = NS_NewAtom("Deleting");
|
||||
}
|
||||
|
||||
nsHTMLEditor::~nsHTMLEditor()
|
||||
|
@ -559,8 +562,6 @@ NS_IMETHODIMP nsHTMLEditor::EditorKeyPress(nsIDOMUIEvent* aKeyEvent)
|
|||
PRBool isShift, ctrlKey, altKey, metaKey;
|
||||
nsresult res;
|
||||
|
||||
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
|
||||
|
||||
if (!aKeyEvent) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
|
||||
|
@ -584,21 +585,54 @@ NS_IMETHODIMP nsHTMLEditor::EditorKeyPress(nsIDOMUIEvent* aKeyEvent)
|
|||
}
|
||||
else if (keyCode == nsIDOMUIEvent::DOM_VK_RETURN)
|
||||
{
|
||||
nsAutoString empty;
|
||||
if (isShift && !(mFlags&eEditorPlaintextBit))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
return InsertBR(&brNode); // only inserts a br node
|
||||
return TypedText(empty, eTypedBR); // only inserts a br node
|
||||
}
|
||||
else
|
||||
return InsertBreak(); // uses rules to figure out what to insert
|
||||
{
|
||||
return TypedText(empty, eTypedBreak); // uses rules to figure out what to insert
|
||||
}
|
||||
}
|
||||
else // normal typing
|
||||
{
|
||||
nsAutoString key(character);
|
||||
return TypedText(key, eTypedText);
|
||||
}
|
||||
|
||||
nsAutoString key(character);
|
||||
return InsertText(key);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* This routine is needed to provide a bottleneck for typing for logging
|
||||
purposes. Can't use EditorKeyPress() (above) for that since it takes
|
||||
a nsIDOMUIEvent* parameter. So instead we pass enough info through
|
||||
to TypedText() to determine what action to take, but without passing
|
||||
an event.
|
||||
*/
|
||||
NS_IMETHODIMP nsHTMLEditor::TypedText(const nsString& aString, PRInt32 aAction)
|
||||
{
|
||||
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case eTypedText:
|
||||
{
|
||||
return InsertText(aString);
|
||||
}
|
||||
case eTypedBR:
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
return InsertBR(&brNode); // only inserts a br node
|
||||
}
|
||||
case eTypedBreak:
|
||||
{
|
||||
return InsertBreak(); // uses rules to figure out what to insert
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled)
|
||||
{
|
||||
if (!outHandled) return NS_ERROR_NULL_POINTER;
|
||||
|
@ -739,10 +773,11 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
|||
result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kSetTextProperty);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
selection->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -836,6 +871,9 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
|||
// for setting a compound selection yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -994,11 +1032,11 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr
|
|||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kRemoveTextProperty);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (PR_FALSE==cancel)
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
selection->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -1080,6 +1118,9 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr
|
|||
ResetTextSelectionForRange(parentForSelection, rangeStartOffset, rangeEndOffset, selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -1137,14 +1178,10 @@ NS_IMETHODIMP nsHTMLEditor::DeleteSelection(nsIEditor::ESelectionCollapseDirecti
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// unnamed placeholder txns dont merge, but they do get sucked
|
||||
// into placeholders that they are nested in. So this delte wont
|
||||
// merge with other deletes, but if it happens in the course of
|
||||
// a typing placehilder context, it will be consumed by that.
|
||||
// This is the desired behavior.
|
||||
nsAutoPlaceHolderBatch batch(this, nsnull);
|
||||
// delete placeholder txns merge.
|
||||
nsAutoPlaceHolderBatch batch(this, gDeleteTxnName);
|
||||
|
||||
// pre-process
|
||||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1153,10 +1190,14 @@ NS_IMETHODIMP nsHTMLEditor::DeleteSelection(nsIEditor::ESelectionCollapseDirecti
|
|||
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kDeleteSelection);
|
||||
ruleInfo.collapsedAction = aAction;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
result = DeleteSelectionImpl(aAction);
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -1169,30 +1210,32 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoPlaceHolderBatch batch(this, nsnull);
|
||||
|
||||
// pre-process
|
||||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsAutoString resultString;
|
||||
PlaceholderTxn *placeholderTxn=nsnull;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertText);
|
||||
// ruleInfo.placeTxn = &placeholderTxn;
|
||||
ruleInfo.inString = &aStringToInsert;
|
||||
ruleInfo.outString = &resultString;
|
||||
ruleInfo.typeInState = *mTypeInState;
|
||||
ruleInfo.maxLength = mMaxTextLength;
|
||||
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
result = InsertTextImpl(resultString);
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
// if (placeholderTxn)
|
||||
// placeholderTxn->SetAbsorb(PR_FALSE); // this ends the merging of txns into placeholderTxn
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1333,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1298,8 +1341,9 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertBreak);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(res)))
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
// create the new BR node
|
||||
nsCOMPtr<nsIDOMNode> newNode;
|
||||
|
@ -1350,6 +1394,9 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
}
|
||||
|
@ -1374,106 +1421,110 @@ nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
// hand off to the rules system, see if it has anything to say about this
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertElement);
|
||||
ruleInfo.insertElement = aElement;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (aDeleteSelection)
|
||||
if (!handled)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
PRInt32 tempOffset;
|
||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);
|
||||
if (!NS_SUCCEEDED(result))
|
||||
return result;
|
||||
}
|
||||
|
||||
// If deleting, selection will be collapsed.
|
||||
// so if not, we collapse it
|
||||
if (!aDeleteSelection)
|
||||
{
|
||||
// Named Anchor is a special case,
|
||||
// We collapse to insert element BEFORE the selection
|
||||
// For all other tags, we insert AFTER the selection
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
if (IsNamedAnchorNode(node))
|
||||
if (aDeleteSelection)
|
||||
{
|
||||
selection->CollapseToStart();
|
||||
} else {
|
||||
selection->CollapseToEnd();
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
PRInt32 tempOffset;
|
||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);
|
||||
if (!NS_SUCCEEDED(result))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentSelectedNode;
|
||||
PRInt32 offsetForInsert;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));
|
||||
// XXX: ERROR_HANDLING bad XPCOM usage
|
||||
if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode)
|
||||
{
|
||||
// If deleting, selection will be collapsed.
|
||||
// so if not, we collapse it
|
||||
if (!aDeleteSelection)
|
||||
{
|
||||
// Named Anchor is a special case,
|
||||
// We collapse to insert element BEFORE the selection
|
||||
// For all other tags, we insert AFTER the selection
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
if (IsNamedAnchorNode(node))
|
||||
{
|
||||
selection->CollapseToStart();
|
||||
} else {
|
||||
selection->CollapseToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentSelectedNode;
|
||||
PRInt32 offsetForInsert;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));
|
||||
// XXX: ERROR_HANDLING bad XPCOM usage
|
||||
if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode)
|
||||
{
|
||||
#ifdef DEBUG_cmanske
|
||||
{
|
||||
nsAutoString name;
|
||||
parentSelectedNode->GetNodeName(name);
|
||||
printf("InsertElement: Anchor node of selection: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf(" Offset: %d\n", offsetForInsert);
|
||||
}
|
||||
{
|
||||
nsAutoString name;
|
||||
parentSelectedNode->GetNodeName(name);
|
||||
printf("InsertElement: Anchor node of selection: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf(" Offset: %d\n", offsetForInsert);
|
||||
}
|
||||
#endif
|
||||
nsAutoString tagName;
|
||||
aElement->GetNodeName(tagName);
|
||||
tagName.ToLowerCase();
|
||||
nsCOMPtr<nsIDOMNode> parent = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> topChild = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString parentTagName;
|
||||
PRBool isRoot;
|
||||
nsAutoString tagName;
|
||||
aElement->GetNodeName(tagName);
|
||||
tagName.ToLowerCase();
|
||||
nsCOMPtr<nsIDOMNode> parent = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> topChild = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString parentTagName;
|
||||
PRBool isRoot;
|
||||
|
||||
// Search up the parent chain to find a suitable container
|
||||
while (!CanContainTag(parent, tagName))
|
||||
{
|
||||
// If the current parent is a root (body or table cell)
|
||||
// then go no further - we can't insert
|
||||
parent->GetNodeName(parentTagName);
|
||||
res = IsRootTag(parentTagName, isRoot);
|
||||
if (!NS_SUCCEEDED(res) || isRoot)
|
||||
return NS_ERROR_FAILURE;
|
||||
// Get the next parent
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp)
|
||||
return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
// Search up the parent chain to find a suitable container
|
||||
while (!CanContainTag(parent, tagName))
|
||||
{
|
||||
// If the current parent is a root (body or table cell)
|
||||
// then go no further - we can't insert
|
||||
parent->GetNodeName(parentTagName);
|
||||
res = IsRootTag(parentTagName, isRoot);
|
||||
if (!NS_SUCCEEDED(res) || isRoot)
|
||||
return NS_ERROR_FAILURE;
|
||||
// Get the next parent
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp)
|
||||
return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
#ifdef DEBUG_cmanske
|
||||
{
|
||||
nsAutoString name;
|
||||
parent->GetNodeName(name);
|
||||
printf("Parent node to insert under: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
topChild->GetNodeName(name);
|
||||
printf("TopChild to split: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
}
|
||||
{
|
||||
nsAutoString name;
|
||||
parent->GetNodeName(name);
|
||||
printf("Parent node to insert under: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
topChild->GetNodeName(name);
|
||||
printf("TopChild to split: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
if (parent != topChild)
|
||||
{
|
||||
// we need to split some levels above the original selection parent
|
||||
res = SplitNodeDeep(topChild, parentSelectedNode, offsetForInsert, &offsetForInsert);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (parent != topChild)
|
||||
{
|
||||
// we need to split some levels above the original selection parent
|
||||
res = SplitNodeDeep(topChild, parentSelectedNode, offsetForInsert, &offsetForInsert);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
}
|
||||
// Now we can insert the new node
|
||||
res = InsertNode(aElement, parent, offsetForInsert);
|
||||
|
||||
// Set caret after element, but check for special case
|
||||
// of inserting table-related elements: set in first cell instead
|
||||
if (!SetCaretInTableCell(aElement))
|
||||
res = SetCaretAfterElement(aElement);
|
||||
|
||||
}
|
||||
// Now we can insert the new node
|
||||
res = InsertNode(aElement, parent, offsetForInsert);
|
||||
|
||||
// Set caret after element, but check for special case
|
||||
// of inserting table-related elements: set in first cell instead
|
||||
if (!SetCaretInTableCell(aElement))
|
||||
res = SetCaretAfterElement(aElement);
|
||||
|
||||
}
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1848,7 +1899,7 @@ nsHTMLEditor::InsertList(const nsString& aListType)
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
|
@ -1860,222 +1911,31 @@ nsHTMLEditor::InsertList(const nsString& aListType)
|
|||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
if (!handled)
|
||||
{
|
||||
// have to find a place to put the list
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aListType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// make a list
|
||||
nsCOMPtr<nsIDOMNode> newList;
|
||||
res = CreateNode(aListType, parent, offset, getter_AddRefs(newList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// make a list item
|
||||
nsAutoString tag("li");
|
||||
nsCOMPtr<nsIDOMNode> newItem;
|
||||
res = CreateNode(tag, newList, 0, getter_AddRefs(newItem));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
// XXX - revisit when layout is fixed
|
||||
res = selection->Collapse(newItem,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#if 0
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveList(const nsString& aListType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kRemoveList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// no default behavior for this yet. what would it mean?
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeBasicBlock);
|
||||
ruleInfo.blockType = &aBlockType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the block
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aBlockType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a block
|
||||
nsCOMPtr<nsIDOMNode> newBlock;
|
||||
res = CreateNode(aBlockType, parent, offset, getter_AddRefs(newBlock));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// xxx
|
||||
|
||||
// put a space in it so layout will draw it
|
||||
res = selection->Collapse(newBlock,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(nbsp);
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: Implement "outdent"
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::Indent(const nsString& aIndent)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kIndent);
|
||||
if (aIndent == "outdent")
|
||||
ruleInfo.action = nsHTMLEditRules::kOutdent;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Do default - insert a blockquote node if selection collapsed
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString inward("indent");
|
||||
if (aIndent == inward)
|
||||
{
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the blockquote
|
||||
// have to find a place to put the list
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString bq("blockquote");
|
||||
while ( !CanContainTag(parent, bq))
|
||||
|
||||
while ( !CanContainTag(parent, aListType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
|
@ -2090,13 +1950,20 @@ nsHTMLEditor::Indent(const nsString& aIndent)
|
|||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a blockquote
|
||||
nsCOMPtr<nsIDOMNode> newBQ;
|
||||
res = CreateNode(bq, parent, offset, getter_AddRefs(newBQ));
|
||||
// make a list
|
||||
nsCOMPtr<nsIDOMNode> newList;
|
||||
res = CreateNode(aListType, parent, offset, getter_AddRefs(newList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// make a list item
|
||||
nsAutoString tag("li");
|
||||
nsCOMPtr<nsIDOMNode> newItem;
|
||||
res = CreateNode(tag, newList, 0, getter_AddRefs(newItem));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
res = selection->Collapse(newBQ,0);
|
||||
// XXX - revisit when layout is fixed
|
||||
res = selection->Collapse(newItem,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#if 0
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -2105,9 +1972,205 @@ nsHTMLEditor::Indent(const nsString& aIndent)
|
|||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveList(const nsString& aListType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kRemoveList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// no default behavior for this yet. what would it mean?
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeBasicBlock);
|
||||
ruleInfo.blockType = &aBlockType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the block
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aBlockType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a block
|
||||
nsCOMPtr<nsIDOMNode> newBlock;
|
||||
res = CreateNode(aBlockType, parent, offset, getter_AddRefs(newBlock));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// xxx
|
||||
|
||||
// put a space in it so layout will draw it
|
||||
res = selection->Collapse(newBlock,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(nbsp);
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: Implement "outdent"
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::Indent(const nsString& aIndent)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kIndent);
|
||||
if (aIndent == "outdent")
|
||||
ruleInfo.action = nsHTMLEditRules::kOutdent;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
// Do default - insert a blockquote node if selection collapsed
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString inward("indent");
|
||||
if (aIndent == inward)
|
||||
{
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the blockquote
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString bq("blockquote");
|
||||
while ( !CanContainTag(parent, bq))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a blockquote
|
||||
nsCOMPtr<nsIDOMNode> newBQ;
|
||||
res = CreateNode(bq, parent, offset, getter_AddRefs(newBQ));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
res = selection->Collapse(newBQ,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2118,7 +2181,7 @@ nsHTMLEditor::Align(const nsString& aAlignType)
|
|||
{
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
|
@ -2127,8 +2190,11 @@ nsHTMLEditor::Align(const nsString& aAlignType)
|
|||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kAlign);
|
||||
ruleInfo.alignType = &aAlignType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(res))
|
||||
return res;
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -3284,8 +3350,8 @@ nsHTMLEditor::Undo(PRUint32 aCount)
|
|||
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
GetSelection(getter_AddRefs(selection));
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
|
||||
if (!cancel && NS_SUCCEEDED(result))
|
||||
{
|
||||
|
@ -3309,8 +3375,8 @@ nsHTMLEditor::Redo(PRUint32 aCount)
|
|||
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
GetSelection(getter_AddRefs(selection));
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
|
||||
if (!cancel && NS_SUCCEEDED(result))
|
||||
{
|
||||
|
@ -3441,14 +3507,14 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString,
|
|||
const nsString& aFormatType,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsString resultString;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kOutputText);
|
||||
ruleInfo.outString = &resultString;
|
||||
ruleInfo.outputFormat = &aFormatType;
|
||||
nsresult rv = mRules->WillDoAction(nsnull, &ruleInfo, &cancel);
|
||||
if (NS_FAILED(rv)) { return rv; }
|
||||
if (PR_TRUE==cancel)
|
||||
nsresult rv = mRules->WillDoAction(nsnull, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(rv)) { return rv; }
|
||||
if (handled)
|
||||
{ // this case will get triggered by password fields
|
||||
aOutputString = *(ruleInfo.outString);
|
||||
}
|
||||
|
@ -3680,10 +3746,10 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat
|
|||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertTextIME);
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (NS_FAILED(result)) return result;
|
||||
// we don't care if WillInsert said to cancel...
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(result)) return result;
|
||||
|
||||
result = SetInputMethodText(aCompositionString,aTextRangeList);
|
||||
if (NS_FAILED(result)) return result;
|
||||
mIMEBufferLength = aCompositionString.Length();
|
||||
|
@ -3694,6 +3760,7 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat
|
|||
ps->GetCaret(getter_AddRefs(caretP));
|
||||
caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed);
|
||||
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
|
||||
NS_IMETHOD EditorKeyPress(nsIDOMUIEvent* aKeyEvent);
|
||||
NS_IMETHOD TypedText(const nsString& aString, PRInt32 aAction);
|
||||
|
||||
NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty);
|
||||
NS_IMETHOD GetDocumentLength(PRInt32 *aCount);
|
||||
|
@ -482,6 +483,7 @@ protected:
|
|||
|
||||
public:
|
||||
static nsIAtom *gTypingTxnName;
|
||||
static nsIAtom *gDeleteTxnName;
|
||||
|
||||
// friends
|
||||
friend class nsHTMLEditRules;
|
||||
|
|
|
@ -155,6 +155,27 @@ nsHTMLEditorLog::DeleteSelection(nsIEditor::ESelectionCollapseDirection aAction)
|
|||
return nsHTMLEditor::DeleteSelection(aAction);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditorLog::TypedText(const nsString& aStringToInsert, PRInt32 aAction)
|
||||
{
|
||||
nsAutoHTMLEditorLogLock logLock(this);
|
||||
|
||||
if (!mLocked && mFileSpec)
|
||||
{
|
||||
PrintSelection();
|
||||
|
||||
Write("window.editorShell.TypedText(\"");
|
||||
PrintUnicode(aStringToInsert);
|
||||
Write("\", ");
|
||||
WriteInt("%d", aAction);
|
||||
Write(");\n");
|
||||
|
||||
Flush();
|
||||
}
|
||||
|
||||
return nsHTMLEditor::TypedText(aStringToInsert, aAction);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditorLog::InsertText(const nsString& aStringToInsert)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
NS_IMETHOD SetParagraphFormat(const nsString& aParagraphFormat);
|
||||
NS_IMETHOD RemoveInlineProperty(nsIAtom *aProperty, const nsString *aAttribute);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::ESelectionCollapseDirection aAction);
|
||||
NS_IMETHOD TypedText(const nsString& aString, PRInt32 aAction);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
NS_IMETHOD InsertBreak();
|
||||
NS_IMETHOD Undo(PRUint32 aCount);
|
||||
|
|
|
@ -121,12 +121,15 @@ nsTextEditRules::SetFlags(PRUint32 aFlags)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
nsRulesInfo *aInfo,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
// null selection is legal
|
||||
if (!aInfo || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aInfo || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
@ -134,10 +137,11 @@ nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
return WillInsertBreak(aSelection, aCancel, aHandled);
|
||||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
aCancel,
|
||||
aHandled,
|
||||
info->inString,
|
||||
info->outString,
|
||||
info->typeInState,
|
||||
|
@ -145,20 +149,21 @@ nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
case kInsertTextIME:
|
||||
return WillInsert(aSelection, aCancel);
|
||||
case kDeleteSelection:
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel);
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel, aHandled);
|
||||
case kUndo:
|
||||
return WillUndo(aSelection, aCancel);
|
||||
return WillUndo(aSelection, aCancel, aHandled);
|
||||
case kRedo:
|
||||
return WillRedo(aSelection, aCancel);
|
||||
return WillRedo(aSelection, aCancel, aHandled);
|
||||
case kSetTextProperty:
|
||||
return WillSetTextProperty(aSelection, aCancel);
|
||||
return WillSetTextProperty(aSelection, aCancel, aHandled);
|
||||
case kRemoveTextProperty:
|
||||
return WillRemoveTextProperty(aSelection, aCancel);
|
||||
return WillRemoveTextProperty(aSelection, aCancel, aHandled);
|
||||
case kOutputText:
|
||||
return WillOutputText(aSelection,
|
||||
info->outputFormat,
|
||||
info->outString,
|
||||
aCancel);
|
||||
aCancel,
|
||||
aHandled);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -239,10 +244,11 @@ nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
*aHandled = PR_FALSE;
|
||||
if (mFlags & nsIHTMLEditor::eEditorSingleLineMask) {
|
||||
*aCancel = PR_TRUE;
|
||||
}
|
||||
|
@ -261,19 +267,22 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *aInString,
|
||||
nsString *aOutString,
|
||||
TypeInState aTypeInState,
|
||||
PRInt32 aMaxLength)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
|
||||
if (!aSelection || !aCancel || !aHandled || !aInString || !aOutString)
|
||||
{return NS_ERROR_NULL_POINTER;}
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
nsresult res;
|
||||
|
||||
// initialize out params
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
*aOutString = *aInString;
|
||||
|
||||
// handle docs with a max length
|
||||
|
@ -576,8 +585,10 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
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"
|
||||
|
@ -594,8 +605,10 @@ nsTextEditRules::DidSetTextProperty(nsIDOMSelection *aSelection, nsresult aResul
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
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"
|
||||
|
@ -614,13 +627,15 @@ nsTextEditRules::DidRemoveTextProperty(nsIDOMSelection *aSelection, nsresult aRe
|
|||
nsresult
|
||||
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// if there is only bogus content, cancel the operation
|
||||
if (mBogusNode) {
|
||||
|
@ -745,12 +760,13 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -808,12 +824,13 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -869,25 +886,28 @@ nsresult
|
|||
nsTextEditRules::WillOutputText(nsIDOMSelection *aSelection,
|
||||
const nsString *aOutputFormat,
|
||||
nsString *aOutString,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
// null selection ok
|
||||
if (!aOutString || !aOutputFormat || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aOutString || !aOutputFormat || !aCancel || !aHandled)
|
||||
{ return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
if (PR_TRUE == aOutputFormat->Equals("text/plain"))
|
||||
{ // only use these rules for plain text output
|
||||
if (mFlags & nsIHTMLEditor::eEditorPasswordMask)
|
||||
{
|
||||
*aOutString = mPasswordText;
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
else if (mBogusNode)
|
||||
{ // this means there's no content, so output null string
|
||||
*aOutString = "";
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
// nsEditRules methods
|
||||
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags);
|
||||
|
@ -85,6 +85,7 @@ protected:
|
|||
// nsTextEditRules implementation methods
|
||||
nsresult WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
|
@ -92,7 +93,7 @@ protected:
|
|||
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
|
||||
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
|
@ -100,21 +101,22 @@ protected:
|
|||
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
PRBool *aCancel);
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled);
|
||||
nsresult DidDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
nsresult aResult);
|
||||
|
||||
nsresult WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidSetTextProperty(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidRemoveTextProperty(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
/** called prior to nsIEditor::OutputToString
|
||||
|
@ -127,7 +129,8 @@ protected:
|
|||
nsresult WillOutputText(nsIDOMSelection *aSelection,
|
||||
const nsString *aInFormat,
|
||||
nsString *aOutText,
|
||||
PRBool *aOutCancel);
|
||||
PRBool *aOutCancel,
|
||||
PRBool *aHandled);
|
||||
|
||||
nsresult DidOutputText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
|
|
|
@ -1782,6 +1782,32 @@ nsEditorShell::DeleteSelection(PRInt32 action)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* This routine should only be called when playing back a log */
|
||||
NS_IMETHODIMP
|
||||
nsEditorShell::TypedText(const PRUnichar *aTextToInsert, PRInt32 aAction)
|
||||
{
|
||||
nsresult err = NS_NOINTERFACE;
|
||||
|
||||
nsAutoString textToInsert(aTextToInsert);
|
||||
|
||||
switch (mEditorType)
|
||||
{
|
||||
case ePlainTextEditorType:
|
||||
case eHTMLTextEditorType:
|
||||
{
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
||||
if (htmlEditor)
|
||||
err = htmlEditor->TypedText(textToInsert, aAction);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err = NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorShell::InsertText(const PRUnichar *textToInsert)
|
||||
|
|
|
@ -146,6 +146,8 @@ interface nsIEditorShell : nsISupports
|
|||
void SetDocumentCharacterSet(in wstring characterSet);
|
||||
|
||||
/* Structure change */
|
||||
/* TypedText actionToTake param is an enum - values in nsIHTMLEditor.h */
|
||||
void TypedText(in wstring textToInsert, in PRInt32 actionToTake);
|
||||
void InsertText(in wstring textToInsert);
|
||||
void InsertSource(in wstring textToInsert);
|
||||
void InsertBreak();
|
||||
|
|
|
@ -112,8 +112,9 @@ NS_IMETHODIMP PlaceholderTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransact
|
|||
if (gNoisy) { printf("Placeholder txn assimilated %p\n", aTransaction); }
|
||||
}
|
||||
else
|
||||
{ // merge typing transactions if the selection matches
|
||||
if (mName.get() == nsHTMLEditor::gTypingTxnName)
|
||||
{ // merge typing or deletion transactions if the selection matches
|
||||
if ( (mName.get() == nsHTMLEditor::gTypingTxnName) ||
|
||||
(mName.get() == nsHTMLEditor::gDeleteTxnName) )
|
||||
{
|
||||
nsCOMPtr<nsIAbsorbingTransaction> plcTxn;// = do_QueryInterface(editTxn);
|
||||
// cant do_QueryInterface() above due to our broken transaction interfaces.
|
||||
|
@ -123,7 +124,7 @@ NS_IMETHODIMP PlaceholderTxn::Merge(PRBool *aDidMerge, nsITransaction *aTransact
|
|||
{
|
||||
nsIAtom *atom;
|
||||
plcTxn->GetTxnName(&atom);
|
||||
if (atom && (atom == nsHTMLEditor::gTypingTxnName))
|
||||
if (atom && (atom == mName.get()))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> otherTxnStartNode;
|
||||
PRInt32 otherTxnStartOffset;
|
||||
|
@ -167,8 +168,9 @@ NS_IMETHODIMP PlaceholderTxn::EndPlaceHolderBatch()
|
|||
if (plcTxn) plcTxn->EndPlaceHolderBatch();
|
||||
}
|
||||
|
||||
// if we are a typing transaction, remember our selection state
|
||||
if (mName.get() == nsHTMLEditor::gTypingTxnName)
|
||||
// if we are a typing or deleting transaction, remember our selection state
|
||||
if ( (mName.get() == nsHTMLEditor::gTypingTxnName) ||
|
||||
(mName.get() == nsHTMLEditor::gDeleteTxnName) )
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
|
|
@ -44,7 +44,7 @@ class nsEditRules
|
|||
{
|
||||
public:
|
||||
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags)=0;
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel)=0;
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled)=0;
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags)=0;
|
||||
|
|
|
@ -563,7 +563,7 @@ nsEditor::BeginPlaceHolderTransaction(nsIAtom *aName)
|
|||
PRBool collapsed;
|
||||
res = selection->GetIsCollapsed(&collapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (collapsed) // we cant merge with previous typing if selection not collapsed
|
||||
if (collapsed) // we cant merge with previous typing/deleting if selection not collapsed
|
||||
{
|
||||
// need to remember colapsed selection point to Init the placeholder with later.
|
||||
// this is because we dont actually make the placeholder until we need it, and we
|
||||
|
|
|
@ -617,11 +617,11 @@ protected:
|
|||
nsCOMPtr<nsITransactionManager> mTxnMgr;
|
||||
nsCOMPtr<nsIEditProperty> mEditProperty;
|
||||
nsCOMPtr<nsICSSStyleSheet> mLastStyleSheet; // is owning this dangerous?
|
||||
nsWeakPtr mPlaceHolderTxn;
|
||||
nsIAtom *mPlaceHolderName;
|
||||
PRInt32 mPlaceHolderBatch;
|
||||
nsCOMPtr<nsIDOMNode> mTxnStartNode;
|
||||
PRInt32 mTxnStartOffset;
|
||||
nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes
|
||||
nsIAtom *mPlaceHolderName; // name of placeholder transaction
|
||||
PRInt32 mPlaceHolderBatch; // nesting count for batching
|
||||
nsCOMPtr<nsIDOMNode> mTxnStartNode; // saved selection info to pass to placeholder at init time
|
||||
PRInt32 mTxnStartOffset; // " " " "
|
||||
|
||||
//
|
||||
// data necessary to build IME transactions
|
||||
|
|
|
@ -72,12 +72,15 @@ nsHTMLEditRules::~nsHTMLEditRules()
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
nsRulesInfo *aInfo,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aInfo || !aCancel)
|
||||
if (!aInfo || !aCancel || !aHandled)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
@ -87,30 +90,31 @@ nsHTMLEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
aHandled,
|
||||
info->inString,
|
||||
info->outString,
|
||||
info->typeInState,
|
||||
info->maxLength);
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
return WillInsertBreak(aSelection, aCancel, aHandled);
|
||||
case kDeleteSelection:
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel);
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel, aHandled);
|
||||
case kMakeList:
|
||||
return WillMakeList(aSelection, info->bOrdered, aCancel);
|
||||
return WillMakeList(aSelection, info->bOrdered, aCancel, aHandled);
|
||||
case kIndent:
|
||||
return WillIndent(aSelection, aCancel);
|
||||
return WillIndent(aSelection, aCancel, aHandled);
|
||||
case kOutdent:
|
||||
return WillOutdent(aSelection, aCancel);
|
||||
return WillOutdent(aSelection, aCancel, aHandled);
|
||||
case kAlign:
|
||||
return WillAlign(aSelection, info->alignType, aCancel);
|
||||
return WillAlign(aSelection, info->alignType, aCancel, aHandled);
|
||||
case kMakeBasicBlock:
|
||||
return WillMakeBasicBlock(aSelection, info->blockType, aCancel);
|
||||
return WillMakeBasicBlock(aSelection, info->blockType, aCancel, aHandled);
|
||||
case kRemoveList:
|
||||
return WillRemoveList(aSelection, info->bOrdered, aCancel);
|
||||
return WillRemoveList(aSelection, info->bOrdered, aCancel, aHandled);
|
||||
case kInsertElement:
|
||||
return WillInsert(aSelection, aCancel);
|
||||
}
|
||||
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel);
|
||||
return nsTextEditRules::WillDoAction(aSelection, aInfo, aCancel, aHandled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,14 +147,16 @@ nsHTMLEditRules::DidDoAction(nsIDOMSelection *aSelection,
|
|||
nsresult
|
||||
nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
PRInt32 aMaxLength)
|
||||
{ if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
{ if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
nsresult res;
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
PRInt32 selOffset;
|
||||
|
@ -176,7 +182,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
|
||||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
// split any mailcites in the way
|
||||
if (mFlags & nsIHTMLEditor::eEditorMailMask)
|
||||
|
@ -277,23 +283,23 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
// is it a solo tab?
|
||||
if (partialString == "\t" )
|
||||
{
|
||||
res = InsertTab(aSelection,&bCancel,outString);
|
||||
res = InsertTab(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo space?
|
||||
else if (partialString == " ")
|
||||
{
|
||||
res = InsertSpace(aSelection,&bCancel,outString);
|
||||
res = InsertSpace(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo nbsp?
|
||||
else if (partialString == nbspStr)
|
||||
{
|
||||
res = InsertSpace(aSelection,&bCancel,outString);
|
||||
res = InsertSpace(aSelection,outString);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = DoTextInsertion(aSelection, aCancel, outString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, outString, typeInState);
|
||||
}
|
||||
// is it a solo return?
|
||||
else if (partialString == "\n")
|
||||
|
@ -302,7 +308,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
}
|
||||
else
|
||||
{
|
||||
res = DoTextInsertion(aSelection, aCancel, &partialString, typeInState);
|
||||
res = DoTextInsertion(aSelection, &bCancel, &partialString, typeInState);
|
||||
}
|
||||
if (NS_FAILED(res)) return res;
|
||||
pos = theString.FindCharInSet(specialChars);
|
||||
|
@ -312,11 +318,12 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsresult res;
|
||||
res = WillInsert(aSelection, aCancel);
|
||||
|
@ -372,7 +379,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
if (isPRE)
|
||||
{
|
||||
nsString theString = "\n";
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return mEditor->InsertTextImpl(theString);
|
||||
}
|
||||
|
||||
|
@ -415,7 +422,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
res = mEditor->SetAttribute(brElem, "type", "_moz");
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
else if (bIsMozDiv && AtStartOfBlock(node, offset, blockParent))
|
||||
{
|
||||
|
@ -442,21 +449,21 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
if (!newDiv || !IsMozDiv(newDiv)) return NS_ERROR_FAILURE;
|
||||
res = aSelection->Collapse(newDiv, 0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
|
||||
// headers: close (or split) header
|
||||
else if (IsHeader(blockParent))
|
||||
{
|
||||
res = ReturnInHeader(aSelection, blockParent, node, offset);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// paragraphs: special rules to look for <br>s
|
||||
else if (IsParagraph(blockParent))
|
||||
{
|
||||
res = ReturnInParagraph(aSelection, blockParent, node, offset, aCancel);
|
||||
res = ReturnInParagraph(aSelection, blockParent, node, offset, aCancel, aHandled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -464,7 +471,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
else if (IsListItem(blockParent))
|
||||
{
|
||||
res = ReturnInListItem(aSelection, blockParent, node, offset);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -474,11 +481,15 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aAction,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// if there is only bogus content, cancel the operation
|
||||
if (mBogusNode)
|
||||
|
@ -542,7 +553,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
nsCOMPtr<nsIDOMNode> topParent;
|
||||
leftParent->GetParentNode(getter_AddRefs(topParent));
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = JoinNodesSmart(leftParent,rightParent,&selNode,&selOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// fix up selection
|
||||
|
@ -582,7 +593,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
nsCOMPtr<nsIDOMNode> topParent;
|
||||
leftParent->GetParentNode(getter_AddRefs(topParent));
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = JoinNodesSmart(leftParent,rightParent,&selNode,&selOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// fix up selection
|
||||
|
@ -689,7 +700,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
if (IsParagraph(leftParent))
|
||||
{
|
||||
// first delete the selection
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = mEditor->DeleteSelectionImpl(aAction);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// then join para's, insert break
|
||||
|
@ -702,7 +713,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
if (IsListItem(leftParent) || IsHeader(leftParent))
|
||||
{
|
||||
// first delete the selection
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
res = mEditor->DeleteSelectionImpl(aAction);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// join blocks
|
||||
|
@ -723,9 +734,12 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESe
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection,
|
||||
PRBool aOrdered,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -733,6 +747,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsAutoString blockType("ul");
|
||||
if (aOrdered) blockType = "ol";
|
||||
|
@ -752,7 +767,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kMakeList);
|
||||
|
@ -964,11 +979,15 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBo
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrdered, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection,
|
||||
PRBool aOrdered,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoString blockType("ul");
|
||||
if (aOrdered) blockType = "ol";
|
||||
|
@ -1053,11 +1072,15 @@ nsHTMLEditRules::WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrdered, PR
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection,
|
||||
const nsString *aBlockType,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
PRBool makeEmpty;
|
||||
nsresult res = ShouldMakeEmptyBlock(aSelection, aBlockType, &makeEmpty);
|
||||
|
@ -1067,7 +1090,7 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString
|
|||
|
||||
// else it's not that easy...
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kMakeBasicBlock);
|
||||
|
@ -1086,16 +1109,17 @@ nsHTMLEditRules::WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool * aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
|
||||
|
@ -1194,11 +1218,12 @@ nsHTMLEditRules::WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
// initialize out param
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
nsresult res = NS_OK;
|
||||
|
@ -1302,9 +1327,12 @@ nsHTMLEditRules::WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel)
|
||||
nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection,
|
||||
const nsString *alignType,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
nsresult res = WillInsert(aSelection, aCancel);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -1312,7 +1340,8 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignTyp
|
|||
// initialize out param
|
||||
// we want to ignore result of WillInsert()
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsAutoSelectionReset selectionResetter(aSelection);
|
||||
|
||||
PRBool outMakeEmpty;
|
||||
|
@ -1325,7 +1354,7 @@ nsHTMLEditRules::WillAlign(nsIDOMSelection *aSelection, const nsString *alignTyp
|
|||
// this basically just expands the range to include the immediate
|
||||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> arrayOfRanges;
|
||||
res = GetPromotedRanges(aSelection, &arrayOfRanges, kAlign);
|
||||
|
@ -2475,7 +2504,6 @@ nsHTMLEditRules::InsertContainerAbove(nsIDOMNode *inNode,
|
|||
//
|
||||
nsresult
|
||||
nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
nsString *outString)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
|
@ -2538,7 +2566,6 @@ nsHTMLEditRules::InsertTab(nsIDOMSelection *aSelection,
|
|||
//
|
||||
nsresult
|
||||
nsHTMLEditRules::InsertSpace(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
nsString *outString)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
|
@ -2650,10 +2677,13 @@ nsHTMLEditRules::ReturnInParagraph(nsIDOMSelection *aSelection,
|
|||
nsIDOMNode *aHeader,
|
||||
nsIDOMNode *aNode,
|
||||
PRInt32 aOffset,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aHeader || !aNode || !aCancel) return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aHeader || !aNode || !aCancel || !aHandled)
|
||||
{ return NS_ERROR_NULL_POINTER; }
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> sibling;
|
||||
nsresult res = NS_OK;
|
||||
|
@ -3308,6 +3338,7 @@ nsHTMLEditRules::CleanUpSelection(nsIDOMSelection *aSelection)
|
|||
isupports = do_QueryInterface(node);
|
||||
arrayOfNodes->AppendElement(isupports);
|
||||
}
|
||||
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual ~nsHTMLEditRules();
|
||||
|
||||
// nsEditRules methods
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
|
||||
protected:
|
||||
|
@ -49,24 +49,26 @@ protected:
|
|||
// nsHTMLEditRules implementation methods
|
||||
nsresult WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
PRInt32 aMaxLength);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction, PRBool *aCancel);
|
||||
nsresult WillMakeList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel);
|
||||
nsresult WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel);
|
||||
nsresult WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel);
|
||||
nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection, nsIEditor::ESelectionCollapseDirection aAction,
|
||||
PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillMakeList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillRemoveList(nsIDOMSelection *aSelection, PRBool aOrderd, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillIndent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillOutdent(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillAlign(nsIDOMSelection *aSelection, const nsString *alignType, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult WillMakeBasicBlock(nsIDOMSelection *aSelection, const nsString *aBlockType, PRBool *aCancel, PRBool *aHandled);
|
||||
|
||||
nsresult InsertTab(nsIDOMSelection *aSelection, PRBool *aCancel, nsString *outString);
|
||||
nsresult InsertSpace(nsIDOMSelection *aSelection, PRBool *aCancel, nsString *outString);
|
||||
nsresult InsertTab(nsIDOMSelection *aSelection, nsString *outString);
|
||||
nsresult InsertSpace(nsIDOMSelection *aSelection, nsString *outString);
|
||||
|
||||
nsresult ReturnInHeader(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
|
||||
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel);
|
||||
nsresult ReturnInParagraph(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult ReturnInListItem(nsIDOMSelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
|
||||
|
||||
// helper methods
|
||||
|
|
|
@ -113,6 +113,7 @@ static char hrefText[] = "href";
|
|||
static char anchorTxt[] = "anchor";
|
||||
static char namedanchorText[] = "namedanchor";
|
||||
nsIAtom *nsHTMLEditor::gTypingTxnName;
|
||||
nsIAtom *nsHTMLEditor::gDeleteTxnName;
|
||||
|
||||
|
||||
#define IsLink(s) (s.EqualsIgnoreCase(hrefText))
|
||||
|
@ -211,6 +212,8 @@ nsHTMLEditor::nsHTMLEditor()
|
|||
// NS_INIT_REFCNT();
|
||||
if (!gTypingTxnName)
|
||||
gTypingTxnName = NS_NewAtom("Typing");
|
||||
if (!gDeleteTxnName)
|
||||
gDeleteTxnName = NS_NewAtom("Deleting");
|
||||
}
|
||||
|
||||
nsHTMLEditor::~nsHTMLEditor()
|
||||
|
@ -559,8 +562,6 @@ NS_IMETHODIMP nsHTMLEditor::EditorKeyPress(nsIDOMUIEvent* aKeyEvent)
|
|||
PRBool isShift, ctrlKey, altKey, metaKey;
|
||||
nsresult res;
|
||||
|
||||
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
|
||||
|
||||
if (!aKeyEvent) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (NS_SUCCEEDED(aKeyEvent->GetKeyCode(&keyCode)) &&
|
||||
|
@ -584,21 +585,54 @@ NS_IMETHODIMP nsHTMLEditor::EditorKeyPress(nsIDOMUIEvent* aKeyEvent)
|
|||
}
|
||||
else if (keyCode == nsIDOMUIEvent::DOM_VK_RETURN)
|
||||
{
|
||||
nsAutoString empty;
|
||||
if (isShift && !(mFlags&eEditorPlaintextBit))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
return InsertBR(&brNode); // only inserts a br node
|
||||
return TypedText(empty, eTypedBR); // only inserts a br node
|
||||
}
|
||||
else
|
||||
return InsertBreak(); // uses rules to figure out what to insert
|
||||
{
|
||||
return TypedText(empty, eTypedBreak); // uses rules to figure out what to insert
|
||||
}
|
||||
}
|
||||
else // normal typing
|
||||
{
|
||||
nsAutoString key(character);
|
||||
return TypedText(key, eTypedText);
|
||||
}
|
||||
|
||||
nsAutoString key(character);
|
||||
return InsertText(key);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* This routine is needed to provide a bottleneck for typing for logging
|
||||
purposes. Can't use EditorKeyPress() (above) for that since it takes
|
||||
a nsIDOMUIEvent* parameter. So instead we pass enough info through
|
||||
to TypedText() to determine what action to take, but without passing
|
||||
an event.
|
||||
*/
|
||||
NS_IMETHODIMP nsHTMLEditor::TypedText(const nsString& aString, PRInt32 aAction)
|
||||
{
|
||||
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case eTypedText:
|
||||
{
|
||||
return InsertText(aString);
|
||||
}
|
||||
case eTypedBR:
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
return InsertBR(&brNode); // only inserts a br node
|
||||
}
|
||||
case eTypedBreak:
|
||||
{
|
||||
return InsertBreak(); // uses rules to figure out what to insert
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled)
|
||||
{
|
||||
if (!outHandled) return NS_ERROR_NULL_POINTER;
|
||||
|
@ -739,10 +773,11 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
|||
result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kSetTextProperty);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
selection->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -836,6 +871,9 @@ NS_IMETHODIMP nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
|||
// for setting a compound selection yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -994,11 +1032,11 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr
|
|||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kRemoveTextProperty);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (PR_FALSE==cancel)
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
PRBool isCollapsed;
|
||||
selection->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -1080,6 +1118,9 @@ NS_IMETHODIMP nsHTMLEditor::RemoveInlineProperty(nsIAtom *aProperty, const nsStr
|
|||
ResetTextSelectionForRange(parentForSelection, rangeStartOffset, rangeEndOffset, selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -1137,14 +1178,10 @@ NS_IMETHODIMP nsHTMLEditor::DeleteSelection(nsIEditor::ESelectionCollapseDirecti
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// unnamed placeholder txns dont merge, but they do get sucked
|
||||
// into placeholders that they are nested in. So this delte wont
|
||||
// merge with other deletes, but if it happens in the course of
|
||||
// a typing placehilder context, it will be consumed by that.
|
||||
// This is the desired behavior.
|
||||
nsAutoPlaceHolderBatch batch(this, nsnull);
|
||||
// delete placeholder txns merge.
|
||||
nsAutoPlaceHolderBatch batch(this, gDeleteTxnName);
|
||||
|
||||
// pre-process
|
||||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1153,10 +1190,14 @@ NS_IMETHODIMP nsHTMLEditor::DeleteSelection(nsIEditor::ESelectionCollapseDirecti
|
|||
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kDeleteSelection);
|
||||
ruleInfo.collapsedAction = aAction;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
result = DeleteSelectionImpl(aAction);
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
|
@ -1169,30 +1210,32 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoPlaceHolderBatch batch(this, nsnull);
|
||||
|
||||
// pre-process
|
||||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsAutoString resultString;
|
||||
PlaceholderTxn *placeholderTxn=nsnull;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertText);
|
||||
// ruleInfo.placeTxn = &placeholderTxn;
|
||||
ruleInfo.inString = &aStringToInsert;
|
||||
ruleInfo.outString = &resultString;
|
||||
ruleInfo.typeInState = *mTypeInState;
|
||||
ruleInfo.maxLength = mMaxTextLength;
|
||||
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(result)) return result;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
result = InsertTextImpl(resultString);
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
// if (placeholderTxn)
|
||||
// placeholderTxn->SetAbsorb(PR_FALSE); // this ends the merging of txns into placeholderTxn
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1333,7 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1298,8 +1341,9 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertBreak);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(res)))
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
// create the new BR node
|
||||
nsCOMPtr<nsIDOMNode> newNode;
|
||||
|
@ -1350,6 +1394,9 @@ NS_IMETHODIMP nsHTMLEditor::InsertBreak()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
}
|
||||
|
@ -1374,106 +1421,110 @@ nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
// hand off to the rules system, see if it has anything to say about this
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertElement);
|
||||
ruleInfo.insertElement = aElement;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (aDeleteSelection)
|
||||
if (!handled)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
PRInt32 tempOffset;
|
||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);
|
||||
if (!NS_SUCCEEDED(result))
|
||||
return result;
|
||||
}
|
||||
|
||||
// If deleting, selection will be collapsed.
|
||||
// so if not, we collapse it
|
||||
if (!aDeleteSelection)
|
||||
{
|
||||
// Named Anchor is a special case,
|
||||
// We collapse to insert element BEFORE the selection
|
||||
// For all other tags, we insert AFTER the selection
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
if (IsNamedAnchorNode(node))
|
||||
if (aDeleteSelection)
|
||||
{
|
||||
selection->CollapseToStart();
|
||||
} else {
|
||||
selection->CollapseToEnd();
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
PRInt32 tempOffset;
|
||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);
|
||||
if (!NS_SUCCEEDED(result))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentSelectedNode;
|
||||
PRInt32 offsetForInsert;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));
|
||||
// XXX: ERROR_HANDLING bad XPCOM usage
|
||||
if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode)
|
||||
{
|
||||
// If deleting, selection will be collapsed.
|
||||
// so if not, we collapse it
|
||||
if (!aDeleteSelection)
|
||||
{
|
||||
// Named Anchor is a special case,
|
||||
// We collapse to insert element BEFORE the selection
|
||||
// For all other tags, we insert AFTER the selection
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
if (IsNamedAnchorNode(node))
|
||||
{
|
||||
selection->CollapseToStart();
|
||||
} else {
|
||||
selection->CollapseToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentSelectedNode;
|
||||
PRInt32 offsetForInsert;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));
|
||||
// XXX: ERROR_HANDLING bad XPCOM usage
|
||||
if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode)
|
||||
{
|
||||
#ifdef DEBUG_cmanske
|
||||
{
|
||||
nsAutoString name;
|
||||
parentSelectedNode->GetNodeName(name);
|
||||
printf("InsertElement: Anchor node of selection: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf(" Offset: %d\n", offsetForInsert);
|
||||
}
|
||||
{
|
||||
nsAutoString name;
|
||||
parentSelectedNode->GetNodeName(name);
|
||||
printf("InsertElement: Anchor node of selection: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf(" Offset: %d\n", offsetForInsert);
|
||||
}
|
||||
#endif
|
||||
nsAutoString tagName;
|
||||
aElement->GetNodeName(tagName);
|
||||
tagName.ToLowerCase();
|
||||
nsCOMPtr<nsIDOMNode> parent = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> topChild = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString parentTagName;
|
||||
PRBool isRoot;
|
||||
nsAutoString tagName;
|
||||
aElement->GetNodeName(tagName);
|
||||
tagName.ToLowerCase();
|
||||
nsCOMPtr<nsIDOMNode> parent = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> topChild = parentSelectedNode;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString parentTagName;
|
||||
PRBool isRoot;
|
||||
|
||||
// Search up the parent chain to find a suitable container
|
||||
while (!CanContainTag(parent, tagName))
|
||||
{
|
||||
// If the current parent is a root (body or table cell)
|
||||
// then go no further - we can't insert
|
||||
parent->GetNodeName(parentTagName);
|
||||
res = IsRootTag(parentTagName, isRoot);
|
||||
if (!NS_SUCCEEDED(res) || isRoot)
|
||||
return NS_ERROR_FAILURE;
|
||||
// Get the next parent
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp)
|
||||
return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
// Search up the parent chain to find a suitable container
|
||||
while (!CanContainTag(parent, tagName))
|
||||
{
|
||||
// If the current parent is a root (body or table cell)
|
||||
// then go no further - we can't insert
|
||||
parent->GetNodeName(parentTagName);
|
||||
res = IsRootTag(parentTagName, isRoot);
|
||||
if (!NS_SUCCEEDED(res) || isRoot)
|
||||
return NS_ERROR_FAILURE;
|
||||
// Get the next parent
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp)
|
||||
return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
#ifdef DEBUG_cmanske
|
||||
{
|
||||
nsAutoString name;
|
||||
parent->GetNodeName(name);
|
||||
printf("Parent node to insert under: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
topChild->GetNodeName(name);
|
||||
printf("TopChild to split: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
}
|
||||
{
|
||||
nsAutoString name;
|
||||
parent->GetNodeName(name);
|
||||
printf("Parent node to insert under: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
topChild->GetNodeName(name);
|
||||
printf("TopChild to split: ");
|
||||
wprintf(name.GetUnicode());
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
if (parent != topChild)
|
||||
{
|
||||
// we need to split some levels above the original selection parent
|
||||
res = SplitNodeDeep(topChild, parentSelectedNode, offsetForInsert, &offsetForInsert);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (parent != topChild)
|
||||
{
|
||||
// we need to split some levels above the original selection parent
|
||||
res = SplitNodeDeep(topChild, parentSelectedNode, offsetForInsert, &offsetForInsert);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
}
|
||||
// Now we can insert the new node
|
||||
res = InsertNode(aElement, parent, offsetForInsert);
|
||||
|
||||
// Set caret after element, but check for special case
|
||||
// of inserting table-related elements: set in first cell instead
|
||||
if (!SetCaretInTableCell(aElement))
|
||||
res = SetCaretAfterElement(aElement);
|
||||
|
||||
}
|
||||
// Now we can insert the new node
|
||||
res = InsertNode(aElement, parent, offsetForInsert);
|
||||
|
||||
// Set caret after element, but check for special case
|
||||
// of inserting table-related elements: set in first cell instead
|
||||
if (!SetCaretInTableCell(aElement))
|
||||
res = SetCaretAfterElement(aElement);
|
||||
|
||||
}
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1848,7 +1899,7 @@ nsHTMLEditor::InsertList(const nsString& aListType)
|
|||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
|
@ -1860,222 +1911,31 @@ nsHTMLEditor::InsertList(const nsString& aListType)
|
|||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
if (!handled)
|
||||
{
|
||||
// have to find a place to put the list
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aListType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// make a list
|
||||
nsCOMPtr<nsIDOMNode> newList;
|
||||
res = CreateNode(aListType, parent, offset, getter_AddRefs(newList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// make a list item
|
||||
nsAutoString tag("li");
|
||||
nsCOMPtr<nsIDOMNode> newItem;
|
||||
res = CreateNode(tag, newList, 0, getter_AddRefs(newItem));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
// XXX - revisit when layout is fixed
|
||||
res = selection->Collapse(newItem,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#if 0
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveList(const nsString& aListType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kRemoveList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// no default behavior for this yet. what would it mean?
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeBasicBlock);
|
||||
ruleInfo.blockType = &aBlockType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the block
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aBlockType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a block
|
||||
nsCOMPtr<nsIDOMNode> newBlock;
|
||||
res = CreateNode(aBlockType, parent, offset, getter_AddRefs(newBlock));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// xxx
|
||||
|
||||
// put a space in it so layout will draw it
|
||||
res = selection->Collapse(newBlock,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(nbsp);
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: Implement "outdent"
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::Indent(const nsString& aIndent)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kIndent);
|
||||
if (aIndent == "outdent")
|
||||
ruleInfo.action = nsHTMLEditRules::kOutdent;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// Do default - insert a blockquote node if selection collapsed
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString inward("indent");
|
||||
if (aIndent == inward)
|
||||
{
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the blockquote
|
||||
// have to find a place to put the list
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString bq("blockquote");
|
||||
while ( !CanContainTag(parent, bq))
|
||||
|
||||
while ( !CanContainTag(parent, aListType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
|
@ -2090,13 +1950,20 @@ nsHTMLEditor::Indent(const nsString& aIndent)
|
|||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a blockquote
|
||||
nsCOMPtr<nsIDOMNode> newBQ;
|
||||
res = CreateNode(bq, parent, offset, getter_AddRefs(newBQ));
|
||||
// make a list
|
||||
nsCOMPtr<nsIDOMNode> newList;
|
||||
res = CreateNode(aListType, parent, offset, getter_AddRefs(newList));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// make a list item
|
||||
nsAutoString tag("li");
|
||||
nsCOMPtr<nsIDOMNode> newItem;
|
||||
res = CreateNode(tag, newList, 0, getter_AddRefs(newItem));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
res = selection->Collapse(newBQ,0);
|
||||
// XXX - revisit when layout is fixed
|
||||
res = selection->Collapse(newItem,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#if 0
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
@ -2105,9 +1972,205 @@ nsHTMLEditor::Indent(const nsString& aIndent)
|
|||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveList(const nsString& aListType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kRemoveList);
|
||||
if (aListType == "ol") ruleInfo.bOrdered = PR_TRUE;
|
||||
else ruleInfo.bOrdered = PR_FALSE;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
// no default behavior for this yet. what would it mean?
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::InsertBasicBlock(const nsString& aBlockType)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kMakeBasicBlock);
|
||||
ruleInfo.blockType = &aBlockType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
// Find out if the selection is collapsed:
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the block
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
|
||||
while ( !CanContainTag(parent, aBlockType))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a block
|
||||
nsCOMPtr<nsIDOMNode> newBlock;
|
||||
res = CreateNode(aBlockType, parent, offset, getter_AddRefs(newBlock));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// xxx
|
||||
|
||||
// put a space in it so layout will draw it
|
||||
res = selection->Collapse(newBlock,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(nbsp);
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: Implement "outdent"
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::Indent(const nsString& aIndent)
|
||||
{
|
||||
nsresult res;
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
||||
PRBool cancel, handled;
|
||||
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
|
||||
// pre-process
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kIndent);
|
||||
if (aIndent == "outdent")
|
||||
ruleInfo.action = nsHTMLEditRules::kOutdent;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || (NS_FAILED(res))) return res;
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
// Do default - insert a blockquote node if selection collapsed
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
PRBool isCollapsed;
|
||||
res = selection->GetIsCollapsed(&isCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (!node) res = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsAutoString inward("indent");
|
||||
if (aIndent == inward)
|
||||
{
|
||||
if (isCollapsed)
|
||||
{
|
||||
// have to find a place to put the blockquote
|
||||
nsCOMPtr<nsIDOMNode> parent = node;
|
||||
nsCOMPtr<nsIDOMNode> topChild = node;
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsAutoString bq("blockquote");
|
||||
while ( !CanContainTag(parent, bq))
|
||||
{
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
if (!tmp) return NS_ERROR_FAILURE;
|
||||
topChild = parent;
|
||||
parent = tmp;
|
||||
}
|
||||
|
||||
if (parent != node)
|
||||
{
|
||||
// we need to split up to the child of parent
|
||||
res = SplitNodeDeep(topChild, node, offset, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// make a blockquote
|
||||
nsCOMPtr<nsIDOMNode> newBQ;
|
||||
res = CreateNode(bq, parent, offset, getter_AddRefs(newBQ));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// put a space in it so layout will draw the list item
|
||||
res = selection->Collapse(newBQ,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
nsAutoString theText(" ");
|
||||
res = InsertText(theText);
|
||||
if (NS_FAILED(res)) return res;
|
||||
// reposition selection to before the space character
|
||||
res = GetStartNodeAndOffset(selection, &node, &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = selection->Collapse(node,0);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2118,7 +2181,7 @@ nsHTMLEditor::Align(const nsString& aAlignType)
|
|||
{
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRBool cancel= PR_FALSE;
|
||||
PRBool cancel, handled;
|
||||
|
||||
// Find out if the selection is collapsed:
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
|
@ -2127,8 +2190,11 @@ nsHTMLEditor::Align(const nsString& aAlignType)
|
|||
if (!selection) return NS_ERROR_NULL_POINTER;
|
||||
nsTextRulesInfo ruleInfo(nsHTMLEditRules::kAlign);
|
||||
ruleInfo.alignType = &aAlignType;
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
|
||||
res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(res))
|
||||
return res;
|
||||
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -3284,8 +3350,8 @@ nsHTMLEditor::Undo(PRUint32 aCount)
|
|||
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
GetSelection(getter_AddRefs(selection));
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
|
||||
if (!cancel && NS_SUCCEEDED(result))
|
||||
{
|
||||
|
@ -3309,8 +3375,8 @@ nsHTMLEditor::Redo(PRUint32 aCount)
|
|||
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
GetSelection(getter_AddRefs(selection));
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
|
||||
if (!cancel && NS_SUCCEEDED(result))
|
||||
{
|
||||
|
@ -3441,14 +3507,14 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString,
|
|||
const nsString& aFormatType,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
PRBool cancel;
|
||||
PRBool cancel, handled;
|
||||
nsString resultString;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kOutputText);
|
||||
ruleInfo.outString = &resultString;
|
||||
ruleInfo.outputFormat = &aFormatType;
|
||||
nsresult rv = mRules->WillDoAction(nsnull, &ruleInfo, &cancel);
|
||||
if (NS_FAILED(rv)) { return rv; }
|
||||
if (PR_TRUE==cancel)
|
||||
nsresult rv = mRules->WillDoAction(nsnull, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(rv)) { return rv; }
|
||||
if (handled)
|
||||
{ // this case will get triggered by password fields
|
||||
aOutputString = *(ruleInfo.outString);
|
||||
}
|
||||
|
@ -3680,10 +3746,10 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat
|
|||
nsresult result = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(result)) return result;
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertTextIME);
|
||||
PRBool cancel;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if (NS_FAILED(result)) return result;
|
||||
// we don't care if WillInsert said to cancel...
|
||||
PRBool cancel, handled;
|
||||
result = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(result)) return result;
|
||||
|
||||
result = SetInputMethodText(aCompositionString,aTextRangeList);
|
||||
if (NS_FAILED(result)) return result;
|
||||
mIMEBufferLength = aCompositionString.Length();
|
||||
|
@ -3694,6 +3760,7 @@ nsHTMLEditor::SetCompositionString(const nsString& aCompositionString, nsIPrivat
|
|||
ps->GetCaret(getter_AddRefs(caretP));
|
||||
caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed);
|
||||
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
|
||||
NS_IMETHOD EditorKeyPress(nsIDOMUIEvent* aKeyEvent);
|
||||
NS_IMETHOD TypedText(const nsString& aString, PRInt32 aAction);
|
||||
|
||||
NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty);
|
||||
NS_IMETHOD GetDocumentLength(PRInt32 *aCount);
|
||||
|
@ -482,6 +483,7 @@ protected:
|
|||
|
||||
public:
|
||||
static nsIAtom *gTypingTxnName;
|
||||
static nsIAtom *gDeleteTxnName;
|
||||
|
||||
// friends
|
||||
friend class nsHTMLEditRules;
|
||||
|
|
|
@ -155,6 +155,27 @@ nsHTMLEditorLog::DeleteSelection(nsIEditor::ESelectionCollapseDirection aAction)
|
|||
return nsHTMLEditor::DeleteSelection(aAction);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditorLog::TypedText(const nsString& aStringToInsert, PRInt32 aAction)
|
||||
{
|
||||
nsAutoHTMLEditorLogLock logLock(this);
|
||||
|
||||
if (!mLocked && mFileSpec)
|
||||
{
|
||||
PrintSelection();
|
||||
|
||||
Write("window.editorShell.TypedText(\"");
|
||||
PrintUnicode(aStringToInsert);
|
||||
Write("\", ");
|
||||
WriteInt("%d", aAction);
|
||||
Write(");\n");
|
||||
|
||||
Flush();
|
||||
}
|
||||
|
||||
return nsHTMLEditor::TypedText(aStringToInsert, aAction);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditorLog::InsertText(const nsString& aStringToInsert)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
NS_IMETHOD SetParagraphFormat(const nsString& aParagraphFormat);
|
||||
NS_IMETHOD RemoveInlineProperty(nsIAtom *aProperty, const nsString *aAttribute);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::ESelectionCollapseDirection aAction);
|
||||
NS_IMETHOD TypedText(const nsString& aString, PRInt32 aAction);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
NS_IMETHOD InsertBreak();
|
||||
NS_IMETHOD Undo(PRUint32 aCount);
|
||||
|
|
|
@ -121,12 +121,15 @@ nsTextEditRules::SetFlags(PRUint32 aFlags)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
nsRulesInfo *aInfo,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
// null selection is legal
|
||||
if (!aInfo || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aInfo || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
@ -134,10 +137,11 @@ nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
return WillInsertBreak(aSelection, aCancel, aHandled);
|
||||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
aCancel,
|
||||
aHandled,
|
||||
info->inString,
|
||||
info->outString,
|
||||
info->typeInState,
|
||||
|
@ -145,20 +149,21 @@ nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|||
case kInsertTextIME:
|
||||
return WillInsert(aSelection, aCancel);
|
||||
case kDeleteSelection:
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel);
|
||||
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel, aHandled);
|
||||
case kUndo:
|
||||
return WillUndo(aSelection, aCancel);
|
||||
return WillUndo(aSelection, aCancel, aHandled);
|
||||
case kRedo:
|
||||
return WillRedo(aSelection, aCancel);
|
||||
return WillRedo(aSelection, aCancel, aHandled);
|
||||
case kSetTextProperty:
|
||||
return WillSetTextProperty(aSelection, aCancel);
|
||||
return WillSetTextProperty(aSelection, aCancel, aHandled);
|
||||
case kRemoveTextProperty:
|
||||
return WillRemoveTextProperty(aSelection, aCancel);
|
||||
return WillRemoveTextProperty(aSelection, aCancel, aHandled);
|
||||
case kOutputText:
|
||||
return WillOutputText(aSelection,
|
||||
info->outputFormat,
|
||||
info->outString,
|
||||
aCancel);
|
||||
aCancel,
|
||||
aHandled);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -239,10 +244,11 @@ nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
*aHandled = PR_FALSE;
|
||||
if (mFlags & nsIHTMLEditor::eEditorSingleLineMask) {
|
||||
*aCancel = PR_TRUE;
|
||||
}
|
||||
|
@ -261,19 +267,22 @@ nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *aInString,
|
||||
nsString *aOutString,
|
||||
TypeInState aTypeInState,
|
||||
PRInt32 aMaxLength)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
|
||||
if (!aSelection || !aCancel || !aHandled || !aInString || !aOutString)
|
||||
{return NS_ERROR_NULL_POINTER;}
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
nsresult res;
|
||||
|
||||
// initialize out params
|
||||
*aCancel = PR_TRUE;
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_TRUE;
|
||||
*aOutString = *aInString;
|
||||
|
||||
// handle docs with a max length
|
||||
|
@ -576,8 +585,10 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
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"
|
||||
|
@ -594,8 +605,10 @@ nsTextEditRules::DidSetTextProperty(nsIDOMSelection *aSelection, nsresult aResul
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
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"
|
||||
|
@ -614,13 +627,15 @@ nsTextEditRules::DidRemoveTextProperty(nsIDOMSelection *aSelection, nsresult aRe
|
|||
nsresult
|
||||
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
// if there is only bogus content, cancel the operation
|
||||
if (mBogusNode) {
|
||||
|
@ -745,12 +760,13 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -808,12 +824,13 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -869,25 +886,28 @@ nsresult
|
|||
nsTextEditRules::WillOutputText(nsIDOMSelection *aSelection,
|
||||
const nsString *aOutputFormat,
|
||||
nsString *aOutString,
|
||||
PRBool *aCancel)
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
// null selection ok
|
||||
if (!aOutString || !aOutputFormat || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
if (!aOutString || !aOutputFormat || !aCancel || !aHandled)
|
||||
{ return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
*aHandled = PR_FALSE;
|
||||
|
||||
if (PR_TRUE == aOutputFormat->Equals("text/plain"))
|
||||
{ // only use these rules for plain text output
|
||||
if (mFlags & nsIHTMLEditor::eEditorPasswordMask)
|
||||
{
|
||||
*aOutString = mPasswordText;
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
else if (mBogusNode)
|
||||
{ // this means there's no content, so output null string
|
||||
*aOutString = "";
|
||||
*aCancel = PR_TRUE;
|
||||
*aHandled = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
// nsEditRules methods
|
||||
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags);
|
||||
|
@ -85,6 +85,7 @@ protected:
|
|||
// nsTextEditRules implementation methods
|
||||
nsresult WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled,
|
||||
const nsString *inString,
|
||||
nsString *outString,
|
||||
TypeInState typeInState,
|
||||
|
@ -92,7 +93,7 @@ protected:
|
|||
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
|
||||
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
|
@ -100,21 +101,22 @@ protected:
|
|||
|
||||
nsresult WillDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
PRBool *aCancel);
|
||||
PRBool *aCancel,
|
||||
PRBool *aHandled);
|
||||
nsresult DidDeleteSelection(nsIDOMSelection *aSelection,
|
||||
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
||||
nsresult aResult);
|
||||
|
||||
nsresult WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidSetTextProperty(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidRemoveTextProperty(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidUndo(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled);
|
||||
nsresult DidRedo(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
/** called prior to nsIEditor::OutputToString
|
||||
|
@ -127,7 +129,8 @@ protected:
|
|||
nsresult WillOutputText(nsIDOMSelection *aSelection,
|
||||
const nsString *aInFormat,
|
||||
nsString *aOutText,
|
||||
PRBool *aOutCancel);
|
||||
PRBool *aOutCancel,
|
||||
PRBool *aHandled);
|
||||
|
||||
nsresult DidOutputText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
|
|
|
@ -65,6 +65,12 @@ public:
|
|||
eEditorMailMask = (1 << eEditorMailBit)
|
||||
};
|
||||
|
||||
// below used by TypedText()
|
||||
enum {
|
||||
eTypedText, // user typed text
|
||||
eTypedBR, // user typed shift-enter to get a br
|
||||
eTypedBreak // user typed enter
|
||||
};
|
||||
|
||||
/* ------------ Document info methods -------------- */
|
||||
|
||||
|
@ -148,6 +154,12 @@ public:
|
|||
*/
|
||||
NS_IMETHOD EditorKeyPress(nsIDOMUIEvent* aKeyEvent)=0;
|
||||
|
||||
/**
|
||||
* TypedText responds to user typing. Provides a logging bottleneck for typing.
|
||||
* @param aString string to type
|
||||
* @param aAction action to take: insert text, insert BR, insert break
|
||||
*/
|
||||
NS_IMETHOD TypedText(const nsString& aString, PRInt32 aAction)=0;
|
||||
|
||||
/**
|
||||
* Insert a break into the content model.<br>
|
||||
|
|
Загрузка…
Ссылка в новой задаче