`ElementDeletionObserver` is managed by the irregular approach. It's
grabbed as a mutation observer of the anonymous node and its parent
element and **itself** with the caller of the constructor adding the
refcount and releasing itself when the observing elements are destroyed
or the parent chain is changed, i.e., when the instance becomes
unnecessary. Therefore, it's hard to check the safety with the static
analysis. Therefore, this patch makes the caller of the constructor
delegates the management of the lifetime to the instance explicitly.
Differential Revision: https://phabricator.services.mozilla.com/D290788
To distinguish whether a DOM modification is expected one or not, we
need to know what the editor is doing and what is expected result by
the mutation.
This patch adds some wrapper classes of DOM API calls and make all
callers of them except the target is very new node which has not been
connected to any DOM.
Differential Revision: https://phabricator.services.mozilla.com/D260587
This reverts commit 73d1ab198c.
Revert "Bug 1973655 - part 2: Make `HTMLEditorMutationObserver.cpp` r=m_kato"
This reverts commit 8603a23c33.
Revert "Bug 1973655 - part 1: Make the editor module not call DOM API to modify the DOM directly r=m_kato"
This reverts commit a8abe8d84c.
To distinguish whether a DOM modification is expected one or not, we
need to know what the editor is doing and what is expected result by
the mutation.
This patch adds some wrapper classes of DOM API calls and make all
callers of them except the target is very new node which has not been
connected to any DOM.
Differential Revision: https://phabricator.services.mozilla.com/D260587
Move the relevant bits to html.css or other UA sheets, and use faster
things than attribute selectors (read: classes) for resizers and such
things.
The hidden class can just be a hidden attribute since we don't otherwise
style these.
The cursor can just be set at the resizer / grabber creation time.
One known behavior change other than this is not styling using the
_moz_abspos attribute. The reasoning for this is that these are content
nodes, and in general having these kinds of rules for content nodes
isn't great. E.g. these two pages behave differently:
* data:text/html,<div _moz_abspos=black>boo</div>
* data:text/html,<div _moz_abspos=black>boo</div><div contenteditable></div>
We could use the style attribute for this, I suppose, just like we set
the position or what not, but then we need to save / restore as needed
or something. I'd rather not change the stacking order or backgrounds or
what not, too.
If you feel very strongly about that piece of functionality of the
abspos editor I could try to restore it somehow. But I honestly rather
not.
The rest of the stuff should just work.
Differential Revision: https://phabricator.services.mozilla.com/D235319
Reuse the editor's manual NAC machinery for now, and hook it into
StyleChildrenIterator and co.
We might need to slightly tweak the setup for selector-matching, not
sure yet, but that should be fine.
Differential Revision: https://phabricator.services.mozilla.com/D228255
Reuse the editor's manual NAC machinery for now, and hook it into
StyleChildrenIterator and co.
We might need to slightly tweak the setup for selector-matching, not
sure yet, but that should be fine.
Differential Revision: https://phabricator.services.mozilla.com/D228255
Reuse the editor's manual NAC machinery for now, and hook it into
StyleChildrenIterator and co.
We might need to slightly tweak the setup for selector-matching, not
sure yet, but that should be fine.
Differential Revision: https://phabricator.services.mozilla.com/D228255
Selection ranges can cross editing host boundaries if no editing host has focus.
Therefore, `Selection.focusNode` may be in an editing host but there may be
no active/focused editing host.
The computation may be expensive if there are a lot of ranges and selecting
in slotted shadow tree. However, it's rare case, so, I think it's okay for
now.
Differential Revision: https://phabricator.services.mozilla.com/D224282
In the fallback code for native key bindings and in the inline table handling,
the editor still use `GetDOMEventTarget()` and `IsInUncomposedDoc()` which are
not aware of shadow DOM.
Differential Revision: https://phabricator.services.mozilla.com/D193621
We have more readable and faster versions (that just omit the namespace
arg).
Mostly done via sed, with a couple helpers to use the faster lookups
where possible.
Differential Revision: https://phabricator.services.mozilla.com/D181795
Deletion of mutation observers from a list resulted in O(n^2) behavior and could lead to massive freezes.
This is resolved by using a LinkedList instead, reducing complexity to O(n).
A safely iterable doubly linked list was implemented based on `mozilla::DoublyLinkedList`,
allowing to insert and remove elements while iterating the list.
Due to the nature of `mozilla::DoublyLinkedList`, every Mutation Observer now inherits `mozilla::DoublyLinkedListElement<T>`.
This implies that a Mutation Observer can only be part of one DoublyLinkedList.
This conflicts with some Mutation Observers, which are being added to multiple `nsINode`s.
To continue supporting this, new MutationObserver base classes `nsMultiMutationObserver` and `nsStubMultiMutationObserver` are introduced,
which create `MutationObserverWrapper` objects each time they are added to a `nsINode`.
The wrapper objects forward every call to the actual observer.
Differential Revision: https://phabricator.services.mozilla.com/D157031
It's currently computes the corresponding editing host from the focus node of
`Selection` with climbing up the DOM tree. So, it does not just return a stored
element. Therefore, some callers use it multiple times. For avoiding it, we
should rename it to explain that it computes the editing host.
Note that I think that we should make it takes a node to compute editing host
without `Selection` for solving the case of no selection ranges. Therefore,
I don't like to include more information into the name.
Differential Revision: https://phabricator.services.mozilla.com/D147504
This lifts a bunch of string conversions higher up the stack, but allows
us to make the servo code use utf-8 unconditionally, and seemed faster
in my benchmarking (see comment 0).
It should also make a bunch of attribute setters faster too (like
setting .cssText), now that we use UTF8String for them (we couldn't
because we couldn't specify different string types for the getter and
setters).
Differential Revision: https://phabricator.services.mozilla.com/D99590
Although we use CSS property for Inline table editing UI, we use edit
transaction for it unfortunately. When hiding this UI, since removing
element doesn't use edit transaction, transaction will be canceled before
showing this UI.
It is unnecessary to use edit transaction for UI, so we shouldn't use it.
Differential Revision: https://phabricator.services.mozilla.com/D90056
We were dealing with it correctly when switching display from e.g. block
to inline, or such. But we were not dealing with it when the node was
undisplayed.
Handle it properly, and free one frame bit while at it. We can't really
do this for ManualNAC (the editor resizers) because they request a
reframe explicitly.
Differential Revision: https://phabricator.services.mozilla.com/D76679
In favor of the NativeAnonymous versions which they forward to.
Done automatically with:
rg -l 'IsInAnonymousSubtree' | xargs sed -i 's/IsInAnonymousSubtree/IsInNativeAnonymousSubtree/g'
And removing the function definitions afterwards.
Differential Revision: https://phabricator.services.mozilla.com/D76681
Due to the include hell, `EditorBase.h` cannot include `EditorUtils.h`.
Therefore we need these 3 methods once. Additionally, `IsModifiableNode()`
is really odd method and looks like that it's used for the following 2 purposes:
1. Simply can be editable.
2. Can be removed from parent.
For the former case, we should sort out it with
`EditorUtils::IsEditableContent()`, but for now, this patch moves it to
`HTMLEditUtils::IsSimplyEditable()`. On the other hand, for the latter case,
we obviously has a bug. Therefore, this patch creates
`HTMLEditUtils::IsRemovableFromParentNode()` and make it check whether the
removing node is also editable.
Unfortunately, `EditorUtils::IsEditableContent()` needs to take editor type.
But it's most callers are in `HTMLEditor` and most of remains are in
common methods of `EditorBase`. I guess we could remove this ugly argument
in the future.
Depends on D70874
Differential Revision: https://phabricator.services.mozilla.com/D70875
We can relax about `GetElementOrParentElement*()` because they just return
`nullptr` when selection anchor is a `Document` node.
Additionally, this patch renames the internal APIs to the names similar to
modern DOM API.
Finally, this adds automated test for
`nsIHTMLEditor.getElementOrParentByTagName()`.
Differential Revision: https://phabricator.services.mozilla.com/D70152
When it refers computed value of style, it may flush pending notifications.
Therefore, they should be marked as `MOZ_CAN_RUN_SCRIPT`.
Differential Revision: https://phabricator.services.mozilla.com/D70151
When it refers computed value of style, it may flush pending notifications.
Therefore, they should be marked as `MOZ_CAN_RUN_SCRIPT`.
Differential Revision: https://phabricator.services.mozilla.com/D70151
In particular, the ones where we transcode unconditionally atm (property names
and such).
There are others like cssText getters and setters which are a bit harder,
because I either need to rewrite all our serialization code to work with UTF8
(which is fine, but a lot of work), or teach webidl to have a setter that takes
UTF8String as input but returns DOMString as output (which is at best hacky).
Differential Revision: https://phabricator.services.mozilla.com/D58631
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
BindContext was going to have way more information at first, but then I realized
that most of the things I wanted to know were basically a flag away using the
parent node.
Still I think it's worth it, now experimenting with BindToTree will only mean
adding a field to a struct that's included from a couple cpp files, instead of a
massive pain.
I also think this is clearer, and doing this highlights quite a few
inconsistencies in our code which I've left untouched, but commented with
FIXMEs.
Steps are:
$ for file in $(rg 'nsresult BindToTree\(' | cut -d : -f 1 | sort | uniq); do sed -i 's#nsresult BindToTree(Document\* aDocument, nsIContent\* aParent,#nsresult BindToTree(BindContext\&, nsINode\& aParent)#g' $file; done
$ for file in $(rg 'nsresult BindToTree\(' | cut -d : -f 1 | sort | uniq); do sed -i 's# nsIContent\* aBindingParent) override#override#g' $file; done
$ for file in $(rg '::BindToTree\(' | cut -d : -f 1 | sort | uniq); do sed -i 's#::BindToTree(Document\* aDocument, nsIContent\* aParent,#::BindToTree(BindContext\& aContext, nsINode\& aParent)#g' $file; done
$ for file in $(rg '::BindToTree\(' | cut -d : -f 1 | sort | uniq); do sed -i 's#nsIContent\* aBindingParent)##g' $file; done
$ for file in $(rg '::BindToTree\(' | cut -d : -f 1 | sort | uniq); do sed -i 's#::BindToTree(aDocument, aParent, aBindingParent)#::BindToTree(aContext, aParent)#g' $file; done
$ ./mach clang-format
Then manual fixups.
Depends on D32948
Differential Revision: https://phabricator.services.mozilla.com/D32949