Closed Bug 1647556 Opened 6 years ago Closed 6 years ago

Make `WSRunScanner` and `WSRunObject` stop using array of `WSFragment`

Categories

(Core :: DOM: Editor, task, P2)

task

Tracking

()

RESOLVED FIXED
mozilla80
Tracking Status
firefox80 --- fixed

People

(Reporter: masayuki, Assigned: masayuki)

References

Details

(Whiteboard: [h2review-noted])

Attachments

(27 files)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review

WSFragment looks like that it abstractly explains its range's meaning and its array can explain any cases. However, it's created only for specific cases which WSRunScanner and WSRunObject want to do something and have incomplete data but enough for what they do something. This is a big reason why nobody cannot explain what WSRunObject is doing. So, there should be a new class instead of WSFragment and which explain what currently array of WSFragment explain with more self-documented methods.

The patches too many, but I've not achieved what I planned. Therefore, I'd like to split this patch only for making WSRunScanner and WSRunObject stop using WSFragment array.

Summary: Redesign `WSFragment` → Make `WSRunScanner` and `WSRunObject` stop using array of `WSFragment`

This adds some WPTs for testing how to treat invisible leading and/or trailing
white-spaces in block elements. I think that they should be removed as far
as possible because they may become visible suddenly if browsers fail to handle
them with their bugs. However, it's acceptable if the result keeps white-
spaces as invisible. Therefore, this makes some new tests allow multiple
results.

For making easier to understand the contents of WSRunScanner::mFragments,
we should stop using InitializeWithSingleFragment() for now because it's
designed for doing same things a lot, but used only by 2 users and they set
different parameters so that it does not do same things for the callers.

Depends on D82268

This patch just creates new stack only class and make it initializes
WSRunScanner::mFragments instead of WSRunScanner.

Depends on D82269

One of the WSFragmentusers' purpose is, they remove invisible white-spaces
when there are. So, TextFragmentData should have API to retrieve the
ranges and use them for initializing WSFragment which represents leading
or trailing white-spaces. For making this patch smaller as far as possible,
these APIs implements only the case when there is no NBSP.

For result of the new API, this creates a template class, EditorDOMRangeBase,
whose boundary type is EditorDOMPointBase. Its methods are named from
nsRange's same methods.

Depends on D82270

Different from GetInvisibleTrailingWhiteSpaceRange(), it always returns
the range even if it's collapsed (i.e., there is no leading white-space).

Depends on D82273

Scrub() does remove leading white-spaces and trailing white-spaces if
there is. So, it does not require WSFragment anymore.

Depends on D82274

Most methods handling something with WSFragment work only with instances
whose IsVisibleAndMiddleOfHardLine() return true, and currently, such
instance exists only one at most in the array. Therefore, they just want
an API to get such fragment.

Depends on D82275

This patch implements the case that when the range is not start of hard line.

Depends on D82276

It scans all WSFragments in the array and call NormalizeWhiteSpacesAtEndOf()
only with visible instance. However, as we know, there is at most one such
instance. Therefore, it does not need to scan the fragments (i.e., don't need
to create all fragments).

Depends on D82278

They return a point in an WSFragment whose IsVisibleAndMiddleOfLine()
returns true or start/end of the range. Therefore, they can ignore the
other WSFragments and save comparing points to at most twice.

Depends on D82279

It looks for same WSFragment twice with comparing text and what it looks for
is the instance whose IsVisibleAndMiddleOfLine() returns true.
Additionally, doing twice is for checking only whether the split point is
start or end of the range. Therefore, we can make it simpler with using
TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine().

Depends on D82280

It removes some invisible leading and/or trailing white-spaces when it inserts
<br> element into the invisible white-space sequence. It currently checks
whether the insertion point is in invisible leading and trailing white-spaces
or not with FindNearestFragment(), but we can do same thing with
comparing the insertion point with the result of
TextFragmentData::GetInvisibleLeadingWhiteSpaceRange() and
TextFragmentData::GetInvisibleLeadingWhiteSpaceRange(). However, current
implementation does not make sense because:

  • It checks trailing white-spaces with !IsEndOfHardLine() and
    IsStartOfHardLine(), but this means that it does ignores invisible
    white-spaces which are the only content in a line.
  • It checks leading white-spaces with !IsStartOfHardLine() and
    IsEndOfHardLine(), so, this also ignores invisible white-spaces which
    are the only content in a line.
  • The important thing of the logic is prevent that invisible leading and
    trailing white-spaces become visible with new <br> element, but this
    is done only for trailing white-spaces.

Depends on D82282

Similar to WSRunObject::InsertBreak(), WSRunObject::InsertText() can work
with the new API.

Depends on D82283

Similar to WSRunObject::InsertBreak(), WSRunObject::InsertText() can use
the new APIs for InsertBreak() even though the name is odd for InsertText(),
but the mismatching is caused by odd logic of it. If replacing range starts
from and/or ends by middle of invisible white-space sequence, all of the
invisible white-spaces should be removed to prevent they become visible.
However, we shouldn't change any behavior in this bug.

Depends on D82284

I realized that WSFragment::MarkAsVisible() is called only by
TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine(). Therefore,
beforeRun && !beforeRun->IsStartOfHardLine() && beforeRun->IsVisible() can be
handled with pointPositionWithVisibleWhiteSpacesAtStart and
afterRun && !afterRun->IsEndOfHardLine() && afterRun->IsVisible() can be
handled with pointPositionWithVisibleWhiteSpacesAtEnd. So, we can make
WSRunObject::InsertText() stop using FindNearestFragment() to compute
inserting string.

Depends on D82285

For handling composition, WSRunObject::InsertText() rescan white-spaces at
end of replacing range. However, in most cases, mScanStartPoint and
mScanEndPoint are same. Therefore, we can save the runtime cost of the
rescan easier than the old design.

Depends on D82286

Similar to the previous changes, WSRunObject::PrepareToDeleteRangePriv()
can use TextDataFragment::CreateWSFragmentForVisibleAndMiddleOfLine() and
result of comparing with deleting range.

Depends on D82287

Unfortunately, remaining code which use beforeRun and afterRun of
WSRunObject::PreareToDeleteRangePriv() is completely broken. It tries to
do what the new utility methods say, but as you see in the method, the
checking code does not make sense. For now, we should keep this broken
check even with the expensive DOM point comparisons. I hope that this does
not harm any benchmark score.

Note that I tested this with all automated tests with comparing the result
of these methods with MOZ_ASSERT() like this:
https://hg.mozilla.org/try/rev/29cb7840e404473a41d2d1fbdd229f762ccac5d3
So, I think that this is enough safe because the most edge cases are tested
by the first patch in this bug and editing/run/(forwarddelete|delete).html
of WPT.

Depends on D82289

Now, nobody uses WSRunScanner::FindNearestRun() so that we can remove it.
Then, there is no users of WSRunScanner:mFragments. Therefore, we can remove
the member, accessors and initializers.

Depends on D82290

Now, we know that it returns WSFragment for visible white-spaces and may
lie position in the line. Therefore, we should rename it as just representing
visible white-spaces.

Depends on D82291

Now, WSFragment instances are created only by
TextFragmentData::CreateWSFragmentForVisibleWhiteSpaces(). Therefore, it's
always visible.

Additionally, this patch hides WSFragment constructors from the others too.

Depends on D82293

Now, we can call WSFragment VisibleWhiteSpacesData. Then, the methods of
WSRunObject which take WSFragment as their arguments become clearer what
they mean.

Depends on D82294

Attachment #9161445 - Attachment description: Bug 1647556 - part 3-3: Implement the complicated case of `GetInvisibleLeadingWhiteSpaceRange()` r=m_kato! → Bug 1647556 - part 3-3: Implement the other complicated case of `GetInvisibleLeadingWhiteSpaceRange()` r=m_kato!
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/5766d99b88f3 Add some WPTs for testing how to treat invisible leading and trailing white-spaces in block element r=m_kato
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/24445 for changes under testing/web-platform/tests
Upstream web-platform-tests status checks passed, PR will merge once commit reaches central.
Upstream PR merged by moz-wptsync-bot
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/8af1108e3266 part 1: Get rid of `WSRunScanner::InitializeWithSingleFragment()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/135b4d5c05f5 part 2: Create `WSRunScanner::TextFragmentData` class for the alternative of `WSFragment`s r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/36836e51b805 part 3-1: Add API to `WSRunScanner::TextFragmentData` to get range of invisible leading or trailing white-spaces r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/8afb15f59ee5 part 3-2: Implement complicated case of `GetInvisibleTrailingWhiteSpaceRange()` r=m_kato
Attachment #9161458 - Attachment description: Bug 1647556 - part 10-3: Make `WSRunObject::InsertText()` stop rescan end of replacing range if it's collapsed r=m_kato! → Bug 1647556 - part 10-4: Make `WSRunObject::InsertText()` stop rescan end of replacing range if it's collapsed r=m_kato!
Attachment #9161450 - Attachment description: Bug 1647556 - part 6: Make `WSRunObject::AdjustWhiteSpace()` use `TextDataFragment::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato! → Bug 1647556 - part 6: Make `WSRunObject::AdjustWhiteSpace()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato!
Attachment #9161451 - Attachment description: Bug 1647556 - part 7: Make `ScanPreviousVisibleNodeOrBlockBoundaryFrom()` and `ScanNextVisibleNodeOrBlockBoundaryFrom()` use `TextDataFragment::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato! → Bug 1647556 - part 7: Make `ScanPreviousVisibleNodeOrBlockBoundaryFrom()` and `ScanNextVisibleNodeOrBlockBoundaryFrom()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato!
Attachment #9161456 - Attachment description: Bug 1647556 - part 10-2: Make `WSRunObject::InsertText()` use `TextDataFragment::GetNewInvisibleLeadingWhiteSpaceRangeIfSplittingAt()` and `TextDataFragment::GetNewInvisibleTrailingWhiteSpaceRangeIfSplittingAt()` r=m_kato! → Bug 1647556 - part 10-2: Make `WSRunObject::InsertText()` use `TextFragmentData::GetNewInvisibleLeadingWhiteSpaceRangeIfSplittingAt()` and `TextFragmentData::GetNewInvisibleTrailingWhiteSpaceRangeIfSplittingAt()` r=m_kato!
Attachment #9161459 - Attachment description: Bug 1647556 - part 11-1: Make `WSRunObject::PrepareToDeleteRangePriv()` use `TextDataFragment::CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato! → Bug 1647556 - part 11-1: Make `WSRunObject::PrepareToDeleteRangePriv()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato!
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/79f971fe23ec part 3-3: Implement the other complicated case of `GetInvisibleLeadingWhiteSpaceRange()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/024fea0f46f7 part 4: Rewrite `WSRunObject::Scrub()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/57a1e9abceea part 5-1: Create new API to get `WSFragment` in middle of line and visible r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/7a056aa7fe9a part 5-2: Implement another case of `CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/a4d6dfa8fd52 part 5-3: Implement the other case of `CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato https://hg.mozilla.org/integration/autoland/rev/239c8b488cf5 part 6: Make `WSRunObject::AdjustWhiteSpace()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/c4c0cd6b85a2 part 7: Make `ScanPreviousVisibleNodeOrBlockBoundaryFrom()` and `ScanNextVisibleNodeOrBlockBoundaryFrom()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` instead of scanning all `WSFragment`s r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/bb0345cd3591 part 8: Make `WSRunObject::PrepareToSplitAcrossBlocksPriv()` stop using `FindNearestFragment()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/0455f6b42105 part 9-1: Make `WSRunObject::InsertBreak()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` like previous patch r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/14d786ed7169 part 9-2: Make `WSRunObject::InsertBreak()` stop using `FindNearestFragment()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/775e39b253e7 part 10-1: Make `WSRunObject::InsertText()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/148101a527f9 part 10-2: Make `WSRunObject::InsertText()` use `TextFragmentData::GetNewInvisibleLeadingWhiteSpaceRangeIfSplittingAt()` and `TextFragmentData::GetNewInvisibleTrailingWhiteSpaceRangeIfSplittingAt()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/7ad0e54e103a part 10-3: Make `WSRunObject::InsertText()` stop using `WSRunScanner::FindNearestFragment()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/b7aa7da129cc part 10-4: Make `WSRunObject::InsertText()` stop rescan end of replacing range if it's collapsed r=m_kato https://hg.mozilla.org/integration/autoland/rev/25a94f449887 part 11-1: Make `WSRunObject::PrepareToDeleteRangePriv()` use `TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/b7cdd57e400b part 11-2: Make `WSRunObject::PrepareToDeleteRangePriv()` use `TextFragmentData::GetNewInvisibleLeadingWhiteSpaceRangeIfSplittingAt()` and `TextFragmentData::GetNewInvisibleTrailingWhiteSpaceRangeIfSplittingAt()` r=m_kato
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/14f31c9d33d9 part 11-3: Make `WSRunObject::PrepareToDeleteRangePriv()` stop using `WSRunScanner::FindNearestRun()` r=m_kato https://hg.mozilla.org/integration/autoland/rev/1711f8f090e3 part 12: Get rid of `WSRunScanner::FindNearestRun()` and `WSRunScanner::mFragments` r=m_kato https://hg.mozilla.org/integration/autoland/rev/7963aeba2dae part 13: Rename `CreateWSFragmentForVisibleAndMiddleOfLine()` to `CreateWSFragmentForVisibleWhiteSpaces()` r=m_kato https://hg.mozilla.org/integration/autoland/rev/b9cae60a1da4 part 14: Get rid of unnecessary `WSFragment` memebers r=m_kato https://hg.mozilla.org/integration/autoland/rev/bc2e1b86dcd3 part 15: Get rid of visible state of `WSFragment` r=m_kato https://hg.mozilla.org/integration/autoland/rev/6afa4d826913 part 16: Rename `WSFragment` to `VisibleWhiteSpacesData` r=m_kato
Whiteboard: [h2review-noted]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: