Cleanup in preparation for the actual fix for bug 283897. r=brade@comcast.net, sr=bzbarsky@mit.edu

This commit is contained in:
jst%mozilla.jstenback.com 2005-03-24 19:00:01 +00:00
parent 5bde169b94
commit 006a859d7d
13 changed files with 584 additions and 726 deletions

View File

@ -41,6 +41,7 @@
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMEventReceiver.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsUnicharUtils.h"
@ -54,6 +55,14 @@
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMRange.h"
#include "nsIDOM3EventTarget.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMEventGroup.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsIDOMDragListener.h"
#include "nsIDocument.h"
#include "nsITransactionManager.h"
#include "nsIAbsorbingTransaction.h"
@ -142,7 +151,6 @@ nsEditor::nsEditor()
, mSavedSel()
, mRangeUpdater()
, mShouldTxnSetSelection(PR_TRUE)
, mBodyElement(nsnull)
, mAction(nsnull)
, mDirection(eNone)
, mInIMEMode(PR_FALSE)
@ -269,11 +277,9 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
if (!ps) return NS_ERROR_NOT_INITIALIZED;
//set up body element if we are passed one.
//set up root element if we are passed one.
if (aRoot)
mBodyElement = do_QueryInterface(aRoot);
mRootElement = do_QueryInterface(aRoot);
// Set up the DTD
// XXX - in the long run we want to get this from the document, but there
@ -331,6 +337,17 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot
NS_IMETHODIMP
nsEditor::PostCreate()
{
nsresult rv = CreateEventListeners();
if (NS_FAILED(rv))
{
RemoveEventListeners();
return rv;
}
rv = InstallEventListeners();
NS_ENSURE_SUCCESS(rv, rv);
// nuke the modification count, so the doc appears unmodified
// do this before we notify listeners
ResetModificationCount();
@ -345,12 +362,132 @@ nsEditor::PostCreate()
return NS_OK;
}
nsresult
nsEditor::InstallEventListeners()
{
NS_ENSURE_TRUE(mDocWeak && mPresShellWeak && mKeyListenerP &&
mMouseListenerP && mFocusListenerP && mTextListenerP &&
mCompositionListenerP && mDragListenerP,
NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
if (!erP) {
RemoveEventListeners();
return NS_ERROR_FAILURE;
}
nsresult rv = NS_OK;
// register the event listeners with the DOM event reveiver
nsCOMPtr<nsIDOM3EventTarget> dom3Targ(do_QueryInterface(erP));
nsCOMPtr<nsIDOMEventGroup> sysGroup;
erP->GetSystemEventGroup(getter_AddRefs(sysGroup));
if (sysGroup)
{
rv = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"),
mKeyListenerP, PR_FALSE, sysGroup);
NS_ASSERTION(NS_SUCCEEDED(rv),
"failed to register key listener in system group");
}
rv |= erP->AddEventListenerByIID(mMouseListenerP,
NS_GET_IID(nsIDOMMouseListener));
rv |= erP->AddEventListenerByIID(mFocusListenerP,
NS_GET_IID(nsIDOMFocusListener));
rv |= erP->AddEventListenerByIID(mTextListenerP,
NS_GET_IID(nsIDOMTextListener));
rv |= erP->AddEventListenerByIID(mCompositionListenerP,
NS_GET_IID(nsIDOMCompositionListener));
rv |= erP->AddEventListenerByIID(mDragListenerP,
NS_GET_IID(nsIDOMDragListener));
if (NS_FAILED(rv))
{
NS_ERROR("failed to register some event listeners");
RemoveEventListeners();
}
return rv;
}
void
nsEditor::RemoveEventListeners()
{
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
if (erP)
{
// unregister the event listeners with the DOM event reveiver
if (mKeyListenerP)
{
nsCOMPtr<nsIDOMEventGroup> sysGroup;
erP->GetSystemEventGroup(getter_AddRefs(sysGroup));
if (sysGroup)
{
nsCOMPtr<nsIDOM3EventTarget> dom3Targ(do_QueryInterface(erP));
dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"),
mKeyListenerP, PR_FALSE,
sysGroup);
}
}
if (mMouseListenerP)
{
erP->RemoveEventListenerByIID(mMouseListenerP,
NS_GET_IID(nsIDOMMouseListener));
}
if (mFocusListenerP)
{
erP->RemoveEventListenerByIID(mFocusListenerP,
NS_GET_IID(nsIDOMFocusListener));
}
if (mTextListenerP)
{
erP->RemoveEventListenerByIID(mTextListenerP,
NS_GET_IID(nsIDOMTextListener));
}
if (mCompositionListenerP)
{
erP->RemoveEventListenerByIID(mCompositionListenerP,
NS_GET_IID(nsIDOMCompositionListener));
}
if (mDragListenerP)
{
erP->RemoveEventListenerByIID(mDragListenerP,
NS_GET_IID(nsIDOMDragListener));
}
}
mKeyListenerP = nsnull;
mMouseListenerP = nsnull;
mFocusListenerP = nsnull;
mTextListenerP = nsnull;
mCompositionListenerP = nsnull;
mDragListenerP = nsnull;
}
NS_IMETHODIMP
nsEditor::PreDestroy()
{
// tell our listeners that the doc is going away
NotifyDocumentListeners(eDocumentToBeDestroyed);
// Unregister event listeners
RemoveEventListeners();
return NS_OK;
}
@ -854,15 +991,17 @@ nsEditor::SetShouldTxnSetSelection(PRBool aShould)
NS_IMETHODIMP
nsEditor::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty)
{
nsCOMPtr<nsIDOMElement> rootElement;
nsresult res = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res)) return res;
if (!rootElement) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
nsCOMPtr<nsIDOMNode> firstChild;
res = rootNode->GetFirstChild(getter_AddRefs(firstChild));
*aDocumentIsEmpty = PR_TRUE;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
PRBool hasChildNodes;
nsresult res = rootElement->HasChildNodes(&hasChildNodes);
*aDocumentIsEmpty = !hasChildNodes;
*aDocumentIsEmpty = NS_SUCCEEDED(res) && firstChild;
return res;
}
@ -897,10 +1036,9 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument()
return NS_ERROR_NOT_INITIALIZED;
// get the root element
nsCOMPtr<nsIDOMElement> rootElement;
result = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(result)) return result;
if (!rootElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
// find first editable thingy
nsCOMPtr<nsIDOMNode> firstNode;
@ -926,7 +1064,7 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument()
}
else
{
// just the body node, set selection to inside the body
// just the root node, set selection to inside the root
result = selection->Collapse(rootElement, 0);
}
return result;
@ -937,7 +1075,7 @@ nsEditor::EndOfDocument()
{
if (!mDocWeak || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
nsresult res;
// get selection
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
@ -945,19 +1083,17 @@ nsEditor::EndOfDocument()
if (!selection) return NS_ERROR_NULL_POINTER;
// get the root element
nsCOMPtr<nsIDOMElement> rootElement;
res = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res)) return res;
if (!rootElement) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
// get the length of the rot element
PRUint32 len;
res = GetLengthOfDOMNode(rootNode, len);
if (NS_FAILED(res)) return res;
res = GetLengthOfDOMNode(rootElement, len);
if (NS_FAILED(res)) return res;
// set the selection to after the last child of the root element
return selection->Collapse(rootNode, (PRInt32)len);
return selection->Collapse(rootElement, (PRInt32)len);
}
NS_IMETHODIMP
@ -1798,7 +1934,7 @@ NS_IMETHODIMP
nsEditor::DumpContentTree()
{
#ifdef DEBUG
nsCOMPtr<nsIContent> root = do_QueryInterface(mBodyElement);
nsCOMPtr<nsIContent> root = do_QueryInterface(mRootElement);
if (root) root->List(stdout);
#endif
return NS_OK;
@ -2073,7 +2209,7 @@ nsEditor::GetKBStateControl(nsIKBStateControl **aKBSC)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIWidget> widget;
res = GetEditorContentWindow(shell, mBodyElement, getter_AddRefs(widget));
res = GetEditorContentWindow(shell, GetRoot(), getter_AddRefs(widget));
if (NS_FAILED(res))
return res;
@ -2224,40 +2360,40 @@ nsEditor::GetQueryCaretRect(nsQueryCaretRectEventReply* aReply)
/* Non-interface, public methods */
// This seems like too much work! There should be a "nsDOMDocument::GetBody()"
// Have a look in nsHTMLDocument. Maybe add it to nsIHTMLDocument.
NS_IMETHODIMP
nsEditor::GetRootElement(nsIDOMElement **aBodyElement)
nsEditor::GetRootElement(nsIDOMElement **aRootElement)
{
if (!aBodyElement)
if (!aRootElement)
return NS_ERROR_NULL_POINTER;
*aBodyElement = 0;
if (mBodyElement)
if (mRootElement)
{
// if we have cached the body element, use that
*aBodyElement = mBodyElement;
NS_ADDREF(*aBodyElement);
*aRootElement = mRootElement;
NS_ADDREF(*aRootElement);
return NS_OK;
}
*aRootElement = 0;
NS_PRECONDITION(mDocWeak, "bad state, null mDocWeak");
nsCOMPtr<nsIDOMHTMLDocument> doc = do_QueryReferent(mDocWeak);
if (!doc) return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIDOMHTMLElement>bodyElement;
// Use the documents body element as the editor root if we didn't
// get a root element during initialization.
nsCOMPtr<nsIDOMHTMLElement> bodyElement;
nsresult result = doc->GetBody(getter_AddRefs(bodyElement));
if (NS_FAILED(result))
return result;
if (!bodyElement)
return NS_ERROR_NULL_POINTER;
// Use the first body node in the list:
mBodyElement = do_QueryInterface(bodyElement);
*aBodyElement = bodyElement;
NS_ADDREF(*aBodyElement);
mRootElement = bodyElement;
*aRootElement = bodyElement;
NS_ADDREF(*aRootElement);
return NS_OK;
}
@ -2335,15 +2471,14 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
// Use transaction system for undo only if destination
// is already in the document
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult result = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(result)) return result;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
PRBool destInBody = PR_TRUE;
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement);
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
nsCOMPtr<nsIDOMNode> p = aDestNode;
while (p && p!= bodyNode)
while (p && p != rootNode)
{
nsCOMPtr<nsIDOMNode> tmp;
if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp)
@ -2380,6 +2515,9 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
}
}
}
nsresult result = NS_OK;
// Set just the attributes that the source element has
for (i = 0; i < sourceCount; i++)
{
@ -2653,20 +2791,11 @@ NS_IMETHODIMP nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToIns
NS_IMETHODIMP nsEditor::SelectEntireDocument(nsISelection *aSelection)
{
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsIDOMElement>bodyElement;
nsresult result = GetRootElement(getter_AddRefs(bodyElement));
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
if (bodyNode)
{
result = aSelection->SelectAllChildren(bodyNode);
}
else {
return NS_ERROR_NO_INTERFACE;
}
}
return result;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement) { return NS_ERROR_NOT_INITIALIZED; }
return aSelection->SelectAllChildren(rootElement);
}
@ -3737,27 +3866,21 @@ nsEditor::IsRootNode(nsIDOMNode *inNode)
if (!inNode)
return PR_FALSE;
nsCOMPtr<nsIDOMElement> rootElement;
nsresult result = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(result) || !rootElement)
return PR_FALSE;
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
return inNode == rootNode.get();
return inNode == rootNode;
}
PRBool
nsEditor::IsDescendantOfBody(nsIDOMNode *inNode)
{
if (!inNode) return PR_FALSE;
nsCOMPtr<nsIDOMElement> junk;
if (!mBodyElement) GetRootElement(getter_AddRefs(junk));
if (!mBodyElement) return PR_FALSE;
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(mBodyElement);
nsIDOMElement *rootElement = GetRoot();
if (!rootElement) return PR_FALSE;
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElement);
if (inNode == root.get()) return PR_TRUE;
nsCOMPtr<nsIDOMNode> parent, node = do_QueryInterface(inNode);
@ -5275,15 +5398,68 @@ nsEditor::HandleInlineSpellCheck(PRInt32 action,
aEndOffset) : NS_OK;
}
already_AddRefed<nsIDOMEventReceiver>
nsEditor::GetDOMEventReceiver()
{
nsIDOMEventReceiver *erp = nsnull;
nsIDOMElement *rootElement = GetRoot();
// Now hack to make sure we are not anonymous content.
// If we are grab the parent of root element for our observer.
nsCOMPtr<nsIContent> content = do_QueryInterface(rootElement);
if (content)
{
nsIContent* parent = content->GetParent();
if (parent)
{
if (parent->IndexOf(content) < 0)
{
// this will put listener on the form element basically
CallQueryInterface(parent, &erp);
}
}
}
if (!erp)
{
// Don't use getDocument here, because we have no way of knowing
// if Init() was ever called. So we need to get the document
// ourselves, if it exists.
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryReferent(mDocWeak);
if (domdoc)
{
CallQueryInterface(domdoc, &erp);
}
}
return erp;
}
nsIDOMElement *
nsEditor::GetRoot()
{
if (!mRootElement)
{
nsCOMPtr<nsIDOMElement> root;
// Let GetRootElement() do the work
GetRootElement(getter_AddRefs(root));
}
return mRootElement;
}
NS_IMETHODIMP
nsEditor::SwitchTextDirection()
{
// Get the current body direction from its frame
nsCOMPtr<nsIDOMElement> rootElement;
nsresult rv = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(rv))
return rv;
// Get the current root direction from its frame
nsIDOMElement *rootElement = GetRoot();
nsresult rv;
nsCOMPtr<nsIContent> content = do_QueryInterface(rootElement, &rv);
if (NS_FAILED(rv))
return rv;

View File

@ -85,6 +85,7 @@ class AddStyleSheetTxn;
class RemoveStyleSheetTxn;
class nsIFile;
class nsISelectionController;
class nsIDOMEventReceiver;
#define kMOZEditorBogusNodeAttr NS_LITERAL_STRING("_moz_editor_bogus_node")
#define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
@ -331,6 +332,16 @@ protected:
// Get nsIKBStateControl interface
nsresult GetKBStateControl(nsIKBStateControl **aKBSC);
// install the event listeners for the editor
nsresult InstallEventListeners();
virtual nsresult CreateEventListeners() = 0;
// unregister and release our event listeners
virtual void RemoveEventListeners();
public:
/** All editor operations which alter the doc should be prefaced
@ -558,6 +569,11 @@ public:
nsIDOMNode *aEndNode,
PRInt32 aEndOffset);
already_AddRefed<nsIDOMEventReceiver> GetDOMEventReceiver();
// Fast non-refcounting editor root element accessor
nsIDOMElement *GetRoot();
public:
// Argh! These transaction names are used by PlaceholderTxn and
// nsPlaintextEditor. They should be localized to those classes.
@ -583,7 +599,7 @@ protected:
nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset
nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges
PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
nsCOMPtr<nsIDOMElement> mBodyElement; // cached body node
nsCOMPtr<nsIDOMElement> mRootElement; // cached root node
PRInt32 mAction; // the current editor action
EDirection mDirection; // the current direction of editor action
@ -608,6 +624,13 @@ protected:
nsString* mPhonetic;
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
nsCOMPtr<nsIDOMEventListener> mTextListenerP;
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
nsCOMPtr<nsIDOMEventListener> mFocusListenerP;
static PRInt32 gInstanceCount;
friend PRBool NSCanUnload(nsISupports* serviceMgr);

View File

@ -321,16 +321,14 @@ nsHTMLEditor::HideGrabber()
// get the root content node.
nsCOMPtr<nsIDOMElement> bodyElement;
res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(bodyElement);
if (!bodyContent) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(rootElement);
if (!rootContent) return NS_ERROR_NULL_POINTER;
DeleteRefToAnonymousNode(mGrabber, bodyContent, docObserver);
DeleteRefToAnonymousNode(mGrabber, rootContent, docObserver);
mGrabber = nsnull;
DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver);
DeleteRefToAnonymousNode(mPositioningShadow, rootContent, docObserver);
mPositioningShadow = nsnull;
return NS_OK;
@ -352,12 +350,10 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
// first, let's keep track of that element...
mAbsolutelyPositionedObject = aElement;
nsCOMPtr<nsIDOMElement> bodyElement;
res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement) return NS_ERROR_NULL_POINTER;
res = CreateGrabber(bodyElement, getter_AddRefs(mGrabber));
res = CreateGrabber(rootElement, getter_AddRefs(mGrabber));
if (NS_FAILED(res)) return res;
// and set its position
return RefreshGrabber();
@ -366,14 +362,12 @@ nsHTMLEditor::ShowGrabberOnElement(nsIDOMElement * aElement)
nsresult
nsHTMLEditor::StartMoving(nsIDOMElement *aHandle)
{
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult result = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(result)) return result;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement) return NS_ERROR_NULL_POINTER;
// now, let's create the resizing shadow
result = CreateShadow(getter_AddRefs(mPositioningShadow), bodyElement,
mAbsolutelyPositionedObject);
nsresult result = CreateShadow(getter_AddRefs(mPositioningShadow),
rootElement, mAbsolutelyPositionedObject);
if (NS_FAILED(result)) return result;
result = SetShadowPosition(mPositioningShadow, mAbsolutelyPositionedObject,
mPositionedObjectX, mPositionedObjectY);
@ -412,15 +406,13 @@ nsHTMLEditor::GrabberClicked()
mMouseMotionListenerP = new ResizerMouseMotionListener(this);
if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;}
nsCOMPtr<nsIDOMEventReceiver> erP;
res = GetDOMEventReceiver(getter_AddRefs(erP));
if (NS_SUCCEEDED(res ))
{
res = erP->AddEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener));
NS_ASSERTION(NS_SUCCEEDED(res), "failed to register mouse motion listener");
}
else
HandleEventListenerError();
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
NS_ENSURE_TRUE(erP, NS_ERROR_FAILURE);
res = erP->AddEventListenerByIID(mMouseMotionListenerP,
NS_GET_IID(nsIDOMMouseMotionListener));
NS_ASSERTION(NS_SUCCEEDED(res),
"failed to register mouse motion listener");
}
mGrabberClicked = PR_TRUE;
return res;
@ -438,21 +430,21 @@ nsHTMLEditor::EndMoving()
// get the root content node.
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
if (!bodyContent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> rootContent( do_QueryInterface(rootElement) );
if (!rootContent) return NS_ERROR_FAILURE;
DeleteRefToAnonymousNode(mPositioningShadow, bodyContent, docObserver);
DeleteRefToAnonymousNode(mPositioningShadow, rootContent, docObserver);
mPositioningShadow = nsnull;
}
nsCOMPtr<nsIDOMEventReceiver> erP;
nsresult res = GetDOMEventReceiver(getter_AddRefs(erP));
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
if (NS_SUCCEEDED(res) && erP && mMouseMotionListenerP) {
res = erP->RemoveEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener));
if (erP && mMouseMotionListenerP) {
#ifdef DEBUG
nsresult res =
#endif
erP->RemoveEventListenerByIID(mMouseMotionListenerP, NS_GET_IID(nsIDOMMouseMotionListener));
NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener");
}
mMouseMotionListenerP = nsnull;

View File

@ -274,11 +274,8 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
if (!mUtilRange) return NS_ERROR_NULL_POINTER;
// set up mDocChangeRange to be whole doc
nsCOMPtr<nsIDOMElement> bodyElem;
nsCOMPtr<nsIDOMNode> bodyNode;
mHTMLEditor->GetRootElement(getter_AddRefs(bodyElem));
bodyNode = do_QueryInterface(bodyElem);
if (bodyNode)
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
if (rootElem)
{
// temporarily turn off rules sniffing
nsAutoLockRulesSniffing lockIt((nsTextEditRules*)this);
@ -287,7 +284,7 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
mDocChangeRange = do_CreateInstance("@mozilla.org/content/range;1");
if (!mDocChangeRange) return NS_ERROR_NULL_POINTER;
}
mDocChangeRange->SelectNode(bodyNode);
mDocChangeRange->SelectNode(rootElem);
res = AdjustSpecialBreaks();
if (NS_FAILED(res)) return res;
}
@ -792,10 +789,11 @@ nsHTMLEditRules::GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign)
// get selection location
nsCOMPtr<nsIDOMNode> parent;
nsCOMPtr<nsIDOMElement> rootElem;
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
if (!rootElem)
return NS_ERROR_FAILURE;
PRInt32 offset, rootOffset;
res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem));
if (NS_FAILED(res)) return res;
res = nsEditor::GetNodeLocation(rootElem, address_of(parent), &rootOffset);
if (NS_FAILED(res)) return res;
res = mHTMLEditor->GetStartNodeAndOffset(selection, address_of(parent), &offset);
@ -994,12 +992,10 @@ nsHTMLEditRules::GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent)
// gather up info we need for test
nsCOMPtr<nsIDOMNode> parent, tmp, root;
nsCOMPtr<nsIDOMElement> rootElem;
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
if (!rootElem) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISelection> selection;
PRInt32 selOffset;
res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem));
if (NS_FAILED(res)) return res;
if (!rootElem) return NS_ERROR_NULL_POINTER;
root = do_QueryInterface(rootElem);
if (!root) return NS_ERROR_NO_INTERFACE;
res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
@ -1092,9 +1088,7 @@ nsHTMLEditRules::GetParagraphState(PRBool *aMixed, nsAString &outFormat)
}
// remember root node
nsCOMPtr<nsIDOMElement> rootElem;
res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElem));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
if (!rootElem) return NS_ERROR_NULL_POINTER;
// loop through the nodes in selection and examine their paragraph format
@ -1869,17 +1863,13 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!startNode) return NS_ERROR_FAILURE;
// get the root element
nsCOMPtr<nsIDOMElement> bodyNode;
{
res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyNode));
if (NS_FAILED(res)) return res;
if (!bodyNode) return NS_ERROR_UNEXPECTED;
}
nsIDOMElement *rootNode = mHTMLEditor->GetRoot();
if (!rootNode) return NS_ERROR_UNEXPECTED;
if (bCollapsed)
{
// if we are inside an empty block, delete it.
res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled);
res = CheckForEmptyBlock(startNode, rootNode, aSelection, aHandled);
if (NS_FAILED(res)) return res;
if (*aHandled) return NS_OK;
@ -3313,7 +3303,7 @@ nsHTMLEditRules::WillMakeBasicBlock(nsISelection *aSelection,
res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(parent), &offset);
if (NS_FAILED(res)) return res;
if (tString.EqualsLiteral("normal") ||
tString.IsEmpty() ) // we are removing blocks (going to "body text")
tString.IsEmpty() ) // we are removing blocks (going to "body text")
{
nsCOMPtr<nsIDOMNode> curBlock = parent;
if (!IsBlockNode(curBlock))
@ -3822,7 +3812,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
// or whatever is appropriate. Wohoo!
nsCOMPtr<nsIDOMNode> curBlockQuote, firstBQChild, lastBQChild;
PRBool curBlockQuoteIsIndentedWithCSS;
PRBool curBlockQuoteIsIndentedWithCSS = PR_FALSE;
PRInt32 listCount = arrayOfNodes.Count();
PRInt32 i;
nsCOMPtr<nsIDOMNode> curParent;
@ -4921,9 +4911,10 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection)
nsCOMPtr<nsIDOMNode> visNode, firstBRParent;
PRInt32 visOffset=0, firstBROffset=0;
PRInt16 wsType;
nsCOMPtr<nsIDOMElement> rootElement;
res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElement));
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
if (!rootElement)
return NS_ERROR_FAILURE;
// find previous visible thingy before start of selection
if ((selStartNode!=selCommon) && (selStartNode!=rootElement))
{
@ -5507,13 +5498,10 @@ nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange,
{
PRBool bIsEmptyNode = PR_FALSE;
// check for body
nsCOMPtr<nsIDOMElement> bodyElement;
nsCOMPtr<nsIDOMNode> bodyNode;
res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_UNEXPECTED;
bodyNode = do_QueryInterface(bodyElement);
if (block != bodyNode)
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
if (!rootElement) return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
if (block != rootNode)
{
// ok, not body, check if empty
res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, PR_TRUE, PR_FALSE);
@ -7423,9 +7411,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
// check if br can go into the destination node
if (bIsEmptyNode && mHTMLEditor->CanContainTag(selNode, NS_LITERAL_STRING("br")))
{
nsCOMPtr<nsIDOMElement> rootElement;
res = mHTMLEditor->GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
if (!rootElement) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
if (selNode == rootNode)
@ -8003,14 +7989,10 @@ nsresult
nsHTMLEditRules::ConfirmSelectionInBody()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> bodyElement;
nsCOMPtr<nsIDOMNode> bodyNode;
// get the body
res = mHTMLEditor->GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_UNEXPECTED;
bodyNode = do_QueryInterface(bodyElement);
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
if (!rootElement) return NS_ERROR_UNEXPECTED;
// get the selection
nsCOMPtr<nsISelection>selection;
@ -8036,7 +8018,7 @@ nsHTMLEditRules::ConfirmSelectionInBody()
{
// uncomment this to see when we get bad selections
// NS_NOTREACHED("selection not in body");
selection->Collapse(bodyNode,0);
selection->Collapse(rootElement, 0);
}
// get the selection end location
@ -8056,7 +8038,7 @@ nsHTMLEditRules::ConfirmSelectionInBody()
{
// uncomment this to see when we get bad selections
// NS_NOTREACHED("selection not in body");
selection->Collapse(bodyNode,0);
selection->Collapse(rootElement, 0);
}
return res;

View File

@ -168,8 +168,9 @@ nsHTMLEditor::nsHTMLEditor()
nsHTMLEditor::~nsHTMLEditor()
{
// remove the rules as an action listener. Else we get a bad ownership loop later on.
// it's ok if the rules aren't a listener; we ignore the error.
// remove the rules as an action listener. Else we get a bad
// ownership loop later on. it's ok if the rules aren't a listener;
// we ignore the error.
nsCOMPtr<nsIEditActionListener> mListener = do_QueryInterface(mRules);
RemoveEditActionListener(mListener);
@ -195,11 +196,12 @@ nsHTMLEditor::~nsHTMLEditor()
NS_IF_RELEASE(mTypeInState);
mSelectionListenerP = nsnull;
if (mHTMLCSSUtils)
delete mHTMLCSSUtils;
delete mHTMLCSSUtils;
// free any default style propItems
RemoveAllDefaultProperties();
RemoveEventListeners();
}
/* static */
@ -315,120 +317,61 @@ NS_IMETHODIMP nsHTMLEditor::Init(nsIDOMDocument *aDoc,
return result;
}
NS_IMETHODIMP
nsHTMLEditor::PostCreate()
nsresult
nsHTMLEditor::CreateEventListeners()
{
nsresult result = InstallEventListeners();
if (NS_FAILED(result)) return result;
nsresult rv = NS_OK;
result = nsEditor::PostCreate();
return result;
}
NS_IMETHODIMP
nsHTMLEditor::InstallEventListeners()
{
NS_ASSERTION(mDocWeak, "no document set on this editor");
if (!mDocWeak) return NS_ERROR_NOT_INITIALIZED;
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
nsresult result;
// get a key listener
result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
// get a mouse listener
result = NS_NewHTMLEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
// get a text listener
result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this);
if (NS_FAILED(result)) {
#ifdef DEBUG_TAGUE
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
#endif
HandleEventListenerError();
return result;
}
// get a composition listener
result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this);
if (NS_FAILED(result)) {
#ifdef DEBUG_TAGUE
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
#endif
HandleEventListenerError();
return result;
}
// get a drag listener
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
// get a focus listener
result = NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
nsCOMPtr<nsIDOMEventReceiver> erP;
result = GetDOMEventReceiver(getter_AddRefs(erP));
//end hack
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
// register the event listeners with the DOM event reveiver
nsCOMPtr<nsIDOM3EventTarget> dom3Targ(do_QueryInterface(erP));
nsCOMPtr<nsIDOMEventGroup> sysGroup;
if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) {
result = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup);
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register key listener in system group");
}
if (NS_SUCCEEDED(result))
if (!mMouseListenerP)
{
result = erP->AddEventListenerByIID(mMouseListenerP, NS_GET_IID(nsIDOMMouseListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse listener");
if (NS_SUCCEEDED(result))
// get a mouse listener
rv = NS_NewHTMLEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
if (NS_FAILED(rv))
{
result = erP->AddEventListenerByIID(mFocusListenerP, NS_GET_IID(nsIDOMFocusListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register focus listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mTextListenerP, NS_GET_IID(nsIDOMTextListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register text listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mCompositionListenerP, NS_GET_IID(nsIDOMCompositionListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register composition listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mDragListenerP, NS_GET_IID(nsIDOMDragListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register drag listener");
}
}
}
return rv;
}
}
if (NS_FAILED(result)) {
HandleEventListenerError();
return nsPlaintextEditor::CreateEventListeners();
}
void
nsHTMLEditor::RemoveEventListeners()
{
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
if (erP)
{
// Both mMouseMotionListenerP and mResizeEventListenerP can be
// registerd with other targets than the DOM event receiver that
// we can reach from here. But nonetheless, unregister the event
// listeners with the DOM event reveiver (if it's registerd with
// other targets, it'll get unregisterd once the target goes
// away).
if (mMouseMotionListenerP)
{
// mMouseMotionListenerP might be registerd either by IID or
// name, unregister by both.
erP->RemoveEventListenerByIID(mMouseMotionListenerP,
NS_GET_IID(nsIDOMMouseMotionListener));
erP->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
mMouseMotionListenerP, PR_TRUE);
}
if (mResizeEventListenerP)
{
erP->RemoveEventListener(NS_LITERAL_STRING("resize"),
mResizeEventListenerP, PR_FALSE);
}
}
return result;
mMouseMotionListenerP = nsnull;
mResizeEventListenerP = nsnull;
nsPlaintextEditor::RemoveEventListeners();
}
NS_IMETHODIMP
@ -472,9 +415,7 @@ NS_IMETHODIMP nsHTMLEditor::BeginningOfDocument()
return NS_ERROR_NOT_INITIALIZED;
// get the root element
nsCOMPtr<nsIDOMElement> rootElement;
res = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement) return NS_ERROR_NULL_POINTER;
// find first editable thingy
@ -1603,63 +1544,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode)
return res;
}
nsresult
nsHTMLEditor::GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver)
{
if (!aEventReceiver)
return NS_ERROR_NULL_POINTER;
*aEventReceiver = 0;
nsCOMPtr<nsIDOMElement> rootElement;
nsresult result = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(result))
return result;
if (!rootElement)
return NS_ERROR_FAILURE;
// Now hack to make sure we are not anonymous content.
// If we are grab the parent of root element for our observer.
nsCOMPtr<nsIContent> content = do_QueryInterface(rootElement);
if (content)
{
nsIContent* parent = content->GetParent();
if (parent)
{
if (parent->IndexOf(content) < 0)
{
rootElement = do_QueryInterface(parent); //this will put listener on the form element basically
result = CallQueryInterface(rootElement, aEventReceiver);
}
else
rootElement = 0; // Let the event receiver work on the document instead of the root element
}
}
else
rootElement = 0;
if (!rootElement && mDocWeak)
{
// Don't use getDocument here, because we have no way of knowing if
// Init() was ever called. So we need to get the document ourselves,
// if it exists.
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryReferent(mDocWeak);
if (!domdoc)
return NS_ERROR_FAILURE;
result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), (void **)aEventReceiver);
}
return result;
}
nsresult
nsHTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(nsISelection *aSelection, nsIDOMNode *aNode)
{
@ -1815,8 +1699,7 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement> bodyElement;
res = GetRootElement(getter_AddRefs(bodyElement));
nsIDOMElement *bodyElement = GetRoot();
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
@ -2476,7 +2359,6 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P
res = NodeIsBlockStatic(nodeToExamine, &isBlock);
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMHTMLHtmlElement> htmlElement;
nsCOMPtr<nsIDOMNode> tmp;
if (aBlockLevel) {
@ -2488,15 +2370,15 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P
}
do {
// retrieve the computed style of background-color for blockParent
mHTMLCSSUtils->GetComputedProperty(blockParent, nsEditProperty::cssBackgroundColor,
mHTMLCSSUtils->GetComputedProperty(blockParent,
nsEditProperty::cssBackgroundColor,
aOutColor);
tmp = blockParent;
tmp.swap(blockParent);
res = tmp->GetParentNode(getter_AddRefs(blockParent));
htmlElement = do_QueryInterface(tmp);
// look at parent if the queried color is transparent and if the node to
// examine is not the root of the document
} while ( aOutColor.EqualsLiteral("transparent") && htmlElement );
if (!htmlElement && aOutColor.EqualsLiteral("transparent")) {
} while (aOutColor.EqualsLiteral("transparent") && blockParent);
if (aOutColor.EqualsLiteral("transparent")) {
// we have hit the root of the document and the color is still transparent !
// Grumble... Let's look at the default background color because that's the
// color we are looking for
@ -2529,11 +2411,10 @@ nsHTMLEditor::GetCSSBackgroundColorState(PRBool *aMixed, nsAString &aOutColor, P
break;
}
}
res = nodeToExamine->GetParentNode(getter_AddRefs(tmp));
tmp.swap(nodeToExamine);
res = tmp->GetParentNode(getter_AddRefs(nodeToExamine));
if (NS_FAILED(res)) return res;
nodeToExamine = tmp;
htmlElement = do_QueryInterface(tmp);
} while ( aOutColor.EqualsLiteral("transparent") && htmlElement );
} while ( aOutColor.EqualsLiteral("transparent") && nodeToExamine );
}
return NS_OK;
}
@ -2578,8 +2459,7 @@ nsHTMLEditor::GetHTMLBackgroundColorState(PRBool *aMixed, nsAString &aOutColor)
}
// If no table or cell found, get page body
res = nsEditor::GetRootElement(getter_AddRefs(element));
if (NS_FAILED(res)) return res;
element = GetRoot();
if (!element) return NS_ERROR_NULL_POINTER;
return element->GetAttribute(styleName, aOutColor);
@ -3504,8 +3384,7 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor)
// If we failed to find a cell, fall through to use originally-found element
} else {
// No table element -- set the background color on the body tag
res = nsEditor::GetRootElement(getter_AddRefs(element));
if (NS_FAILED(res)) return res;
element = GetRoot();
if (!element) return NS_ERROR_NULL_POINTER;
}
// Use the editor method that goes through the transaction system
@ -3519,22 +3398,18 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor)
NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsAString& aAttribute, const nsAString& aValue)
{
nsresult res;
// TODO: Check selection for Cell, Row, Column or table and do color on appropriate level
NS_ASSERTION(mDocWeak, "Missing Editor DOM Document");
// Set the background color attribute on the body tag
nsCOMPtr<nsIDOMElement> bodyElement;
nsIDOMElement *bodyElement = GetRoot();
res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
if (!bodyElement) res = NS_ERROR_NULL_POINTER;
if (NS_SUCCEEDED(res))
{
// Use the editor method that goes through the transaction system
res = SetAttribute(bodyElement, aAttribute, aValue);
}
return res;
if (!bodyElement)
return NS_ERROR_NULL_POINTER;
// Use the editor method that goes through the transaction system
return SetAttribute(bodyElement, aAttribute, aValue);
}
NS_IMETHODIMP
@ -4009,8 +3884,7 @@ nsCOMPtr<nsIDOMNode> nsHTMLEditor::FindUserSelectAllNode(nsIDOMNode *aNode)
{
nsCOMPtr<nsIDOMNode> resultNode; // starts out empty
nsCOMPtr<nsIDOMNode> node = aNode;
nsCOMPtr<nsIDOMElement>root;
GetRootElement(getter_AddRefs(root));
nsIDOMElement *root = GetRoot();
if (!nsEditorUtils::IsDescendantOf(aNode, root))
return nsnull;
@ -4403,31 +4277,23 @@ nsHTMLEditor::TagCanContainTag(const nsAString& aParentTag, const nsAString& aCh
NS_IMETHODIMP
nsHTMLEditor::SelectEntireDocument(nsISelection *aSelection)
{
nsresult res;
if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }
// get body node
nsCOMPtr<nsIDOMElement>bodyElement;
res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
if (!bodyNode) return NS_ERROR_FAILURE;
// get editor root node
nsIDOMElement *rootElement = GetRoot();
// is doc empty?
PRBool bDocIsEmpty;
res = mRules->DocumentIsEmpty(&bDocIsEmpty);
nsresult res = mRules->DocumentIsEmpty(&bDocIsEmpty);
if (NS_FAILED(res)) return res;
if (bDocIsEmpty)
{
// if its empty dont select entire doc - that would select the bogus node
return aSelection->Collapse(bodyNode, 0);
return aSelection->Collapse(rootElement, 0);
}
else
{
return nsEditor::SelectEntireDocument(aSelection);
}
return res;
return nsEditor::SelectEntireDocument(aSelection);
}
@ -4525,10 +4391,10 @@ void nsHTMLEditor::IsTextPropertySetByContent(nsIDOMNode *aNode,
nsCOMPtr<nsIDOMNode>temp;
result = node->GetParentNode(getter_AddRefs(temp));
if (NS_SUCCEEDED(result) && temp) {
node = do_QueryInterface(temp);
node = temp;
}
else {
node = do_QueryInterface(nsnull);
node = nsnull;
}
}
}
@ -4718,17 +4584,6 @@ nsCOMPtr<nsIDOMElement> nsHTMLEditor::FindPreElement()
}
#endif /* PRE_NODE_IN_BODY */
void nsHTMLEditor::HandleEventListenerError()
{
// null out the nsCOMPtrs
mKeyListenerP = nsnull;
mMouseListenerP = nsnull;
mTextListenerP = nsnull;
mDragListenerP = nsnull;
mCompositionListenerP = nsnull;
mFocusListenerP = nsnull;
}
/* this method scans the selection for adjacent text nodes
* and collapses them into a single text node.
* "adjacent" means literally adjacent siblings of the same parent.
@ -4843,14 +4698,11 @@ nsHTMLEditor::GetNextElementByTagName(nsIDOMElement *aCurrentElement,
NS_IMETHODIMP
nsHTMLEditor::SetSelectionAtDocumentStart(nsISelection *aSelection)
{
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_SUCCEEDED(res))
{
if (!bodyElement) return NS_ERROR_NULL_POINTER;
res = aSelection->Collapse(bodyElement,0);
}
return res;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
return aSelection->Collapse(rootElement,0);
}
#ifdef XP_MAC
@ -5061,7 +4913,7 @@ nsHTMLEditor::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLNode: returns the previous editable leaf node, if there is
// one within the <body>
//
//
nsresult
nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, PRBool bNoBlockCrossing)
{

View File

@ -327,10 +327,6 @@ public:
/** Internal, static version */
static nsresult NodeIsBlockStatic(nsIDOMNode *aNode, PRBool *aIsBlock);
/** we override this here to install event listeners */
NS_IMETHOD PostCreate();
NS_IMETHOD GetFlags(PRUint32 *aFlags);
NS_IMETHOD SetFlags(PRUint32 aFlags);
@ -444,12 +440,10 @@ protected:
NS_IMETHOD InitRules();
/** install the event listeners for the editor
* used to be part of Init, but now broken out into a separate method
* called by PostCreate, giving the caller the chance to interpose
* their own listeners before we install our own backstops.
*/
NS_IMETHOD InstallEventListeners();
// Create the event listeners for the editor to install
virtual nsresult CreateEventListeners();
virtual void RemoveEventListeners();
/** returns the layout object (nsIFrame in the real world) for aNode
* @param aNode the content to get a frame for
@ -659,9 +653,6 @@ protected:
PRInt32 aHighWaterMark);
nsIDOMNode* GetArrayEndpoint(PRBool aEnd, nsCOMArray<nsIDOMNode>& aNodeArray);
/** simple utility to handle any error with event listener allocation or registration */
void HandleEventListenerError();
/* small utility routine to test if a break node is visible to user */
PRBool IsVisBreak(nsIDOMNode *aNode);
@ -746,8 +737,6 @@ protected:
nsresult GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstLeaf);
nsresult GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastLeaf);
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
//XXX Kludge: Used to suppress spurious drag/drop events (bug 50703)
PRBool mIgnoreSpuriousDragEvent;
@ -857,7 +846,6 @@ protected:
nsCOMPtr<nsIDOMElement> mResizedObject;
nsCOMPtr<nsIDOMEventListener> mMouseMotionListenerP;
nsCOMPtr<nsIDOMEventListener> mMutationListenerP;
nsCOMPtr<nsISelectionListener> mSelectionListenerP;
nsCOMPtr<nsIDOMEventListener> mResizeEventListenerP;

View File

@ -72,9 +72,7 @@ nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell)
return NS_OK;
// the resizers and the shadow will be anonymous children of the body
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *bodyElement = GetRoot();
if (!bodyElement) return NS_ERROR_NULL_POINTER;
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
@ -129,9 +127,7 @@ nsHTMLEditor::HideInlineTableEditingUI()
// get the root content node.
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = nsEditor::GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *bodyElement = GetRoot();
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
if (!bodyContent) return NS_ERROR_FAILURE;

View File

@ -336,12 +336,11 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
mResizedObject = aResizedElement;
// the resizers and the shadow will be anonymous children of the body
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
nsIDOMElement *bodyElement = GetRoot();
if (!bodyElement) return NS_ERROR_NULL_POINTER;
// let's create the resizers
nsresult res;
res = CreateResizer(getter_AddRefs(mTopLeftHandle),
nsIHTMLObjectResizer::eTopLeft, bodyElement);
if (NS_FAILED(res)) return res;
@ -409,7 +408,7 @@ nsHTMLEditor::ShowResizers(nsIDOMElement *aResizedElement)
if (!global) { return NS_ERROR_NULL_POINTER; }
mResizeEventListenerP = new DocumentResizeEventListener(this);
if (!mResizeEventListenerP) { return NS_ERROR_NULL_POINTER; }
if (!mResizeEventListenerP) { return NS_ERROR_OUT_OF_MEMORY; }
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(global);
res = target->AddEventListener(NS_LITERAL_STRING("resize"), mResizeEventListenerP, PR_FALSE);
@ -432,10 +431,7 @@ nsHTMLEditor::HideResizers(void)
// get the root content node.
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *bodyElement = GetRoot();
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
if (!bodyContent) return NS_ERROR_FAILURE;
@ -463,10 +459,10 @@ nsHTMLEditor::HideResizers(void)
// don't forget to remove the listeners !
nsCOMPtr<nsIDOMEventReceiver> erP;
res = GetDOMEventReceiver(getter_AddRefs(erP));
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
nsresult res;
if (NS_SUCCEEDED(res) && erP && mMouseMotionListenerP)
if (erP && mMouseMotionListenerP)
{
res = erP->RemoveEventListener(NS_LITERAL_STRING("mousemove"), mMouseMotionListenerP, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(res), "failed to remove mouse motion listener");
@ -593,17 +589,17 @@ nsHTMLEditor::StartResizing(nsIDOMElement *aHandle)
// add a mouse move listener to the editor
if (!mMouseMotionListenerP) {
mMouseMotionListenerP = new ResizerMouseMotionListener(this);
if (!mMouseMotionListenerP) {return NS_ERROR_NULL_POINTER;}
nsCOMPtr<nsIDOMEventReceiver> erP;
result = GetDOMEventReceiver(getter_AddRefs(erP));
if (NS_SUCCEEDED(result) && erP)
{
result = erP->AddEventListener(NS_LITERAL_STRING("mousemove"), mMouseMotionListenerP, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse motion listener");
if (!mMouseMotionListenerP) {
return NS_ERROR_OUT_OF_MEMORY;
}
else
HandleEventListenerError();
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
NS_ENSURE_TRUE(erP, NS_ERROR_FAILURE);
result = erP->AddEventListener(NS_LITERAL_STRING("mousemove"),
mMouseMotionListenerP, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(result),
"failed to register mouse motion listener");
}
return result;
}

View File

@ -105,14 +105,13 @@ nsPlaintextEditor::~nsPlaintextEditor()
// Remove event listeners. Note that if we had an HTML editor,
// it installed its own instead of these
nsCOMPtr<nsIDOMEventReceiver> erP;
nsresult result = GetDOMEventReceiver(getter_AddRefs(erP));
if (NS_SUCCEEDED(result) && erP)
nsCOMPtr<nsIDOMEventReceiver> erP = GetDOMEventReceiver();
if (erP)
{
nsCOMPtr<nsIDOM3EventTarget> dom3Targ(do_QueryInterface(erP));
nsCOMPtr<nsIDOMEventGroup> sysGroup;
if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) {
result = dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup);
dom3Targ->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup);
}
if (mMouseListenerP) {
@ -277,119 +276,46 @@ nsPlaintextEditor::SetDocumentCharacterSet(const nsACString & characterSet)
return result;
}
NS_IMETHODIMP
nsPlaintextEditor::PostCreate()
nsresult
nsPlaintextEditor::CreateEventListeners()
{
nsresult result = InstallEventListeners();
if (NS_FAILED(result)) return result;
nsresult rv = NS_OK;
return nsEditor::PostCreate();
}
NS_IMETHODIMP
nsPlaintextEditor::InstallEventListeners()
{
NS_ASSERTION(mDocWeak, "no document set on this editor");
if (!mDocWeak) return NS_ERROR_NOT_INITIALIZED;
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
nsresult result;
// get a key listener
result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
}
// get a mouse listener
result = NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
if (!mMouseListenerP) {
// get a mouse listener
rv |= NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
}
// get a text listener
result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this);
if (NS_FAILED(result)) {
#ifdef DEBUG_TAGUE
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
#endif
HandleEventListenerError();
return result;
if (!mKeyListenerP) {
// get a key listener
rv |= NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
}
// get a composition listener
result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this);
if (NS_FAILED(result)) {
#ifdef DEBUG_TAGUE
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
#endif
HandleEventListenerError();
return result;
if (!mTextListenerP) {
// get a text listener
rv |= NS_NewEditorTextListener(getter_AddRefs(mTextListenerP), this);
}
// get a drag listener
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
if (!mCompositionListenerP) {
// get a composition listener
rv |=
NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),
this);
}
// get a focus listener
result = NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this);
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
if (!mDragListenerP) {
// get a drag listener
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak);
rv |= NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell,
this);
}
nsCOMPtr<nsIDOMEventReceiver> erP;
result = GetDOMEventReceiver(getter_AddRefs(erP));
//end hack
if (NS_FAILED(result)) {
HandleEventListenerError();
return result;
if (!mFocusListenerP) {
// get a focus listener
rv |= NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this);
}
// register the event listeners with the DOM event reveiver
nsCOMPtr<nsIDOM3EventTarget> dom3Targ(do_QueryInterface(erP));
nsCOMPtr<nsIDOMEventGroup> sysGroup;
if (NS_SUCCEEDED(erP->GetSystemEventGroup(getter_AddRefs(sysGroup)))) {
result = dom3Targ->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), mKeyListenerP, PR_FALSE, sysGroup);
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register key listener in system group");
}
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mMouseListenerP, NS_GET_IID(nsIDOMMouseListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register mouse listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mFocusListenerP, NS_GET_IID(nsIDOMFocusListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register focus listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mTextListenerP, NS_GET_IID(nsIDOMTextListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register text listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mCompositionListenerP, NS_GET_IID(nsIDOMCompositionListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register composition listener");
if (NS_SUCCEEDED(result))
{
result = erP->AddEventListenerByIID(mDragListenerP, NS_GET_IID(nsIDOMDragListener));
NS_ASSERTION(NS_SUCCEEDED(result), "failed to register drag listener");
}
}
}
}
}
if (NS_FAILED(result)) {
HandleEventListenerError();
}
return result;
return rv;
}
NS_IMETHODIMP
@ -738,59 +664,6 @@ nsPlaintextEditor::GetAbsoluteOffsetsForPoints(nsIDOMNode *aInStartNode,
return result;
}
nsresult
nsPlaintextEditor::GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver)
{
if (!aEventReceiver)
return NS_ERROR_NULL_POINTER;
*aEventReceiver = 0;
nsCOMPtr<nsIDOMElement> rootElement;
nsresult result = GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(result))
return result;
if (!rootElement)
return NS_ERROR_FAILURE;
// Now hack to make sure we are not anonymous content.
// If we are grab the parent of root element for our observer.
nsCOMPtr<nsIContent> content = do_QueryInterface(rootElement);
if (content)
{
nsCOMPtr<nsIContent> parent = content->GetParent();
if (parent)
{
if (parent->IndexOf(content) < 0 )
{
rootElement = do_QueryInterface(parent); //this will put listener on the form element basically
result = CallQueryInterface(rootElement, aEventReceiver);
}
else
rootElement = 0; // Let the event receiver work on the document instead of the root element
}
}
else
rootElement = 0;
if (!rootElement && mDocWeak)
{
// Don't use getDocument here, because we have no way of knowing if
// Init() was ever called. So we need to get the document ourselves,
// if it exists.
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryReferent(mDocWeak);
if (!domdoc)
return NS_ERROR_FAILURE;
result = domdoc->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), (void **)aEventReceiver);
}
return result;
}
NS_IMETHODIMP nsPlaintextEditor::DeleteSelection(nsIEditor::EDirection aAction)
{
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
@ -1051,26 +924,27 @@ nsPlaintextEditor::GetTextLength(PRInt32 *aCount)
if (docEmpty)
return NS_OK;
// get the body node
nsCOMPtr<nsIDOMElement> bodyElement;
result = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(result)) { return result; }
if (!bodyElement) { return NS_ERROR_NULL_POINTER; }
// get the root node
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
{
return NS_ERROR_NULL_POINTER;
}
// get the offsets of the first and last children of the body node
nsCOMPtr<nsIDOMNode>lastChild;
result = bodyElement->GetLastChild(getter_AddRefs(lastChild));
result = rootElement->GetLastChild(getter_AddRefs(lastChild));
if (NS_FAILED(result)) { return result; }
if (!lastChild) { return NS_ERROR_NULL_POINTER; }
PRInt32 numBodyChildren = 0;
result = GetChildOffset(lastChild, bodyElement, numBodyChildren);
result = GetChildOffset(lastChild, rootElement, numBodyChildren);
if (NS_FAILED(result)) { return result; }
// count
PRInt32 start, end;
result = GetAbsoluteOffsetsForPoints(bodyElement, 0,
bodyElement, numBodyChildren,
bodyElement, start, end);
result = GetAbsoluteOffsetsForPoints(rootElement, 0,
rootElement, numBodyChildren,
rootElement, start, end);
if (NS_SUCCEEDED(result))
{
NS_ASSERTION(0==start, "GetAbsoluteOffsetsForPoints failed to set start correctly.");
@ -1146,15 +1020,14 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn)
// Ought to set a style sheet here ...
// Probably should keep around an mPlaintextStyleSheet for this purpose.
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_NULL_POINTER;
// Get the current style for this body element:
// Get the current style for this root element:
NS_NAMED_LITERAL_STRING(styleName, "style");
nsAutoString styleValue;
res = bodyElement->GetAttribute(styleName, styleValue);
nsresult res = rootElement->GetAttribute(styleName, styleValue);
if (NS_FAILED(res)) return res;
// We'll replace styles for these values:
@ -1202,7 +1075,7 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn)
else
styleValue.AppendLiteral("white-space: pre;");
return bodyElement->SetAttribute(styleName, styleValue);
return rootElement->SetAttribute(styleName, styleValue);
}
@ -1359,8 +1232,7 @@ nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType,
// in which case we set the selection to encompass the root.
else
{
nsCOMPtr<nsIDOMElement> rootElement;
GetRootElement(getter_AddRefs(rootElement));
nsIDOMElement *rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
if (!nsTextEditUtils::IsBody(rootElement))
{
@ -1880,19 +1752,18 @@ NS_IMETHODIMP
nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection)
{
if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }
// is doc empty?
PRBool bDocIsEmpty;
if (NS_SUCCEEDED(mRules->DocumentIsEmpty(&bDocIsEmpty)) && bDocIsEmpty)
{
// get body node
nsCOMPtr<nsIDOMElement>bodyElement;
nsresult res = GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_FAILURE;
// get root node
nsIDOMElement *rootElement = GetRoot();
if (!rootElement)
return NS_ERROR_FAILURE;
// if it's empty don't select entire doc - that would select the bogus node
return aSelection->Collapse(bodyElement, 0);
return aSelection->Collapse(rootElement, 0);
}
return nsEditor::SelectEntireDocument(aSelection);
@ -1931,21 +1802,6 @@ NS_IMETHODIMP nsPlaintextEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports
#pragma mark -
#endif
void nsPlaintextEditor::HandleEventListenerError()
{
// null out the nsCOMPtrs
mKeyListenerP = nsnull;
mMouseListenerP = nsnull;
mTextListenerP = nsnull;
mDragListenerP = nsnull;
mCompositionListenerP = nsnull;
mFocusListenerP = nsnull;
}
#ifdef XP_MAC
#pragma mark -
#endif
nsresult
nsPlaintextEditor::SetAttributeOrEquivalent(nsIDOMElement * aElement,
const nsAString & aAttribute,

View File

@ -111,9 +111,6 @@ public:
NS_IMETHOD SetDocumentCharacterSet(const nsACString & characterSet);
/** we override this here to install event listeners */
NS_IMETHOD PostCreate();
NS_IMETHOD GetFlags(PRUint32 *aFlags);
NS_IMETHOD SetFlags(PRUint32 aFlags);
@ -180,13 +177,9 @@ protected:
NS_IMETHOD InitRules();
void BeginEditorInit();
nsresult EndEditorInit();
/** install the event listeners for the editor
* used to be part of Init, but now broken out into a separate method
* called by PostCreate, giving the caller the chance to interpose
* their own listeners before we install our own backstops.
*/
NS_IMETHOD InstallEventListeners();
// Create the event listeners for the editor to install.
virtual nsresult CreateEventListeners();
/** returns the layout object (nsIFrame in the real world) for aNode
* @param aNode the content to get a frame for
@ -222,14 +215,9 @@ protected:
/** shared outputstring; returns whether selection is collapsed and resulting string */
nsresult SharedOutputString(PRUint32 aFlags, PRBool* aIsCollapsed, nsAString& aResult);
/** simple utility to handle any error with event listener allocation or registration */
void HandleEventListenerError();
/* small utility routine to test the eEditorReadonly bit */
PRBool IsModifiable();
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
//XXX Kludge: Used to suppress spurious drag/drop events (bug 50703)
PRBool mIgnoreSpuriousDragEvent;
NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent) {mIgnoreSpuriousDragEvent = aIgnoreSpuriousDragEvent; return NS_OK;}
@ -238,12 +226,6 @@ protected:
protected:
nsCOMPtr<nsIEditRules> mRules;
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
nsCOMPtr<nsIDOMEventListener> mTextListenerP;
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
nsCOMPtr<nsIDOMEventListener> mFocusListenerP;
PRBool mWrapToWindow;
PRInt32 mWrapColumn;
PRInt32 mMaxTextLength;

View File

@ -93,8 +93,6 @@ nsTextEditRules::nsTextEditRules()
, mPasswordText()
, mPasswordIMEText()
, mPasswordIMEIndex(0)
, mBogusNode(nsnull)
, mBody(nsnull)
, mFlags(0) // initialized to 0 ("no flags set"). Real initial value is given in Init()
, mActionNesting(0)
, mLockRulesSniffing(PR_FALSE)
@ -131,16 +129,12 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
mEditor->GetSelection(getter_AddRefs(selection));
NS_ASSERTION(selection, "editor cannot get selection");
// remember our root node
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = mEditor->GetRootElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;
if (!bodyElement) return NS_ERROR_NULL_POINTER;
mBody = do_QueryInterface(bodyElement);
if (!mBody) return NS_ERROR_FAILURE;
// Cache our body node, if available.
GetBody();
// put in a magic br if needed
res = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
// Put in a magic br if needed. This method handles null selection,
// which should never happen anyway
nsresult res = CreateBogusNodeIfNeeded(selection);
if (NS_FAILED(res)) return res;
if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
@ -149,25 +143,31 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
res = CreateTrailingBRIfNeeded();
if (NS_FAILED(res)) return res;
}
// create a range that is the entire body contents
nsCOMPtr<nsIDOMRange> wholeDoc = do_CreateInstance("@mozilla.org/content/range;1");
if (!wholeDoc) return NS_ERROR_NULL_POINTER;
wholeDoc->SetStart(mBody,0);
nsCOMPtr<nsIDOMNodeList> list;
res = mBody->GetChildNodes(getter_AddRefs(list));
if (NS_FAILED(res)) return res;
if (!list) return NS_ERROR_FAILURE;
PRUint32 listCount;
res = list->GetLength(&listCount);
if (NS_FAILED(res)) return res;
if (mBody)
{
// create a range that is the entire body contents
nsCOMPtr<nsIDOMRange> wholeDoc =
do_CreateInstance("@mozilla.org/content/range;1");
if (!wholeDoc) return NS_ERROR_NULL_POINTER;
wholeDoc->SetStart(mBody,0);
nsCOMPtr<nsIDOMNodeList> list;
res = mBody->GetChildNodes(getter_AddRefs(list));
if (NS_FAILED(res)) return res;
if (!list) return NS_ERROR_FAILURE;
res = wholeDoc->SetEnd(mBody, listCount);
if (NS_FAILED(res)) return res;
PRUint32 listCount;
res = list->GetLength(&listCount);
if (NS_FAILED(res)) return res;
// replace newlines in that range with breaks
return ReplaceNewlines(wholeDoc);
res = wholeDoc->SetEnd(mBody, listCount);
if (NS_FAILED(res)) return res;
// replace newlines in that range with breaks
res = ReplaceNewlines(wholeDoc);
}
return res;
}
NS_IMETHODIMP
@ -368,7 +368,7 @@ nsTextEditRules::DocumentIsEmpty(PRBool *aDocumentIsEmpty)
if (!aDocumentIsEmpty)
return NS_ERROR_NULL_POINTER;
*aDocumentIsEmpty = (mBogusNode.get() != nsnull);
*aDocumentIsEmpty = (mBogusNode != nsnull);
return NS_OK;
}
@ -392,7 +392,7 @@ nsTextEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
if (mBogusNode)
{
mEditor->DeleteNode(mBogusNode);
mBogusNode = do_QueryInterface(nsnull);
mBogusNode = nsnull;
}
return NS_OK;
@ -455,9 +455,7 @@ nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult)
if (NS_FAILED(res)) return res;
// confirm we are at end of document
if (selOffset == 0) return NS_OK; // cant be after a br if we are at offset 0
nsCOMPtr<nsIDOMElement> rootElem;
res = mEditor->GetRootElement(getter_AddRefs(rootElem));
if (NS_FAILED(res)) return res;
nsIDOMElement *rootElem = mEditor->GetRoot();
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem);
if (!root) return NS_ERROR_NULL_POINTER;
@ -950,7 +948,7 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection,
// make sure it is not last node in editfield. If it is, cancel deletion.
if (nextNode && (aCollapsedAction == nsIEditor::eNext) && nsTextEditUtils::IsBreak(nextNode))
{
if (!mBody) return NS_ERROR_NULL_POINTER;
if (!GetBody()) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> lastChild;
res = mBody->GetLastChild(getter_AddRefs(lastChild));
if (lastChild == nextNode)
@ -1025,17 +1023,15 @@ nsTextEditRules:: DidUndo(nsISelection *aSelection, nsresult aResult)
if (NS_SUCCEEDED(res))
{
if (mBogusNode) {
mBogusNode = do_QueryInterface(nsnull);
mBogusNode = nsnull;
}
else
{
nsCOMPtr<nsIDOMElement> theBody;
res = mEditor->GetRootElement(getter_AddRefs(theBody));
if (NS_FAILED(res)) return res;
if (!theBody) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theBody);
nsIDOMElement *theRoot = mEditor->GetRoot();
if (!theRoot) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theRoot);
if (node && mEditor->IsMozEditorBogusNode(node))
mBogusNode = do_QueryInterface(node);
mBogusNode = node;
}
}
return res;
@ -1060,17 +1056,16 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
if (NS_SUCCEEDED(res))
{
if (mBogusNode) {
mBogusNode = do_QueryInterface(nsnull);
mBogusNode = nsnull;
}
else
{
nsCOMPtr<nsIDOMElement> theBody;
res = mEditor->GetRootElement(getter_AddRefs(theBody));
if (NS_FAILED(res)) return res;
if (!theBody) return NS_ERROR_FAILURE;
nsIDOMElement *theRoot = mEditor->GetRoot();
if (!theRoot) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(NS_LITERAL_STRING("div"), getter_AddRefs(nodeList));
res = theRoot->GetElementsByTagName(NS_LITERAL_STRING("div"),
getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
if (nodeList)
{
@ -1078,11 +1073,11 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
nodeList->GetLength(&len);
if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node
nsCOMPtr<nsIDOMNode>node;
nsCOMPtr<nsIDOMNode> node;
nodeList->Item(0, getter_AddRefs(node));
if (!node) return NS_ERROR_NULL_POINTER;
if (mEditor->IsMozEditorBogusNode(node))
mBogusNode = do_QueryInterface(node);
mBogusNode = node;
}
}
}
@ -1213,7 +1208,7 @@ nsTextEditRules::CreateTrailingBRIfNeeded()
// but only if we aren't a single line edit field
if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask)
return NS_OK;
if (!mBody) return NS_ERROR_NULL_POINTER;
if (!GetBody()) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> lastChild;
nsresult res = mBody->GetLastChild(getter_AddRefs(lastChild));
// assuming CreateBogusNodeIfNeeded() has been called first
@ -1242,13 +1237,19 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
// tell rules system to not do any post-processing
nsAutoRules beginRulesSniffing(mEditor, nsEditor::kOpIgnore, nsIEditor::eNone);
if (!mBody) return NS_ERROR_NULL_POINTER;
if (!GetBody())
{
// we don't even have a body yet, don't insert any bogus nodes at
// this point.
return NS_OK;
}
// 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;
nsCOMPtr<nsIDOMNode> bodyChild;
nsresult res = mBody->GetFirstChild(getter_AddRefs(bodyChild));
while ((NS_SUCCEEDED(res)) && bodyChild)
{
@ -1270,7 +1271,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
nsCOMPtr<nsIDOMElement>brElement = do_QueryInterface(newContent);
// set mBogusNode to be the newly created <br>
mBogusNode = do_QueryInterface(brElement);
mBogusNode = brElement;
if (!mBogusNode) return NS_ERROR_NULL_POINTER;
// give it a special attribute
@ -1412,3 +1413,15 @@ nsTextEditRules::CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<ns
}
return res;
}
nsIDOMNode *
nsTextEditRules::GetBody()
{
if (!mBody)
{
// remember our body node
mBody = mEditor->GetRoot();
}
return mBody;
}

View File

@ -170,7 +170,7 @@ protected:
nsresult ReplaceNewlines(nsIDOMRange *aRange);
/** creates a trailing break in the text doc if there is not one already */
nsresult CreateTrailingBRIfNeeded();
nsresult CreateTrailingBRIfNeeded();
/** creates a bogus text node if the document has no editable content */
nsresult CreateBogusNodeIfNeeded(nsISelection *aSelection);
@ -196,6 +196,8 @@ protected:
nsIEditor::EDirection aAction,
PRBool *aCancel);
nsIDOMNode *GetBody();
// data members
nsPlaintextEditor *mEditor; // note that we do not refcount the editor
nsString mPasswordText; // a buffer we use to store the real value of password editors

View File

@ -104,17 +104,17 @@ nsTextEditUtils::HasMozAttr(nsIDOMNode *node)
PRBool
nsTextEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor)
{
if ( node )
if (node)
{
nsCOMPtr<nsIDOMElement> bodyElement;
nsresult res = editor->GetRootElement(getter_AddRefs(bodyElement));
nsCOMPtr<nsIDOMElement> rootElement;
nsresult res = editor->GetRootElement(getter_AddRefs(rootElement));
if (NS_FAILED(res))
return res;
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(bodyElement);
if (!bodyNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
if (!rootNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsIDOMNode> p = node;
while (p && p!= bodyNode)
while (p && p != rootNode)
{
if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp)
return PR_FALSE;