--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -3143,95 +3143,89 @@ nsEditor::GetLengthOfDOMNode(nsIDOMNode
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
*aResultNode = nsnull;
nsCOMPtr<nsINode> parentNode = do_QueryInterface(aParentNode);
NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
*aResultNode = do_QueryInterface(GetPriorNode(parentNode, aOffset,
- aEditableNode, bNoBlockCrossing,
- aActiveEditorRoot));
+ aEditableNode,
+ bNoBlockCrossing));
return NS_OK;
}
nsIContent*
nsEditor::GetPriorNode(nsINode* aParentNode,
PRInt32 aOffset,
bool aEditableNode,
- bool aNoBlockCrossing,
- nsIContent* aActiveEditorRoot)
+ bool aNoBlockCrossing)
{
MOZ_ASSERT(aParentNode);
// If we are at the beginning of the node, or it is a text node, then just
// look before it.
if (!aOffset || aParentNode->NodeType() == nsIDOMNode::TEXT_NODE) {
if (aNoBlockCrossing && IsBlockNode(aParentNode)) {
// If we aren't allowed to cross blocks, don't look before this block.
return nsnull;
}
- return GetPriorNode(aParentNode, aEditableNode,
- aNoBlockCrossing, aActiveEditorRoot);
+ return GetPriorNode(aParentNode, aEditableNode, aNoBlockCrossing);
}
// else look before the child at 'aOffset'
if (nsIContent* child = aParentNode->GetChildAt(aOffset)) {
- return GetPriorNode(child, aEditableNode, aNoBlockCrossing,
- aActiveEditorRoot);
+ return GetPriorNode(child, aEditableNode, aNoBlockCrossing);
}
// unless there isn't one, in which case we are at the end of the node
// and want the deep-right child.
nsIContent* resultNode = GetRightmostChild(aParentNode, aNoBlockCrossing);
if (!resultNode || !aEditableNode || IsEditable(resultNode)) {
return resultNode;
}
// restart the search from the non-editable node we just found
- return GetPriorNode(resultNode, aEditableNode, aNoBlockCrossing, aActiveEditorRoot);
+ return GetPriorNode(resultNode, aEditableNode, aNoBlockCrossing);
}
nsresult
nsEditor::GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
*aResultNode = nsnull;
nsCOMPtr<nsINode> parentNode = do_QueryInterface(aParentNode);
NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
*aResultNode = do_QueryInterface(GetNextNode(parentNode, aOffset,
- aEditableNode, bNoBlockCrossing,
- aActiveEditorRoot));
+ aEditableNode,
+ bNoBlockCrossing));
return NS_OK;
}
nsIContent*
nsEditor::GetNextNode(nsINode* aParentNode,
PRInt32 aOffset,
bool aEditableNode,
- bool aNoBlockCrossing,
- nsIContent* aActiveEditorRoot)
+ bool aNoBlockCrossing)
{
MOZ_ASSERT(aParentNode);
// if aParentNode is a text node, use its location instead
if (aParentNode->NodeType() == nsIDOMNode::TEXT_NODE) {
nsINode* parent = aParentNode->GetNodeParent();
NS_ENSURE_TRUE(parent, nsnull);
aOffset = parent->IndexOf(aParentNode) + 1; // _after_ the text node
@@ -3245,89 +3239,76 @@ nsEditor::GetNextNode(nsINode* aParentNo
return child;
}
nsIContent* resultNode = GetLeftmostChild(child, aNoBlockCrossing);
if (!resultNode) {
return child;
}
- if (!IsDescendantOfRoot(resultNode)) {
+ if (!IsDescendantOfEditorRoot(resultNode)) {
return nsnull;
}
if (!aEditableNode || IsEditable(resultNode)) {
return resultNode;
}
// restart the search from the non-editable node we just found
- return GetNextNode(resultNode, aEditableNode, aNoBlockCrossing,
- aActiveEditorRoot);
+ return GetNextNode(resultNode, aEditableNode, aNoBlockCrossing);
}
// unless there isn't one, in which case we are at the end of the node
// and want the next one.
if (aNoBlockCrossing && IsBlockNode(aParentNode)) {
// don't cross out of parent block
return NS_OK;
}
- return GetNextNode(aParentNode, aEditableNode, aNoBlockCrossing,
- aActiveEditorRoot);
+ return GetNextNode(aParentNode, aEditableNode, aNoBlockCrossing);
}
nsresult
nsEditor::GetPriorNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
NS_ENSURE_TRUE(currentNode, NS_ERROR_NULL_POINTER);
*aResultNode = do_QueryInterface(GetPriorNode(currentNode, aEditableNode,
- bNoBlockCrossing,
- aActiveEditorRoot));
+ bNoBlockCrossing));
return NS_OK;
}
nsIContent*
nsEditor::GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
- bool aNoBlockCrossing /* = false */,
- nsIContent* aActiveEditorRoot /* = null */)
+ bool aNoBlockCrossing /* = false */)
{
MOZ_ASSERT(aCurrentNode);
- if (!IsDescendantOfRoot(aCurrentNode) ||
- (aActiveEditorRoot &&
- !nsContentUtils::ContentIsDescendantOf(aCurrentNode,
- aActiveEditorRoot))) {
+ if (!IsDescendantOfEditorRoot(aCurrentNode)) {
return nsnull;
}
- return FindNode(aCurrentNode, false, aEditableNode, aNoBlockCrossing,
- aActiveEditorRoot);
+ return FindNode(aCurrentNode, false, aEditableNode, aNoBlockCrossing);
}
nsIContent*
nsEditor::FindNextLeafNode(nsINode *aCurrentNode,
bool aGoForward,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
// called only by GetPriorNode so we don't need to check params.
- NS_PRECONDITION(IsDescendantOfRoot(aCurrentNode) &&
- !IsRoot(aCurrentNode) &&
- (!aActiveEditorRoot ||
- nsContentUtils::ContentIsDescendantOf(aCurrentNode,
- aActiveEditorRoot)),
+ NS_PRECONDITION(IsDescendantOfEditorRoot(aCurrentNode) &&
+ !IsEditorRoot(aCurrentNode),
"Bogus arguments");
nsINode* cur = aCurrentNode;
for (;;) {
// if aCurrentNode has a sibling in the right direction, return
// that sibling's closest child (or itself if it has no children)
nsIContent* sibling =
aGoForward ? cur->GetNextSibling() : cur->GetPreviousSibling();
@@ -3346,99 +3327,88 @@ nsEditor::FindNextLeafNode(nsINode *aCu
return leaf;
}
nsINode *parent = cur->GetNodeParent();
if (!parent) {
return nsnull;
}
- NS_ASSERTION(IsDescendantOfRoot(parent),
+ NS_ASSERTION(IsDescendantOfEditorRoot(parent),
"We started with a proper descendant of root, and should stop "
"if we ever hit the root, so we better have a descendant of "
"root now!");
- if (IsRoot(parent) ||
- (bNoBlockCrossing && IsBlockNode(parent)) ||
- parent == aActiveEditorRoot) {
+ if (IsEditorRoot(parent) ||
+ (bNoBlockCrossing && IsBlockNode(parent))) {
return nsnull;
}
cur = parent;
}
NS_NOTREACHED("What part of for(;;) do you not understand?");
return nsnull;
}
nsresult
nsEditor::GetNextNode(nsIDOMNode* aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing,
- nsIContent* aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
if (!currentNode || !aResultNode) {
return NS_ERROR_NULL_POINTER;
}
*aResultNode = do_QueryInterface(GetNextNode(currentNode, aEditableNode,
- bNoBlockCrossing,
- aActiveEditorRoot));
+ bNoBlockCrossing));
return NS_OK;
}
nsIContent*
nsEditor::GetNextNode(nsINode* aCurrentNode,
bool aEditableNode,
- bool bNoBlockCrossing,
- nsIContent* aActiveEditorRoot)
+ bool bNoBlockCrossing)
{
MOZ_ASSERT(aCurrentNode);
- if (!IsDescendantOfRoot(aCurrentNode) ||
- (aActiveEditorRoot &&
- !nsContentUtils::ContentIsDescendantOf(aCurrentNode,
- aActiveEditorRoot))) {
+ if (!IsDescendantOfEditorRoot(aCurrentNode)) {
return nsnull;
}
- return FindNode(aCurrentNode, true, aEditableNode, bNoBlockCrossing,
- aActiveEditorRoot);
+ return FindNode(aCurrentNode, true, aEditableNode, bNoBlockCrossing);
}
nsIContent*
nsEditor::FindNode(nsINode *aCurrentNode,
bool aGoForward,
bool aEditableNode,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot)
-{
- if (IsRoot(aCurrentNode) || aCurrentNode == aActiveEditorRoot) {
+ bool bNoBlockCrossing)
+{
+ if (IsEditorRoot(aCurrentNode)) {
// Don't allow traversal above the root node! This helps
// prevent us from accidentally editing browser content
// when the editor is in a text widget.
return nsnull;
}
nsIContent* candidate =
- FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing,
- aActiveEditorRoot);
+ FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing);
if (!candidate) {
return nsnull;
}
if (!aEditableNode || IsEditable(candidate)) {
return candidate;
}
- return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing,
- aActiveEditorRoot);
+ return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing);
}
already_AddRefed<nsIDOMNode>
nsEditor::GetRightmostChild(nsIDOMNode *aCurrentNode,
bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(aCurrentNode, nsnull);
nsCOMPtr<nsIDOMNode> resultNode, temp = aCurrentNode;
@@ -3603,16 +3573,24 @@ nsEditor::IsRoot(nsINode* inNode)
{
NS_ENSURE_TRUE(inNode, false);
nsCOMPtr<nsINode> rootNode = GetRoot();
return inNode == rootNode;
}
+bool
+nsEditor::IsEditorRoot(nsINode* aNode)
+{
+ NS_ENSURE_TRUE(aNode, false);
+ nsCOMPtr<nsINode> rootNode = GetEditorRoot();
+ return aNode == rootNode;
+}
+
bool
nsEditor::IsDescendantOfRoot(nsIDOMNode* inNode)
{
nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
return IsDescendantOfRoot(node);
}
bool
@@ -3620,16 +3598,26 @@ nsEditor::IsDescendantOfRoot(nsINode* in
{
NS_ENSURE_TRUE(inNode, false);
nsCOMPtr<nsIContent> root = GetRoot();
NS_ENSURE_TRUE(root, false);
return nsContentUtils::ContentIsDescendantOf(inNode, root);
}
+bool
+nsEditor::IsDescendantOfEditorRoot(nsINode* aNode)
+{
+ NS_ENSURE_TRUE(aNode, false);
+ nsCOMPtr<nsIContent> root = GetEditorRoot();
+ NS_ENSURE_TRUE(root, false);
+
+ return nsContentUtils::ContentIsDescendantOf(aNode, root);
+}
+
bool
nsEditor::IsContainer(nsIDOMNode *aNode)
{
return aNode ? true : false;
}
bool
nsEditor::IsTextInDirtyFrameVisible(nsIContent *aNode)
@@ -5228,16 +5216,22 @@ nsEditor::GetRoot()
// Let GetRootElement() do the work
GetRootElement(getter_AddRefs(root));
}
return mRootElement;
}
+dom::Element*
+nsEditor::GetEditorRoot()
+{
+ return GetRoot();
+}
+
nsresult
nsEditor::DetermineCurrentDirection()
{
// Get the current root direction from its frame
dom::Element *rootElement = GetRoot();
// If we don't have an explicit direction, determine our direction
// from the content's direction
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -368,18 +368,17 @@ protected:
// stub. see comment in source.
virtual bool IsBlockNode(nsIDOMNode *aNode);
virtual bool IsBlockNode(nsINode *aNode);
// helper for GetPriorNode and GetNextNode
nsIContent* FindNextLeafNode(nsINode *aCurrentNode,
bool aGoForward,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot);
+ bool bNoBlockCrossing);
// Get nsIWidget interface
nsresult GetWidget(nsIWidget **aWidget);
// install the event listeners for the editor
virtual nsresult InstallEventListeners();
@@ -472,77 +471,67 @@ public:
/** get the node immediately prior to aCurrentNode
* @param aCurrentNode the node from which we start the search
* @param aEditableNode if true, only return an editable node
* @param aResultNode [OUT] the node that occurs before aCurrentNode in the tree,
* skipping non-editable nodes if aEditableNode is true.
* If there is no prior node, aResultNode will be nsnull.
* @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
- * @param aActiveEditorRoot If non-null, only return descendants of aActiveEditorRoot.
*/
nsresult GetPriorNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing = false,
- nsIContent *aActiveEditorRoot = nsnull);
+ bool bNoBlockCrossing = false);
nsIContent* GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
- bool aNoBlockCrossing = false,
- nsIContent* aActiveEditorRoot = nsnull);
+ bool aNoBlockCrossing = false);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing = false,
- nsIContent *aActiveEditorRoot = nsnull);
+ bool bNoBlockCrossing = false);
nsIContent* GetPriorNode(nsINode* aParentNode,
PRInt32 aOffset,
bool aEditableNode,
- bool aNoBlockCrossing = false,
- nsIContent* aActiveEditorRoot = nsnull);
+ bool aNoBlockCrossing = false);
/** get the node immediately after to aCurrentNode
* @param aCurrentNode the node from which we start the search
* @param aEditableNode if true, only return an editable node
* @param aResultNode [OUT] the node that occurs after aCurrentNode in the tree,
* skipping non-editable nodes if aEditableNode is true.
* If there is no prior node, aResultNode will be nsnull.
*/
nsresult GetNextNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing = false,
- nsIContent *aActiveEditorRoot = nsnull);
+ bool bNoBlockCrossing = false);
nsIContent* GetNextNode(nsINode* aCurrentNode,
bool aEditableNode,
- bool bNoBlockCrossing = false,
- nsIContent* aActiveEditorRoot = nsnull);
+ bool bNoBlockCrossing = false);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
- bool bNoBlockCrossing = false,
- nsIContent *aActiveEditorRoot = nsnull);
+ bool bNoBlockCrossing = false);
nsIContent* GetNextNode(nsINode* aParentNode,
PRInt32 aOffset,
bool aEditableNode,
- bool aNoBlockCrossing = false,
- nsIContent* aActiveEditorRoot = nsnull);
+ bool aNoBlockCrossing = false);
// Helper for GetNextNode and GetPriorNode
nsIContent* FindNode(nsINode *aCurrentNode,
bool aGoForward,
bool aEditableNode,
- bool bNoBlockCrossing,
- nsIContent *aActiveEditorRoot);
+ bool bNoBlockCrossing);
/**
* Get the rightmost child of aCurrentNode;
* return nsnull if aCurrentNode has no children.
*/
already_AddRefed<nsIDOMNode> GetRightmostChild(nsIDOMNode *aCurrentNode,
bool bNoBlockCrossing = false);
nsIContent* GetRightmostChild(nsINode *aCurrentNode,
bool bNoBlockCrossing = false);
@@ -574,20 +563,22 @@ public:
bool CanContain(nsIDOMNode* aParent, nsIDOMNode* aChild);
bool CanContainTag(nsIDOMNode* aParent, nsIAtom* aTag);
bool TagCanContain(nsIAtom* aParentTag, nsIDOMNode* aChild);
virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
/** returns true if aNode is our root node */
bool IsRoot(nsIDOMNode* inNode);
bool IsRoot(nsINode* inNode);
+ bool IsEditorRoot(nsINode* aNode);
/** returns true if aNode is a descendant of our root node */
bool IsDescendantOfRoot(nsIDOMNode* inNode);
bool IsDescendantOfRoot(nsINode* inNode);
+ bool IsDescendantOfEditorRoot(nsINode* aNode);
/** returns true if aNode is a container */
virtual bool IsContainer(nsIDOMNode *aNode);
/** returns true if aNode is an editable node */
bool IsEditable(nsIDOMNode *aNode);
bool IsEditable(nsIContent *aNode);
@@ -667,16 +658,20 @@ public:
nsIDOMNode *aEndNode,
PRInt32 aEndOffset);
virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget() = 0;
// Fast non-refcounting editor root element accessor
mozilla::dom::Element *GetRoot();
+ // Likewise, but gets the editor's root instead, which is different for HTML
+ // editors
+ virtual mozilla::dom::Element* GetEditorRoot();
+
// Accessor methods to flags
bool IsPlaintextEditor() const
{
return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
}
bool IsSingleLineEditor() const
{
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -4348,17 +4348,18 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNod
NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
nsIContent* activeEditingHost = GetActiveEditingHost();
if (!activeEditingHost) {
*outNode = nsnull;
return NS_OK;
}
- nsresult res = GetPriorNode(inNode, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
+ nsresult res = GetPriorNode(inNode, true, address_of(*outNode),
+ bNoBlockCrossing);
NS_ENSURE_SUCCESS(res, res);
NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
"GetPriorNode screwed up");
return res;
}
@@ -4371,17 +4372,18 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNod
NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
nsIContent* activeEditingHost = GetActiveEditingHost();
if (!activeEditingHost) {
*outNode = nsnull;
return NS_OK;
}
- nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
+ nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode),
+ bNoBlockCrossing);
NS_ENSURE_SUCCESS(res, res);
NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
"GetPriorNode screwed up");
return res;
}
@@ -5710,8 +5712,15 @@ nsHTMLEditor::GetPreferredIMEState(IMESt
}
already_AddRefed<nsIContent>
nsHTMLEditor::GetInputEventTargetContent()
{
nsCOMPtr<nsIContent> target = GetActiveEditingHost();
return target.forget();
}
+
+// virtual MOZ_OVERRIDE
+dom::Element*
+nsHTMLEditor::GetEditorRoot()
+{
+ return GetActiveEditingHost();
+}
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -131,16 +131,17 @@ public:
/* ------------ nsPlaintextEditor overrides -------------- */
NS_IMETHOD GetIsDocumentEditable(bool *aIsDocumentEditable);
NS_IMETHOD BeginningOfDocument();
virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
virtual already_AddRefed<nsIContent> GetFocusedContent();
virtual bool IsActiveInDOMWindow();
virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget();
+ virtual mozilla::dom::Element* GetEditorRoot() MOZ_OVERRIDE;
virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
/* ------------ nsStubMutationObserver overrides --------- */
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED