When the diff processor collapses shared groups based on the user
context preference, it would sometimes collapse a single line, resulting
in a common group labeled "Show 1 common line" which takes up exactly
as much space in the diff view as the line itself. Moreover, the GWT UI
does not collapse single line common sections in this way (but does when
there are two or more lines).
Sets the threshold to collapse at least two lines and encodes this in a
test.
Bug: Issue 4721
Change-Id: I8a3a8556fd66a313eacc361379612c700d7ae070
A source of latency when creating diff comments in large diffs is the
work needed to reflow the diff DOM to make room for the new comment.
This is particularly evident when adding comments to new files because
the diff is built as an addition group representing the entire file, so
the comment causes a reflow on every subsequent line.
This change optimizes this process in three ways.
* **Limit the size of ADD & REMOVE groups:** The diff processor will now
break an add or a remove chunk into a series of smaller chunks of the
same kind. This is controlled by the MAX_GROUP_SIZE constant. In this
way the number of nodes that need to be reflowed when a comment is
added to an add or remove group is limited to the number of subsequent
lines in that group plus the subsequent number of groups.
* **GPU optimize group in general:** Adds CSS properties to diff TBODY
elements (which correspond to groups, for the most part) that trigger
GPU acceleration when available.
* **Apply `table-layout: fixed;`** This style speeds up table reflow in
general.
Change-Id: Ie0e3665b7752fec67f7123cfae70ae99e6f67521
Previously each group was rendered asynchronously, i.e. deferring
control between each group render. This caused the total render time to
be ~10x slower than totally synchronous. But the advantage of this
approach was that the content at the start of the diff would be visible
as soon as possible.
This change finds a compromise by combining processing/rendering the
diff groups in larger synchronous batches which are based on the number
of lines in the groups.
Change-Id: I5d42700962f51bea0dedb05763a1d8eb1c32bfd1
Building on existing support for asynchronous diff processing, the
rendering stage is now also asynchronous. The `emitGroup` method of
gr-diff-builder (which constructs a DOM fragment and attaches it to the
document) is now called whenever the processor emits a new group, rather
than waiting for all groups to be available and looping over them.
Adds support for canceling the processor, and removes a behavior where
the diff was being re-rendered needlessly, causing visible flicker.
Updates a test that broke when rendering became asynchronous.
Change-Id: I37fcd65efc8c901b85fc93e91611c022edc10dc4
Modifies the `process` method of gr-diff-processor to traverse diff
content using an asynchronous recursive loop rather than a blocking
for-loop. The async version maintains the promise interface already
established.
Refactored to constrain side-effects to the `process` method. Whereas,
formerly, helper methods in gr-diff-processor both read and wrote the
component's internal state, they are rewritten to be more pure, making
them simpler to understand, test, and invoke asynchronously.
Documentation is added throughout as well as tests for helper functions.
Note that this change only makes the processing step asynchronous.
Upgrading the diff-rendering stage to be non-blocking will come in a
later change.
Change-Id: Ifd50eeb75797b173937890caacc92cad5675fc20
Moves the diff-processing functionality of the gr-diff-builder component
into a new gr-diff-processor component which exposes a promise-based
interface. This is step one of creating an asynchronous (non-blocking)
diff rendering system.
As much as possible, this change is a transfer of code (with tests) from
one component to another, making it easier to verify that functionality
has not changed. Cleanup of the code, and refactoring it into a
more-testable form will come with later changes.
Feature: Issue 3916
Change-Id: I875b03b20bf953b128cbe3c5001ba1f8eba12c61