Commit Graph
38 Commits
Author SHA1 Message Date
Leo Tenenbaum 6fd98b6963 Bug 2039944 - EditContext non-composed text insertion. r=masayuki,webidl,smaug
Differential Revision: https://phabricator.services.mozilla.com/D300797
2026-05-20 20:15:19 +00:00
agoloman 38b46ea44d Revert "Bug 2039944 - EditContext non-composed text insertion. r=masayuki,webidl,smaug" for causing build bustages @HTMLEditSubActionHandler.cpp.
This reverts commit bb35dbdb26.
2026-05-20 17:32:07 +00:00
Leo Tenenbaum bb35dbdb26 Bug 2039944 - EditContext non-composed text insertion. r=masayuki,webidl,smaug
Differential Revision: https://phabricator.services.mozilla.com/D300797
2026-05-20 17:03:15 +00:00
Sylvestre Ledru 9f5cc05eee Bug 2023419 - Remove Emacs/Vim modelines from editor/ r=masayuki
replaced by .editorconfig
# ignore-this-changeset

Differential Revision: https://phabricator.services.mozilla.com/D287844
2026-03-16 12:52:41 +00:00
Masayuki Nakano cb42ef186c Bug 1996500 - part 4: Make the other parts of HTMLEditor use the new APIs r=m_kato
This simplifies a lot position about inserting new padding line break
for the last empty line and each behavior is improved by the new API.

Differential Revision: https://phabricator.services.mozilla.com/D284965
2026-03-04 06:59:55 +00:00
Masayuki Nakano d670a975c9 Bug 1996500 - part 1: Make HTMLEditUtils have APIs for handling unnecessary line breaks r=m_kato
Perhaps, we should stop using "visible" from the API names because
some API users use the methods while modifying the DOM.  Therefore, the
new APIs explain the position of a line break or whether it's
significant or unnecessary from the layout point of view.

This patch adds API to check a line break position which may return
following/preceding block boundary's element and to scan following
block boundary with ignoring unnecessary line break which is done in
some places with calling
`WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary()` twice.

Additionally, making the extant internal API mainly `HTMLEditUtils`
use the new API to do the correct handling.

Note that this makes `HTMLEditUtils::GetLeafNodeType` return `Ignore`
if the caller does not want invisible things and the node is in
`display:none` element.  This change is required to keep passing some
tests whose editing host is `display:inline` and it's followed by
invisible text like `<script>`.

Differential Revision: https://phabricator.services.mozilla.com/D284962
2026-03-04 06:59:46 +00:00
Masayuki Nakano 005b916b08 Bug 2015203 - Make AutoInsertParagraphHandler::GetBetterPointToSplitParagraph use the right point for creating the EditorLineBreak r=m_kato
`WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary()` returns the
position **after** the preceding preformatted line break. Therefore,
it needs to use `offset - 1`, but it uses `offset` as-is. So, it should
use `CreateLineBreak<EditorLineBreak>()` instead.

Additionally, then, the position to split may be a middle of a `Text`.
Therefore, `WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesBefore()`
is not available for the preformatted line break unless it's at start
of a `Text`. Instead, it needs to use
`WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt()`.

Finally, `WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt()`
may delete some collapsed white-spaces before the preformatted line
break. Therefore, it needs to track `EditorLineBreak` with
`AutoTrackLineBreak`. (It forgets automatically flushing itself at
destruction. Therefore, this patch fixes it too.)

Differential Revision: https://phabricator.services.mozilla.com/D282358
2026-02-12 04:31:17 +00:00
Masayuki Nakano 91fa81075a Bug 1998077 - part 7: Reimplement HTMLEditUtils::GetInclusiveDeepestFirstChildWhichHasOneChild with LeafNodeOptions r=m_kato
Similarly, we can implement it with `LeafNodeOptions` to ignore
unnecessary nodes.  Then, we can get rid of `WalkTreeOption` and
`WalkTreeOptions` completely.

Differential Revision: https://phabricator.services.mozilla.com/D277524
2026-01-13 05:27:53 +00:00
Masayuki Nakano 80e02f4320 Bug 1998077 - part 6: Reimplement HTMLEditUtils::Get(First|Last)Child() and HTMLEditUtils::Get(Next|Previous)Sibling() with LeafNodeOptions r=m_kato
`WalkTreeOptions` is similar to `LeafNodeOptions` and it's hard to
maintain both of them.  Additionally, `LeafNodeOptions` can specify
which type of leaf nodes should be ignored at scanning.  Therefore,
`LeafNodeOptions` can be used for them.

Differential Revision: https://phabricator.services.mozilla.com/D277523
2026-01-13 05:27:50 +00:00
Masayuki Nakano b289a47a35 Bug 1998077 - part 5: Replace the remaining HTMLEditUtils::Get(Next|Previous)Content() with new ones based on Get(Next|Previous)LeafNodeOr(Next|Previous)BlockElement() r=m_kato
`HTMLEditUtils::GetNextContent()` and
`HTMLEditUtils::GetPreviousContent()` are wrappers of
`HTMLEditUtils::GetAdjacentContent()` and
`HTMLEditUtils::GetAdjacentLeafContent()`.  The behavior is similar to
`HTMLEditUtils::GetNextLeafContentOrNextBlockElement()` or
`HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement()` but
they won't stop at block inclusive ancestor or a block sibling of an
inclusive ancestor.  Therefore, we can get rid of them and use the new
and better implementation.

Differential Revision: https://phabricator.services.mozilla.com/D277522
2026-01-13 05:27:47 +00:00
Masayuki Nakano 1afcba4cc6 Bug 1998077 - part 3: Add new options to ignore empty/invisible leaf nodes r=m_kato
This adds some options which ignore some types of inline elements.

For example, `IgnoreAnyEmptyInlineContainers` is useful to scan previous
or next editable point because Chrome ignores empty inline elements when
deleting from next to an inline element.

`IgnoreInvisibleInlineVoidElements` is useful to scan invisible line
break from end of a block or checking a line break is invisible because
visible inline element makes a line after the last line break. E.g.,
```html
<div>ABC<br><span></span></div>
```
This shows only one line. However,
```html
<div>ABC<br><span style="border:1px solid"></span></div>
```
This shows 2 lines in the `<div>`.

Additionally, renaming the existing `LeafNodeType` values for making
them easier to understand.

Differential Revision: https://phabricator.services.mozilla.com/D277520
2026-01-13 05:27:41 +00:00
Masayuki Nakano d9e52c123e Bug 1998077 - part 2: Add WSType::EmptyInlineContainerElement r=m_kato
An empty inline container element such as `<span></span>` has 2
meanings, if it's visible with specified style, e.g., has non-zero
padding, it should be treated like a replaced element like `<img>`.
However, if it's invisible, it should be treated as `Comment` or
empty `Text`.  Therefore, the scanner users need a special handling for
them in some cases.  So, it should be identified with the new `WSType`.

Unfortunately, neither
`HTMLEditUtils::IsInclusiveAncestorCSSDisplayNone` nor
`HTMLEditUtils::IsVisibleElementEvenIfLeafNode` is testable within
GTest because it does not have layout information.

Differential Revision: https://phabricator.services.mozilla.com/D277519
2026-01-13 05:27:38 +00:00
Sandor Molnar b77ea8700f Revert "Bug 1998077 - part 7: Reimplement HTMLEditUtils::GetInclusiveDeepestFirstChildWhichHasOneChild with LeafNodeOptions r=m_kato" for causing build bustages @ WSRunScanner.cpp
This reverts commit 5ccf392dce.

Revert "Bug 1998077 - part 6: Reimplement `HTMLEditUtils::Get(First|Last)Child()` and `HTMLEditUtils::Get(Next|Previous)Sibling()` with `LeafNodeOptions` r=m_kato"

This reverts commit 12eb928cb5.

Revert "Bug 1998077 - part 5: Replace the remaining `HTMLEditUtils::Get(Next|Previous)Content()` with new ones based on `Get(Next|Previous)LeafNodeOr(Next|Previous)BlockElement()` r=m_kato"

This reverts commit 58b4243d10.

Revert "Bug 1998077 - part 4: Replace some callers of `HTMLEditUtils::Get(Next|Previous)Content()` with `HTMLEditUtils::Get(Next|Previous)LeafContentOr(Next|Previous)BlockElement()` r=m_kato"

This reverts commit dd46967eb4.

Revert "Bug 1998077 - part 3: Add new options to ignore empty/invisible leaf nodes r=m_kato"

This reverts commit ca50a4a628.

Revert "Bug 1998077 - part 2: Add `WSType::EmptyInlineContainerElement` r=m_kato"

This reverts commit 4a5d93d631.

Revert "Bug 1998077 - part 1: Make `HTMLEditUtils::IsVisibleElementEvenIfLeafNode` work better if primary frame is available r=m_kato"

This reverts commit b42dc9d35f.
2026-01-07 06:15:59 +00:00
Masayuki Nakano 5ccf392dce Bug 1998077 - part 7: Reimplement HTMLEditUtils::GetInclusiveDeepestFirstChildWhichHasOneChild with LeafNodeOptions r=m_kato
Similarly, we can implement it with `LeafNodeOptions` to ignore
unnecessary nodes.  Then, we can get rid of `WalkTreeOption` and
`WalkTreeOptions` completely.

Differential Revision: https://phabricator.services.mozilla.com/D277524
2026-01-07 01:12:57 +00:00
Masayuki Nakano 12eb928cb5 Bug 1998077 - part 6: Reimplement HTMLEditUtils::Get(First|Last)Child() and HTMLEditUtils::Get(Next|Previous)Sibling() with LeafNodeOptions r=m_kato
`WalkTreeOptions` is similar to `LeafNodeOptions` and it's hard to
maintain both of them.  Additionally, `LeafNodeOptions` can specify
which type of leaf nodes should be ignored at scanning.  Therefore,
`LeafNodeOptions` can be used for them.

Differential Revision: https://phabricator.services.mozilla.com/D277523
2026-01-07 01:12:54 +00:00
Masayuki Nakano 58b4243d10 Bug 1998077 - part 5: Replace the remaining HTMLEditUtils::Get(Next|Previous)Content() with new ones based on Get(Next|Previous)LeafNodeOr(Next|Previous)BlockElement() r=m_kato
`HTMLEditUtils::GetNextContent()` and
`HTMLEditUtils::GetPreviousContent()` are wrappers of
`HTMLEditUtils::GetAdjacentContent()` and
`HTMLEditUtils::GetAdjacentLeafContent()`.  The behavior is similar to
`HTMLEditUtils::GetNextLeafContentOrNextBlockElement()` or
`HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement()` but
they won't stop at block inclusive ancestor or a block sibling of an
inclusive ancestor.  Therefore, we can get rid of them and use the new
and better implementation.

Differential Revision: https://phabricator.services.mozilla.com/D277522
2026-01-07 01:12:52 +00:00
Masayuki Nakano ca50a4a628 Bug 1998077 - part 3: Add new options to ignore empty/invisible leaf nodes r=m_kato
This adds some options which ignore some types of inline elements.

For example, `IgnoreAnyEmptyInlineContainers` is useful to scan previous
or next editable point because Chrome ignores empty inline elements when
deleting from next to an inline element.

`IgnoreInvisibleInlineVoidElements` is useful to scan invisible line
break from end of a block or checking a line break is invisible because
visible inline element makes a line after the last line break. E.g.,
```html
<div>ABC<br><span></span></div>
```
This shows only one line. However,
```html
<div>ABC<br><span style="border:1px solid"></span></div>
```
This shows 2 lines in the `<div>`.

Additionally, renaming the existing `LeafNodeType` values for making
them easier to understand.

Differential Revision: https://phabricator.services.mozilla.com/D277520
2026-01-07 01:12:46 +00:00
Masayuki Nakano 4a5d93d631 Bug 1998077 - part 2: Add WSType::EmptyInlineContainerElement r=m_kato
An empty inline container element such as `<span></span>` has 2
meanings, if it's visible with specified style, e.g., has non-zero
padding, it should be treated like a replaced element like `<img>`.
However, if it's invisible, it should be treated as `Comment` or
empty `Text`.  Therefore, the scanner users need a special handling for
them in some cases.  So, it should be identified with the new `WSType`.

Unfortunately, neither
`HTMLEditUtils::IsInclusiveAncestorCSSDisplayNone` nor
`HTMLEditUtils::IsVisibleElementEvenIfLeafNode` is testable within
GTest because it does not have layout information.

Differential Revision: https://phabricator.services.mozilla.com/D277519
2026-01-07 01:12:43 +00:00
Masayuki Nakano bd3adf2837 Bug 2003973 - Make HTMLEditor check whether selection is in a replaced or a void element stricter r=m_kato
Currently, we do something special only for `<select>`, `<option>`
and `<optgroup>`.  However, we should treat replaced elements and
void elements more consistently.

This patch adds new `HTMLEditUtils` methods to check them easier and
stricter and get the root node of them because DOM API can make invalid
tree even in a void element.

Then, we should handle insertions before the replaced or the void
element if selection range is collapsed in it. However, deletion should
not be handled for that if the range is completely in such element.
Additionally, if range boundary is in such element, we should adjust
the range not to include such element since it's not fully selected
so that shouldn't be deleted nor replaced.  These rules are basically
compatible with Chrome.

Finally, if such element is completely hidden, such elements should be
deleted silently with deleting surrounding content if collapsed next to
one.  However, this does not work well with a `Backspace` key press even
after applying this patch.

Finally, some tests of `editing-around-select-element.tentative.html`
start failing.  The reason is, this patch makes the surrounding block
boundary of `<select>` with adjusting the selection range and that makes
`<select>` moved into another parent.  At this time, the `<select>`
gets `style="white-space: nowrap"`.  I'm not sure where did this but
not a critical failures.  Therefore, this patch contains this
regression.

Differential Revision: https://phabricator.services.mozilla.com/D275170
2025-12-12 07:08:20 +00:00
Masayuki Nakano 71a528f921 Bug 1998288 - Make HTMLWithContextInserter::InsertContents stop touching Selection r=m_kato
The method touches `Selection` in its `for` loops and that appear in
the reported profile in bug 1997834.  Therefore, it should stop touching
the `Selection`, and its only caller should update `Selection` instead.

Additionally, this rewrites entire the method to make it simpler and
not use variables in the wide scopes.  That makes it easier to
understand.  However, except in some edge cases, this does not change
the behavior.

Differential Revision: https://phabricator.services.mozilla.com/D271362
2025-11-15 00:30:29 +00:00
Masayuki Nakano 6983335537 Bug 1996501 - part 2: Make WSRunScanner take an EnumSet instead of a set of Scan and BlockInlineCheck r=m_kato
It's not required explicitly to specify
`BlockInlineCheck::UseComputedDisplayStyle` and
`BlockInlineCheck::UseComputedDisplayOutsideStyle` to `WSRunScanner`
too.  And it should take an `EnumSet` for making it easier to maintain
the class in the future.

Differential Revision: https://phabricator.services.mozilla.com/D270117
2025-10-31 05:05:10 +00:00
Masayuki Nakano 5c667a6c58 Bug 1752093 - Make HTMLEditUtils::Is*() take const nsIContent& as far as possible r=m_kato
In the historical reason, some of them still take `nsINode*`.  In these
days, converting from `nsINode` to `nsIContent` or `Element` is faster
than before and most callers already use `nsIContent`.  Therefore, we
should make them take `const nsIContent&`.

Only some methods, allowing callers use pointer makes them simpler.
Therefore, only some methods have overloads which take
`const nsIContent*` instead.

Differential Revision: https://phabricator.services.mozilla.com/D265525
2025-09-30 01:31:25 +00:00
Cristina Horotan 8bdbf9625e Revert "Bug 1752093 - Make HTMLEditUtils::Is*() take const nsIContent& as far as possible r=m_kato" for causing assertion in nsINode.h
This reverts commit d7a3d6e49b.
2025-09-26 06:41:47 +00:00
Masayuki Nakano d7a3d6e49b Bug 1752093 - Make HTMLEditUtils::Is*() take const nsIContent& as far as possible r=m_kato
In the historical reason, some of them still take `nsINode*`.  In these
days, converting from `nsINode` to `nsIContent` or `Element` is faster
than before and most callers already use `nsIContent`.  Therefore, we
should make them take `const nsIContent&`.

Only some methods, allowing callers use pointer makes them simpler.
Therefore, only some methods have overloads which take
`const nsIContent*` instead.

Differential Revision: https://phabricator.services.mozilla.com/D265525
2025-09-26 01:07:57 +00:00
Masayuki Nakano c9af7d0d54 Bug 1988909 - Refine HTMLEditUtils::GetAncestorElement and HTMLEditUtils::GetInclusiveAncestorElement with adding uint tests r=m_kato
These utility methods behave odd in some edge cases and they are not
tested.  Therefore, they should be tested with new unit tests and we
should fix the odd behaviors.

Differential Revision: https://phabricator.services.mozilla.com/D265186
2025-09-21 23:15:27 +00:00
Masayuki Nakano 68c35294f1 Bug 1979228 - Optimize MoveSiblingsTransaction for IMEContentObserver r=m_kato
`IMEContentObserver` has a cache to avoid to compute start offset of
inserted or removing text every time.  However, that works only when
the same mutation occurs of consecutive nodes.

`MoveSiblingsTransaction` uses `nsINode::InsertBefore()` directly to
connected nodes.  Therefore, from `IMEContentObserver` point of view,
multiple pairs of removing text and inserting text occur.  So,
`IMEContentObserver` cannot use its cache.

Therefore, `MoveSiblingsTransaction` should remove all nodes first.
Then, `IMEContentObserver` can use the cache for deleting text.
Finally, `MoveSiblingsTransaction` should insert all removed nodes to
the DOM.  Then, `IMEContentObserver` can use the cache for inserting
text.

Differential Revision: https://phabricator.services.mozilla.com/D259720
2025-08-12 08:25:39 +00:00
Masayuki Nakano 5e1360feca Bug 1979561 - part 5: Make HTMLEditor::HandleHTMLIndentAroundRanges use HTMLEditor::MoveSiblingsWithTransaction r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D259716
2025-08-08 23:42:44 +00:00
Masayuki Nakano 48f67c673f Bug 1899083 - part 6: Rewrite AutoInsertParagraphHandler::HandleInHeadingElement r=m_kato
This make `AutoInsertParagraphHandler::HandleInHeadingElement`:
* stop splitting the heading element if split at end
* use `SplitParagraphWithTransaction` if splitting the heading element

Then, this also cases the failures because not touching the invisible
`<br>` element in the heading element.  Failing with this reason does
not make sense because not touching the heading element saves the
footprint for undo transactions.  Therefore, this patch makes the tests
allow the `<br>`s to stay there.

Differential Revision: https://phabricator.services.mozilla.com/D257131
2025-07-22 06:36:28 +00:00
Masayuki Nakano 7b601baf2a Bug 1899083 - part 5: Make AutoInsertParagraphHandler::HandleInListItemElement stop splitting <dt>/<dd> if splitting at end r=m_kato
If the right `<dt>`/`<dd>` is empty, the method replaces it with
opposite type element without copying the style.  So, we can consider
whether we can just insert an opposite list item before splitting the
given list item.

Note that new failures were passed by a bug of current code.  That is,
the method treats invisible `<br>` as visible.  So, the cases cause
different result whether there is an invisible `<br>` at end of the
list item even though it does not cause different look for the users.

Inserting opposite type of list item is a Gecko specific behavior.
I think we should stop doing that in Firefox for the compatibility with
the other browsers in a follow up bug.

Differential Revision: https://phabricator.services.mozilla.com/D257130
2025-07-22 06:36:25 +00:00
Masayuki Nakano 420068615f Bug 1899083 - part 4: Make AutoInsertParagraphHandler::HandleInListItemElement use AutoInsertParagraphHandler::SplitParagraphWithTransaction r=m_kato
`SplitParagraphWithTransaction()` does a lot of additional works to
split a paragraph.  This should be done when `insertParagraph` is
performed in an list item.

Then, we can drop the following code in `HandleInListItemElement()`:
* Inserting a padding `<br>` into empty left list item
* Copying styles at end of the left `<li>` to the right empty one
* Considering the caret position with scanning the right list item

Differential Revision: https://phabricator.services.mozilla.com/D257129
2025-07-22 06:21:08 +00:00
Masayuki Nakano 81bea21d35 Bug 1899083 - part 3: Rewrite handling insertParagraph handler when Selection is in a normal paragraph r=m_kato
Unfortunately, I don't have any ideas to separate this change because
the current behavior is broken, it assumes only simple cases.  However,
with rewriting the code simpler, we'll get the unexpected passes.
Therefore, this patch has a big change.

The strategy of the new behavior is, first, put a padding `<br>` to next
to the split point if and only if it's immediately before a block
boundary and delete unnecessary existing invisible `<br>` element if
it puts a new `<br>`.  Next, put a `<br>` to end of the left paragraph
if and only if the paragraph ends with a block boundary or a line break
or the split occurred at end of the deepest inline element.

Differential Revision: https://phabricator.services.mozilla.com/D257128
2025-07-22 05:30:36 +00:00
Masayuki Nakano fba329f07e Bug 1899083 - part 2: Make AutoInsertParagraphHandler::GetBetterSplitPointToAvoidToContinueLink work better r=m_kato
The method does not check invisible white-spaces nor `Comment` nodes.
Therefore, it may work differently from the user's point of view in
some edge cases.

Additionally, for making the following patch simpler and safer, the
split point should be outside a non-splittable element like `<img>`.

Differential Revision: https://phabricator.services.mozilla.com/D257127
2025-07-22 05:16:16 +00:00
Masayuki Nakano 9495e7aaac Bug 1899083 - part 1: Make the legacy insertParagraph handling cases outside HandleInParagraph r=m_kato
In the IE/Netscape era, we inserted a <br> in specific cases even if
`insertParagraph` command is being handled.  Although this patch makes
the legacy mode slower because of increasing the number of `<br>`
element scanning, we should split it off to make `HandleInParagraph`
simpler to optimize its logic later.

Differential Revision: https://phabricator.services.mozilla.com/D257126
2025-07-22 02:41:33 +00:00
Masayuki Nakano 37de891c4b Bug 1974913 - part 4: Make AutoInsertParagraphHandler and AutoInsertLineBreakHandler use shared helper methods to make the handler body smaller r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D255727
2025-07-08 01:31:32 +00:00
Masayuki Nakano 0252cf686b Bug 1974913 - part 3: Make AutoInsertParagraphHandler store HTMLEditor, editing host and default paragraph type r=m_kato
Currently, `AutoInsertParagraphHandler` is created only by
`HTMLEditor::InsertParagraphSeparatorAsSubAction()` and its
`aEditingHost` is always computed with `LimitInBody::No` [1][2].

Therefore, we can get rid of the re-computation of the editing host in
`AutoInsertParagraphHandler::Run()` and can make its constructor cache
the given editing host.

1. https://searchfox.org/mozilla-central/rev/adc939fe81358079709e3cf985d928863a19e272/editor/libeditor/HTMLEditor.cpp#1552-1553,1559
2. https://searchfox.org/mozilla-central/rev/adc939fe81358079709e3cf985d928863a19e272/editor/libeditor/HTMLEditor.cpp#1600-1601,1607

Differential Revision: https://phabricator.services.mozilla.com/D255726
2025-07-08 01:31:29 +00:00
Masayuki Nakano 79398eadbb Bug 1974913 - part 2: Spin the lambdas in AutoInsertParagraphHandler off as methods of the class r=m_kato
The lambdas were intended for avoiding to increase helper methods of
only a few specific `HTMLEditor` methods.  However, now, the methods are
grouped into `AutoInsertParagraphHandler`.  Therefore, we can make the
lambdas as its private methods.

Differential Revision: https://phabricator.services.mozilla.com/D255725
2025-07-08 01:31:26 +00:00
Masayuki Nakano 3fd9c0773b Bug 1974913 - part 1: Make insertParagraph and insertLineBreak handlers be stack only classes r=m_kato
For allowing to create helper methods and share more data between
helper methods without adding a lot of arguments to each method,
they should be stack only class.

Differential Revision: https://phabricator.services.mozilla.com/D255724
2025-07-08 01:31:23 +00:00
Masayuki Nakano 4422352e4d Bug 1974913 - part 0: Copy HTMLEditSubActionHandler.cpp first r=m_kato
Git does not track file copies but Git may keep the per line history if
they detect a file copy.  So, this might help to Git the per line
history of insert paragraph command handler and insert line break
command handler.

Differential Revision: https://phabricator.services.mozilla.com/D255723
2025-07-08 01:31:20 +00:00