summaryrefslogtreecommitdiffstats
path: root/editor/docs/EditorModuleStructure.rst
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--editor/docs/EditorModuleStructure.rst219
1 files changed, 219 insertions, 0 deletions
diff --git a/editor/docs/EditorModuleStructure.rst b/editor/docs/EditorModuleStructure.rst
new file mode 100644
index 0000000000..e179145a0d
--- /dev/null
+++ b/editor/docs/EditorModuleStructure.rst
@@ -0,0 +1,219 @@
+#######################
+Editor module structure
+#######################
+
+This document explains the structure of the editor module and overview of classes.
+
+Introduction
+============
+
+This module implements the builtin editors of editable elements or documents, and this does **not**
+implement the interface with DOM API and visual feedback of the editing UI. In other words, this
+module implements DOM tree editors.
+
+Directories
+===========
+
+composer
+--------
+
+Previously, this directory contained "Composer" UI related code. However, currently, this
+directory contains ``nsEditingSession`` and ``ComposerCommandsUpdater``.
+
+libeditor
+---------
+
+This is the main directory which contains "core" implementation of editors.
+
+spellchecker
+------------
+
+Despite of the directory name, implementation of the spellchecker is **not** here. This directory
+contains only a bridge between editor classes and the spellchecker and serialized text of editable
+content for spellchecking.
+
+txmgr
+-----
+
+This directory contains transaction items and transaction classes. They were designed for generic
+use cases, e.g., managing undo/redo of bookmarks/history of browser, etc, but they are used only by
+the editor.
+
+Main classes
+============
+
+EditorBase
+----------
+
+``EditorBase`` class is an abstract class of editors. This inherits ``nsIEditor`` XPCOM interface,
+implement common features which work with instance of classes, and exposed by
+``mozilla/EditorBase.h``.
+
+TextEditor
+----------
+
+``TextEditor`` class is the implementation of plaintext editor which works with ``<input>`` and
+``<textarea>``. Its exposed root is the host HTML elements, however, the editable root is an
+anonymous ``<div>`` created in a native anonymous subtree under the exposed root elements. This
+creates a ``Text`` node as the first child of the anonymous ``<div>`` and modify its data. If the text
+data ends with a line-break, i.e., the last line is empty, append a ``<br>`` element for making the
+empty last line visible.
+
+This also implements password editor. It works almost same as normal text editor, but each character
+may be masked by masked character such as "●" or "*" by the layout module for the privacy.
+Therefore, this manages masked/unmasked range of password and maybe making typed character
+automatically after a while for mobile devices.
+
+This is exposed with ``mozilla/TextEditor.h``.
+
+Selection in TextEditor
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Independent ``Selection`` and ``nsFrameSelection`` per ``<input>`` or ``<textarea>``.
+
+Lifetime of TextEditor
+^^^^^^^^^^^^^^^^^^^^^^
+
+Created when an editable ``<textarea>`` is created or a text-editable ``<input>`` element gets focus.
+Note that the initialization may run asynchronously if it's requested when it's not safe to run
+script. Destroyed when the element becomes invisible. Note that ``TextEditor`` is recreated when
+every reframe of the host element. This means that when the size of ``<input>`` or ``<textarea>``
+is changed for example, ``TextEditor`` is recreated and forget undo/redo transactions, but takes
+over the value, selection ranges and composition of IME from the previous instance.
+
+HTMLEditor
+----------
+
+``HTMLEditor`` class is the implementation of rich text editor which works with ``contenteditable``,
+``Document.designMode`` and XUL ``<editor>``. Its instance is created per document even if the
+document has multiple elements having ``contenteditable`` attribute. Therefore, undo/redo
+transactions are shared in all editable regions.
+
+This is exposed with ``mozilla/HTMLEditor.h``.
+
+Selection in HTMLEditor
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The instance for the ``Document`` and ``Window``. When an editable element gets focus, ``HTMLEditor``
+sets the ancestor limit of ``Selection`` to the focused element or the ``<body>`` of the ``Document``.
+Then, ``Selection`` cannot cross boundary of the limiter element.
+
+Lifetime of HTMLEditor
+^^^^^^^^^^^^^^^^^^^^^^
+
+Created when first editable region is created in the ``Document``. Destroyed when last editable
+region becomes non-editable.
+
+Currently, even while ``HTMLEditor`` is handling an edit command/operation (called edit action in
+editor classes), each DOM mutation can be tracked with legacy DOM mutation events synchronously.
+Thus, after changing the DOM tree from ``HTMLEditor``, any state could occur, e.g., the editor
+itself may have been destroyed, the DOM tree have been modified, the ``Selection`` have been
+modified, etc. This issue is tracked in
+`bug 1710784 <https://bugzilla.mozilla.org/show_bug.cgi?id=1710784>`__.
+
+
+EditorUtils
+-----------
+
+This class has only static utility methods which are used by ``EditorBase`` or ``TextEditor`` and
+may be used by ``HTMLEditor`` too. I.e., the utility methods which are used **not** only by
+``HTMLEditor`` should be implemented in this class.
+
+Typically, sateless methods should be implemented as ``static`` methods of utility classes because
+editor classes have too many methods and fields.
+
+This class is not exposed.
+
+HTMLEditUtils
+-------------
+
+This class has only static utility methods which are used only by ``HTMLEditor``.
+
+This class is not exposed.
+
+AutoRangeArray
+--------------
+
+This class is a stack only class and intended to copy of normal selection ranges. In the new code,
+`Selection` shouldn't be referred directly, instead, methods should take reference to this instance
+and modify it. Finally, root caller should apply the ranges to `Selection`. Then, `HTMLEditor`
+does not need to take care of unexpected `Selection` updates by legacy DOM mutation event listeners.
+
+This class is not exposed.
+
+EditorDOMPoint, EditorRawDOMPoint, EditorDOMPointInText, EditorRawDOMPointInText
+--------------------------------------------------------------------------------
+
+It represents a point in a DOM tree with one of the following:
+
+* Container node and offset in it
+* Container node and child node in it
+* Container node and both offset and child node in it
+
+In most cases, instances are initialized with a container and only offset or child node. Then,
+when ``Offset()`` or ``GetChild()`` is called, the last one is "fixed". After inserting new child
+node before the offset and/or the child node, ``IsSetAndValid()`` will return ``false`` since the
+child node is not the child at the offset.
+
+If you want to keep using after modifying the DOM tree, you can make the instance forget offset or
+child node with ``AutoEditorDOMPointChildInvalidator`` and ``AutoEditorDOMRangeChildrenInvalidator``.
+The reason why the forgetting methods are not simply exposed is, ``Offset()`` and ``GetChild()``
+are available even after the DOM tree is modified to get the cached offset and child node,
+additionally, which method may modify the DOM tree may be not clear for developers. Therefore,
+creating a block only for these helper classes makes the updating point clearer.
+
+These classes are exposed with ``mozilla/EditorDOMPoint.h``.
+
+EditorDOMRange, EditorRawDOMRange, EditorDOMRangeInTexts, EditorRawDOMRangeInTexts
+----------------------------------------------------------------------------------
+
+It represents 2 points in a DOM tree with 2 ``Editor*DOMPoint(InText)``. Different from ``nsRange``,
+the instances do not track the DOM tree changes. Therefore, the initialization is much faster than
+``nsRange`` and can be in the stack.
+
+These classes are exposed with ``mozilla/EditorDOMPoint.h``.
+
+AutoTrackDOMPoint, AutoTrackDOMRange
+------------------------------------
+
+These methods updates ``Editor*DOMPoint(InText)`` or ``Editor*DOMRange(InTexts)`` at destruction
+with applying the changes caused by the editor instance. In other words, they don't track the DOM
+tree changes by the web apps like changes from legacy DOM mutation event listeners.
+
+These classes are currently exposed with ``mozilla/SelectionState.h``, but we should stop exposing
+them.
+
+WSRunScanner
+------------
+
+A helper class of ``HTMLEditor``. This class scans previous or (inclusive) next visible thing from
+a DOM point or a DOM node. This is typically useful for considering whether a `<br>` is visible or
+invisible due to near a block element boundary, finding nearest editable character from caret
+position, etc. However, the running cost is **not** cheap, thus if you find another way to consider
+it simpler, use it instead, and also this does not check the actual style of the nodes (visible vs.
+invisible, block vs. inline), thus you'd get unexpected result in tricky cases.
+
+This class is not exposed.
+
+WhiteSpaceVisibilityKeeper
+--------------------------
+
+A helper class of ``HTMLEditor`` to handle collapsible white-spaces as what user expected. This
+class currently handles white-space normalization (e.g., when user inputs multiple collapsible
+white-spaces, this replaces some of them to NBSPs), but the behavior is different from the other
+browsers. We should re-implement this with emulating the other browsers' behavior as far as possible,
+but currently it's put off due to not affecting UX (tracked in
+`bug 1658699 <https://bugzilla.mozilla.org/show_bug.cgi?id=1658699>`__.
+
+This class is not exposed.
+
+\*Transaction
+-------------
+
+``*Transaction`` classes represents a small transaction of updating the DOM tree and implements
+"do", "undo" and "redo" of the update.
+
+Note that each class instance is created too many (one edit action may cause multiple transactions).
+Therefore, each instance must be smaller as far as possible, and if you have an idea to collapse
+multiple instances to one instance, you should fix it. Then, users can run Firefox with smaller
+memory devices especially if the transaction is used in ``TextEditor``.