Commit Graph

363 Commits

Author SHA1 Message Date
Antonio Scandurra
964f209c40 Don't throw an error when setting an incredibly small lineHeight
Instead, if the measured line height equals 0, default it to 1 so that
the editor component doesn't start computing `NaN` or `Infinity` values
due to e.g. dividing by 0.

We should probably consider sanitizing line heights smaller than a
certain threshold, but that's non trivial because line height is
expressed as a multiplier of the font size. Also, users may style the
`line-height` property via CSS, which may still throw errors when using
small values.
2017-08-12 15:38:32 +02:00
Antonio Scandurra
b4f029e9f0 Test both Chrome 56 and other Chrome versions IME behavior 2017-08-12 14:38:18 +02:00
Antonio Scandurra
fc1327eb22 Fix measuring lines in presence of pending autoscroll requests
Calling `pixelPositionForScreenPosition` was sometimes throwing an error
indicating that the requested position was not rendered and that, as
such, could not be measured.

This was caused by trying to measure a line that was visible at the
moment of the call while also having a pending autoscroll request that
would cause that line to go off-screen. Due to how the code was
structured, we would mistakenly detect that line as visible, autoscroll
to a different location, re-render a different region of the buffer and
then try to measure the now invisible line.

This commit fixes this issue by restructuring and simplifying the logic
for rendering extra lines in order to measure them. Now, every line for
which a measurement has been requested is stored in a `linesToMeasure`
map. During the first phase of the update process (after honoring
autoscroll requests), we detect which of these lines are currently
visible and if they're not, store them into the
`extraRenderedScreenLines` map, which is then used to render lines that
are invisible but need to be measured.
2017-08-12 12:31:50 +02:00
Antonio Scandurra
00d27befe8 Create, update and destroy highlights manually
Etch's reconciliation routine causes elements to be sometimes
re-ordered. In order to move an element, however, Etch needs to first
detach it from the DOM and then re-append it at the right location.

This behavior is unacceptable for highlight decorations because it could
re-start CSS animations on a certain highlight decoration when a
completely different one is added or removed.

Even though we are still interested in restructuring etch's
reconciliation logic to prevent unwanted re-orderings, with this commit
we are switching to a custom routine to create/update/remove highlight
decorations that prevents unnecessary moves and, as a result, fixes the
undesired behavior described above.
2017-08-10 17:48:34 +02:00
Jason Rudolph
47420761f5 Add basic test for TextEditorComponent::didPaste(event) 2017-08-07 11:32:57 -04:00
Jason Rudolph
c7bfbc181c 🐛 Fix atom/tabs#461
On Linux, when the user performs a middle-button mouse click, Chromium
fires both a mouse-down event *and* a paste event. This commit teaches
the TextEditorComponent to ignore the paste event.

When the user performs a middle-mouse click on a tab, we get close the
tab and attempt to prevent Chromium's default processing for the event.
[1] This prevents Chromium's default processing for the *mouse down*
event, but then Chromium also fires a *paste* event, and that event
pastes the clipboard's current content into the newly-focused text
editor. 🙀

Since Atom already has its own logic for handling pasting, we
shouldn't (🤞) need to handle browser paste events. By ignoring the
browser paste events on Linux, we fix atom/tabs#461.

[1]
ce1d92e0ab/lib/tab-bar-view.coffee (L416-L418)
2017-08-07 10:19:08 -04:00
Jason Rudolph
50f02495c0 Attempt to fix flaky test re: flashing highlight decorations
Based on the assertion failures seen in
https://github.com/atom/atom/issues/15158#issue-247808059, it seems that
the flash for class 'c' sometimes ends before the flash for class 'd'
happens. Prior to this change, we only flashed class 'c' for 100ms, and
perhaps that isn't always enough time.

In this commit, we increase the flash duration from 100ms to 1000ms,
greatly increasing the likelihood that we're allowing enough time for
the flash on class 'd' to take place before the flash for class 'c'
ends. We also extract the scenario into its own test, so that 1) we can
more clearly explain the scenario that these assertions are testing and
2) future intermittent test failures will be easier to isolate.
2017-08-04 14:28:28 -04:00
Jason Rudolph
15a055b6cd Revert some of the changes from 29810c6cd1
xref: https://github.com/atom/atom/pull/15154#discussion_r131270263
2017-08-03 17:57:13 -04:00
Jason Rudolph
29810c6cd1 Attempt to fix flaky test re: blinking cursor
As shown in #15122, this test sometimes fails in CI with the following
error:

  TextEditorComponent
    rendering
      it blinks cursors when the editor is focused and the cursors are not moving
        Expected '0' to be '1'.
          at it (C:\projects\atom\spec\text-editor-component-spec.js:414:49)
        Expected '0' to be '1'.
          at it (C:\projects\atom\spec\text-editor-component-spec.js:415:49)

I *think* this might be a case of overspecification in the test's
assertions. Prior to this commit, the test expected the blinking cursor
to *start* in the visible state, and then transition to the invisible
state. When we see the failure above, I suspect that the cursor has
already transitioned from the visible state to the invisible state by
the time the assertion runs.

Since the test aims to verify that the cursor blinks, it seems like we
should focus on the blinking, and not worry about the *initial* state of
the cursor. This commit removes the assertions that verify the initial
state of the cursor, and instead asserts that the cursor toggles between
the visible and the invisible state.
2017-08-03 12:25:01 -04:00
Nathan Sobo
1584189962 Ensure custom decoration elements fill their container 2017-08-02 20:34:18 -06:00
Max Brunsfeld
48abb16edb Fix exception in screenPositionForPixelPosition when content updates are pending
Signed-off-by: Nathan Sobo <nathan@github.com>
2017-07-18 14:31:47 -07:00
Nathan Sobo
dc73841673 Add test for null-guarding element during gutter decoration update 2017-07-13 14:37:58 -06:00
Nathan Sobo
f6d2f966bf Fix middle-mouse-button paste on Linux
Chrome now synthesizes a textInput event on mouseup for middle mouse
button clicks, which rendered our custom JS for handling that case
redundant.
2017-07-10 15:53:23 -06:00
Nathan Sobo
960e515e77 Merge pull request #14948 from atom/ns-add-gutter-decoration-class
Always render 'decoration' class on custom decorations
2017-07-05 15:24:43 -06:00
Antonio Scandurra
bcaf655325 Update buffer-row and screen-row data fields on each line number node 2017-07-05 11:12:48 +02:00
Antonio Scandurra
942dd03bd0 Assign screen-row to each line number as a data field 2017-07-05 11:11:44 +02:00
Nathan Sobo
e7b4ad48f0 Always render 'decoration' class on custom decorations 2017-07-03 16:10:41 -06:00
Lukas Geiger
e686c4d7f8 Remove invalidateBlockDecorationDimensions from tests
This is now automatically called by the mutation observer.
2017-06-30 14:08:40 +02:00
Antonio Scandurra
52ba6c7342 Fix measuring block dec. if adding them before updating element's width 2017-06-26 12:52:18 +02:00
Antonio Scandurra
0a46c9ad7b Prevent block decorations from mistakenly wrapping during measurements
Before rendering block decorations, we read their heights by putting
them into a special div called `blockDecorationMeasurementsArea`.

Previously, this div was not explicitly sized, which was causing
decorations to wrap while being measured but not when actually rendering
them.

This commit fixes this inconsistency by explicitly styling the
measurement area so that it has the same width as the component scroll
width.
2017-06-13 12:31:27 +02:00
Antonio Scandurra
a314deeff9 Unfocus test 2017-06-12 11:27:58 +02:00
Antonio Scandurra
9a0709e95e Don't try to measure lines that don't exist
By the time that the animation frame is delivered, the requested
autoscroll
position could not exist anymore. This could cause the editor component
to measure a non-existent line and, as a result, throw an exception.

With this commit we will always ignore measurements for screen lines
that do not exist.
2017-06-09 18:40:24 +02:00
Antonio Scandurra
6d1f8ea88c Render line number gutter without numbers when showLineNumbers is false
Signed-off-by: Nathan Sobo <nathan@github.com>
2017-06-01 16:29:04 +02:00
Nathan Sobo
2372227b00 Fix specs on macOS when "Show scroll bars" option isn't "always" 2017-06-01 12:01:11 +02:00
Antonio Scandurra
3b3505d969 Always allow to destroy free-form folds from the gutter 2017-05-16 14:36:50 +02:00
Antonio Scandurra
ad6202cadb Show foldable icon on the last screen row belonging to a buffer row 2017-05-16 14:26:57 +02:00
Antonio Scandurra
4c5127ca2f Update foldable icon when a row's foldability changes 2017-05-16 14:05:11 +02:00
Antonio Scandurra
0d4e2b3556 Fix editor component tests on Windows 2017-05-12 13:04:03 +02:00
Nathan Sobo
4eecf8d1a6 Don't change number of tiles based on block decorations
This means we may render more tiles than necessary when we have block
decorations, but it prevents changing the number of rendered tiles
during scrolling with certain combinations of line height and editor
height. If it ever becomes a problem we can get smarter about
subtracting the height of the visible block decorations from the editor
height, but for now this gives us more reliable performance for the
common case.
2017-05-09 15:09:14 -06:00
Antonio Scandurra
be2aaa0b22 Use explicit state to recycle tiles instead of modulo scheme
This avoids updating tiles unnecessarily when changing the number of
rendered tiles.

Signed-off-by: Nathan Sobo <nathan@github.com>
2017-05-09 17:46:29 +02:00
Max Brunsfeld
1c8847cb4f 🐎 Ensure rendered tile count is stable when scrolling
Signed-off-by: Nathan Sobo <nathan@github.com>
2017-05-08 15:50:16 -07:00
Nathan Sobo
f76e850aa5 Fix rendering artifacts when resizing with soft wraps
Previously, we were accidentally depending on the state of the display
layer when forcing it to update its index. This caused us to not index
enough content to cover the visibile area, which meant we weren't
querying enough lines to fill the screen in some situations.
2017-05-08 10:58:33 -06:00
Antonio Scandurra
df4116d4aa Fix clicking past the content height
Signed-off-by: Nathan Sobo <nathan@github.com>
2017-05-05 19:55:14 +02:00
Antonio Scandurra
15f25a745a Update width of content when approximate longest screen row changes 2017-05-05 11:29:57 -06:00
Antonio Scandurra
2855e01289 Don't create empty nodes when a text decoration ends next to a text tag
This was causing problems in measurements because in that code path we
assume that text nodes are never empty. This commit also adds a test
verifying this invariant when a text decoration ending right after a
text tag is added.
2017-05-05 11:22:01 +02:00
Antonio Scandurra
f7b79b477a Update class list even when the editor is not attached 2017-05-05 09:30:08 +02:00
Nathan Sobo
bc34344d90 Maintain the scroll position when changing font size 2017-05-05 09:30:08 +02:00
Nathan Sobo
c5c48094ba Avoid requesting horizontal measurement when auto-scrolling vertically
This was leaving a measurement request in the map that was getting
picked up on the next frame. In some cases, the requested measurement
row was not present, causing an exception.
2017-05-05 09:30:08 +02:00
Nathan Sobo
1b1973db15 Rename method to match old implementation 2017-05-05 09:30:08 +02:00
Nathan Sobo
42bb02c8a8 Account for vertical scrollbar width when soft-wrapping lines 2017-05-05 09:30:08 +02:00
Nathan Sobo
fe13279531 Update DOM in screenPositionForPixelPosition if needed
Some packages are interacting with this method assuming this behavior,
so this commit eliminates `screenPositionForPixelPositionSync` and
instead just performs the DOM update in `screenPositionForPixelPosition`
if it is needed.
2017-05-05 09:30:08 +02:00
Antonio Scandurra
c2b854123b Never create empty spans at the beginning of a row
This was happening when a text decoration overlapped a row, but the next
boundary was located exactly at the beginning of it.
2017-05-05 09:29:30 +02:00
Nathan Sobo
ac8a908385 Implement text decorations in rendering layer 2017-05-05 09:29:30 +02:00
Antonio Scandurra
570cfdeaff Ignore resize events if they are delivered while the editor is hidden 2017-05-05 09:29:30 +02:00
Nathan Sobo
c36303e631 Avoid blowing away classes assigned on the editor element by packages
/cc @t9md
2017-05-05 09:29:30 +02:00
Nathan Sobo
c7228f6d81 Fix error when attaching soft-wrap editor in synchronous update mode
Taking the initial measurement was setting the soft wrap column, which
was triggering a display layer reset, which was scheduling an update.
This update occurred at an unexpected time causing an exception.
2017-05-05 09:29:30 +02:00
Nathan Sobo
bd6eedcc88 Eliminate strictly contained divs wrapping lines and highlights
I was hoping to strictly contain the layouts of highlights an lines
separately, since they are updated during different render phases.
Unfortunately, strict containment requires both divs to be positioned
absolutely. This in turn creates separate stacking contexts for lines
and highlights, which makes it impossible to render highlights in front
lines which themes sometimes need to do. For example,
atom-material-syntax pushes bracket matcher highlights to the front so
they are not obscured by the theme's solid black cursor line background.

/cc @as-cii. You should examine my work here and make sure I'm not
screwing something up with your line/block decoration update code.
2017-05-05 09:29:30 +02:00
Antonio Scandurra
72351481c7 Fix positioning for block decorations located at the beginning of a tile 2017-05-05 09:29:30 +02:00
Nathan Sobo
82cdf80f25 Extract CursorsAndInputComponent 2017-05-05 09:29:30 +02:00
Nathan Sobo
1ca4c69c87 WIP: Start extracting gutter component 2017-05-05 09:29:30 +02:00