gecko-dev/editor/libeditor/EditorDOMPoint.h
Masayuki Nakano 8b6c211c36 Bug 1408544 - part 1: Reimplement EditorDOMPoint as a subclass of RangeBoundary r=catalinb,m_kato
A lot of methods in editor returns a child offset with an out param when it
returns its container and offset in the container.  This is ugly hack for
performance of nsINode::IndexOf().  However, there are a lot of regression
since the relation between offset and child node can be broken really easily.

So, we should make EditorDOMPoint as a subclass of RangeBoundary and manage
a set of container, reference child and its offset in it (e.g.,
SetNextSibling() added by this patch).

Note that RangeBoundary's performance is not good for temporary use if we set
a point with offset, it immediately retrieves mRef.  The following patch will
improve this performance.

MozReview-Commit-ID: 7mcJ1P1OjVr

--HG--
rename : editor/libeditor/EditorUtils.h => editor/libeditor/EditorDOMPoint.h
extra : rebase_source : 785094fcfc592d9e5b48cbc36ed225dbb8bb4111
2017-11-01 14:41:03 +09:00

95 lines
2.8 KiB
C++

/* -*- 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/. */
#ifndef mozilla_EditorDOMPoint_h
#define mozilla_EditorDOMPoint_h
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/RangeBoundary.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsINode.h"
namespace mozilla {
template<typename ParentType, typename RefType>
class EditorDOMPointBase;
typedef EditorDOMPointBase<nsCOMPtr<nsINode>,
nsCOMPtr<nsIContent>> EditorDOMPoint;
typedef EditorDOMPointBase<nsINode*, nsIContent*> EditorRawDOMPoint;
template<typename ParentType, typename RefType>
class MOZ_STACK_CLASS EditorDOMPointBase final
: public RangeBoundaryBase<ParentType, RefType>
{
public:
EditorDOMPointBase()
: RangeBoundaryBase<ParentType, RefType>()
{
}
EditorDOMPointBase(nsINode* aConatiner,
int32_t aOffset)
: RangeBoundaryBase<ParentType, RefType>(aConatiner,
aOffset)
{
}
EditorDOMPointBase(nsIDOMNode* aDOMContainer,
int32_t aOffset)
: RangeBoundaryBase<ParentType, RefType>()
{
nsCOMPtr<nsINode> container = do_QueryInterface(aDOMContainer);
this->Set(container, aOffset);
}
/**
* Different from RangeBoundary, aReferenceChild should be a child node
* which you want to refer. So, set non-nullptr if offset is
* 0 - Length() - 1. Otherwise, set nullptr, i.e., if offset is same as
* Length().
*/
EditorDOMPointBase(nsINode* aContainer,
nsIContent* aPointedNode)
: RangeBoundaryBase<ParentType, RefType>(aContainer,
GetRef(aPointedNode))
{
}
EditorDOMPointBase(nsINode* aConatiner,
nsIContent* aPointedNode,
int32_t aOffset)
: RangeBoundaryBase<ParentType, RefType>(aConatiner,
GetRef(aPointedNode),
aOffset)
{
}
template<typename PT, typename RT>
explicit EditorDOMPointBase(const RangeBoundaryBase<PT, RT>& aOther)
: RangeBoundaryBase<ParentType, RefType>(aOther)
{
}
explicit EditorDOMPointBase(const RawRangeBoundary& aRawRangeBoundary)
: RangeBoundaryBase<ParentType, RefType>(aRawRangeBoundary)
{
}
private:
static nsIContent* GetRef(nsIContent* aPointedNode)
{
MOZ_ASSERT(aPointedNode);
return aPointedNode ? aPointedNode->GetPreviousSibling() : nullptr;
}
};
} // namespace mozilla
#endif // #ifndef mozilla_EditorDOMPoint_h