зеркало из https://github.com/mozilla/pjs.git
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start. We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to another app. * added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the rules system deal with those flags. The flags I added are: TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus. TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus. * added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line behavior. * cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the ownership model on the listeners, it was a big help. * added support for a max text length. You can now tell the text editor, be no bigger than n characters.
This commit is contained in:
Родитель
35b0d02e18
Коммит
87b3a69509
|
@ -108,6 +108,7 @@ LINCS=-I$(PUBLIC)\editor \
|
|||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I$(PUBLIC)\js \
|
||||
-I$(PUBLIC)\pref \
|
||||
-I$(PUBLIC)\txmgr \
|
||||
-I$(PUBLIC)\netlib \
|
||||
-I$(PUBLIC)\pref \
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
NS_IMETHOD InsertNode(nsIDOMNode * aNode,
|
||||
nsIDOMNode * aParent,
|
||||
PRInt32 aPosition);
|
||||
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
|
||||
NS_IMETHOD BeginComposition(void);
|
||||
|
@ -200,7 +201,7 @@ public:
|
|||
NS_IMETHOD RemoveEditActionListener(nsIEditActionListener *aListener);
|
||||
|
||||
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
|
||||
|
||||
|
||||
/*END nsIEditor interfaces*/
|
||||
|
||||
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
*/
|
||||
#include "nsEditorEventListeners.h"
|
||||
#include "nsEditor.h"
|
||||
|
||||
#include "CreateElementTxn.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMSelection.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
|
@ -1241,10 +1240,133 @@ NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITex
|
|||
if (nsnull==it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
it->SetEditor(aEditor);
|
||||
return it->QueryInterface(nsIDOMEventListener::GetIID(), (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult,
|
||||
nsITextEditor *aEditor)
|
||||
{
|
||||
nsTextEditorFocusListener* it = new nsTextEditorFocusListener();
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
it->SetEditor(aEditor);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
return it->QueryInterface(nsIDOMEventListener::GetIID(), (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* nsTextEditorFocusListener implementation
|
||||
*/
|
||||
|
||||
NS_IMPL_ADDREF(nsTextEditorFocusListener)
|
||||
|
||||
NS_IMPL_RELEASE(nsTextEditorFocusListener)
|
||||
|
||||
|
||||
nsTextEditorFocusListener::nsTextEditorFocusListener()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsTextEditorFocusListener::~nsTextEditorFocusListener()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (nsnull == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
static NS_DEFINE_IID(kIDOMFocusListenerIID, NS_IDOMFOCUSLISTENER_IID);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*)(nsISupports*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kIDOMEventListenerIID)) {
|
||||
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kIDOMFocusListenerIID)) {
|
||||
*aInstancePtr = (void*)(nsIDOMFocusListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::Focus(nsIDOMEvent* aDragEvent)
|
||||
{
|
||||
// turn on selection and caret
|
||||
if (mEditor)
|
||||
{
|
||||
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
||||
if (editor)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell>ps;
|
||||
editor->GetPresShell(getter_AddRefs(ps));
|
||||
if (ps)
|
||||
{
|
||||
ps->SetCaretEnabled(PR_TRUE);
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument>domDoc;
|
||||
editor->GetDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc)
|
||||
{
|
||||
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
|
||||
if (doc)
|
||||
{
|
||||
doc->SetDisplaySelection(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::Blur(nsIDOMEvent* aDragEvent)
|
||||
{
|
||||
// turn off selection and caret
|
||||
if (mEditor)
|
||||
{
|
||||
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
||||
if (editor)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell>ps;
|
||||
editor->GetPresShell(getter_AddRefs(ps));
|
||||
if (ps)
|
||||
{
|
||||
ps->SetCaretEnabled(PR_FALSE);
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument>domDoc;
|
||||
editor->GetDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc)
|
||||
{
|
||||
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
|
||||
if (doc)
|
||||
{
|
||||
doc->SetDisplaySelection(PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsITextEditor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
@ -195,10 +196,42 @@ public:
|
|||
/*END implementations of dragevent handler interface*/
|
||||
|
||||
protected:
|
||||
nsITextEditor* mEditor; // weak reference
|
||||
|
||||
nsITextEditor* mEditor;
|
||||
|
||||
};
|
||||
|
||||
/** editor Implementation of the FocusListener interface
|
||||
*/
|
||||
class nsTextEditorFocusListener : public nsIDOMFocusListener
|
||||
{
|
||||
public:
|
||||
/** default constructor
|
||||
*/
|
||||
nsTextEditorFocusListener();
|
||||
/** default destructor
|
||||
*/
|
||||
virtual ~nsTextEditorFocusListener();
|
||||
|
||||
/** SetEditor gives an address to the editor that will be accessed
|
||||
* @param aEditor the editor this listener calls for editing operations
|
||||
*/
|
||||
void SetEditor(nsITextEditor *aEditor){mEditor = aEditor;}
|
||||
|
||||
/*interfaces for addref and release and queryinterface*/
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/*BEGIN implementations of focus event handler interface*/
|
||||
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
|
||||
public:
|
||||
virtual nsresult Focus(nsIDOMEvent* aEvent);
|
||||
virtual nsresult Blur(nsIDOMEvent* aEvent);
|
||||
/*END implementations of focus event handler interface*/
|
||||
|
||||
protected:
|
||||
nsITextEditor* mEditor; // weak reference
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** factory for the editor key listener
|
||||
*/
|
||||
|
@ -219,5 +252,10 @@ extern nsresult NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResu
|
|||
/** factory for the editor composition listener
|
||||
*/
|
||||
extern nsresult NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
|
||||
|
||||
/** factory for the editor composition listener
|
||||
*/
|
||||
extern nsresult NS_NewEditorFocusListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
|
||||
|
||||
#endif //editorInterfaces_h__
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
|
||||
NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell)
|
||||
{
|
||||
NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -34,7 +34,12 @@
|
|||
|
||||
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
|
||||
|
||||
|
||||
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
|
||||
if (mFlags & TEXT_EDITOR_FLAG_READONLY || mFlags & TEXT_EDITOR_FLAG_DISALBED) \
|
||||
{ \
|
||||
*aCancel = PR_TRUE; \
|
||||
return NS_OK; \
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* Constructor/Destructor
|
||||
|
@ -43,6 +48,7 @@ static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
|
|||
nsTextEditRules::nsTextEditRules()
|
||||
{
|
||||
mEditor = nsnull;
|
||||
mFlags=0;
|
||||
}
|
||||
|
||||
nsTextEditRules::~nsTextEditRules()
|
||||
|
@ -58,9 +64,27 @@ nsTextEditRules::~nsTextEditRules()
|
|||
NS_IMETHODIMP
|
||||
nsTextEditRules::Init(nsIEditor *aEditor)
|
||||
{
|
||||
// null aNextRule is ok
|
||||
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
|
||||
mEditor = (nsTextEditor*)aEditor; // we hold a non-refcounted reference back to our editor
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
mEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ASSERTION(selection, "editor cannot get selection");
|
||||
nsresult result = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
if (!aFlags) { return NS_ERROR_NULL_POINTER; }
|
||||
*aFlags = mFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::SetFlags(PRUint32 aFlags)
|
||||
{
|
||||
mFlags = aFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -68,14 +92,15 @@ NS_IMETHODIMP
|
|||
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aInfo)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aInfo) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
||||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
|
@ -105,6 +130,8 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection,
|
|||
|
||||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return DidInsertBreak(aSelection, aResult);
|
||||
case kInsertText:
|
||||
return DidInsertText(aSelection, aResult);
|
||||
case kDeleteSelection:
|
||||
|
@ -127,6 +154,8 @@ nsresult
|
|||
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
|
@ -148,6 +177,27 @@ nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
if (mFlags & TEXT_EDITOR_FLAG_SINGLELINE) {
|
||||
*aCancel = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
*aCancel = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
|
@ -156,8 +206,8 @@ nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
nsString *outString,
|
||||
TypeInState typeInState)
|
||||
{
|
||||
if (!aSelection || !aCancel || !inString || !outString)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aCancel || !inString || !outString) {return NS_ERROR_NULL_POINTER;}
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out params
|
||||
*aCancel = PR_FALSE;
|
||||
|
@ -442,21 +492,12 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
nsresult
|
||||
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
|
||||
{
|
||||
if (!aTag) { return NS_ERROR_NULL_POINTER; }
|
||||
*aTag = NS_NewAtom("BR");
|
||||
return NS_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
|
@ -482,71 +523,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
|
|||
// insert a special bogus text node with a character in it.
|
||||
if (NS_SUCCEEDED(result)) // only do this work if DeleteSelection completed successfully
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
mEditor->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if ((NS_SUCCEEDED(result)) && nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if ((NS_SUCCEEDED(result)) && bodyNode)
|
||||
{ // now we've got the body tag.
|
||||
// iterate the body tag, looking for editable content
|
||||
// if no editable content is found, insert the bogus node
|
||||
PRBool needsBogusContent=PR_TRUE;
|
||||
nsCOMPtr<nsIDOMNode>bodyChild;
|
||||
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
||||
while ((NS_SUCCEEDED(result)) && bodyChild)
|
||||
{
|
||||
if (PR_TRUE==nsEditor::IsEditable(bodyChild))
|
||||
{
|
||||
needsBogusContent = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode>temp;
|
||||
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
||||
bodyChild = do_QueryInterface(temp);
|
||||
}
|
||||
if (PR_TRUE==needsBogusContent)
|
||||
{
|
||||
// set mBogusNode to be the newly created <P>
|
||||
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
|
||||
getter_AddRefs(mBogusNode));
|
||||
if ((NS_SUCCEEDED(result)) && mBogusNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newTNode;
|
||||
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), mBogusNode, 0,
|
||||
getter_AddRefs(newTNode));
|
||||
if ((NS_SUCCEEDED(result)) && newTNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
|
||||
newNodeAsText = do_QueryInterface(newTNode);
|
||||
if (newNodeAsText)
|
||||
{
|
||||
nsAutoString data;
|
||||
data += 160;
|
||||
newNodeAsText->SetData(data);
|
||||
aSelection->Collapse(newTNode, 0);
|
||||
}
|
||||
}
|
||||
// make sure we know the PNode is bogus
|
||||
nsCOMPtr<nsIDOMElement>newPElement;
|
||||
newPElement = do_QueryInterface(mBogusNode);
|
||||
if (newPElement)
|
||||
{
|
||||
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
||||
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
|
||||
newPElement->SetAttribute(att, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = CreateBogusNodeIfNeeded(aSelection);
|
||||
// if we don't have an empty document, check the selection to see if any collapsing is necessary
|
||||
if (!mBogusNode)
|
||||
{
|
||||
|
@ -615,6 +592,7 @@ nsresult
|
|||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
@ -666,6 +644,7 @@ nsresult
|
|||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
@ -709,7 +688,77 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
|
||||
{
|
||||
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
mEditor->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if ((NS_SUCCEEDED(result)) && nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if ((NS_SUCCEEDED(result)) && bodyNode)
|
||||
{ // now we've got the body tag.
|
||||
// iterate the body tag, looking for editable content
|
||||
// if no editable content is found, insert the bogus node
|
||||
PRBool needsBogusContent=PR_TRUE;
|
||||
nsCOMPtr<nsIDOMNode>bodyChild;
|
||||
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
||||
while ((NS_SUCCEEDED(result)) && bodyChild)
|
||||
{
|
||||
if (PR_TRUE==nsEditor::IsEditable(bodyChild))
|
||||
{
|
||||
needsBogusContent = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode>temp;
|
||||
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
||||
bodyChild = do_QueryInterface(temp);
|
||||
}
|
||||
if (PR_TRUE==needsBogusContent)
|
||||
{
|
||||
// set mBogusNode to be the newly created <P>
|
||||
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
|
||||
getter_AddRefs(mBogusNode));
|
||||
if ((NS_SUCCEEDED(result)) && mBogusNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newTNode;
|
||||
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), mBogusNode, 0,
|
||||
getter_AddRefs(newTNode));
|
||||
if ((NS_SUCCEEDED(result)) && newTNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
|
||||
newNodeAsText = do_QueryInterface(newTNode);
|
||||
if (newNodeAsText)
|
||||
{
|
||||
nsAutoString data;
|
||||
data += 160;
|
||||
newNodeAsText->SetData(data);
|
||||
aSelection->Collapse(newTNode, 0);
|
||||
}
|
||||
}
|
||||
// make sure we know the PNode is bogus
|
||||
nsCOMPtr<nsIDOMElement>newPElement;
|
||||
newPElement = do_QueryInterface(mBogusNode);
|
||||
if (newPElement)
|
||||
{
|
||||
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
||||
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
|
||||
newPElement->SetAttribute(att, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
NS_IMETHOD Init(nsIEditor *aEditor);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags);
|
||||
|
||||
// nsTextEditRules action id's
|
||||
enum
|
||||
|
@ -57,7 +59,8 @@ public:
|
|||
kUndo = 1000,
|
||||
kRedo = 1001,
|
||||
kInsertText = 2000,
|
||||
kDeleteSelection = 2001
|
||||
kDeleteSelection = 2001,
|
||||
kInsertBreak = 2002
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -72,6 +75,9 @@ protected:
|
|||
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
|
||||
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
|
@ -112,10 +118,14 @@ protected:
|
|||
nsresult InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
|
||||
nsIAtom *aTag,
|
||||
nsIDOMSelection *aSelection);
|
||||
|
||||
/** creates a bogus text node if the document has no editable content */
|
||||
nsresult CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection);
|
||||
|
||||
// data
|
||||
nsTextEditor *mEditor; // note that we do not refcount the editor
|
||||
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
|
||||
PRUint32 mFlags;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMSelection.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
|
@ -97,9 +98,6 @@ static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
|||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
//static NS_DEFINE_IID(kIInputStreamIID, NS_IINPUTSTREAM_IID);
|
||||
//static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gNoisy = PR_FALSE;
|
||||
|
@ -155,6 +153,7 @@ nsTextEditor::nsTextEditor()
|
|||
// NS_INIT_REFCNT();
|
||||
mRules = nsnull;
|
||||
nsEditProperty::InstanceInit();
|
||||
mMaxTextLength = -1;
|
||||
}
|
||||
|
||||
nsTextEditor::~nsTextEditor()
|
||||
|
@ -175,19 +174,18 @@ nsTextEditor::~nsTextEditor()
|
|||
if (mMouseListenerP) {
|
||||
erP->RemoveEventListenerByIID(mMouseListenerP, nsIDOMMouseListener::GetIID());
|
||||
}
|
||||
|
||||
if (mTextListenerP) {
|
||||
erP->RemoveEventListenerByIID(mTextListenerP, nsIDOMTextListener::GetIID());
|
||||
}
|
||||
|
||||
if (mCompositionListenerP) {
|
||||
erP->RemoveEventListenerByIID(mCompositionListenerP, nsIDOMCompositionListener::GetIID());
|
||||
}
|
||||
|
||||
if (mDragListenerP) {
|
||||
erP->RemoveEventListenerByIID(mDragListenerP, nsIDOMDragListener::GetIID());
|
||||
if (mTextListenerP) {
|
||||
erP->RemoveEventListenerByIID(mTextListenerP, nsIDOMTextListener::GetIID());
|
||||
}
|
||||
if (mCompositionListenerP) {
|
||||
erP->RemoveEventListenerByIID(mCompositionListenerP, nsIDOMCompositionListener::GetIID());
|
||||
}
|
||||
if (mFocusListenerP) {
|
||||
erP->RemoveEventListenerByIID(mFocusListenerP, nsIDOMFocusListener::GetIID());
|
||||
}
|
||||
if (mDragListenerP) {
|
||||
erP->RemoveEventListenerByIID(mDragListenerP, nsIDOMDragListener::GetIID());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
NS_NOTREACHED("~nsTextEditor");
|
||||
|
@ -228,7 +226,8 @@ NS_IMETHODIMP nsTextEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
return nsEditor::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
|
||||
NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell)
|
||||
{
|
||||
NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
|
@ -258,94 +257,121 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
|
|||
// Init the rules system
|
||||
InitRules();
|
||||
|
||||
// get a key listener
|
||||
result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
|
||||
if (NS_OK != result) {
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
|
||||
// get a mouse listener
|
||||
result = NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
|
||||
if (NS_OK != result) {
|
||||
#ifdef DEBUG_akkana
|
||||
printf("Couldn't get mouse listener\n");
|
||||
#endif
|
||||
// drop the key listener if we couldn't get a mouse listener.
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
|
||||
result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this);
|
||||
if (NS_OK !=result) {
|
||||
// drop the key and mouse listeners
|
||||
// get a text listener
|
||||
result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this);
|
||||
if (NS_OK !=result)
|
||||
{
|
||||
#ifdef DEBUG_TAGUE
|
||||
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
|
||||
#endif
|
||||
mMouseListenerP = do_QueryInterface(0);
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
return result;
|
||||
}
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
|
||||
result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this);
|
||||
if (NS_OK!=result) {
|
||||
// drop the key and mouse listeners
|
||||
// get a composition listener
|
||||
result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this);
|
||||
if (NS_OK!=result)
|
||||
{
|
||||
#ifdef DEBUG_TAGUE
|
||||
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
|
||||
#endif
|
||||
mMouseListenerP = do_QueryInterface(0);
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
mTextListenerP = do_QueryInterface(0);
|
||||
return result;
|
||||
}
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
|
||||
// get a drag listener
|
||||
result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), this);
|
||||
if (NS_OK != result) {
|
||||
//return result;
|
||||
mMouseListenerP = do_QueryInterface(0);
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
mTextListenerP = do_QueryInterface(0);
|
||||
mCompositionListenerP = do_QueryInterface(0);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
result = aDoc->QueryInterface(nsIDOMEventReceiver::GetIID(), getter_AddRefs(erP));
|
||||
if (NS_OK != result)
|
||||
{
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
mMouseListenerP = do_QueryInterface(0); //dont need these if we cant register them
|
||||
mTextListenerP = do_QueryInterface(0);
|
||||
mDragListenerP = do_QueryInterface(0); //dont need these if we cant register them
|
||||
mCompositionListenerP = do_QueryInterface(0);
|
||||
HandleEventListenerError();
|
||||
//return result; // XXX: why is this return commented out?
|
||||
}
|
||||
|
||||
// get a focus listener
|
||||
result = NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this);
|
||||
if (NS_OK != result)
|
||||
{
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
//cmanske: Shouldn't we check result from this?
|
||||
result = erP->AddEventListenerByIID(mKeyListenerP, nsIDOMKeyListener::GetIID());
|
||||
|
||||
// get the DOM event receiver
|
||||
nsCOMPtr<nsIDOMEventReceiver> erP;
|
||||
result = aDoc->QueryInterface(nsIDOMEventReceiver::GetIID(), getter_AddRefs(erP));
|
||||
if (!NS_SUCCEEDED(result))
|
||||
{
|
||||
printf("nsTextEditor::Init -- faile to add mKeyListenerP\n");
|
||||
HandleEventListenerError();
|
||||
return result;
|
||||
}
|
||||
|
||||
// register the event listeners with the DOM event reveiver
|
||||
result = erP->AddEventListenerByIID(mKeyListenerP, nsIDOMKeyListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register key listener");
|
||||
result = erP->AddEventListenerByIID(mMouseListenerP, nsIDOMMouseListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse listener");
|
||||
result = erP->AddEventListenerByIID(mFocusListenerP, nsIDOMFocusListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register focus listener");
|
||||
result = erP->AddEventListenerByIID(mTextListenerP, nsIDOMTextListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register text listener");
|
||||
result = erP->AddEventListenerByIID(mCompositionListenerP, nsIDOMCompositionListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register composition listener");
|
||||
#ifdef NEW_DRAG_AND_DROP
|
||||
erP->AddEventListenerByIID(mDragListenerP, nsIDOMDragListener::GetIID());
|
||||
#endif
|
||||
erP->AddEventListenerByIID(mMouseListenerP, nsIDOMMouseListener::GetIID());
|
||||
|
||||
erP->AddEventListenerByIID(mTextListenerP, nsIDOMTextListener::GetIID());
|
||||
erP->AddEventListenerByIID(mCompositionListenerP, nsIDOMCompositionListener::GetIID());
|
||||
|
||||
result = NS_OK;
|
||||
|
||||
result = erP->AddEventListenerByIID(mDragListenerP, nsIDOMDragListener::GetIID());
|
||||
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register drag listener");
|
||||
#endif result = NS_OK;
|
||||
EnableUndo(PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsTextEditor::InitRules()
|
||||
void nsTextEditor::HandleEventListenerError()
|
||||
{
|
||||
printf("failed to add event listener\n");
|
||||
mKeyListenerP = do_QueryInterface(0);
|
||||
mMouseListenerP = do_QueryInterface(0);
|
||||
mTextListenerP = do_QueryInterface(0);
|
||||
mDragListenerP = do_QueryInterface(0);
|
||||
mCompositionListenerP = do_QueryInterface(0);
|
||||
mFocusListenerP = do_QueryInterface(0);
|
||||
}
|
||||
|
||||
void nsTextEditor::InitRules()
|
||||
{
|
||||
// instantiate the rules for this text editor
|
||||
// XXX: we should be told which set of rules to instantiate
|
||||
mRules = new nsTextEditRules();
|
||||
mRules->Init(this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditor::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
if (!mRules || !aFlags) { return NS_ERROR_NULL_POINTER; }
|
||||
return mRules->GetFlags(aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditor::SetFlags(PRUint32 aFlags)
|
||||
{
|
||||
if (!mRules) { return NS_ERROR_NULL_POINTER; }
|
||||
return mRules->SetFlags(aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::SetTextProperty(nsIAtom *aProperty,
|
||||
const nsString *aAttribute,
|
||||
|
@ -803,17 +829,10 @@ NS_IMETHODIMP nsTextEditor::DeleteSelection(nsIEditor::ECollapsedSelectionAction
|
|||
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
|
||||
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");
|
||||
|
||||
|
||||
// XXXX: Horrible hack! We are doing this because
|
||||
// of an error in Gecko which is not rendering the
|
||||
// document after a change via the DOM - gpk 2/13/99
|
||||
// BEGIN HACK!!!
|
||||
// HACKForceRedraw();
|
||||
// END HACK
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* XXX InsertText must respect mMaxTextLength */
|
||||
NS_IMETHODIMP nsTextEditor::InsertText(const nsString& aStringToInsert)
|
||||
{
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
|
@ -841,18 +860,34 @@ NS_IMETHODIMP nsTextEditor::InsertText(const nsString& aStringToInsert)
|
|||
if (placeholderTxn)
|
||||
placeholderTxn->SetAbsorb(PR_FALSE); // this ends the merging of txns into placeholderTxn
|
||||
|
||||
// BEGIN HACK!!!
|
||||
// HACKForceRedraw();
|
||||
// END HACK
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::SetMaxTextLength(PRInt32 aMaxTextLength)
|
||||
{
|
||||
mMaxTextLength = aMaxTextLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextEditor::InsertBreak()
|
||||
{
|
||||
// For plainttext just pass newlines through
|
||||
nsAutoString key;
|
||||
key += '\n';
|
||||
return InsertText(key);
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
PRBool cancel= PR_FALSE;
|
||||
|
||||
// pre-process
|
||||
nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertBreak);
|
||||
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
||||
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
||||
{
|
||||
// For plainttext just pass newlines through
|
||||
nsAutoString key;
|
||||
key += '\n';
|
||||
result = InsertText(key);
|
||||
nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ public:
|
|||
//Initialization
|
||||
NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell);
|
||||
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags);
|
||||
|
||||
//============================================================================
|
||||
// Methods that are duplicates of nsEditor -- exposed here for convenience
|
||||
// Editing Operations
|
||||
|
@ -65,6 +68,7 @@ public:
|
|||
NS_IMETHOD RemoveTextProperty(nsIAtom *aProperty, const nsString *aAttribute);
|
||||
NS_IMETHOD DeleteSelection(nsIEditor::ECollapsedSelectionAction aAction);
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
NS_IMETHOD SetMaxTextLength(PRInt32 aMaxTextLength);
|
||||
NS_IMETHOD InsertBreak();
|
||||
NS_IMETHOD CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode);
|
||||
|
||||
|
@ -257,6 +261,9 @@ protected:
|
|||
NS_IMETHOD OutputText(nsIOutputStream* aOutputStream, nsString* aOutputString, nsString* aCharsetOverride);
|
||||
NS_IMETHOD OutputHTML(nsIOutputStream* aOutputStream, nsString* aOutputString, nsString* aCharsetOverride);
|
||||
|
||||
/** simple utility to handle any error with event listener allocation or registration */
|
||||
void HandleEventListenerError();
|
||||
|
||||
// this overrides the base class implementation. It is not exported in nsITextEditor.
|
||||
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
|
||||
|
||||
|
@ -269,7 +276,9 @@ protected:
|
|||
nsCOMPtr<nsIDOMEventListener> mTextListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mFocusListenerP;
|
||||
PRBool mIsComposing;
|
||||
PRInt32 mMaxTextLength;
|
||||
|
||||
// friends
|
||||
friend class nsTextEditRules;
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
NS_IMETHOD InsertNode(nsIDOMNode * aNode,
|
||||
nsIDOMNode * aParent,
|
||||
PRInt32 aPosition);
|
||||
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert);
|
||||
|
||||
NS_IMETHOD BeginComposition(void);
|
||||
|
@ -200,7 +201,7 @@ public:
|
|||
NS_IMETHOD RemoveEditActionListener(nsIEditActionListener *aListener);
|
||||
|
||||
NS_IMETHOD DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed);
|
||||
|
||||
|
||||
/*END nsIEditor interfaces*/
|
||||
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ NS_IMETHODIMP nsHTMLEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
|
||||
NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell)
|
||||
{
|
||||
NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
|
||||
nsresult result=NS_ERROR_NULL_POINTER;
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
*/
|
||||
#include "nsEditorEventListeners.h"
|
||||
#include "nsEditor.h"
|
||||
|
||||
#include "CreateElementTxn.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMSelection.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
|
@ -1241,10 +1240,133 @@ NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITex
|
|||
if (nsnull==it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
it->SetEditor(aEditor);
|
||||
return it->QueryInterface(nsIDOMEventListener::GetIID(), (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult,
|
||||
nsITextEditor *aEditor)
|
||||
{
|
||||
nsTextEditorFocusListener* it = new nsTextEditorFocusListener();
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
it->SetEditor(aEditor);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
return it->QueryInterface(nsIDOMEventListener::GetIID(), (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* nsTextEditorFocusListener implementation
|
||||
*/
|
||||
|
||||
NS_IMPL_ADDREF(nsTextEditorFocusListener)
|
||||
|
||||
NS_IMPL_RELEASE(nsTextEditorFocusListener)
|
||||
|
||||
|
||||
nsTextEditorFocusListener::nsTextEditorFocusListener()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsTextEditorFocusListener::~nsTextEditorFocusListener()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (nsnull == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
static NS_DEFINE_IID(kIDOMFocusListenerIID, NS_IDOMFOCUSLISTENER_IID);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*)(nsISupports*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kIDOMEventListenerIID)) {
|
||||
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kIDOMFocusListenerIID)) {
|
||||
*aInstancePtr = (void*)(nsIDOMFocusListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::Focus(nsIDOMEvent* aDragEvent)
|
||||
{
|
||||
// turn on selection and caret
|
||||
if (mEditor)
|
||||
{
|
||||
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
||||
if (editor)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell>ps;
|
||||
editor->GetPresShell(getter_AddRefs(ps));
|
||||
if (ps)
|
||||
{
|
||||
ps->SetCaretEnabled(PR_TRUE);
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument>domDoc;
|
||||
editor->GetDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc)
|
||||
{
|
||||
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
|
||||
if (doc)
|
||||
{
|
||||
doc->SetDisplaySelection(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditorFocusListener::Blur(nsIDOMEvent* aDragEvent)
|
||||
{
|
||||
// turn off selection and caret
|
||||
if (mEditor)
|
||||
{
|
||||
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
||||
if (editor)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell>ps;
|
||||
editor->GetPresShell(getter_AddRefs(ps));
|
||||
if (ps)
|
||||
{
|
||||
ps->SetCaretEnabled(PR_FALSE);
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument>domDoc;
|
||||
editor->GetDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc)
|
||||
{
|
||||
nsCOMPtr<nsIDocument>doc = do_QueryInterface(domDoc);
|
||||
if (doc)
|
||||
{
|
||||
doc->SetDisplaySelection(PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsITextEditor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
@ -195,10 +196,42 @@ public:
|
|||
/*END implementations of dragevent handler interface*/
|
||||
|
||||
protected:
|
||||
nsITextEditor* mEditor; // weak reference
|
||||
|
||||
nsITextEditor* mEditor;
|
||||
|
||||
};
|
||||
|
||||
/** editor Implementation of the FocusListener interface
|
||||
*/
|
||||
class nsTextEditorFocusListener : public nsIDOMFocusListener
|
||||
{
|
||||
public:
|
||||
/** default constructor
|
||||
*/
|
||||
nsTextEditorFocusListener();
|
||||
/** default destructor
|
||||
*/
|
||||
virtual ~nsTextEditorFocusListener();
|
||||
|
||||
/** SetEditor gives an address to the editor that will be accessed
|
||||
* @param aEditor the editor this listener calls for editing operations
|
||||
*/
|
||||
void SetEditor(nsITextEditor *aEditor){mEditor = aEditor;}
|
||||
|
||||
/*interfaces for addref and release and queryinterface*/
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/*BEGIN implementations of focus event handler interface*/
|
||||
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
|
||||
public:
|
||||
virtual nsresult Focus(nsIDOMEvent* aEvent);
|
||||
virtual nsresult Blur(nsIDOMEvent* aEvent);
|
||||
/*END implementations of focus event handler interface*/
|
||||
|
||||
protected:
|
||||
nsITextEditor* mEditor; // weak reference
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** factory for the editor key listener
|
||||
*/
|
||||
|
@ -219,5 +252,10 @@ extern nsresult NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResu
|
|||
/** factory for the editor composition listener
|
||||
*/
|
||||
extern nsresult NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
|
||||
|
||||
/** factory for the editor composition listener
|
||||
*/
|
||||
extern nsresult NS_NewEditorFocusListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
|
||||
|
||||
#endif //editorInterfaces_h__
|
||||
|
||||
|
|
|
@ -34,7 +34,12 @@
|
|||
|
||||
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
|
||||
|
||||
|
||||
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
|
||||
if (mFlags & TEXT_EDITOR_FLAG_READONLY || mFlags & TEXT_EDITOR_FLAG_DISALBED) \
|
||||
{ \
|
||||
*aCancel = PR_TRUE; \
|
||||
return NS_OK; \
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* Constructor/Destructor
|
||||
|
@ -43,6 +48,7 @@ static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
|
|||
nsTextEditRules::nsTextEditRules()
|
||||
{
|
||||
mEditor = nsnull;
|
||||
mFlags=0;
|
||||
}
|
||||
|
||||
nsTextEditRules::~nsTextEditRules()
|
||||
|
@ -58,9 +64,27 @@ nsTextEditRules::~nsTextEditRules()
|
|||
NS_IMETHODIMP
|
||||
nsTextEditRules::Init(nsIEditor *aEditor)
|
||||
{
|
||||
// null aNextRule is ok
|
||||
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
|
||||
mEditor = (nsTextEditor*)aEditor; // we hold a non-refcounted reference back to our editor
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
mEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ASSERTION(selection, "editor cannot get selection");
|
||||
nsresult result = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::GetFlags(PRUint32 *aFlags)
|
||||
{
|
||||
if (!aFlags) { return NS_ERROR_NULL_POINTER; }
|
||||
*aFlags = mFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextEditRules::SetFlags(PRUint32 aFlags)
|
||||
{
|
||||
mFlags = aFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -68,14 +92,15 @@ NS_IMETHODIMP
|
|||
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
||||
nsRulesInfo *aInfo, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aInfo)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aInfo) { return NS_ERROR_NULL_POINTER; }
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
||||
|
||||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return WillInsertBreak(aSelection, aCancel);
|
||||
case kInsertText:
|
||||
return WillInsertText(aSelection,
|
||||
aCancel,
|
||||
|
@ -105,6 +130,8 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection,
|
|||
|
||||
switch (info->action)
|
||||
{
|
||||
case kInsertBreak:
|
||||
return DidInsertBreak(aSelection, aResult);
|
||||
case kInsertText:
|
||||
return DidInsertText(aSelection, aResult);
|
||||
case kDeleteSelection:
|
||||
|
@ -127,6 +154,8 @@ nsresult
|
|||
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
|
@ -148,6 +177,27 @@ nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
if (mFlags & TEXT_EDITOR_FLAG_SINGLELINE) {
|
||||
*aCancel = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
*aCancel = PR_FALSE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
||||
PRBool *aCancel,
|
||||
|
@ -156,8 +206,8 @@ nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
|||
nsString *outString,
|
||||
TypeInState typeInState)
|
||||
{
|
||||
if (!aSelection || !aCancel || !inString || !outString)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!aSelection || !aCancel || !inString || !outString) {return NS_ERROR_NULL_POINTER;}
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out params
|
||||
*aCancel = PR_FALSE;
|
||||
|
@ -442,21 +492,12 @@ nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTa
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
nsresult
|
||||
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
|
||||
{
|
||||
if (!aTag) { return NS_ERROR_NULL_POINTER; }
|
||||
*aTag = NS_NewAtom("BR");
|
||||
return NS_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
|
||||
|
@ -482,71 +523,7 @@ nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResul
|
|||
// insert a special bogus text node with a character in it.
|
||||
if (NS_SUCCEEDED(result)) // only do this work if DeleteSelection completed successfully
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
mEditor->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if ((NS_SUCCEEDED(result)) && nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if ((NS_SUCCEEDED(result)) && bodyNode)
|
||||
{ // now we've got the body tag.
|
||||
// iterate the body tag, looking for editable content
|
||||
// if no editable content is found, insert the bogus node
|
||||
PRBool needsBogusContent=PR_TRUE;
|
||||
nsCOMPtr<nsIDOMNode>bodyChild;
|
||||
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
||||
while ((NS_SUCCEEDED(result)) && bodyChild)
|
||||
{
|
||||
if (PR_TRUE==nsEditor::IsEditable(bodyChild))
|
||||
{
|
||||
needsBogusContent = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode>temp;
|
||||
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
||||
bodyChild = do_QueryInterface(temp);
|
||||
}
|
||||
if (PR_TRUE==needsBogusContent)
|
||||
{
|
||||
// set mBogusNode to be the newly created <P>
|
||||
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
|
||||
getter_AddRefs(mBogusNode));
|
||||
if ((NS_SUCCEEDED(result)) && mBogusNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newTNode;
|
||||
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), mBogusNode, 0,
|
||||
getter_AddRefs(newTNode));
|
||||
if ((NS_SUCCEEDED(result)) && newTNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
|
||||
newNodeAsText = do_QueryInterface(newTNode);
|
||||
if (newNodeAsText)
|
||||
{
|
||||
nsAutoString data;
|
||||
data += 160;
|
||||
newNodeAsText->SetData(data);
|
||||
aSelection->Collapse(newTNode, 0);
|
||||
}
|
||||
}
|
||||
// make sure we know the PNode is bogus
|
||||
nsCOMPtr<nsIDOMElement>newPElement;
|
||||
newPElement = do_QueryInterface(mBogusNode);
|
||||
if (newPElement)
|
||||
{
|
||||
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
||||
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
|
||||
newPElement->SetAttribute(att, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = CreateBogusNodeIfNeeded(aSelection);
|
||||
// if we don't have an empty document, check the selection to see if any collapsing is necessary
|
||||
if (!mBogusNode)
|
||||
{
|
||||
|
@ -615,6 +592,7 @@ nsresult
|
|||
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
@ -666,6 +644,7 @@ nsresult
|
|||
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
||||
{
|
||||
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// initialize out param
|
||||
*aCancel = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
@ -709,7 +688,77 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
|
|||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
|
||||
{
|
||||
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
mEditor->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString bodyTag = "body";
|
||||
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
||||
if ((NS_SUCCEEDED(result)) && nodeList)
|
||||
{
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
||||
nsCOMPtr<nsIDOMNode>bodyNode;
|
||||
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
||||
if ((NS_SUCCEEDED(result)) && bodyNode)
|
||||
{ // now we've got the body tag.
|
||||
// iterate the body tag, looking for editable content
|
||||
// if no editable content is found, insert the bogus node
|
||||
PRBool needsBogusContent=PR_TRUE;
|
||||
nsCOMPtr<nsIDOMNode>bodyChild;
|
||||
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
||||
while ((NS_SUCCEEDED(result)) && bodyChild)
|
||||
{
|
||||
if (PR_TRUE==nsEditor::IsEditable(bodyChild))
|
||||
{
|
||||
needsBogusContent = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode>temp;
|
||||
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
||||
bodyChild = do_QueryInterface(temp);
|
||||
}
|
||||
if (PR_TRUE==needsBogusContent)
|
||||
{
|
||||
// set mBogusNode to be the newly created <P>
|
||||
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
|
||||
getter_AddRefs(mBogusNode));
|
||||
if ((NS_SUCCEEDED(result)) && mBogusNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newTNode;
|
||||
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), mBogusNode, 0,
|
||||
getter_AddRefs(newTNode));
|
||||
if ((NS_SUCCEEDED(result)) && newTNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
|
||||
newNodeAsText = do_QueryInterface(newTNode);
|
||||
if (newNodeAsText)
|
||||
{
|
||||
nsAutoString data;
|
||||
data += 160;
|
||||
newNodeAsText->SetData(data);
|
||||
aSelection->Collapse(newTNode, 0);
|
||||
}
|
||||
}
|
||||
// make sure we know the PNode is bogus
|
||||
nsCOMPtr<nsIDOMElement>newPElement;
|
||||
newPElement = do_QueryInterface(mBogusNode);
|
||||
if (newPElement)
|
||||
{
|
||||
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
||||
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
|
||||
newPElement->SetAttribute(att, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
NS_IMETHOD Init(nsIEditor *aEditor);
|
||||
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel);
|
||||
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags);
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags);
|
||||
|
||||
// nsTextEditRules action id's
|
||||
enum
|
||||
|
@ -57,7 +59,8 @@ public:
|
|||
kUndo = 1000,
|
||||
kRedo = 1001,
|
||||
kInsertText = 2000,
|
||||
kDeleteSelection = 2001
|
||||
kDeleteSelection = 2001,
|
||||
kInsertBreak = 2002
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -72,6 +75,9 @@ protected:
|
|||
nsresult DidInsertText(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
nsresult CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState);
|
||||
|
||||
nsresult WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel);
|
||||
nsresult DidInsert(nsIDOMSelection *aSelection, nsresult aResult);
|
||||
|
||||
|
@ -112,10 +118,14 @@ protected:
|
|||
nsresult InsertStyleAndNewTextNode(nsIDOMNode *aParentNode,
|
||||
nsIAtom *aTag,
|
||||
nsIDOMSelection *aSelection);
|
||||
|
||||
/** creates a bogus text node if the document has no editable content */
|
||||
nsresult CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection);
|
||||
|
||||
// data
|
||||
nsTextEditor *mEditor; // note that we do not refcount the editor
|
||||
nsCOMPtr<nsIDOMNode> mBogusNode; // magic node acts as placeholder in empty doc
|
||||
PRUint32 mFlags;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -163,4 +163,3 @@ nsTSDNotifier::DidJoinNodes(nsIDOMNode *aLeftNode,
|
|||
|
||||
return mDoc->JoinNodes(aLeftNode, aRightNode, aParent);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
nsIDOMNode *aRightNode,
|
||||
nsIDOMNode *aParent,
|
||||
nsresult aResult);
|
||||
|
||||
};
|
||||
|
||||
#endif // nsTSDNotifier_h__
|
||||
|
|
|
@ -37,6 +37,10 @@ Editor Action Listener interface to outside world
|
|||
* <P>
|
||||
* nsIEditActionListener is the interface used by applications wishing to be notified
|
||||
* when the editor modifies the DOM tree.
|
||||
*
|
||||
* Note: this is the wrong class to implement if you are interested in generic
|
||||
* change notifications. For generic notifications, you should implement
|
||||
* nsIDocumentObserver.
|
||||
*/
|
||||
class nsIEditActionListener : public nsISupports{
|
||||
public:
|
||||
|
@ -126,7 +130,6 @@ public:
|
|||
nsIDOMNode *aRightNode,
|
||||
nsIDOMNode *aParent,
|
||||
nsresult aResult)=0;
|
||||
|
||||
};
|
||||
|
||||
#endif //nsIEditActionListener_h__
|
||||
|
|
|
@ -47,10 +47,11 @@ public:
|
|||
|
||||
typedef enum {eSaveFileText = 0, eSaveFileHTML = 1 } ESaveFileType;
|
||||
|
||||
/** Initialize the text editor
|
||||
/** Initialize the HTML editor
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell )=0;
|
||||
NS_IMETHOD Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell)=0;
|
||||
|
||||
// Methods shared with nsITextEditor (see nsITextEditor.h for details)
|
||||
NS_IMETHOD SetTextProperty(nsIAtom *aProperty,
|
||||
|
|
|
@ -32,6 +32,11 @@ class nsIAtom;
|
|||
class nsIOutputStream;
|
||||
class nsString;
|
||||
|
||||
#define TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text entry is allowed via events
|
||||
#define TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
|
||||
#define TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
|
||||
#define TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
|
||||
#define TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
|
||||
/**
|
||||
* The general text editor interface.
|
||||
* <P>
|
||||
|
@ -42,17 +47,24 @@ class nsString;
|
|||
* a single line plain text editor is instantiated by using the SingleLinePlainTextGUIManager
|
||||
* to limit UI and the SingleLinePlainTextEditRules to filter input and output.
|
||||
*/
|
||||
class nsITextEditor : public nsISupports {
|
||||
class nsITextEditor : public nsISupports
|
||||
{
|
||||
public:
|
||||
typedef enum {ePlainText=0, eRichText=1} TextType;
|
||||
typedef enum {eSingleLine=0, eMultipleLines=1, ePassword=2} EditorType;
|
||||
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_ITEXTEDITOR_IID; return iid; }
|
||||
|
||||
/** Initialize the text editor
|
||||
*
|
||||
* @param aDoc the document being edited. Cannot be changed after Init
|
||||
* @param aPresShell the presentation shell displaying aDoc. Cannot be changed after Init
|
||||
*/
|
||||
NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)=0;
|
||||
NS_IMETHOD Init(nsIDOMDocument *aDoc,
|
||||
nsIPresShell *aPresShell)=0;
|
||||
|
||||
/** return the edit flags for this editor */
|
||||
NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;
|
||||
|
||||
/** set the edit flags for this editor. May be called at any time. */
|
||||
NS_IMETHOD SetFlags(PRUint32 aFlags)=0;
|
||||
|
||||
/**
|
||||
* SetTextProperties() sets the aggregate properties on the current selection
|
||||
|
@ -117,6 +129,14 @@ public:
|
|||
*/
|
||||
NS_IMETHOD InsertText(const nsString& aStringToInsert)=0;
|
||||
|
||||
/**
|
||||
* SetMaxTextLength sets a limit on the number of characters the document is allowed to contain.
|
||||
* Any text insertion will truncate the inserted string to respect this number
|
||||
* It is somewhat expensive to set this property, so do so only when necessary.
|
||||
* A value of -1 means there is no limit.
|
||||
*/
|
||||
NS_IMETHOD SetMaxTextLength(PRInt32 aMaxLength)=0;
|
||||
|
||||
/**
|
||||
* The handler for the ENTER key.
|
||||
* @see nsIEditor::InsertBreak
|
||||
|
|
|
@ -163,4 +163,3 @@ nsTSDNotifier::DidJoinNodes(nsIDOMNode *aLeftNode,
|
|||
|
||||
return mDoc->JoinNodes(aLeftNode, aRightNode, aParent);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
nsIDOMNode *aRightNode,
|
||||
nsIDOMNode *aParent,
|
||||
nsresult aResult);
|
||||
|
||||
};
|
||||
|
||||
#endif // nsTSDNotifier_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче