`DeleteSelection*()` are members of `TextEditor`, but they are also used by
`HTMLEditor`. Therefore, they and pref cache members for them should be
in `EditorBase` too.
Depends on D71911
Differential Revision: https://phabricator.services.mozilla.com/D72290
This patch also names the former to `GetInclusiveAncestorBlockElement()` and
the latter to `GetAncestorBlockElement()` for consistency with modern DOM
API names.
Depends on D70882
Differential Revision: https://phabricator.services.mozilla.com/D70883
It's a virtual method which always returns true if `TextEditor`. Therefore,
we can move it into `HTMLEditUtils` and we can make the only caller of
`EditorBase` check `IsTextEditor()` instead.
Depends on D70880
Differential Revision: https://phabricator.services.mozilla.com/D70882
A lot of editor code refers `nsINode::IsText()` directly so that we don't
need to keep the too simple editor API anymore.
Depends on D70876
Differential Revision: https://phabricator.services.mozilla.com/D70877
--HG--
extra : moz-landing-system : lando
`HTMLEditor::IsBlockNode()` is a virtual method derived from
`EditorBase::IsBlockNode()`. For the performance, `EditorBase`'s one just
return false for text node and `<br>` element. However, these check cost
is really cheap in these days. Therefore, we can make `TextEditor` also
use rich API.
This patch moves `HTMLEditor::NodeIsBlockStatic()` and
`HTMLEditor::NodeIsInlineStatic()` to `HTMLEditUtils`, and removes the wrapper
of the fommer, `HTMLEditor::IsBlockNode()` and `WSRunScanner::IsBlockNode()`.
Differential Revision: https://phabricator.services.mozilla.com/D70874
--HG--
extra : moz-landing-system : lando
I'm still not sure how the crash occurs especially on Thunderbird. However,
it could be possible if `pointToInsert` is modified with an orphan node (i.e.,
when `pointToInsert.GetContainer()` returns `nullptr`). Therefore, this patch
makes it check whether the inserted node stays at expected position or not,
and if it's not, make it keep inserting next content nodes to previous position
because it must look like odd that inserting to different position.
Differential Revision: https://phabricator.services.mozilla.com/D69154
--HG--
extra : moz-landing-system : lando
This rejiggers a bit the way selection focus is handled so that focusing a
disabled form control with the mouse handles selection properly, and hides the
document selection and so on.
This matches the behavior of other browsers as far as I can tell.
Given now readonly and disabled editors behave the same, we can simplify a bit
the surrounding editor code.
Differential Revision: https://phabricator.services.mozilla.com/D66464
--HG--
extra : moz-landing-system : lando
This rejiggers a bit the way selection focus is handled so that focusing a
disabled form control with the mouse handles selection properly, and hides the
document selection and so on.
This matches the behavior of other browsers as far as I can tell.
Given now readonly and disabled editors behave the same, we can simplify a bit
the surrounding editor code.
Differential Revision: https://phabricator.services.mozilla.com/D66464
--HG--
extra : moz-landing-system : lando
The key here is to test the type of the variable declaration for being a
smartptr type, instead of testing the type of the variable _use_.
Differential Revision: https://phabricator.services.mozilla.com/D65581
--HG--
extra : moz-landing-system : lando
Some script run methods of `WSRunObject` guarantee the lifetime of its
`mHTMLEditor`. However, they should be guaranteed by the instantiators
(all of them are `HTMLEditor`).
Differential Revision: https://phabricator.services.mozilla.com/D64334
--HG--
extra : moz-landing-system : lando
Some methods of `EditorDOMPointBase` assumes the container node type is
`nsINode`. However, it's not good for reuse. Therefore, this patch makes
most methods of them be template methods.
Differential Revision: https://phabricator.services.mozilla.com/D64331
--HG--
extra : moz-landing-system : lando
When `WSScanResult::ReachedCurrentBlockBoundary()` returns true, reached content
of backward scan result is same as the scanner's `GetStartReasonContent()` and
reached content of forward scan result is same as the scanner's
`GetEndReasonContent()`. For making code in the blocks of
`if (foo.ReachedCurrentBlockBoundary())` easier to understand, we should use
the result's content.
Differential Revision: https://phabricator.services.mozilla.com/D63615
--HG--
extra : moz-landing-system : lando
They are really messy because they take a lot of out parameters, and these
out parameter meaning is really unclear. Therefore, they should return
a stack only class instance which explain the meaning with getter methods.
And also it should store the result node as `nsIContent`.
And also this patch adds static methods for them for their users which don't
need `WSRunScanner` instance.
Differential Revision: https://phabricator.services.mozilla.com/D63613
--HG--
extra : moz-landing-system : lando
Now, all setter guarantee that they are subclass instances of `nsIContent`.
Differential Revision: https://phabricator.services.mozilla.com/D63612
--HG--
extra : moz-landing-system : lando
This patch assumes that only element node can have content node. I.e., we
won't hit the following `MOZ_ASSERT`:
```
Element* element = nullptr;
nsIContent* content = aContent;
while (content) {
if (content->IsElement()) {
element = content->AsElement();
break;
}
content = content->GetParent();
}
MOZ_ASSERT(!content || content == element || content->GetParent() == element);
```
Differential Revision: https://phabricator.services.mozilla.com/D63308
--HG--
extra : moz-landing-system : lando
IsEmptyNode won't return error if parameter is not null. So we shouldn't use
nserror for return value and use assertion to check parameter.
Differential Revision: https://phabricator.services.mozilla.com/D63124
--HG--
extra : moz-landing-system : lando
Finally, this patch makes `HTMLEditor::DoInsertHTMLWithContext()` stop using
array of `nsINode`.
Differential Revision: https://phabricator.services.mozilla.com/D61984
--HG--
extra : moz-landing-system : lando
For guaranteeing the meaning of `aArrayOfListAndTableRelatedElements`,
`ReplaceOrphanedStructure()` should call
`CollectListAndTableRelatedElementsAt()` by itself rather than taking as
a parameter.
Then, what it does becomes a little bit clearer. Therefore, this patch renames
`ReplaceOrphanedStructure()` to `EnsureBeginsOrEndsWithValidContent()` and
`DiscoverPartialListsAndTables()` to `GetMostAncestorListOrTableElement()`,
and adds a lot of comments.
As far as I've tested by my hand, the behavior is not changed even though
it's really buggy in some cases. We should fix them after writing automated
tests in another bug.
Differential Revision: https://phabricator.services.mozilla.com/D61983
--HG--
extra : moz-landing-system : lando
For guaranteeing the meaning of list or `<table>` element in
`ReplaceOrphanedStructure()`, it should call `DiscoverPartialListsAndTables()`.
Then, their meaning becomes clearer than coming from its parameter.
Differential Revision: https://phabricator.services.mozilla.com/D61982
--HG--
extra : moz-landing-system : lando
In these patches, we know that there are a lot of helper methods to fix node
list which is created by `SubtreeContentIterator` and will be inserted into
the editor's DOM tree, and they are not used by other places. So, we can
encapsulate them into a stack only class for making their usage clearer.
Differential Revision: https://phabricator.services.mozilla.com/D61981
--HG--
extra : moz-landing-system : lando
Unfortunately, even with this cleaning up, I don't understand what it does
because existing comment and what actually it does seem different.
Differential Revision: https://phabricator.services.mozilla.com/D61980
--HG--
extra : moz-landing-system : lando
`HTMLEditor::DiscoverPartialListsAndTables()` can be static and we can make
its definition simpler. However, due to the odd logic, I'm still not sure
what it does. I'll update it after cleaning up its result user,
`HTMLEditor::ReplaceOrphanedStructure()`.
Differential Revision: https://phabricator.services.mozilla.com/D61979
--HG--
extra : moz-landing-system : lando
`HTMLEditor::CreateListOfNodesToPaste()` can be static and it does not need to
take `DocumentFragment` as an argument if the range is always specified.
For avoiding 2 input path to specify a range, we should make it take only
range boundaries and array of nodes to return the collected nodes.
Differential Revision: https://phabricator.services.mozilla.com/D61978
--HG--
extra : moz-landing-system : lando
It can be a static method and does not make sense taking array of nodes as
input argument because it refers only first or last node of the array.
Differential Revision: https://phabricator.services.mozilla.com/D61977
--HG--
extra : moz-landing-system : lando
The name does not explain what it does. Additionally, it should be same style
as `HTMLEditor::IsReplaceableListElement()` for making it easier to understand.
Differential Revision: https://phabricator.services.mozilla.com/D61976
--HG--
extra : moz-landing-system : lando
`HTMLEditor::ScanForListAndTableStructure()` is complicated because it has
2 modes, one is for handling list element, the other is for handling table
element. This patch splits them as 2 methods.
Differential Revision: https://phabricator.services.mozilla.com/D61975
--HG--
extra : moz-landing-system : lando
Helper methods of `HTMLEditor::DoInsertHTMLWithContext()` which uses array of
`nsINode` is really messy and we can make them simpler. This is first
preparation of a series of refactoring patches of them.
Differential Revision: https://phabricator.services.mozilla.com/D61974
--HG--
extra : moz-landing-system : lando
`TrivialFunctor` returns always true for `DOMIterator::AppendList()`. That
means that `DOMIterator` appends all nodes which are listed up by
`ContentIterator`. So, it's reasonable to make `DOMIterator` have
`AppendAllNodesToArray()` because it's more self-documented and faster.
Additionally, `BRNodeFunctor` always returns true when nodes with which
`HTMLBRElement::FromNode()` returns non-nullptr. So, we can make
`AppendAllNodesToArray()` a template class which just checks whether
every nodes are specific node type.
Differential Revision: https://phabricator.services.mozilla.com/D61968
--HG--
extra : moz-landing-system : lando
When file is dropped on `contenteditable` element, the data is `BlobImpl`
instance in e10s mode. Then, editor tries to insert asynchronously with its
`BlobReader`. However, currently, `BlobReader` does not have a reference of
`DataTransfer` object for setting `beforeinput` event and `input` event.
Therefore, when you drop file into `contenteditable` element on debug build,
you see hitting `MOZ_ASSERT` because of unexpected null `DataTransfer` object.
This patch makes it store `DataTransfer` object for both `beforeinput` event
and `input` event, and dispatch `beforeinput` event only when it hasn't been
dispatched yet (i.e., not dispatched before it's created). The case shouldn't
occur, but let's have the fallback path in release builds for avoiding
inconvenience of our users.
Differential Revision: https://phabricator.services.mozilla.com/D60238
--HG--
extra : moz-landing-system : lando
`AutoEditActionDataSetter` is created in the stack when editor's public method
is called and that guarantees lifetime of global objects in editor such as
editor itself, selection controller, etc.
The dispatcher of `beforeinput` event returns `NS_ERROR_EDITOR_ACTION_CANCELED`
if an event is actually dispatched but canceled. The reason why it's an error
is, editor code must stop handling anything when any methods return error.
So, returning an error code is reasonable in editor module. But when it's
filtered by `EditorBase::ToGenericNSResult()` at return statement of public
methods, it's converted to `NS_SUCCESS_DOM_NO_OPERATION`. This avoids throwing
new exception, but editor class users in C++ can distinguish whether each edit
action is canceled or handled. The reason why we should not throw new
exception from XPCOM API is, without taking care of each caller may break some
our UI (especially for avoiding to break comm-central). Therefore, this patch
does not make XPCOM methods return error code when `beforeinput` event is
canceled.
In most cases, immediately after creating `AutoEditActionDataSetter` is good
timing to dispatch `beforeinput` event since editor has not touched the DOM
yet. If `beforeinput` requires `data` or `dataTransfer`, methods need to
dispatch `beforeinput` event after that. Alhtough this is not a good thing
from point of view of consistency of the code. However, I have no better
idea.
Note 1: Our implementation does NOT conform to the spec about event order
between `keypress` and `beforeinput` (dispatching `beforeinput` event after
`keypress` event). However, we follow all other browsers' behavior so that it
must be safe and the spec should be updated for backward compatibility.
Spec issue: https://github.com/w3c/uievents/issues/220
Note 2: Our implementation does NOT conform to the spec about event order
between `compositionupdate` and `beforeinput`. Our behavior is same as
Safari, but different from Chrome. This might cause web-compat issues.
However, our behavior does make sense from point of view of consistency of
event spec. Additionally, at both `compositionupdate` and `beforeinput`,
composition string in editor has not been modified yet. Therefore, this
may not cause web-compat issues (and I hope so).
Spec issue: https://github.com/w3c/input-events/issues/49
Note that this patch makes editor detect bugs that `beforeinput` event hasn't
been handled yet when it dispatches `input` event or modifying `data` and
`dataTransfer` value are modified after dispatching `beforeinput` event with
`MOZ_ASSERT`s.
Differential Revision: https://phabricator.services.mozilla.com/D58127
--HG--
extra : moz-landing-system : lando
`AutoEditActionDataSetter` is created in the stack when editor's public method
is called and that guarantees lifetime of global objects in editor such as
editor itself, selection controller, etc.
The dispatcher of `beforeinput` event returns `NS_ERROR_EDITOR_ACTION_CANCELED`
if an event is actually dispatched but canceled. The reason why it's an error
is, editor code must stop handling anything when any methods return error.
So, returning an error code is reasonable in editor module. But when it's
filtered by `EditorBase::ToGenericNSResult()` at return statement of public
methods, it's converted to `NS_SUCCESS_DOM_NO_OPERATION`. This avoids throwing
new exception, but editor class users in C++ can distinguish whether each edit
action is canceled or handled. The reason why we should not throw new
exception from XPCOM API is, without taking care of each caller may break some
our UI (especially for avoiding to break comm-central). Therefore, this patch
does not make XPCOM methods return error code when `beforeinput` event is
canceled.
In most cases, immediately after creating `AutoEditActionDataSetter` is good
timing to dispatch `beforeinput` event since editor has not touched the DOM
yet. If `beforeinput` requires `data` or `dataTransfer`, methods need to
dispatch `beforeinput` event after that. Alhtough this is not a good thing
from point of view of consistency of the code. However, I have no better
idea.
Note 1: Our implementation does NOT conform to the spec about event order
between `keypress` and `beforeinput` (dispatching `beforeinput` event after
`keypress` event). However, we follow all other browsers' behavior so that it
must be safe and the spec should be updated for backward compatibility.
Spec issue: https://github.com/w3c/uievents/issues/220
Note 2: Our implementation does NOT conform to the spec about event order
between `compositionupdate` and `beforeinput`. Our behavior is same as
Safari, but different from Chrome. This might cause web-compat issues.
However, our behavior does make sense from point of view of consistency of
event spec. Additionally, at both `compositionupdate` and `beforeinput`,
composition string in editor has not been modified yet. Therefore, this
may not cause web-compat issues (and I hope so).
Spec issue: https://github.com/w3c/input-events/issues/49
Note that this patch makes editor detect bugs that `beforeinput` event hasn't
been handled yet when it dispatches `input` event or modifying `data` and
`dataTransfer` value are modified after dispatching `beforeinput` event with
`MOZ_ASSERT`s.
Differential Revision: https://phabricator.services.mozilla.com/D58127
--HG--
extra : moz-landing-system : lando
Chrome moves focus to dropped element or editing host containing dropped
element, but we don't do it. For compatibility with Chrome, it's better to
follow their behavior. Additionally, this fixes 2 issues. One is, when
dropping something into non-focused contenteditable element, we've failed to
initialize selection from `TextEditor::PrepareToInsertContent()` because
`pointToInsert` is outside of selection limiter if another editing host
has focus. The other is, when same case, we've failed to insert dropped
content because edit action handlers of `HTMLEditor` check whether editing
position is in active editing host.
Finally, this patch makes `TextEditor::OnDrop()` cancels to dispatch "input"
event if it fails something before trying to insert dropped content. Without
this change, `EditorBase::DispatchInputEvent()` tries to dispatch without
proper `data` or `dataTransfer` and that hits `MOZ_ASSERT` in `nsContentUtils`.
Additionally, this fixes an existing bug which `HTMLEditor` may insert `\r`
as-is if it comes from paste or drop. Otherwise, we need complicated `todo_is`
paths in `test_dragdrop.html`.
Differential Revision: https://phabricator.services.mozilla.com/D57447
--HG--
extra : moz-landing-system : lando
The inclusions were removed with the following very crude script and the
resulting breakage was fixed up by hand. The manual fixups did either
revert the changes done by the script, replace a generic header with a more
specific one or replace a header with a forward declaration.
find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do
interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2)
if [ -n "$interfaces" ]; then
if [[ "$interfaces" == *$'\n'* ]]; then
regexp="\("
for i in $interfaces; do regexp="$regexp$i\|"; done
regexp="${regexp%%\\\|}\)"
else
regexp="$interfaces"
fi
interface=$(basename "$path")
rg -l "#include.*${interface%%.idl}.h" . | while read path2; do
hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" )
if [ $hits -eq 0 ]; then
echo "Removing ${interface} from ${path2}"
grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp
mv -f "$path2".tmp "$path2"
fi
done
fi
done
Differential Revision: https://phabricator.services.mozilla.com/D55443
--HG--
extra : moz-landing-system : lando
With making it take `WidgetKeyboardEvent*`, it won't need to return "handled"
state. However, when we implement `beforeinput` event, it needs to return
"canceled" state. Therefore, it should return `EditActionResult`.
Differential Revision: https://phabricator.services.mozilla.com/D51953
--HG--
extra : moz-landing-system : lando
When inserting `<li>` elements into `<ul>`, `<ol>` or `<li>` element,
`HTMLEditor::DoInsertHTMLWithContext()` removes unnecessary empty `<li>`
elements at insertion point. At this time, we've computed next insertion
point with removed `<li>` element. Therefore, insertion point goes out
from the DOM tree. This patch makes it compute new insertion point before
removing each empty `<li>` element.
Additionally, this patch adds some WPT data for testing this case. I verified
that Chrome passes the new tests too.
Differential Revision: https://phabricator.services.mozilla.com/D49394
--HG--
extra : moz-landing-system : lando
Both method take a DOM point with `nsCOMPtr<nsINode>*` and `int32_t*`.
This makes each caller complicated. Instead, we should use stack only class
to return both `EditorDOMPoint` and `nsresult`. I name it `EditResult`.
Additionally, this fixes a bug of `HTMLeditor::SplitStyleAboveRange()`. That
is not tracking new selection start point while it splits elements at end
of given range. This is detected by the debug assertion in
`ToRawRangeBoundary()` (i.e., this fix is required to pass some tests).
Differential Revision: https://phabricator.services.mozilla.com/D47858
--HG--
extra : moz-landing-system : lando