Commit Graph

304 Commits

Author SHA1 Message Date
Wliu
1a4e6c4c85 Merge pull request #15603 from jsoref/spelling
Spelling
2017-09-10 18:29:38 +02:00
Josh Soref
5cbe7c8897 spelling: appearance 2017-09-10 15:46:38 +00:00
Antonio Scandurra
c1981ffb44 Correctly remove block decorations whose markers have been destroyed
In https://github.com/atom/atom/pull/15503 we mistakenly assumed
`marker.isValid` accounted only for the validity of the marker. However,
that method returns `false` also for markers that are valid but have
been destroyed. As a result, the editor component was mistakenly not
removing block decorations associated with such markers.

With this commit we will rely on the local `wasValid` variable instead.
If its value is `true`, it means that the block decoration has been
accounted for in the `lineTopIndex` and must, as a result, be cleaned up
in case the marker or the decoration gets destroyed.
2017-09-07 17:52:04 +02:00
Antonio Scandurra
806b652da4 Flush scroll position to dummy scrollbar components on re-attach
This prevents the dummy scrollbars from resetting their position to `0`
when the editor element is moved elsewhere in the DOM (e.g. when
splitting a pane item).
2017-09-07 15:05:42 +02:00
Antonio Scandurra
7bd2c670e1 Merge pull request #15546 from atom/as-never-autoscroll-when-clicking-on-content
Don't autoscroll when using the mouse to add, delete or move selections
2017-09-06 02:12:15 -07:00
Antonio Scandurra
20ea98ad41 Don't render block decorations located outside the visible range
Previously, when trying to use block decorations on non-empty markers,
Atom could sometimes throw an error if such markers ended or started at
a position that was not currently rendered.

In fact, even if we already restricted the decoration query to markers
that intersected the visible row range, markers that were only partially
visible would still be considered for rendering. If, depending on the
`reversed` property, we decided to render the tail or head of the marker
in question and this was outside the viewport, Atom would throw the
aforementioned exception.

This commit addresses the above issue by explicitly ignoring block
decorations that are located on rows that are not yet rendered.
2017-09-05 18:05:35 +02:00
Antonio Scandurra
91bb1e12c7 Don't autoscroll when using the mouse to add, delete or move selections 2017-09-05 15:26:54 +02:00
Antonio Scandurra
6e919e7acd Don't remeasure invalid block decorations
This fixes an uncaught exception that was being thrown after
invalidating a marker and resizing the editor.
2017-09-02 11:11:27 +02:00
Antonio Scandurra
3e10a84d49 Merge pull request #15506 from atom/as-honor-scrollbar-visible-only-when-scrolling
Honor macOS "Show scrollbars only when scrolling" setting
2017-08-31 11:29:26 +02:00
Antonio Scandurra
f85deec482 Merge pull request #15503 from atom/as-fix-invalidated-block-decoration-markers
Fix rendering of block decorations for invalid markers
2017-08-31 11:29:14 +02:00
Antonio Scandurra
12e6740c9c Merge pull request #15487 from atom/as-scroll-sensitivity
Always honor scroll intent on mousewheel
2017-08-31 11:28:16 +02:00
Antonio Scandurra
50088b16c9 Honor macOS "Show scrollbars only when scrolling" setting
Previously, we were hiding scrollbars when their height/width was 0. On
macOS, however, users can decide to only show scrollbars while
scrolling, which causes Atom to detect scrollbars as being invisible
during measurements. As a result, we were mistakenly setting the
visibility property to `hidden` when this setting was on, thus
preventing users from seeing the scrollbar on scroll.

With this commit we are changing the dummy scrollbar components to only
become invisible when the content is not scrollable rather than when the
scrollbars have zero width or height.

As part of this, we have also renamed the
`is{Horizontal,Vertical}ScrollbarVisible` functions to
`canScroll{Horizontally,Vertically}`, to better express their intent.
2017-08-30 17:11:40 +02:00
Antonio Scandurra
9bf47f31cb Fix rendering of block decorations for invalid markers
Previously, when a marker became invalid we would delete the
corresponding block decoration from the DOM, without however removing it
from the `lineTopIndex`. Also, we had a similar issue when decorating a
marker that was already invalid: we would account for it in the index
without adding it to the DOM.

This commit addresses the above problems by ensuring that block
decorations are never added for invalid markers. At the same time, the
editor component will still keep track of changes on the marker that was
decorated, so that it can detect when its validity changes and render it
appropriately.
2017-08-30 14:25:20 +02:00
Antonio Scandurra
76e2e03139 Always honor scroll intent on mousewheel
This commit introduces a change in the way we respond to mousewheel
events. In particular, if `delta * scrollSensitivity` is less than 1 or
greater than -1, we will round it up or down in an attempt to honor the
user's scroll intent.
2017-08-29 13:39:11 +02:00
Antonio Scandurra
b486e3edda Move highlight decorations outside of tiles
As a consequence of https://github.com/atom/atom/pull/15378, we are now
able to render highlight decorations in a separate div, as opposed to
having an highlight container for each tile.

Code-wise this is much simpler, because highlights spanning multiple
tiles can be represented via a single region and don't need to be split
across the tiles they span anymore. As a byproduct, performance should
improve as well, because the number of nodes that need to be managed
should decrease significantly.

This also fixes https://github.com/atom/atom/issues/15449, and other
similar rendering artifacts, because highlight decoration DOM nodes
won't need to move between tiles anymore when their position changes.
2017-08-29 11:44:07 +02:00
Antonio Scandurra
74ae169fcc Maintain a map of line components instead of line nodes and text nodes
Other than simplifying the code, this will help us understand whether
https://github.com/atom/atom/issues/15263 might be related to a node
reuse issue.

Signed-off-by: Nathan Sobo <nathan@github.com>
2017-08-23 14:52:50 +02:00
Antonio Scandurra
e6b84dbb44 Test handleMouseDragUntilMouseUp 2017-08-22 14:38:05 +02:00
Antonio Scandurra
2f46b8e00e Put back mistakenly deleted line 2017-08-21 09:53:54 +02:00
Nathan Sobo
3d0d1ae44e Prevent block decoration margins from collapsing during measurement
We now render a 1px high sentinel element between off-screen block
decorations before measuring them to prevent margins from collapsing.
2017-08-20 08:23:41 -06:00
Nathan Sobo
835ed10f7c Handle highlight end rows with 'before' blocks in addition to 'after' 2017-08-20 07:32:44 -06:00
Nathan Sobo
f33051da33 Fix highlight end pixel position calculation
Previously, we were calculating the position preceding block decorations
for the row following the end of the highlighted range, but that's
actually wrong. We just want the position following block decorations of
the end of the highlighted range, plus one line height. This prevents us
from incorrectly rendering the end of highlight after block decorations
that immediately follow the end of the highlighted range.
2017-08-20 07:00:50 -06:00
Antonio Scandurra
effc6d9d21 Fix line number position when block decorations are at tile boundaries
When there are block decorations, we compute a `marginTop` style for
line numbers, so that they can be aligned correctly to the corresponding
line nodes.

This commit fixes a regression in the logic that calculated the
`marginTop` value, which was failing to correctly render line numbers
when block decorations were located right before the end of a tile, or
exactly at
the beginning of it.
2017-08-19 15:40:32 +02:00
Antonio Scandurra
1ffc8997d2 Set visibility: hidden on dummy scrollbars if native ones are invisible
This prevents the cursor from unexpectedly changing when approaching the
bottom/right corner of the editor with the mouse, even when no scrollbar
is being shown.
2017-08-17 15:11:32 +02:00
Antonio Scandurra
1b5ed62e4f Ignore scroll requests to NaN, null or undefined positions 2017-08-17 09:17:52 +02:00
Nathan Sobo
9cf7f609f5 Round return values of getMaxScrollTop/Left 2017-08-16 15:59:04 -06:00
Nathan Sobo
72322985d9 Merge pull request #15337 from atom/ns-remeasure-longest-line
Remeasure the longest line's width when the font size changes
2017-08-16 14:32:22 -06:00
Nathan Sobo
2bcfd934c0 Fix tests by ignoring off screen lines
Also, clear the dataset when recycling DOM elements

Signed-off-by: Antonio Scandurra <as-cii@github.com>
2017-08-16 12:31:42 -06:00
Antonio Scandurra
15e3fbaa07 Merge pull request #15339 from atom/ns-as-clear-lines-to-measure-later
Only clear linesToMeasure when we have actually measured
2017-08-16 20:08:59 +02:00
Nathan Sobo
9d356020c5 Remeasure the longest line's width when the font size changes 2017-08-16 11:53:55 -06:00
Nathan Sobo
c626836b2e Only clear linesToMeasure when we have actually measured
Previously, as soon as we decided to render linesToMeasure, we would
clear them out. However, if a second update interleaved with the update
that initially requested measurement, it could cause the requested lines
to not be present when the measurement phase from the first update
occurred. Now, any additional updates will only add to the set of lines
that need to be measured until the measurement phase actually happens.

Signed-off-by: Antonio Scandurra <as-cii@github.com>
2017-08-16 11:28:58 -06:00
Nathan Sobo
c398fe66c9 Hide off-screen lines when we render them for measurement 2017-08-16 10:00:57 -06:00
Nathan Sobo
e9a00ce9b3 Merge pull request #15324 from atom/ns-fix-mousewheel-handling
Only scroll one axis at a time, whichever has the greater delta
2017-08-15 19:29:36 -06:00
Nathan Sobo
4493ae2270 Only scroll one axis at a time, whichever has the greater delta 2017-08-15 16:08:07 -06:00
Nathan Sobo
b35708b8cf Add test for placeholder text positioning 2017-08-15 15:48:18 -06:00
Antonio Scandurra
3d71e627eb Move cursors container inside lines container
This will ensure that applying any style that changes the location of
the lines container will also correctly position the cursors.
2017-08-15 18:44:23 +02:00
Nathan Sobo
7226f6fb08 Merge pull request #15313 from atom/as-fix-extra-schedule-update
Ensure extra document updates are not scheduled during `updateSync`
2017-08-15 09:01:22 -06:00
Antonio Scandurra
f569514938 Ensure extra document updates are not scheduled during updateSync
When changing the editor styles, we force the component to remeasure
character dimensions. If they change, each line's height could change
too, causing the current scroll top position to not match the viewport
the user was observing. Thus, when detecting a line height change, we
try to show users the area of the screen they were looking prior to
tweaking the font size.

In trying to maintain the aforementioned logical position, however, we
were mistakenly scheduling a new update before actually finishing the
current one. This was problematic because if the first update detected
that the longest screen line changed and such line was off-screen, it
would try to render it. Before having the chance to measure it, though,
the new update would kick in and delete the new longest screen line
node, because it assumed it had already been measured. Finally, when
`measureContentDuringUpdateSync` fired, it would notice that the longest
screen line node did not exist and throw an exception as a result.

This commit changes the `updateSync` method to set the `updateScheduled`
flag only before returning control to the caller, as opposed to doing so
at the beginning. This prevents calls to `scheduleUpdate` made in
`updateSync` from scheduling new unwanted updates.
2017-08-15 15:32:29 +02:00
Antonio Scandurra
e980598aba Honor editor's scrollSensitivity parameter 2017-08-15 12:22:59 +02:00
Antonio Scandurra
eb1eeb3fde Ignore clicks on block decorations
Previously, clicking on a block decoration to interact with it would
cause the editor to scroll to the line next to it. This is inconvenient,
especially if the decoration was designed to be interactive and
contained buttons or links. If the decoration was close to the bottom of
the screen, clicking on a button inside of it would make the editor
scroll down and abort the click.

This behavior regressed during the editor rendering layer rewrite and
with this commit we are restoring the original behavior by simply
ignoring clicks that land on block decorations.
2017-08-14 15:43:48 +02:00
Nathan Sobo
ff32fd80bf Merge pull request #15273 from atom/as-fix-line-height-0
Don't throw an error when setting an incredibly small `lineHeight`
2017-08-12 13:46:23 -06:00
Nathan Sobo
feb0cddf5e Merge pull request #15265 from atom/ns-ime-workaround
Work around incorrect data on `compositionupdate` events in Chrome 56
2017-08-12 13:26:01 -06:00
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