Comparar commits

...

209 Commits

Autor SHA1 Mensagem Data
Nathan Sobo 0d587028af Preserve tiles that are the target of mousewheel events
This allows velocity-style mouse wheel scrolling to continue once the
tile has been scrolled off screen.
2014-08-08 14:39:25 -06:00
Nathan Sobo d4207c04d6 Render content and gutter tiles with an opaque background color 2014-08-07 18:40:57 -06:00
Nathan Sobo da864b6eec Account for scroll position when translating mouse clicks to positions 2014-08-07 15:22:47 -06:00
Nathan Sobo ce75ee011a Maintain scrollTop and scrollLeft as top-level presenter properties 2014-08-07 15:22:22 -06:00
Nathan Sobo 71b7fb3b5d Render line number decorations based on presenter state 2014-08-07 15:17:05 -06:00
Nathan Sobo f413a21a11 Add line number decorations to the presenter 2014-08-07 15:01:22 -06:00
Nathan Sobo 544cd54a41 Start rendering tiled line numbers. Still rough. 2014-08-07 15:00:35 -06:00
Nathan Sobo 8b1eec39b5 Add a dummy tile to the gutter presenter with the maxLineNumberDigits
This will be used to hold open the gutter's width despite the absolute
positioned tiles.
2014-08-07 09:02:14 -06:00
Nathan Sobo 02b955f823 Break out 'content' and 'gutter' presenters
For now they're just an extra level in the hash, but we'll need to store
the maxLineNumberDigits in the gutter presenter for maintenance of the
dummy line node.
2014-08-07 08:48:00 -06:00
Nathan Sobo 30d386527d Update maxLineNumberDigits in gutter tiles 2014-08-07 07:19:10 -06:00
Nathan Sobo 0af6dfc94c Decide how to handle screen line changes in each tile presenter 2014-08-07 07:19:10 -06:00
Nathan Sobo ef7a6b94b2 Combine specs for line and gutter tiles 2014-08-07 07:19:10 -06:00
Nathan Sobo 4d6be72f56 Start adding gutter tiles to EditorPresenter 2014-08-07 07:19:09 -06:00
Nathan Sobo 3ded5ec0f8 Return dot-separated line numbers to indicate soft wraps 2014-08-07 07:19:09 -06:00
Nathan Sobo 2f15f72139 Add DisplayBuffer::lineNumbersForScreenRows 2014-08-07 07:19:09 -06:00
Nathan Sobo 6f9fa39ad2 Remove DisplayStateManager. Using EditorPresenter instead. 2014-08-07 07:19:09 -06:00
Nathan Sobo f2eeb0629f Avoid occasional blank lines at the top and bottom of the editor 2014-08-07 07:19:09 -06:00
Nathan Sobo 1fdb4dbeda Un-f 2014-08-07 07:19:09 -06:00
Nathan Sobo 54c2139992 Add line decorations to EditorPresenter 2014-08-07 07:19:09 -06:00
Nathan Sobo 6e7dedb198 Explicit model tile height in presenter 2014-08-07 07:19:09 -06:00
Nathan Sobo 1fc33e1e21 Render and update lines based on mutable presenter 2014-08-07 07:19:09 -06:00
Nathan Sobo 583096a916 Handle scrollLeft changes 2014-08-07 07:19:09 -06:00
Nathan Sobo 4d88acd756 Start on a mutable EditorPresenter object 2014-08-07 07:19:09 -06:00
Nathan Sobo a3afaed950 Add proper line decorations to initial state 2014-08-07 07:19:09 -06:00
Nathan Sobo 716219b9a3 Handle 'onlyNonEmpty' option for line decorations 2014-08-07 07:19:08 -06:00
Nathan Sobo bc558194e9 Handle 'onlyEmpty' option for line decorations 2014-08-07 07:19:08 -06:00
Nathan Sobo c1ee2f420b Support 'onlyHead' option in line decorations 2014-08-07 07:19:08 -06:00
Nathan Sobo 58d9304c22 Refactor line decoration updates 2014-08-07 07:19:08 -06:00
Nathan Sobo 3226f54b97 Improve custom matcher to express omission of values 2014-08-07 07:19:08 -06:00
Nathan Sobo 63969a6467 Use line decorations to update display
Basic line decorations are working, but we still need to handle special
decoration options.
2014-08-07 07:19:08 -06:00
Nathan Sobo d5f7aca0ad Build line decorations into initial state 2014-08-07 07:19:08 -06:00
Nathan Sobo 94160044ad Fix fat finger 2014-08-07 07:19:08 -06:00
Nathan Sobo 4dcb35152f Only handle line decorations for now 2014-08-07 07:19:08 -06:00
Nathan Sobo 45ac962681 Update the display state on when line decorations are updated or removed 2014-08-07 07:19:08 -06:00
Nathan Sobo c5d502ab88 Add line decorations to display state when they're added 2014-08-07 07:19:08 -06:00
Nathan Sobo c75fc8aa01 Make ::updateTiles an iterator for operation-specific updates
Previously, I was trying to update everything with the same method. Now
I'm performing updates that are specifically tailored to each type of
operation on the model.
2014-08-07 07:19:07 -06:00
Nathan Sobo e954430599 Update tile states when display buffer changes 2014-08-07 07:19:07 -06:00
Nathan Sobo 44795da767 WIP: Base editor updates on immutable display state 2014-08-07 07:19:07 -06:00
Nathan Sobo 11df5c2855 Render cursors 2014-08-07 07:19:07 -06:00
Nathan Sobo 11189692b7 Break lines out into manually-updated tiles 2014-08-07 07:19:07 -06:00
Nathan Sobo a7fb07ccfa Avoid React handling of keydown/textInput to save ~1ms on keystrokes 2014-08-07 07:19:07 -06:00
Nathan Sobo a8df20271f WIP 2014-08-07 07:19:07 -06:00
Nathan Sobo 84064a811c :non_potable_water: Unsubscribe from window resize in EditorComponent
This fixes a major memory leak
2014-08-07 04:59:02 -06:00
Cheng Zhao 3c932d6d91 Upgrade to atom-shell@0.15.3 2014-08-07 00:11:40 +08:00
Ben Ogle a24d1d1af7 Upgrade find-and-replace 2014-08-05 11:31:58 -07:00
Ben Ogle edb5b43d64 Upgrade settings view for #3176 2014-08-05 11:20:38 -07:00
Ben Ogle ac496e1fa4 Upgrade tabs to fix hanging in #1663 2014-08-05 10:54:57 -07:00
Ben Ogle 103f3f8597 Merge pull request #3185 from sryze/patch-1
Add build fix from #2435
2014-08-05 10:17:24 -07:00
Kevin Sawicki 9842baedce Use Atom as FileDescription
This is the text presented when the app is presented in a select list.

Closes #3179
2014-08-05 07:59:02 -07:00
Kevin Sawicki aaa916f78d Upgrade to language-coffee-script@0.29 2014-08-05 07:52:49 -07:00
Sergey Zolotarev 7f6a4cccaf Add build fix from #2435 2014-08-05 18:00:25 +07:00
Kevin Sawicki 87edff1e42 Upgrade to language-gfm@0.46 2014-08-04 11:09:42 -07:00
Kevin Sawicki 96f35d3cde Upgrade to language-ruby@0.34 2014-08-04 11:09:41 -07:00
Nathan Sobo 7e45ffa4c3 Center around the cursor in Editor::scrollToCursorPosition by default
Fixes #3131
2014-08-04 11:58:07 -06:00
Kevin Sawicki 6af69b0fc7 Merge pull request #3164 from Bengt/patch-1
Correct Node.js' spelling, link Git and GNOME Keyring
2014-08-04 10:39:12 -07:00
Cheng Zhao 99e02570d1 Upgrade to atom-shell@0.15.2 2014-08-04 22:12:44 +08:00
Bengt Lüers 823cfcac57 Correct Node.js' spelling, link Git and GNOME Keyring 2014-08-03 16:06:18 +02:00
Nathan Sobo de6ccd8c08 Merge pull request #3146 from atom/ns-latency
Improve cursor movement and typing latency a bit
2014-08-02 09:21:51 -07:00
Ben Ogle 2135d3be83 Update statusbar to add toggle 2014-08-01 10:22:14 -07:00
Nathan Sobo 1c3720c160 Upgrade keybinding-resolver for spec fix 2014-07-31 15:23:58 -06:00
Nathan Sobo 6c72b13adc Upgrade keymap to avoid temp objects in keystrokeForKeyboardEvent 2014-07-31 15:21:37 -06:00
Kevin Sawicki 1404904d24 Upgrade to language-gfm@0.45 2014-07-31 14:15:01 -07:00
Nathan Sobo db243936b4 Update emissary for Emitter::emit optimization 2014-07-31 15:11:25 -06:00
Nathan Sobo 6e72627e9e Stop propagation of keydown/textInput events to prevent React handler
React's global synthetic event handler is somewhat expensive. This
prevents it from being invoked on every keystroke, saving ~1ms.
2014-07-31 15:11:06 -06:00
Kevin Sawicki 3d36ba7ecc Upgrade to scrollbar-style 1.0.2 2014-07-31 13:30:27 -07:00
Kevin Sawicki a7c0d6073f Upgrade to markdown-preview@0.95 2014-07-31 13:24:18 -07:00
Kevin Sawicki f25b468272 Upgrade to apm 0.88 2014-07-31 13:07:44 -07:00
Kevin Sawicki 2d0fb8ee6b Upgrade to incompatible-packages@0.5 2014-07-31 09:19:15 -07:00
Kevin Sawicki d875becc7a Upgrade to snippets@0.51 2014-07-31 09:06:38 -07:00
Kevin Sawicki cb72af63fd Upgrade to language-yaml@0.14 2014-07-31 08:57:09 -07:00
Kevin Sawicki f7187f1d5a Spy on atom.inDevMode() 2014-07-31 08:42:31 -07:00
Kevin Sawicki 700acdc5a2 Upgrade to incompatible-packages@0.4 2014-07-31 08:37:18 -07:00
Kevin Sawicki 18016ae9df 💄 Use unless instead of if not 2014-07-31 08:33:36 -07:00
Kevin Sawicki a30faa5bea Merge pull request #3139 from maschs/ms-incompatibleModulesDev
In devmode do not load incompatible modules from cache
2014-07-31 08:32:58 -07:00
Kevin Sawicki 05a113bb7a Merge pull request #3120 from atom/ks-remove-vendored-dlls
Remove vendored dlls
2014-07-31 08:32:53 -07:00
Kevin Sawicki f5d4ece9cd Remove vendored dlls
These are now provided by atom-shell
2014-07-31 08:20:33 -07:00
Cheng Zhao 3bda37c56c Upgrade to atom-shell@0.15.1 2014-07-31 23:19:50 +08:00
Maximilian Schüßler 62b52cb70a In devmode do not load incompatible from cache 2014-07-31 16:24:29 +02:00
Kevin Sawicki a4fe594441 Upgrade to apm 0.87 2014-07-30 17:42:32 -07:00
Kevin Sawicki 9d0e46126b Upgrade to language-coffee-script@0.28 2014-07-30 16:24:54 -07:00
Kevin Sawicki cb1bb4a691 Upgrade to apm 0.86 2014-07-30 10:55:18 -07:00
Kevin Sawicki d3a24c3749 Upgrade to runas 1.0.1 2014-07-30 10:54:23 -07:00
Kevin Sawicki 092849835e Upgrade to pathwatcher 2.0.6 2014-07-30 10:49:45 -07:00
Nathan Sobo b24ade4de5 Upgrade to React 0.11.1 2014-07-29 21:26:21 -06:00
Nathan Sobo 0f77a2eef9 Only unmount ReactEditorView's component before removing if its mounted
Fixes #3108

Unmounting the component the first time can cause a focusout event,
which leads to a redundant removal and an attempt to unmount again. This
protects against that.
2014-07-29 20:02:01 -06:00
Kevin Sawicki 662c2fc9d3 Upgrade to apm 0.85 2014-07-29 17:22:13 -07:00
Kevin Sawicki 510b1a7068 Upgrade to symbols-view@0.63 2014-07-29 17:22:13 -07:00
Kevin Sawicki c4f9914df6 Upgrade to scrollbar-style 1.0.1 2014-07-29 17:22:13 -07:00
Kevin Sawicki 2140ce3beb Upgrade to pathwatcher 2.0.5 2014-07-29 17:22:13 -07:00
Kevin Sawicki a597bca75e Upgrade to oniguruma 3.0.3 2014-07-29 17:22:12 -07:00
Kevin Sawicki 2895aae121 Upgrade to spell-check@0.40 2014-07-29 17:22:12 -07:00
Kevin Sawicki 4e20d93f03 Upgrade to oniguruma 3.0.2 2014-07-29 17:22:12 -07:00
Kevin Sawicki 1cc4e2e045 Upgrade to nslog@1.0.1 2014-07-29 17:22:12 -07:00
Kevin Sawicki 9fb427c468 Upgrade to git-utils 2.1.3 2014-07-29 17:22:12 -07:00
Nathan Sobo a9bd061144 Un-f 2014-07-29 16:52:21 -06:00
Nathan Sobo 0736b28abf Merge pull request #3102 from dmnd/export-atom-react
Export Atom's version of React and Reactionary
2014-07-29 15:43:53 -06:00
Ben Ogle 9ac5b67b6e Merge pull request #3121 from atom/bo-style-mini
Style mini editors
2014-07-29 13:39:49 -07:00
Ben Ogle 25601d691d Pull the mini editor styles out from react rule 2014-07-29 13:07:07 -07:00
Ben Ogle 0d1c11764b Upgrade dark-ui theme for new variable 2014-07-29 12:54:49 -07:00
Ben Ogle 729ff461f1 Upgrade settings-view for mini editor changes 2014-07-29 12:46:01 -07:00
Ben Ogle 0360a1918c Upgrade atom-light-ui for mini editor fixes 2014-07-29 12:33:01 -07:00
Ben Ogle 23f21bcda2 Style the mini editors for a constant height
Adds an @input-font-size variable.
2014-07-29 12:31:34 -07:00
Ben Ogle 800d65e3de Absolutify the placeholder text in mini editors.
Fixes #3118
2014-07-29 12:19:16 -07:00
Ben Ogle 5ce9b3ac55 Upgrade solarized syntax themes for scala support 2014-07-29 10:37:11 -07:00
Kevin Sawicki f86191dff8 Upgrade to incompatible-packages@0.3 2014-07-29 09:26:38 -07:00
Cheng Zhao 412793697f Merge pull request #3112 from atom/chrome36
Upgrade to Chrome36
2014-07-29 14:44:34 +08:00
Cheng Zhao 3274ef9fb9 Upgrade to atom-shell@0.15.0 2014-07-29 14:27:32 +08:00
Nathan Sobo f8e2231dfc Increase overdraw margin to avoid intermittent full screen repaints
On Chromium 35, the screen seems to be full-screen painting on a Cinema
Display every few frames, causing frame rates to drop from 60 to 30 when
autoscrolling with the cursor. Increasing the overdraw avoids this.
2014-07-28 21:57:06 -06:00
Nathan Sobo 837eaccd16 Remove extra nextAnimationFrame call 2014-07-28 21:53:18 -06:00
Nathan Sobo 4f3570b56b Merge pull request #3106 from atom/ns-react-css-font-styling
Apply React editor font styles via CSS instead of inline styles
2014-07-28 21:08:51 -06:00
Nathan Sobo 8918a42b3b Merge pull request #3104 from dmnd/react-dev-mode
Show detailed React errors/warnings in devMode
2014-07-28 21:02:11 -06:00
Nathan Sobo bd77a02207 Measure DOM in EditorComponent when a stylesheet is updated 2014-07-28 21:00:15 -06:00
Nathan Sobo eebbb99fc8 Handle editor font config options with a global stylesheet
Previously, each editor observed font-related config values on its own
and applied inline styles to honor them. This made it difficult to style
the editor like a normal element with CSS.

Moving this to a global stylesheet that targets editors via the .editor
selector means that the font size setting can be overridden in specific
contexts, such as when using mini editors.
2014-07-28 21:00:15 -06:00
Nathan Sobo 2b27c0b440 Only handle stylesheet changes after initial measurement 2014-07-28 20:59:28 -06:00
Nathan Sobo 8e69b0c4a0 Base font styling on the computed style of the editor element
Previously, font styling was always explicitly assigned via the config.
This commit is the first step in basing the font styling of the editor
on the styles assigned via CSS. This will allow the editor's
font-family, font-size, and line-height to be assigned via CSS just like
they are for any other element, which will make it easier to style mini
editors.

We still need to switch the font settings to adjust a global stylesheet
rather than updating inline styles on each editor individually.
2014-07-28 20:59:28 -06:00
Kevin Sawicki 532744b4eb 📝 Mention installed apm command 2014-07-28 18:49:53 -07:00
Kevin Sawicki ddd89ed6d1 📝 Remove step that is only is supported on Mac 2014-07-28 18:49:03 -07:00
Kevin Sawicki 5a53e5b96a 📝 Mark mdkeb step as optional 2014-07-28 18:48:15 -07:00
Kevin Sawicki 69f84f7e6d Merge pull request #2680 from Bengt/patch-1
individual descriptions for instructions
2014-07-28 18:46:51 -07:00
Kevin Sawicki e2c65345ab Upgrade to language-javascript@0.39 2014-07-28 18:43:32 -07:00
Bengt Lüers f47bcddf10 individual descriptions for instructions 2014-07-29 02:33:02 +02:00
Kevin Sawicki 5e19230809 Upgrade to language-javascript@0.38 2014-07-28 17:31:46 -07:00
Kevin Sawicki f8961fbd53 Upgrade to autocomplete@0.29 2014-07-28 17:19:45 -07:00
Kevin Sawicki bef750cb1f Upgrade to fs-plus 2.2.6 2014-07-28 17:11:21 -07:00
Kevin Sawicki 4e2f06aec7 Merge pull request #3098 from Bengt/patch-2
Update linux.md
2014-07-28 16:51:09 -07:00
Kevin Sawicki 02c47ba1ea 💄 2014-07-28 16:49:08 -07:00
Kevin Sawicki f6cb59be47 Merge pull request #3062 from ehuss/win32-sourcemaps
Fix source maps for CoffeeScript on Windows.
2014-07-28 16:44:06 -07:00
Kevin Sawicki 397871a012 Upgrade to language-gfm@0.44 2014-07-28 16:04:11 -07:00
Kevin Sawicki 10239e0466 Upgrade to fs-plus 2.2.5 2014-07-28 16:03:18 -07:00
Kevin Sawicki 69ef99481b Upgrade to language-source@0.8 2014-07-28 15:37:59 -07:00
Kevin Sawicki fc20de82ce Downgrade to tree-view@0.112 2014-07-28 15:34:41 -07:00
Kevin Sawicki 0232da27f5 Downgrade to symbols-view@0.62 2014-07-28 15:30:42 -07:00
Kevin Sawicki ba452e2400 Downgrade to 0.39.0 2014-07-28 15:25:07 -07:00
Kevin Sawicki 9b5b8e7528 Downgrade to snippets@0.50 2014-07-28 15:18:27 -07:00
Kevin Sawicki 6e65947d54 Downgrade to link@0.25 2014-07-28 15:12:47 -07:00
Kevin Sawicki 93c5e241f3 Downgrade to markdown-preview@0.94 2014-07-28 15:10:32 -07:00
Kevin Sawicki e0c61136a6 Upgrade to dev-live-reload@0.33 2014-07-28 15:07:50 -07:00
Kevin Sawicki c5cc13ddb3 Downgrade to bracket-matcher@0.51 2014-07-28 15:03:54 -07:00
Kevin Sawicki fd47c89f9d Add trailing .0 for consistency 2014-07-28 15:01:25 -07:00
Kevin Sawicki 34ad902cb3 Downgrade to archive-view 0.35 2014-07-28 15:00:52 -07:00
Kevin Sawicki 9678418e56 Downgrade to apm 0.84 2014-07-28 14:58:49 -07:00
Kevin Sawicki 691d6c3b5f Merge pull request #3032 from atom/chrome35
Upgrade to Chrome 35
2014-07-28 14:52:34 -07:00
Kevin Sawicki 431555195a Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-28 14:40:14 -07:00
Kevin Sawicki b0aa5e6c88 Prepare 0.121 2014-07-28 14:36:07 -07:00
Nathan Sobo 7f882b00f5 Don't allow updates to be requested for unmounted components
In 444c18be34, I stopped polling the DOM
when an update was pending to prevent delay of the next animation frame.

Unfortunately, we rely on synchronously polling the DOM when an editor
view is attached to perform the initial measurement of the default char
width, which is required to position the wrap guide.

In componentWillMount, observing the config was requesting an update,
causing us to skip this synchronous update at attachment time and
position the wrap guide wrong.

This prevents update requests that occur before mount from pausing the
polling that we perform on attachment, restoring correct function to the
wrap guide.
2014-07-28 14:42:35 -06:00
Kevin Sawicki 3af3a0d27e Upgrade to incompatible-packages@0.2 2014-07-28 10:25:08 -07:00
Kevin Sawicki 7e415ffdb7 Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-28 09:02:38 -07:00
Desmond Brand 65ffd21574 Show detailed React errors/warnings in devMode
Fixes #3099.

React development mode has a lot of useful warnings and exceptions. These don't
show up in production mode. This change puts React into dev mode when Atom is
run via `atom --dev`.
2014-07-27 16:10:47 -07:00
Nathan Sobo 393552a4b6 Take cursors off the GPU and position them on the lines layer
The compositor overhead is not worth it.
2014-07-27 11:47:33 -06:00
Nathan Sobo 444c18be34 Stop polling when an update is pending 2014-07-27 11:46:22 -06:00
Nathan Sobo dca096b8e3 Use requestAnimationFrame to batch updates in Chrome 35
In Chrome 31, setImmediate was yielding better behavior. But now Chrome
35 seems to behave more smoothly when we use requestAnimationFrame, and
the delay for keystrokes is non-existent.
2014-07-27 11:46:22 -06:00
Nathan Sobo 57a03e7884 Kill dummy highlight component now that Chrome 35 fixes render artifact
Previously, removing the last highlight caused rendering artifacts.
Chrome 35 no longer exhibits this problem so we can remove this
workaround.
2014-07-27 11:46:22 -06:00
Cheng Zhao fe1819f587 Revert "Don't start crash reporter on Windows."
This reverts commit 684f15ab89.
2014-07-27 11:07:36 +08:00
Cheng Zhao aa157af93e Upgrade to atom-shell@0.14.3 2014-07-27 11:07:07 +08:00
Desmond Brand 0e58e03de7 Export Atom's version of React and Reactionary
Fixes #3101 and works around facebook/react#1939.
2014-07-26 17:49:51 -07:00
Bengt Lüers e011c80b07 Update linux.md
Add step for checking out the latest release by git tag.
2014-07-26 18:44:38 +02:00
Kevin Sawicki 9dc59b9807 💄 2014-07-25 17:12:03 -07:00
Kevin Sawicki 15689ebfb5 📝 2014-07-25 17:11:33 -07:00
Kevin Sawicki 6250419fcb containsNativeModule -> isNativeModule 2014-07-25 17:09:46 -07:00
Kevin Sawicki 70621afe62 📝 2014-07-25 17:08:10 -07:00
Kevin Sawicki 6f29710d88 Upgrade to incompatible-packages@0.1 2014-07-25 17:00:17 -07:00
Kevin Sawicki 7b07d7116b Store string in local storage 2014-07-25 16:06:35 -07:00
Kevin Sawicki f175086865 Always return boolean from Package::isCompatible 2014-07-25 15:56:09 -07:00
Kevin Sawicki c6071a9802 Don't throw incompatible error, log instead 2014-07-25 15:49:34 -07:00
Kevin Sawicki ac138c1dc8 Throw error when activating incompatible package 2014-07-25 15:46:35 -07:00
Kevin Sawicki 85b7261d31 Don't store incompatible packages in custom object
The info is on the Package object itself to the loaded/activated
packages can just be iterated over.
2014-07-25 15:36:09 -07:00
Kevin Sawicki d47348e8f9 Cache incompatible modules in local storage 2014-07-25 15:34:03 -07:00
Kevin Sawicki 56df7bdbe3 Add version to package 2014-07-25 15:23:36 -07:00
Kevin Sawicki 1ea909d4db Check installed packages for working native modules
Test require each native module in each installed package to make sure
it can be required successfully in Atom.
2014-07-25 15:19:16 -07:00
Kevin Sawicki caa6f9b06e Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-25 09:19:44 -07:00
Cheng Zhao 684f15ab89 Don't start crash reporter on Windows.
It is causing crashes on Windows, before it is fixed in atom-shell we
temporarily disable the crash reporter.
2014-07-25 23:28:29 +08:00
Cheng Zhao 4238e031da Upgrade to atom-shell@0.14.2 2014-07-25 23:27:03 +08:00
Nathan Sobo a3d82e9414 Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-24 18:14:11 -07:00
Nathan Sobo 7515fd94ba Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-24 17:40:37 -07:00
Kevin Sawicki 8ad8be2583 Merge branch 'master' into chrome35 2014-07-24 14:53:24 -07:00
Kevin Sawicki b922f01257 Merge branch 'master' into chrome35
Conflicts:
	package.json
2014-07-24 14:17:17 -07:00
Cheng Zhao 83ad1fe8af Upgrade to atom-shell@0.14.1 2014-07-24 23:37:00 +08:00
Cheng Zhao dcbf730129 Merge branch 'master' into chrome35
Conflicts:
	apm/package.json
	package.json
2014-07-24 17:17:35 +08:00
Cheng Zhao 39868a2330 Make atom.setSize synchronous. 2014-07-24 16:29:20 +08:00
Eric Huss 772726ca96 Fix source maps for CoffeeScript on Windows.
The sourceURL needs to be a URL, not a file path.
2014-07-23 16:49:53 -07:00
Kevin Sawicki 5f7f5b5367 Merge branch 'master' into chrome35 2014-07-22 17:56:24 -07:00
Kevin Sawicki 683f8e06f8 Upgrade to underscore-plus@1.5.1 2014-07-22 15:57:49 -07:00
Kevin Sawicki bc4173f856 Remove logging of screen lines in spec 2014-07-22 14:51:13 -07:00
Kevin Sawicki 8099c46c8e Use OnigRegExp::testSync 2014-07-22 14:38:08 -07:00
Kevin Sawicki bbfd9b8178 Use testSync instead of test 2014-07-22 14:08:40 -07:00
Kevin Sawicki 6d34de68ac Add Sync suffix to oniguruma methods 2014-07-22 13:31:52 -07:00
Kevin Sawicki 10fb929a1b Upgrade to first-mate@2.0.1 2014-07-22 13:24:39 -07:00
Cheng Zhao 52e049bedc Merge branch 'master' into chrome35
Conflicts:
	apm/package.json
	package.json
2014-07-22 10:13:40 +08:00
Cheng Zhao a6640f6da7 Upgrade to atom-shell@0.14.0 2014-07-22 09:58:53 +08:00
Cheng Zhao eeadd823e6 Upgrade to atom-keymap@1.0.0 2014-07-21 09:40:13 +08:00
Cheng Zhao 8a5bd357cd Upgrade to text-buffer@3.0.0 2014-07-21 09:39:48 +08:00
Cheng Zhao 42621805a7 Upgrade to link@1.0.0 2014-07-18 23:10:56 +08:00
Cheng Zhao fed55b8896 Upgrade to bracket-matcher@1.0.0 2014-07-18 22:50:31 +08:00
Cheng Zhao 73daa4bb74 Upgrade to scrollbar-style@1.0.0 2014-07-18 22:24:03 +08:00
Cheng Zhao 92546c60b3 Upgrade to scandal@1.0.0 2014-07-18 22:18:11 +08:00
Cheng Zhao 2fa91e5dfb Upgrade to frist-mate@2.0.0 2014-07-18 22:06:12 +08:00
Cheng Zhao aac0913b8b Upgrade to tree-view@1.0.0 2014-07-18 21:50:06 +08:00
Cheng Zhao acc75ca859 Upgrade to symbols-view@1.0.0 2014-07-18 21:40:52 +08:00
Cheng Zhao 8eb4e13df8 Upgrade to spell-check@1.0.0 2014-07-18 21:07:47 +08:00
Cheng Zhao 087d9c1da6 Upgrade to snippets@1.0.0 2014-07-18 14:54:03 +08:00
Cheng Zhao 18336076a8 Upgrade to markdown-preview@1.0.0 2014-07-18 14:46:46 +08:00
Cheng Zhao 7fee5f5f25 Upgrade to dev-live-reload@1.0.0 2014-07-18 14:37:16 +08:00
Cheng Zhao c2f04a00d2 Upgrade to archive-view@1.0.0 2014-07-18 14:28:09 +08:00
Cheng Zhao cc927123f9 Upgrade to nslog@1.0.0 2014-07-18 11:28:03 +08:00
Cheng Zhao 97b426429b Upgrade to oniguruma@3.0.0 2014-07-18 10:16:17 +08:00
Cheng Zhao 3686530943 Upgrade to pathwatcher@2.0.2 2014-07-18 10:15:35 +08:00
Cheng Zhao 621ef450da Upgrade to runas@1.0.0 2014-07-18 10:14:56 +08:00
Cheng Zhao 1e08bcd634 Upgrade to git-utils@2.0 2014-07-18 10:14:14 +08:00
Cheng Zhao ede468d4c9 Upgrade to apm 1.0.0 2014-07-18 10:09:45 +08:00
45 arquivos alterados com 2162 adições e 795 exclusões
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.83.0"
"atom-package-manager": "0.88.0"
}
}
+1 -1
Ver Arquivo
@@ -33,7 +33,7 @@
"read-package-json": "1.1.8",
"request": "~2.27.0",
"rimraf": "~2.2.2",
"runas": "0.5.x",
"runas": "~1.0.1",
"underscore-plus": "1.x",
"unzip": "~0.1.9",
"vm-compatibility-layer": "~0.1.0"
-3
Ver Arquivo
@@ -148,9 +148,6 @@ module.exports = (grunt) ->
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
if process.platform is 'win32'
cp path.join('resources', 'win', 'msvcp100.dll'), path.join(shellAppDir, 'msvcp100.dll')
cp path.join('resources', 'win', 'msvcr100.dll'), path.join(shellAppDir, 'msvcr100.dll')
# Set up chocolatey ignore and gui files
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
+2 -2
Ver Arquivo
@@ -45,8 +45,8 @@ module.exports = (grunt) ->
strings =
CompanyName: 'GitHub, Inc.'
FileDescription: 'The hackable editor'
LegalCopyright: 'Copyright (C) 2013 GitHub, Inc. All rights reserved'
FileDescription: 'Atom'
LegalCopyright: 'Copyright (C) 2014 GitHub, Inc. All rights reserved'
ProductName: 'Atom'
ProductVersion: version
+26 -17
Ver Arquivo
@@ -6,21 +6,21 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* OS with 64-bit or 32-bit architecture
* C++ toolchain
* git
* [node.js](http://nodejs.org/download/) v0.10.x
* [npm](http://www.npmjs.org/) v1.4.x (bundled with node.js)
* [Git](http://git-scm.com/)
* [Node.js](http://nodejs.org/download/) v0.10.x
* [npm](http://www.npmjs.org/) v1.4.x (bundled with Node.js)
* `npm -v` to check the version.
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses python2.
* You might need to run this command as `sudo`, depending on how you have set up [npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* libgnome-keyring-dev
* development headers for [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring)
### Ubuntu / Debian
* `sudo apt-get install build-essential git libgnome-keyring-dev`
* Instructions for [node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
### Fedora
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
* Instructions for [node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
### Arch
* `sudo pacman -S base-devel git nodejs libgnome-keyring`
@@ -30,19 +30,28 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
If you have problems with permissions don't forget to prefix with `sudo`
```sh
git clone https://github.com/atom/atom
cd atom
script/build # Creates application at $TMPDIR/atom-build/Atom
sudo script/grunt install # Installs command to /usr/local/bin/atom
script/grunt mkdeb # Generates a .deb package at $TMPDIR/atom-build, e.g. /tmp/atom-build
```
To run `atom` and `apm` from a terminal open atom's command palette `ctrl+shift+p` and run `Window: Install Shell Commands`
Create the atom application at `$TMPDIR/atom-build/Atom`:
```sh
script/build
```
Install the `atom` and `apm` commands to `/usr/local/bin`:
```sh
sudo script/grunt install
```
Generate a `.deb` package at `$TMPDIR/atom-build`: (*optional*)
```sh
script/grunt mkdeb
```
Use the newly installed atom by restarting any running atom instances.
## Troubleshooting
### Exception: "TypeError: Unable to watch path"
If you get following error with a big traceback right after Atom starts:
@@ -69,7 +78,7 @@ See also https://github.com/atom/atom/issues/2082.
### /usr/bin/env: node: No such file or directory
If you get this notice when attempting to `script/build`, you either do not
have nodejs installed, or node isn't identified as nodejs on your machine.
have Node.js installed, or node isn't identified as Node.js on your machine.
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
your terminal may fix the issue.
+13
Ver Arquivo
@@ -66,6 +66,19 @@ If none of this works, do install Github for Windows and use its Git shell. Make
* https://github.com/TooTallNate/node-gyp/issues/297
* https://code.google.com/p/gyp/issues/detail?id=393
* `script/build` stops at installing runas with 'Failed at the runas@0.5.4 install script.'
See the next item.
* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.`
* If you're building atom with Visual Studio 2013 try executing the following
command in your Git shell and then re-run `script/build`:
```
$env:GYP_MSVS_VERSION=2013
```
* Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed.
* Do try the build command one more time, as experience shows it often works on second try in many of these cases.
+2
Ver Arquivo
@@ -25,3 +25,5 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
module.exports.View = View
module.exports.WorkspaceView = require '../src/workspace-view'
module.exports.Workspace = require '../src/workspace'
module.exports.React = require 'react-atom-fork'
module.exports.Reactionary = require 'reactionary-atom-fork'
+43 -43
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.120.0",
"version": "0.121.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,108 +17,108 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.13.3",
"atomShellVersion": "0.15.3",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^0.28.0",
"atom-keymap": "^1.0.2",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
"coffeestack": "0.7.0",
"delegato": "^1",
"emissary": "^1.2.1",
"first-mate": "^1.7.1",
"fs-plus": "^2.2.4",
"emissary": "^1.2.2",
"first-mate": "^2.0.1",
"fs-plus": "^2.2.6",
"fstream": "0.1.24",
"fuzzaldrin": "^1.1",
"git-utils": "^1.6",
"git-utils": "^2.1.3",
"grim": "0.11.0",
"guid": "0.0.10",
"jasmine-tagged": "^1.1.2",
"less-cache": "0.13.0",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "0.5.0",
"oniguruma": "^1.0.6",
"nslog": "^1.0.1",
"oniguruma": "^3.0.3",
"optimist": "0.4.0",
"pathwatcher": "^1.5",
"pathwatcher": "^2.0.6",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
"react-atom-fork": "^0.10.0",
"reactionary-atom-fork": "^0.9.0",
"runas": "0.5.4",
"scandal": "0.16.0",
"react-atom-fork": "^0.11.2",
"reactionary-atom-fork": "^1.0.0",
"runas": "1.0.1",
"scandal": "1.0.0",
"scoped-property-store": "^0.9.0",
"scrollbar-style": "^0.4.0",
"scrollbar-style": "^1.0.2",
"season": "^1.0.2",
"semver": "1.1.4",
"serializable": "^1",
"space-pen": "3.2.0",
"temp": "0.7.0",
"text-buffer": "^2.4.2",
"text-buffer": "^3.0.0",
"theorist": "^1",
"underscore-plus": "^1.5.0",
"underscore-plus": "^1.5.1",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.19.0",
"atom-dark-ui": "0.32.0",
"atom-dark-ui": "0.33.0",
"atom-light-syntax": "0.20.0",
"atom-light-ui": "0.28.0",
"atom-light-ui": "0.29.0",
"base16-tomorrow-dark-theme": "0.20.0",
"base16-tomorrow-light-theme": "0.4.0",
"solarized-dark-syntax": "0.21.0",
"solarized-light-syntax": "0.11.0",
"archive-view": "0.34.0",
"autocomplete": "0.28.0",
"solarized-dark-syntax": "0.22.0",
"solarized-light-syntax": "0.12.0",
"archive-view": "0.35.0",
"autocomplete": "0.29.0",
"autoflow": "0.17.0",
"autosave": "0.14.0",
"background-tips": "0.15.0",
"bookmarks": "0.27.0",
"bracket-matcher": "0.50.0",
"bracket-matcher": "0.51.0",
"command-palette": "0.24.0",
"deprecation-cop": "0.7.0",
"dev-live-reload": "0.32.0",
"dev-live-reload": "0.33.0",
"exception-reporting": "0.19.0",
"feedback": "0.33.0",
"find-and-replace": "0.127.0",
"find-and-replace": "0.128.0",
"fuzzy-finder": "0.57.0",
"git-diff": "0.37.0",
"go-to-line": "0.23.0",
"grammar-selector": "0.27.0",
"image-view": "0.36.0",
"keybinding-resolver": "0.18.0",
"link": "0.24.0",
"markdown-preview": "0.93.0",
"incompatible-packages": "0.5.0",
"keybinding-resolver": "0.19.0",
"link": "0.25.0",
"markdown-preview": "0.95.0",
"metrics": "0.33.0",
"open-on-github": "0.29.0",
"package-generator": "0.31.0",
"release-notes": "0.36.0",
"settings-view": "0.136.0",
"snippets": "0.49.0",
"spell-check": "0.38.0",
"status-bar": "0.41.0",
"settings-view": "0.138.0",
"snippets": "0.51.0",
"spell-check": "0.40.0",
"status-bar": "0.42.0",
"styleguide": "0.29.0",
"symbols-view": "0.61.0",
"tabs": "0.48.0",
"symbols-view": "0.63.0",
"tabs": "0.49.0",
"timecop": "0.22.0",
"tree-view": "0.111.0",
"tree-view": "0.112.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.17.0",
"whitespace": "0.25.0",
"wrap-guide": "0.21.0",
"language-c": "0.26.0",
"language-coffee-script": "0.27.0",
"language-coffee-script": "0.29.0",
"language-css": "0.17.0",
"language-gfm": "0.43.0",
"language-gfm": "0.46.0",
"language-git": "0.9.0",
"language-go": "0.16.0",
"language-html": "0.22.0",
"language-hyperlink": "0.10.0",
"language-java": "0.11.0",
"language-javascript": "0.37.0",
"language-javascript": "0.39.0",
"language-json": "0.8.0",
"language-less": "0.13.0",
"language-make": "0.10.0",
@@ -127,17 +127,17 @@
"language-php": "0.15.0",
"language-property-list": "0.7.0",
"language-python": "0.18.0",
"language-ruby": "0.33.0",
"language-ruby": "0.34.0",
"language-ruby-on-rails": "0.15.0",
"language-sass": "0.14.0",
"language-shellscript": "0.8.0",
"language-source": "0.7.0",
"language-source": "0.8.0",
"language-sql": "0.9.0",
"language-text": "0.6.0",
"language-todo": "0.10.0",
"language-toml": "0.12.0",
"language-xml": "0.17.0",
"language-yaml": "0.13.0"
"language-yaml": "0.14.0"
},
"private": true,
"scripts": {
Arquivo binário não exibido.
Arquivo binário não exibido.
+8
Ver Arquivo
@@ -1167,3 +1167,11 @@ describe "DisplayBuffer", ->
expect(displayBuffer.getScrollWidth()).toBe 10 * 63 + operatorWidth * 2 + cursorWidth
expect(changedSpy.callCount).toBe 1
describe "::lineNumbersForScreenRows(startRow, endRow)", ->
it "returns the line numbers for the given screen row range, inclusive of the endRow", ->
displayBuffer.createFold(4, 7)
displayBuffer.setEditorWidthInChars(30)
displayBuffer.setSoftWrap(true)
expect(displayBuffer.lineNumbersForScreenRows(6, 11)).toEqual ['4.2', '5', '9', '9.1', '9.2', '10']
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+581
Ver Arquivo
@@ -0,0 +1,581 @@
TextBuffer = require 'text-buffer'
_ = require 'underscore-plus'
EditorPresenter = require '../src/editor-presenter'
Editor = require '../src/editor'
describe "DisplayStateManager", ->
[buffer, editor, presenter] = []
beforeEach ->
@addMatchers(toHaveValues: ToHaveValuesMatcher)
spyOn(EditorPresenter::, 'getContentTileSize').andReturn 5
spyOn(EditorPresenter::, 'getGutterTileSize').andReturn 5
buffer = new TextBuffer(filePath: atom.project.resolve('sample.js'))
buffer.loadSync()
buffer.insert([12, 3], '\n' + buffer.getText()) # repeat text so we have more lines
editor = new Editor({buffer})
editor.setLineHeightInPixels(10)
editor.setDefaultCharWidth(10)
editor.setHeight(100)
editor.setWidth(500)
presenter = new EditorPresenter(editor)
afterEach ->
editor.destroy()
describe "scrollPosition", ->
it "maintains the scrollTop and scrollLeft as top-level presenter properties", ->
expect(presenter.scrollTop).toBe 0
expect(presenter.scrollLeft).toBe 0
editor.setScrollTop(20)
editor.setScrollLeft(30)
expect(presenter.scrollTop).toBe 20
expect(presenter.scrollLeft).toBe 30
describe "tiles", ->
describe "initial state", ->
it "renders tiles that overlap the visible row range", ->
expect(presenter).toHaveValues
content:
tiles:
0:
startRow: 0
top: 0
width: editor.getWidth()
height: 5 * 10
lineHeightInPixels: 10
lines: editor.linesForScreenRows(0, 4)
5:
startRow: 5
top: 50
width: editor.getWidth()
height: 5 * 10
lineHeightInPixels: 10
lines: editor.linesForScreenRows(5, 9)
10:
startRow: 10
top: 100
width: editor.getWidth()
height: 5 * 10
lineHeightInPixels: 10
lines: editor.linesForScreenRows(10, 14)
gutter:
tiles:
0:
startRow: 0
top: 0
height: 5 * 10
lineHeightInPixels: 10
lineNumbers: editor.lineNumbersForScreenRows(0, 4)
5:
startRow: 5
top: 50
height: 5 * 10
lineHeightInPixels: 10
lineNumbers: editor.lineNumbersForScreenRows(5, 9)
10:
startRow: 10
top: 100
height: 5 * 10
lineHeightInPixels: 10
lineNumbers: editor.lineNumbersForScreenRows(10, 14)
it "renders a dummy gutter tile to maintain the proper gutter width", ->
expect(presenter.gutter).toHaveValues
dummyTile:
dummy: true
maxLineNumberDigits: 2
it "assigns the backgroundColor on the content and gutter tiles, favoring the gutter's background color if it's assigned", ->
editor.setBackgroundColor('#ff0')
presenter = new EditorPresenter(editor)
expect(presenter).toHaveValues
content:
tiles:
0: backgroundColor: '#ff0'
5: backgroundColor: '#ff0'
10: backgroundColor: '#ff0'
gutter:
tiles:
0: backgroundColor: '#ff0'
5: backgroundColor: '#ff0'
10: backgroundColor: '#ff0'
editor.setGutterBackgroundColor('#a00')
presenter = new EditorPresenter(editor)
expect(presenter).toHaveValues
content:
tiles:
0: backgroundColor: '#ff0'
5: backgroundColor: '#ff0'
10: backgroundColor: '#ff0'
gutter:
tiles:
0: backgroundColor: '#a00'
5: backgroundColor: '#a00'
10: backgroundColor: '#a00'
describe "when the width is changed", ->
it "updates the line tiles with the new width", ->
editor.setWidth(700)
expect(presenter.content.tiles).toHaveValues
0:
width: 700
5:
width: 700
10:
width: 700
describe "when the height is changed", ->
it "updates the rendered tiles to reflect the change", ->
editor.setHeight(160)
expect(presenter).toHaveValues
content:
tiles:
0:
startRow: 0
top: 0
5:
startRow: 5
top: 50
10:
startRow: 10
top: 100
15:
startRow: 15
top: 150
gutter:
tiles:
0:
startRow: 0
top: 0
5:
startRow: 5
top: 50
10:
startRow: 10
top: 100
15:
startRow: 15
top: 150
editor.setHeight(70)
expect(presenter).toHaveValues
content:
tiles:
0:
startRow: 0
top: 0
5:
startRow: 5
top: 50
gutter:
tiles:
0:
startRow: 0
top: 0
5:
startRow: 5
top: 50
describe "when lineHeightInPixels changes", ->
it "updates the rendered tiles to reflect the change", ->
editor.setScrollTop(10)
editor.setLineHeightInPixels(7)
expect(presenter).toHaveValues
content:
tiles:
0:
startRow: 0
top: 0 - 10
height: 5 * 7
lineHeightInPixels: 7
5:
startRow: 5
top: 7 * 5 - 10
height: 5 * 7
lineHeightInPixels: 7
10:
startRow: 10
top: 7 * 10 - 10
height: 5 * 7
lineHeightInPixels: 7
15:
startRow: 15
top: 7 * 15 - 10
height: 5 * 7
lineHeightInPixels: 7
gutter:
tiles:
0:
startRow: 0
top: 0 - 10
height: 5 * 7
lineHeightInPixels: 7
5:
startRow: 5
top: 7 * 5 - 10
height: 5 * 7
lineHeightInPixels: 7
10:
startRow: 10
top: 7 * 10 - 10
height: 5 * 7
lineHeightInPixels: 7
15:
startRow: 15
top: 7 * 15 - 10
height: 5 * 7
lineHeightInPixels: 7
describe "when scrollTop changes", ->
it "updates the rendered tiles to reflect the change", ->
editor.setScrollTop(20)
expect(presenter).toHaveValues
content:tiles:
0:
top: -20
lines: editor.linesForScreenRows(0, 4)
5:
top: 30
lines: editor.linesForScreenRows(5, 9)
10:
top: 80
lines: editor.linesForScreenRows(10, 14)
gutter:tiles:
0:
top: -20
lineNumbers: editor.lineNumbersForScreenRows(0, 4)
5:
top: 30
lineNumbers: editor.lineNumbersForScreenRows(5, 9)
10:
top: 80
lineNumbers: editor.lineNumbersForScreenRows(10, 14)
editor.setScrollTop(70)
expect(presenter.content.tiles).toHaveValues
5:
top: -20
lines: editor.linesForScreenRows(5, 9)
10:
top: 30
lines: editor.linesForScreenRows(10, 14)
15:
top: 80
lines: editor.linesForScreenRows(15, 19)
describe "when scrollLeft changes", ->
it "updates the rendered tiles to reflect the change", ->
expect(presenter.content.tiles).toHaveValues
0:
left: 0
5
left: 0
10:
left: 0
editor.setScrollLeft(30)
expect(presenter.content.tiles).toHaveValues
0:
left: -30
5:
left: -30
10:
left: -30
describe "when the backgroundColor or gutterBackgroundColor change", ->
it "updates the backgroundColor of the tiles", ->
editor.setBackgroundColor('#abe')
expect(presenter).toHaveValues
content:
tiles:
0: backgroundColor: '#abe'
5: backgroundColor: '#abe'
10: backgroundColor: '#abe'
gutter:
tiles:
0: backgroundColor: '#abe'
5: backgroundColor: '#abe'
10: backgroundColor: '#abe'
editor.setGutterBackgroundColor('#dad')
expect(presenter).toHaveValues
content:
tiles:
0: backgroundColor: '#abe'
5: backgroundColor: '#abe'
10: backgroundColor: '#abe'
gutter:
tiles:
0: backgroundColor: '#dad'
5: backgroundColor: '#dad'
10: backgroundColor: '#dad'
describe "lines", ->
describe "initial state", ->
it "breaks lines into tiles", ->
expect(presenter.content.tiles).toHaveValues
0:
startRow: 0
lines: editor.linesForScreenRows(0, 4)
5:
startRow: 5
lines: editor.linesForScreenRows(5, 9)
10:
startRow: 10
lines: editor.linesForScreenRows(10, 14)
describe "when the screen lines change", ->
it "updates the lines in the tiles to reflect the change", ->
buffer.setTextInRange([[3, 5], [7, 0]], "a\nb\nc\nd")
expect(presenter.content.tiles).toHaveValues
0:
startRow: 0
lines: editor.linesForScreenRows(0, 4)
5:
startRow: 5
lines: editor.linesForScreenRows(5, 9)
10
startRow: 10
lines: editor.linesForScreenRows(10, 14)
describe "line decorations", ->
marker = null
beforeEach ->
marker = editor.markBufferRange([[3, 4], [5, 6]], invalidate: 'touch')
describe "initial state", ->
it "renders existing line decorations on the appropriate lines", ->
decoration = editor.decorateMarker(marker, type: 'line', class: 'test')
presenter = new EditorPresenter(editor)
decorationsById = {}
decorationsById[decoration.id] = decoration.getParams()
expect(presenter.content.tiles).toHaveValues
0:
lineDecorations:
3: decorationsById
4: decorationsById
5:
lineDecorations:
5: decorationsById
describe "when a line decoration is added, updated, invalidated, or removed", ->
it "updates the presented line decorations accordingly", ->
decoration = editor.decorateMarker(marker, type: 'line', class: 'test')
decorationsById = {}
decorationsById[decoration.id] = decoration.getParams()
expect(presenter.content.tiles).toHaveValues
0:
lineDecorations:
3: decorationsById
4: decorationsById
5:
lineDecorations:
5: decorationsById
marker.setBufferRange([[8, 4], [10, 6]])
expect(presenter.content.tiles).toHaveValues
0:
lineDecorations:
3: null
4: null
5:
lineDecorations:
5: null
8: decorationsById
9: decorationsById
10:
lineDecorations:
10: decorationsById
buffer.insert([8, 5], 'invalidate marker')
expect(presenter.content.tiles).toHaveValues
5:
lineDecorations:
8: null
9: null
10:
lineDecorations:
10: null
buffer.undo()
expect(presenter.content.tiles).toHaveValues
5:
lineDecorations:
8: decorationsById
9: decorationsById
10:
lineDecorations:
10: decorationsById
marker.destroy()
expect(presenter.content.tiles).toHaveValues
5:
lineDecorations:
8: null
9: null
10:
lineDecorations:
10: null
describe "line numbers", ->
describe "when the screen lines change", ->
it "updates the line numbers to reflect the change", ->
editor.createFold(4, 7)
expect(presenter.gutter.tiles).toHaveValues
0:
lineNumbers: editor.lineNumbersForScreenRows(0, 4)
5:
lineNumbers: editor.lineNumbersForScreenRows(5, 9)
10:
lineNumbers: editor.lineNumbersForScreenRows(10, 14)
it "updates the maxLineNumberDigits if necessary", ->
buffer.setText('')
expect(presenter.gutter.dummyTile.maxLineNumberDigits).toBe 1
expect(presenter.gutter.tiles).toHaveValues
0:
maxLineNumberDigits: 1
buffer.setText([0..10].join('\n'))
expect(presenter.gutter.dummyTile.maxLineNumberDigits).toBe 2
expect(presenter.gutter.tiles).toHaveValues
0:
maxLineNumberDigits: 2
5:
maxLineNumberDigits: 2
10:
maxLineNumberDigits: 2
buffer.delete([[8, 0], [Infinity, 0]])
expect(presenter.gutter.dummyTile.maxLineNumberDigits).toBe 1
expect(presenter.gutter.tiles).toHaveValues
0:
maxLineNumberDigits: 1
5:
maxLineNumberDigits: 1
describe "line number decorations", ->
marker = null
beforeEach ->
marker = editor.markBufferRange([[3, 4], [5, 6]], invalidate: 'touch')
describe "initial state", ->
it "renders existing line number decorations on the appropriate lines", ->
decoration = editor.decorateMarker(marker, type: 'gutter', class: 'test')
presenter = new EditorPresenter(editor)
decorationsById = {}
decorationsById[decoration.id] = decoration.getParams()
expect(presenter.gutter.tiles).toHaveValues
0:
lineNumberDecorations:
3: decorationsById
4: decorationsById
5:
lineNumberDecorations:
5: decorationsById
describe "when a line number decorations is added, updated, invalidated, or removed", ->
it "updates the presented line decorations accordingly", ->
decoration = editor.decorateMarker(marker, type: 'gutter', class: 'test')
decorationsById = {}
decorationsById[decoration.id] = decoration.getParams()
expect(presenter.gutter.tiles).toHaveValues
0:
lineNumberDecorations:
3: decorationsById
4: decorationsById
5:
lineNumberDecorations:
5: decorationsById
marker.setBufferRange([[8, 4], [10, 6]])
expect(presenter.gutter.tiles).toHaveValues
0:
lineNumberDecorations:
3: null
4: null
5:
lineNumberDecorations:
5: null
8: decorationsById
9: decorationsById
10:
lineNumberDecorations:
10: decorationsById
buffer.insert([8, 5], 'invalidate marker')
expect(presenter.gutter.tiles).toHaveValues
5:
lineNumberDecorations:
8: null
9: null
10:
lineNumberDecorations:
10: null
buffer.undo()
expect(presenter.gutter.tiles).toHaveValues
5:
lineNumberDecorations:
8: decorationsById
9: decorationsById
10:
lineNumberDecorations:
10: decorationsById
marker.destroy()
expect(presenter.gutter.tiles).toHaveValues
5:
lineNumberDecorations:
8: null
9: null
10:
lineNumberDecorations:
10: null
ToHaveValuesMatcher = (expected) ->
hasAllValues = true
wrongValues = {}
checkValues = (actual, expected, keyPath=[]) ->
for key, expectedValue of expected
key = numericKey if numericKey = parseInt(key)
currentKeyPath = keyPath.concat([key])
if expectedValue?
if actual.hasOwnProperty(key)
actualValue = actual[key]
if expectedValue.constructor is Object and _.size(expectedValue) > 0
checkValues(actualValue, expectedValue, currentKeyPath)
else
unless _.isEqual(actualValue, expectedValue)
hasAllValues = false
_.setValueForKeyPath(wrongValues, currentKeyPath.join('.'), {actualValue, expectedValue})
else
hasAllValues = false
_.setValueForKeyPath(wrongValues, currentKeyPath.join('.'), {expectedValue})
else
actualValue = actual[key]
if actualValue?
hasAllValues = false
_.setValueForKeyPath(wrongValues, currentKeyPath.join('.'), {actualValue, expectedValue})
this.message = => "Object did not have expected values: #{jasmine.pp(wrongValues)}"
checkValues(@actual, expected)
console.warn "Object did not have expected values:", wrongValues unless hasAllValues
hasAllValues
+8 -3
Ver Arquivo
@@ -3301,20 +3301,25 @@ describe "Editor", ->
expect(editor.getText()).toBe ' '
describe ".scrollToCursorPosition()", ->
it "scrolls the last cursor into view", ->
it "scrolls the last cursor into view, centering around the cursor if possible and the 'center' option isn't false", ->
editor.setCursorScreenPosition([8, 8])
editor.setLineHeightInPixels(10)
editor.setDefaultCharWidth(10)
editor.setHeight(50)
editor.setHeight(60)
editor.setWidth(50)
editor.setHorizontalScrollbarHeight(0)
expect(editor.getScrollTop()).toBe 0
expect(editor.getScrollLeft()).toBe 0
editor.scrollToCursorPosition()
expect(editor.getScrollBottom()).toBe (9 + editor.getVerticalScrollMargin()) * 10
expect(editor.getScrollTop()).toBe (8.5 * 10) - 30
expect(editor.getScrollBottom()).toBe (8.5 * 10) + 30
expect(editor.getScrollRight()).toBe (9 + editor.getHorizontalScrollMargin()) * 10
editor.setScrollTop(0)
editor.scrollToCursorPosition(center: false)
expect(editor.getScrollBottom()).toBe (9 + editor.getVerticalScrollMargin()) * 10
describe ".pageUp/Down()", ->
it "scrolls one screen height up or down and moves the cursor one page length", ->
editor.manageScrollPosition = true
-1
Ver Arquivo
@@ -2652,7 +2652,6 @@ describe "EditorView", ->
expect(editor.getCursorBufferPosition()).toEqual [0, 0]
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {'
expect(buffer.lineForRow(13)).toBe 'var a = function() {'
editor.logScreenLines()
expect(editor.isFoldedAtBufferRow(0)).toBe true
expect(editor.isFoldedAtBufferRow(13)).toBe true
@@ -0,0 +1 @@
throw new Error("this simulates a native module's failure to load")
@@ -0,0 +1,4 @@
{
"name": "native-module",
"main": "./main.js"
}
@@ -0,0 +1,5 @@
{
"name": "package-with-incompatible-native-module",
"version": "1.0",
"main": "./main.js"
}
+31
Ver Arquivo
@@ -1,8 +1,39 @@
{$} = require 'atom'
path = require 'path'
Package = require '../src/package'
ThemePackage = require '../src/theme-package'
describe "Package", ->
describe "when the package contains incompatible native modules", ->
beforeEach ->
spyOn(atom, 'inDevMode').andReturn(false)
it "does not activate it", ->
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
pack = new Package(packagePath)
expect(pack.isCompatible()).toBe false
expect(pack.incompatibleModules[0].name).toBe 'native-module'
expect(pack.incompatibleModules[0].path).toBe path.join(packagePath, 'node_modules', 'native-module')
it "caches the incompatible native modules in local storage", ->
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
cacheKey = null
cacheItem = null
spyOn(global.localStorage, 'setItem').andCallFake (key, item) ->
cacheKey = key
cacheItem = item
spyOn(global.localStorage, 'getItem').andCallFake (key) ->
return cacheItem if cacheKey is key
expect(new Package(packagePath).isCompatible()).toBe false
expect(global.localStorage.getItem.callCount).toBe 1
expect(global.localStorage.setItem.callCount).toBe 1
expect(new Package(packagePath).isCompatible()).toBe false
expect(global.localStorage.getItem.callCount).toBe 2
expect(global.localStorage.setItem.callCount).toBe 1
describe "theme", ->
theme = null
+2
Ver Arquivo
@@ -130,6 +130,8 @@ afterEach ->
atom.project?.destroy()
atom.project = null
atom.themes.removeStylesheet('global-editor-styles')
delete atom.state.packageStates
$('#jasmine-content').empty() unless window.debugContent
+28 -1
Ver Arquivo
@@ -20,7 +20,6 @@ describe "WorkspaceView", ->
waitsForPromise ->
atom.workspace.open(pathToOpen)
describe "@deserialize()", ->
viewState = null
@@ -294,3 +293,31 @@ describe "WorkspaceView", ->
expect(atom.workspaceView).toHaveClass 'scrollbars-visible-always'
scrollbarStyle.emitValue 'overlay'
expect(atom.workspaceView).toHaveClass 'scrollbars-visible-when-scrolling'
describe "editor font styling", ->
[editorNode, editor] = []
beforeEach ->
atom.workspaceView.attachToDom()
editorNode = atom.workspaceView.find('.editor')[0]
editor = atom.workspaceView.find('.editor').view().getEditor()
it "updates the font-size based on the 'editor.fontSize' config value", ->
initialCharWidth = editor.getDefaultCharWidth()
expect(getComputedStyle(editorNode).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
expect(getComputedStyle(editorNode).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
expect(editor.getDefaultCharWidth()).toBeGreaterThan initialCharWidth
it "updates the font-family based on the 'editor.fontFamily' config value", ->
initialCharWidth = editor.getDefaultCharWidth()
expect(getComputedStyle(editorNode).fontFamily).toBe atom.config.get('editor.fontFamily')
atom.config.set('editor.fontFamily', 'sans-serif')
expect(getComputedStyle(editorNode).fontFamily).toBe atom.config.get('editor.fontFamily')
expect(editor.getDefaultCharWidth()).not.toBe initialCharWidth
it "updates the line-height based on the 'editor.lineHeight' config value", ->
initialLineHeight = editor.getLineHeightInPixels()
atom.config.set('editor.lineHeight', '30px')
expect(getComputedStyle(editorNode).lineHeight).toBe atom.config.get('editor.lineHeight')
expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight
+2 -2
Ver Arquivo
@@ -150,7 +150,7 @@ class Atom extends Model
process.env.NODE_PATH = exportsPath
# Make react.js faster
process.env.NODE_ENV ?= 'production'
process.env.NODE_ENV ?= 'production' unless devMode
@config = new Config({configDirPath, resourcePath})
@keymaps = new KeymapManager({configDirPath, resourcePath})
@@ -438,7 +438,7 @@ class Atom extends Model
# width - The {Number} of pixels.
# height - The {Number} of pixels.
setSize: (width, height) ->
ipc.send('call-window-method', 'setSize', width, height)
@getCurrentWindow().setSize(width, height)
# Public: Set the position of current window.
#
+6 -1
Ver Arquivo
@@ -18,11 +18,16 @@ getCachedJavaScript = (cachePath) ->
try
fs.readFileSync(cachePath, 'utf8')
convertFilePath = (filePath) ->
if process.platform is 'win32'
filePath = "/#{path.resolve(filePath).replace(/\\/g, '/')}"
encodeURI(filePath)
compileCoffeeScript = (coffee, filePath, cachePath) ->
{js, v3SourceMap} = CoffeeScript.compile(coffee, filename: filePath, sourceMap: true)
# Include source map in the web page environment.
if btoa? and JSON? and unescape? and encodeURIComponent?
js = "#{js}\n//# sourceMappingURL=data:application/json;base64,#{btoa unescape encodeURIComponent v3SourceMap}\n//# sourceURL=#{filePath}"
js = "#{js}\n//# sourceMappingURL=data:application/json;base64,#{btoa unescape encodeURIComponent v3SourceMap}\n//# sourceURL=#{convertFilePath(filePath)}"
try
fs.writeFileSync(cachePath, js)
js
+3 -14
Ver Arquivo
@@ -8,22 +8,11 @@ CursorComponent = React.createClass
render: ->
{pixelRect, defaultCharWidth} = @props
{height, width} = pixelRect
{top, left, height, width} = pixelRect
width = defaultCharWidth if width is 0
WebkitTransform = @getTransform()
WebkitTransform = "translate(#{left}px, #{top}px)"
div className: 'cursor', style: {height, width, WebkitTransform}
getTransform: ->
{pixelRect, scrollTop, scrollLeft, useHardwareAcceleration} = @props
{top, left} = pixelRect
top -= scrollTop
left -= scrollLeft
if useHardwareAcceleration
"translate3d(#{left}px, #{top}px, 0px)"
else
"translate(#{left}px, #{top}px)"
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'pixelRect', 'scrollTop', 'scrollLeft', 'defaultCharWidth')
not isEqualForProperties(newProps, @props, 'pixelRect', 'defaultCharWidth')
+2 -2
Ver Arquivo
@@ -95,8 +95,8 @@ class Cursor extends Model
getBufferPosition: ->
@marker.getHeadBufferPosition()
autoscroll: ->
@editor.scrollToScreenRange(@getScreenRange())
autoscroll: (options) ->
@editor.scrollToScreenRange(@getScreenRange(), options)
# Public: If the marker range is empty, the cursor is marked as being visible.
updateVisibility: ->
+2 -2
Ver Arquivo
@@ -12,7 +12,7 @@ CursorsComponent = React.createClass
cursorBlinkIntervalHandle: null
render: ->
{performedInitialMeasurement, cursorPixelRects, scrollTop, scrollLeft, defaultCharWidth, useHardwareAcceleration} = @props
{performedInitialMeasurement, cursorPixelRects, defaultCharWidth} = @props
{blinkOff} = @state
className = 'cursors'
@@ -21,7 +21,7 @@ CursorsComponent = React.createClass
div {className},
if performedInitialMeasurement
for key, pixelRect of cursorPixelRects
CursorComponent({key, pixelRect, scrollTop, scrollLeft, defaultCharWidth, useHardwareAcceleration})
CursorComponent({key, pixelRect, defaultCharWidth})
getInitialState: ->
blinkOff: false
+2 -2
Ver Arquivo
@@ -220,8 +220,8 @@ class DisplayBufferMarker
@oldTailScreenPosition, newTailScreenPosition,
@oldHeadBufferPosition, newHeadBufferPosition,
@oldTailBufferPosition, newTailBufferPosition,
textChanged,
isValid
@wasValid, isValid,
textChanged
}
@oldHeadBufferPosition = newHeadBufferPosition
+33 -1
Ver Arquivo
@@ -401,13 +401,45 @@ class DisplayBuffer extends Model
# buffer rows corresponding to every screen row in the range
#
# startScreenRow - The screen row {Number} to start at
# endScreenRow - The screen row {Number} to end at (default: the last screen row)
# endScreenRow - The screen row {Number} to end at, inclusive.
#
# Returns an {Array} of buffer rows as {Numbers}s.
bufferRowsForScreenRows: (startScreenRow, endScreenRow) ->
for screenRow in [startScreenRow..endScreenRow]
@rowMap.bufferRowRangeForScreenRow(screenRow)[0]
# Given starting and ending screen rows, this returns an array of the line
# number strings corresponding to every screen row in the range.
#
# Line numbers start at 1 as opposed to row numbers which start at 0.
# Soft wrapped lines are indicated by dot-separated strings. For example, if
# line 9 wraps twice, it will appear as '9', '9.1', '9.2'.
#
# startScreenRow - The screen row {Number} to start at
# endScreenRow - The screen row {Number} to end at, inclusive.
#
# Returns an {Array} of line numbers as {String}s.
lineNumbersForScreenRows: (startScreenRow, endScreenRow) ->
bufferRows = @bufferRowsForScreenRows(startScreenRow, endScreenRow)
# Pad the leading
leadingSoftWraps = 0
while @bufferRowForScreenRow(startScreenRow - leadingSoftWraps - 1) is bufferRows[0]
bufferRows.unshift(bufferRows[0])
leadingSoftWraps++
lineNumbers = []
for bufferRow in bufferRows
lineNumber = (bufferRow + 1).toString()
if bufferRow is lastBufferRow
lineNumber += ".#{++softWraps}"
else
lastBufferRow = bufferRow
softWraps = 0
lineNumbers.push(lineNumber)
lineNumbers[leadingSoftWraps..]
# Creates a new fold between two row numbers.
#
# startRow - The row {Number} to start folding at
+81 -66
Ver Arquivo
@@ -6,13 +6,11 @@ scrollbarStyle = require 'scrollbar-style'
GutterComponent = require './gutter-component'
InputComponent = require './input-component'
CursorsComponent = require './cursors-component'
LinesComponent = require './lines-component'
ScrollbarComponent = require './scrollbar-component'
ScrollbarCornerComponent = require './scrollbar-corner-component'
SubscriberMixin = require './subscriber-mixin'
DummyHighlightDecoration = {id: 'dummy', startPixelPosition: {top: 0, left: 0}, endPixelPosition: {top: 0, left: 0}, decorations: [{class: 'dummy'}]}
EditorPresenter = require './editor-presenter'
module.exports =
EditorComponent = React.createClass
@@ -43,7 +41,7 @@ EditorComponent = React.createClass
scrollSensitivity: 0.4
heightAndWidthMeasurementRequested: false
measureLineHeightAndDefaultCharWidthWhenShown: false
remeasureCharacterWidthsIfVisibleAfterNextUpdate: false
remeasureCharacterWidthsWhenShown: false
inputEnabled: true
scopedCharacterWidthsChangeCount: null
domPollingInterval: 100
@@ -51,13 +49,14 @@ EditorComponent = React.createClass
domPollingPaused: false
render: ->
{focused, fontSize, lineHeight, fontFamily, showIndentGuide, showInvisibles, showLineNumbers, visible} = @state
{focused, showIndentGuide, showInvisibles, showLineNumbers, visible} = @state
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
contentPresenter = @presenter.content
gutterPresenter = @presenter.gutter
maxLineNumberDigits = editor.getLineCount().toString().length
invisibles = if showInvisibles and not mini then @state.invisibles else {}
hasSelection = editor.getSelection()? and !editor.getSelection().isEmpty()
style = {fontSize, fontFamily}
style.lineHeight = lineHeight unless mini
style = {}
if @performedInitialMeasurement
renderedRowRange = @getRenderedRowRange()
@@ -95,7 +94,8 @@ EditorComponent = React.createClass
div {className, style, tabIndex: -1},
if @shouldRenderGutter()
GutterComponent {
ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations,
ref: 'gutter', gutterPresenter
onMouseDown: @onGutterMouseDown, lineDecorations,
defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight,
scrollTop, scrollHeight, lineHeightInPixels, @pendingChanges, mouseWheelScreenRow,
@useHardwareAcceleration, @performedInitialMeasurement, @backgroundColor, @gutterBackgroundColor
@@ -109,18 +109,14 @@ EditorComponent = React.createClass
onFocus: @onInputFocused
onBlur: @onInputBlurred
CursorsComponent {
scrollTop, scrollLeft, cursorPixelRects, cursorBlinkPeriod, cursorBlinkResumeDelay,
lineHeightInPixels, defaultCharWidth, @scopedCharacterWidthsChangeCount, @useHardwareAcceleration,
@performedInitialMeasurement
}
LinesComponent {
ref: 'lines',
ref: 'lines', contentPresenter,
editor, lineHeightInPixels, defaultCharWidth, lineDecorations, highlightDecorations,
showIndentGuide, renderedRowRange, @pendingChanges, scrollTop, scrollLeft,
@scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow, invisibles,
@visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth, @useHardwareAcceleration,
placeholderText, @performedInitialMeasurement, @backgroundColor
placeholderText, @performedInitialMeasurement, @backgroundColor, cursorPixelRects,
cursorBlinkPeriod, cursorBlinkResumeDelay
}
ScrollbarComponent
@@ -167,7 +163,7 @@ EditorComponent = React.createClass
getDefaultProps: ->
cursorBlinkPeriod: 800
cursorBlinkResumeDelay: 100
lineOverdrawMargin: 8
lineOverdrawMargin: 15
componentWillMount: ->
@pendingChanges = []
@@ -175,6 +171,9 @@ EditorComponent = React.createClass
@observeConfig()
@setScrollSensitivity(atom.config.get('editor.scrollSensitivity'))
@presenter = new EditorPresenter(@props.editor)
@subscribe @presenter, 'did-change', @requestUpdate
componentDidMount: ->
{editor} = @props
@@ -184,7 +183,7 @@ EditorComponent = React.createClass
@listenForDOMEvents()
@listenForCommands()
@subscribe atom.themes, 'stylesheet-added stylsheet-removed', @onStylesheetsChanged
@subscribe atom.themes, 'stylesheet-added stylesheet-removed stylesheet-updated', @onStylesheetsChanged
@subscribe scrollbarStyle.changes, @refreshScrollbars
if @visible = @isVisible()
@@ -194,6 +193,7 @@ EditorComponent = React.createClass
componentWillUnmount: ->
@props.parentView.trigger 'editor:will-be-removed', [@props.parentView]
@unsubscribe()
window.removeEventListener 'resize', @requestHeightAndWidthMeasurement
clearInterval(@domPollingIntervalId)
@domPollingIntervalId = null
@@ -219,20 +219,24 @@ EditorComponent = React.createClass
if @performedInitialMeasurement
@measureScrollbars() if @measuringScrollbars
@measureLineHeightAndDefaultCharWidthIfNeeded(prevState)
@remeasureCharacterWidthsIfNeeded(prevState)
performInitialMeasurement: ->
console.log "INITIAL MEASUREMENT"
@updatesPaused = true
@measureLineHeightAndDefaultCharWidth()
@measureHeightAndWidth()
@sampleFontStyling()
@sampleBackgroundColors()
@measureScrollbars()
@measureLineHeightAndDefaultCharWidth() if @measureLineHeightAndDefaultCharWidthWhenShown
# @remeasureCharacterWidths() if @remeasureCharacterWidthsWhenShown
@props.editor.setVisible(true)
@updatesPaused = false
@performedInitialMeasurement = true
requestUpdate: ->
return unless @isMounted()
@pauseDOMPolling()
if @updatesPaused
@updateRequestedWhilePaused = true
return
@@ -241,7 +245,7 @@ EditorComponent = React.createClass
@forceUpdate()
else unless @updateRequested
@updateRequested = true
setImmediate =>
requestAnimationFrame =>
@updateRequested = false
@forceUpdate() if @isMounted()
@@ -255,6 +259,9 @@ EditorComponent = React.createClass
@updateRequestedWhilePaused = false
@forceUpdate()
getTopmostDOMNode: ->
@props.parentView.element
getRenderedRowRange: ->
{editor, lineOverdrawMargin} = @props
[visibleStartRow, visibleEndRow] = editor.getVisibleRowRange()
@@ -296,7 +303,9 @@ EditorComponent = React.createClass
{cursor} = selection
screenRange = cursor.getScreenRange()
if renderedStartRow <= screenRange.start.row < renderedEndRow
cursorPixelRects[cursor.id] = editor.pixelRectForScreenRange(screenRange)
pixelRect = editor.pixelRectForScreenRange(screenRange)
pixelRect.startRow = screenRange.start.row
cursorPixelRects[cursor.id] = pixelRect
cursorPixelRects
getLineDecorations: (decorationsByMarkerId) ->
@@ -346,11 +355,6 @@ EditorComponent = React.createClass
decorations: []
filteredDecorations[markerId].decorations.push decorationParams
# At least in Chromium 31, removing the last highlight causes a rendering
# artifact where chunks of the lines disappear, so we always leave this
# dummy highlight in place to prevent that.
filteredDecorations['dummy'] = DummyHighlightDecoration
filteredDecorations
observeEditor: ->
@@ -521,9 +525,6 @@ EditorComponent = React.createClass
parentView.command command, listener
observeConfig: ->
@subscribe atom.config.observe 'editor.fontFamily', @setFontFamily
@subscribe atom.config.observe 'editor.fontSize', @setFontSize
@subscribe atom.config.observe 'editor.lineHeight', @setLineHeight
@subscribe atom.config.observe 'editor.showIndentGuide', @setShowIndentGuide
@subscribe atom.config.observe 'editor.invisibles', @setInvisibles
@subscribe atom.config.observe 'editor.showInvisibles', @setShowInvisibles
@@ -535,7 +536,14 @@ EditorComponent = React.createClass
@refs.input.focus()
onTextInput: (event) ->
event.stopPropagation()
# If we prevent the insertion of a space character, then the browser
# interprets the spacebar keypress as a page-down command.
event.preventDefault() unless event.data is ' '
return unless @isInputEnabled()
event.reactSkipEventDispatch = true
{editor} = @props
inputNode = event.target
@@ -550,9 +558,6 @@ EditorComponent = React.createClass
editor.insertText(event.data)
inputNode.value = event.data
# If we prevent the insertion of a space character, then the browser
# interprets the spacebar keypress as a page-down command.
event.preventDefault() unless event.data is ' '
onInputFocused: ->
@setState(focused: true)
@@ -678,10 +683,12 @@ EditorComponent = React.createClass
editor.setSelectedScreenRange([tailPosition, [dragRow + 1, 0]])
onStylesheetsChanged: (stylesheet) ->
return unless @performedInitialMeasurement
@refreshScrollbars() if @containsScrollbarSelector(stylesheet)
@sampleFontStyling()
@sampleBackgroundColors()
@remeasureCharacterWidthsIfVisibleAfterNextUpdate = true
@requestUpdate() if @visible
@remeasureCharacterWidths()
onScreenLinesChanged: (change) ->
{editor} = @props
@@ -773,12 +780,13 @@ EditorComponent = React.createClass
resumeDOMPollingAfterDelay: null # created lazily
pollDOM: ->
return if @domPollingPaused or not @isMounted()
return if @domPollingPaused or @updateRequested or not @isMounted()
wasVisible = @visible
if @visible = @isVisible()
if wasVisible
@measureHeightAndWidth()
@sampleFontStyling()
@sampleBackgroundColors()
else
@performInitialMeasurement()
@@ -821,46 +829,50 @@ EditorComponent = React.createClass
clientWidth -= paddingLeft
editor.setWidth(clientWidth) if clientWidth > 0
sampleFontStyling: ->
oldFontSize = @fontSize
oldFontFamily = @fontFamily
oldLineHeight = @lineHeight
{@fontSize, @fontFamily, @lineHeight} = getComputedStyle(@getTopmostDOMNode())
if @fontSize isnt oldFontSize or @fontFamily isnt oldFontFamily or @lineHeight isnt oldLineHeight
@measureLineHeightAndDefaultCharWidth()
if (@fontSize isnt oldFontSize or @fontFamily isnt oldFontFamily) and @performedInitialMeasurement
@remeasureCharacterWidths()
sampleBackgroundColors: (suppressUpdate) ->
{parentView} = @props
{editor, parentView} = @props
{showLineNumbers} = @state
{backgroundColor} = getComputedStyle(parentView.element)
if backgroundColor isnt @backgroundColor
editor.setBackgroundColor(backgroundColor)
@backgroundColor = backgroundColor
@requestUpdate() unless suppressUpdate
if @shouldRenderGutter()
gutterBackgroundColor = getComputedStyle(@refs.gutter.getDOMNode()).backgroundColor
gutterBackgroundColor = null if gutterBackgroundColor is 'rgba(0, 0, 0, 0)'
if gutterBackgroundColor isnt @gutterBackgroundColor
editor.setGutterBackgroundColor(backgroundColor)
@gutterBackgroundColor = gutterBackgroundColor
@requestUpdate() unless suppressUpdate
measureLineHeightAndDefaultCharWidthIfNeeded: (prevState) ->
if not isEqualForProperties(prevState, @state, 'lineHeight', 'fontSize', 'fontFamily')
if @visible
@measureLineHeightAndDefaultCharWidth()
else
@measureLineHeightAndDefaultCharWidthWhenShown = true
else if @measureLineHeightAndDefaultCharWidthWhenShown and @visible
@measureLineHeightAndDefaultCharWidthWhenShown = false
@measureLineHeightAndDefaultCharWidth()
measureLineHeightAndDefaultCharWidth: ->
@refs.lines.measureLineHeightAndDefaultCharWidth()
remeasureCharacterWidthsIfNeeded: (prevState) ->
if not isEqualForProperties(prevState, @state, 'fontSize', 'fontFamily')
if @visible
@remeasureCharacterWidths()
else
@remeasureCharacterWidthsIfVisibleAfterNextUpdate = true
else if @remeasureCharacterWidthsIfVisibleAfterNextUpdate and @visible
@remeasureCharacterWidthsIfVisibleAfterNextUpdate = false
@remeasureCharacterWidths()
if @visible
@measureLineHeightAndDefaultCharWidthWhenShown = false
@refs.lines.measureLineHeightAndDefaultCharWidth()
else
@measureLineHeightAndDefaultCharWidthWhenShown = true
remeasureCharacterWidths: ->
@refs.lines.remeasureCharacterWidths()
if @visible
@remeasureCharacterWidthsWhenShown = false
@refs.lines.remeasureCharacterWidths()
else
@remeasureCharacterWidthsWhenShown = true
measureScrollbars: ->
return unless @visible
@@ -921,19 +933,22 @@ EditorComponent = React.createClass
null
getFontSize: ->
@state.fontSize
parseInt(getComputedStyle(@getTopmostDOMNode()).fontSize)
setFontSize: (fontSize) ->
@setState({fontSize})
@getTopmostDOMNode().style.fontSize = fontSize + 'px'
@sampleFontStyling()
getFontFamily: ->
@state.fontFamily
getComputedStyle(@getTopmostDOMNode()).fontFamily
setFontFamily: (fontFamily) ->
@setState({fontFamily})
@getTopmostDOMNode().style.fontFamily = fontFamily
@sampleFontStyling()
setLineHeight: (lineHeight) ->
@setState({lineHeight})
@getTopmostDOMNode().style.lineHeight = lineHeight
@sampleFontStyling()
setShowIndentGuide: (showIndentGuide) ->
@setState({showIndentGuide})
@@ -978,8 +993,8 @@ EditorComponent = React.createClass
{clientX, clientY} = event
linesClientRect = @refs.lines.getDOMNode().getBoundingClientRect()
top = clientY - linesClientRect.top
left = clientX - linesClientRect.left
top = clientY - linesClientRect.top + @presenter.scrollTop
left = clientX - linesClientRect.left + @presenter.scrollLeft
{top, left}
getModel: ->
+331
Ver Arquivo
@@ -0,0 +1,331 @@
{Emitter, Subscriber} = require 'emissary'
_ = require 'underscore-plus'
module.exports =
class EditorPresenter
Emitter.includeInto(this)
Subscriber.includeInto(this)
constructor: (@editor) ->
@content = {tiles: {}}
@gutter = {tiles: {}, dummyTile: {dummy: true}}
@updateTiles()
@updateDummyGutterTile()
@scrollTop = @editor.getScrollTop()
@scrollLeft = @editor.getScrollLeft()
@subscribe @editor.$width.changes, @onWidthChanged
@subscribe @editor.$height.changes, @onHeightChanged
@subscribe @editor.$lineHeightInPixels.changes, @onLineHeightInPixelsChanged
@subscribe @editor.$scrollTop.changes, @onScrollTopChanged
@subscribe @editor.$scrollLeft.changes, @onScrollLeftChanged
@subscribe @editor.$backgroundColor.changes, @onBackgroundColorChanged
@subscribe @editor.$gutterBackgroundColor.changes, @onBackgroundColorChanged
@subscribe @editor, 'screen-lines-changed', @onScreenLinesChanged
@subscribe @editor, 'decoration-added', @onDecorationAdded
@subscribe @editor, 'decoration-removed', @onDecorationRemoved
@subscribe @editor, 'decoration-changed', @onDecorationChanged
getContentTileSize: -> 5
getGutterTileSize: -> 20
getVisibleRowRange: ->
heightInLines = Math.ceil(@editor.getHeight() / @editor.getLineHeightInPixels())
startRow = Math.floor(@editor.getScrollTop() / @editor.getLineHeightInPixels())
endRow = Math.min(@editor.getLineCount(), startRow + heightInLines)
[startRow, endRow]
contentTileStartRowForRow: (startRow) ->
startRow - (startRow % @getContentTileSize())
gutterTileStartRowForRow: (startRow) ->
startRow - (startRow % @getGutterTileSize())
getContentTileRowRange: ->
[startRow, endRow] = @getVisibleRowRange()
startRow = @contentTileStartRowForRow(startRow)
endRow = @contentTileStartRowForRow(endRow) + @getContentTileSize()
[startRow, endRow]
getGutterTileRowRange: ->
[startRow, endRow] = @getVisibleRowRange()
startRow = @gutterTileStartRowForRow(startRow)
endRow = @gutterTileStartRowForRow(endRow) + @getGutterTileSize()
[startRow, endRow]
updateTiles: (fn) ->
@updateContentTiles(fn)
@updateGutterTiles(fn)
@emit 'did-change'
updateContentTiles: (fn) ->
[startRow, endRow] = @getContentTileRowRange()
for tileStartRow of @content.tiles
delete @content.tiles[tileStartRow] unless startRow <= tileStartRow < endRow
for tileStartRow in [startRow...endRow] by @getContentTileSize()
if existingTile = @content.tiles[tileStartRow]
fn?(existingTile)
else
tileEndRow = tileStartRow + @getContentTileSize()
@content.tiles[tileStartRow] = new ContentTilePresenter(@editor, tileStartRow, tileEndRow)
updateGutterTiles: (fn) ->
[startRow, endRow] = @getGutterTileRowRange()
for tileStartRow of @gutter.tiles
delete @gutter.tiles[tileStartRow] unless startRow <= tileStartRow < endRow
for tileStartRow in [startRow...endRow] by @getGutterTileSize()
if existingTile = @gutter.tiles[tileStartRow]
fn?(existingTile)
else
tileEndRow = tileStartRow + @getGutterTileSize()
@gutter.tiles[tileStartRow] = new GutterTilePresenter(@editor, tileStartRow, tileEndRow)
updateDummyGutterTile: ->
@gutter.dummyTile.maxLineNumberDigits = @editor.getLineCount().toString().length
onWidthChanged: =>
@updateTiles (tile) -> tile.updateWidth()
onHeightChanged: =>
@updateTiles()
onLineHeightInPixelsChanged: =>
@updateTiles (tile) -> tile.updateLineHeightInPixels()
onScrollTopChanged: (@scrollTop) =>
@updateTiles (tile) -> tile.updateScrollTop()
onScrollLeftChanged: (@scrollLeft) =>
@updateTiles (tile) -> tile.updateScrollLeft()
onScreenLinesChanged: (change) =>
@updateDummyGutterTile() if change.bufferDelta isnt 0
@updateTiles (tile) -> tile.onScreenLinesChanged(change)
onBackgroundColorChanged: =>
@updateTiles (tile) -> tile.updateBackgroundColor()
onDecorationAdded: (marker, decoration) =>
@updateTiles (tile) -> tile.onDecorationAdded(decoration)
onDecorationRemoved: (marker, decoration) =>
@updateTiles (tile) -> tile.onDecorationRemoved(decoration)
onDecorationChanged: (marker, decoration, change) =>
@updateTiles (tile) -> tile.onDecorationChanged(decoration, change)
class ContentTilePresenter
constructor: (@editor, @startRow, @endRow) ->
@lineDecorations = {}
@updateWidth()
@updateLineHeightInPixels()
@updateScrollTop()
@updateScrollLeft()
@updateBackgroundColor()
@updateLines()
@populateDecorations()
updateWidth: ->
@width = @editor.getWidth()
updateHeight: ->
@height = (@endRow - @startRow) * @editor.getLineHeightInPixels()
updateLineHeightInPixels: ->
@lineHeightInPixels = @editor.getLineHeightInPixels()
@updateTop()
@updateHeight()
updateScrollTop: ->
@updateTop()
updateScrollLeft: ->
@left = 0 - @editor.getScrollLeft()
updateBackgroundColor: ->
@backgroundColor = @editor.getBackgroundColor()
updateTop: ->
@top = @startRow * @editor.getLineHeightInPixels() - @editor.getScrollTop()
updateLines: ->
@lines = @editor.linesForScreenRows(@startRow, @endRow - 1)
populateDecorations: ->
for markerId, decorations of @editor.decorationsForScreenRowRange(@startRow, @endRow)
for decoration in decorations
@onDecorationAdded(decoration)
onScreenLinesChanged: (change) ->
@updateLines() if change.start < @endRow
onDecorationAdded: (decoration) ->
if decoration.isType('line')
@onLineDecorationAdded(decoration)
onDecorationRemoved: (decoration) ->
if decoration.isType('line')
@onLineDecorationRemoved(decoration)
onDecorationChanged: (decoration, change) ->
if decoration.isType('line')
@onLineDecorationChanged(decoration, change)
onLineDecorationAdded: (decoration) ->
marker = decoration.getMarker()
headRow = marker.getHeadScreenPosition().row
tailRow = marker.getTailScreenPosition().row
valid = marker.isValid()
params = decoration.getParams()
if rowRange = @rowRangeForLineDecoration(params, headRow, tailRow, valid)
@addLineDecorations(params, rowRange...)
onLineDecorationRemoved: (decoration) ->
marker = decoration.getMarker()
headRow = marker.getHeadScreenPosition().row
tailRow = marker.getTailScreenPosition().row
valid = true # FIXME: Markers shouldn't always be invalidated when destroyed
params = decoration.getParams()
if rowRange = @rowRangeForLineDecoration(params, headRow, tailRow, valid)
@removeLineDecorations(params, rowRange...)
onLineDecorationChanged: (decoration, change) ->
params = decoration.getParams()
{oldHeadScreenPosition, oldTailScreenPosition, wasValid} = change
if rowRange = @rowRangeForLineDecoration(params, oldHeadScreenPosition.row, oldTailScreenPosition.row, wasValid)
@removeLineDecorations(params, rowRange...)
{newHeadScreenPosition, newTailScreenPosition, isValid} = change
if rowRange = @rowRangeForLineDecoration(params, newHeadScreenPosition.row, newTailScreenPosition.row, isValid)
@addLineDecorations(params, rowRange...)
addLineDecorations: (params, decorationStartRow, decorationEndRow) ->
unless decorationEndRow < @startRow or @endRow <= decorationStartRow
for row in [decorationStartRow..decorationEndRow]
@lineDecorations[row] ?= {}
@lineDecorations[row][params.id] = params
removeLineDecorations: (params, decorationStartRow, decorationEndRow) ->
unless decorationEndRow < @startRow or @endRow <= decorationStartRow
for row in [decorationStartRow..decorationEndRow]
delete @lineDecorations[row][params.id]
delete @lineDecorations[row] if _.size(@lineDecorations[row]) is 0
rowRangeForLineDecoration: (decoration, headRow, tailRow, valid) ->
return unless valid
startRow = Math.min(headRow, tailRow)
endRow = Math.max(headRow, tailRow)
[startRow, endRow]
class GutterTilePresenter
constructor: (@editor, @startRow, @endRow) ->
@lineNumberDecorations = {}
@populateDecorations()
@updateLineHeightInPixels()
@updateScrollTop()
@updateBackgroundColor()
populateDecorations: ->
for markerId, decorations of @editor.decorationsForScreenRowRange(@startRow, @endRow)
for decoration in decorations
@onDecorationAdded(decoration)
updateLineHeightInPixels: ->
@lineHeightInPixels = @editor.getLineHeightInPixels()
@updateTop()
@updateHeight()
@updateLineNumbers()
updateScrollLeft: -> # NO-OP
updateScrollTop: ->
@updateTop()
updateBackgroundColor: ->
@backgroundColor = @editor.getGutterBackgroundColor() ? @editor.getBackgroundColor()
updateTop: ->
@top = @startRow * @editor.getLineHeightInPixels() - @editor.getScrollTop()
updateWidth: -> # NO-OP
updateHeight: ->
@height = (@endRow - @startRow) * @editor.getLineHeightInPixels()
updateLineNumbers: ->
@lineNumbers = @editor.lineNumbersForScreenRows(@startRow, @endRow - 1)
@maxLineNumberDigits = @editor.getLineCount().toString().length
updateMaxLineNumberDigits: ->
@maxLineNumberDigits = @editor.getLineCount().toString().length
onScreenLinesChanged: (change) ->
if change.bufferDelta isnt 0 or change.screenDelta isnt 0
@updateMaxLineNumberDigits()
@updateLineNumbers() if change.start < @endRow
onDecorationAdded: (decoration) ->
return unless decoration.isType('gutter')
marker = decoration.getMarker()
headRow = marker.getHeadScreenPosition().row
tailRow = marker.getTailScreenPosition().row
valid = marker.isValid()
params = decoration.getParams()
if rowRange = @rowRangeForLineNumberDecoration(params, headRow, tailRow, valid)
@addLineNumberDecorations(params, rowRange...)
onDecorationRemoved: (decoration) ->
return unless decoration.isType('gutter')
marker = decoration.getMarker()
headRow = marker.getHeadScreenPosition().row
tailRow = marker.getTailScreenPosition().row
valid = true # FIXME: Markers shouldn't always be invalidated when destroyed
params = decoration.getParams()
if rowRange = @rowRangeForLineNumberDecoration(params, headRow, tailRow, valid)
@removeLineNumberDecorations(params, rowRange...)
onDecorationChanged: (decoration, change) ->
return unless decoration.isType('gutter')
params = decoration.getParams()
{oldHeadScreenPosition, oldTailScreenPosition, wasValid} = change
if rowRange = @rowRangeForLineNumberDecoration(params, oldHeadScreenPosition.row, oldTailScreenPosition.row, wasValid)
@removeLineNumberDecorations(params, rowRange...)
{newHeadScreenPosition, newTailScreenPosition, isValid} = change
if rowRange = @rowRangeForLineNumberDecoration(params, newHeadScreenPosition.row, newTailScreenPosition.row, isValid)
@addLineNumberDecorations(params, rowRange...)
addLineNumberDecorations: (params, decorationStartRow, decorationEndRow) ->
unless decorationEndRow < @startRow or @endRow <= decorationStartRow
for row in [decorationStartRow..decorationEndRow]
@lineNumberDecorations[row] ?= {}
@lineNumberDecorations[row][params.id] = params
removeLineNumberDecorations: (params, decorationStartRow, decorationEndRow) ->
unless decorationEndRow < @startRow or @endRow <= decorationStartRow
for row in [decorationStartRow..decorationEndRow]
delete @lineNumberDecorations[row][params.id]
delete @lineNumberDecorations[row] if _.size(@lineNumberDecorations[row]) is 0
rowRangeForLineNumberDecoration: (decoration, headRow, tailRow, valid) ->
return unless valid
startRow = Math.min(headRow, tailRow)
endRow = Math.max(headRow, tailRow)
[startRow, endRow]
+347
Ver Arquivo
@@ -0,0 +1,347 @@
{extend, toArray, isEqual, clone} = require 'underscore-plus'
Decoration = require './decoration'
WrapperDiv = document.createElement('div')
module.exports =
class EditorTileComponent
top: null
left: null
height: null
width: null
lineHeightInPixels: null
lineWidths: null
backgroundColor: null
preserved: false
constructor: (@presenter) ->
@lineNodesByLineId = {}
@screenRowsByLineId = {}
@lineIdsByScreenRow = {}
@lineDecorationsByLineId = {}
@cursorPixelRectsById = {}
@cursorNodesById = {}
@domNode = document.createElement('div')
@domNode.dataset.tile = true
@domNode.style.position = 'absolute'
@domNode.style.overflow = 'hidden'
@buildLines()
@update()
stateChangedForKeys: ->
for key in arguments
return true if @prevState?.get(key) isnt @state.get(key)
false
update: ->
@updateTransform()
@updateWidth()
@updateHeight()
@updateBackgroundColor()
@updateLines()
# @clearScreenRowCaches() if newProps.lineHeightInPixels isnt @props.lineHeightInPixels
# @updateCursors()
preserve: ->
return if @preserved
@domNode.style.visibility = 'hidden'
@preserved = true
revive: (@presenter) ->
@domNode.style.visibility = ''
@visible = true
updateTransform: ->
{left, top} = @presenter
unless left is @left and top is @top
@domNode.style['-webkit-transform'] = "translate3d(#{left}px, #{top}px, 0px)"
@left = left
@top = top
updateWidth: ->
{width} = @presenter
unless width is @width
@domNode.style.width = width + 'px'
@width = width
updateHeight: ->
{height} = @presenter
unless height is @height
@domNode.style.height = height + 'px'
@height = height
updateBackgroundColor: ->
{backgroundColor} = @presenter
unless backgroundColor is @backgroundColor
@domNode.style.backgroundColor = backgroundColor
@backgroundColor = backgroundColor
buildLines: ->
{startRow, lines, lineDecorations} = @presenter
linesHTML = ""
for line, i in lines
screenRow = startRow + i
linesHTML += @buildLineHTML(line, screenRow)
@domNode.innerHTML = linesHTML
for line, i in lines
screenRow = startRow + i
lineNode = @domNode.children[i]
@lineNodesByLineId[line.id] = lineNode
@screenRowsByLineId[line.id] = screenRow
@lineDecorationsByLineId[line.id] = clone(lineDecorations[screenRow])
@lineIdsByScreenRow[screenRow] = line.id
updateLines: ->
{lines, width} = @presenter
@removeLineNodes()
@appendOrUpdateVisibleLineNodes()
@lineWidths = width
removeLineNodes: () ->
lineIds = new Set
lineIds.add(line.id.toString()) for line in @presenter.lines
for lineId, lineNode of @lineNodesByLineId when not lineIds.has(lineId)
screenRow = @screenRowsByLineId[lineId]
delete @lineNodesByLineId[lineId]
delete @lineIdsByScreenRow[screenRow] if @lineIdsByScreenRow[screenRow] is lineId
delete @screenRowsByLineId[lineId]
delete @lineDecorationsByLineId[lineId]
@domNode.removeChild(lineNode)
appendOrUpdateVisibleLineNodes: ->
{startRow, lines, lineHeightInPixels, width} = @presenter
newLines = null
newLinesHTML = null
for line, index in lines
screenRow = startRow + index
if @hasLineNode(line.id)
@updateLineNode(line, screenRow)
else
newLines ?= []
newLinesHTML ?= ""
newLines.push(line)
newLinesHTML += @buildLineHTML(line, screenRow)
@screenRowsByLineId[line.id] = screenRow
@lineIdsByScreenRow[screenRow] = line.id
@lineHeightInPixels = lineHeightInPixels
@lineWidths = width
return unless newLines?
WrapperDiv.innerHTML = newLinesHTML
newLineNodes = toArray(WrapperDiv.children)
for line, i in newLines
lineNode = newLineNodes[i]
@lineNodesByLineId[line.id] = lineNode
@domNode.appendChild(lineNode)
updateLineNode: (line, screenRow) ->
{startRow, lineHeightInPixels, width} = @presenter
lineNode = @lineNodesByLineId[line.id]
unless width is @lineWidths
lineNode.style.width = width + 'px'
unless @screenRowsByLineId[line.id] is screenRow and lineHeightInPixels is @lineHeightInPixels
lineNode.style.top = (screenRow - startRow) * lineHeightInPixels + 'px'
unless @screenRowsByLineId[line.id] is screenRow
lineNode.dataset.screenRow = screenRow
@screenRowsByLineId[line.id] = screenRow
@lineIdsByScreenRow[screenRow] = line.id
@updateLineDecorations(lineNode, line, screenRow)
updateLineDecorations: (lineNode, line, screenRow) ->
desiredDecorations = @presenter.lineDecorations[screenRow]
if currentDecorations = @lineDecorationsByLineId[line.id]
for id, decoration of currentDecorations
unless desiredDecorations?[id]?
lineNode.classList.remove(decoration.class)
delete currentDecorations[id]
if desiredDecorations?
currentDecorations = (@lineDecorationsByLineId[line.id] ?= {})
for id, decoration of desiredDecorations
unless currentDecorations[id]?
lineNode.classList.add(decoration.class)
currentDecorations[id] = decoration
clearScreenRowCaches: ->
@screenRowsByLineId = {}
@lineIdsByScreenRow = {}
hasLineNode: (lineId) ->
@lineNodesByLineId.hasOwnProperty(lineId)
lineNodeForScreenRow: (screenRow) ->
@lineNodesByLineId[@lineIdsByScreenRow[screenRow]]
hasDecoration: (decorations, decoration) ->
decorations? and decorations[decoration.id] is decoration
buildLineHTML: (line, screenRow) ->
{startRow, lineHeightInPixels, width} = @presenter
{text, fold, isSoftWrapped, indentLevel} = line
classes = @getLineClasses(screenRow)
top = (screenRow - startRow) * lineHeightInPixels
style = "position: absolute; top: #{top}px; width: #{width}px;"
lineHTML = """<div class="#{classes}" style="#{style}">"""
if text is ""
lineHTML += @buildEmptyLineInnerHTML(line)
else
lineHTML += @buildLineInnerHTML(line)
lineHTML += '<span class="fold-marker"></span>' if fold?
lineHTML += "</div>"
lineHTML
getLineClasses: (screenRow) ->
classes = ''
if lineDecorationsForScreenRow = @presenter.lineDecorations[screenRow]
for id, decoration of lineDecorationsForScreenRow
classes += decoration.class + ' '
classes + 'line'
buildEmptyLineInnerHTML: (line) ->
invisibles = {}
showIndentGuide = false
# {showIndentGuide, invisibles} = @props
{cr, eol} = invisibles
{indentLevel, tabLength} = line
if showIndentGuide and indentLevel > 0
invisiblesToRender = []
invisiblesToRender.push(cr) if cr? and line.lineEnding is '\r\n'
invisiblesToRender.push(eol) if eol?
lineHTML = ''
for i in [0...indentLevel]
lineHTML += "<span class='indent-guide'>"
for j in [0...tabLength]
if invisible = invisiblesToRender.shift()
lineHTML += "<span class='invisible-character'>#{invisible}</span>"
else
lineHTML += ' '
lineHTML += "</span>"
while invisiblesToRender.length
lineHTML += "<span class='invisible-character'>#{invisiblesToRender.shift()}</span>"
lineHTML
else
# @buildEndOfLineHTML(line, @props.invisibles) or '&nbsp;'
@buildEndOfLineHTML(line, {}) or '&nbsp;'
buildLineInnerHTML: (line) ->
# {invisibles, mini, showIndentGuide} = @props
invisibles = {}
mini = false
showIndentGuide = false
{tokens, text} = line
innerHTML = ""
scopeStack = []
firstTrailingWhitespacePosition = text.search(/\s*$/)
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
for token in tokens
innerHTML += @updateScopeStack(scopeStack, token.scopes)
hasIndentGuide = not mini and showIndentGuide and (token.hasLeadingWhitespace or (token.hasTrailingWhitespace and lineIsWhitespaceOnly))
innerHTML += token.getValueAsHtml({invisibles, hasIndentGuide})
innerHTML += @popScope(scopeStack) while scopeStack.length > 0
innerHTML += @buildEndOfLineHTML(line, invisibles)
innerHTML
buildEndOfLineHTML: (line, invisibles) ->
# return '' if @props.mini or line.isSoftWrapped()
return '' if line.isSoftWrapped()
html = ''
# Note the lack of '?' in the character checks. A user can set the chars
# to an empty string which we will interpret as not-set
if invisibles.cr and line.lineEnding is '\r\n'
html += "<span class='invisible-character'>#{invisibles.cr}</span>"
if invisibles.eol
html += "<span class='invisible-character'>#{invisibles.eol}</span>"
html
updateScopeStack: (scopeStack, desiredScopes) ->
html = ""
# Find a common prefix
for scope, i in desiredScopes
break unless scopeStack[i] is desiredScopes[i]
# Pop scopes until we're at the common prefx
until scopeStack.length is i
html += @popScope(scopeStack)
# Push onto common prefix until scopeStack equals desiredScopes
for j in [i...desiredScopes.length]
html += @pushScope(scopeStack, desiredScopes[j])
html
popScope: (scopeStack) ->
scopeStack.pop()
"</span>"
pushScope: (scopeStack, scope) ->
scopeStack.push(scope)
"<span class=\"#{scope.replace(/\.+/g, ' ')}\">"
updateCursors: ->
return
{cursorPixelRects, startRow, lineHeightInPixels} = @props
for id of @cursorPixelRectsById
@removeCursorNode(id) unless cursorPixelRects?.hasOwnProperty(id)
if cursorPixelRects?
for id, newPixelRect of cursorPixelRects
newPixelRect.top -= startRow * lineHeightInPixels
if oldPixelRect = @cursorPixelRectsById[id]
unless isEqual(oldPixelRect, newPixelRect)
@updateCursorNode(id, newPixelRect)
else
@buildCursorNode(id, newPixelRect)
updateCursorNode: (id, pixelRect) ->
{top, left, height, width} = pixelRect
@cursorNodesById[id].style.top = top + 'px'
@cursorNodesById[id].style.left = left + 'px'
@cursorNodesById[id].style.height = height + 'px'
@cursorNodesById[id].style.width = width + 'px'
@cursorPixelRectsById[id] = pixelRect
buildCursorNode: (id, pixelRect) ->
cursorNode = document.createElement('div')
cursorNode.className = 'cursor'
cursorNode.style.position = 'absolute'
@cursorNodesById[id] = cursorNode
@cursorPixelRectsById[id] = pixelRect
@updateCursorNode(id, pixelRect)
@domNode.appendChild(cursorNode)
removeCursorNode: (id) ->
@domNode.removeChild(@cursorNodesById[id])
delete @cursorPixelRectsById[id]
delete @cursorNodesById[id]
+2 -2
Ver Arquivo
@@ -641,9 +641,9 @@ class EditorView extends View
@scrollBottom(@editor.getScreenLineCount() * @lineHeight)
# Public: Scrolls the editor to the position of the most recently added
# cursor.
# cursor if it isn't current on screen.
#
# The editor is also centered.
# The editor is centered around the cursor's position if possible.
scrollToCursorPosition: ->
@scrollToBufferPosition(@editor.getCursorBufferPosition(), center: true)
+21 -2
Ver Arquivo
@@ -152,6 +152,10 @@ class Editor extends Model
updateBatchDepth: 0
selectionFlashDuration: 500
@properties
backgroundColor: null
gutterBackgroundColor: null
@delegatesMethods 'suggestedIndentForBufferRow', 'autoIndentBufferRow', 'autoIndentBufferRows',
'autoDecreaseIndentForBufferRow', 'toggleLineCommentForBufferRow', 'toggleLineCommentsForBufferRows',
toProperty: 'languageMode'
@@ -591,6 +595,9 @@ class Editor extends Model
# {Delegates to: DisplayBuffer.bufferRowsForScreenRows}
bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow)
# {Delegats to: DisplayBuffer.lineNumbersForScreenRows}
lineNumbersForScreenRows: (startRow, endRow) -> @displayBuffer.lineNumbersForScreenRows(startRow, endRow)
bufferRowForScreenRow: (row) -> @displayBuffer.bufferRowForScreenRow(row)
# Public: Get the syntactic scopes for the given position in buffer
@@ -1588,8 +1595,14 @@ class Editor extends Model
moveCursorToBeginningOfPreviousParagraph: ->
@moveCursors (cursor) -> cursor.moveToBeginningOfPreviousParagraph()
scrollToCursorPosition: ->
@getCursor().autoscroll()
# Public: Scroll the editor to reveal the most recently added cursor if it is
# off-screen.
#
# options - An optional hash of options.
# :center - Center the editor around the cursor if possible. Defauls to
# true.
scrollToCursorPosition: (options) ->
@getCursor().autoscroll(center: options?.center ? true)
pageUp: ->
newScrollTop = @getScrollTop() - @getHeight()
@@ -2019,6 +2032,12 @@ class Editor extends Model
getScrollHeight: -> @displayBuffer.getScrollHeight()
getScrollWidth: (scrollWidth) -> @displayBuffer.getScrollWidth(scrollWidth)
setBackgroundColor: (@backgroundColor) -> @backgroundColor
getBackgroundColor: -> @backgroundColor
setGutterBackgroundColor: (@gutterBackgroundColor) -> @gutterBackgroundColor
getGutterBackgroundColor: -> @gutterBackgroundColor
getVisibleRowRange: -> @displayBuffer.getVisibleRowRange()
intersectsVisibleRowRange: (startRow, endRow) -> @displayBuffer.intersectsVisibleRowRange(startRow, endRow)
+35 -174
Ver Arquivo
@@ -4,6 +4,7 @@ React = require 'react-atom-fork'
{isEqual, isEqualForProperties, multiplyString, toArray} = require 'underscore-plus'
Decoration = require './decoration'
SubscriberMixin = require './subscriber-mixin'
GutterTileComponent = require './gutter-tile-component'
WrapperDiv = document.createElement('div')
@@ -16,196 +17,51 @@ GutterComponent = React.createClass
measuredWidth: null
render: ->
{scrollHeight, scrollViewHeight, onMouseDown, backgroundColor, gutterBackgroundColor} = @props
if gutterBackgroundColor isnt 'rbga(0, 0, 0, 0)'
backgroundColor = gutterBackgroundColor
div className: 'gutter', onClick: @onClick, onMouseDown: onMouseDown,
div className: 'line-numbers', ref: 'lineNumbers', style:
height: Math.max(scrollHeight, scrollViewHeight)
WebkitTransform: @getTransform()
backgroundColor: backgroundColor
getTransform: ->
{scrollTop, useHardwareAcceleration} = @props
if useHardwareAcceleration
"translate3d(0px, #{-scrollTop}px, 0px)"
else
"translate(0px, #{-scrollTop}px)"
div className: 'gutter', onClick: @onClick, onMouseDown: @props.onMouseDown
componentWillMount: ->
@lineNumberNodesById = {}
@lineNumberIdsByScreenRow = {}
@screenRowsByLineNumberId = {}
@renderedDecorationsByLineNumberId = {}
@tileComponentsByStartRow = {}
componentDidMount: ->
@appendDummyLineNumber()
@updateLineNumbers() if @props.performedInitialMeasurement
# Only update the gutter if the visible row range has changed or if a
# non-zero-delta change to the screen lines has occurred within the current
# visible row range.
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props,
'renderedRowRange', 'scrollTop', 'lineHeightInPixels', 'mouseWheelScreenRow', 'lineDecorations',
'scrollViewHeight', 'useHardwareAcceleration', 'backgroundColor', 'gutterBackgroundColor'
)
{renderedRowRange, pendingChanges, lineDecorations} = newProps
return false unless renderedRowRange?
for change in pendingChanges when Math.abs(change.screenDelta) > 0 or Math.abs(change.bufferDelta) > 0
return true unless change.end <= renderedRowRange.start or renderedRowRange.end <= change.start
false
@appendDummyTile()
@getDOMNode().addEventListener 'mousewheel', @onMouseWheel
componentDidUpdate: (oldProps) ->
return unless @props.performedInitialMeasurement
if @props.performedInitialMeasurement
@updateTiles()
unless isEqualForProperties(oldProps, @props, 'maxLineNumberDigits')
@updateDummyLineNumber()
@removeLineNumberNodes()
updateTiles: ->
{gutterPresenter} = @props
@clearScreenRowCaches() unless oldProps.lineHeightInPixels is @props.lineHeightInPixels
@updateLineNumbers()
domNode = @getDOMNode()
clearScreenRowCaches: ->
@lineNumberIdsByScreenRow = {}
@screenRowsByLineNumberId = {}
for tileStartRow, tileComponent of @tileComponentsByStartRow
unless gutterPresenter.tiles[tileStartRow]?
if tileComponent.domNode is @preservedTileNode
tileComponent.preserve()
else
domNode.removeChild(tileComponent.domNode)
delete @tileComponentsByStartRow[tileStartRow]
for tileStartRow, tilePresenter of gutterPresenter.tiles
if tileComponent = @tileComponentsByStartRow[tileStartRow]
tileComponent = @tileComponentsByStartRow[tileStartRow]
tileComponent.revive(tilePresenter) if tileComponent.preserved
tileComponent.update()
else
tileComponent = new GutterTileComponent(tilePresenter)
@tileComponentsByStartRow[tileStartRow] = tileComponent
domNode.appendChild(tileComponent.domNode)
# This dummy line number element holds the gutter to the appropriate width,
# since the real line numbers are absolutely positioned for performance reasons.
appendDummyLineNumber: ->
{maxLineNumberDigits} = @props
WrapperDiv.innerHTML = @buildLineNumberHTML(-1, false, maxLineNumberDigits)
@dummyLineNumberNode = WrapperDiv.children[0]
@refs.lineNumbers.getDOMNode().appendChild(@dummyLineNumberNode)
appendDummyTile: ->
@dummyTileComponent = new GutterTileComponent(@props.gutterPresenter.dummyTile)
@getDOMNode().appendChild(@dummyTileComponent.domNode)
updateDummyLineNumber: ->
@dummyLineNumberNode.innerHTML = @buildLineNumberInnerHTML(0, false, @props.maxLineNumberDigits)
updateLineNumbers: ->
lineNumberIdsToPreserve = @appendOrUpdateVisibleLineNumberNodes()
@removeLineNumberNodes(lineNumberIdsToPreserve)
appendOrUpdateVisibleLineNumberNodes: ->
{editor, renderedRowRange, scrollTop, maxLineNumberDigits, lineDecorations} = @props
[startRow, endRow] = renderedRowRange
newLineNumberIds = null
newLineNumbersHTML = null
visibleLineNumberIds = new Set
wrapCount = 0
for bufferRow, index in editor.bufferRowsForScreenRows(startRow, endRow - 1)
screenRow = startRow + index
if bufferRow is lastBufferRow
id = "#{bufferRow}-#{wrapCount++}"
else
id = bufferRow.toString()
lastBufferRow = bufferRow
wrapCount = 0
visibleLineNumberIds.add(id)
if @hasLineNumberNode(id)
@updateLineNumberNode(id, bufferRow, screenRow, wrapCount > 0)
else
newLineNumberIds ?= []
newLineNumbersHTML ?= ""
newLineNumberIds.push(id)
newLineNumbersHTML += @buildLineNumberHTML(bufferRow, wrapCount > 0, maxLineNumberDigits, screenRow)
@screenRowsByLineNumberId[id] = screenRow
@lineNumberIdsByScreenRow[screenRow] = id
@renderedDecorationsByLineNumberId[id] = lineDecorations[screenRow]
if newLineNumberIds?
WrapperDiv.innerHTML = newLineNumbersHTML
newLineNumberNodes = toArray(WrapperDiv.children)
node = @refs.lineNumbers.getDOMNode()
for lineNumberId, i in newLineNumberIds
lineNumberNode = newLineNumberNodes[i]
@lineNumberNodesById[lineNumberId] = lineNumberNode
node.appendChild(lineNumberNode)
visibleLineNumberIds
removeLineNumberNodes: (lineNumberIdsToPreserve) ->
{mouseWheelScreenRow} = @props
node = @refs.lineNumbers.getDOMNode()
for lineNumberId, lineNumberNode of @lineNumberNodesById when not lineNumberIdsToPreserve?.has(lineNumberId)
screenRow = @screenRowsByLineNumberId[lineNumberId]
if not screenRow? or screenRow isnt mouseWheelScreenRow
delete @lineNumberNodesById[lineNumberId]
delete @lineNumberIdsByScreenRow[screenRow] if @lineNumberIdsByScreenRow[screenRow] is lineNumberId
delete @screenRowsByLineNumberId[lineNumberId]
delete @renderedDecorationsByLineNumberId[lineNumberId]
node.removeChild(lineNumberNode)
buildLineNumberHTML: (bufferRow, softWrapped, maxLineNumberDigits, screenRow) ->
{editor, lineHeightInPixels, lineDecorations} = @props
if screenRow?
style = "position: absolute; top: #{screenRow * lineHeightInPixels}px;"
else
style = "visibility: hidden;"
innerHTML = @buildLineNumberInnerHTML(bufferRow, softWrapped, maxLineNumberDigits)
classes = ''
if lineDecorations? and decorations = lineDecorations[screenRow]
for id, decoration of decorations
if Decoration.isType(decoration, 'gutter')
classes += decoration.class + ' '
classes += "foldable " if bufferRow >= 0 and editor.isFoldableAtBufferRow(bufferRow)
classes += "line-number line-number-#{bufferRow}"
"<div class=\"#{classes}\" style=\"#{style}\" data-buffer-row=\"#{bufferRow}\" data-screen-row=\"#{screenRow}\">#{innerHTML}</div>"
buildLineNumberInnerHTML: (bufferRow, softWrapped, maxLineNumberDigits) ->
if softWrapped
lineNumber = ""
else
lineNumber = (bufferRow + 1).toString()
padding = multiplyString('&nbsp;', maxLineNumberDigits - lineNumber.length)
iconHTML = '<div class="icon-right"></div>'
padding + lineNumber + iconHTML
updateLineNumberNode: (lineNumberId, bufferRow, screenRow, softWrapped) ->
{editor, lineDecorations} = @props
node = @lineNumberNodesById[lineNumberId]
if editor.isFoldableAtBufferRow(bufferRow)
node.classList.add('foldable')
else
node.classList.remove('foldable')
decorations = lineDecorations[screenRow]
previousDecorations = @renderedDecorationsByLineNumberId[lineNumberId]
if previousDecorations?
for id, decoration of previousDecorations
if Decoration.isType(decoration, 'gutter') and not @hasDecoration(decorations, decoration)
node.classList.remove(decoration.class)
if decorations?
for id, decoration of decorations
if Decoration.isType(decoration, 'gutter') and not @hasDecoration(previousDecorations, decoration)
node.classList.add(decoration.class)
unless @screenRowsByLineNumberId[lineNumberId] is screenRow
{lineHeightInPixels} = @props
node.style.top = screenRow * lineHeightInPixels + 'px'
node.dataset.screenRow = screenRow
@screenRowsByLineNumberId[lineNumberId] = screenRow
@lineNumberIdsByScreenRow[screenRow] = lineNumberId
hasDecoration: (decorations, decoration) ->
decorations? and decorations[decoration.id] is decoration
@@ -226,3 +82,8 @@ GutterComponent = React.createClass
editor.unfoldBufferRow(bufferRow)
else
editor.foldBufferRow(bufferRow)
onMouseWheel: (event) ->
node = event.target
node = node.parentNode until not node? or node.dataset.tile
@preservedTileNode = node
+166
Ver Arquivo
@@ -0,0 +1,166 @@
{toArray, multiplyString, clone} = require 'underscore-plus'
WrapperDiv = document.createElement('div')
module.exports =
class GutterTileComponent
preserved: false
constructor: (@presenter) ->
@lineNumberNodesById = {}
@screenRowsByLineNumberId = {}
@lineNumberDecorationsByLineNumberId = {}
@domNode = document.createElement('div')
@domNode.dataset.tile = true
@domNode.style.overflow = 'hidden'
if @presenter.dummy
@domNode.style.visibility = 'hidden'
else
@domNode.style.position = 'absolute'
@domNode.style.top = '0px'
@appendDummyLineNumber()
@update()
appendDummyLineNumber: ->
WrapperDiv.innerHTML = @buildLineNumberHTML('0')
@domNode.appendChild(WrapperDiv.firstChild)
update: ->
return if @presenter.dummy
@updateTransform()
@updateHeight()
@updateBackgroundColor()
@updateLineNumbers()
preserve: ->
return if @preserved
@domNode.style.visibility = 'hidden'
@preserved = true
revive: (@presenter) ->
@domNode.style.visibility = ''
@visible = true
updateTransform: ->
{top} = @presenter
unless top is @top
@domNode.style['-webkit-transform'] = "translate3d(0px, #{top}px, 0px)"
@top = top
updateHeight: ->
{height} = @presenter
unless height is @height
@domNode.style.height = height + 'px'
@height = height
updateBackgroundColor: ->
{backgroundColor} = @presenter
unless backgroundColor is @backgroundColor
@domNode.style.backgroundColor = backgroundColor
@backgroundColor = backgroundColor
updateLineNumbers: ->
{lineNumbers, lineNumberDecorations} = @presenter
lineNumbersSet = new Set
lineNumbersSet.add(lineNumber) for lineNumber in lineNumbers
for lineNumberId, lineNumberNode of @lineNumberNodesById
unless lineNumbersSet.has(lineNumberId)
delete @lineNumberNodesById[lineNumberId]
delete @screenRowsByLineNumberId[lineNumberId]
delete @lineNumberDecorationsByLineNumberId[lineNumberId]
@domNode.removeChild(lineNumberNode)
newLineNumberIds = []
newLineNumbersHTML = ""
for lineNumberId, i in lineNumbers
screenRow = @presenter.startRow + i
if @lineNumberNodesById[lineNumberId]?
@updateLineNumberNode(lineNumberId, screenRow)
else
newLineNumberIds.push(lineNumberId)
newLineNumbersHTML += @buildLineNumberHTML(lineNumberId, screenRow)
@screenRowsByLineNumberId[lineNumberId] = screenRow
# @lineNumberIdsByScreenRow[screenRow] = id
@lineNumberDecorationsByLineNumberId[lineNumberId] = clone(lineNumberDecorations[screenRow])
if newLineNumberIds.length > 0
WrapperDiv.innerHTML = newLineNumbersHTML
newLineNumberNodes = toArray(WrapperDiv.children)
for lineNumberId, i in newLineNumberIds
@lineNumberNodesById[lineNumberId] = newLineNumberNodes[i]
@lineNumberDecorationsByLineNumberId
@domNode.appendChild(newLineNumberNodes[i])
buildLineNumberHTML: (lineNumberId, screenRow) ->
{lineHeightInPixels, lineNumberDecorations} = @presenter
if screenRow?
top = (screenRow - @presenter.startRow) * lineHeightInPixels
style = "position: absolute; top: #{top}px;"
else
style = "visibility: hidden;"
innerHTML = @buildLineNumberInnerHTML(lineNumberId)
classes = ''
if decorationsById = lineNumberDecorations?[screenRow]
for id, decoration of decorationsById
classes += decoration.class + ' '
# classes += "foldable " if bufferRow >= 0 and editor.isFoldableAtBufferRow(bufferRow)
classes += "line-number line-number-#{lineNumberId.replace(/\..*/, '')}"
"<div class=\"#{classes}\" style=\"#{style}\" data-screen-row=\"#{screenRow}\">#{innerHTML}</div>"
buildLineNumberInnerHTML: (lineNumberId) ->
{maxLineNumberDigits} = @presenter
softWrapped = lineNumberId.indexOf('.') isnt -1
if softWrapped
lineNumber = ""
else
lineNumber = lineNumberId
padding = multiplyString('&nbsp;', maxLineNumberDigits - lineNumber.length)
iconHTML = '<div class="icon-right"></div>'
padding + lineNumber + iconHTML
updateLineNumberNode: (lineNumberId, screenRow) ->
{lineDecorations} = @presenter
node = @lineNumberNodesById[lineNumberId]
# if editor.isFoldableAtBufferRow(bufferRow)
# node.classList.add('foldable')
# else
# node.classList.remove('foldable')
unless @screenRowsByLineNumberId[lineNumberId] is screenRow
{lineHeightInPixels} = @presenter
node.style.top = screenRow * lineHeightInPixels + 'px'
node.dataset.screenRow = screenRow
@screenRowsByLineNumberId[lineNumberId] = screenRow
# @lineNumberIdsByScreenRow[screenRow] = lineNumberId
@updateLineNumberDecorations(node, lineNumberId, screenRow)
updateLineNumberDecorations: (lineNumberNode, lineNumberId, screenRow) ->
desiredDecorations = @presenter.lineNumberDecorations[screenRow]
if currentDecorations = @lineNumberDecorationsByLineNumberId[lineNumberId]
for id, decoration of currentDecorations
unless desiredDecorations?[id]?
lineNumberNode.classList.remove(decoration.class)
delete currentDecorations[id]
if desiredDecorations?
currentDecorations = (@lineNumberDecorationsByLineNumberId[lineNumberId] ?= {})
for id, decoration of desiredDecorations
unless currentDecorations[id]?
lineNumberNode.classList.add(decoration.class)
currentDecorations[id] = decoration
+10 -10
Ver Arquivo
@@ -43,12 +43,12 @@ class LanguageMode
commentStartRegex = new OnigRegExp("^(\\s*)(#{commentStartRegexString})")
if commentEndString
shouldUncomment = commentStartRegex.test(buffer.lineForRow(start))
shouldUncomment = commentStartRegex.testSync(buffer.lineForRow(start))
if shouldUncomment
commentEndRegexString = _.escapeRegExp(commentEndString).replace(/^(\s+)/, '(?:$1)?')
commentEndRegex = new OnigRegExp("(#{commentEndRegexString})(\\s*)$")
startMatch = commentStartRegex.search(buffer.lineForRow(start))
endMatch = commentEndRegex.search(buffer.lineForRow(end))
startMatch = commentStartRegex.searchSync(buffer.lineForRow(start))
endMatch = commentEndRegex.searchSync(buffer.lineForRow(end))
if startMatch and endMatch
buffer.transact ->
columnStart = startMatch[1].length
@@ -72,13 +72,13 @@ class LanguageMode
blank = line?.match(/^\s*$/)
allBlank = false unless blank
allBlankOrCommented = false unless blank or commentStartRegex.test(line)
allBlankOrCommented = false unless blank or commentStartRegex.testSync(line)
shouldUncomment = allBlankOrCommented and not allBlank
if shouldUncomment
for row in [start..end]
if match = commentStartRegex.search(buffer.lineForRow(row))
if match = commentStartRegex.searchSync(buffer.lineForRow(row))
columnStart = match[1].length
columnEnd = columnStart + match[2].length
buffer.setTextInRange([[row, columnStart], [row, columnEnd]], "")
@@ -168,7 +168,7 @@ class LanguageMode
continue if @editor.isBufferRowBlank(row)
indentation = @editor.indentationForBufferRow(row)
if indentation <= startIndentLevel
includeRowInFold = indentation == startIndentLevel and @foldEndRegexForScopes(scopes)?.search(@editor.lineForBufferRow(row))
includeRowInFold = indentation == startIndentLevel and @foldEndRegexForScopes(scopes)?.searchSync(@editor.lineForBufferRow(row))
foldEndRow = row if includeRowInFold
break
@@ -250,10 +250,10 @@ class LanguageMode
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex.test(precedingLine) and not @editor.isBufferRowCommented(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex.testSync(precedingLine) and not @editor.isBufferRowCommented(precedingRow)
return desiredIndentLevel unless decreaseIndentRegex = @decreaseIndentRegexForScopes(scopes)
desiredIndentLevel -= 1 if decreaseIndentRegex.test(currentLine)
desiredIndentLevel -= 1 if decreaseIndentRegex.testSync(currentLine)
Math.max(desiredIndentLevel, 0)
@@ -293,7 +293,7 @@ class LanguageMode
return unless increaseIndentRegex and decreaseIndentRegex
line = @buffer.lineForRow(bufferRow)
return unless decreaseIndentRegex.test(line)
return unless decreaseIndentRegex.testSync(line)
currentIndentLevel = @editor.indentationForBufferRow(bufferRow)
return if currentIndentLevel is 0
@@ -302,7 +302,7 @@ class LanguageMode
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel -= 1 unless increaseIndentRegex.test(precedingLine)
desiredIndentLevel -= 1 unless increaseIndentRegex.testSync(precedingLine)
if desiredIndentLevel >= 0 and desiredIndentLevel < currentIndentLevel
@editor.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
+57 -227
Ver Arquivo
@@ -5,7 +5,9 @@ React = require 'react-atom-fork'
{$$} = require 'space-pen'
Decoration = require './decoration'
CursorsComponent = require './cursors-component'
HighlightsComponent = require './highlights-component'
EditorTileComponent = require './editor-tile-component'
DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0]
AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT}
@@ -15,43 +17,27 @@ module.exports =
LinesComponent = React.createClass
displayName: 'LinesComponent'
tileSize: 5
preservedTileNode: null
render: ->
{performedInitialMeasurement} = @props
if performedInitialMeasurement
{editor, highlightDecorations, scrollHeight, scrollWidth, placeholderText, backgroundColor} = @props
{lineHeightInPixels, defaultCharWidth, scrollViewHeight, scopedCharacterWidthsChangeCount} = @props
style =
height: Math.max(scrollHeight, scrollViewHeight)
width: scrollWidth
WebkitTransform: @getTransform()
backgroundColor: backgroundColor
div {className: 'lines', style},
div className: 'placeholder-text', placeholderText if placeholderText?
HighlightsComponent({editor, highlightDecorations, lineHeightInPixels, defaultCharWidth, scopedCharacterWidthsChangeCount, performedInitialMeasurement})
getTransform: ->
{scrollTop, scrollLeft, useHardwareAcceleration} = @props
if useHardwareAcceleration
"translate3d(#{-scrollLeft}px, #{-scrollTop}px, 0px)"
else
"translate(#{-scrollLeft}px, #{-scrollTop}px)"
div className: 'lines'
componentWillMount: ->
@measuredLines = new WeakSet
@lineNodesByLineId = {}
@screenRowsByLineId = {}
@lineIdsByScreenRow = {}
@renderedDecorationsByLineId = {}
@tileComponentsByStartRow = {}
componentDidMount: ->
@getDOMNode().addEventListener 'mousewheel', @onMouseWheel
shouldComponentUpdate: (newProps) ->
return true
return true unless isEqualForProperties(newProps, @props,
'renderedRowRange', 'lineDecorations', 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth',
'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically', 'invisibles', 'visible',
'scrollViewHeight', 'mouseWheelScreenRow', 'scopedCharacterWidthsChangeCount', 'lineWidth', 'useHardwareAcceleration',
'placeholderText', 'performedInitialMeasurement', 'backgroundColor'
'placeholderText', 'performedInitialMeasurement', 'backgroundColor', 'cursorPixelRects'
)
{renderedRowRange, pendingChanges} = newProps
@@ -67,209 +53,19 @@ LinesComponent = React.createClass
false
componentDidUpdate: (prevProps) ->
{visible, scrollingVertically, performedInitialMeasurement} = @props
{performedInitialMeasurement, visible, scrollingVertically} = @props
return unless performedInitialMeasurement
@clearScreenRowCaches() unless prevProps.lineHeightInPixels is @props.lineHeightInPixels
@removeLineNodes() unless isEqualForProperties(prevProps, @props, 'showIndentGuide', 'invisibles')
@updateLines(@props.lineWidth isnt prevProps.lineWidth)
@clearTiles() unless isEqualForProperties(prevProps, @props, 'showIndentGuide', 'invisibles')
@updateTiles()
@measureCharactersInNewLines() if visible and not scrollingVertically
clearScreenRowCaches: ->
@screenRowsByLineId = {}
@lineIdsByScreenRow = {}
updateLines: (updateWidth) ->
{editor, renderedRowRange, showIndentGuide, selectionChanged, lineDecorations} = @props
[startRow, endRow] = renderedRowRange
visibleLines = editor.linesForScreenRows(startRow, endRow - 1)
@removeLineNodes(visibleLines)
@appendOrUpdateVisibleLineNodes(visibleLines, startRow, updateWidth)
removeLineNodes: (visibleLines=[]) ->
{mouseWheelScreenRow} = @props
visibleLineIds = new Set
visibleLineIds.add(line.id.toString()) for line in visibleLines
node = @getDOMNode()
for lineId, lineNode of @lineNodesByLineId when not visibleLineIds.has(lineId)
screenRow = @screenRowsByLineId[lineId]
if not screenRow? or screenRow isnt mouseWheelScreenRow
delete @lineNodesByLineId[lineId]
delete @lineIdsByScreenRow[screenRow] if @lineIdsByScreenRow[screenRow] is lineId
delete @screenRowsByLineId[lineId]
delete @renderedDecorationsByLineId[lineId]
node.removeChild(lineNode)
appendOrUpdateVisibleLineNodes: (visibleLines, startRow, updateWidth) ->
{lineDecorations} = @props
newLines = null
newLinesHTML = null
for line, index in visibleLines
screenRow = startRow + index
if @hasLineNode(line.id)
@updateLineNode(line, screenRow, updateWidth)
else
newLines ?= []
newLinesHTML ?= ""
newLines.push(line)
newLinesHTML += @buildLineHTML(line, screenRow)
@screenRowsByLineId[line.id] = screenRow
@lineIdsByScreenRow[screenRow] = line.id
@renderedDecorationsByLineId[line.id] = lineDecorations[screenRow]
return unless newLines?
WrapperDiv.innerHTML = newLinesHTML
newLineNodes = toArray(WrapperDiv.children)
node = @getDOMNode()
for line, i in newLines
lineNode = newLineNodes[i]
@lineNodesByLineId[line.id] = lineNode
node.appendChild(lineNode)
hasLineNode: (lineId) ->
@lineNodesByLineId.hasOwnProperty(lineId)
buildLineHTML: (line, screenRow) ->
{editor, mini, showIndentGuide, lineHeightInPixels, lineDecorations, lineWidth} = @props
{tokens, text, lineEnding, fold, isSoftWrapped, indentLevel} = line
classes = ''
if decorations = lineDecorations[screenRow]
for id, decoration of decorations
if Decoration.isType(decoration, 'line')
classes += decoration.class + ' '
classes += 'line'
top = screenRow * lineHeightInPixels
lineHTML = "<div class=\"#{classes}\" style=\"position: absolute; top: #{top}px; width: #{lineWidth}px;\" data-screen-row=\"#{screenRow}\">"
if text is ""
lineHTML += @buildEmptyLineInnerHTML(line)
else
lineHTML += @buildLineInnerHTML(line)
lineHTML += '<span class="fold-marker"></span>' if fold
lineHTML += "</div>"
lineHTML
buildEmptyLineInnerHTML: (line) ->
{showIndentGuide, invisibles} = @props
{cr, eol} = invisibles
{indentLevel, tabLength} = line
if showIndentGuide and indentLevel > 0
invisiblesToRender = []
invisiblesToRender.push(cr) if cr? and line.lineEnding is '\r\n'
invisiblesToRender.push(eol) if eol?
lineHTML = ''
for i in [0...indentLevel]
lineHTML += "<span class='indent-guide'>"
for j in [0...tabLength]
if invisible = invisiblesToRender.shift()
lineHTML += "<span class='invisible-character'>#{invisible}</span>"
else
lineHTML += ' '
lineHTML += "</span>"
while invisiblesToRender.length
lineHTML += "<span class='invisible-character'>#{invisiblesToRender.shift()}</span>"
lineHTML
else
@buildEndOfLineHTML(line, @props.invisibles) or '&nbsp;'
buildLineInnerHTML: (line) ->
{invisibles, mini, showIndentGuide, invisibles} = @props
{tokens, text} = line
innerHTML = ""
scopeStack = []
firstTrailingWhitespacePosition = text.search(/\s*$/)
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
for token in tokens
innerHTML += @updateScopeStack(scopeStack, token.scopes)
hasIndentGuide = not mini and showIndentGuide and (token.hasLeadingWhitespace or (token.hasTrailingWhitespace and lineIsWhitespaceOnly))
innerHTML += token.getValueAsHtml({invisibles, hasIndentGuide})
innerHTML += @popScope(scopeStack) while scopeStack.length > 0
innerHTML += @buildEndOfLineHTML(line, invisibles)
innerHTML
buildEndOfLineHTML: (line, invisibles) ->
return '' if @props.mini or line.isSoftWrapped()
html = ''
# Note the lack of '?' in the character checks. A user can set the chars
# to an empty string which we will interpret as not-set
if invisibles.cr and line.lineEnding is '\r\n'
html += "<span class='invisible-character'>#{invisibles.cr}</span>"
if invisibles.eol
html += "<span class='invisible-character'>#{invisibles.eol}</span>"
html
updateScopeStack: (scopeStack, desiredScopes) ->
html = ""
# Find a common prefix
for scope, i in desiredScopes
break unless scopeStack[i] is desiredScopes[i]
# Pop scopes until we're at the common prefx
until scopeStack.length is i
html += @popScope(scopeStack)
# Push onto common prefix until scopeStack equals desiredScopes
for j in [i...desiredScopes.length]
html += @pushScope(scopeStack, desiredScopes[j])
html
popScope: (scopeStack) ->
scopeStack.pop()
"</span>"
pushScope: (scopeStack, scope) ->
scopeStack.push(scope)
"<span class=\"#{scope.replace(/\.+/g, ' ')}\">"
updateLineNode: (line, screenRow, updateWidth) ->
{editor, lineHeightInPixels, lineDecorations, lineWidth} = @props
lineNode = @lineNodesByLineId[line.id]
decorations = lineDecorations[screenRow]
previousDecorations = @renderedDecorationsByLineId[line.id]
if previousDecorations?
for id, decoration of previousDecorations
if Decoration.isType(decoration, 'line') and not @hasDecoration(decorations, decoration)
lineNode.classList.remove(decoration.class)
if decorations?
for id, decoration of decorations
if Decoration.isType(decoration, 'line') and not @hasDecoration(previousDecorations, decoration)
lineNode.classList.add(decoration.class)
lineNode.style.width = lineWidth + 'px' if updateWidth
unless @screenRowsByLineId[line.id] is screenRow
lineNode.style.top = screenRow * lineHeightInPixels + 'px'
lineNode.dataset.screenRow = screenRow
@screenRowsByLineId[line.id] = screenRow
@lineIdsByScreenRow[screenRow] = line.id
hasDecoration: (decorations, decoration) ->
decorations? and decorations[decoration.id] is decoration
lineNodeForScreenRow: (screenRow) ->
@lineNodesByLineId[@lineIdsByScreenRow[screenRow]]
tileComponent = @tileComponentsByStartRow[@tileStartRowForScreenRow(screenRow)]
tileComponent?.lineNodeForScreenRow(screenRow)
tileStartRowForScreenRow: (screenRow) ->
screenRow - (screenRow % @tileSize)
measureLineHeightAndDefaultCharWidth: ->
node = @getDOMNode()
@@ -282,19 +78,48 @@ LinesComponent = React.createClass
editor.setLineHeightInPixels(lineHeightInPixels)
editor.setDefaultCharWidth(charWidth)
updateTiles: ->
{contentPresenter} = @props
domNode = @getDOMNode()
for tileStartRow, tileComponent of @tileComponentsByStartRow
unless contentPresenter.tiles[tileStartRow]?
if tileComponent.domNode is @preservedTileNode
tileComponent.preserve()
else
domNode.removeChild(tileComponent.domNode)
delete @tileComponentsByStartRow[tileStartRow]
for tileStartRow, tilePresenter of contentPresenter.tiles
if tileComponent = @tileComponentsByStartRow[tileStartRow]
tileComponent = @tileComponentsByStartRow[tileStartRow]
tileComponent.revive(tilePresenter) if tileComponent.preserved
tileComponent.update()
else
tileComponent = new EditorTileComponent(tilePresenter)
@tileComponentsByStartRow[tileStartRow] = tileComponent
domNode.appendChild(tileComponent.domNode)
clearTiles: ->
for startRow, tileComponent of @tileComponentsByStartRow
domNode.removeChild(tileComponent.domNode)
delete @tileComponentsByStartRow[startRow]
remeasureCharacterWidths: ->
@clearScopedCharWidths()
@measureCharactersInNewLines()
measureCharactersInNewLines: ->
return
{editor} = @props
[visibleStartRow, visibleEndRow] = @props.renderedRowRange
node = @getDOMNode()
editor.batchCharacterMeasurement =>
for tokenizedLine in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
for tokenizedLine, i in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
screenRow = visibleStartRow + i
unless @measuredLines.has(tokenizedLine)
lineNode = @lineNodesByLineId[tokenizedLine.id]
lineNode = @lineNodeForScreenRow(screenRow)
@measureCharactersInLine(tokenizedLine, lineNode)
return
@@ -336,3 +161,8 @@ LinesComponent = React.createClass
clearScopedCharWidths: ->
@measuredLines.clear()
@props.editor.clearScopedCharWidths()
onMouseWheel: (event) ->
node = event.target
node = node.parentNode until node.dataset.tile
@preservedTileNode = node
+70
Ver Arquivo
@@ -269,6 +269,7 @@ class Package
requireMainModule: ->
return @mainModule if @mainModule?
return unless @isCompatible()
mainModulePath = @getMainModulePath()
@mainModule = require(mainModulePath) if fs.isFileSync(mainModulePath)
@@ -340,3 +341,72 @@ class Package
for eventHandler in eventHandlers
eventHandler.handler = eventHandler.disabledHandler
delete eventHandler.disabledHandler
# Does the given module path contain native code?
isNativeModule: (modulePath) ->
try
fs.listSync(path.join(modulePath, 'build', 'Release'), ['.node']).length > 0
catch error
false
# Get an array of all the native modules that this package depends on.
# This will recurse through all dependencies.
getNativeModuleDependencyPaths: ->
nativeModulePaths = []
traversePath = (nodeModulesPath) =>
try
for modulePath in fs.listSync(nodeModulesPath)
nativeModulePaths.push(modulePath) if @isNativeModule(modulePath)
traversePath(path.join(modulePath, 'node_modules'))
traversePath(path.join(@path, 'node_modules'))
nativeModulePaths
# Get the incompatible native modules that this package depends on.
# This recurses through all dependencies and requires all modules that
# contain a `.node` file.
#
# This information is cached in local storage on a per package/version basis
# to minimize the impact on startup time.
getIncompatibleNativeModules: ->
localStorageKey = "installed-packages:#{@name}:#{@metadata.version}"
unless atom.inDevMode()
try
{incompatibleNativeModules} = JSON.parse(global.localStorage.getItem(localStorageKey)) ? {}
return incompatibleNativeModules if incompatibleNativeModules?
incompatibleNativeModules = []
for nativeModulePath in @getNativeModuleDependencyPaths()
try
require(nativeModulePath)
catch error
try
version = require("#{nativeModulePath}/package.json").version
incompatibleNativeModules.push
path: nativeModulePath
name: path.basename(nativeModulePath)
version: version
error: error.message
global.localStorage.setItem(localStorageKey, JSON.stringify({incompatibleNativeModules}))
incompatibleNativeModules
# Public: Is this package compatible with this version of Atom?
#
# Incompatible packages cannot be activated. This will include packages
# installed to ~/.atom/packages that were built against node 0.11.10 but
# now need to be upgrade to node 0.11.13.
#
# Returns a {Boolean}, true if compatible, false if incompatible.
isCompatible: ->
return @compatible if @compatible?
if @path.indexOf(path.join(atom.packages.resourcePath, 'node_modules') + path.sep) is 0
# Bundled packages are always considered compatible
@compatible = true
else if packageMain = @getMainModulePath()
@incompatibleModules = @getIncompatibleNativeModules()
@compatible = @incompatibleModules.length is 0
else
@compatible = true
+1 -1
Ver Arquivo
@@ -115,7 +115,7 @@ class ReactEditorView extends View
@find('.lines').prepend(view)
beforeRemove: ->
React.unmountComponentAtNode(@element)
React.unmountComponentAtNode(@element) if @component.isMounted()
@attached = false
@trigger 'editor:detached', this
+5 -2
Ver Arquivo
@@ -57,8 +57,7 @@ class WindowEventHandler
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
@subscribe $(document), 'keydown', (event) ->
atom.keymaps.handleKeyboardEvent(event.originalEvent)
document.addEventListener 'keydown', @onKeydown
@subscribe $(document), 'drop', (e) ->
e.preventDefault()
@@ -95,6 +94,10 @@ class WindowEventHandler
bindCommandToAction('core:redo', 'redo:')
bindCommandToAction('core:select-all', 'selectAll:')
onKeydown: (event) ->
atom.keymaps.handleKeyboardEvent(event)
event.stopImmediatePropagation()
openLink: ({target, currentTarget}) ->
location = target?.getAttribute('href') or currentTarget?.getAttribute('href')
if location and location[0] isnt '#' and /^https?:\/\//.test(location)
+25
Ver Arquivo
@@ -96,6 +96,11 @@ class WorkspaceView extends View
when 'overlay'
@addClass("scrollbars-visible-when-scrolling")
@subscribe atom.config.observe 'editor.fontSize', @setEditorFontSize
@subscribe atom.config.observe 'editor.fontFamily', @setEditorFontFamily
@subscribe atom.config.observe 'editor.lineHeight', @setEditorLineHeight
@updateTitle()
@on 'focus', (e) => @handleFocus(e)
@@ -340,6 +345,26 @@ class WorkspaceView extends View
beforeRemove: ->
@model.destroy()
setEditorFontSize: (fontSize) =>
@setEditorStyle('font-size', fontSize + 'px')
setEditorFontFamily: (fontFamily) =>
@setEditorStyle('font-family', fontFamily)
setEditorLineHeight: (lineHeight) =>
@setEditorStyle('line-height', lineHeight)
setEditorStyle: (property, value) ->
unless styleNode = atom.themes.stylesheetElementForId('global-editor-styles')[0]
atom.themes.applyStylesheet('global-editor-styles', '.editor {}')
styleNode = atom.themes.stylesheetElementForId('global-editor-styles')[0]
{sheet} = styleNode
editorRule = sheet.cssRules[0]
editorRule.style[property] = value
atom.themes.emit 'stylesheet-updated', sheet
atom.themes.emit 'stylesheets-changed'
# Deprecated
eachPane: (callback) ->
deprecate("Use WorkspaceView::eachPaneView instead")
+7 -4
Ver Arquivo
@@ -83,8 +83,15 @@
}
}
}
}
.editor.mini {
font-size: @input-font-size;
line-height: @component-line-height;
max-height: @component-line-height + 2; // +2 for borders
.placeholder-text {
position: absolute;
color: @text-color-subtle;
}
}
@@ -300,8 +307,4 @@
.scroll-view {
overflow: hidden;
}
.placeholder-text {
color: @text-color-subtle;
}
}
+1
Ver Arquivo
@@ -67,6 +67,7 @@
// Sizes
@font-size: 13px;
@input-font-size: 14px;
@disclosure-arrow-size: 12px;