summaryrefslogtreecommitdiff
path: root/editor/libeditor/EditorUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'editor/libeditor/EditorUtils.h')
-rw-r--r--editor/libeditor/EditorUtils.h315
1 files changed, 315 insertions, 0 deletions
diff --git a/editor/libeditor/EditorUtils.h b/editor/libeditor/EditorUtils.h
new file mode 100644
index 0000000000..34286da8a9
--- /dev/null
+++ b/editor/libeditor/EditorUtils.h
@@ -0,0 +1,315 @@
+/* -*- 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_EditorUtils_h
+#define mozilla_EditorUtils_h
+
+#include "mozilla/EditorBase.h"
+#include "mozilla/GuardObjects.h"
+#include "nsCOMPtr.h"
+#include "nsDebug.h"
+#include "nsIDOMNode.h"
+#include "nsIEditor.h"
+#include "nscore.h"
+
+class nsIAtom;
+class nsIContentIterator;
+class nsIDOMDocument;
+class nsIDOMEvent;
+class nsISimpleEnumerator;
+class nsITransferable;
+class nsRange;
+
+namespace mozilla {
+template <class T> class OwningNonNull;
+
+namespace dom {
+class Selection;
+} // namespace dom
+
+/***************************************************************************
+ * stack based helper class for batching a collection of txns inside a
+ * placeholder txn.
+ */
+class MOZ_RAII AutoPlaceHolderBatch
+{
+private:
+ nsCOMPtr<nsIEditor> mEditor;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+public:
+ AutoPlaceHolderBatch(nsIEditor* aEditor,
+ nsIAtom* aAtom
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : mEditor(aEditor)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ if (mEditor) {
+ mEditor->BeginPlaceHolderTransaction(aAtom);
+ }
+ }
+ ~AutoPlaceHolderBatch()
+ {
+ if (mEditor) {
+ mEditor->EndPlaceHolderTransaction();
+ }
+ }
+};
+
+/***************************************************************************
+ * stack based helper class for batching a collection of txns.
+ * Note: I changed this to use placeholder batching so that we get
+ * proper selection save/restore across undo/redo.
+ */
+class MOZ_RAII AutoEditBatch final : public AutoPlaceHolderBatch
+{
+private:
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+public:
+ explicit AutoEditBatch(nsIEditor* aEditor
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : AutoPlaceHolderBatch(aEditor, nullptr)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ }
+ ~AutoEditBatch() {}
+};
+
+/***************************************************************************
+ * stack based helper class for saving/restoring selection. Note that this
+ * assumes that the nodes involved are still around afterwards!
+ */
+class MOZ_RAII AutoSelectionRestorer final
+{
+private:
+ // Ref-counted reference to the selection that we are supposed to restore.
+ RefPtr<dom::Selection> mSelection;
+ EditorBase* mEditorBase; // Non-owning ref to EditorBase.
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+public:
+ /**
+ * Constructor responsible for remembering all state needed to restore
+ * aSelection.
+ */
+ AutoSelectionRestorer(dom::Selection* aSelection,
+ EditorBase* aEditorBase
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+
+ /**
+ * Destructor restores mSelection to its former state
+ */
+ ~AutoSelectionRestorer();
+
+ /**
+ * Abort() cancels to restore the selection.
+ */
+ void Abort();
+};
+
+/***************************************************************************
+ * stack based helper class for StartOperation()/EndOperation() sandwich
+ */
+class MOZ_RAII AutoRules final
+{
+public:
+ AutoRules(EditorBase* aEditorBase, EditAction aAction,
+ nsIEditor::EDirection aDirection
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : mEditorBase(aEditorBase)
+ , mDoNothing(false)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ // mAction will already be set if this is nested call
+ if (mEditorBase && !mEditorBase->mAction) {
+ mEditorBase->StartOperation(aAction, aDirection);
+ } else {
+ mDoNothing = true; // nested calls will end up here
+ }
+ }
+
+ ~AutoRules()
+ {
+ if (mEditorBase && !mDoNothing) {
+ mEditorBase->EndOperation();
+ }
+ }
+
+protected:
+ EditorBase* mEditorBase;
+ bool mDoNothing;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+/***************************************************************************
+ * stack based helper class for turning off active selection adjustment
+ * by low level transactions
+ */
+class MOZ_RAII AutoTransactionsConserveSelection final
+{
+public:
+ explicit AutoTransactionsConserveSelection(EditorBase* aEditorBase
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : mEditorBase(aEditorBase)
+ , mOldState(true)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ if (mEditorBase) {
+ mOldState = mEditorBase->GetShouldTxnSetSelection();
+ mEditorBase->SetShouldTxnSetSelection(false);
+ }
+ }
+
+ ~AutoTransactionsConserveSelection()
+ {
+ if (mEditorBase) {
+ mEditorBase->SetShouldTxnSetSelection(mOldState);
+ }
+ }
+
+protected:
+ EditorBase* mEditorBase;
+ bool mOldState;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+/***************************************************************************
+ * stack based helper class for batching reflow and paint requests.
+ */
+class MOZ_RAII AutoUpdateViewBatch final
+{
+public:
+ explicit AutoUpdateViewBatch(EditorBase* aEditorBase
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : mEditorBase(aEditorBase)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ NS_ASSERTION(mEditorBase, "null mEditorBase pointer!");
+
+ if (mEditorBase) {
+ mEditorBase->BeginUpdateViewBatch();
+ }
+ }
+
+ ~AutoUpdateViewBatch()
+ {
+ if (mEditorBase) {
+ mEditorBase->EndUpdateViewBatch();
+ }
+ }
+
+protected:
+ EditorBase* mEditorBase;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+/******************************************************************************
+ * some helper classes for iterating the dom tree
+ *****************************************************************************/
+
+class BoolDomIterFunctor
+{
+public:
+ virtual bool operator()(nsINode* aNode) const = 0;
+};
+
+class MOZ_RAII DOMIterator
+{
+public:
+ explicit DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
+
+ explicit DOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+ virtual ~DOMIterator();
+
+ nsresult Init(nsRange& aRange);
+
+ void AppendList(
+ const BoolDomIterFunctor& functor,
+ nsTArray<mozilla::OwningNonNull<nsINode>>& arrayOfNodes) const;
+
+protected:
+ nsCOMPtr<nsIContentIterator> mIter;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class MOZ_RAII DOMSubtreeIterator final : public DOMIterator
+{
+public:
+ explicit DOMSubtreeIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
+ virtual ~DOMSubtreeIterator();
+
+ nsresult Init(nsRange& aRange);
+};
+
+class TrivialFunctor final : public BoolDomIterFunctor
+{
+public:
+ // Used to build list of all nodes iterator covers
+ virtual bool operator()(nsINode* aNode) const
+ {
+ return true;
+ }
+};
+
+/******************************************************************************
+ * general dom point utility struct
+ *****************************************************************************/
+struct MOZ_STACK_CLASS EditorDOMPoint final
+{
+ nsCOMPtr<nsINode> node;
+ int32_t offset;
+
+ EditorDOMPoint()
+ : node(nullptr)
+ , offset(-1)
+ {}
+ EditorDOMPoint(nsINode* aNode, int32_t aOffset)
+ : node(aNode)
+ , offset(aOffset)
+ {}
+ EditorDOMPoint(nsIDOMNode* aNode, int32_t aOffset)
+ : node(do_QueryInterface(aNode))
+ , offset(aOffset)
+ {}
+
+ void SetPoint(nsINode* aNode, int32_t aOffset)
+ {
+ node = aNode;
+ offset = aOffset;
+ }
+ void SetPoint(nsIDOMNode* aNode, int32_t aOffset)
+ {
+ node = do_QueryInterface(aNode);
+ offset = aOffset;
+ }
+};
+
+class EditorUtils final
+{
+public:
+ static bool IsDescendantOf(nsINode* aNode, nsINode* aParent,
+ int32_t* aOffset = 0);
+ static bool IsDescendantOf(nsIDOMNode* aNode, nsIDOMNode* aParent,
+ int32_t* aOffset = 0);
+ static bool IsLeafNode(nsIDOMNode* aNode);
+};
+
+class EditorHookUtils final
+{
+public:
+ static bool DoInsertionHook(nsIDOMDocument* aDoc, nsIDOMEvent* aEvent,
+ nsITransferable* aTrans);
+
+private:
+ static nsresult GetHookEnumeratorFromDocument(
+ nsIDOMDocument*aDoc,
+ nsISimpleEnumerator** aEnumerator);
+};
+
+} // namespace mozilla
+
+#endif // #ifndef mozilla_EditorUtils_h