Merge the last green PGO changeset from mozilla-inbound to mozilla-central

This commit is contained in:
Ehsan Akhgari 2012-07-05 11:11:34 -04:00
commit e20e91b0d7
51 changed files with 693 additions and 919 deletions

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=b2g
ac_add_options --target=arm-android-eabi
ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-eabi-4.4.3/bin/arm-eabi-"
ac_add_options --with-endian=little
ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols
ac_add_options --enable-debug

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=b2g
ac_add_options --target=arm-android-eabi
ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-eabi-4.4.3/bin/arm-eabi-"
ac_add_options --with-endian=little
ac_add_options --disable-elf-hack
ac_add_options --enable-debug-symbols
ac_add_options --enable-profiling

View File

@ -2518,6 +2518,12 @@ public:
int64_t MemoryUsage() const {
int64_t pixels = int64_t(Width()) * int64_t(Height());
// If there is no defined format, we're not taking up any memory
if (!mInternalFormatForGL) {
return 0;
}
switch (mInternalFormatForGL) {
case LOCAL_GL_STENCIL_INDEX8:
return pixels;

View File

@ -451,6 +451,11 @@ bool WebGLContext::ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint
uint32_t WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type)
{
// If there is no defined format or type, we're not taking up any memory
if (!format || !type) {
return 0;
}
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
switch (format) {

View File

@ -1,188 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "DeleteElementTxn.h"
#include "nsSelectionState.h"
#ifdef DEBUG
#include "nsIDOMElement.h"
#endif
#ifdef DEBUG
static bool gNoisy = false;
#endif
DeleteElementTxn::DeleteElementTxn()
: EditTxn()
,mElement()
,mParent()
,mRefNode()
,mRangeUpdater(nsnull)
{
}
NS_IMPL_CYCLE_COLLECTION_CLASS(DeleteElementTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRefNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRefNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(DeleteElementTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(DeleteElementTxn, EditTxn)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteElementTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
NS_IMETHODIMP DeleteElementTxn::Init(nsIEditor *aEditor,
nsIDOMNode *aElement,
nsRangeUpdater *aRangeUpdater)
{
NS_ENSURE_TRUE(aEditor && aElement, NS_ERROR_NULL_POINTER);
mEditor = aEditor;
mElement = do_QueryInterface(aElement);
nsresult result = mElement->GetParentNode(getter_AddRefs(mParent));
if (NS_FAILED(result)) { return result; }
// do nothing if the parent is read-only
if (mParent && !mEditor->IsModifiableNode(mParent)) {
return NS_ERROR_FAILURE;
}
mRangeUpdater = aRangeUpdater;
return NS_OK;
}
NS_IMETHODIMP DeleteElementTxn::DoTransaction(void)
{
#ifdef DEBUG
if (gNoisy)
{
printf("%p Do Delete Element element = %p\n",
static_cast<void*>(this),
static_cast<void*>(mElement.get()));
}
#endif
NS_ENSURE_TRUE(mElement, NS_ERROR_NOT_INITIALIZED);
if (!mParent) { return NS_OK; } // this is a no-op, there's no parent to delete mElement from
#ifdef DEBUG
// begin debug output
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
if (element)
element->GetTagName(elementTag);
nsCOMPtr<nsIDOMElement> parentElement = do_QueryInterface(mParent);
nsAutoString parentElementTag(NS_LITERAL_STRING("text node"));
if (parentElement)
parentElement->GetTagName(parentElementTag);
char *c, *p;
c = ToNewCString(elementTag);
p = ToNewCString(parentElementTag);
if (c&&p)
{
if (gNoisy)
printf(" DeleteElementTxn: deleting child %s from parent %s\n", c, p);
NS_Free(c);
NS_Free(p);
}
// end debug output
#endif
// remember which child mElement was (by remembering which child was next)
mElement->GetNextSibling(getter_AddRefs(mRefNode)); // can return null mRefNode
// give range updater a chance. SelAdjDeleteNode() needs to be called *before*
// we do the action, unlike some of the other nsRangeStore update methods.
if (mRangeUpdater)
mRangeUpdater->SelAdjDeleteNode(mElement);
nsCOMPtr<nsIDOMNode> resultNode;
return mParent->RemoveChild(mElement, getter_AddRefs(resultNode));
}
NS_IMETHODIMP DeleteElementTxn::UndoTransaction(void)
{
#ifdef DEBUG
if (gNoisy)
{
printf("%p Undo Delete Element element = %p, parent = %p\n",
static_cast<void*>(this),
static_cast<void*>(mElement.get()),
static_cast<void*>(mParent.get()));
}
#endif
if (!mParent) { return NS_OK; } // this is a legal state, the txn is a no-op
if (!mElement) { return NS_ERROR_NULL_POINTER; }
#ifdef DEBUG
// begin debug output
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
if (element)
element->GetTagName(elementTag);
nsCOMPtr<nsIDOMElement> parentElement = do_QueryInterface(mParent);
nsAutoString parentElementTag(NS_LITERAL_STRING("text node"));
if (parentElement)
parentElement->GetTagName(parentElementTag);
char *c, *p;
c = ToNewCString(elementTag);
p = ToNewCString(parentElementTag);
if (c&&p)
{
if (gNoisy)
printf(" DeleteElementTxn: inserting child %s back into parent %s\n", c, p);
NS_Free(c);
NS_Free(p);
}
// end debug output
#endif
nsCOMPtr<nsIDOMNode> resultNode;
return mParent->InsertBefore(mElement, mRefNode, getter_AddRefs(resultNode));
}
NS_IMETHODIMP DeleteElementTxn::RedoTransaction(void)
{
#ifdef DEBUG
if (gNoisy)
{
printf("%p Redo Delete Element element = %p, parent = %p\n",
static_cast<void*>(this),
static_cast<void*>(mElement.get()),
static_cast<void*>(mParent.get()));
}
#endif
if (!mParent) { return NS_OK; } // this is a legal state, the txn is a no-op
if (!mElement) { return NS_ERROR_NULL_POINTER; }
if (mRangeUpdater)
mRangeUpdater->SelAdjDeleteNode(mElement);
nsCOMPtr<nsIDOMNode> resultNode;
return mParent->RemoveChild(mElement, getter_AddRefs(resultNode));
}
NS_IMETHODIMP DeleteElementTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("DeleteElementTxn");
return NS_OK;
}

View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DeleteNodeTxn.h"
#include "nsSelectionState.h" // nsRangeUpdater
#include "nsEditor.h"
DeleteNodeTxn::DeleteNodeTxn()
: EditTxn(), mNode(), mParent(), mRefNode(), mRangeUpdater(nsnull)
{
}
NS_IMPL_CYCLE_COLLECTION_CLASS(DeleteNodeTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRefNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRefNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(DeleteNodeTxn, EditTxn)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteNodeTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
nsresult
DeleteNodeTxn::Init(nsEditor* aEditor, nsINode* aNode,
nsRangeUpdater* aRangeUpdater)
{
NS_ENSURE_TRUE(aEditor && aNode, NS_ERROR_NULL_POINTER);
mEditor = aEditor;
mNode = aNode;
mParent = aNode->GetNodeParent();
// do nothing if the node has a parent and it's read-only
NS_ENSURE_TRUE(!mParent || mEditor->IsModifiableNode(mParent),
NS_ERROR_FAILURE);
mRangeUpdater = aRangeUpdater;
return NS_OK;
}
NS_IMETHODIMP
DeleteNodeTxn::DoTransaction()
{
NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
if (!mParent) {
// this is a no-op, there's no parent to delete mNode from
return NS_OK;
}
// remember which child mNode was (by remembering which child was next);
// mRefNode can be null
mRefNode = mNode->GetNextSibling();
// give range updater a chance. SelAdjDeleteNode() needs to be called
// *before* we do the action, unlike some of the other nsRangeStore update
// methods.
if (mRangeUpdater) {
mRangeUpdater->SelAdjDeleteNode(mNode->AsDOMNode());
}
return mParent->RemoveChild(mNode);
}
NS_IMETHODIMP
DeleteNodeTxn::UndoTransaction()
{
if (!mParent) {
// this is a legal state, the txn is a no-op
return NS_OK;
}
if (!mNode) {
return NS_ERROR_NULL_POINTER;
}
nsresult res;
mParent->InsertBefore(mNode, mRefNode, &res);
return res;
}
NS_IMETHODIMP
DeleteNodeTxn::RedoTransaction()
{
if (!mParent) {
// this is a legal state, the txn is a no-op
return NS_OK;
}
if (!mNode) {
return NS_ERROR_NULL_POINTER;
}
if (mRangeUpdater) {
mRangeUpdater->SelAdjDeleteNode(mNode->AsDOMNode());
}
return mParent->RemoveChild(mNode);
}
NS_IMETHODIMP
DeleteNodeTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("DeleteNodeTxn");
return NS_OK;
}

View File

@ -3,53 +3,54 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DeleteElementTxn_h__
#define DeleteElementTxn_h__
#ifndef DeleteNodeTxn_h__
#define DeleteNodeTxn_h__
#include "EditTxn.h"
#include "nsIDOMNode.h"
#include "nsIEditor.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
class nsRangeUpdater;
class nsEditor;
/**
* A transaction that deletes a single element
*/
class DeleteElementTxn : public EditTxn
class DeleteNodeTxn : public EditTxn
{
public:
/** initialize the transaction.
* @param aElement the node to delete
*/
NS_IMETHOD Init(nsIEditor *aEditor, nsIDOMNode *aElement, nsRangeUpdater *aRangeUpdater);
nsresult Init(nsEditor* aEditor, nsINode* aNode,
nsRangeUpdater* aRangeUpdater);
DeleteElementTxn();
DeleteNodeTxn();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteElementTxn, EditTxn)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeleteNodeTxn, EditTxn)
NS_DECL_EDITTXN
NS_IMETHOD RedoTransaction();
protected:
/** the element to delete */
nsCOMPtr<nsIDOMNode> mElement;
nsCOMPtr<nsINode> mNode;
/** parent of node to delete */
nsCOMPtr<nsIDOMNode> mParent;
nsCOMPtr<nsINode> mParent;
/** next sibling to remember for undo/redo purposes */
nsCOMPtr<nsIDOMNode> mRefNode;
nsCOMPtr<nsIContent> mRefNode;
/** the editor for this transaction */
nsIEditor* mEditor;
nsEditor* mEditor;
/** range updater object */
nsRangeUpdater *mRangeUpdater;
nsRangeUpdater* mRangeUpdater;
};
#endif

View File

@ -5,7 +5,7 @@
#include "DeleteRangeTxn.h"
#include "DeleteTextTxn.h"
#include "DeleteElementTxn.h"
#include "DeleteNodeTxn.h"
#include "nsIContentIterator.h"
#include "nsComponentManagerUtils.h"
@ -160,8 +160,8 @@ DeleteRangeTxn::CreateTxnsToDeleteBetween(nsINode* aNode,
nsresult res = NS_OK;
for (PRInt32 i = aStartOffset; i < aEndOffset; ++i) {
nsRefPtr<DeleteElementTxn> txn = new DeleteElementTxn();
res = txn->Init(mEditor, child->AsDOMNode(), mRangeUpdater);
nsRefPtr<DeleteNodeTxn> txn = new DeleteNodeTxn();
res = txn->Init(mEditor, child, mRangeUpdater);
if (NS_SUCCEEDED(res)) {
AppendChild(txn);
}
@ -217,9 +217,9 @@ DeleteRangeTxn::CreateTxnsToDeleteNodesBetween()
nsCOMPtr<nsINode> node = iter->GetCurrentNode();
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
nsRefPtr<DeleteElementTxn> txn = new DeleteElementTxn();
nsRefPtr<DeleteNodeTxn> txn = new DeleteNodeTxn();
res = txn->Init(mEditor, node->AsDOMNode(), mRangeUpdater);
res = txn->Init(mEditor, node, mRangeUpdater);
NS_ENSURE_SUCCESS(res, res);
AppendChild(txn);

View File

@ -38,7 +38,7 @@ CPPSRCS += \
ChangeAttributeTxn.cpp \
ChangeCSSInlineStyleTxn.cpp \
CreateElementTxn.cpp \
DeleteElementTxn.cpp \
DeleteNodeTxn.cpp \
DeleteRangeTxn.cpp \
DeleteTextTxn.cpp \
EditAggregateTxn.cpp \

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var root = document.documentElement;
while (root.firstChild) { root.removeChild(root.firstChild); }
var body = document.createElementNS("http://www.w3.org/1999/xhtml", "body");
var div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
root.contentEditable = "true";
root.appendChild(div);
root.removeChild(div);
root.insertBefore(body, root.firstChild);
window.getSelection().removeAllRanges();
var r0 = document.createRange();
r0.setStart(body, 0);
r0.setEnd(body, 0);
window.getSelection().addRange(r0);
var r1 = document.createRange();
r1.setStart(div, 0);
r1.setEnd(div, 0);
window.getSelection().addRange(r1);
document.execCommand("inserthtml", false, "1");
}
</script>
</head>
<body onload="boom();"></body>
</html>

View File

@ -14,3 +14,4 @@ load 762183.html
load 766360.html
load 766413.html
load 766845.xhtml
load 768765.html

View File

@ -55,7 +55,7 @@
#include "ChangeAttributeTxn.h"
#include "CreateElementTxn.h"
#include "InsertElementTxn.h"
#include "DeleteElementTxn.h"
#include "DeleteNodeTxn.h"
#include "InsertTextTxn.h"
#include "DeleteTextTxn.h"
#include "DeleteRangeTxn.h"
@ -1463,16 +1463,15 @@ nsEditor::JoinNodes(nsIDOMNode * aLeftNode,
nsIDOMNode * aRightNode,
nsIDOMNode * aParent)
{
PRInt32 i, offset;
PRInt32 i;
nsAutoRules beginRulesSniffing(this, kOpJoinNode, nsIEditor::ePrevious);
// remember some values; later used for saved selection updating.
// find the offset between the nodes to be joined.
nsresult result = GetChildOffset(aRightNode, aParent, offset);
NS_ENSURE_SUCCESS(result, result);
PRInt32 offset = GetChildOffset(aRightNode, aParent);
// find the number of children of the lefthand node
PRUint32 oldLeftNodeLen;
result = GetLengthOfDOMNode(aLeftNode, oldLeftNodeLen);
nsresult result = GetLengthOfDOMNode(aLeftNode, oldLeftNodeLen);
NS_ENSURE_SUCCESS(result, result);
for (i = 0; i < mActionListeners.Count(); i++)
@ -1493,29 +1492,36 @@ nsEditor::JoinNodes(nsIDOMNode * aLeftNode,
}
NS_IMETHODIMP nsEditor::DeleteNode(nsIDOMNode * aElement)
NS_IMETHODIMP
nsEditor::DeleteNode(nsIDOMNode* aNode)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_STATE(node);
return DeleteNode(node);
}
nsresult
nsEditor::DeleteNode(nsINode* aNode)
{
PRInt32 i, offset;
nsCOMPtr<nsIDOMNode> parent;
nsAutoRules beginRulesSniffing(this, kOpCreateNode, nsIEditor::ePrevious);
// save node location for selection updating code.
nsresult result = GetNodeLocation(aElement, address_of(parent), &offset);
NS_ENSURE_SUCCESS(result, result);
for (i = 0; i < mActionListeners.Count(); i++)
mActionListeners[i]->WillDeleteNode(aElement);
nsRefPtr<DeleteElementTxn> txn;
result = CreateTxnForDeleteElement(aElement, getter_AddRefs(txn));
if (NS_SUCCEEDED(result)) {
result = DoTransaction(txn);
for (PRInt32 i = 0; i < mActionListeners.Count(); i++) {
mActionListeners[i]->WillDeleteNode(aNode->AsDOMNode());
}
for (i = 0; i < mActionListeners.Count(); i++)
mActionListeners[i]->DidDeleteNode(aElement, result);
nsRefPtr<DeleteNodeTxn> txn;
nsresult res = CreateTxnForDeleteNode(aNode, getter_AddRefs(txn));
if (NS_SUCCEEDED(res)) {
res = DoTransaction(txn);
}
return result;
for (PRInt32 i = 0; i < mActionListeners.Count(); i++) {
mActionListeners[i]->DidDeleteNode(aNode->AsDOMNode(), res);
}
NS_ENSURE_SUCCESS(res, res);
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////
@ -1735,10 +1741,11 @@ nsresult
nsEditor::MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset)
{
NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
nsresult res;
nsCOMPtr<nsIDOMNode> oldParent;
PRInt32 oldOffset;
nsresult res = GetNodeLocation(aNode, address_of(oldParent), &oldOffset);
GetNodeLocation(aNode, address_of(oldParent), &oldOffset);
if (aOffset == -1)
{
@ -2956,10 +2963,8 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
result = GetLengthOfDOMNode(leftNode, firstNodeLength);
NS_ENSURE_SUCCESS(result, result);
nsCOMPtr<nsIDOMNode> parent;
result = GetNodeLocation(aNodeToJoin, address_of(parent), &joinOffset);
NS_ENSURE_SUCCESS(result, result);
result = GetNodeLocation(aNodeToKeep, address_of(parent), &keepOffset);
NS_ENSURE_SUCCESS(result, result);
GetNodeLocation(aNodeToJoin, address_of(parent), &joinOffset);
GetNodeLocation(aNodeToKeep, address_of(parent), &keepOffset);
// if selection endpoint is between the nodes, remember it as being
// in the one that is going away instead. This simplifies later selection
@ -3132,34 +3137,33 @@ nsEditor::JoinNodesImpl(nsIDOMNode * aNodeToKeep,
}
nsresult
nsEditor::GetChildOffset(nsIDOMNode *aChild, nsIDOMNode *aParent, PRInt32 &aOffset)
PRInt32
nsEditor::GetChildOffset(nsIDOMNode* aChild, nsIDOMNode* aParent)
{
NS_ASSERTION((aChild && aParent), "bad args");
MOZ_ASSERT(aChild && aParent);
nsCOMPtr<nsIContent> content = do_QueryInterface(aParent);
nsCOMPtr<nsIContent> cChild = do_QueryInterface(aChild);
NS_ENSURE_TRUE(cChild && content, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
nsCOMPtr<nsINode> child = do_QueryInterface(aChild);
MOZ_ASSERT(parent && child);
aOffset = content->IndexOf(cChild);
return NS_OK;
PRInt32 idx = parent->IndexOf(child);
MOZ_ASSERT(idx != -1);
return idx;
}
nsresult
nsEditor::GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset)
// static
void
nsEditor::GetNodeLocation(nsIDOMNode* aChild, nsCOMPtr<nsIDOMNode>* outParent,
PRInt32* outOffset)
{
NS_ASSERTION((inChild && outParent && outOffset), "bad args");
nsresult result = NS_ERROR_NULL_POINTER;
if (inChild && outParent && outOffset)
{
result = inChild->GetParentNode(getter_AddRefs(*outParent));
if ((NS_SUCCEEDED(result)) && (*outParent))
{
result = GetChildOffset(inChild, *outParent, *outOffset);
}
MOZ_ASSERT(aChild && outParent && outOffset);
*outOffset = -1;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
aChild->GetParentNode(getter_AddRefs(*outParent))));
if (*outParent) {
*outOffset = GetChildOffset(aChild, *outParent);
}
return result;
}
// returns the number of things inside aNode.
@ -3906,24 +3910,6 @@ nsEditor::AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2)
}
// IsTextOrElementNode: true if node of dom type element or text
//
bool
nsEditor::IsTextOrElementNode(nsIDOMNode *aNode)
{
if (!aNode)
{
NS_NOTREACHED("null node passed to IsTextOrElementNode()");
return false;
}
PRUint16 nodeType;
aNode->GetNodeType(&nodeType);
return ((nodeType == nsIDOMNode::ELEMENT_NODE) || (nodeType == nsIDOMNode::TEXT_NODE));
}
///////////////////////////////////////////////////////////////////////////
// IsTextNode: true if node of dom type text
//
@ -4444,12 +4430,14 @@ nsEditor::DeleteSelectionAndPrepareToCreateNode()
nsresult res;
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
MOZ_ASSERT(selection->GetAnchorFocusRange());
if (!selection->Collapsed()) {
if (!selection->GetAnchorFocusRange()->Collapsed()) {
res = DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
NS_ENSURE_SUCCESS(res, res);
MOZ_ASSERT(selection->Collapsed(),
MOZ_ASSERT(selection->GetAnchorFocusRange() &&
selection->GetAnchorFocusRange()->Collapsed(),
"Selection not collapsed after delete");
}
@ -4610,20 +4598,18 @@ NS_IMETHODIMP nsEditor::CreateTxnForInsertElement(nsIDOMNode * aNode,
return rv;
}
NS_IMETHODIMP nsEditor::CreateTxnForDeleteElement(nsIDOMNode * aElement,
DeleteElementTxn ** aTxn)
nsresult
nsEditor::CreateTxnForDeleteNode(nsINode* aNode, DeleteNodeTxn** aTxn)
{
NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
nsRefPtr<DeleteElementTxn> txn = new DeleteElementTxn();
nsRefPtr<DeleteNodeTxn> txn = new DeleteNodeTxn();
nsresult rv = txn->Init(this, aElement, &mRangeUpdater);
if (NS_SUCCEEDED(rv))
{
txn.forget(aTxn);
}
nsresult res = txn->Init(this, aNode, &mRangeUpdater);
NS_ENSURE_SUCCESS(res, res);
return rv;
txn.forget(aTxn);
return NS_OK;
}
NS_IMETHODIMP
@ -4815,9 +4801,8 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsRange* aRange,
aTxn->AppendChild(txn);
} else {
// priorNode is not chardata, so tell its parent to delete it
nsRefPtr<DeleteElementTxn> txn;
res = CreateTxnForDeleteElement(priorNode->AsDOMNode(),
getter_AddRefs(txn));
nsRefPtr<DeleteNodeTxn> txn;
res = CreateTxnForDeleteNode(priorNode, getter_AddRefs(txn));
NS_ENSURE_SUCCESS(res, res);
aTxn->AppendChild(txn);
@ -4852,9 +4837,8 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsRange* aRange,
aTxn->AppendChild(txn);
} else {
// nextNode is not chardata, so tell its parent to delete it
nsRefPtr<DeleteElementTxn> txn;
res = CreateTxnForDeleteElement(nextNode->AsDOMNode(),
getter_AddRefs(txn));
nsRefPtr<DeleteNodeTxn> txn;
res = CreateTxnForDeleteNode(nextNode, getter_AddRefs(txn));
NS_ENSURE_SUCCESS(res, res);
aTxn->AppendChild(txn);
}
@ -4915,9 +4899,8 @@ nsEditor::CreateTxnForDeleteInsertionPoint(nsRange* aRange,
*aOffset = delTextTxn->GetOffset();
*aLength = delTextTxn->GetNumCharsToDelete();
} else {
nsRefPtr<DeleteElementTxn> delElementTxn;
res = CreateTxnForDeleteElement(selectedNode->AsDOMNode(),
getter_AddRefs(delElementTxn));
nsRefPtr<DeleteNodeTxn> delElementTxn;
res = CreateTxnForDeleteNode(selectedNode, getter_AddRefs(delElementTxn));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(delElementTxn, NS_ERROR_NULL_POINTER);
@ -4953,9 +4936,7 @@ nsEditor::AppendNodeToSelectionAsRange(nsIDOMNode *aNode)
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
PRInt32 offset;
res = GetChildOffset(aNode, parentNode, offset);
NS_ENSURE_SUCCESS(res, res);
PRInt32 offset = GetChildOffset(aNode, parentNode);
nsCOMPtr<nsIDOMRange> range;
res = CreateRange(parentNode, offset, parentNode, offset+1, getter_AddRefs(range));

View File

@ -41,7 +41,7 @@ class nsIPresShell;
class ChangeAttributeTxn;
class CreateElementTxn;
class InsertElementTxn;
class DeleteElementTxn;
class DeleteNodeTxn;
class InsertTextTxn;
class DeleteTextTxn;
class SplitElementTxn;
@ -176,6 +176,7 @@ public:
nsIDOMNode ** aNewNode);
/* helper routines for node/parent manipulations */
nsresult DeleteNode(nsINode* aNode);
nsresult ReplaceContainer(nsINode* inNode,
mozilla::dom::Element** outNode,
const nsAString& aNodeType,
@ -251,10 +252,9 @@ protected:
PRInt32 aOffset,
InsertElementTxn ** aTxn);
/** create a transaction for removing aElement from its parent.
/** create a transaction for removing aNode from its parent.
*/
NS_IMETHOD CreateTxnForDeleteElement(nsIDOMNode * aElement,
DeleteElementTxn ** aTxn);
nsresult CreateTxnForDeleteNode(nsINode* aNode, DeleteNodeTxn** aTxn);
nsresult CreateTxnForDeleteSelection(EDirection aAction,
@ -436,20 +436,19 @@ public:
bool aNodeToKeepIsFirst);
/**
* Set aOffset to the offset of aChild in aParent.
* Returns an error if aChild is not an immediate child of aParent.
* Return the offset of aChild in aParent. Asserts fatally if parent or
* child is null, or parent is not child's parent.
*/
static nsresult GetChildOffset(nsIDOMNode *aChild,
nsIDOMNode *aParent,
PRInt32 &aOffset);
static PRInt32 GetChildOffset(nsIDOMNode *aChild,
nsIDOMNode *aParent);
/**
* Set aParent to the parent of aChild.
* Set aOffset to the offset of aChild in aParent.
* Set outParent to the parent of aChild.
* Set outOffset to the offset of aChild in outParent.
*/
static nsresult GetNodeLocation(nsIDOMNode *aChild,
nsCOMPtr<nsIDOMNode> *aParent,
PRInt32 *aOffset);
static void GetNodeLocation(nsIDOMNode* aChild,
nsCOMPtr<nsIDOMNode>* outParent,
PRInt32* outOffset);
/** returns the number of things inside aNode in the out-param aCount.
* @param aNode is the node to get the length of.
@ -590,7 +589,6 @@ public:
bool NodesSameType(nsIDOMNode *aNode1, nsIDOMNode *aNode2);
virtual bool AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2);
static bool IsTextOrElementNode(nsIDOMNode *aNode);
static bool IsTextNode(nsIDOMNode *aNode);
static bool IsTextNode(nsINode *aNode);

View File

@ -14,9 +14,9 @@ Private Editor interface for a class that can provide helper functions
*/
#define NS_IEDITORSUPPORT_IID \
{/* 89b999b0-c529-11d2-86da-000064657374*/ \
0x89b999b0, 0xc529, 0x11d2, \
{0x86, 0xda, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74} }
{/* c4cbcda8-58ec-4f03-9c99-5e46b6828b7a*/ \
0xc4cbcda8, 0x58ec, 0x4f03, \
{0x0c, 0x99, 0x5e, 0x46, 0xb6, 0x82, 0x8b, 0x7a} }
/**
@ -53,10 +53,7 @@ public:
nsIDOMNode *aParent,
bool aNodeToKeepIsFirst)=0;
static nsresult GetChildOffset(nsIDOMNode *aChild, nsIDOMNode *aParent, PRInt32 &aOffset);
static PRInt32 GetChildOffset(nsIDOMNode* aChild, nsIDOMNode* aParent);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIEditorSupport, NS_IEDITORSUPPORT_IID)

View File

@ -243,29 +243,30 @@ nsRangeUpdater::SelAdjInsertNode(nsIDOMNode *aParent, PRInt32 aPosition)
return SelAdjCreateNode(aParent, aPosition);
}
nsresult
void
nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
{
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return;
}
MOZ_ASSERT(aNode);
PRUint32 i, count = mArray.Length();
if (!count) {
return NS_OK;
return;
}
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset = 0;
nsresult res = nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
// check for range endpoints that are after aNode and in the same parent
nsRangeStore *item;
for (i=0; i<count; i++)
{
item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
MOZ_ASSERT(item);
if ((item->startNode.get() == parent) && (item->startOffset > offset))
item->startOffset--;
@ -300,7 +301,6 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
item->endOffset = offset;
}
}
return NS_OK;
}
@ -316,11 +316,10 @@ nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsID
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
nsresult result = nsEditor::GetNodeLocation(aOldRightNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(result, result);
nsEditor::GetNodeLocation(aOldRightNode, address_of(parent), &offset);
// first part is same as inserting aNewLeftnode
result = SelAdjInsertNode(parent,offset-1);
nsresult result = SelAdjInsertNode(parent,offset-1);
NS_ENSURE_SUCCESS(result, result);
// next step is to check for range enpoints inside aOldRightNode

View File

@ -79,7 +79,7 @@ class nsRangeUpdater
// which is not what you want if you know you are reinserting it.
nsresult SelAdjCreateNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjInsertNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjDeleteNode(nsIDOMNode *aNode);
void SelAdjDeleteNode(nsIDOMNode *aNode);
nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode);
nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html contenteditable="true">
<head>
<script>
function boom()
{
var looseText = document.createTextNode("x");
window.getSelection().collapse(looseText, 0);
document.queryCommandState("insertorderedlist");
}
</script>
</head>
<body onload="setTimeout(boom, 0)"></body>
</html>

View File

@ -33,3 +33,4 @@ load 766305.html
load 766387.html
load 766795.html
load 767169.html
load 768748.html

View File

@ -618,8 +618,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
}
if (lastInsertNode)
{
rv = GetNodeLocation(lastInsertNode, address_of(parentNode), &offsetOfNewNode);
NS_ENSURE_SUCCESS(rv, rv);
GetNodeLocation(lastInsertNode, address_of(parentNode), &offsetOfNewNode);
offsetOfNewNode++;
}
}
@ -658,9 +657,8 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
else // we need to find a container for selection. Look up.
{
tmp = selNode;
rv = GetNodeLocation(tmp, address_of(selNode), &selOffset);
GetNodeLocation(tmp, address_of(selNode), &selOffset);
++selOffset; // want to be *after* last leaf node in paste
NS_ENSURE_SUCCESS(rv, rv);
}
// make sure we don't end up with selection collapsed after an invisible break node
@ -679,7 +677,8 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
{
// don't leave selection past an invisible break;
// reset {selNode,selOffset} to point before break
rv = GetNodeLocation(wsRunObj.mStartReasonNode, address_of(selNode), &selOffset);
GetNodeLocation(wsRunObj.mStartReasonNode, address_of(selNode),
&selOffset);
// we want to be inside any inline style prior to break
nsWSRunObject wsRunObj(this, selNode, selOffset);
wsRunObj.PriorVisibleNode(selNode, selOffset, address_of(visNode),
@ -694,7 +693,8 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
{
// prior visible thing is an image or some other non-text thingy.
// We want to be right after it.
rv = GetNodeLocation(wsRunObj.mStartReasonNode, address_of(selNode), &selOffset);
GetNodeLocation(wsRunObj.mStartReasonNode, address_of(selNode),
&selOffset);
++selOffset;
}
}
@ -713,8 +713,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
PRInt32 linkOffset;
rv = SplitNodeDeep(link, selNode, selOffset, &linkOffset, true, address_of(leftLink));
NS_ENSURE_SUCCESS(rv, rv);
rv = GetNodeLocation(leftLink, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(rv, rv);
GetNodeLocation(leftLink, address_of(selNode), &selOffset);
selection->Collapse(selNode, selOffset+1);
}
}
@ -2012,8 +2011,10 @@ nsHTMLEditor::InsertAsPlaintextQuotation(const nsAString & aQuotedText,
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
if (NS_SUCCEEDED(GetNodeLocation(newNode, address_of(parent), &offset)) && parent)
selection->Collapse(parent, offset+1);
GetNodeLocation(newNode, address_of(parent), &offset);
if (parent) {
selection->Collapse(parent, offset + 1);
}
}
return rv;
}
@ -2095,8 +2096,10 @@ nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
if (NS_SUCCEEDED(GetNodeLocation(newNode, address_of(parent), &offset)) && parent)
selection->Collapse(parent, offset+1);
GetNodeLocation(newNode, address_of(parent), &offset);
if (parent) {
selection->Collapse(parent, offset + 1);
}
}
return rv;
}

View File

@ -59,7 +59,7 @@ enum
};
/********************************************************
* first some helpful funcotrs we will use
* first some helpful functors we will use
********************************************************/
static bool IsBlockNode(nsIDOMNode* node)
@ -760,8 +760,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign)
NS_ENSURE_TRUE(rootElem, NS_ERROR_FAILURE);
PRInt32 offset, rootOffset;
res = nsEditor::GetNodeLocation(rootElem, address_of(parent), &rootOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(rootElem, address_of(parent), &rootOffset);
res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
@ -1204,8 +1203,7 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, bool *aCancel)
// if we are here then the selection is right after a mozBR
// that is in the same block as the selection. We need to move
// the selection start to be before the mozBR.
res = nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
res = aSelection->Collapse(selNode,selOffset);
NS_ENSURE_SUCCESS(res, res);
}
@ -1610,8 +1608,7 @@ nsHTMLEditRules::StandardBreakImpl(nsIDOMNode* aNode, PRInt32 aOffset,
address_of(brNode), nsIEditor::eNone);
}
NS_ENSURE_SUCCESS(res, res);
res = nsEditor::GetNodeLocation(brNode, address_of(node), &aOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(brNode, address_of(node), &aOffset);
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
if (bAfterBlock && bBeforeBlock) {
// we just placed a br between block boundaries. This is the one case
@ -1635,9 +1632,7 @@ nsHTMLEditRules::StandardBreakImpl(nsIDOMNode* aNode, PRInt32 aOffset,
// get the style from the line above.
nsCOMPtr<nsIDOMNode> brParent;
PRInt32 brOffset;
res = nsEditor::GetNodeLocation(secondBR, address_of(brParent),
&brOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(secondBR, address_of(brParent), &brOffset);
if (brParent != node || brOffset != aOffset + 1) {
res = mHTMLEditor->MoveNode(secondBR, node, aOffset+1);
NS_ENSURE_SUCCESS(res, res);
@ -1703,8 +1698,7 @@ nsHTMLEditRules::SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool
if (nsEditorUtils::IsDescendantOf(visNode, citeNode, &unused))
{
// it is. so lets reset our selection to be just after it.
res = mHTMLEditor->GetNodeLocation(visNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
mHTMLEditor->GetNodeLocation(visNode, address_of(selNode), &selOffset);
++selOffset;
}
}
@ -1969,8 +1963,7 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection,
bool moveOnly = true;
res = nsEditor::GetNodeLocation(visNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(visNode, address_of(selNode), &selOffset);
bool interLineIsRight;
res = aSelection->GetInterlinePosition(&interLineIsRight);
@ -2516,8 +2509,7 @@ nsHTMLEditRules::GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection
}
else
{
res = nsEditor::GetNodeLocation(aNode, outSelNode, outSelOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aNode, outSelNode, outSelOffset);
if (!nsTextEditUtils::IsBreak(aNode) || mHTMLEditor->IsVisBreak(aNode))
{
if (aAction == nsIEditor::ePrevious)
@ -3001,8 +2993,7 @@ nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
nsCOMPtr<nsIDOMNode> newBlock;
nsCOMPtr<nsIDOMNode> curNode = arrayOfNodes[i];
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// make sure we don't assemble content that is in different table cells
// into the same list. respect table cell boundaries when listifying.
@ -3063,9 +3054,7 @@ nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(curParent, address_of(parent),
&offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curParent, address_of(parent), &offset);
res = mHTMLEditor->CreateNode(*aListType, parent, offset,
getter_AddRefs(curList));
NS_ENSURE_SUCCESS(res, res);
@ -3218,8 +3207,7 @@ nsHTMLEditRules::WillRemoveList(nsISelection *aSelection,
// here's where we actually figure out what to do
nsIDOMNode* curNode = arrayOfNodes[i];
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
if (nsHTMLEditUtils::IsListItem(curNode)) // unlist this listitem
{
@ -3523,8 +3511,7 @@ nsHTMLEditRules::WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool * a
if (!mHTMLEditor->IsEditable(curNode)) continue;
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// some logic for putting list items into nested lists...
if (nsHTMLEditUtils::IsList(curParent))
@ -3707,8 +3694,7 @@ nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *
if (!mHTMLEditor->IsEditable(curNode)) continue;
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// some logic for putting list items into nested lists...
if (nsHTMLEditUtils::IsList(curParent))
@ -3789,8 +3775,7 @@ nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *
if (listitem)
{
if (indentedLI == listitem) continue; // already indented this list item
res = nsEditor::GetNodeLocation(listitem, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(listitem, address_of(curParent), &offset);
// check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
if (curList)
@ -3898,8 +3883,7 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHan
// here's where we actually figure out what to do
nsCOMPtr<nsIDOMNode> curNode = arrayOfNodes[i];
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// is it a blockquote?
if (nsHTMLEditUtils::IsBlockquote(curNode))
@ -4165,8 +4149,7 @@ nsHTMLEditRules::SplitBlock(nsIDOMNode *aBlock,
nsresult res;
// get split point location
res = nsEditor::GetNodeLocation(aStartChild, address_of(startParent), &startOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aStartChild, address_of(startParent), &startOffset);
// do the splits!
res = mHTMLEditor->SplitNodeDeep(aBlock, startParent, startOffset, &offset,
@ -4179,8 +4162,7 @@ nsHTMLEditRules::SplitBlock(nsIDOMNode *aBlock,
*aLeftNode = leftNode;
// get split point location
res = nsEditor::GetNodeLocation(aEndChild, address_of(endParent), &endOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aEndChild, address_of(endParent), &endOffset);
endOffset++; // want to be after lastBQChild
// do the splits!
@ -4569,8 +4551,7 @@ nsHTMLEditRules::WillAlign(nsISelection *aSelection,
if (!mHTMLEditor->IsEditable(curNode)) continue;
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// the node is a table element, an horiz rule, a paragraph, a div
// or a section header; in HTML 4, it can directly carry the ALIGN
@ -4791,8 +4772,7 @@ nsHTMLEditRules::CheckForEmptyBlock(nsIDOMNode *aStartNode,
{
nsCOMPtr<nsIDOMNode> blockParent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(emptyBlock, address_of(blockParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(emptyBlock, address_of(blockParent), &offset);
NS_ENSURE_TRUE(blockParent && offset >= 0, NS_ERROR_FAILURE);
if (nsHTMLEditUtils::IsListItem(emptyBlock))
@ -4805,8 +4785,8 @@ nsHTMLEditRules::CheckForEmptyBlock(nsIDOMNode *aStartNode,
{
nsCOMPtr<nsIDOMNode> listParent;
PRInt32 listOffset;
res = nsEditor::GetNodeLocation(blockParent, address_of(listParent), &listOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(blockParent, address_of(listParent),
&listOffset);
NS_ENSURE_TRUE(listParent && listOffset >= 0, NS_ERROR_FAILURE);
// if we are a sublist, skip the br creation
if (!nsHTMLEditUtils::IsList(listParent))
@ -4857,15 +4837,13 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock,
nsCOMPtr<nsIDOMNode> nodeParent;
PRInt32 nodeOffset;
if (NS_SUCCEEDED(nsEditor::GetNodeLocation(rightmostNode,
address_of(nodeParent),
&nodeOffset)))
{
runTest = true;
testNode = nodeParent;
// use offset + 1, because we want the last node included in our evaluation
testOffset = nodeOffset + 1;
}
nsEditor::GetNodeLocation(rightmostNode, address_of(nodeParent),
&nodeOffset);
runTest = true;
testNode = nodeParent;
// use offset + 1, because we want the last node included in our
// evaluation
testOffset = nodeOffset + 1;
}
}
else if (aOffset)
@ -5172,8 +5150,7 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode, true);
if (child)
{
res = nsEditor::GetNodeLocation(child, address_of(newEndNode), &newEndOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(child, address_of(newEndNode), &newEndOffset);
++newEndOffset; // offset *after* child
}
// else block is empty - we can leave selection alone here, i think.
@ -5185,8 +5162,8 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
res = mHTMLEditor->GetPriorHTMLNode(endNode, endOffset, address_of(child));
if (child)
{
res = nsEditor::GetNodeLocation(child, address_of(newEndNode), &newEndOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(child, address_of(newEndNode),
&newEndOffset);
++newEndOffset; // offset *after* child
}
// else block is empty - we can leave selection alone here, i think.
@ -5194,8 +5171,8 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
else if (wsEndObj.mStartReason == nsWSRunObject::eBreak)
{
// endpoint is just after break. lets adjust it to before it.
res = nsEditor::GetNodeLocation(wsEndObj.mStartReasonNode, address_of(newEndNode), &newEndOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(wsEndObj.mStartReasonNode,
address_of(newEndNode), &newEndOffset);
}
}
@ -5216,8 +5193,8 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode, true);
if (child)
{
res = nsEditor::GetNodeLocation(child, address_of(newStartNode), &newStartOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(child, address_of(newStartNode),
&newStartOffset);
}
// else block is empty - we can leave selection alone here, i think.
}
@ -5228,16 +5205,16 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
res = mHTMLEditor->GetNextHTMLNode(startNode, startOffset, address_of(child));
if (child)
{
res = nsEditor::GetNodeLocation(child, address_of(newStartNode), &newStartOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(child, address_of(newStartNode),
&newStartOffset);
}
// else block is empty - we can leave selection alone here, i think.
}
else if (wsStartObj.mEndReason == nsWSRunObject::eBreak)
{
// startpoint is just before a break. lets adjust it to after it.
res = nsEditor::GetNodeLocation(wsStartObj.mEndReasonNode, address_of(newStartNode), &newStartOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(wsStartObj.mEndReasonNode,
address_of(newStartNode), &newStartOffset);
++newStartOffset; // offset *after* break
}
}
@ -5268,197 +5245,176 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
///////////////////////////////////////////////////////////////////////////
// GetPromotedPoint: figure out where a start or end point for a block
// operation really is
nsresult
nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode,
void
nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
PRInt32 aOffset,
nsEditor::OperationID actionID,
nsCOMPtr<nsIDOMNode> *outNode,
PRInt32 *outOffset)
nsCOMPtr<nsIDOMNode>* outNode,
PRInt32* outOffset)
{
nsCOMPtr<nsIDOMNode> nearNode, node = aNode;
nsCOMPtr<nsIDOMNode> parent = aNode;
PRInt32 pOffset, offset = aOffset;
// default values
*outNode = node;
*outOffset = offset;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
MOZ_ASSERT(node && outNode && outOffset);
// we do one thing for text actions, something else entirely for other actions
// default values
*outNode = node->AsDOMNode();
*outOffset = aOffset;
// we do one thing for text actions, something else entirely for other
// actions
if (actionID == nsEditor::kOpInsertText ||
actionID == nsEditor::kOpInsertIMEText ||
actionID == nsEditor::kOpInsertBreak ||
actionID == nsEditor::kOpDeleteText)
{
actionID == nsEditor::kOpDeleteText) {
bool isSpace, isNBSP;
nsCOMPtr<nsIDOMNode> temp;
// for text actions, we want to look backwards (or forwards, as appropriate)
// for additional whitespace or nbsp's. We may have to act on these later even though
// they are outside of the initial selection. Even if they are in another node!
if (aWhere == kStart)
{
do
{
PRInt32 prevOffset;
mHTMLEditor->IsPrevCharWhitespace(node, offset, &isSpace, &isNBSP,
address_of(temp), &prevOffset);
if (isSpace || isNBSP) {
node = temp;
offset = prevOffset;
} else {
break;
}
} while (node);
*outNode = node;
*outOffset = offset;
nsCOMPtr<nsIContent> content = do_QueryInterface(node), temp;
// for text actions, we want to look backwards (or forwards, as
// appropriate) for additional whitespace or nbsp's. We may have to act on
// these later even though they are outside of the initial selection. Even
// if they are in another node!
while (content) {
PRInt32 offset;
if (aWhere == kStart) {
mHTMLEditor->IsPrevCharInNodeWhitespace(content, *outOffset,
&isSpace, &isNBSP,
getter_AddRefs(temp), &offset);
} else {
mHTMLEditor->IsNextCharInNodeWhitespace(content, *outOffset,
&isSpace, &isNBSP,
getter_AddRefs(temp), &offset);
}
if (isSpace || isNBSP) {
content = temp;
*outOffset = offset;
} else {
break;
}
}
else if (aWhere == kEnd)
{
do
{
PRInt32 nextOffset;
mHTMLEditor->IsNextCharWhitespace(node, offset, &isSpace, &isNBSP,
address_of(temp), &nextOffset);
if (isSpace || isNBSP) {
node = temp;
offset = nextOffset;
} else {
break;
}
} while (node);
*outNode = node;
*outOffset = offset;
}
return NS_OK;
*outNode = content->AsDOMNode();
return;
}
// else not a text section. In this case we want to see if we should
// grab any adjacent inline nodes and/or parents and other ancestors
nsresult res = NS_OK;
if (aWhere == kStart)
{
PRInt32 offset = aOffset;
// else not a text section. In this case we want to see if we should grab
// any adjacent inline nodes and/or parents and other ancestors
if (aWhere == kStart) {
// some special casing for text nodes
if (nsEditor::IsTextNode(aNode))
{
res = nsEditor::GetNodeLocation(aNode, address_of(node), &offset);
NS_ENSURE_SUCCESS(res, res);
if (node->IsNodeOfType(nsINode::eTEXT)) {
if (!node->GetNodeParent()) {
// Okay, can't promote any further
return;
}
offset = node->GetNodeParent()->IndexOf(node);
node = node->GetNodeParent();
}
// look back through any further inline nodes that
// aren't across a <br> from us, and that are enclosed in the same block.
nsCOMPtr<nsIDOMNode> priorNode;
res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(priorNode), true);
while (priorNode && NS_SUCCEEDED(res))
{
if (mHTMLEditor->IsVisBreak(priorNode))
break;
if (IsBlockNode(priorNode))
break;
res = nsEditor::GetNodeLocation(priorNode, address_of(node), &offset);
NS_ENSURE_SUCCESS(res, res);
res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(priorNode), true);
NS_ENSURE_SUCCESS(res, res);
}
// finding the real start for this point. look up the tree for as long as we are the
// first node in the container, and as long as we haven't hit the body node.
res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(nearNode), true);
NS_ENSURE_SUCCESS(res, res);
while (!nearNode && !nsTextEditUtils::IsBody(node))
{
// some cutoffs are here: we don't need to also include them in the aWhere == kEnd case.
// as long as they are in one or the other it will work.
// special case for outdent: don't keep looking up
// if we have found a blockquote element to act on
if ((actionID == nsHTMLEditor::kOpOutdent) && nsHTMLEditUtils::IsBlockquote(node))
break;
// look back through any further inline nodes that aren't across a <br>
// from us, and that are enclosed in the same block.
nsCOMPtr<nsINode> priorNode =
mHTMLEditor->GetPriorHTMLNode(node, offset, true);
res = nsEditor::GetNodeLocation(node, address_of(parent), &pOffset);
NS_ENSURE_SUCCESS(res, res);
while (priorNode && priorNode->GetNodeParent() &&
!mHTMLEditor->IsVisBreak(priorNode->AsDOMNode()) &&
!IsBlockNode(priorNode->AsDOMNode())) {
offset = priorNode->GetNodeParent()->IndexOf(priorNode);
node = priorNode->GetNodeParent();
priorNode = mHTMLEditor->GetPriorHTMLNode(node, offset, true);
}
// finding the real start for this point. look up the tree for as long as
// we are the first node in the container, and as long as we haven't hit
// the body node.
nsCOMPtr<nsIContent> nearNode =
mHTMLEditor->GetPriorHTMLNode(node, offset, true);
while (!nearNode && node->Tag() != nsGkAtoms::body &&
node->GetNodeParent()) {
// some cutoffs are here: we don't need to also include them in the
// aWhere == kEnd case. as long as they are in one or the other it will
// work. special case for outdent: don't keep looking up if we have
// found a blockquote element to act on
if (actionID == nsHTMLEditor::kOpOutdent &&
node->Tag() == nsGkAtoms::blockquote) {
break;
}
PRInt32 parentOffset = node->GetNodeParent()->IndexOf(node);
nsCOMPtr<nsINode> parent = node->GetNodeParent();
// Don't walk past the editable section. Note that we need to check
// before walking up to a parent because we need to return the parent
// object, so the parent itself might not be in the editable area, but
// it's OK if we're not performing a block-level action.
bool blockLevelAction = (actionID == nsHTMLEditor::kOpIndent)
|| (actionID == nsHTMLEditor::kOpOutdent)
|| (actionID == nsHTMLEditor::kOpAlign)
|| (actionID == nsHTMLEditor::kOpMakeBasicBlock);
bool blockLevelAction = actionID == nsHTMLEditor::kOpIndent ||
actionID == nsHTMLEditor::kOpOutdent ||
actionID == nsHTMLEditor::kOpAlign ||
actionID == nsHTMLEditor::kOpMakeBasicBlock;
if (!mHTMLEditor->IsDescendantOfEditorRoot(parent) &&
(blockLevelAction || !mHTMLEditor->IsDescendantOfEditorRoot(node))) {
break;
}
node = parent;
offset = pOffset;
res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(nearNode), true);
NS_ENSURE_SUCCESS(res, res);
}
*outNode = node;
offset = parentOffset;
nearNode = mHTMLEditor->GetPriorHTMLNode(node, offset, true);
}
*outNode = node->AsDOMNode();
*outOffset = offset;
return res;
return;
}
if (aWhere == kEnd)
{
// some special casing for text nodes
if (nsEditor::IsTextNode(aNode))
{
res = nsEditor::GetNodeLocation(aNode, address_of(node), &offset);
NS_ENSURE_SUCCESS(res, res);
offset++; // want to be after the text node
// aWhere == kEnd
// some special casing for text nodes
if (node->IsNodeOfType(nsINode::eTEXT)) {
if (!node->GetNodeParent()) {
// Okay, can't promote any further
return;
}
// want to be after the text node
offset = 1 + node->GetNodeParent()->IndexOf(node);
node = node->GetNodeParent();
}
// look ahead through any further inline nodes that aren't across a <br> from
// us, and that are enclosed in the same block.
nsCOMPtr<nsIContent> nextNode =
mHTMLEditor->GetNextHTMLNode(node, offset, true);
while (nextNode && !IsBlockNode(nextNode->AsDOMNode()) &&
nextNode->GetNodeParent()) {
offset = 1 + nextNode->GetNodeParent()->IndexOf(nextNode);
node = nextNode->GetNodeParent();
if (mHTMLEditor->IsVisBreak(nextNode->AsDOMNode())) {
break;
}
nextNode = mHTMLEditor->GetNextHTMLNode(node, offset, true);
}
// finding the real end for this point. look up the tree for as long as we
// are the last node in the container, and as long as we haven't hit the body
// node.
nsCOMPtr<nsIContent> nearNode =
mHTMLEditor->GetNextHTMLNode(node, offset, true);
while (!nearNode && node->Tag() != nsGkAtoms::body &&
node->GetNodeParent()) {
PRInt32 parentOffset = node->GetNodeParent()->IndexOf(node);
nsCOMPtr<nsINode> parent = node->GetNodeParent();
// Don't walk past the editable section. Note that we need to check before
// walking up to a parent because we need to return the parent object, so
// the parent itself might not be in the editable area, but it's OK.
if (!mHTMLEditor->IsDescendantOfEditorRoot(node) &&
!mHTMLEditor->IsDescendantOfEditorRoot(parent)) {
break;
}
// look ahead through any further inline nodes that
// aren't across a <br> from us, and that are enclosed in the same block.
nsCOMPtr<nsIDOMNode> nextNode;
res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nextNode), true);
while (nextNode && NS_SUCCEEDED(res))
{
if (IsBlockNode(nextNode))
break;
res = nsEditor::GetNodeLocation(nextNode, address_of(node), &offset);
NS_ENSURE_SUCCESS(res, res);
offset++;
if (mHTMLEditor->IsVisBreak(nextNode))
break;
res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nextNode), true);
NS_ENSURE_SUCCESS(res, res);
}
// finding the real end for this point. look up the tree for as long as we are the
// last node in the container, and as long as we haven't hit the body node.
res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nearNode), true);
NS_ENSURE_SUCCESS(res, res);
while (!nearNode && !nsTextEditUtils::IsBody(node))
{
res = nsEditor::GetNodeLocation(node, address_of(parent), &pOffset);
NS_ENSURE_SUCCESS(res, res);
// Don't walk past the editable section. Note that we need to check
// before walking up to a parent because we need to return the parent
// object, so the parent itself might not be in the editable area, but
// it's OK.
if (!mHTMLEditor->IsDescendantOfEditorRoot(node) &&
!mHTMLEditor->IsDescendantOfEditorRoot(parent)) {
break;
}
node = parent;
offset = pOffset+1; // we want to be AFTER nearNode
res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nearNode), true);
NS_ENSURE_SUCCESS(res, res);
}
*outNode = node;
*outOffset = offset;
return res;
node = parent;
// we want to be AFTER nearNode
offset = parentOffset + 1;
nearNode = mHTMLEditor->GetNextHTMLNode(node, offset, true);
}
return res;
*outNode = node->AsDOMNode();
*outOffset = offset;
}
@ -5571,10 +5527,10 @@ nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange,
PRInt32 opStartOffset, opEndOffset;
nsCOMPtr<nsIDOMRange> opRange;
res = GetPromotedPoint( kStart, startNode, startOffset, inOperationType, address_of(opStartNode), &opStartOffset);
NS_ENSURE_SUCCESS(res, res);
res = GetPromotedPoint( kEnd, endNode, endOffset, inOperationType, address_of(opEndNode), &opEndOffset);
NS_ENSURE_SUCCESS(res, res);
GetPromotedPoint(kStart, startNode, startOffset, inOperationType,
address_of(opStartNode), &opStartOffset);
GetPromotedPoint(kEnd, endNode, endOffset, inOperationType,
address_of(opEndNode), &opEndOffset);
// Make sure that the new range ends up to be in the editable section.
if (!mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) ||
@ -6103,8 +6059,8 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode,
breakNode = arrayOfBreaks[i];
NS_ENSURE_TRUE(breakNode, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER);
res = nsEditor::GetNodeLocation(breakNode, address_of(splitParentNode), &splitOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(breakNode, address_of(splitParentNode),
&splitOffset);
res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset,
&resultOffset, false, address_of(leftNode), address_of(rightNode));
NS_ENSURE_SUCCESS(res, res);
@ -6306,12 +6262,13 @@ nsHTMLEditRules::ReturnInHeader(nsISelection *aSelection,
// remeber where the header is
nsCOMPtr<nsIDOMNode> headerParent;
PRInt32 offset;
nsresult res = nsEditor::GetNodeLocation(aHeader, address_of(headerParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aHeader, address_of(headerParent), &offset);
// get ws code to adjust any ws
nsCOMPtr<nsIDOMNode> selNode = aNode;
res = nsWSRunObject::PrepareToSplitAcrossBlocks(mHTMLEditor, address_of(selNode), &aOffset);
nsresult res = nsWSRunObject::PrepareToSplitAcrossBlocks(mHTMLEditor,
address_of(selNode),
&aOffset);
NS_ENSURE_SUCCESS(res, res);
// split the header
@ -6364,8 +6321,7 @@ nsHTMLEditRules::ReturnInHeader(nsISelection *aSelection,
}
else
{
res = nsEditor::GetNodeLocation(sibling, address_of(headerParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(sibling, address_of(headerParent), &offset);
// put selection after break
res = aSelection->Collapse(headerParent,offset+1);
}
@ -6394,11 +6350,11 @@ nsHTMLEditRules::ReturnInParagraph(nsISelection* aSelection,
}
*aCancel = false;
*aHandled = false;
nsresult res;
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
nsresult res = nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aNode, address_of(parent), &offset);
bool doesCRCreateNewP = mHTMLEditor->GetReturnInParagraphCreatesNewParagraph();
@ -6527,7 +6483,7 @@ nsHTMLEditRules::SplitParagraph(nsIDOMNode *aPara,
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(child, address_of(parent), &offset);
nsEditor::GetNodeLocation(child, address_of(parent), &offset);
aSelection->Collapse(parent,offset);
}
return res;
@ -6559,8 +6515,7 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootContent);
nsCOMPtr<nsIDOMNode> list;
PRInt32 itemOffset;
res = nsEditor::GetNodeLocation(aListItem, address_of(list), &itemOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aListItem, address_of(list), &itemOffset);
// if we are in an empty listitem, then we want to pop up out of the list
// but only if prefs says it's ok and if the parent isn't the active editing host.
@ -6572,8 +6527,7 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
// get the list offset now -- before we might eventually split the list
nsCOMPtr<nsIDOMNode> listparent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(list, address_of(listparent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(list, address_of(listparent), &offset);
// are we the last list item in the list?
bool bIsLast;
@ -6651,8 +6605,7 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
{
nsCOMPtr<nsIDOMNode> list;
PRInt32 itemOffset;
res = nsEditor::GetNodeLocation(aListItem, address_of(list), &itemOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aListItem, address_of(list), &itemOffset);
nsAutoString listTag((nodeAtom == nsEditProperty::dt) ? NS_LITERAL_STRING("dd") : NS_LITERAL_STRING("dt"));
nsCOMPtr<nsIDOMNode> newListItem;
@ -6670,7 +6623,7 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
{
nsCOMPtr<nsIDOMNode> brParent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(brNode, address_of(brParent), &offset);
nsEditor::GetNodeLocation(brNode, address_of(brParent), &offset);
return aSelection->Collapse(brParent, offset);
}
}
@ -6688,8 +6641,7 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(visNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(visNode, address_of(parent), &offset);
return aSelection->Collapse(parent, offset);
}
else
@ -6728,8 +6680,7 @@ nsHTMLEditRules::MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes)
{
// get the node to act on, and its location
curNode = arrayOfNodes[i];
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// if the node is a table element or list item, dive inside
if (nsHTMLEditUtils::IsTableElementButNotTable(curNode) ||
@ -6927,8 +6878,7 @@ nsHTMLEditRules::ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsA
{
// get the node to act on, and its location
curNode = arrayOfNodes[i];
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
nsAutoString curNodeTag;
nsEditor::GetTagString(curNode, curNodeTag);
ToLowerCase(curNodeTag);
@ -7121,8 +7071,7 @@ nsHTMLEditRules::JoinNodesSmart( nsIDOMNode *aNodeLeft,
// left & right node are same type
PRInt32 parOffset;
nsCOMPtr<nsIDOMNode> parent, rightParent;
res = nsEditor::GetNodeLocation(aNodeLeft, address_of(parent), &parOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(aNodeLeft, address_of(parent), &parOffset);
aNodeRight->GetParentNode(getter_AddRefs(rightParent));
// if they don't have the same parent, first move the 'right' node
@ -7394,8 +7343,7 @@ nsHTMLEditRules::PinSelectionToNewBlock(nsISelection *aSelection)
else
{
nsCOMPtr<nsIDOMNode> tmp2;
res = nsEditor::GetNodeLocation(tmp, address_of(tmp2), (PRInt32*)&endPoint);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(tmp, address_of(tmp2), (PRInt32*)&endPoint);
tmp = tmp2;
endPoint++; // want to be after this node
}
@ -7410,8 +7358,7 @@ nsHTMLEditRules::PinSelectionToNewBlock(nsISelection *aSelection)
if (!(mHTMLEditor->IsTextNode(tmp) || mHTMLEditor->IsContainer(tmp)))
{
nsCOMPtr<nsIDOMNode> tmp2;
res = nsEditor::GetNodeLocation(tmp, address_of(tmp2), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(tmp, address_of(tmp2), &offset);
tmp = tmp2;
}
return aSelection->Collapse(tmp, 0);
@ -7486,8 +7433,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
while (!mHTMLEditor->IsEditable(selNode))
{
// scan up the tree until we find an editable place to be
res = nsEditor::GetNodeLocation(temp, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(temp, address_of(selNode), &selOffset);
NS_ENSURE_TRUE(selNode, NS_ERROR_FAILURE);
temp = selNode;
}
@ -7550,8 +7496,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
nsCOMPtr<nsIDOMNode> brNode;
res = CreateMozBR(selNode, selOffset, getter_AddRefs(brNode));
NS_ENSURE_SUCCESS(res, res);
res = nsEditor::GetNodeLocation(brNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(brNode, address_of(selNode), &selOffset);
// selection stays *before* moz-br, sticking to it
selPriv->SetInterlinePosition(true);
res = aSelection->Collapse(selNode,selOffset);
@ -7607,8 +7552,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
}
else // must be break or image
{
res = nsEditor::GetNodeLocation(nearNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(nearNode, address_of(selNode), &selOffset);
if (aAction == nsIEditor::ePrevious) selOffset++; // want to be beyond it if we backed up to it
res = aSelection->Collapse(selNode, selOffset);
}
@ -7839,8 +7783,7 @@ nsHTMLEditRules::RemoveEmptyNodes()
// but preserve br.
nsCOMPtr<nsIDOMNode> parent, brNode;
PRInt32 offset;
res = nsEditor::GetNodeLocation(delNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(delNode, address_of(parent), &offset);
res = mHTMLEditor->CreateBR(parent, offset, address_of(brNode));
NS_ENSURE_SUCCESS(res, res);
}
@ -7969,8 +7912,7 @@ nsHTMLEditRules::PopListItem(nsIDOMNode *aListItem, bool *aOutOfList)
nsCOMPtr<nsIDOMNode> curParent;
nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(aListItem));
PRInt32 offset;
nsresult res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
if (!nsHTMLEditUtils::IsListItem(curNode))
return NS_ERROR_FAILURE;
@ -7979,11 +7921,10 @@ nsHTMLEditRules::PopListItem(nsIDOMNode *aListItem, bool *aOutOfList)
// otherwise we do.
nsCOMPtr<nsIDOMNode> curParPar;
PRInt32 parOffset;
res = nsEditor::GetNodeLocation(curParent, address_of(curParPar), &parOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curParent, address_of(curParPar), &parOffset);
bool bIsFirstListItem;
res = mHTMLEditor->IsFirstEditableChild(curNode, &bIsFirstListItem);
nsresult res = mHTMLEditor->IsFirstEditableChild(curNode, &bIsFirstListItem);
NS_ENSURE_SUCCESS(res, res);
bool bIsLastListItem;
@ -8761,8 +8702,7 @@ nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, b
if (!mHTMLEditor->IsEditable(curNode)) continue;
PRInt32 offset;
res = nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(curNode, address_of(curParent), &offset);
// some logic for putting list items into nested lists...
if (nsHTMLEditUtils::IsList(curParent))
@ -8786,7 +8726,8 @@ nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, b
if (!curPositionedDiv) {
PRInt32 parentOffset;
nsCOMPtr<nsIDOMNode> curParentParent;
res = nsEditor::GetNodeLocation(curParent, address_of(curParentParent), &parentOffset);
nsEditor::GetNodeLocation(curParent, address_of(curParentParent),
&parentOffset);
res = mHTMLEditor->CreateNode(divType, curParentParent, parentOffset, getter_AddRefs(curPositionedDiv));
mNewBlock = curPositionedDiv;
}
@ -8815,8 +8756,7 @@ nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, b
if (listitem)
{
if (indentedLI == listitem) continue; // already indented this list item
res = nsEditor::GetNodeLocation(listitem, address_of(curParent), &offset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(listitem, address_of(curParent), &offset);
// check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
if (curList)
@ -8836,7 +8776,8 @@ nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, b
if (!curPositionedDiv) {
PRInt32 parentOffset;
nsCOMPtr<nsIDOMNode> curParentParent;
res = nsEditor::GetNodeLocation(curParent, address_of(curParentParent), &parentOffset);
nsEditor::GetNodeLocation(curParent, address_of(curParentParent),
&parentOffset);
res = mHTMLEditor->CreateNode(divType, curParentParent, parentOffset, getter_AddRefs(curPositionedDiv));
mNewBlock = curPositionedDiv;
}

View File

@ -211,9 +211,9 @@ protected:
bool IsFirstNode(nsIDOMNode *aNode);
bool IsLastNode(nsIDOMNode *aNode);
nsresult NormalizeSelection(nsISelection *inSelection);
nsresult GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode,
PRInt32 aOffset, nsEditor::OperationID actionID,
nsCOMPtr<nsIDOMNode> *outNode, PRInt32 *outOffset);
void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
PRInt32 aOffset, nsEditor::OperationID actionID,
nsCOMPtr<nsIDOMNode>* outNode, PRInt32* outOffset);
nsresult GetPromotedRanges(nsISelection *inSelection,
nsCOMArray<nsIDOMRange> &outArrayOfRanges,
nsEditor::OperationID inOperationType);

View File

@ -64,6 +64,7 @@
#include "nsIFrame.h"
#include "nsIParserService.h"
#include "mozilla/dom/Element.h"
#include "nsTextFragment.h"
using namespace mozilla;
using namespace mozilla::widget;
@ -525,8 +526,7 @@ nsHTMLEditor::BeginningOfDocument()
else if ((visType==nsWSRunObject::eBreak) ||
(visType==nsWSRunObject::eSpecial))
{
res = GetNodeLocation(visNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(visNode, address_of(selNode), &selOffset);
done = true;
}
else if (visType==nsWSRunObject::eOtherBlock)
@ -546,8 +546,7 @@ nsHTMLEditor::BeginningOfDocument()
// like a <hr>
// We want to place the caret in front of that block.
res = GetNodeLocation(visNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(visNode, address_of(selNode), &selOffset);
done = true;
}
else
@ -557,8 +556,7 @@ nsHTMLEditor::BeginningOfDocument()
isEmptyBlock)
{
// skip the empty block
res = GetNodeLocation(visNode, address_of(curNode), &curOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(visNode, address_of(curNode), &curOffset);
++curOffset;
}
else
@ -847,195 +845,70 @@ nsHTMLEditor::GetBlockNodeParent(nsIDOMNode *aNode)
return p.forget();
}
///////////////////////////////////////////////////////////////////////////
// NextNodeInBlock: gets the next/prev node in the block, if any. Next node
// must be an element or text node, others are ignored
already_AddRefed<nsIDOMNode>
nsHTMLEditor::NextNodeInBlock(nsIDOMNode *aNode, IterDirection aDir)
{
NS_ENSURE_TRUE(aNode, nsnull);
nsresult rv;
nsCOMPtr<nsIContentIterator> iter =
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &rv);
NS_ENSURE_SUCCESS(rv, nsnull);
// much gnashing of teeth as we twit back and forth between content and domnode types
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
nsCOMPtr<nsIDOMNode> blockParent;
bool isBlock;
if (NS_SUCCEEDED(NodeIsBlockStatic(aNode, &isBlock)) && isBlock) {
blockParent = aNode;
} else {
blockParent = GetBlockNodeParent(aNode);
}
NS_ENSURE_TRUE(blockParent, nsnull);
nsCOMPtr<nsIContent> blockContent = do_QueryInterface(blockParent);
NS_ENSURE_TRUE(blockContent, nsnull);
if (NS_FAILED(iter->Init(blockContent))) {
return nsnull;
}
if (NS_FAILED(iter->PositionAt(content))) {
return nsnull;
}
while (!iter->IsDone()) {
// ignore nodes that aren't elements or text, or that are the
// block parent
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(iter->GetCurrentNode());
if (node && IsTextOrElementNode(node) && node != blockParent &&
node != aNode)
return node.forget();
if (aDir == kIterForward)
iter->Next();
else
iter->Prev();
}
return nsnull;
}
static const PRUnichar nbsp = 160;
///////////////////////////////////////////////////////////////////////////
// IsNextCharWhitespace: checks the adjacent content in the same block
// to see if following selection is whitespace or nbsp
///////////////////////////////////////////////////////////////////////////////
// IsNextCharInNodeWhitespace: checks the adjacent content in the same node to
// see if following selection is whitespace or nbsp
void
nsHTMLEditor::IsNextCharWhitespace(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool *outIsSpace,
bool *outIsNBSP,
nsCOMPtr<nsIDOMNode> *outNode,
PRInt32 *outOffset)
nsHTMLEditor::IsNextCharInNodeWhitespace(nsIContent* aContent,
PRInt32 aOffset,
bool* outIsSpace,
bool* outIsNBSP,
nsIContent** outNode,
PRInt32* outOffset)
{
MOZ_ASSERT(outIsSpace && outIsNBSP);
MOZ_ASSERT(aContent && outIsSpace && outIsNBSP);
MOZ_ASSERT((outNode && outOffset) || (!outNode && !outOffset));
*outIsSpace = false;
*outIsNBSP = false;
if (outNode) *outNode = nsnull;
if (outOffset) *outOffset = -1;
nsAutoString tempString;
PRUint32 strLength;
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aParentNode);
if (textNode)
{
textNode->GetLength(&strLength);
if ((PRUint32)aOffset < strLength)
{
// easy case: next char is in same node
textNode->SubstringData(aOffset,aOffset+1,tempString);
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
*outIsNBSP = (tempString.First() == nbsp);
if (outNode) *outNode = do_QueryInterface(aParentNode);
if (outOffset) *outOffset = aOffset+1; // yes, this is _past_ the character;
return;
}
if (outNode && outOffset) {
*outNode = nsnull;
*outOffset = -1;
}
// harder case: next char in next node.
nsCOMPtr<nsIDOMNode> node = NextNodeInBlock(aParentNode, kIterForward);
nsCOMPtr<nsIDOMNode> tmp;
while (node)
{
bool isBlock (false);
NodeIsBlock(node, &isBlock);
if (isBlock) // skip over bold, italic, link, ect nodes
{
if (IsTextNode(node) && IsEditable(node))
{
textNode = do_QueryInterface(node);
textNode->GetLength(&strLength);
if (strLength)
{
textNode->SubstringData(0,1,tempString);
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
*outIsNBSP = (tempString.First() == nbsp);
if (outNode) *outNode = do_QueryInterface(node);
if (outOffset) *outOffset = 1; // yes, this is _past_ the character;
return;
}
// else it's an empty text node, or not editable; skip it.
}
else // node is an image or some other thingy that doesn't count as whitespace
{
break;
}
if (aContent->IsNodeOfType(nsINode::eTEXT) &&
(PRUint32)aOffset < aContent->Length()) {
PRUnichar ch = aContent->GetText()->CharAt(aOffset);
*outIsSpace = nsCRT::IsAsciiSpace(ch);
*outIsNBSP = (ch == nbsp);
if (outNode && outOffset) {
NS_IF_ADDREF(*outNode = aContent);
// yes, this is _past_ the character
*outOffset = aOffset + 1;
}
tmp = node;
node = NextNodeInBlock(tmp, kIterForward);
}
}
///////////////////////////////////////////////////////////////////////////
// IsPrevCharWhitespace: checks the adjacent content in the same block
// to see if following selection is whitespace
///////////////////////////////////////////////////////////////////////////////
// IsPrevCharInNodeWhitespace: checks the adjacent content in the same node to
// see if following selection is whitespace
void
nsHTMLEditor::IsPrevCharWhitespace(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool *outIsSpace,
bool *outIsNBSP,
nsCOMPtr<nsIDOMNode> *outNode,
PRInt32 *outOffset)
nsHTMLEditor::IsPrevCharInNodeWhitespace(nsIContent* aContent,
PRInt32 aOffset,
bool* outIsSpace,
bool* outIsNBSP,
nsIContent** outNode,
PRInt32* outOffset)
{
MOZ_ASSERT(outIsSpace && outIsNBSP);
MOZ_ASSERT(aContent && outIsSpace && outIsNBSP);
MOZ_ASSERT((outNode && outOffset) || (!outNode && !outOffset));
*outIsSpace = false;
*outIsNBSP = false;
if (outNode) *outNode = nsnull;
if (outOffset) *outOffset = -1;
nsAutoString tempString;
PRUint32 strLength;
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aParentNode);
if (textNode)
{
if (aOffset > 0)
{
// easy case: prev char is in same node
textNode->SubstringData(aOffset-1,aOffset,tempString);
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
*outIsNBSP = (tempString.First() == nbsp);
if (outNode) *outNode = do_QueryInterface(aParentNode);
if (outOffset) *outOffset = aOffset-1;
return;
}
if (outNode && outOffset) {
*outNode = nsnull;
*outOffset = -1;
}
// harder case: prev char in next node
nsCOMPtr<nsIDOMNode> node = NextNodeInBlock(aParentNode, kIterBackward);
nsCOMPtr<nsIDOMNode> tmp;
while (node)
{
bool isBlock (false);
NodeIsBlock(node, &isBlock);
if (isBlock) // skip over bold, italic, link, ect nodes
{
if (IsTextNode(node) && IsEditable(node))
{
textNode = do_QueryInterface(node);
textNode->GetLength(&strLength);
if (strLength)
{
// you could use nsIContent::TextIsOnlyWhitespace here
textNode->SubstringData(strLength-1,strLength,tempString);
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
*outIsNBSP = (tempString.First() == nbsp);
if (outNode) *outNode = do_QueryInterface(aParentNode);
if (outOffset) *outOffset = strLength-1;
return;
}
// else it's an empty text node, or not editable; skip it.
}
else // node is an image or some other thingy that doesn't count as whitespace
{
break;
}
if (aContent->IsNodeOfType(nsINode::eTEXT) && aOffset > 0) {
PRUnichar ch = aContent->GetText()->CharAt(aOffset - 1);
*outIsSpace = nsCRT::IsAsciiSpace(ch);
*outIsNBSP = (ch == nbsp);
if (outNode && outOffset) {
NS_IF_ADDREF(*outNode = aContent);
*outOffset = aOffset - 1;
}
// otherwise we found a node we want to skip, keep going
tmp = node;
node = NextNodeInBlock(tmp, kIterBackward);
}
}
@ -1783,17 +1656,13 @@ nsHTMLEditor::SelectElement(nsIDOMElement* aElement)
res = aElement->GetParentNode(getter_AddRefs(parent));
if (NS_SUCCEEDED(res) && parent)
{
PRInt32 offsetInParent;
res = GetChildOffset(aElement, parent, offsetInParent);
PRInt32 offsetInParent = GetChildOffset(aElement, parent);
if (NS_SUCCEEDED(res))
{
// Collapse selection to just before desired element,
res = selection->Collapse(parent, offsetInParent);
if (NS_SUCCEEDED(res)) {
// then extend it to just after
res = selection->Extend(parent, offsetInParent+1);
}
// Collapse selection to just before desired element,
res = selection->Collapse(parent, offsetInParent);
if (NS_SUCCEEDED(res)) {
// then extend it to just after
res = selection->Extend(parent, offsetInParent + 1);
}
}
}
@ -1815,26 +1684,9 @@ nsHTMLEditor::SetCaretAfterElement(nsIDOMElement* aElement)
res = aElement->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
PRInt32 offsetInParent;
res = GetChildOffset(aElement, parent, offsetInParent);
if (NS_SUCCEEDED(res))
{
// Collapse selection to just after desired element,
res = selection->Collapse(parent, offsetInParent+1);
#if 0 //def DEBUG_cmanske
{
nsAutoString name;
parent->GetNodeName(name);
printf("SetCaretAfterElement: Parent node: ");
wprintf(name.get());
printf(" Offset: %d\n\nHTML:\n", offsetInParent+1);
nsAutoString Format("text/html");
nsAutoString ContentsAs;
OutputToString(Format, 2, ContentsAs);
wprintf(ContentsAs.get());
}
#endif
}
PRInt32 offsetInParent = GetChildOffset(aElement, parent);
// Collapse selection to just after desired element,
res = selection->Collapse(parent, offsetInParent + 1);
}
return res;
}
@ -4285,6 +4137,17 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLNode: same as above but takes {parent,offset} instead of node
//
nsIContent*
nsHTMLEditor::GetPriorHTMLNode(nsINode* aParent, PRInt32 aOffset,
bool aNoBlockCrossing)
{
if (!GetActiveEditingHost()) {
return nsnull;
}
return GetPriorNode(aParent, aOffset, true, aNoBlockCrossing);
}
nsresult
nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
{
@ -4299,7 +4162,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<
nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode),
bNoBlockCrossing);
NS_ENSURE_SUCCESS(res, res);
NS_ASSERTION(!*outNode || IsDescendantOfEditorRoot(*outNode),
"GetPriorNode screwed up");
return res;
@ -4328,6 +4191,17 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode,
///////////////////////////////////////////////////////////////////////////
// GetNHTMLextNode: same as above but takes {parent,offset} instead of node
//
nsIContent*
nsHTMLEditor::GetNextHTMLNode(nsINode* aParent, PRInt32 aOffset,
bool aNoBlockCrossing)
{
nsIContent* content = GetNextNode(aParent, aOffset, true, aNoBlockCrossing);
if (content && !IsDescendantOfEditorRoot(content)) {
return nsnull;
}
return content;
}
nsresult
nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
{

View File

@ -229,19 +229,18 @@ public:
/* ------------ Block methods moved from nsEditor -------------- */
static already_AddRefed<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
static already_AddRefed<nsIDOMNode> NextNodeInBlock(nsIDOMNode *aNode, IterDirection aDir);
void IsNextCharWhitespace(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool *outIsSpace,
bool *outIsNBSP,
nsCOMPtr<nsIDOMNode> *outNode = 0,
PRInt32 *outOffset = 0);
void IsPrevCharWhitespace(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool *outIsSpace,
bool *outIsNBSP,
nsCOMPtr<nsIDOMNode> *outNode = 0,
PRInt32 *outOffset = 0);
void IsNextCharInNodeWhitespace(nsIContent* aContent,
PRInt32 aOffset,
bool* outIsSpace,
bool* outIsNBSP,
nsIContent** outNode = nsnull,
PRInt32* outOffset = 0);
void IsPrevCharInNodeWhitespace(nsIContent* aContent,
PRInt32 aOffset,
bool* outIsSpace,
bool* outIsNBSP,
nsIContent** outNode = nsnull,
PRInt32* outOffset = 0);
/* ------------ Overrides of nsEditor interface methods -------------- */
@ -694,7 +693,11 @@ protected:
nsresult GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing = false);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing = false);
nsIContent* GetPriorHTMLNode(nsINode* aParent, PRInt32 aOffset,
bool aNoBlockCrossing = false);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing = false);
nsIContent* GetNextHTMLNode(nsINode* aParent, PRInt32 aOffset,
bool aNoBlockCrossing = false);
nsresult GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing = false);
nsresult IsFirstEditableChild( nsIDOMNode *aNode, bool *aOutIsFirst);

View File

@ -937,15 +937,13 @@ nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRa
!nsTextEditUtils::IsBody(tmp) &&
!nsHTMLEditUtils::IsNamedAnchor(tmp))
{
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(tmp, address_of(parent), &tmpOffset);
tmp = parent;
}
NS_ENSURE_TRUE(tmp, NS_ERROR_NULL_POINTER);
if (nsHTMLEditUtils::IsNamedAnchor(tmp))
{
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(tmp, address_of(parent), &tmpOffset);
startNode = parent;
startOffset = tmpOffset;
}
@ -955,15 +953,13 @@ nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRa
!nsTextEditUtils::IsBody(tmp) &&
!nsHTMLEditUtils::IsNamedAnchor(tmp))
{
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(tmp, address_of(parent), &tmpOffset);
tmp = parent;
}
NS_ENSURE_TRUE(tmp, NS_ERROR_NULL_POINTER);
if (nsHTMLEditUtils::IsNamedAnchor(tmp))
{
res = GetNodeLocation(tmp, address_of(parent), &tmpOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(tmp, address_of(parent), &tmpOffset);
endNode = parent;
endOffset = tmpOffset + 1;
}
@ -995,8 +991,7 @@ nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
IsEditable(startNode) &&
IsAtFrontOfNode(startNode, startOffset) )
{
res = GetNodeLocation(startNode, address_of(parent), &startOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(startNode, address_of(parent), &startOffset);
startNode = parent;
}
NS_ENSURE_TRUE(startNode, NS_ERROR_NULL_POINTER);
@ -1006,8 +1001,7 @@ nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
IsEditable(endNode) &&
IsAtEndOfNode(endNode, endOffset) )
{
res = GetNodeLocation(endNode, address_of(parent), &endOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(endNode, address_of(parent), &endOffset);
endNode = parent;
endOffset++; // we are AFTER this node
}
@ -1035,8 +1029,7 @@ bool nsHTMLEditor::IsAtFrontOfNode(nsIDOMNode *aNode, PRInt32 aOffset)
nsCOMPtr<nsIDOMNode> firstNode;
GetFirstEditableChild(aNode, address_of(firstNode));
NS_ENSURE_TRUE(firstNode, true);
PRInt32 offset;
nsEditor::GetChildOffset(firstNode, aNode, offset);
PRInt32 offset = GetChildOffset(firstNode, aNode);
if (offset < aOffset) return false;
return true;
}
@ -1058,8 +1051,7 @@ bool nsHTMLEditor::IsAtEndOfNode(nsIDOMNode *aNode, PRInt32 aOffset)
nsCOMPtr<nsIDOMNode> lastNode;
GetLastEditableChild(aNode, address_of(lastNode));
NS_ENSURE_TRUE(lastNode, true);
PRInt32 offset;
nsEditor::GetChildOffset(lastNode, aNode, offset);
PRInt32 offset = GetChildOffset(lastNode, aNode);
if (offset < aOffset) return true;
return false;
}

View File

@ -97,10 +97,7 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(cellParent, NS_ERROR_NULL_POINTER);
PRInt32 cellOffset;
res = GetChildOffset(aCell, cellParent, cellOffset);
NS_ENSURE_SUCCESS(res, res);
PRInt32 cellOffset = GetChildOffset(aCell, cellParent);
nsCOMPtr<nsIDOMElement> newCell;
if (aIsHeader)
@ -660,8 +657,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, bool aAfter)
parentRow->GetParentNode(getter_AddRefs(parentOfRow));
NS_ENSURE_TRUE(parentOfRow, NS_ERROR_NULL_POINTER);
res = GetChildOffset(parentRow, parentOfRow, newRowOffset);
NS_ENSURE_SUCCESS(res, res);
newRowOffset = GetChildOffset(parentRow, parentOfRow);
// Adjust for when adding past the end
if (aAfter && startRowIndex >= rowCount)
@ -2870,8 +2866,9 @@ nsHTMLEditor::GetCellContext(nsISelection **aSelection,
*aCellParent = cellParent.get();
NS_ADDREF(*aCellParent);
if (aCellOffset)
res = GetChildOffset(cell, cellParent, *aCellOffset);
if (aCellOffset) {
*aCellOffset = GetChildOffset(cell, cellParent);
}
}
return res;
@ -3139,12 +3136,11 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PR
// We didn't find a cell
// Set selection to just before the table
nsCOMPtr<nsIDOMNode> tableParent;
PRInt32 tableOffset;
res = aTable->GetParentNode(getter_AddRefs(tableParent));
if(NS_SUCCEEDED(res) && tableParent)
{
if(NS_SUCCEEDED(GetChildOffset(aTable, tableParent, tableOffset)))
return selection->Collapse(tableParent, tableOffset);
PRInt32 tableOffset = GetChildOffset(aTable, tableParent);
return selection->Collapse(tableParent, tableOffset);
}
// Last resort: Set selection to start of doc
// (it's very bad to not have a valid selection!)

View File

@ -115,12 +115,10 @@ nsWSRunObject::PrepareToDeleteNode(nsHTMLEditor *aHTMLEd,
nsIDOMNode *aNode)
{
NS_ENSURE_TRUE(aNode && aHTMLEd, NS_ERROR_NULL_POINTER);
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = aHTMLEd->GetNodeLocation(aNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
aHTMLEd->GetNodeLocation(aNode, address_of(parent), &offset);
nsWSRunObject leftWSObj(aHTMLEd, parent, offset);
nsWSRunObject rightWSObj(aHTMLEd, parent, offset+1);

View File

@ -228,10 +228,9 @@ nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
// The decision for dropping before or after the
// subtree should really be done based on coordinates.
rv = GetNodeLocation(userSelectNode, address_of(newSelectionParent),
&newSelectionOffset);
GetNodeLocation(userSelectNode, address_of(newSelectionParent),
&newSelectionOffset);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(newSelectionParent, NS_ERROR_FAILURE);
}

View File

@ -447,8 +447,7 @@ nsPlaintextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
// split the text node
res = SplitNode(node, theOffset, getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(res, res);
res = GetNodeLocation(node, address_of(tmp), &offset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(node, address_of(tmp), &offset);
}
// create br
res = CreateNode(brType, tmp, offset, getter_AddRefs(brNode));
@ -468,8 +467,7 @@ nsPlaintextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
{
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
res = GetNodeLocation(*outBRNode, address_of(parent), &offset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(*outBRNode, address_of(parent), &offset);
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
@ -526,8 +524,7 @@ nsPlaintextEditor::InsertBR(nsCOMPtr<nsIDOMNode>* outBRNode)
NS_ENSURE_SUCCESS(res, res);
// position selection after br
res = GetNodeLocation(*outBRNode, address_of(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
GetNodeLocation(*outBRNode, address_of(selNode), &selOffset);
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
selPriv->SetInterlinePosition(true);
return selection->Collapse(selNode, selOffset+1);
@ -1570,8 +1567,7 @@ nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection)
if (childNode && nsTextEditUtils::IsMozBR(childNode)) {
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 parentOffset;
rv = GetNodeLocation(childNode, address_of(parentNode), &parentOffset);
NS_ENSURE_SUCCESS(rv, rv);
GetNodeLocation(childNode, address_of(parentNode), &parentOffset);
return aSelection->Extend(parentNode, parentOffset);
}

View File

@ -419,9 +419,7 @@ nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection)
nsCOMPtr<nsIDOMNode> parentNode;
PRInt32 parentOffset;
res = nsEditor::GetNodeLocation(selNode, address_of(parentNode),
&parentOffset);
NS_ENSURE_SUCCESS(res, res);
nsEditor::GetNodeLocation(selNode, address_of(parentNode), &parentOffset);
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER);

View File

@ -8,7 +8,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-arch=armv6
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -14,7 +14,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-arch=armv6
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -10,7 +10,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-arch=armv6
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-arch=armv6
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-arch=armv6
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=i386-linux-android
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r7b"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=9

View File

@ -13,7 +13,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=i386-linux-android
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r7b"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=9

View File

@ -9,7 +9,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=i386-linux-android
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r7b"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=9

View File

@ -6,7 +6,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=i386-linux-android
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r7b"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=9

View File

@ -6,7 +6,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=i386-linux-android
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r7b"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=9

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -13,7 +13,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -9,7 +9,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -6,7 +6,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -6,7 +6,6 @@ ac_add_options --enable-application=mobile/android
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r15/platforms/android-14"
ac_add_options --with-android-version=5

View File

@ -7,7 +7,6 @@ ac_add_options --enable-application=mobile
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r13/platforms/android-13"
ac_add_options --with-android-version=5

View File

@ -9,7 +9,6 @@ ac_add_options --enable-application=mobile
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r13/platforms/android-13"
ac_add_options --with-android-version=5

View File

@ -6,7 +6,6 @@ ac_add_options --enable-application=mobile/xul
# Android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
ac_add_options --with-android-sdk="/tools/android-sdk-r13/platforms/android-13"
ac_add_options --with-android-version=5

View File

@ -325,13 +325,26 @@ function CopyPassword() {
clipboard.copyString(password, document);
}
function CopyUsername() {
// Copy selected signon's username to clipboard
var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"].
getService(Components.interfaces.nsIClipboardHelper);
var row = document.getElementById("signonsTree").currentIndex;
var username = signonsTreeView.getCellText(row, {id : "userCol" });
clipboard.copyString(username);
}
function UpdateCopyPassword() {
var singleSelection = (signonsTreeView.selection.count == 1);
var menuitem = document.getElementById("context-copypassword");
if (singleSelection)
menuitem.removeAttribute("disabled");
else
menuitem.setAttribute("disabled", "true");
var passwordMenuitem = document.getElementById("context-copypassword");
var usernameMenuitem = document.getElementById("context-copyusername");
if (singleSelection) {
usernameMenuitem.removeAttribute("disabled");
passwordMenuitem.removeAttribute("disabled");
} else {
usernameMenuitem.setAttribute("disabled", "true");
passwordMenuitem.setAttribute("disabled", "true");
}
}
function masterPasswordLogin(noPasswordCallback) {

View File

@ -31,6 +31,9 @@
<popupset id="signonsTreeContextSet">
<menupopup id="signonsTreeContextMenu"
onpopupshowing="UpdateCopyPassword()">
<menuitem id="context-copyusername"
label="&copyUsernameCmd.label;"
oncommand="CopyUsername()"/>
<menuitem id="context-copypassword"
label="&copyPasswordCmd.label;"
accesskey="&copyPasswordCmd.accesskey;"

View File

@ -33,24 +33,24 @@ function test() {
let pwmgrdlg = window.openDialog(PWMGR_DLG, "Toolkit:PasswordManager", "");
SimpleTest.waitForFocus(doTest, pwmgrdlg);
// Test if "Copy Password" works
// Test if "Copy Username" and "Copy Password" works
function doTest() {
let doc = pwmgrdlg.document;
let selection = doc.getElementById("signonsTree").view.selection;
let menuitem = doc.getElementById("context-copypassword");
let menuitem = doc.getElementById("context-copyusername");
function copyPassword() {
function copyField() {
selection.selectAll();
is(isMenuitemEnabled(), false, "Copy Password should be disabled");
is(isMenuitemEnabled(), false, "Copy should be disabled");
selection.select(0);
is(isMenuitemEnabled(), true, "Copy Password should be enabled");
is(isMenuitemEnabled(), true, "Copy should be enabled");
selection.clearSelection();
is(isMenuitemEnabled(), false, "Copy Password should be disabled");
is(isMenuitemEnabled(), false, "Copy should be disabled");
selection.select(2);
is(isMenuitemEnabled(), true, "Copy Password should be enabled");
is(isMenuitemEnabled(), true, "Copy should be enabled");
menuitem.doCommand();
}
@ -67,7 +67,14 @@ function test() {
});
pwmgrdlg.close();
}
waitForClipboard("coded", copyPassword, cleanUp, cleanUp);
function testPassword() {
menuitem = doc.getElementById("context-copypassword");
info("Testing Copy Password");
waitForClipboard("coded", copyField, cleanUp, cleanUp);
}
info("Testing Copy Username");
waitForClipboard("ehsan", copyField, testPassword, testPassword);
}
}

View File

@ -26,3 +26,5 @@
<!ENTITY copyPasswordCmd.label "Copy Password">
<!ENTITY copyPasswordCmd.accesskey "C">
<!ENTITY copyUsernameCmd.label "Copy Username">