Merge branch 'master' into as-double-reflow-measurements

# Conflicts:
#	src/text-editor-presenter.coffee
This commit is contained in:
Antonio Scandurra
2015-09-18 09:02:50 +02:00
58 changed files with 150 additions and 24 deletions

View File

@@ -31,13 +31,16 @@ module.exports = (grunt) ->
# This allows all subsequent paths to the relative to the root of the repo
grunt.file.setBase(path.resolve('..'))
[major, minor, patch] = packageJson.version.split('.')
tmpDir = os.tmpdir()
appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom'
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
buildDir = path.resolve(buildDir)
installDir = grunt.option('install-dir')
channel = grunt.option('channel')
channel ?= process.env.JANKY_BRANCH if process.env.JANKY_BRANCH in ['stable', 'beta']
channel ?= 'dev'
home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
electronDownloadDir = path.join(home, '.atom', 'electron')
@@ -153,7 +156,7 @@ module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON('package.json')
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir}
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir, channel}
docsOutputDir: 'docs/output'
@@ -234,8 +237,8 @@ module.exports = (grunt) ->
outputDirectory: path.join(buildDir, 'installer')
authors: 'GitHub Inc.'
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
setupIcon: path.resolve(__dirname, '..', 'resources', 'win', 'atom.ico')
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/stable/atom.ico'
setupIcon: path.resolve(__dirname, '..', 'resources', 'app-icons', 'stable', 'atom.ico')
remoteReleases: 'https://atom.io/api/updates'
shell:

View File

@@ -40,7 +40,6 @@ module.exports = (grunt) ->
'benchmark'
'dot-atom'
'vendor'
'resources'
]
{devDependencies} = grunt.file.readJSON('package.json')
@@ -86,9 +85,6 @@ module.exports = (grunt) ->
path.join('build', 'Release', 'obj')
path.join('build', 'Release', '.deps')
path.join('vendor', 'apm')
path.join('resources', 'linux')
path.join('resources', 'mac')
path.join('resources', 'win')
# These are only require in dev mode when the grammar isn't precompiled
path.join('snippets', 'node_modules', 'loophole')
@@ -179,10 +175,14 @@ module.exports = (grunt) ->
if process.platform isnt 'win32'
fs.symlinkSync(path.join('..', '..', 'bin', 'apm'), path.resolve(appDir, '..', 'new-app', 'apm', 'node_modules', '.bin', 'apm'))
channel = grunt.config.get('atom.channel')
cp path.join('resources', 'app-icons', channel, 'png', '1024.png'), path.join(appDir, 'resources', 'atom.png')
if process.platform is 'darwin'
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
unless /.+\.plist/.test(sourcePath)
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
cp path.join('resources', 'app-icons', channel, 'atom.icns'), path.resolve(appDir, '..', 'atom.icns')
cp path.join('resources', 'mac', 'file.icns'), path.resolve(appDir, '..', 'file.icns')
cp path.join('resources', 'mac', 'speakeasy.pem'), path.resolve(appDir, '..', 'speakeasy.pem')
if process.platform is 'win32'
cp path.join('resources', 'win', 'atom.cmd'), path.join(shellAppDir, 'resources', 'cli', 'atom.cmd')
@@ -191,7 +191,7 @@ module.exports = (grunt) ->
cp path.join('resources', 'win', 'apm.sh'), path.join(shellAppDir, 'resources', 'cli', 'apm.sh')
if process.platform is 'linux'
cp path.join('resources', 'linux', 'icons'), path.join(buildDir, 'icons')
cp path.join('resources', 'app-icons', channel, 'png'), path.join(buildDir, 'icons')
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
dependencies.push('copy-info-plist') if process.platform is 'darwin'

View File

@@ -23,6 +23,7 @@ module.exports = (grunt) ->
grunt.registerTask 'mkdeb', 'Create debian package', ->
done = @async()
buildDir = grunt.config.get('atom.buildDir')
channel = grunt.config.get('atom.channel')
if process.arch is 'ia32'
arch = 'i386'
@@ -41,10 +42,10 @@ module.exports = (grunt) ->
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize, executable}
controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data)
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data)
icon = path.join('resources', 'atom.png')
iconPath = path.join('resources', 'app-icons', channel, 'png', '1024.png')
cmd = path.join('script', 'mkdeb')
args = [version, arch, controlFilePath, desktopFilePath, icon, buildDir]
args = [version, arch, controlFilePath, desktopFilePath, iconPath, buildDir]
spawn {cmd, args}, (error) ->
if error?
done(error)

View File

@@ -4,9 +4,10 @@ module.exports = (grunt) ->
grunt.registerTask 'set-exe-icon', 'Set icon of the exe', ->
done = @async()
channel = grunt.config.get('atom.channel')
shellAppDir = grunt.config.get('atom.shellAppDir')
shellExePath = path.join(shellAppDir, 'atom.exe')
iconPath = path.resolve('resources', 'win', 'atom.ico')
iconPath = path.resolve('resources', 'app-icons', channel, 'atom.ico')
rcedit = require('rcedit')
rcedit(shellExePath, {'icon': iconPath}, done)

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "1.0.12-dev",
"version": "1.2.0-dev",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -109,7 +109,7 @@
"package-generator": "0.40.0",
"release-notes": "0.53.0",
"settings-view": "0.216.0",
"snippets": "0.98.0",
"snippets": "0.99.0",
"spell-check": "0.59.0",
"status-bar": "0.79.0",
"styleguide": "0.44.0",
@@ -121,14 +121,14 @@
"welcome": "0.30.0",
"whitespace": "0.31.0",
"wrap-guide": "0.36.0",
"language-c": "0.47.1",
"language-c": "0.48.0",
"language-clojure": "0.16.0",
"language-coffee-script": "0.41.0",
"language-csharp": "0.10.0",
"language-css": "0.34.0",
"language-gfm": "0.81.0",
"language-git": "0.10.0",
"language-go": "0.37.0",
"language-go": "0.39.0",
"language-html": "0.41.2",
"language-hyperlink": "0.14.0",
"language-java": "0.16.0",
@@ -142,7 +142,7 @@
"language-php": "0.30.0",
"language-property-list": "0.8.0",
"language-python": "0.40.0",
"language-ruby": "0.58.0",
"language-ruby": "0.59.0",
"language-ruby-on-rails": "0.22.0",
"language-sass": "0.41.0",
"language-shellscript": "0.17.0",

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 628 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 944 B

After

Width:  |  Height:  |  Size: 944 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 KiB

View File

@@ -48,12 +48,12 @@ function bumpStableVersion (next) {
}
function bumpBetaVersion (next) {
var newVersion = semver.inc(getCurrentVersion(), 'prerelease', 'beta')
var newVersion = semver.inc(getCurrentVersion(), 'preminor', 'beta')
run('npm version ' + newVersion)(next)
}
function bumpDevVersion (next) {
var newVersion = semver.inc(getCurrentVersion(), 'preminor', 'dev')
var newVersion = semver.inc(getCurrentVersion(), 'preminor', 'dev').replace(/\.0$/, '')
series([
run('npm --no-git-tag-version version ' + newVersion),
run('git commit -am "' + newVersion + '"')

View File

@@ -0,0 +1,12 @@
{
"name": "package-with-cached-incompatible-native-module",
"version": "1.0.0",
"main": "./main.js",
"_atomModuleCache": {
"extensions": {
".node": [
"node_modules/native-module/build/Release/native.node"
]
}
}
}

View File

@@ -0,0 +1,4 @@
{
"name": "compatible-native-module",
"main": "./main.js"
}

View File

@@ -0,0 +1 @@
throw new Error("this simulates a native module's failure to load")

View File

@@ -0,0 +1,4 @@
{
"name": "native-module",
"main": "./main.js"
}

View File

@@ -0,0 +1,12 @@
{
"name": "package-with-ignored-incompatible-native-module",
"version": "1.0.0",
"main": "./main.js",
"_atomModuleCache": {
"extensions": {
".node": [
"node_modules/compatible-native-module/build/Release/native.node"
]
}
}
}

View File

@@ -19,6 +19,16 @@ describe "Package", ->
expect(pack.incompatibleModules[0].name).toBe 'native-module'
expect(pack.incompatibleModules[0].path).toBe path.join(packagePath, 'node_modules', 'native-module')
it "utilizes _atomModuleCache if present to determine the package's native dependencies", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-ignored-incompatible-native-module')
pack = new Package(packagePath)
expect(pack.getNativeModuleDependencyPaths().length).toBe(1) # doesn't see the incompatible module
expect(pack.isCompatible()).toBe true
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-cached-incompatible-native-module')
pack = new Package(packagePath)
expect(pack.isCompatible()).toBe false
it "caches the incompatible native modules in local storage", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')

View File

@@ -418,6 +418,24 @@ describe "TextEditorComponent", ->
expect(leafNodes[0].classList.contains('trailing-whitespace')).toBe true
expect(leafNodes[0].classList.contains('leading-whitespace')).toBe false
it "keeps rebuilding lines when continuous reflow is on", ->
wrapperNode.setContinuousReflow(true)
oldLineNodes = componentNode.querySelectorAll(".line")
advanceClock(10)
expect(nextAnimationFrame).toBe(noAnimationFrame)
advanceClock(component.presenter.minimumReflowInterval - 10)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line")
expect(oldLineNodes).not.toEqual(newLineNodes)
wrapperNode.setContinuousReflow(false)
advanceClock(component.presenter.minimumReflowInterval)
expect(nextAnimationFrame).toBe(noAnimationFrame)
describe "when showInvisibles is enabled", ->
invisibles = null
@@ -855,6 +873,24 @@ describe "TextEditorComponent", ->
expect(componentNode.querySelector('.gutter').style.display).toBe ''
expect(component.lineNumberNodeForScreenRow(3)?).toBe true
it "keeps rebuilding line numbers when continuous reflow is on", ->
wrapperNode.setContinuousReflow(true)
oldLineNodes = componentNode.querySelectorAll(".line-number")
advanceClock(10)
expect(nextAnimationFrame).toBe(noAnimationFrame)
advanceClock(component.presenter.minimumReflowInterval - 10)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line-number")
expect(oldLineNodes).not.toEqual(newLineNodes)
wrapperNode.setContinuousReflow(false)
advanceClock(component.presenter.minimumReflowInterval)
expect(nextAnimationFrame).toBe(noAnimationFrame)
describe "fold decorations", ->
describe "rendering fold decorations", ->
it "adds the foldable class to line numbers when the line is foldable", ->

View File

@@ -64,6 +64,9 @@ class LineNumberGutterComponent extends TiledComponent
buildComponentForTile: (id) -> new LineNumbersTileComponent({id, @domElementPool})
shouldRecreateAllTilesOnUpdate: ->
@newState.continuousReflow
###
Section: Private Methods
###

View File

@@ -32,7 +32,7 @@ class LinesComponent extends TiledComponent
@domNode
shouldRecreateAllTilesOnUpdate: ->
@oldState.indentGuidesVisible isnt @newState.indentGuidesVisible
@oldState.indentGuidesVisible isnt @newState.indentGuidesVisible or @newState.continuousReflow
beforeUpdateSync: (state) ->
if @newState.maxHeight isnt @oldState.maxHeight

View File

@@ -590,10 +590,20 @@ class Package
false
# Get an array of all the native modules that this package depends on.
# This will recurse through all dependencies.
#
# First try to get this information from
# @metadata._atomModuleCache.extensions. If @metadata._atomModuleCache doesn't
# exist, recurse through all dependencies.
getNativeModuleDependencyPaths: ->
nativeModulePaths = []
if @metadata._atomModuleCache?
relativeNativeModuleBindingPaths = @metadata._atomModuleCache.extensions?['.node'] ? []
for relativeNativeModuleBindingPath in relativeNativeModuleBindingPaths
nativeModulePath = path.join(@path, relativeNativeModuleBindingPath, '..', '..', '..')
nativeModulePaths.push(nativeModulePath)
return nativeModulePaths
traversePath = (nodeModulesPath) =>
try
for modulePath in fs.listSync(nodeModulesPath)

View File

@@ -832,6 +832,9 @@ class TextEditorComponent
setInputEnabled: (@inputEnabled) -> @inputEnabled
setContinuousReflow: (continuousReflow) ->
@presenter.setContinuousReflow(continuousReflow)
updateParentViewFocusedClassIfNeeded: ->
if @oldState.focused isnt @newState.focused
@hostElement.classList.toggle('is-focused', @newState.focused)

View File

@@ -172,6 +172,12 @@ class TextEditorElement extends HTMLElement
isUpdatedSynchronously: -> @updatedSynchronously
# Extended: Continuously reflows lines and line numbers. (Has performance overhead)
#
# `continuousReflow` A {Boolean} indicating whether to keep reflowing or not.
setContinuousReflow: (continuousReflow) ->
@component?.setContinuousReflow(continuousReflow)
# Extended: get the width of a character of text displayed in this element.
#
# Returns a {Number} of pixels.

View File

@@ -11,6 +11,7 @@ class TextEditorPresenter
mouseWheelScreenRow: null
scopedCharacterWidthsChangeCount: 0
overlayDimensions: {}
minimumReflowInterval: 200
constructor: (params) ->
{@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params
@@ -36,6 +37,7 @@ class TextEditorPresenter
@buildState()
@invalidate()
@startBlinkingCursors() if @focused
@startReflowing() if @continuousReflow
@updating = false
setLinesYardstick: (@linesYardstick) ->
@@ -86,6 +88,7 @@ class TextEditorPresenter
@updateCommonGutterState()
@updateHorizontalDimensions()
@updateReflowState()
@updateFocusedState() if @shouldUpdateFocusedState
@updateHeightState() if @shouldUpdateHeightState
@@ -256,6 +259,23 @@ class TextEditorPresenter
@lineNumberGutter =
tiles: {}
setContinuousReflow: (@continuousReflow) ->
if @continuousReflow
@startReflowing()
else
@stopReflowing()
updateReflowState: ->
@state.content.continuousReflow = @continuousReflow
@lineNumberGutter.continuousReflow = @continuousReflow
startReflowing: ->
@reflowingInterval = setInterval(@emitDidUpdateState.bind(this), @minimumReflowInterval)
stopReflowing: ->
clearInterval(@reflowingInterval)
@reflowingInterval = null
updateFocusedState: ->
@state.focused = @focused