From 74c0e79986c25d04bdd57f80a72840aa91747861 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 16 Nov 2015 09:34:29 -0500 Subject: [PATCH 001/108] :arrow_up: electron@0.35.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a586cd4a..ab90b1a55 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.34.3", + "electronVersion": "0.35.0", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 6cd480b37e486738f376a7692f609bd673831c0a Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 21:16:09 -0500 Subject: [PATCH 002/108] Fix Electron deprecations --- spec/atom-environment-spec.coffee | 6 +++--- spec/atom-reporter.coffee | 2 +- spec/jasmine-test-runner.coffee | 2 +- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 2 +- spec/workspace-element-spec.coffee | 2 +- src/application-delegate.coffee | 4 ++-- src/atom-environment.coffee | 6 +++--- src/browser/application-menu.coffee | 2 +- src/browser/atom-application.coffee | 2 +- src/browser/atom-portable.coffee | 2 +- src/browser/atom-window.coffee | 2 +- src/browser/auto-update-manager.coffee | 2 +- src/browser/auto-updater-win32.coffee | 2 +- src/browser/main.coffee | 4 ++-- src/initialize-test-window.coffee | 2 +- src/menu-manager.coffee | 2 +- src/module-cache.coffee | 2 +- src/register-default-commands.coffee | 2 +- src/text-editor-component.coffee | 2 +- src/workspace-element.coffee | 2 +- static/index.js | 2 +- 22 files changed, 28 insertions(+), 28 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 23f8e0e51..2d8fd70ac 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -47,7 +47,7 @@ describe "AtomEnvironment", -> describe "window onerror handler", -> beforeEach -> spyOn atom, 'openDevTools' - spyOn atom, 'executeJavaScriptInDevTools' + spyOn atom, 'webContents.executeJavaScriptInDevTools' it "will open the dev tools when an error is triggered", -> try @@ -56,7 +56,7 @@ describe "AtomEnvironment", -> window.onerror.call(window, e.toString(), 'abc', 2, 3, e) expect(atom.openDevTools).toHaveBeenCalled() - expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() + expect(atom.webContents.executeJavaScriptInDevTools).toHaveBeenCalled() describe "::onWillThrowError", -> willThrowSpy = null @@ -91,7 +91,7 @@ describe "AtomEnvironment", -> expect(willThrowSpy).toHaveBeenCalled() expect(atom.openDevTools).not.toHaveBeenCalled() - expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled() + expect(atom.webContents.executeJavaScriptInDevTools).not.toHaveBeenCalled() describe "::onDidThrowError", -> didThrowSpy = null diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 35caecb34..9bc4bdbf9 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('ipc-main').send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 7ef34ce54..64191c1f4 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 609d20291..a7b6818f5 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('ipc-main'), 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 3148942b4..9cd68d5e8 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc' +ipc = require 'ipc-main' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 09c54d5ea..110b8d562 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' temp = require('temp').track() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 1999c6e83..ebd497c47 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,5 @@ _ = require 'underscore-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' remote = require 'remote' shell = require 'shell' webFrame = require 'web-frame' @@ -72,7 +72,7 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - remote.getCurrentWindow().executeJavaScriptInDevTools(code) + remote.getCurrentWindow().webContents.executeJavaScriptInDevTools(code) setWindowDocumentEdited: (edited) -> ipc.send("call-window-method", "setDocumentEdited", edited) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 938010607..6082ac4d0 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' _ = require 'underscore-plus' {deprecate} = require 'grim' @@ -671,7 +671,7 @@ class AtomEnvironment extends Model if openDevTools @openDevTools() - @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') + @webContents.executeJavaScriptInDevTools('DevToolsAPI.showConsole()') @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @@ -729,7 +729,7 @@ class AtomEnvironment extends Model @applicationDelegate.toggleWindowDevTools() # Extended: Execute code in dev tools. - executeJavaScriptInDevTools: (code) -> + webContents.executeJavaScriptInDevTools: (code) -> @applicationDelegate.executeJavaScriptInWindowDevTools(code) ### diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 27b9df8e1..b9b4eed92 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,5 @@ app = require 'app' -ipc = require 'ipc' +ipc = require 'ipc-main' Menu = require 'menu' _ = require 'underscore-plus' diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 8bb44349e..4001fba8e 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -9,7 +9,7 @@ app = require 'app' dialog = require 'dialog' shell = require 'shell' fs = require 'fs-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' os = require 'os' net = require 'net' diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 5f8f10cf6..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = class AtomPortable diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index c507b634c..4ab13ef0e 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -81,7 +81,7 @@ class AtomWindow loadSettings = _.clone(loadSettingsObj) delete loadSettings['windowState'] - @browserWindow.loadUrl url.format + @browserWindow.loadURL url.format protocol: 'file' pathname: "#{@resourcePath}/static/index.html" slashes: true diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 55ab2462b..f4a493829 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -31,7 +31,7 @@ class AutoUpdateManager @setState(ErrorState) console.error "Error Downloading Update: #{message}" - autoUpdater.setFeedUrl @feedUrl + autoUpdater.setFeedURL @feedUrl autoUpdater.on 'checking-for-update', => @setState(CheckingState) diff --git a/src/browser/auto-updater-win32.coffee b/src/browser/auto-updater-win32.coffee index 4d043ac4e..13dcd9a1e 100644 --- a/src/browser/auto-updater-win32.coffee +++ b/src/browser/auto-updater-win32.coffee @@ -5,7 +5,7 @@ SquirrelUpdate = require './squirrel-update' class AutoUpdater _.extend @prototype, EventEmitter.prototype - setFeedUrl: (@updateUrl) -> + setFeedURL: (@updateUrl) -> quitAndInstall: -> if SquirrelUpdate.existsSync() diff --git a/src/browser/main.coffee b/src/browser/main.coffee index ca9d7e3ae..2a50cba94 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -59,7 +59,7 @@ setupCrashReporter = -> setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME - atomHome = path.join(app.getHomeDir(), '.atom') + atomHome = path.join(app.getPath(), '.atom') AtomPortable = require './atom-portable' if setPortable and not AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome) @@ -142,7 +142,7 @@ parseCommandLine = -> socketPath = args['socket-path'] profileStartup = args['profile-startup'] urlsToOpen = [] - devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') + devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath(), 'github', 'atom') setPortable = args.portable if args['resource-path'] diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 375581a96..2eea1ec6a 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc' + ipc = require 'ipc-main' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index fa78d3cd6..7f73fdb41 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' diff --git a/src/module-cache.coffee b/src/module-cache.coffee index e9245cf40..a2840a864 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -208,7 +208,7 @@ registerBuiltins = (devMode) -> cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js") rendererRoot = path.join(atomShellRoot, 'renderer', 'api', 'lib') - rendererBuiltins = ['ipc', 'remote'] + rendererBuiltins = ['ipc-renderer', 'remote'] for builtin in rendererBuiltins cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js") diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 6c838b8c0..b873b0728 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 430b0c0fd..525c7a3af 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc' +ipc = require 'ipc-main' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index fb4b19dc3..5b734c3f0 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' diff --git a/static/index.js b/static/index.js index 2a5bcad3a..d62efd4f0 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc').sendChannel('window-command', 'window:loaded') + require('ipc-main').send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 6c811433cfe99b6d1432e263469fde77cee799c7 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 23:11:55 -0500 Subject: [PATCH 003/108] Fix executeJavaScriptInDevTools The joy of Atom and Electron having identically-named functions --- spec/atom-environment-spec.coffee | 6 +++--- src/atom-environment.coffee | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 2d8fd70ac..23f8e0e51 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -47,7 +47,7 @@ describe "AtomEnvironment", -> describe "window onerror handler", -> beforeEach -> spyOn atom, 'openDevTools' - spyOn atom, 'webContents.executeJavaScriptInDevTools' + spyOn atom, 'executeJavaScriptInDevTools' it "will open the dev tools when an error is triggered", -> try @@ -56,7 +56,7 @@ describe "AtomEnvironment", -> window.onerror.call(window, e.toString(), 'abc', 2, 3, e) expect(atom.openDevTools).toHaveBeenCalled() - expect(atom.webContents.executeJavaScriptInDevTools).toHaveBeenCalled() + expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() describe "::onWillThrowError", -> willThrowSpy = null @@ -91,7 +91,7 @@ describe "AtomEnvironment", -> expect(willThrowSpy).toHaveBeenCalled() expect(atom.openDevTools).not.toHaveBeenCalled() - expect(atom.webContents.executeJavaScriptInDevTools).not.toHaveBeenCalled() + expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled() describe "::onDidThrowError", -> didThrowSpy = null diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 6082ac4d0..5afdb1f8d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -671,7 +671,7 @@ class AtomEnvironment extends Model if openDevTools @openDevTools() - @webContents.executeJavaScriptInDevTools('DevToolsAPI.showConsole()') + @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @@ -729,7 +729,7 @@ class AtomEnvironment extends Model @applicationDelegate.toggleWindowDevTools() # Extended: Execute code in dev tools. - webContents.executeJavaScriptInDevTools: (code) -> + executeJavaScriptInDevTools: (code) -> @applicationDelegate.executeJavaScriptInWindowDevTools(code) ### From d2a86e2466960f49314f34a4b33d5f1beafa5792 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 18:46:38 -0500 Subject: [PATCH 004/108] Add 'home' argument to app.getPath() --- src/browser/main.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 2a50cba94..df8b3b74a 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -59,7 +59,7 @@ setupCrashReporter = -> setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME - atomHome = path.join(app.getPath(), '.atom') + atomHome = path.join(app.getPath('home'), '.atom') AtomPortable = require './atom-portable' if setPortable and not AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome) @@ -142,7 +142,7 @@ parseCommandLine = -> socketPath = args['socket-path'] profileStartup = args['profile-startup'] urlsToOpen = [] - devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath(), 'github', 'atom') + devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath('home'), 'github', 'atom') setPortable = args.portable if args['resource-path'] From fec1507ff48f984ef978afb5d09eaf8d17f612ae Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 21:10:40 -0500 Subject: [PATCH 005/108] Require ipc-renderer where it belongs --- spec/jasmine-test-runner.coffee | 2 +- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 2 +- spec/workspace-element-spec.coffee | 2 +- src/application-delegate.coffee | 2 +- src/atom-environment.coffee | 2 +- src/browser/atom-portable.coffee | 2 +- src/initialize-test-window.coffee | 2 +- src/menu-manager.coffee | 2 +- src/register-default-commands.coffee | 2 +- src/text-editor-component.coffee | 2 +- src/workspace-element.coffee | 2 +- static/index.js | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 64191c1f4..8192d4328 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index a7b6818f5..c6062d0ec 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc-main'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('ipc-renderer'), 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 9cd68d5e8..052fed8c0 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 110b8d562..01dddc5b7 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' path = require 'path' temp = require('temp').track() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index c5b65a4c8..d9a032fef 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,5 @@ _ = require 'underscore-plus' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' remote = require 'remote' shell = require 'shell' webFrame = require 'web-frame' diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index d2e069a85..a0049e50b 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' _ = require 'underscore-plus' {deprecate} = require 'grim' diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..eeda81152 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = class AtomPortable diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index b90eb0ed2..ad085730e 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc-main' + ipc = require 'ipc-renderer' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 7f73fdb41..9eabcb697 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index b873b0728..7e8a728bc 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 525c7a3af..c0f1486b5 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index 5b734c3f0..89e990c66 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' diff --git a/static/index.js b/static/index.js index d62efd4f0..651f2b54c 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc-main').send('window-command', 'window:loaded') + require('ipc-renderer').send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 5fca7b6582dc54c812e5ce438d06e6ff9de778eb Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 21:20:45 -0500 Subject: [PATCH 006/108] More ipc-renderer fixes --- spec/atom-reporter.coffee | 2 +- src/browser/application-menu.coffee | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 9bc4bdbf9..931e21777 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc-main').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('ipc-renderer').send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index b9b4eed92..f742c3a54 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,4 @@ app = require 'app' -ipc = require 'ipc-main' Menu = require 'menu' _ = require 'underscore-plus' From f6328fb5115836bd71fb6739eb6072ac091c89e0 Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 16:37:11 -0500 Subject: [PATCH 007/108] One more ipc fix --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index eeda81152..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +ipc = require 'ipc-main' module.exports = class AtomPortable From 50a42af9fdfb1441e6408ffad754375415142abe Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 18:20:51 -0500 Subject: [PATCH 008/108] ...try this? --- src/application-delegate.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index d9a032fef..e88bc321f 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -72,7 +72,8 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - remote.getCurrentWindow().webContents.executeJavaScriptInDevTools(code) + webContents = remote.getCurrentWindow.webContents + webContents.executeJavaScript(code) setWindowDocumentEdited: (edited) -> ipc.send("call-window-method", "setDocumentEdited", edited) From c85cd805440c6550ee745e30dd1d1c1dfed92523 Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 19:49:29 -0500 Subject: [PATCH 009/108] Fix missing parentheses --- src/application-delegate.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index e88bc321f..592170a35 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -72,7 +72,7 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - webContents = remote.getCurrentWindow.webContents + webContents = remote.getCurrentWindow().webContents webContents.executeJavaScript(code) setWindowDocumentEdited: (edited) -> From 9a850f9cb215d84b878ce7f96b6d438b594b107d Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 20:11:26 -0500 Subject: [PATCH 010/108] This is ridiculous --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..eeda81152 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = class AtomPortable From dfe27ff989d12f972436dc563cd8cc798a934a8b Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 20:49:05 -0500 Subject: [PATCH 011/108] More deprecations --- src/browser/atom-window.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 4ab13ef0e..6a36b55eb 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -89,7 +89,7 @@ class AtomWindow getLoadSettings: -> if @browserWindow.webContents? and not @browserWindow.webContents.isLoading() - hash = url.parse(@browserWindow.webContents.getUrl()).hash.substr(1) + hash = url.parse(@browserWindow.webContents.getURL()).hash.substr(1) JSON.parse(decodeURIComponent(hash)) hasProjectPath: -> @getLoadSettings().initialPaths?.length > 0 @@ -147,7 +147,7 @@ class AtomWindow when 1 then @browserWindow.restart() @browserWindow.webContents.on 'will-navigate', (event, url) => - unless url is @browserWindow.webContents.getUrl() + unless url is @browserWindow.webContents.getURL() event.preventDefault() @setupContextMenu() From 991d65c107d750b78613931c9d36eefa54d1ee23 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 24 Nov 2015 19:43:06 -0500 Subject: [PATCH 012/108] :arrow_up: electron@0.35.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d9c7b221..af1dbf7a2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.0", + "electronVersion": "0.35.1", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From e36cf63500742cffd764b246cecb294903626537 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 27 Nov 2015 11:10:31 -0500 Subject: [PATCH 013/108] :arrow_up: electron@0.35.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0c177b42..79cdd4bee 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.1", + "electronVersion": "0.35.2", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 8e6c8b02bbeb03e7488a7a46a9ca94df983de7a4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 27 Nov 2015 13:20:22 -0500 Subject: [PATCH 014/108] Switch back to ipc-main in atom-portable.coffee --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index eeda81152..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +ipc = require 'ipc-main' module.exports = class AtomPortable From 1725b9bf54252be2a2cf81d0b76bd5cb1693d918 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:30:58 +0800 Subject: [PATCH 015/108] Use require('electron') --- src/application-delegate.coffee | 71 +++++++++++++++------------- src/atom-environment.coffee | 8 ++-- src/browser/atom-application.coffee | 31 +++++------- src/browser/atom-portable.coffee | 4 +- src/browser/main.coffee | 3 +- src/initialize-test-window.coffee | 12 ++--- src/menu-manager.coffee | 4 +- src/register-default-commands.coffee | 48 +++++++++---------- src/text-editor-component.coffee | 8 ++-- src/workspace-element.coffee | 4 +- static/index.js | 2 + 11 files changed, 97 insertions(+), 98 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f1812dd25..5e82ebd15 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,28 +1,25 @@ _ = require 'underscore-plus' -ipc = require 'ipc-renderer' -remote = require 'remote' -shell = require 'shell' -webFrame = require 'web-frame' +{ipcRenderer, remote, shell, webFrame} = require 'electron' {Disposable} = require 'event-kit' {getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' module.exports = class ApplicationDelegate open: (params) -> - ipc.send('open', params) + ipcRenderer.send('open', params) pickFolder: (callback) -> responseChannel = "atom-pick-folder-response" - ipc.on responseChannel, (path) -> - ipc.removeAllListeners(responseChannel) + ipcRenderer.on responseChannel, (event, path) -> + ipcRenderer.removeAllListeners(responseChannel) callback(path) - ipc.send("pick-folder", responseChannel) + ipcRenderer.send("pick-folder", responseChannel) getCurrentWindow: -> remote.getCurrentWindow() closeWindow: -> - ipc.send("call-window-method", "close") + ipcRenderer.send("call-window-method", "close") getWindowSize: -> [width, height] = remote.getCurrentWindow().getSize() @@ -36,34 +33,34 @@ class ApplicationDelegate {x, y} setWindowPosition: (x, y) -> - ipc.send("call-window-method", "setPosition", x, y) + ipcRenderer.send("call-window-method", "setPosition", x, y) centerWindow: -> - ipc.send("call-window-method", "center") + ipcRenderer.send("call-window-method", "center") focusWindow: -> - ipc.send("call-window-method", "focus") + ipcRenderer.send("call-window-method", "focus") showWindow: -> - ipc.send("call-window-method", "show") + ipcRenderer.send("call-window-method", "show") hideWindow: -> - ipc.send("call-window-method", "hide") + ipcRenderer.send("call-window-method", "hide") restartWindow: -> - ipc.send("call-window-method", "restart") + ipcRenderer.send("call-window-method", "restart") isWindowMaximized: -> remote.getCurrentWindow().isMaximized() maximizeWindow: -> - ipc.send("call-window-method", "maximize") + ipcRenderer.send("call-window-method", "maximize") isWindowFullScreen: -> remote.getCurrentWindow().isFullScreen() setWindowFullScreen: (fullScreen=false) -> - ipc.send("call-window-method", "setFullScreen", fullScreen) + ipcRenderer.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> new Promise (resolve) -> @@ -75,7 +72,7 @@ class ApplicationDelegate resolve() else remote.getCurrentWindow().once("devtools-opened", -> resolve()) - ipc.send("call-window-method", "openDevTools") + ipcRenderer.send("call-window-method", "openDevTools") closeWindowDevTools: -> new Promise (resolve) -> @@ -87,7 +84,7 @@ class ApplicationDelegate resolve() else remote.getCurrentWindow().once("devtools-closed", -> resolve()) - ipc.send("call-window-method", "closeDevTools") + ipcRenderer.send("call-window-method", "closeDevTools") toggleWindowDevTools: -> new Promise (resolve) => @@ -101,13 +98,13 @@ class ApplicationDelegate @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> - ipc.send("call-window-method", "executeJavaScriptInDevTools", code) + ipcRenderer.send("call-window-method", "executeJavaScriptInDevTools", code) setWindowDocumentEdited: (edited) -> - ipc.send("call-window-method", "setDocumentEdited", edited) + ipcRenderer.send("call-window-method", "setDocumentEdited", edited) setRepresentedFilename: (filename) -> - ipc.send("call-window-method", "setRepresentedFilename", filename) + ipcRenderer.send("call-window-method", "setRepresentedFilename", filename) setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() @@ -115,7 +112,7 @@ class ApplicationDelegate setWindowLoadSettings(loadSettings) setAutoHideWindowMenuBar: (autoHide) -> - ipc.send("call-window-method", "setAutoHideMenuBar", autoHide) + ipcRenderer.send("call-window-method", "setAutoHideMenuBar", autoHide) setWindowMenuBarVisibility: (visible) -> remote.getCurrentWindow().setMenuBarVisibility(visible) @@ -161,35 +158,41 @@ class ApplicationDelegate shell.beep() onDidOpenLocations: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'open-locations' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onUpdateAvailable: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'update-available' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onApplicationMenuCommand: (callback) -> - ipc.on('command', callback) + outerCallback = (event, args...) -> + callback(args...) + + ipcRenderer.on('command', outerCallback) new Disposable -> - ipc.removeListener('command', callback) + ipcRenderer.removeListener('command', outerCallback) onContextMenuCommand: (callback) -> - ipc.on('context-command', callback) + outerCallback = (event, args...) -> + callback(args...) + + ipcRenderer.on('context-command', outerCallback) new Disposable -> - ipc.removeListener('context-command', callback) + ipcRenderer.removeListener('context-command', outerCallback) didCancelWindowUnload: -> - ipc.send('did-cancel-window-unload') + ipcRenderer.send('did-cancel-window-unload') openExternal: (url) -> shell.openExternal(url) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 027c7b547..7c1f81bba 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' _ = require 'underscore-plus' {deprecate} = require 'grim' @@ -206,10 +206,10 @@ class AtomEnvironment extends Model checkPortableHomeWritable = -> responseChannel = "check-portable-home-writable-response" - ipc.on responseChannel, (response) -> - ipc.removeAllListeners(responseChannel) + ipcRenderer.on responseChannel, (event, response) -> + ipcRenderer.removeAllListeners(responseChannel) atom.notifications.addWarning("#{response.message.replace(/([\\\.+\\-_#!])/g, '\\$1')}") if not response.writable - ipc.send('check-portable-home-writable', responseChannel) + ipcRenderer.send('check-portable-home-writable', responseChannel) checkPortableHomeWritable() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 63e3e3cf9..f721596d8 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -2,14 +2,9 @@ AtomWindow = require './atom-window' ApplicationMenu = require './application-menu' AtomProtocolHandler = require './atom-protocol-handler' AutoUpdateManager = require './auto-update-manager' -BrowserWindow = require 'browser-window' StorageFolder = require '../storage-folder' -Menu = require 'menu' -app = require 'app' -dialog = require 'dialog' -shell = require 'shell' +{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron' fs = require 'fs-plus' -ipc = require 'ipc-main' path = require 'path' os = require 'os' net = require 'net' @@ -232,7 +227,7 @@ class AtomApplication @emit('application:new-window') # A request from the associated render process to open a new render process. - ipc.on 'open', (event, options) => + ipcMain.on 'open', (event, options) => window = @windowForEvent(event) if options? if typeof options.pathsToOpen is 'string' @@ -245,39 +240,39 @@ class AtomApplication else @promptForPathToOpen('all', {window}) - ipc.on 'update-application-menu', (event, template, keystrokesByCommand) => + ipcMain.on 'update-application-menu', (event, template, keystrokesByCommand) => win = BrowserWindow.fromWebContents(event.sender) @applicationMenu.update(win, template, keystrokesByCommand) - ipc.on 'run-package-specs', (event, packageSpecPath) => + ipcMain.on 'run-package-specs', (event, packageSpecPath) => @runTests({resourcePath: @devResourcePath, pathsToOpen: [packageSpecPath], headless: false}) - ipc.on 'command', (event, command) => + ipcMain.on 'command', (event, command) => @emit(command) - ipc.on 'window-command', (event, command, args...) -> + ipcMain.on 'window-command', (event, command, args...) -> win = BrowserWindow.fromWebContents(event.sender) win.emit(command, args...) - ipc.on 'call-window-method', (event, method, args...) -> + ipcMain.on 'call-window-method', (event, method, args...) -> win = BrowserWindow.fromWebContents(event.sender) win[method](args...) - ipc.on 'pick-folder', (event, responseChannel) => + ipcMain.on 'pick-folder', (event, responseChannel) => @promptForPath "folder", (selectedPaths) -> event.sender.send(responseChannel, selectedPaths) - ipc.on 'did-cancel-window-unload', => + ipcMain.on 'did-cancel-window-unload', => @quitting = false clipboard = require '../safe-clipboard' - ipc.on 'write-text-to-selection-clipboard', (event, selectedText) -> + ipcMain.on 'write-text-to-selection-clipboard', (event, selectedText) -> clipboard.writeText(selectedText, 'selection') - ipc.on 'write-to-stdout', (event, output) -> + ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipc.on 'write-to-stderr', (event, output) -> + ipcMain.on 'write-to-stderr', (event, output) -> process.stderr.write(output) # Public: Executes the given command. @@ -340,7 +335,7 @@ class AtomApplication _.find @windows, (atomWindow) -> atomWindow.devMode is devMode and atomWindow.containsPaths(pathsToOpen) - # Returns the {AtomWindow} for the given ipc event. + # Returns the {AtomWindow} for the given ipcMain event. windowForEvent: ({sender}) -> window = BrowserWindow.fromWebContents(sender) _.find @windows, ({browserWindow}) -> window is browserWindow diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..ae4bb67ec 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +{ipcMain} = require 'electron' module.exports = class AtomPortable @@ -30,6 +30,6 @@ class AtomPortable catch error message = "Failed to use portable Atom home directory (#{@getPortableAtomHomePath()}). Using the default instead (#{defaultHome}). #{error.message}" - ipc.on 'check-portable-home-writable', (event) -> + ipcMain.on 'check-portable-home-writable', (event) -> event.sender.send 'check-portable-home-writable-response', {writable, message} writable diff --git a/src/browser/main.coffee b/src/browser/main.coffee index df8b3b74a..e2e9d2243 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -4,8 +4,7 @@ process.on 'uncaughtException', (error={}) -> console.log(error.message) if error.message? console.log(error.stack) if error.stack? -crashReporter = require 'crash-reporter' -app = require 'app' +{crashReporter, app} = require 'electron' fs = require 'fs-plus' path = require 'path' yargs = require 'yargs' diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index ad085730e..f54d40dc3 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -4,9 +4,9 @@ cloneObject = (object) -> clone module.exports = ({blobStore}) -> + {crashReporter, remote} = require 'electron' # Start the crash reporter before anything else. - require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub') - remote = require 'remote' + crashReporter.start(productName: 'Atom', companyName: 'GitHub') exitWithStatusCode = (status) -> remote.require('app').emit('will-quit') @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc-renderer' + {ipcRenderer} = require 'electron' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' @@ -29,15 +29,15 @@ module.exports = ({blobStore}) -> handleKeydown = (event) -> # Reload: cmd-r / ctrl-r if (event.metaKey or event.ctrlKey) and event.keyCode is 82 - ipc.send('call-window-method', 'restart') + ipcRenderer.send('call-window-method', 'restart') # Toggle Dev Tools: cmd-alt-i / ctrl-alt-i if (event.metaKey or event.ctrlKey) and event.altKey and event.keyCode is 73 - ipc.send('call-window-method', 'toggleDevTools') + ipcRenderer.send('call-window-method', 'toggleDevTools') # Reload: cmd-w / ctrl-w if (event.metaKey or event.ctrlKey) and event.keyCode is 87 - ipc.send('call-window-method', 'close') + ipcRenderer.send('call-window-method', 'close') window.addEventListener('keydown', handleKeydown, true) diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 9eabcb697..67076dbfa 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' @@ -191,7 +191,7 @@ class MenuManager sendToBrowserProcess: (template, keystrokesByCommand) -> keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand) - ipc.send 'update-application-menu', template, keystrokesByCommand + ipcRenderer.send 'update-application-menu', template, keystrokesByCommand # Get an {Array} of {String} classes for the given element. classesForElement: (element) -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index b43e0a44b..ffb49880f 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', @@ -18,30 +18,30 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> 'window:increase-font-size': -> @getModel().increaseFontSize() 'window:decrease-font-size': -> @getModel().decreaseFontSize() 'window:reset-font-size': -> @getModel().resetFontSize() - 'application:about': -> ipc.send('command', 'application:about') - 'application:show-preferences': -> ipc.send('command', 'application:show-settings') - 'application:show-settings': -> ipc.send('command', 'application:show-settings') - 'application:quit': -> ipc.send('command', 'application:quit') - 'application:hide': -> ipc.send('command', 'application:hide') - 'application:hide-other-applications': -> ipc.send('command', 'application:hide-other-applications') - 'application:install-update': -> ipc.send('command', 'application:install-update') - 'application:unhide-all-applications': -> ipc.send('command', 'application:unhide-all-applications') - 'application:new-window': -> ipc.send('command', 'application:new-window') - 'application:new-file': -> ipc.send('command', 'application:new-file') - 'application:open': -> ipc.send('command', 'application:open') - 'application:open-file': -> ipc.send('command', 'application:open-file') - 'application:open-folder': -> ipc.send('command', 'application:open-folder') - 'application:open-dev': -> ipc.send('command', 'application:open-dev') - 'application:open-safe': -> ipc.send('command', 'application:open-safe') + 'application:about': -> ipcRenderer.send('command', 'application:about') + 'application:show-preferences': -> ipcRenderer.send('command', 'application:show-settings') + 'application:show-settings': -> ipcRenderer.send('command', 'application:show-settings') + 'application:quit': -> ipcRenderer.send('command', 'application:quit') + 'application:hide': -> ipcRenderer.send('command', 'application:hide') + 'application:hide-other-applications': -> ipcRenderer.send('command', 'application:hide-other-applications') + 'application:install-update': -> ipcRenderer.send('command', 'application:install-update') + 'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications') + 'application:new-window': -> ipcRenderer.send('command', 'application:new-window') + 'application:new-file': -> ipcRenderer.send('command', 'application:new-file') + 'application:open': -> ipcRenderer.send('command', 'application:open') + 'application:open-file': -> ipcRenderer.send('command', 'application:open-file') + 'application:open-folder': -> ipcRenderer.send('command', 'application:open-folder') + 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') + 'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe') 'application:add-project-folder': -> atom.addProjectFolder() - 'application:minimize': -> ipc.send('command', 'application:minimize') - 'application:zoom': -> ipc.send('command', 'application:zoom') - 'application:bring-all-windows-to-front': -> ipc.send('command', 'application:bring-all-windows-to-front') - 'application:open-your-config': -> ipc.send('command', 'application:open-your-config') - 'application:open-your-init-script': -> ipc.send('command', 'application:open-your-init-script') - 'application:open-your-keymap': -> ipc.send('command', 'application:open-your-keymap') - 'application:open-your-snippets': -> ipc.send('command', 'application:open-your-snippets') - 'application:open-your-stylesheet': -> ipc.send('command', 'application:open-your-stylesheet') + 'application:minimize': -> ipcRenderer.send('command', 'application:minimize') + 'application:zoom': -> ipcRenderer.send('command', 'application:zoom') + 'application:bring-all-windows-to-front': -> ipcRenderer.send('command', 'application:bring-all-windows-to-front') + 'application:open-your-config': -> ipcRenderer.send('command', 'application:open-your-config') + 'application:open-your-init-script': -> ipcRenderer.send('command', 'application:open-your-init-script') + 'application:open-your-keymap': -> ipcRenderer.send('command', 'application:open-your-keymap') + 'application:open-your-snippets': -> ipcRenderer.send('command', 'application:open-your-snippets') + 'application:open-your-stylesheet': -> ipcRenderer.send('command', 'application:open-your-stylesheet') 'application:open-license': -> @getModel().openLicense() 'window:run-package-specs': -> @runPackageSpecs() 'window:focus-next-pane': -> @getModel().activateNextPane() diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index c0f1486b5..c6ed4e053 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' @@ -263,10 +263,10 @@ class TextEditorComponent writeSelectedTextToSelectionClipboard = => return if @editor.isDestroyed() if selectedText = @editor.getSelectedText() - # This uses ipc.send instead of clipboard.writeText because - # clipboard.writeText is a sync ipc call on Linux and that + # This uses ipcRenderer.send instead of clipboard.writeText because + # clipboard.writeText is a sync ipcRenderer call on Linux and that # will slow down selections. - ipc.send('write-text-to-selection-clipboard', selectedText) + ipcRenderer.send('write-text-to-selection-clipboard', selectedText) @disposables.add @editor.onDidChangeSelectionRange -> clearTimeout(timeoutId) timeoutId = setTimeout(writeSelectedTextToSelectionClipboard) diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index 89e990c66..b3d4c8a7a 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' @@ -104,6 +104,6 @@ class WorkspaceElement extends HTMLElement [projectPath] = @project.relativizePath(activePath) else [projectPath] = @project.getPaths() - ipc.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath + ipcRenderer.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype diff --git a/static/index.js b/static/index.js index 651f2b54c..1f2c61f7c 100644 --- a/static/index.js +++ b/static/index.js @@ -1,4 +1,6 @@ (function () { + process.throwDeprecation = true; + var path = require('path') var FileSystemBlobStore = require('../src/file-system-blob-store') var NativeCompileCache = require('../src/native-compile-cache') From d7e6b6399f761ffeadb387a1c83c75fd1a521602 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:33:53 +0800 Subject: [PATCH 016/108] :arrow_up: electron@0.35.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82211c710..1ff8721c0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.2", + "electronVersion": "0.35.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 1f9cfc929cdc5f57281bc3b44beacf617f134baa Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:50:18 +0800 Subject: [PATCH 017/108] Update the API usages after merge --- src/application-delegate.coffee | 2 +- src/browser/atom-application.coffee | 6 +++--- static/index.js | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 60627e5ce..2c7688de9 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -107,7 +107,7 @@ class ApplicationDelegate ipcRenderer.send("call-window-method", "setRepresentedFilename", filename) addRecentDocument: (filename) -> - ipc.send("add-recent-document", filename) + ipcRenderer.send("add-recent-document", filename) setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index f997c6f86..cbfe36f2d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -273,10 +273,10 @@ class AtomApplication ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipcMain.on 'write-to-stderr', (event, output) -> - process.stderr.write(output) + ipcMain.on 'write-to-stderr', (event, output) -> + process.stderr.write(output) - ipc.on 'add-recent-document', (event, filename) -> + ipcMain.on 'add-recent-document', (event, filename) -> app.addRecentDocument(filename) setupDockMenu: -> diff --git a/static/index.js b/static/index.js index 1f2c61f7c..651f2b54c 100644 --- a/static/index.js +++ b/static/index.js @@ -1,6 +1,4 @@ (function () { - process.throwDeprecation = true; - var path = require('path') var FileSystemBlobStore = require('../src/file-system-blob-store') var NativeCompileCache = require('../src/native-compile-cache') From c186d70beccb3d9ee8e2d77a20383a5609b77444 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 10:03:20 +0800 Subject: [PATCH 018/108] Also use require('electron') in specs --- spec/atom-reporter.coffee | 2 +- spec/jasmine-test-runner.coffee | 4 ++-- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 8 ++++---- spec/workspace-element-spec.coffee | 22 +++++++++++----------- src/browser/atom-application.coffee | 2 +- static/index.js | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 931e21777..d7ff49964 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc-renderer').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('electron').ipcRenderer.send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 8192d4328..0ce21f76d 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' @@ -89,7 +89,7 @@ buildTerminalReporter = (logFile, resolveWithExitCode) -> if logStream? fs.writeSync(logStream, str) else - ipc.send 'write-to-stderr', str + ipcRenderer.send 'write-to-stderr', str {TerminalReporter} = require 'jasmine-tagged' new TerminalReporter diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 19f193917..a18ab06e4 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc-renderer'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('electron').ipcRenderer, 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index e3e76643f..bb7e1665b 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] @@ -53,7 +53,7 @@ describe "WindowEventHandler", -> describe "beforeunload event", -> beforeEach -> jasmine.unspy(TextEditor.prototype, "shouldPromptToSave") - spyOn(ipc, 'send') + spyOn(ipcRenderer, 'send') describe "when pane items are modified", -> editor = null @@ -65,13 +65,13 @@ describe "WindowEventHandler", -> spyOn(atom.workspace, 'confirmClose').andReturn(true) window.dispatchEvent(new CustomEvent('beforeunload')) expect(atom.workspace.confirmClose).toHaveBeenCalled() - expect(ipc.send).not.toHaveBeenCalledWith('did-cancel-window-unload') + expect(ipcRenderer.send).not.toHaveBeenCalledWith('did-cancel-window-unload') it "cancels the unload if the user selects cancel", -> spyOn(atom.workspace, 'confirmClose').andReturn(false) window.dispatchEvent(new CustomEvent('beforeunload')) expect(atom.workspace.confirmClose).toHaveBeenCalled() - expect(ipc.send).toHaveBeenCalledWith('did-cancel-window-unload') + expect(ipcRenderer.send).toHaveBeenCalledWith('did-cancel-window-unload') describe "when a link is clicked", -> it "opens the http/https links in an external application", -> diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 01dddc5b7..24f8f6c3a 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' path = require 'path' temp = require('temp').track() @@ -87,35 +87,35 @@ describe "WorkspaceElement", -> describe "the 'window:run-package-specs' command", -> it "runs the package specs for the active item's project path, or the first project path", -> workspaceElement = atom.views.getView(atom.workspace) - spyOn(ipc, 'send') + spyOn(ipcRenderer, 'send') # No project paths. Don't try to run specs. atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).not.toHaveBeenCalledWith("run-package-specs") + expect(ipcRenderer.send).not.toHaveBeenCalledWith("run-package-specs") projectPaths = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")] atom.project.setPaths(projectPaths) # No active item. Use first project directory. atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item doesn't implement ::getPath(). Use first project directory. item = document.createElement("div") atom.workspace.getActivePane().activateItem(item) atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item has no path. Use first project directory. item.getPath = -> null atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item has path. Use project path for item path. item.getPath = -> path.join(projectPaths[1], "a-file.txt") atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec")) + ipcRenderer.send.reset() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index cbfe36f2d..eb3d9a60c 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -277,7 +277,7 @@ class AtomApplication process.stderr.write(output) ipcMain.on 'add-recent-document', (event, filename) -> - app.addRecentDocument(filename) + app.addRecentDocument(filename) setupDockMenu: -> if process.platform is 'darwin' diff --git a/static/index.js b/static/index.js index 651f2b54c..a55f31b5c 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc-renderer').send('window-command', 'window:loaded') + require('electron').ipcRenderer.send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 2150790596354c6317df33b9dd379e43b3f35111 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 10:21:46 +0800 Subject: [PATCH 019/108] Use the new style of `remote` --- src/application-delegate.coffee | 9 +++------ src/context-menu-manager.coffee | 2 +- src/initialize-test-window.coffee | 2 +- src/safe-clipboard.coffee | 4 ++-- src/window-load-settings-helpers.coffee | 2 +- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 2c7688de9..39e8efe95 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -121,8 +121,7 @@ class ApplicationDelegate remote.getCurrentWindow().setMenuBarVisibility(visible) getPrimaryDisplayWorkAreaSize: -> - screen = remote.require 'screen' - screen.getPrimaryDisplay().workAreaSize + remote.screen.getPrimaryDisplay().workAreaSize confirm: ({message, detailedMessage, buttons}) -> buttons ?= {} @@ -131,8 +130,7 @@ class ApplicationDelegate else buttonLabels = Object.keys(buttons) - dialog = remote.require('dialog') - chosen = dialog.showMessageBox(remote.getCurrentWindow(), { + chosen = remote.dialog.showMessageBox(remote.getCurrentWindow(), { type: 'info' message: message detail: detailedMessage @@ -154,8 +152,7 @@ class ApplicationDelegate params = _.clone(params) params.title ?= 'Save File' params.defaultPath ?= getWindowLoadSettings().initialPaths[0] - dialog = remote.require('dialog') - dialog.showSaveDialog remote.getCurrentWindow(), params + remote.dialog.showSaveDialog remote.getCurrentWindow(), params playBeepSound: -> shell.beep() diff --git a/src/context-menu-manager.coffee b/src/context-menu-manager.coffee index 869076beb..cce767f57 100644 --- a/src/context-menu-manager.coffee +++ b/src/context-menu-manager.coffee @@ -4,7 +4,7 @@ CSON = require 'season' fs = require 'fs-plus' {calculateSpecificity, validateSelector} = require 'clear-cut' {Disposable} = require 'event-kit' -remote = require 'remote' +{remote} = require 'electron' MenuHelpers = require './menu-helpers' platformContextMenu = require('../package.json')?._atomMenu?['context-menu'] diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index f54d40dc3..7de84cf0b 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -9,7 +9,7 @@ module.exports = ({blobStore}) -> crashReporter.start(productName: 'Atom', companyName: 'GitHub') exitWithStatusCode = (status) -> - remote.require('app').emit('will-quit') + remote.app.emit('will-quit') remote.process.exit(status) try diff --git a/src/safe-clipboard.coffee b/src/safe-clipboard.coffee index 8301f9d54..1f91803e2 100644 --- a/src/safe-clipboard.coffee +++ b/src/safe-clipboard.coffee @@ -1,6 +1,6 @@ # Using clipboard in renderer process is not safe on Linux. module.exports = if process.platform is 'linux' and process.type is 'renderer' - require('remote').require('clipboard') + require('electron').remote.clipboard else - require('clipboard') + require('electron').clipboard diff --git a/src/window-load-settings-helpers.coffee b/src/window-load-settings-helpers.coffee index 59ee2f382..4bb514301 100644 --- a/src/window-load-settings-helpers.coffee +++ b/src/window-load-settings-helpers.coffee @@ -1,4 +1,4 @@ -remote = require 'remote' +{remote} = require 'electron' _ = require 'underscore-plus' windowLoadSettings = null From 2e5c7f85736736c61f8a838f5d3abd04666565bd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 11:00:08 +0800 Subject: [PATCH 020/108] executeJavaScriptInDevTools is deprecated --- src/application-delegate.coffee | 2 +- src/browser/atom-application.coffee | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 39e8efe95..8fc51582a 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -98,7 +98,7 @@ class ApplicationDelegate @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> - ipcRenderer.send("call-window-method", "executeJavaScriptInDevTools", code) + ipcRenderer.send("execute-javascript-in-dev-tools", code) setWindowDocumentEdited: (edited) -> ipcRenderer.send("call-window-method", "setDocumentEdited", edited) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index eb3d9a60c..61faa5704 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -279,6 +279,9 @@ class AtomApplication ipcMain.on 'add-recent-document', (event, filename) -> app.addRecentDocument(filename) + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> + event.sender.devToolsWebContents?.executeJavaScript(code) + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ From 678c390e2ed6f1294fc859bd6cd2d97249e3f23d Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 10 Dec 2015 22:52:06 -0500 Subject: [PATCH 021/108] Fix indentation --- src/browser/atom-application.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 61faa5704..7b3694947 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -273,14 +273,14 @@ class AtomApplication ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipcMain.on 'write-to-stderr', (event, output) -> - process.stderr.write(output) + ipcMain.on 'write-to-stderr', (event, output) -> + process.stderr.write(output) - ipcMain.on 'add-recent-document', (event, filename) -> - app.addRecentDocument(filename) + ipcMain.on 'add-recent-document', (event, filename) -> + app.addRecentDocument(filename) - ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> - event.sender.devToolsWebContents?.executeJavaScript(code) + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> + event.sender.devToolsWebContents?.executeJavaScript(code) setupDockMenu: -> if process.platform is 'darwin' From d6fa46accec1191971fcf20dffa7ffd9f9bdd8bc Mon Sep 17 00:00:00 2001 From: Wliu Date: Sat, 12 Dec 2015 13:22:22 -0500 Subject: [PATCH 022/108] Update browser files to use require 'electron' --- src/browser/application-menu.coffee | 3 +-- src/browser/atom-protocol-handler.coffee | 3 +-- src/browser/atom-window.coffee | 4 +--- src/browser/auto-update-manager.coffee | 6 +++--- src/browser/auto-updater-win32.coffee | 4 ++-- src/browser/context-menu.coffee | 2 +- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index f742c3a54..fef9f90fa 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,4 @@ -app = require 'app' -Menu = require 'menu' +{app, Menu} = require 'electron' _ = require 'underscore-plus' # Used to manage the global application menu. diff --git a/src/browser/atom-protocol-handler.coffee b/src/browser/atom-protocol-handler.coffee index 0fda8095b..3967c0525 100644 --- a/src/browser/atom-protocol-handler.coffee +++ b/src/browser/atom-protocol-handler.coffee @@ -1,7 +1,6 @@ -app = require 'app' +{app, protocol} = require 'electron' fs = require 'fs' path = require 'path' -protocol = require 'protocol' # Handles requests with 'atom' protocol. # diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 6a36b55eb..ace12239e 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -1,6 +1,4 @@ -BrowserWindow = require 'browser-window' -app = require 'app' -dialog = require 'dialog' +{BrowserWindow, app, dialog} = require 'electron' path = require 'path' fs = require 'fs' url = require 'url' diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index f4a493829..63a79b60f 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -25,7 +25,7 @@ class AutoUpdateManager if process.platform is 'win32' autoUpdater = require './auto-updater-win32' else - autoUpdater = require 'auto-updater' + {autoUpdater} = require 'electron' autoUpdater.on 'error', (event, message) => @setState(ErrorState) @@ -91,7 +91,7 @@ class AutoUpdateManager onUpdateNotAvailable: => autoUpdater.removeListener 'error', @onUpdateError - dialog = require 'dialog' + {dialog} = require 'electron' dialog.showMessageBox type: 'info' buttons: ['OK'] @@ -102,7 +102,7 @@ class AutoUpdateManager onUpdateError: (event, message) => autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable - dialog = require 'dialog' + {dialog} = require 'electron' dialog.showMessageBox type: 'warning' buttons: ['OK'] diff --git a/src/browser/auto-updater-win32.coffee b/src/browser/auto-updater-win32.coffee index 13dcd9a1e..e31578d49 100644 --- a/src/browser/auto-updater-win32.coffee +++ b/src/browser/auto-updater-win32.coffee @@ -9,9 +9,9 @@ class AutoUpdater quitAndInstall: -> if SquirrelUpdate.existsSync() - SquirrelUpdate.restartAtom(require('app')) + SquirrelUpdate.restartAtom(require('electron').app) else - require('auto-updater').quitAndInstall() + require('electron').autoUpdater.quitAndInstall() downloadUpdate: (callback) -> SquirrelUpdate.spawn ['--download', @updateUrl], (error, stdout) -> diff --git a/src/browser/context-menu.coffee b/src/browser/context-menu.coffee index 44b57cdc9..1bc9c29ba 100644 --- a/src/browser/context-menu.coffee +++ b/src/browser/context-menu.coffee @@ -1,4 +1,4 @@ -Menu = require 'menu' +{Menu} = require 'electron' module.exports = class ContextMenu From ed96ac7daf06a4abb106b54e0e70edc33da11541 Mon Sep 17 00:00:00 2001 From: Wliu Date: Sat, 12 Dec 2015 21:35:14 -0500 Subject: [PATCH 023/108] browserWindow.restart -> .reload --- src/application-delegate.coffee | 4 ++-- src/atom-environment.coffee | 2 +- src/browser/atom-window.coffee | 4 ++-- src/initialize-test-window.coffee | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 8fc51582a..f7b04e10d 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -47,8 +47,8 @@ class ApplicationDelegate hideWindow: -> ipcRenderer.send("call-window-method", "hide") - restartWindow: -> - ipcRenderer.send("call-window-method", "restart") + reloadWindow: -> + ipcRenderer.send("call-window-method", "reload") isWindowMaximized: -> remote.getCurrentWindow().isMaximized() diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f46df14ab..cd6834da4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -492,7 +492,7 @@ class AtomEnvironment extends Model # Extended: Reload the current window. reload: -> - @applicationDelegate.restartWindow() + @applicationDelegate.reloadWindow() # Extended: Returns a {Boolean} that is `true` if the current window is maximized. isMaximized: -> diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index ace12239e..721eb68a6 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -142,7 +142,7 @@ class AtomWindow detail: 'Please report this issue to https://github.com/atom/atom' switch chosen when 0 then @browserWindow.destroy() - when 1 then @browserWindow.restart() + when 1 then @browserWindow.reload() @browserWindow.webContents.on 'will-navigate', (event, url) => unless url is @browserWindow.webContents.getURL() @@ -216,6 +216,6 @@ class AtomWindow isSpecWindow: -> @isSpec - reload: -> @browserWindow.restart() + reload: -> @browserWindow.reload() toggleDevTools: -> @browserWindow.toggleDevTools() diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 7de84cf0b..d9607f8f7 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -29,7 +29,7 @@ module.exports = ({blobStore}) -> handleKeydown = (event) -> # Reload: cmd-r / ctrl-r if (event.metaKey or event.ctrlKey) and event.keyCode is 82 - ipcRenderer.send('call-window-method', 'restart') + ipcRenderer.send('call-window-method', 'reload') # Toggle Dev Tools: cmd-alt-i / ctrl-alt-i if (event.metaKey or event.ctrlKey) and event.altKey and event.keyCode is 73 From 74e830358d939eafda89bf5c7269b81756fe3f50 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 14 Dec 2015 17:31:27 -0500 Subject: [PATCH 024/108] Save the state before the browser window is closed --- src/browser/atom-application.coffee | 1 - src/browser/atom-window.coffee | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 7b3694947..720e0f84d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -208,7 +208,6 @@ class AtomApplication @openPathOnEvent('application:open-license', path.join(process.resourcesPath, 'LICENSE.md')) app.on 'before-quit', => - @saveState(false) @quitting = true app.on 'will-quit', => diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 721eb68a6..8425171b7 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -119,6 +119,9 @@ class AtomWindow false handleEvents: -> + @browserWindow.on 'close', -> + global.atomApplication.saveState(false) + @browserWindow.on 'closed', => global.atomApplication.removeWindow(this) From f4f5e47aab9784ff8405d678b462ef1940c76820 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 14 Dec 2015 17:35:50 -0500 Subject: [PATCH 025/108] One more remote update --- spec/integration/helpers/start-atom.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index b8768f532..6d89af263 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -124,7 +124,7 @@ buildAtomClient = (args, env) -> .addCommand "simulateQuit", (done) -> @execute -> atom.unloadEditorWindow() - .execute -> require("remote").require("app").emit("before-quit") + .execute -> require("electron").remote.app.emit("before-quit") .call(done) module.exports = (args, env, fn) -> From 295698c085efedccf217fcdc16ade5daee547c20 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:01:01 -0500 Subject: [PATCH 026/108] app.terminate --> app.quit --- src/browser/atom-application.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 720e0f84d..0fbeeac9e 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -46,7 +46,7 @@ class AtomApplication client = net.connect {path: options.socketPath}, -> client.write JSON.stringify(options), -> client.end() - app.terminate() + app.quit() client.on 'error', createAtomApplication From bdb11a95f762168ba2ffad070450f674b6d69e53 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:05:27 -0500 Subject: [PATCH 027/108] :arrow_up: tabs@0.89.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1cca017b4..8bce54f82 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "status-bar": "0.80.0", "styleguide": "0.45.0", "symbols-view": "0.110.1", - "tabs": "0.88.0", + "tabs": "0.89.0", "timecop": "0.33.0", "tree-view": "0.198.0", "update-package-dependencies": "0.10.0", From dbc06e599394a7c99f79a3ddbba4133ad3a9ad2a Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:16:15 -0500 Subject: [PATCH 028/108] Initial attempt to update to Electron 0.36.1 --- package.json | 2 +- static/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8bce54f82..0a490b8ee 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.4", + "electronVersion": "0.36.1", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", diff --git a/static/index.html b/static/index.html index 5fcb30ad2..0bd4a7954 100644 --- a/static/index.html +++ b/static/index.html @@ -1,7 +1,7 @@ - + From d75102f46d51599cdc914cda700e05b964f07397 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 18:01:26 -0500 Subject: [PATCH 029/108] Set URL in the crash reporter --- src/browser/main.coffee | 2 +- src/initialize-test-window.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index e2e9d2243..751870573 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -53,7 +53,7 @@ handleStartupEventWithSquirrel = -> SquirrelUpdate.handleStartupEvent(app, squirrelCommand) setupCrashReporter = -> - crashReporter.start(productName: 'Atom', companyName: 'GitHub') + crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post') setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index d9607f8f7..9c5df337b 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -6,7 +6,7 @@ cloneObject = (object) -> module.exports = ({blobStore}) -> {crashReporter, remote} = require 'electron' # Start the crash reporter before anything else. - crashReporter.start(productName: 'Atom', companyName: 'GitHub') + crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post') exitWithStatusCode = (status) -> remote.app.emit('will-quit') From 612ca6ecabe63298351fd3e4c7b865ff267cfc97 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 20:44:51 -0500 Subject: [PATCH 030/108] Missed one of the crash reporters Also convert even more requires... --- static/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/static/index.js b/static/index.js index d7f509635..b2646b5bc 100644 --- a/static/index.js +++ b/static/index.js @@ -54,7 +54,7 @@ } function handleSetupError (error) { - var currentWindow = require('remote').getCurrentWindow() + var currentWindow = require('electron').remote.getCurrentWindow() currentWindow.setSize(800, 600) currentWindow.center() currentWindow.show() @@ -71,9 +71,10 @@ ModuleCache.add(loadSettings.resourcePath) // Start the crash reporter before anything else. - require('crash-reporter').start({ + require('electron').crashReporter.start({ productName: 'Atom', companyName: 'GitHub', + submitURL: 'http://54.249.141.255:1127/post', // By explicitly passing the app version here, we could save the call // of "require('remote').require('app').getVersion()". extra: {_version: loadSettings.appVersion} @@ -124,7 +125,7 @@ } } - var currentWindow = require('remote').getCurrentWindow() + var currentWindow = require('electron').remote.getCurrentWindow() if (currentWindow.devToolsWebContents) { profile() } else { From dbf7bedec81653be81183db3aa6040745164f459 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 30 Dec 2015 10:54:34 -0500 Subject: [PATCH 031/108] :arrow_up: electron@0.36.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 872c38d87..b7123e85c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.1", + "electronVersion": "0.36.2", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From c34ef243d70ed02073444df07eb40646dea84395 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 8 Jan 2016 16:58:02 +0000 Subject: [PATCH 032/108] :arrow_up: electron@0.36.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b67d6a5d..49b754313 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.2", + "electronVersion": "0.36.3", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 271f6b184dc2ba225e43356520a9e25060edeaf9 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 15 Jan 2016 17:21:11 -0500 Subject: [PATCH 033/108] :arrow_up: electron@0.36.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcd36a4be..daf7a94f0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.3", + "electronVersion": "0.36.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From be85af4bc597be5e47259d7654c72268e866a0e4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 25 Jan 2016 16:39:07 -0500 Subject: [PATCH 034/108] :arrow_up: electron@0.36.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 380064d73..c0f62ebd0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.4", + "electronVersion": "0.36.5", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 9db33e5f8e05ebdc7d49fbf61a6ea04caaff35dd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 26 Jan 2016 11:42:12 -0800 Subject: [PATCH 035/108] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0f62ebd0..a1a626636 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.25.0", + "autocomplete-plus": "2.26.0", "autocomplete-snippets": "1.9.0", "autoflow": "0.26.0", "autosave": "0.23.0", From f4be23049d537b78d58a9125d71c28b3f5b2b6f8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 26 Jan 2016 13:26:12 -0800 Subject: [PATCH 036/108] Wait for window resize to take effect in text editor component spec --- spec/text-editor-component-spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 17dfa1183..15ad223fe 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -2155,6 +2155,11 @@ describe('TextEditorComponent', function () { width: windowWidth, height: windowHeight }) + + await conditionPromise(function () { + return window.innerWidth === windowWidth + }) + component.measureDimensions() component.measureWindowSize() await nextViewUpdatePromise() From d1b5e0e7e3ff8e67c58326364af4b8322b415d75 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 26 Jan 2016 17:22:33 -0500 Subject: [PATCH 037/108] :arrow_down: electron@0.36.4 Resolves crashes on Windows --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a1a626636..455bd0503 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.5", + "electronVersion": "0.36.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From a8692f19847153ff4dc1f1256a9d6d779c423f4a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 26 Jan 2016 22:46:17 -0700 Subject: [PATCH 038/108] Extract serialize functionality from ::deactivatePackage. Tests WIP --- spec/package-manager-spec.coffee | 79 +++++++++++++++++--------------- src/package-manager.coffee | 11 ++++- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 46d1d11ee..5a19a10aa 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -444,20 +444,18 @@ describe "PackageManager", -> runs -> expect(console.warn).not.toHaveBeenCalled() - it "passes the activate method the package's previously serialized state if it exists", -> - pack = null + fit "passes the activate method the package's previously serialized state if it exists", -> + pack = atom.packages.loadPackage("package-with-serialization") waitsForPromise -> - atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p - + pack.activate() # require main module runs -> - expect(pack.mainModule.someNumber).not.toBe 77 - pack.mainModule.someNumber = 77 + atom.packages.setPackageState("package-with-serialization", {someNumber: 77}) atom.packages.deactivatePackage("package-with-serialization") spyOn(pack.mainModule, 'activate').andCallThrough() - waitsForPromise -> - atom.packages.activatePackage("package-with-serialization") - runs -> - expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77}) + waitsForPromise -> + atom.packages.activatePackage("package-with-serialization") + runs -> + expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77}) it "invokes ::onDidActivatePackage listeners with the activated package", -> activatedPackage = null @@ -821,6 +819,40 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 + describe "::serialize", -> + # TODO + + describe "::serializePackage(pack)", -> + # afterEach -> + # atom.packages.unloadPackages() + + fit "does not serialize packages that have not been activated called on their main module", -> + spyOn(console, 'warn') + badPack = null + waitsForPromise -> + atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p + + runs -> + spyOn(badPack.mainModule, 'serialize').andCallThrough() + + atom.packages.serializePackage(badPack) + expect(badPack.mainModule.serialize).not.toHaveBeenCalled() + + fit "absorbs exceptions that are thrown by the package module's serialize method", -> + spyOn(console, 'error') + + waitsForPromise -> + atom.packages.activatePackage('package-with-serialize-error') + + waitsForPromise -> + atom.packages.activatePackage('package-with-serialization') + + runs -> + atom.packages.deactivatePackages() + expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() + expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 + expect(console.error).toHaveBeenCalled() + describe "::deactivatePackage(id)", -> afterEach -> atom.packages.unloadPackages() @@ -852,33 +884,6 @@ describe "PackageManager", -> expect(badPack.mainModule.deactivate).not.toHaveBeenCalled() expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy() - it "does not serialize packages that have not been activated called on their main module", -> - spyOn(console, 'warn') - badPack = null - waitsForPromise -> - atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p - - runs -> - spyOn(badPack.mainModule, 'serialize').andCallThrough() - - atom.packages.deactivatePackage("package-that-throws-on-activate") - expect(badPack.mainModule.serialize).not.toHaveBeenCalled() - - it "absorbs exceptions that are thrown by the package module's serialize method", -> - spyOn(console, 'error') - - waitsForPromise -> - atom.packages.activatePackage('package-with-serialize-error') - - waitsForPromise -> - atom.packages.activatePackage('package-with-serialization') - - runs -> - atom.packages.deactivatePackages() - expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() - expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 - expect(console.error).toHaveBeenCalled() - it "absorbs exceptions that are thrown by the package module's deactivate method", -> spyOn(console, 'error') diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 1ecdc5448..3a3a74711 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -467,6 +467,15 @@ class PackageManager return unless hook? and _.isString(hook) and hook.length > 0 @activationHookEmitter.on(hook, callback) + serialize: -> + for pack in @getLoadedPackages() + @serializePackage(pack) + @packageStates + + serializePackage: (pack) -> + if @isPackageActive(pack.name) + @setPackageState(pack.name, state) if state = pack.serialize?() + # Deactivate all packages deactivatePackages: -> @config.transact => @@ -478,8 +487,6 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) - if @isPackageActive(name) - @setPackageState(pack.name, state) if state = pack.serialize?() pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 82d584bac65b163177a5236824dfa061171cf07e Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 26 Jan 2016 22:52:30 -0700 Subject: [PATCH 039/108] Serialize in saveStateSync. Separate deserialization from deactivation. --- src/atom-environment.coffee | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index de52fe55c..110f51acb 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -636,16 +636,19 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() + serialize: -> + @state.project = @project.serialize() + @state.workspace = @workspace.serialize() + @state.packageStates = @packages.serialize() + @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} + @state.fullScreen = @isFullScreen() + unloadEditorWindow: -> return if not @project @storeWindowBackground() - @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} - @state.project = @project.serialize() - @state.workspace = @workspace.serialize() + @serialize() @packages.deactivatePackages() - @state.packageStates = @packages.packageStates - @state.fullScreen = @isFullScreen() @saveStateSync() @saveBlobStoreSync() @@ -782,6 +785,7 @@ class AtomEnvironment extends Model saveStateSync: -> return unless @enablePersistence + @serialize() if storageKey = @getStateKey(@project?.getPaths()) @getStorageFolder().store(storageKey, @state) From 39cb52c2241a83512e2122734cb5655ededee20a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 11:13:29 -0700 Subject: [PATCH 040/108] Fix tests for serialization --- spec/package-manager-spec.coffee | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 5a19a10aa..969215799 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -444,7 +444,7 @@ describe "PackageManager", -> runs -> expect(console.warn).not.toHaveBeenCalled() - fit "passes the activate method the package's previously serialized state if it exists", -> + it "passes the activate method the package's previously serialized state if it exists", -> pack = atom.packages.loadPackage("package-with-serialization") waitsForPromise -> pack.activate() # require main module @@ -819,14 +819,9 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 - describe "::serialize", -> - # TODO + describe "serialization", -> - describe "::serializePackage(pack)", -> - # afterEach -> - # atom.packages.unloadPackages() - - fit "does not serialize packages that have not been activated called on their main module", -> + it "does not serialize packages that have not been activated called on their main module", -> spyOn(console, 'warn') badPack = null waitsForPromise -> @@ -838,7 +833,7 @@ describe "PackageManager", -> atom.packages.serializePackage(badPack) expect(badPack.mainModule.serialize).not.toHaveBeenCalled() - fit "absorbs exceptions that are thrown by the package module's serialize method", -> + it "absorbs exceptions that are thrown by the package module's serialize method", -> spyOn(console, 'error') waitsForPromise -> @@ -848,7 +843,7 @@ describe "PackageManager", -> atom.packages.activatePackage('package-with-serialization') runs -> - atom.packages.deactivatePackages() + atom.packages.serialize() expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 expect(console.error).toHaveBeenCalled() From df83078d741164a32840396527911a0bb2e10496 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 11:15:02 -0700 Subject: [PATCH 041/108] Save state on mousedown or keypress events (debounce 1s). Tests WIP --- spec/atom-environment-spec.coffee | 13 +++++++++++++ src/atom-environment.coffee | 3 +++ 2 files changed, 16 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index b5b975112..938b0eb31 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -174,6 +174,19 @@ describe "AtomEnvironment", -> atom.loadStateSync() expect(atom.state.stuff).toBe("cool") + it "saves state on keypress and mousedown events", -> + spyOn(atom, 'saveStateSync') + + keypress = new KeyboardEvent('keypress') + atom.document.dispatchEvent(keypress) + advanceClock 1100 + expect(atom.saveStateSync).toHaveBeenCalled() + + mousedown = new MouseEvent('mousedown') + atom.document.dispatchEvent(mousedown) + advanceClock 1100 + expect(atom.saveStateSync).toHaveBeenCalled() + describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> beforeEach -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 110f51acb..3e1c28240 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -119,6 +119,9 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params + @document.addEventListener('mousedown', _.debounce(@saveStateSync.bind(this), 1000), true) + @document.addEventListener('keypress', _.debounce(@saveStateSync.bind(this), 1000), true) + @state = {version: @constructor.version} @loadTime = null From 32f51491962cd0d5c95982b0abd6bdf015148571 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 12:38:28 -0800 Subject: [PATCH 042/108] Wait for browser process to acknowledge window manipulation IPC requests We need to avoid using the module for synchronous IPC on startup, but in some cases, we need to know when our asynchronous IPC messages have taken effect. Now, methods like and return Promises that indicate when the message has been processed. --- spec/text-editor-component-spec.js | 6 +--- src/application-delegate.coffee | 13 ++++---- src/atom-environment.coffee | 28 +++++++++-------- src/browser/atom-application.coffee | 19 +++++++++++ src/initialize-application-window.coffee | 14 ++++----- src/ipc-helpers.js | 40 ++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 src/ipc-helpers.js diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 15ad223fe..08da07dd8 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -2151,15 +2151,11 @@ describe('TextEditorComponent', function () { item.style.height = itemHeight + 'px' wrapperNode.style.width = windowWidth + 'px' wrapperNode.style.height = windowHeight + 'px' - atom.setWindowDimensions({ + await atom.setWindowDimensions({ width: windowWidth, height: windowHeight }) - await conditionPromise(function () { - return window.innerWidth === windowWidth - }) - component.measureDimensions() component.measureWindowSize() await nextViewUpdatePromise() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f7b04e10d..f87827886 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,6 @@ _ = require 'underscore-plus' {ipcRenderer, remote, shell, webFrame} = require 'electron' +ipcHelpers = require './ipc-helpers' {Disposable} = require 'event-kit' {getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' @@ -26,26 +27,26 @@ class ApplicationDelegate {width, height} setWindowSize: (width, height) -> - remote.getCurrentWindow().setSize(width, height) + ipcHelpers.call('set-window-size', width, height) getWindowPosition: -> [x, y] = remote.getCurrentWindow().getPosition() {x, y} setWindowPosition: (x, y) -> - ipcRenderer.send("call-window-method", "setPosition", x, y) + ipcHelpers.call('set-window-position', x, y) centerWindow: -> - ipcRenderer.send("call-window-method", "center") + ipcHelpers.call('center-window') focusWindow: -> - ipcRenderer.send("call-window-method", "focus") + ipcHelpers.call('focus-window') showWindow: -> - ipcRenderer.send("call-window-method", "show") + ipcHelpers.call('show-window') hideWindow: -> - ipcRenderer.send("call-window-method", "hide") + ipcHelpers.call('hide-window') reloadWindow: -> ipcRenderer.send("call-window-method", "reload") diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cd6834da4..be05ef4cf 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -519,16 +519,17 @@ class AtomEnvironment extends Model # Restore the window to its previous dimensions and show it. # - # Also restores the full screen and maximized state on the next tick to + # Restores the full screen and maximized state after the window has resized to # prevent resize glitches. displayWindow: -> - dimensions = @restoreWindowDimensions() - @show() - @focus() - - setImmediate => - @setFullScreen(true) if @workspace?.fullScreen - @maximize() if dimensions?.maximized and process.platform isnt 'darwin' + @restoreWindowDimensions().then (dimensions) => + steps = [ + @show(), + @focus() + ] + steps.push(@setFullScreen(true)) if @workspace.fullScreen + steps.push(@maximize()) if dimensions?.maximized and process.platform isnt 'darwin' + Promise.all(steps) # Get the dimensions of this window. # @@ -556,12 +557,14 @@ class AtomEnvironment extends Model # * `width` The new width. # * `height` The new height. setWindowDimensions: ({x, y, width, height}) -> + steps = [] if width? and height? - @setSize(width, height) + steps.push(@setSize(width, height)) if x? and y? - @setPosition(x, y) + steps.push(@setPosition(x, y)) else - @center() + steps.push(@center()) + Promise.all(steps) # Returns true if the dimensions are useable, false if they should be ignored. # Work around for https://github.com/atom/atom-shell/issues/473 @@ -594,8 +597,7 @@ class AtomEnvironment extends Model dimensions = @state.windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() - @setWindowDimensions(dimensions) - dimensions + @setWindowDimensions(dimensions).then -> dimensions storeWindowDimensions: -> dimensions = @getWindowDimensions() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 49bf310dc..ff98c9edc 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -3,6 +3,7 @@ ApplicationMenu = require './application-menu' AtomProtocolHandler = require './atom-protocol-handler' AutoUpdateManager = require './auto-update-manager' StorageFolder = require '../storage-folder' +ipcHelpers = require '../ipc-helpers' {BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron' fs = require 'fs-plus' path = require 'path' @@ -261,6 +262,24 @@ class AtomApplication @promptForPath "folder", (selectedPaths) -> event.sender.send(responseChannel, selectedPaths) + ipcHelpers.respondTo 'set-window-size', (win, width, height) -> + win.setSize(width, height) + + ipcHelpers.respondTo 'set-window-position', (win, x, y) -> + win.setPosition(x, y) + + ipcHelpers.respondTo 'center-window', (win) -> + win.center() + + ipcHelpers.respondTo 'focus-window', (win) -> + win.focus() + + ipcHelpers.respondTo 'show-window', (win) -> + win.show() + + ipcHelpers.respondTo 'hide-window', (win) -> + win.hide() + ipcMain.on 'did-cancel-window-unload', => @quitting = false diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 57aa33ce0..35c48ee0a 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,11 +23,11 @@ module.exports = ({blobStore}) -> enablePersistence: true }) - atom.displayWindow() - atom.startEditorWindow() + atom.displayWindow().then -> + atom.startEditorWindow() - # Workaround for focus getting cleared upon window creation - windowFocused = -> - window.removeEventListener('focus', windowFocused) - setTimeout (-> document.querySelector('atom-workspace').focus()), 0 - window.addEventListener('focus', windowFocused) + # Workaround for focus getting cleared upon window creation + windowFocused = -> + window.removeEventListener('focus', windowFocused) + setTimeout (-> document.querySelector('atom-workspace').focus()), 0 + window.addEventListener('focus', windowFocused) diff --git a/src/ipc-helpers.js b/src/ipc-helpers.js new file mode 100644 index 000000000..c0b38c50e --- /dev/null +++ b/src/ipc-helpers.js @@ -0,0 +1,40 @@ +var ipcRenderer = null +var ipcMain = null +var BrowserWindow = null + +exports.call = function (methodName, ...args) { + if (!ipcRenderer) { + ipcRenderer = require('electron').ipcRenderer + } + + var responseChannel = getResponseChannel(methodName) + + return new Promise(function (resolve) { + ipcRenderer.on(responseChannel, function (event, result) { + ipcRenderer.removeAllListeners(responseChannel) + resolve(result) + }) + + ipcRenderer.send(methodName, ...args) + }) +} + +exports.respondTo = function (methodName, callback) { + if (!ipcMain) { + var electron = require('electron') + ipcMain = electron.ipcMain + BrowserWindow = electron.BrowserWindow + } + + var responseChannel = getResponseChannel(methodName) + + ipcMain.on(methodName, function (event, ...args) { + var browserWindow = BrowserWindow.fromWebContents(event.sender) + var result = callback(browserWindow, ...args) + event.sender.send(responseChannel, result) + }) +} + +function getResponseChannel (methodName) { + return 'ipc-helpers-' + methodName + '-response' +} From 28e535ee15921e621a2b3218acc456e985a24d2b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 13:00:18 -0800 Subject: [PATCH 043/108] Apply window background color after resizing window --- src/atom-environment.coffee | 9 +++++++++ static/index.js | 26 -------------------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index be05ef4cf..44579a4bc 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -524,6 +524,7 @@ class AtomEnvironment extends Model displayWindow: -> @restoreWindowDimensions().then (dimensions) => steps = [ + @restoreWindowBackground(), @show(), @focus() ] @@ -603,6 +604,13 @@ class AtomEnvironment extends Model dimensions = @getWindowDimensions() @state.windowDimensions = dimensions if @isValidDimensions(dimensions) + restoreWindowBackground: -> + if backgroundColor = window.localStorage.getItem('atom:window-background-color') + @backgroundStylesheet = document.createElement('style') + @backgroundStylesheet.type = 'text/css' + @backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }' + document.head.appendChild(@backgroundStylesheet) + storeWindowBackground: -> return if @inSpecMode() @@ -627,6 +635,7 @@ class AtomEnvironment extends Model @packages.loadPackages() @loadStateSync() @document.body.appendChild(@views.getView(@workspace)) + @backgroundStylesheet?.remove() @watchProjectPath() diff --git a/static/index.js b/static/index.js index 796cda363..bedd422fb 100644 --- a/static/index.js +++ b/static/index.js @@ -146,31 +146,6 @@ } } - function setupWindowBackground () { - if (loadSettings && loadSettings.isSpec) { - return - } - - var backgroundColor = window.localStorage.getItem('atom:window-background-color') - if (!backgroundColor) { - return - } - - var backgroundStylesheet = document.createElement('style') - backgroundStylesheet.type = 'text/css' - backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }' - document.head.appendChild(backgroundStylesheet) - - // Remove once the page loads - window.addEventListener('load', function loadWindow () { - window.removeEventListener('load', loadWindow, false) - setTimeout(function () { - backgroundStylesheet.remove() - backgroundStylesheet = null - }, 1000) - }, false) - } - var setupAtomHome = function () { if (process.env.ATOM_HOME) { return @@ -186,5 +161,4 @@ parseLoadSettings() setupAtomHome() - setupWindowBackground() })() From e09c7a99111c1f95da24281dd40aec19b4032be4 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 14:58:19 -0700 Subject: [PATCH 044/108] =?UTF-8?q?Avoid=20binding=20method=20before=20it?= =?UTF-8?q?=E2=80=99s=20spied=20upon=20when=20debouncing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 3e1c28240..d13937bc6 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -119,8 +119,9 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - @document.addEventListener('mousedown', _.debounce(@saveStateSync.bind(this), 1000), true) - @document.addEventListener('keypress', _.debounce(@saveStateSync.bind(this), 1000), true) + debouncedSaveStateSync = _.debounce((=> @saveStateSync()), 1000) + @document.addEventListener('mousedown', debouncedSaveStateSync, true) + @document.addEventListener('keypress', debouncedSaveStateSync, true) @state = {version: @constructor.version} From 130f23166da9ec1cbc3f0e8c5e42e980b071b189 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 14:04:50 -0800 Subject: [PATCH 045/108] Emit window:loaded event after editor window is started --- src/initialize-application-window.coffee | 1 + static/index.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 35c48ee0a..1a4a74447 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -25,6 +25,7 @@ module.exports = ({blobStore}) -> atom.displayWindow().then -> atom.startEditorWindow() + require('electron').ipcRenderer.send('window-command', 'window:loaded') # Workaround for focus getting cleared upon window creation windowFocused = -> diff --git a/static/index.js b/static/index.js index bedd422fb..6b901a215 100644 --- a/static/index.js +++ b/static/index.js @@ -85,7 +85,6 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('electron').ipcRenderer.send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 8d55bbcdeadc41b07a1e5e710e45b4a939c399eb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 15:10:35 -0700 Subject: [PATCH 046/108] :art: clean up test --- spec/package-manager-spec.coffee | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 969215799..8710927df 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -819,9 +819,8 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 - describe "serialization", -> - - it "does not serialize packages that have not been activated called on their main module", -> + describe "::serialize", -> + it "does not serialize packages that threw an error during activation", -> spyOn(console, 'warn') badPack = null waitsForPromise -> @@ -830,7 +829,7 @@ describe "PackageManager", -> runs -> spyOn(badPack.mainModule, 'serialize').andCallThrough() - atom.packages.serializePackage(badPack) + atom.packages.serialize() expect(badPack.mainModule.serialize).not.toHaveBeenCalled() it "absorbs exceptions that are thrown by the package module's serialize method", -> From 126baafda39d3d6a5a0f259ccb81864c069e176c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 15:11:40 -0700 Subject: [PATCH 047/108] Assign debounce interval to property --- spec/atom-environment-spec.coffee | 4 ++-- src/atom-environment.coffee | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 938b0eb31..4621886dc 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -179,12 +179,12 @@ describe "AtomEnvironment", -> keypress = new KeyboardEvent('keypress') atom.document.dispatchEvent(keypress) - advanceClock 1100 + advanceClock atom.saveStateDebounceInterval expect(atom.saveStateSync).toHaveBeenCalled() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) - advanceClock 1100 + advanceClock atom.saveStateDebounceInterval expect(atom.saveStateSync).toHaveBeenCalled() describe "openInitialEmptyEditorIfNecessary", -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index d13937bc6..cabd1896b 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -111,6 +111,8 @@ class AtomEnvironment extends Model # Public: A {Workspace} instance workspace: null + saveStateDebounceInterval: 1000 + ### Section: Construction and Destruction ### @@ -119,7 +121,7 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveStateSync = _.debounce((=> @saveStateSync()), 1000) + debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveStateSync, true) @document.addEventListener('keypress', debouncedSaveStateSync, true) From a2f9a8d32e5529b5f7ce4021104a4a836ae23b82 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 23:52:41 -0700 Subject: [PATCH 048/108] Rename StorageFolder::store to ::storeSync --- src/atom-environment.coffee | 2 +- src/browser/atom-application.coffee | 2 +- src/storage-folder.coffee | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cabd1896b..215bcd7ed 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -794,7 +794,7 @@ class AtomEnvironment extends Model @serialize() if storageKey = @getStateKey(@project?.getPaths()) - @getStorageFolder().store(storageKey, @state) + @getStorageFolder().storeSync(storageKey, @state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 44848eb72..5ff24c458 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -472,7 +472,7 @@ class AtomApplication if loadSettings = window.getLoadSettings() states.push(initialPaths: loadSettings.initialPaths) if states.length > 0 or allowEmpty - @storageFolder.store('application.json', states) + @storageFolder.storeSync('application.json', states) loadState: (options) -> if (states = @storageFolder.load('application.json'))?.length > 0 diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index da8af3f2e..06beae56a 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -6,7 +6,7 @@ class StorageFolder constructor: (containingPath) -> @path = path.join(containingPath, "storage") if containingPath? - store: (name, object) -> + storeSync: (name, object) -> return unless @path? fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') From 5148b8ca3da6f36a050249751f5f6fb7f371e9f0 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 00:47:21 -0700 Subject: [PATCH 049/108] Save state on keydown rather than on keypress --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 215bcd7ed..fc89864eb 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -123,7 +123,7 @@ class AtomEnvironment extends Model debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveStateSync, true) - @document.addEventListener('keypress', debouncedSaveStateSync, true) + @document.addEventListener('keydown', debouncedSaveState, true) @state = {version: @constructor.version} From 54a03516bf51ddf00c6ea0c0dd057fd57e7e7222 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 00:56:52 -0700 Subject: [PATCH 050/108] Save state asynchronously on mousedown and keydown events. Tests WIP --- spec/atom-environment-spec.coffee | 19 ++++++++++--------- src/atom-environment.coffee | 14 ++++++++------ src/storage-folder.coffee | 5 +++++ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 4621886dc..a575b993d 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -163,7 +163,7 @@ describe "AtomEnvironment", -> atom.state.stuff = "cool" atom.project.setPaths([dir1, dir2]) - atom.saveStateSync() + atom.saveState(true) atom.state = {} atom.loadStateSync() @@ -174,18 +174,18 @@ describe "AtomEnvironment", -> atom.loadStateSync() expect(atom.state.stuff).toBe("cool") - it "saves state on keypress and mousedown events", -> - spyOn(atom, 'saveStateSync') + it "saves state on keydown and mousedown events", -> + spyOn(atom, 'saveState') - keypress = new KeyboardEvent('keypress') - atom.document.dispatchEvent(keypress) + keydown = new KeyboardEvent('keydown') + atom.document.dispatchEvent(keydown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveStateSync).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalled() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveStateSync).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalled() describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> @@ -243,9 +243,10 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() + # TODO: fix failing test. devtools show that ::saveState just goes to jasmine.createSpy.spyObj function it "saves the serialized state of the window so it can be deserialized after reload", -> atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) - spyOn(atomEnvironment, 'saveStateSync') + spyOn(atomEnvironment, 'saveState') workspaceState = atomEnvironment.workspace.serialize() grammarsState = {grammarOverridesByPath: atomEnvironment.grammars.grammarOverridesByPath} @@ -256,7 +257,7 @@ describe "AtomEnvironment", -> expect(atomEnvironment.state.workspace).toEqual workspaceState expect(atomEnvironment.state.grammars).toEqual grammarsState expect(atomEnvironment.state.project).toEqual projectState - expect(atomEnvironment.saveStateSync).toHaveBeenCalled() + expect(atomEnvironment.saveState).toHaveBeenCalled() atomEnvironment.destroy() diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index fc89864eb..247b73b40 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -121,8 +121,8 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) - @document.addEventListener('mousedown', debouncedSaveStateSync, true) + debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) + @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) @state = {version: @constructor.version} @@ -653,9 +653,8 @@ class AtomEnvironment extends Model return if not @project @storeWindowBackground() - @serialize() + @saveState(true) @packages.deactivatePackages() - @saveStateSync() @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> @@ -789,12 +788,15 @@ class AtomEnvironment extends Model @blobStore.save() - saveStateSync: -> + saveState: (synchronous) -> return unless @enablePersistence @serialize() if storageKey = @getStateKey(@project?.getPaths()) - @getStorageFolder().storeSync(storageKey, @state) + if synchronous + @getStorageFolder().storeSync(storageKey, @state) + else + @getStorageFolder().storeAsync(storageKey, @state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index 06beae56a..d94a6f013 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,6 +11,11 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') + storeAsync: (name, object) -> + return unless @path? + + fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') + load: (name) -> return unless @path? From 29deb61d4ed084d44c32494c7e6b48c4d0a4d0cb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 01:29:46 -0700 Subject: [PATCH 051/108] Remove AtomEnvironment state instance variable. Tests WIP --- src/atom-environment.coffee | 43 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 247b73b40..e4158accd 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -308,9 +308,6 @@ class AtomEnvironment extends Model @views.clear() @registerDefaultViewProviders() - @state.packageStates = {} - delete @state.workspace - destroy: -> return if not @project @@ -597,7 +594,7 @@ class AtomEnvironment extends Model {x: 0, y: 0, width: Math.min(1024, width), height} restoreWindowDimensions: -> - dimensions = @state.windowDimensions + dimensions = @windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() @setWindowDimensions(dimensions) @@ -605,7 +602,7 @@ class AtomEnvironment extends Model storeWindowDimensions: -> dimensions = @getWindowDimensions() - @state.windowDimensions = dimensions if @isValidDimensions(dimensions) + @windowDimensions = dimensions if @isValidDimensions(dimensions) storeWindowBackground: -> return if @inSpecMode() @@ -643,11 +640,11 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() serialize: -> - @state.project = @project.serialize() - @state.workspace = @workspace.serialize() - @state.packageStates = @packages.serialize() - @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} - @state.fullScreen = @isFullScreen() + project: @project.serialize() + workspace: @workspace.serialize() + packageStates: @packages.serialize() + grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath} + fullScreen: @isFullScreen() unloadEditorWindow: -> return if not @project @@ -790,15 +787,15 @@ class AtomEnvironment extends Model saveState: (synchronous) -> return unless @enablePersistence - @serialize() + state = @serialize() if storageKey = @getStateKey(@project?.getPaths()) if synchronous - @getStorageFolder().storeSync(storageKey, @state) + @getStorageFolder().storeSync(storageKey, state) else - @getStorageFolder().storeAsync(storageKey, @state) + @getStorageFolder().storeAsync(storageKey, state) else - @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) + @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) loadStateSync: -> return unless @enablePersistence @@ -806,31 +803,29 @@ class AtomEnvironment extends Model startTime = Date.now() if stateKey = @getStateKey(@getLoadSettings().initialPaths) - if state = @getStorageFolder().load(stateKey) - @state = state + state = @getStorageFolder().load(stateKey) - if not @state? and windowState = @getLoadSettings().windowState + if not state? and windowState = @getLoadSettings().windowState try - if state = JSON.parse(@getLoadSettings().windowState) - @state = state + state = JSON.parse(@getLoadSettings().windowState) catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error @deserializeTimings.atom = Date.now() - startTime - if grammarOverridesByPath = @state.grammars?.grammarOverridesByPath + if grammarOverridesByPath = state.grammars?.grammarOverridesByPath @grammars.grammarOverridesByPath = grammarOverridesByPath - @setFullScreen(@state.fullScreen) + @setFullScreen(state.fullScreen) - @packages.packageStates = @state.packageStates ? {} + @packages.packageStates = state.packageStates ? {} startTime = Date.now() - @project.deserialize(@state.project, @deserializers) if @state.project? + @project.deserialize(state.project, @deserializers) if state.project? @deserializeTimings.project = Date.now() - startTime startTime = Date.now() - @workspace.deserialize(@state.workspace, @deserializers) if @state.workspace? + @workspace.deserialize(state.workspace, @deserializers) if state.workspace? @deserializeTimings.workspace = Date.now() - startTime getStateKey: (paths) -> From dff4aa8e84f37590c3ae218708c66c285ffb93b7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 14:03:10 -0700 Subject: [PATCH 052/108] Use method name `store` rather than `storeAsync` --- src/atom-environment.coffee | 2 +- src/storage-folder.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e4158accd..b6ebc172f 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -793,7 +793,7 @@ class AtomEnvironment extends Model if synchronous @getStorageFolder().storeSync(storageKey, state) else - @getStorageFolder().storeAsync(storageKey, state) + @getStorageFolder().store(storageKey, state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index d94a6f013..ff3474198 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,7 +11,7 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') - storeAsync: (name, object) -> + store: (name, object) -> return unless @path? fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') From a54f4679af66792322aa35edbfb21da41546b356 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:46:40 -0700 Subject: [PATCH 053/108] Fix tests --- spec/atom-environment-spec.coffee | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index a575b993d..856cd0338 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -160,19 +160,18 @@ describe "AtomEnvironment", -> spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) + spyOn(atom, 'serialize').andReturn({stuff: 'cool'}) + spyOn(atom, 'deserialize') - atom.state.stuff = "cool" atom.project.setPaths([dir1, dir2]) atom.saveState(true) - atom.state = {} atom.loadStateSync() - expect(atom.state.stuff).toBeUndefined() + expect(atom.deserialize).not.toHaveBeenCalled() loadSettings.initialPaths = [dir2, dir1] - atom.state = {} atom.loadStateSync() - expect(atom.state.stuff).toBe("cool") + expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) it "saves state on keydown and mousedown events", -> spyOn(atom, 'saveState') @@ -243,20 +242,11 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() - # TODO: fix failing test. devtools show that ::saveState just goes to jasmine.createSpy.spyObj function it "saves the serialized state of the window so it can be deserialized after reload", -> atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) spyOn(atomEnvironment, 'saveState') - workspaceState = atomEnvironment.workspace.serialize() - grammarsState = {grammarOverridesByPath: atomEnvironment.grammars.grammarOverridesByPath} - projectState = atomEnvironment.project.serialize() - atomEnvironment.unloadEditorWindow() - - expect(atomEnvironment.state.workspace).toEqual workspaceState - expect(atomEnvironment.state.grammars).toEqual grammarsState - expect(atomEnvironment.state.project).toEqual projectState expect(atomEnvironment.saveState).toHaveBeenCalled() atomEnvironment.destroy() From 92bd5051b3f255d7035d70ea31674a14b4c70830 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:47:37 -0700 Subject: [PATCH 054/108] Add env version and window dimensions to serialized state --- src/atom-environment.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index b6ebc172f..8ed254223 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -640,11 +640,13 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() serialize: -> + version: @constructor.version project: @project.serialize() workspace: @workspace.serialize() packageStates: @packages.serialize() grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath} fullScreen: @isFullScreen() + windowDimensions: @windowDimensions unloadEditorWindow: -> return if not @project From c9012a228843df07cf5cd32a32b3329f3fb75ab8 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:48:45 -0700 Subject: [PATCH 055/108] Call AtomEnvironment::deserialize in AtomEnvironment::loadStateSync --- src/atom-environment.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 8ed254223..5c61b1439 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -813,6 +813,9 @@ class AtomEnvironment extends Model catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error + @deserialize(state) if state? + + deserialize: (state) -> @deserializeTimings.atom = Date.now() - startTime if grammarOverridesByPath = state.grammars?.grammarOverridesByPath From 9cec10d9c0c8851d10818f71605a25112f968fd5 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 22:48:31 -0700 Subject: [PATCH 056/108] Remove atom environment state instance variable --- src/atom-environment.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 5c61b1439..2ec28d230 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -125,7 +125,6 @@ class AtomEnvironment extends Model @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) - @state = {version: @constructor.version} @loadTime = null {devMode, safeMode, resourcePath} = @getLoadSettings() From 224b51d17c25633fe297b1dc84500e5c5d047960 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 22:49:46 -0700 Subject: [PATCH 057/108] Add disposable for removing debouncedSaveState listener --- src/atom-environment.coffee | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2ec28d230..4cb2e5928 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -4,7 +4,7 @@ ipc = require 'ipc' _ = require 'underscore-plus' {deprecate} = require 'grim' -{CompositeDisposable, Emitter} = require 'event-kit' +{CompositeDisposable, Disposable, Emitter} = require 'event-kit' fs = require 'fs-plus' {mapSourcePosition} = require 'source-map-support' Model = require './model' @@ -121,11 +121,6 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) - @document.addEventListener('mousedown', debouncedSaveState, true) - @document.addEventListener('keydown', debouncedSaveState, true) - - @loadTime = null {devMode, safeMode, resourcePath} = @getLoadSettings() @@ -205,6 +200,7 @@ class AtomEnvironment extends Model @registerDefaultViewProviders() @installUncaughtErrorHandler() + @attachSaveStateListeners() @installWindowEventHandler() @observeAutoHideMenuBar() @@ -218,6 +214,14 @@ class AtomEnvironment extends Model checkPortableHomeWritable() + attachSaveStateListeners: -> + debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) + @document.addEventListener('mousedown', debouncedSaveState, true) + @document.addEventListener('keydown', debouncedSaveState, true) + @disposables.add new Disposable => + @document.removeEventListener('mousedown', debouncedSaveState, true) + @document.removeEventListener('keydown', debouncedSaveState, true) + setConfigSchema: -> @config.setSchema null, {type: 'object', properties: _.clone(require('./config-schema'))} From 0fd753ea8c790a2cd3955357fb55b426ed2c8761 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 30 Jan 2016 12:07:36 -0500 Subject: [PATCH 058/108] :arrow_up: electron@0.36.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 455bd0503..ca569b342 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.4", + "electronVersion": "0.36.7", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 5e21f7bad9efcc519d291a2b5910a5f4fd5e8ce7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 1 Feb 2016 16:11:10 -0800 Subject: [PATCH 059/108] Serialize package upon deactivation --- spec/package-manager-spec.coffee | 7 ++++--- src/package-manager.coffee | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 8710927df..aa0b2d26f 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -445,11 +445,12 @@ describe "PackageManager", -> expect(console.warn).not.toHaveBeenCalled() it "passes the activate method the package's previously serialized state if it exists", -> - pack = atom.packages.loadPackage("package-with-serialization") + pack = null waitsForPromise -> - pack.activate() # require main module + atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p runs -> - atom.packages.setPackageState("package-with-serialization", {someNumber: 77}) + expect(pack.mainModule.someNumber).not.toBe 77 + pack.mainModule.someNumber = 77 atom.packages.deactivatePackage("package-with-serialization") spyOn(pack.mainModule, 'activate').andCallThrough() waitsForPromise -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 3a3a74711..636286640 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -487,6 +487,7 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) + @serializePackage(pack) pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 81f30d49089cd7853763dc8d2a480d1ec7eca2ab Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 1 Feb 2016 16:49:21 -0800 Subject: [PATCH 060/108] Only call package serialize methods once on quit --- src/atom-environment.coffee | 2 +- src/package-manager.coffee | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 4cb2e5928..68711b260 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -655,8 +655,8 @@ class AtomEnvironment extends Model return if not @project @storeWindowBackground() - @saveState(true) @packages.deactivatePackages() + @saveState(true) @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 636286640..705755af0 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -468,13 +468,12 @@ class PackageManager @activationHookEmitter.on(hook, callback) serialize: -> - for pack in @getLoadedPackages() + for pack in @getActivePackages() @serializePackage(pack) @packageStates serializePackage: (pack) -> - if @isPackageActive(pack.name) - @setPackageState(pack.name, state) if state = pack.serialize?() + @setPackageState(pack.name, state) if state = pack.serialize?() # Deactivate all packages deactivatePackages: -> @@ -487,7 +486,7 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) - @serializePackage(pack) + @serializePackage(pack) if @isPackageActive(pack.name) pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 3b500daab4d552b61e882d0a99872135f5c47552 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 4 Feb 2016 21:43:44 -0800 Subject: [PATCH 061/108] Create StateStore class and specs for storing state in IndexedDB --- spec/state-store-spec.js | 37 +++++++++++++++++++++++++++++++++ src/state-store.js | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 spec/state-store-spec.js create mode 100644 src/state-store.js diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js new file mode 100644 index 000000000..f505cf607 --- /dev/null +++ b/spec/state-store-spec.js @@ -0,0 +1,37 @@ +/** @babel */ +import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' + +const StateStore = require('../src/state-store.js') + +describe("StateStore", () => { + it("can save and load states", () => { + const store = new StateStore() + return store.save('key', {foo:'bar'}) + .then(() => store.load('key')) + .then((state) => { + expect(state).toEqual({foo:'bar'}) + }) + }) + + describe("when there is an error reading from the database", () => { + it("rejects the promise returned by load", () => { + const store = new StateStore() + + const fakeErrorEvent = {target: {errorCode: "Something bad happened"}} + + spyOn(IDBObjectStore.prototype, 'get').andCallFake((key) => { + let request = {} + process.nextTick(() => request.onerror(fakeErrorEvent)) + return request + }) + + return store.load('nonexistentKey') + .then(() => { + throw new Error("Promise should have been rejected") + }) + .catch((event) => { + expect(event).toBe(fakeErrorEvent) + }) + }) + }) +}) diff --git a/src/state-store.js b/src/state-store.js new file mode 100644 index 000000000..7d6ee79f6 --- /dev/null +++ b/src/state-store.js @@ -0,0 +1,45 @@ +'use strict' + +module.exports = +class StateStore { + constructor () { + this.dbPromise = new Promise((resolve, reject) => { + let dbOpenRequest = indexedDB.open('AtomEnvironments', 1) + dbOpenRequest.onupgradeneeded = (event) => { + let db = event.target.result + db.createObjectStore('states') + resolve(db) + } + dbOpenRequest.onsuccess = () => { + resolve(dbOpenRequest.result) + } + dbOpenRequest.onerror = reject + }) + } + + save (key, value) { + return this.dbPromise.then(db => { + return new Promise((resolve, reject) => { + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .put(value, key) + + request.onsuccess = resolve + request.onerror = reject + }) + }) + } + + load (key) { + return this.dbPromise.then(db => { + return new Promise((resolve, reject) => { + var request = db.transaction(['states']) + .objectStore('states') + .get(key) + + request.onsuccess = (event) => resolve(event.target.result) + request.onerror = (event) => reject(event) + }) + }) + } +} From 6e0328b048af8e9d297a81e07784e3bd5762fbdf Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 4 Feb 2016 21:45:00 -0800 Subject: [PATCH 062/108] Refactor to use StateStore instead of StorageFolder --- spec/atom-environment-spec.coffee | 34 +++++++-------- src/atom-environment.coffee | 54 ++++++++++++------------ src/initialize-application-window.coffee | 12 +++--- 3 files changed, 48 insertions(+), 52 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 856cd0338..5afb5169b 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -159,19 +159,22 @@ describe "AtomEnvironment", -> windowState: null spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings - spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) spyOn(atom, 'serialize').andReturn({stuff: 'cool'}) spyOn(atom, 'deserialize') atom.project.setPaths([dir1, dir2]) - atom.saveState(true) + waitsForPromise -> + atom.saveState().then -> + atom.loadState() - atom.loadStateSync() - expect(atom.deserialize).not.toHaveBeenCalled() + runs -> + expect(atom.deserialize).not.toHaveBeenCalled() - loadSettings.initialPaths = [dir2, dir1] - atom.loadStateSync() - expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) + waitsForPromise -> + loadSettings.initialPaths = [dir2, dir1] + atom.loadState() + runs -> + expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) it "saves state on keydown and mousedown events", -> spyOn(atom, 'saveState') @@ -242,15 +245,6 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() - it "saves the serialized state of the window so it can be deserialized after reload", -> - atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) - spyOn(atomEnvironment, 'saveState') - - atomEnvironment.unloadEditorWindow() - expect(atomEnvironment.saveState).toHaveBeenCalled() - - atomEnvironment.destroy() - describe "::destroy()", -> it "does not throw exceptions when unsubscribing from ipc events (regression)", -> configDirPath = temp.mkdirSync() @@ -262,9 +256,11 @@ describe "AtomEnvironment", -> } atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument}) spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn [] - atomEnvironment.startEditorWindow() - atomEnvironment.unloadEditorWindow() - atomEnvironment.destroy() + waitsForPromise -> + atomEnvironment.startEditorWindow() + runs -> + atomEnvironment.unloadEditorWindow() + atomEnvironment.destroy() describe "::openLocations(locations) (called via IPC from browser process)", -> beforeEach -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 68711b260..84f1cb23e 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -10,7 +10,7 @@ fs = require 'fs-plus' Model = require './model' WindowEventHandler = require './window-event-handler' StylesElement = require './styles-element' -StorageFolder = require './storage-folder' +StateStore = require './state-store' {getWindowLoadSettings} = require './window-load-settings-helpers' registerDefaultCommands = require './register-default-commands' @@ -127,6 +127,8 @@ class AtomEnvironment extends Model @emitter = new Emitter @disposables = new CompositeDisposable + @stateStore = new StateStore + @deserializers = new DeserializerManager(this) @deserializeTimings = {} @@ -629,18 +631,18 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - @loadStateSync() - @document.body.appendChild(@views.getView(@workspace)) + @loadState().then => + @document.body.appendChild(@views.getView(@workspace)) - @watchProjectPath() + @watchProjectPath() - @packages.activate() - @keymaps.loadUserKeymap() - @requireUserInitScript() unless @getLoadSettings().safeMode + @packages.activate() + @keymaps.loadUserKeymap() + @requireUserInitScript() unless @getLoadSettings().safeMode - @menu.update() + @menu.update() - @openInitialEmptyEditorIfNecessary() + @openInitialEmptyEditorIfNecessary() serialize: -> version: @constructor.version @@ -656,7 +658,6 @@ class AtomEnvironment extends Model @storeWindowBackground() @packages.deactivatePackages() - @saveState(true) @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> @@ -790,37 +791,39 @@ class AtomEnvironment extends Model @blobStore.save() - saveState: (synchronous) -> - return unless @enablePersistence + saveState: () -> + return Promise.resolve() unless @enablePersistence state = @serialize() if storageKey = @getStateKey(@project?.getPaths()) - if synchronous - @getStorageFolder().storeSync(storageKey, state) - else - @getStorageFolder().store(storageKey, state) + @stateStore.save(storageKey, state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) + Promise.resolve() - loadStateSync: -> - return unless @enablePersistence + loadState: -> + return Promise.resolve() unless @enablePersistence startTime = Date.now() + statePromise = null if stateKey = @getStateKey(@getLoadSettings().initialPaths) - state = @getStorageFolder().load(stateKey) + statePromise = @stateStore.load(stateKey) - if not state? and windowState = @getLoadSettings().windowState + if not statePromise? and windowState = @getLoadSettings().windowState try - state = JSON.parse(@getLoadSettings().windowState) + statePromise = Promise.resolve(JSON.parse(@getLoadSettings().windowState)) catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error - @deserialize(state) if state? + if statePromise? + statePromise.then (state) => + @deserializeTimings.atom = Date.now() - startTime + @deserialize(state) if state? + else + Promise.resolve() deserialize: (state) -> - @deserializeTimings.atom = Date.now() - startTime - if grammarOverridesByPath = state.grammars?.grammarOverridesByPath @grammars.grammarOverridesByPath = grammarOverridesByPath @@ -846,9 +849,6 @@ class AtomEnvironment extends Model getConfigDirPath: -> @configDirPath ?= process.env.ATOM_HOME - getStorageFolder: -> - @storageFolder ?= new StorageFolder(@getConfigDirPath()) - getUserInitScriptPath: -> initScriptPath = fs.resolve(@getConfigDirPath(), 'init', ['js', 'coffee']) initScriptPath ? path.join(@getConfigDirPath(), 'init.coffee') diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 57aa33ce0..45e18163d 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -24,10 +24,10 @@ module.exports = ({blobStore}) -> }) atom.displayWindow() - atom.startEditorWindow() + atom.startEditorWindow().then -> - # Workaround for focus getting cleared upon window creation - windowFocused = -> - window.removeEventListener('focus', windowFocused) - setTimeout (-> document.querySelector('atom-workspace').focus()), 0 - window.addEventListener('focus', windowFocused) + # Workaround for focus getting cleared upon window creation + windowFocused = -> + window.removeEventListener('focus', windowFocused) + setTimeout (-> document.querySelector('atom-workspace').focus()), 0 + window.addEventListener('focus', windowFocused) From 85b32b861ed2f6463ef640a4c4bd1ffb9e55783c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 5 Feb 2016 16:49:23 -0800 Subject: [PATCH 063/108] Add storedAt date for serialized environment state --- src/state-store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/state-store.js b/src/state-store.js index 7d6ee79f6..f07560038 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -19,6 +19,7 @@ class StateStore { save (key, value) { return this.dbPromise.then(db => { + value.storedAt = new Date().toString() return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') .objectStore('states') From f3b39ad82e85a398b33d8a64d504ca7b289e728f Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 14:44:12 -0800 Subject: [PATCH 064/108] =?UTF-8?q?Add=20=E2=80=98indexedDB=E2=80=99=20to?= =?UTF-8?q?=20list=20of=20known=20global=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 322b3c784..94ab84a68 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,8 @@ "runs", "spyOn", "waitsFor", - "waitsForPromise" + "waitsForPromise", + "indexedDB" ] } } From f3a6a1d52283b72fe9fcc23b6c7f5b88545c6096 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 14:44:35 -0800 Subject: [PATCH 065/108] Use prerelease version of text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94ab84a68..fced6c777 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.1.4", + "text-buffer": "8.2.2-1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From dc355629624a7f7852a6b68079862d28eb325df7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 15:12:46 -0800 Subject: [PATCH 066/108] Remove empty parameter list in order to pass linter --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 84f1cb23e..a2b56fdd4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -791,7 +791,7 @@ class AtomEnvironment extends Model @blobStore.save() - saveState: () -> + saveState: -> return Promise.resolve() unless @enablePersistence state = @serialize() From 9b2c791c86443387c16b3d858dbdd22f070bd9cd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:28:01 -0800 Subject: [PATCH 067/108] Don't emit window:loaded event until async window initialization completes Signed-off-by: Katrina Uychaco --- src/initialize-test-window.coffee | 4 +++- static/index.js | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index f3507b479..bdd94461a 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -68,7 +68,9 @@ module.exports = ({blobStore}) -> logFile, headless, testPaths, buildAtomEnvironment, buildDefaultApplicationDelegate, legacyTestRunner }) - promise.then(exitWithStatusCode) if getWindowLoadSettings().headless + promise.then (statusCode) -> + exitWithStatusCode(statusCode) if getWindowLoadSettings().headless + catch error if getWindowLoadSettings().headless console.error(error.stack ? error) diff --git a/static/index.js b/static/index.js index 6d65d3c52..651c2afe6 100644 --- a/static/index.js +++ b/static/index.js @@ -83,8 +83,9 @@ setupCsonCache(CompileCache.getCacheDirectory()) var initialize = require(loadSettings.windowInitializationScript) - initialize({blobStore: blobStore}) - require('ipc').sendChannel('window-command', 'window:loaded') + initialize({blobStore: blobStore}).then(function () { + require('ipc').sendChannel('window-command', 'window:loaded') + }) } function setupCsonCache (cacheDir) { From b0cf440f9cc294fa49a4d4c815615e1db6314288 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:30:10 -0800 Subject: [PATCH 068/108] Handle database connection errors gracefully When opening a second Atom instance (e.g. when running the integration specs) indexedDB connections will fail. In this case, StateStore.prototype.save and StateStore.prototype.load will become noops. Signed-off-by: Katrina Uychaco --- spec/state-store-spec.js | 16 +++++++++++++--- src/atom-environment.coffee | 2 +- src/state-store.js | 29 +++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index f505cf607..955ceb767 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -1,11 +1,14 @@ /** @babel */ -import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' +import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' const StateStore = require('../src/state-store.js') describe("StateStore", () => { + let databaseName = `test-database-${Date.now()}` + let version = 1 + it("can save and load states", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) return store.save('key', {foo:'bar'}) .then(() => store.load('key')) .then((state) => { @@ -13,9 +16,16 @@ describe("StateStore", () => { }) }) + it("resolves with null when a non-existent key is loaded", () => { + const store = new StateStore(databaseName, version) + return store.load('no-such-key').then((value) => { + expect(value).toBeNull() + }) + }); + describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) const fakeErrorEvent = {target: {errorCode: "Something bad happened"}} diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 141c1c112..c02ac59c7 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -127,7 +127,7 @@ class AtomEnvironment extends Model @emitter = new Emitter @disposables = new CompositeDisposable - @stateStore = new StateStore + @stateStore = new StateStore('AtomEnvironments', 1) @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/state-store.js b/src/state-store.js index f07560038..817d4282f 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -2,28 +2,33 @@ module.exports = class StateStore { - constructor () { - this.dbPromise = new Promise((resolve, reject) => { - let dbOpenRequest = indexedDB.open('AtomEnvironments', 1) + constructor (databaseName, version) { + this.dbPromise = new Promise((resolve) => { + let dbOpenRequest = indexedDB.open(databaseName, version) dbOpenRequest.onupgradeneeded = (event) => { let db = event.target.result db.createObjectStore('states') - resolve(db) } dbOpenRequest.onsuccess = () => { resolve(dbOpenRequest.result) } - dbOpenRequest.onerror = reject + dbOpenRequest.onerror = (error) => { + console.error("Could not connect to indexedDB", error) + resolve(null) + } }) } save (key, value) { return this.dbPromise.then(db => { - value.storedAt = new Date().toString() + if (!db) { + return + } + return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') .objectStore('states') - .put(value, key) + .put({value: value, storedAt: new Date().toString()}, key) request.onsuccess = resolve request.onerror = reject @@ -33,12 +38,20 @@ class StateStore { load (key) { return this.dbPromise.then(db => { + if (!db) { + return null + } + return new Promise((resolve, reject) => { var request = db.transaction(['states']) .objectStore('states') .get(key) - request.onsuccess = (event) => resolve(event.target.result) + request.onsuccess = (event) => { + let result = event.target.result + resolve(result ? result.value : null) + } + request.onerror = (event) => reject(event) }) }) From 0f02663f6be31dae4f8f1871268e7bae53aad064 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:30:58 -0800 Subject: [PATCH 069/108] Add --user-data-dir flag, to control indexedDB directory This way, we can still use indexedDB in the integration tests Signed-off-by: Katrina Uychaco --- spec/integration/helpers/start-atom.coffee | 4 +++- spec/integration/startup-spec.coffee | 2 ++ src/browser/main.coffee | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index 3c1016ad2..af9ce094b 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -15,6 +15,8 @@ ChromedriverPort = 9515 ChromedriverURLBase = "/wd/hub" ChromedriverStatusURL = "http://localhost:#{ChromedriverPort}#{ChromedriverURLBase}/status" +userDataDir = temp.mkdirSync('atom-user-data-dir') + chromeDriverUp = (done) -> checkStatus = -> http @@ -48,7 +50,7 @@ buildAtomClient = (args, env) -> "atom-env=#{map(env, (value, key) -> "#{key}=#{value}").join(" ")}" "dev" "safe" - "user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}" + "user-data-dir=#{userDataDir}" "socket-path=#{SocketPath}" ]) diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee index 6e8a7f55a..f22e7ae2c 100644 --- a/spec/integration/startup-spec.coffee +++ b/spec/integration/startup-spec.coffee @@ -153,6 +153,8 @@ describe "Starting Atom", -> .waitForPaneItemCount(0, 3000) .execute -> atom.workspace.open() .waitForPaneItemCount(1, 3000) + .keys("Hello!") + .waitUntil((-> Promise.resolve(false)), 1100) runAtom [tempDirPath], {ATOM_HOME: atomHome}, (client) -> client diff --git a/src/browser/main.coffee b/src/browser/main.coffee index ca9d7e3ae..bbce1d87f 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -32,6 +32,9 @@ start = -> app.on 'open-url', addUrlToOpen app.on 'will-finish-launching', setupCrashReporter + if args.userDataDir? + app.setPath('userData', args.userDataDir) + app.on 'ready', -> app.removeListener 'open-file', addPathToOpen app.removeListener 'open-url', addUrlToOpen @@ -119,6 +122,7 @@ parseCommandLine = -> options.alias('v', 'version').boolean('v').describe('v', 'Print the version.') options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') + options.string('user-data-dir') args = options.argv @@ -140,6 +144,7 @@ parseCommandLine = -> pidToKillWhenClosed = args['pid'] if args['wait'] logFile = args['log-file'] socketPath = args['socket-path'] + userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') @@ -164,6 +169,6 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, - logFile, socketPath, profileStartup, timeout, setPortable} + logFile, socketPath, userDataDir, profileStartup, timeout, setPortable} start() From fa70560eba330e2b8f31add9d93d8f4a2173607a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:34:32 -0800 Subject: [PATCH 070/108] :shirt: Use single quotes in JS string Signed-off-by: Katrina Uychaco --- src/state-store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state-store.js b/src/state-store.js index 817d4282f..f5e687d4f 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -13,7 +13,7 @@ class StateStore { resolve(dbOpenRequest.result) } dbOpenRequest.onerror = (error) => { - console.error("Could not connect to indexedDB", error) + console.error('Could not connect to indexedDB', error) resolve(null) } }) From 7b808257a60103d1e1f78fec9d8a028731ecbdd9 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 11:04:30 -0800 Subject: [PATCH 071/108] Add test to check for indexedDB connection --- spec/atom-environment-spec.coffee | 7 +++++++ src/state-store.js | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 5afb5169b..7aaed602b 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -152,6 +152,8 @@ describe "AtomEnvironment", -> atom.enablePersistence = false it "selects the state based on the current project paths", -> + jasmine.useRealClock() + [dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")] loadSettings = _.extend atom.getLoadSettings(), @@ -163,6 +165,11 @@ describe "AtomEnvironment", -> spyOn(atom, 'deserialize') atom.project.setPaths([dir1, dir2]) + # State persistence will fail if other Atom instances are running + waitsForPromise -> + atom.stateStore.connect().then (isConnected) -> + expect(isConnected).toBe true + waitsForPromise -> atom.saveState().then -> atom.loadState() diff --git a/src/state-store.js b/src/state-store.js index f5e687d4f..feefbbb34 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -19,6 +19,10 @@ class StateStore { }) } + connect () { + return this.dbPromise.then(db => !!db) + } + save (key, value) { return this.dbPromise.then(db => { if (!db) { From 285c082ac0ecaeb2464040f8d1c9b25fc77e7e87 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 12:37:31 -0800 Subject: [PATCH 072/108] Use text-buffer 8.2.2-2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f883ee866..68f7c3bae 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.2.2-1", + "text-buffer": "8.2.2-2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From f6ced98be873739dd4233ab16192019324dc5c4e Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 11:43:41 -0800 Subject: [PATCH 073/108] Fix bug from merge with PR#10743 --- src/atom-environment.coffee | 20 +++++++++++--------- src/initialize-application-window.coffee | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2d7427ba0..f7869f9af 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -615,7 +615,7 @@ class AtomEnvironment extends Model # But after that, e.g., when the window's been reloaded, we want to use the # dimensions we've saved for it. if not @isFirstLoad() - dimensions = @state.windowDimensions + dimensions = @windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() @@ -648,18 +648,18 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - @loadState().then => - @document.body.appendChild(@views.getView(@workspace)) + + @document.body.appendChild(@views.getView(@workspace)) - @watchProjectPath() + @watchProjectPath() - @packages.activate() - @keymaps.loadUserKeymap() - @requireUserInitScript() unless @getLoadSettings().safeMode + @packages.activate() + @keymaps.loadUserKeymap() + @requireUserInitScript() unless @getLoadSettings().safeMode - @menu.update() + @menu.update() - @openInitialEmptyEditorIfNecessary() + @openInitialEmptyEditorIfNecessary() serialize: -> version: @constructor.version @@ -846,6 +846,8 @@ class AtomEnvironment extends Model @setFullScreen(state.fullScreen) + @windowDimensions = state.windowDimensions if state.windowDimensions + @packages.packageStates = state.packageStates ? {} startTime = Date.now() diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 0044a8d18..e4fa4af4d 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,9 +23,9 @@ module.exports = ({blobStore}) -> enablePersistence: true }) - atom.loadStateSync() - atom.displayWindow() - atom.startEditorWindow().then -> + atom.loadState().then -> + atom.displayWindow() + atom.startEditorWindow() # Workaround for focus getting cleared upon window creation windowFocused = -> From 8e33f8bf5b974a690cf291dcfad5a38b5cc12a57 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 11:50:44 -0800 Subject: [PATCH 074/108] Wait for tab to open in webdriverio `waitForPaneItemCount` command --- spec/integration/helpers/start-atom.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index af9ce094b..9df884286 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -85,7 +85,8 @@ buildAtomClient = (args, env) -> .addCommand "waitForPaneItemCount", (count, timeout, cb) -> @waitUntil(-> - @execute(-> atom.workspace?.getActivePane()?.getItems().length) + @waitForExist('.tab', 10000) + .execute(-> atom.workspace?.getActivePane()?.getItems().length) .then(({value}) -> value is count) , timeout) .then (result) -> From c2ff75f94bf1a0382ea46c01e8c39c7a1676cce9 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 13:57:20 -0800 Subject: [PATCH 075/108] Use `user-data-dir` with temp directory when running core tests This is to ensure successful database connection. Since core specs and package specs are run at the same time and both open an indexedDB connection, there were occasional core spec failures due to failed database connection. --- build/tasks/spec-task.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/tasks/spec-task.coffee b/build/tasks/spec-task.coffee index 892c92696..1d4be1e6f 100644 --- a/build/tasks/spec-task.coffee +++ b/build/tasks/spec-task.coffee @@ -1,5 +1,6 @@ fs = require 'fs' path = require 'path' +temp = require('temp').track() _ = require 'underscore-plus' async = require 'async' @@ -94,7 +95,7 @@ module.exports = (grunt) -> if process.platform in ['darwin', 'linux'] options = cmd: appPath - args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath] + args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath, "--user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}"] opts: env: _.extend({}, process.env, ATOM_INTEGRATION_TESTS_ENABLED: true From 5e7f2741b43cbaacb2e5a2be1ab7505bd4d63ab7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 14:50:30 -0800 Subject: [PATCH 076/108] In startup-spec check pane item count after editor has been loaded --- spec/integration/startup-spec.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee index f22e7ae2c..e82d34e57 100644 --- a/spec/integration/startup-spec.coffee +++ b/spec/integration/startup-spec.coffee @@ -28,13 +28,12 @@ describe "Starting Atom", -> it "opens the parent directory and creates an empty text editor", -> runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) -> client - .waitForPaneItemCount(1, 1000) - .treeViewRootDirectories() .then ({value}) -> expect(value).toEqual([tempDirPath]) .waitForExist("atom-text-editor", 5000) .then (exists) -> expect(exists).toBe true + .waitForPaneItemCount(1, 1000) .click("atom-text-editor") .keys("Hello!") .execute -> atom.workspace.getActiveTextEditor().getText() From 7cfe0b659e0e7bba6e452e99d6d5652050e37d8c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 14:50:51 -0800 Subject: [PATCH 077/108] Revert "Wait for tab to open in webdriverio `waitForPaneItemCount` command" This reverts commit 8e33f8bf5b974a690cf291dcfad5a38b5cc12a57. --- spec/integration/helpers/start-atom.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index 9df884286..af9ce094b 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -85,8 +85,7 @@ buildAtomClient = (args, env) -> .addCommand "waitForPaneItemCount", (count, timeout, cb) -> @waitUntil(-> - @waitForExist('.tab', 10000) - .execute(-> atom.workspace?.getActivePane()?.getItems().length) + @execute(-> atom.workspace?.getActivePane()?.getItems().length) .then(({value}) -> value is count) , timeout) .then (result) -> From 6f4936983e60afd1cb70b68c28a11ad08ac2364d Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 15:40:04 -0800 Subject: [PATCH 078/108] Revert test since `startEditorWindow` no longer returns a promise --- spec/atom-environment-spec.coffee | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 7aaed602b..561ecf3b5 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -263,11 +263,9 @@ describe "AtomEnvironment", -> } atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument}) spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn [] - waitsForPromise -> - atomEnvironment.startEditorWindow() - runs -> - atomEnvironment.unloadEditorWindow() - atomEnvironment.destroy() + atomEnvironment.startEditorWindow() + atomEnvironment.unloadEditorWindow() + atomEnvironment.destroy() describe "::openLocations(locations) (called via IPC from browser process)", -> beforeEach -> From 255b943d45344c13596e8b3420c142d29e1d14ba Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 19:56:25 -0800 Subject: [PATCH 079/108] Add ability to clear IndexedDB state object store --- spec/state-store-spec.js | 16 +++++++++++++++- src/state-store.js | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index 955ceb767..95fdcb71b 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -21,7 +21,21 @@ describe("StateStore", () => { return store.load('no-such-key').then((value) => { expect(value).toBeNull() }) - }); + }) + + it("can clear the state object store", () => { + const store = new StateStore(databaseName, version) + return store.save('key', {foo:'bar'}) + .then(() => store.count()) + .then((count) => + expect(count).toBe(1) + ) + .then(() => store.clear()) + .then(() => store.count()) + .then((count) => { + expect(count).toBe(0) + }) + }) describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { diff --git a/src/state-store.js b/src/state-store.js index feefbbb34..2175bbe4c 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -25,9 +25,7 @@ class StateStore { save (key, value) { return this.dbPromise.then(db => { - if (!db) { - return - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') @@ -42,9 +40,7 @@ class StateStore { load (key) { return this.dbPromise.then(db => { - if (!db) { - return null - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states']) @@ -60,4 +56,36 @@ class StateStore { }) }) } + + clear () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .clear() + + request.onsuccess = resolve + request.onerror = reject + }) + }) + } + + count () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states']) + .objectStore('states') + .count() + + request.onsuccess = () => { + resolve(request.result) + } + request.onerror = reject + }) + }) + } } From ace3ae8ed8e6da7d916b8cc726e29f3f597b3a16 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 12 Feb 2016 09:33:25 -0800 Subject: [PATCH 080/108] Remove unused Core Team Project Management labels Some Core Team labels aren't used anymore. To prevent misleading our users, we are removing these labels from the CONTRIBUTING document. --- CONTRIBUTING.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 466355903..b4519bcf1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -406,10 +406,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and | Label name | `atom/atom` :mag_right: | `atom`‑org :mag_right: | Description | | --- | --- | --- | --- | -| `in-progress` | [search][search-atom-repo-label-in-progress] | [search][search-atom-org-label-in-progress] | Tasks which the Atom core team is working on currently. | -| `on-deck` | [search][search-atom-repo-label-on-deck] | [search][search-atom-org-label-on-deck] | Tasks which the Atom core team plans to work on next. | -| `shipping` | [search][search-atom-repo-label-shipping] | [search][search-atom-org-label-shipping] | Tasks which the Atom core team completed and will be released in one of the next releases. | -| `post-1.0-roadmap` | [search][search-atom-repo-label-post-1.0-roadmap] | [search][search-atom-org-label-post-1.0-roadmap] | The Atom core team's roadmap post version 1.0.0. | | `atom` | [search][search-atom-repo-label-atom] | [search][search-atom-org-label-atom] | Topics discussed for prioritization at the next meeting of Atom core team members. | #### Pull Request Labels @@ -498,14 +494,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and [search-atom-org-label-deprecation-help]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Adeprecation-help [search-atom-repo-label-electron]: https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Fatom+is%3Aopen+label%3Aelectron [search-atom-org-label-electron]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aelectron -[search-atom-repo-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aon-deck -[search-atom-org-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aon-deck -[search-atom-repo-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ain-progress -[search-atom-org-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ain-progress -[search-atom-repo-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ashipping -[search-atom-org-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ashipping -[search-atom-repo-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Apost-1.0-roadmap -[search-atom-org-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Apost-1.0-roadmap [search-atom-repo-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aatom [search-atom-org-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aatom [search-atom-repo-label-work-in-progress]: https://github.com/pulls?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Awork-in-progress From 22c9fe7cb7e8fdc76a98096c0f3212ed21ab03aa Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 12 Feb 2016 14:06:06 -0800 Subject: [PATCH 081/108] :fire: trailing white space --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f7869f9af..248ee7e6a 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -648,7 +648,7 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - + @document.body.appendChild(@views.getView(@workspace)) @watchProjectPath() From 427dba57adc771032ff2c978a2d59cf3d8e8817a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 12 Feb 2016 14:07:21 -0800 Subject: [PATCH 082/108] Remove unused StorageFolder::store method (moved state to IndexedDB) --- src/storage-folder.coffee | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index ff3474198..06beae56a 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,11 +11,6 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') - store: (name, object) -> - return unless @path? - - fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') - load: (name) -> return unless @path? From 81c15bd8b41778fe6373bd34357667d4f3f4b53a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 14:19:03 -0800 Subject: [PATCH 083/108] Make --profile-startup flag work w/ async initializion --- static/index.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/static/index.js b/static/index.js index 87f7e04af..4e5494b18 100644 --- a/static/index.js +++ b/static/index.js @@ -85,7 +85,7 @@ var initialize = require(loadSettings.windowInitializationScript) - initialize({blobStore: blobStore}).then(function () { + return initialize({blobStore: blobStore}).then(function () { require('electron').ipcRenderer.send('window-command', 'window:loaded') }) } @@ -115,16 +115,12 @@ function profileStartup (loadSettings, initialTime) { function profile () { console.profile('startup') - try { - var startTime = Date.now() - setupWindow(loadSettings) + var startTime = Date.now() + setupWindow(loadSettings).then(function () { setLoadTime(Date.now() - startTime + initialTime) - } catch (error) { - handleSetupError(error) - } finally { console.profileEnd('startup') console.log('Switch to the Profiles tab to view the created startup profile') - } + }) } var currentWindow = require('electron').remote.getCurrentWindow() From 24dc4c6c738c5b5d49506461f38b501b702a99ac Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 19:56:50 -0800 Subject: [PATCH 084/108] Add command-line argument to clear state in IndexedDB --- src/browser/main.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index bbce1d87f..c1df3455f 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -123,6 +123,7 @@ parseCommandLine = -> options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') + options.boolean('clear-state').describe('clear-state', 'Delete all Atom environment state.') args = options.argv @@ -146,6 +147,7 @@ parseCommandLine = -> socketPath = args['socket-path'] userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] + clearState = args['clear-state'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') setPortable = args.portable @@ -169,6 +171,7 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, - logFile, socketPath, userDataDir, profileStartup, timeout, setPortable} + logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, + clearState} start() From f8ae09b1122ded5de3d4958630b485a2e1fd82a0 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 14 Feb 2016 15:10:07 -0800 Subject: [PATCH 085/108] Register Atom for file associations in Windows #6177 #4893 #6860 --- src/browser/squirrel-update.coffee | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 3660158fc..f9684ce49 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -20,6 +20,7 @@ else fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom' directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom' backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom' +applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' environmentKeyPath = 'HKCU\\Environment' # Spawn a command and invoke the callback when it completes with an error @@ -64,6 +65,10 @@ installContextMenu = (callback) -> args.push('/f') spawnReg(args, callback) + installFileHandler = (callback) -> + args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""] + addToRegistry(args, callback) + installMenu = (keyPath, arg, callback) -> args = [keyPath, '/ve', '/d', 'Open with Atom'] addToRegistry args, -> @@ -74,7 +79,8 @@ installContextMenu = (callback) -> installMenu fileKeyPath, '%1', -> installMenu directoryKeyPath, '%1', -> - installMenu(backgroundKeyPath, '%V', callback) + installMenu backgroundKeyPath, '%V', -> + installFileHandler(callback) isAscii = (text) -> index = 0 @@ -124,7 +130,8 @@ uninstallContextMenu = (callback) -> deleteFromRegistry fileKeyPath, -> deleteFromRegistry directoryKeyPath, -> - deleteFromRegistry(backgroundKeyPath, callback) + deleteFromRegistry backgroundKeyPath, -> + deleteFromRegistry(applicationsKeyPath, callback) # Add atom and apm to the PATH # From 47459948cff0f8da55197094b1d4fe941aabdceb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 15 Feb 2016 21:28:25 -0800 Subject: [PATCH 086/108] =?UTF-8?q?Clear=20state=20in=20indexedDB=20if=20?= =?UTF-8?q?=E2=80=98clear-state=E2=80=99=20command-line=20flag=20is=20pass?= =?UTF-8?q?ed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 6 ++++-- src/browser/atom-application.coffee | 17 +++++++++-------- src/browser/atom-window.coffee | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f7869f9af..cdb22b40d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -122,13 +122,15 @@ class AtomEnvironment extends Model {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params @loadTime = null - {devMode, safeMode, resourcePath} = @getLoadSettings() + {devMode, safeMode, resourcePath, clearState} = @getLoadSettings() @emitter = new Emitter @disposables = new CompositeDisposable @stateStore = new StateStore('AtomEnvironments', 1) + @stateStore.clear() if clearState + @deserializers = new DeserializerManager(this) @deserializeTimings = {} @@ -648,7 +650,7 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - + @document.body.appendChild(@views.getView(@workspace)) @watchProjectPath() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 5ff24c458..891caf19d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication exit: (status) -> app.exit(status) constructor: (options) -> - {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout} = options + {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearState} = options @socketPath = null if options.test @@ -89,16 +89,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearState}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -387,8 +387,8 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window}) + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState}) # Public: Opens multiple paths, in existing windows if possible. # @@ -400,9 +400,10 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window}={}) -> + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearState}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) + clearState = Boolean(clearState) locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) @@ -435,7 +436,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup}) + openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 20ba2ad5c..35ccabb8a 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -50,6 +50,7 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.firstLoad = true + loadSettings.clearState ?= false # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec From 702af8cd1635a016c1a374d621013c32f96bc292 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 15 Feb 2016 21:46:25 -0800 Subject: [PATCH 087/108] Use pre-released text-buffer version 8.3.1-0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ccae78a3..38956f362 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.0-0", + "text-buffer": "8.3.1-0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 63270f417432f12ffeacf93f42c77308ea8e6211 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 16 Feb 2016 14:35:12 +0100 Subject: [PATCH 088/108] Add TextEditor.prototype.cursorsForScreenRowRange So that `TextEditorPresenter` can avoid to scan through all the cursors to understand whether they're visible on screen. This dramatically reduces the calls to `getScreenRange` and, thus, makes `updateCursorsState` faster for multi-cursor edits. --- src/text-editor-presenter.coffee | 16 ++++++---------- src/text-editor.coffee | 10 ++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index b13bf9036..a36c860ed 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -432,18 +432,14 @@ class TextEditorPresenter return updateCursorsState: -> - @state.content.cursors = {} - @updateCursorState(cursor) for cursor in @model.cursors # using property directly to avoid allocation - return - - updateCursorState: (cursor) -> return unless @startRow? and @endRow? and @hasPixelRectRequirements() and @baseCharacterWidth? - screenRange = cursor.getScreenRange() - return unless cursor.isVisible() and @startRow <= screenRange.start.row < @endRow - pixelRect = @pixelRectForScreenRange(screenRange) - pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 - @state.content.cursors[cursor.id] = pixelRect + @state.content.cursors = {} + for cursor in @model.cursorsForScreenRowRange(@startRow, @endRow - 1) when cursor.isVisible() + pixelRect = @pixelRectForScreenRange(cursor.getScreenRange()) + pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 + @state.content.cursors[cursor.id] = pixelRect + return updateOverlaysState: -> return unless @hasOverlayPositionRequirements() diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 2ba45a3ba..55f6d84ad 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -109,6 +109,7 @@ class TextEditor extends Model @emitter = new Emitter @disposables = new CompositeDisposable @cursors = [] + @cursorsByMarkerId = new Map @selections = [] buffer ?= new TextBuffer @@ -1944,10 +1945,18 @@ class TextEditor extends Model getCursorsOrderedByBufferPosition: -> @getCursors().sort (a, b) -> a.compare(b) + cursorsForScreenRowRange: (startScreenRow, endScreenRow) -> + cursors = [] + for marker in @selectionsMarkerLayer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow]) + if cursor = @cursorsByMarkerId.get(marker.id) + cursors.push(cursor) + cursors + # Add a cursor based on the given {TextEditorMarker}. addCursor: (marker) -> cursor = new Cursor(editor: this, marker: marker, config: @config) @cursors.push(cursor) + @cursorsByMarkerId.set(marker.id, cursor) @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true) @decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true) @@ -2446,6 +2455,7 @@ class TextEditor extends Model removeSelection: (selection) -> _.remove(@cursors, selection.cursor) _.remove(@selections, selection) + @cursorsByMarkerId.delete(selection.cursor.marker.id) @emitter.emit 'did-remove-cursor', selection.cursor @emitter.emit 'did-remove-selection', selection From 083f577889a232909dc2117aa18c3efe1dc674fc Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 10:28:30 -0800 Subject: [PATCH 089/108] =?UTF-8?q?Use=20more=20descriptive=20flag=20for?= =?UTF-8?q?=20clearing=20state=20-=20=E2=80=98clear-window-state=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 4 ++-- src/browser/atom-application.coffee | 18 +++++++++--------- src/browser/atom-window.coffee | 2 +- src/browser/main.coffee | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cdb22b40d..ed36f5da2 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -122,14 +122,14 @@ class AtomEnvironment extends Model {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params @loadTime = null - {devMode, safeMode, resourcePath, clearState} = @getLoadSettings() + {devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings() @emitter = new Emitter @disposables = new CompositeDisposable @stateStore = new StateStore('AtomEnvironments', 1) - @stateStore.clear() if clearState + @stateStore.clear() if clearWindowState @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 891caf19d..e889840e5 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication exit: (status) -> app.exit(status) constructor: (options) -> - {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearState} = options + {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearWindowState} = options @socketPath = null if options.test @@ -89,16 +89,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearState}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -387,8 +387,8 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState}) + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState}) # Public: Opens multiple paths, in existing windows if possible. # @@ -400,10 +400,10 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearState}={}) -> + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) - clearState = Boolean(clearState) + clearWindowState = Boolean(clearWindowState) locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) @@ -436,7 +436,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearState}) + openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 35ccabb8a..0c0f8f919 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -50,7 +50,7 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.firstLoad = true - loadSettings.clearState ?= false + loadSettings.clearWindowState ?= false # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec diff --git a/src/browser/main.coffee b/src/browser/main.coffee index c1df3455f..c0613fb09 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -123,7 +123,7 @@ parseCommandLine = -> options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') - options.boolean('clear-state').describe('clear-state', 'Delete all Atom environment state.') + options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.') args = options.argv @@ -147,7 +147,7 @@ parseCommandLine = -> socketPath = args['socket-path'] userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] - clearState = args['clear-state'] + clearWindowState = args['clear-window-state'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') setPortable = args.portable @@ -172,6 +172,6 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, - clearState} + clearWindowState} start() From c691dd05c57322cffd25f58bb4fec57fb9e3b31c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 11:57:35 -0800 Subject: [PATCH 090/108] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38956f362..3977cb806 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.1-0", + "text-buffer": "8.3.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From ae26e6c8ca284bb2858c65074c8d1d64564d1593 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 14:16:28 -0800 Subject: [PATCH 091/108] Add core setting for pending tabs configuration --- src/config-schema.coffee | 4 ++++ src/workspace.coffee | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 15e5223b8..36c5fc5ba 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -108,6 +108,10 @@ module.exports = description: 'Automatically update Atom when a new release is available.' type: 'boolean' default: true + openPendingPaneItems: + description: 'Open pane items in pending state, such that only one pending item is open per pane.' + type: 'boolean' + default: true editor: type: 'object' diff --git a/src/workspace.coffee b/src/workspace.coffee index 79cfb3e8e..4ed620481 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -414,6 +414,9 @@ class Workspace extends Model split = options.split uri = @project.resolvePath(uri) + if not atom.config.get('core.openPendingPaneItems') + options.pending = false + # Avoid adding URLs as recent documents to work-around this Spotlight crash: # https://github.com/atom/atom/issues/10071 if uri? and not url.parse(uri).protocol? From c9150c3f73493760200511721ea6c4814bdb1314 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 15:24:18 -0800 Subject: [PATCH 092/108] Add test for core.openPendingPaneItems setting --- spec/workspace-spec.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e89e4c6bd..bb4ac1532 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1532,3 +1532,14 @@ describe "Workspace", -> atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.close).toHaveBeenCalled() + + describe "when the core.openPendingPaneItems option is falsey", -> + it "does not open item with `pending: true` option as pending", -> + editor = null + atom.config.set('core.openPendingPaneItems', false) + + waitsForPromise -> + atom.workspace.open('sample.js', pending: true).then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBeFalsy() From 8d27d1925c3ce53fc4edfcecd1ab6ad06dd6c70a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 12:46:49 -0800 Subject: [PATCH 093/108] Avoid emitting config events while loading packages --- src/package-manager.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 705755af0..33f8f86a3 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -357,7 +357,9 @@ class PackageManager packagePaths = @getAvailablePackagePaths() packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath)) packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath) - @loadPackage(packagePath) for packagePath in packagePaths + @config.transact => + @loadPackage(packagePath) for packagePath in packagePaths + return @emitter.emit 'did-load-initial-packages' loadPackage: (nameOrPath) -> From 59b34fdf2ea022bb32de4a7e8f7ad2885edc5c03 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 17 Feb 2016 00:02:39 -0800 Subject: [PATCH 094/108] Update grunt-electron-installer to latest version --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 6c41d4355..2f8d88d8a 100644 --- a/build/package.json +++ b/build/package.json @@ -25,7 +25,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.16.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.6", + "grunt-electron-installer": "1.2.2", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From f5e5b830df2bdd93381a45cd0f63518afb6d7adb Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 17 Feb 2016 00:08:08 -0800 Subject: [PATCH 095/108] Avoid 260-character path limits on Windows in script\clean --- script/clean | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/script/clean b/script/clean index fd0aa5bfa..0c947baf2 100755 --- a/script/clean +++ b/script/clean @@ -4,15 +4,16 @@ var fs = require('fs'); var path = require('path'); var os = require('os'); -var removeCommand = process.platform === 'win32' ? 'rmdir /S /Q ' : 'rm -rf '; +var isWindows = process.platform === 'win32'; +var removeCommand = isWindows ? 'rmdir /S /Q ' : 'rm -rf '; var productName = require('../package.json').productName; process.chdir(path.dirname(__dirname)); -var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; +var home = process.env[isWindows ? 'USERPROFILE' : 'HOME']; var tmpdir = os.tmpdir(); // Windows: Use START as a way to ignore error if Atom.exe isnt running -var killatom = process.platform === 'win32' ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; +var killatom = isWindows ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; var commands = [ killatom, @@ -39,12 +40,32 @@ var run = function() { if (Array.isArray(next)) { var pathToRemove = path.resolve.apply(path.resolve, next); - if (fs.existsSync(pathToRemove)) - next = removeCommand + pathToRemove; - else + if (fs.existsSync(pathToRemove)) { + if (isWindows) { + removeFolderRecursive(pathToRemove); + } else { + next = removeCommand + pathToRemove; + cp.safeExec(next, run); + } + } + else { return run(); + } } - - cp.safeExec(next, run); + else + cp.safeExec(next, run); }; run(); + +// Windows has a 260-char path limit for rmdir etc. Just recursively delete in Node. +var removeFolderRecursive = function(folderPath) { + fs.readdirSync(folderPath).forEach(function(entry, index) { + var entryPath = path.join(folderPath, entry); + if (fs.lstatSync(entryPath).isDirectory()) { + removeFolderRecursive(entryPath); + } else { + fs.unlinkSync(entryPath); + } + }); + fs.rmdirSync(folderPath); +}; From 0afa9bb21ccc3cae1f8f3ed6e4e6a250ef6e65be Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:02:48 +0100 Subject: [PATCH 096/108] Don't update foldable status, ever --- spec/tokenized-buffer-spec.coffee | 81 ------------------------------- src/tokenized-buffer.coffee | 1 + 2 files changed, 1 insertion(+), 81 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 72b292cc2..14843ddb8 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,87 +903,6 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe ".foldable on tokenized lines", -> - changes = null - - beforeEach -> - changes = [] - buffer = atom.project.bufferForPathSync('sample.js') - buffer.insert [10, 0], " // multi-line\n // comment\n // block\n" - buffer.insert [0, 0], "// multi-line\n// comment\n// block\n" - tokenizedBuffer = new TokenizedBuffer({ - buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert - }) - fullyTokenize(tokenizedBuffer) - tokenizedBuffer.onDidChange (change) -> - delete change.bufferChange - changes.push(change) - - it "sets .foldable to true on the first line of multi-line comments", -> - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false - - buffer.insert([0, Infinity], '\n') - expect(changes).toEqual [{start: 0, end: 1, delta: 1}] - - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false - - changes = [] - buffer.undo() - expect(changes).toEqual [{start: 0, end: 2, delta: -1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - - it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> - buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([7, 0], ' ') - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.undo() - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([7, 0], " \n x\n") - expect(changes).toEqual [{start: 6, end: 7, delta: 2}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([9, 0], " ") - expect(changes).toEqual [{start: 9, end: 9, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> spyOn(atom.grammars.nullGrammar, 'tokenizeLine').andCallThrough() diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 0fdf4eea8..5a95d9f15 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -288,6 +288,7 @@ class TokenizedBuffer extends Model row - increment updateFoldableStatus: (startRow, endRow) -> + return [startRow, endRow] return [startRow, endRow] if @largeFileMode scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow From 012fa354c41a495983588f7148c5413c28209e96 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:28:38 +0100 Subject: [PATCH 097/108] Add TokenizedBuffer.prototype.foldableRowsForRowRange --- src/display-buffer.coffee | 3 +++ src/text-editor-presenter.coffee | 3 ++- src/text-editor.coffee | 5 ++++- src/tokenized-buffer.coffee | 24 +++++------------------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 8b95656f9..8015f2df2 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -413,6 +413,9 @@ class DisplayBuffer extends Model isFoldedAtScreenRow: (screenRow) -> @largestFoldContainingBufferRow(@bufferRowForScreenRow(screenRow))? + foldableBufferRowsForBufferRowRange: (startRow, endRow) -> + @tokenizedBuffer.foldableRowsForRowRange(startRow, endRow) + # Destroys the fold with the given id destroyFoldWithId: (id) -> @foldsByMarkerId[id]?.destroy() diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index a36c860ed..147eaa962 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -599,6 +599,7 @@ class TextEditorPresenter if endRow > startRow bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1) + foldableBufferRows = @model.foldableBufferRowsForBufferRowRange(bufferRows[0], bufferRows[bufferRows.length - 1]) for bufferRow, i in bufferRows if bufferRow is lastBufferRow softWrapped = true @@ -609,7 +610,7 @@ class TextEditorPresenter screenRow = startRow + i line = @model.tokenizedLineForScreenRow(screenRow) decorationClasses = @lineNumberDecorationClassesForRow(screenRow) - foldable = @model.isFoldableAtScreenRow(screenRow) + foldable = foldableBufferRows.has(bufferRow) blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight if screenRow % @tileSize isnt 0 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 55f6d84ad..6c80cfc01 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2940,7 +2940,7 @@ class TextEditor extends Model # Returns a {Boolean}. isFoldableAtBufferRow: (bufferRow) -> # @languageMode.isFoldableAtBufferRow(bufferRow) - @displayBuffer.tokenizedBuffer.tokenizedLineForRow(bufferRow)?.foldable ? false + @foldableBufferRowsForBufferRowRange(bufferRow, bufferRow).has(bufferRow) # Extended: Determine whether the given row in screen coordinates is foldable. # @@ -2953,6 +2953,9 @@ class TextEditor extends Model bufferRow = @displayBuffer.bufferRowForScreenRow(screenRow) @isFoldableAtBufferRow(bufferRow) + foldableBufferRowsForBufferRowRange: (startRow, endRow) -> + @displayBuffer.foldableBufferRowsForBufferRowRange(startRow, endRow) + # Extended: Fold the given buffer row if it isn't currently folded, and unfold # it otherwise. toggleFoldAtBufferRow: (bufferRow) -> diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 5a95d9f15..055e3fe47 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -210,8 +210,6 @@ class TokenizedBuffer extends Model @validateRow(endRow) @invalidateRow(endRow + 1) unless filledRegion - [startRow, endRow] = @updateFoldableStatus(startRow, endRow) - event = {start: startRow, end: endRow, delta: 0} @emitter.emit 'did-change', event @@ -271,9 +269,6 @@ class TokenizedBuffer extends Model if newEndStack and not _.isEqual(newEndStack, previousEndStack) @invalidateRow(end + delta + 1) - [start, end] = @updateFoldableStatus(start, end + delta) - end -= delta - event = {start, end, delta, bufferChange: e} @emitter.emit 'did-change', event @@ -287,23 +282,14 @@ class TokenizedBuffer extends Model row - increment - updateFoldableStatus: (startRow, endRow) -> - return [startRow, endRow] - return [startRow, endRow] if @largeFileMode - + foldableRowsForRowRange: (startRow, endRow) -> scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow scanStartRow-- while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment() scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow - - for row in [scanStartRow..scanEndRow] by 1 - foldable = @isFoldableAtRow(row) - line = @tokenizedLineForRow(row) - unless line.foldable is foldable - line.foldable = foldable - startRow = Math.min(startRow, row) - endRow = Math.max(endRow, row) - - [startRow, endRow] + foldableRows = new Set + for row in [scanStartRow..scanEndRow] by 1 when @isFoldableAtRow(row) + foldableRows.add(row) + foldableRows isFoldableAtRow: (row) -> if @largeFileMode From d05dfa6efe2131f468cca75dd407f0a992dceb4e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:29:38 +0100 Subject: [PATCH 098/108] :racehorse: Update lines state only in pre-measurement phase --- src/text-editor-presenter.coffee | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 147eaa962..48f269b9d 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -90,7 +90,7 @@ class TextEditorPresenter @updateLineDecorations() @updateBlockDecorations() - @updateTilesState() + @updateTilesState(true) @updating = false @state @@ -112,7 +112,7 @@ class TextEditorPresenter @updateHiddenInputState() @updateContentState() @updateHighlightDecorations() if @shouldUpdateDecorations - @updateTilesState() + @updateTilesState(false) @updateCursorsState() @updateOverlaysState() @updateLineNumberGutterState() @@ -327,7 +327,7 @@ class TextEditorPresenter clearScreenRowsToMeasure: -> @screenRowsToMeasure = [] - updateTilesState: -> + updateTilesState: (updateLinesState) -> return unless @startRow? and @endRow? and @lineHeight? screenRows = @getScreenRows() @@ -367,8 +367,9 @@ class TextEditorPresenter gutterTile.display = "block" gutterTile.zIndex = zIndex - @updateLinesState(tile, rowsWithinTile) - @updateLineNumbersState(gutterTile, rowsWithinTile) + if updateLinesState + @updateLinesState(tile, rowsWithinTile) + @updateLineNumbersState(gutterTile, rowsWithinTile) visibleTiles[tileStartRow] = true zIndex++ From 2c71a448b3b1397dcd3e451484750c037909e5b2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 11:04:19 +0100 Subject: [PATCH 099/108] Put foldable specs back --- spec/tokenized-buffer-spec.coffee | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 14843ddb8..72b292cc2 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,6 +903,87 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } + describe ".foldable on tokenized lines", -> + changes = null + + beforeEach -> + changes = [] + buffer = atom.project.bufferForPathSync('sample.js') + buffer.insert [10, 0], " // multi-line\n // comment\n // block\n" + buffer.insert [0, 0], "// multi-line\n// comment\n// block\n" + tokenizedBuffer = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + fullyTokenize(tokenizedBuffer) + tokenizedBuffer.onDidChange (change) -> + delete change.bufferChange + changes.push(change) + + it "sets .foldable to true on the first line of multi-line comments", -> + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent + expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false + + buffer.insert([0, Infinity], '\n') + expect(changes).toEqual [{start: 0, end: 1, delta: 1}] + + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false + + changes = [] + buffer.undo() + expect(changes).toEqual [{start: 0, end: 2, delta: -1}] + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent + + it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> + buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([7, 0], ' ') + expect(changes).toEqual [{start: 6, end: 7, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.undo() + expect(changes).toEqual [{start: 6, end: 7, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([7, 0], " \n x\n") + expect(changes).toEqual [{start: 6, end: 7, delta: 2}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([9, 0], " ") + expect(changes).toEqual [{start: 9, end: 9, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> spyOn(atom.grammars.nullGrammar, 'tokenizeLine').andCallThrough() From a613fa5133b4671c77aa08d2d5ce92785d0137db Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 11:17:24 +0100 Subject: [PATCH 100/108] Adapt specs to use the new API --- spec/tokenized-buffer-spec.coffee | 106 +++++++++++++++--------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 72b292cc2..0f5c9c52d 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,7 +903,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe ".foldable on tokenized lines", -> + describe "::foldableRowsForRowRange(startRow, endRow)", -> changes = null beforeEach -> @@ -915,74 +915,74 @@ describe "TokenizedBuffer", -> buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert }) fullyTokenize(tokenizedBuffer) - tokenizedBuffer.onDidChange (change) -> - delete change.bufferChange - changes.push(change) - it "sets .foldable to true on the first line of multi-line comments", -> - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false + it "includes the first line of multi-line comments", -> + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 16) + expect(foldableRows.has(0)).toBe true + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true # because of indent + expect(foldableRows.has(13)).toBe true + expect(foldableRows.has(14)).toBe false + expect(foldableRows.has(15)).toBe false + expect(foldableRows.has(16)).toBe false buffer.insert([0, Infinity], '\n') - expect(changes).toEqual [{start: 0, end: 1, delta: 1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) + expect(foldableRows.has(0)).toBe false + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe true + expect(foldableRows.has(3)).toBe false - changes = [] buffer.undo() - expect(changes).toEqual [{start: 0, end: 2, delta: -1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) + expect(foldableRows.has(0)).toBe true + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true # because of indent + + it "includes non-comment lines that precede an increase in indentation", -> buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 8) + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true + expect(foldableRows.has(4)).toBe true + expect(foldableRows.has(5)).toBe false + expect(foldableRows.has(6)).toBe false + expect(foldableRows.has(7)).toBe true + expect(foldableRows.has(8)).toBe false + buffer.insert([7, 0], ' ') - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false + buffer.undo() - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe false + expect(foldableRows.has(7)).toBe true + expect(foldableRows.has(8)).toBe false + buffer.insert([7, 0], " \n x\n") - expect(changes).toEqual [{start: 6, end: 7, delta: 2}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false + buffer.insert([9, 0], " ") - expect(changes).toEqual [{start: 9, end: 9, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> From 90c75fd6da268a1636278ce935285b5f298c66b7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 14:35:22 +0100 Subject: [PATCH 101/108] Delete specs testing previous behavior When emitting the `did-change` event, `updateFoldableStatus` used to extend the change region up and down to include all the lines that changed their foldability status because of a buffer change. I assume this was supposed to invalidate folds that *contained* the change whenever a line was edited in a way that affected also the previous or subsequent ones. That information, however, is not being used by `DisplayBuffer`, which does not alter existing folded regions when they become invalid. I believe the correct behavior should be to unfold the invalid region and recompute those screen lines. Nonetheless, it seems reasonable to me to keep the original (wrong) behavior and not address it in this branch, because it strays from the original intent of this refactoring. We should probably fix it once for all in another PR or when integrating/implementing `DisplayLayer`. --- spec/tokenized-buffer-spec.coffee | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 0f5c9c52d..ca64d2edb 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -202,8 +202,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.firstInvalidRow()).toBe 3 advanceClock() - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 7, delta: 0) + expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 7, delta: 0) expect(tokenizedBuffer.firstInvalidRow()).toBe 8 describe "when there is a buffer change surrounding an invalid row", -> @@ -253,7 +252,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 2, delta: 0) + expect(event).toEqual(start: 2, end: 2, delta: 0) changeHandler.reset() advanceClock() @@ -263,8 +262,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(event).toEqual(start: 2, end: 5, delta: 0) + expect(event).toEqual(start: 3, end: 5, delta: 0) it "resumes highlighting with the state of the previous line", -> buffer.insert([0, 0], '/*') @@ -292,7 +290,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 0, end: 3, delta: -2) # starts at 0 because foldable on row 0 becomes false + expect(event).toEqual(start: 1, end: 3, delta: -2) describe "when the change invalidates the tokenization of subsequent lines", -> it "schedules the invalidated lines to be tokenized in the background", -> @@ -305,7 +303,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 3, delta: -1) + expect(event).toEqual(start: 2, end: 3, delta: -1) changeHandler.reset() advanceClock() @@ -314,8 +312,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(event).toEqual(start: 2, end: 4, delta: 0) + expect(event).toEqual(start: 3, end: 4, delta: 0) describe "when lines are both updated and inserted", -> it "updates tokens to reflect the change", -> @@ -339,7 +336,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 0, end: 2, delta: 2) # starts at 0 because .foldable becomes false on row 0 + expect(event).toEqual(start: 1, end: 2, delta: 2) describe "when the change invalidates the tokenization of subsequent lines", -> it "schedules the invalidated lines to be tokenized in the background", -> @@ -350,7 +347,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 2, delta: 2) + expect(event).toEqual(start: 2, end: 2, delta: 2) expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js'] expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js'] expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js'] @@ -894,7 +891,7 @@ describe "TokenizedBuffer", -> buffer.setTextInRange([[7, 0], [8, 65]], ' ok') delete changeHandler.argsForCall[0][0].bufferChange - expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 10, delta: -1) # starts at row 4 because it became foldable + expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 10, delta: -1) expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 2 From bea324eae92017e04f8ad0006a0d0da09f8f323e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 15:05:31 +0100 Subject: [PATCH 102/108] :fire: Use just `isFoldableAtBufferRow` --- spec/language-mode-spec.coffee | 11 ----- spec/tokenized-buffer-spec.coffee | 82 ++++++++++++++----------------- src/display-buffer.coffee | 4 +- src/text-editor-presenter.coffee | 9 +++- src/text-editor.coffee | 6 +-- src/tokenized-buffer.coffee | 9 ---- src/tokenized-line.coffee | 1 - 7 files changed, 47 insertions(+), 75 deletions(-) diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index 7ea4a1ae9..cd32e29c7 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -463,17 +463,6 @@ describe "LanguageMode", -> fold2 = editor.tokenizedLineForScreenRow(5).fold expect(fold2).toBeFalsy() - describe ".isFoldableAtBufferRow(bufferRow)", -> - it "returns true if the line starts a multi-line comment", -> - expect(languageMode.isFoldableAtBufferRow(1)).toBe true - expect(languageMode.isFoldableAtBufferRow(6)).toBe true - expect(languageMode.isFoldableAtBufferRow(17)).toBe false - - it "does not return true for a line in the middle of a comment that's followed by an indented line", -> - expect(languageMode.isFoldableAtBufferRow(7)).toBe false - editor.buffer.insert([8, 0], ' ') - expect(languageMode.isFoldableAtBufferRow(7)).toBe false - describe "css", -> beforeEach -> waitsForPromise -> diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index ca64d2edb..88c095f68 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -900,7 +900,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe "::foldableRowsForRowRange(startRow, endRow)", -> + describe "::isFoldableAtRow(row)", -> changes = null beforeEach -> @@ -914,72 +914,64 @@ describe "TokenizedBuffer", -> fullyTokenize(tokenizedBuffer) it "includes the first line of multi-line comments", -> - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 16) - expect(foldableRows.has(0)).toBe true - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true # because of indent - expect(foldableRows.has(13)).toBe true - expect(foldableRows.has(14)).toBe false - expect(foldableRows.has(15)).toBe false - expect(foldableRows.has(16)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent + expect(tokenizedBuffer.isFoldableAtRow(13)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(14)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(15)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(16)).toBe false buffer.insert([0, Infinity], '\n') - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) - expect(foldableRows.has(0)).toBe false - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe true - expect(foldableRows.has(3)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe false buffer.undo() - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) - expect(foldableRows.has(0)).toBe true - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true # because of indent + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent it "includes non-comment lines that precede an increase in indentation", -> buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 8) - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true - expect(foldableRows.has(4)).toBe true - expect(foldableRows.has(5)).toBe false - expect(foldableRows.has(6)).toBe false - expect(foldableRows.has(7)).toBe true - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(4)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(5)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([7, 0], ' ') - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.undo() - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe false - expect(foldableRows.has(7)).toBe true - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([7, 0], " \n x\n") - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([9, 0], " ") - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 8015f2df2..d01ad03c9 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -413,8 +413,8 @@ class DisplayBuffer extends Model isFoldedAtScreenRow: (screenRow) -> @largestFoldContainingBufferRow(@bufferRowForScreenRow(screenRow))? - foldableBufferRowsForBufferRowRange: (startRow, endRow) -> - @tokenizedBuffer.foldableRowsForRowRange(startRow, endRow) + isFoldableAtBufferRow: (row) -> + @tokenizedBuffer.isFoldableAtRow(row) # Destroys the fold with the given id destroyFoldWithId: (id) -> diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 48f269b9d..3266eea70 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -600,8 +600,14 @@ class TextEditorPresenter if endRow > startRow bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1) - foldableBufferRows = @model.foldableBufferRowsForBufferRowRange(bufferRows[0], bufferRows[bufferRows.length - 1]) + previousBufferRow = -1 + foldable = false for bufferRow, i in bufferRows + # don't compute foldability more than once per buffer row + if previousBufferRow isnt bufferRow + foldable = @model.isFoldableAtBufferRow(bufferRow) + previousBufferRow = bufferRow + if bufferRow is lastBufferRow softWrapped = true else @@ -611,7 +617,6 @@ class TextEditorPresenter screenRow = startRow + i line = @model.tokenizedLineForScreenRow(screenRow) decorationClasses = @lineNumberDecorationClassesForRow(screenRow) - foldable = foldableBufferRows.has(bufferRow) blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight if screenRow % @tileSize isnt 0 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 6c80cfc01..c0a6f2057 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2939,8 +2939,7 @@ class TextEditor extends Model # # Returns a {Boolean}. isFoldableAtBufferRow: (bufferRow) -> - # @languageMode.isFoldableAtBufferRow(bufferRow) - @foldableBufferRowsForBufferRowRange(bufferRow, bufferRow).has(bufferRow) + @displayBuffer.isFoldableAtBufferRow(bufferRow) # Extended: Determine whether the given row in screen coordinates is foldable. # @@ -2953,9 +2952,6 @@ class TextEditor extends Model bufferRow = @displayBuffer.bufferRowForScreenRow(screenRow) @isFoldableAtBufferRow(bufferRow) - foldableBufferRowsForBufferRowRange: (startRow, endRow) -> - @displayBuffer.foldableBufferRowsForBufferRowRange(startRow, endRow) - # Extended: Fold the given buffer row if it isn't currently folded, and unfold # it otherwise. toggleFoldAtBufferRow: (bufferRow) -> diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 055e3fe47..5c62f9ecd 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -282,15 +282,6 @@ class TokenizedBuffer extends Model row - increment - foldableRowsForRowRange: (startRow, endRow) -> - scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow - scanStartRow-- while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment() - scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow - foldableRows = new Set - for row in [scanStartRow..scanEndRow] by 1 when @isFoldableAtRow(row) - foldableRows.add(row) - foldableRows - isFoldableAtRow: (row) -> if @largeFileMode false diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index c97a621ac..372f488a6 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -33,7 +33,6 @@ class TokenizedLine endOfLineInvisibles: null lineIsWhitespaceOnly: false firstNonWhitespaceIndex: 0 - foldable: false constructor: (properties) -> @id = idCounter++ From 2a35d19dd35bd3b0d16a6da193a35f954b68d5fa Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 16:00:35 +0100 Subject: [PATCH 103/108] :racehorse: Memoize TokenizedLine.prototype.isComment --- src/tokenized-line.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index 372f488a6..bf6a6dd2b 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -491,15 +491,20 @@ class TokenizedLine @endOfLineInvisibles.push(eol) if eol isComment: -> + return @isCommentLine if @isCommentLine? + + @isCommentLine = false iterator = @getTokenIterator() while iterator.next() scopes = iterator.getScopes() continue if scopes.length is 1 continue unless NonWhitespaceRegex.test(iterator.getText()) for scope in scopes - return true if CommentScopeRegex.test(scope) + if CommentScopeRegex.test(scope) + @isCommentLine = true + break break - false + @isCommentLine isOnlyWhitespace: -> @lineIsWhitespaceOnly From 6a32a874e9a8048db139a8f86389df053eb3d888 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 16:09:10 +0100 Subject: [PATCH 104/108] :racehorse: Compare markers instead of ranges in Selection This largely reduces the overhead of converting ranges and points from native to javascript objects. --- src/selection.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/selection.coffee b/src/selection.coffee index 2ba66ebb0..465d76a4c 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -755,7 +755,7 @@ class Selection extends Model # # * `otherSelection` A {Selection} to compare against compare: (otherSelection) -> - @getBufferRange().compare(otherSelection.getBufferRange()) + @marker.compare(otherSelection.marker) ### Section: Private Utilities From 68bf2f8dc7c3d69439aaac1cc4ac8f0ae27e7133 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 17:20:54 +0100 Subject: [PATCH 105/108] :green_heart: Fix unrelated failing spec --- spec/text-editor-component-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 08da07dd8..8aaccbd6c 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -544,7 +544,7 @@ describe('TextEditorComponent', function () { editor.setSoftWrapped(true) await nextViewUpdatePromise() - componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 17 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() await nextViewUpdatePromise() }) From b8677c13df3257e90ebff14cbbd3d07a70aa945a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 17 Feb 2016 11:56:50 -0800 Subject: [PATCH 106/108] Rename config to `allowPendingPaneItems` and improve description --- spec/workspace-spec.coffee | 4 ++-- src/config-schema.coffee | 4 ++-- src/workspace.coffee | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index bb4ac1532..534f2bf61 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1533,10 +1533,10 @@ describe "Workspace", -> atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.close).toHaveBeenCalled() - describe "when the core.openPendingPaneItems option is falsey", -> + describe "when the core.allowPendingPaneItems option is falsey", -> it "does not open item with `pending: true` option as pending", -> editor = null - atom.config.set('core.openPendingPaneItems', false) + atom.config.set('core.allowPendingPaneItems', false) waitsForPromise -> atom.workspace.open('sample.js', pending: true).then (o) -> editor = o diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 36c5fc5ba..346551ff5 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -108,8 +108,8 @@ module.exports = description: 'Automatically update Atom when a new release is available.' type: 'boolean' default: true - openPendingPaneItems: - description: 'Open pane items in pending state, such that only one pending item is open per pane.' + allowPendingPaneItems: + description: 'Allow items to be previewed without adding them to a pane permanently, such as when single clicking files in the tree view.' type: 'boolean' default: true diff --git a/src/workspace.coffee b/src/workspace.coffee index 4ed620481..b26383786 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -414,7 +414,7 @@ class Workspace extends Model split = options.split uri = @project.resolvePath(uri) - if not atom.config.get('core.openPendingPaneItems') + if not atom.config.get('core.allowPendingPaneItems') options.pending = false # Avoid adding URLs as recent documents to work-around this Spotlight crash: From a146401f21dfb7804799a9420d1b891975297022 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 17 Feb 2016 14:14:59 -0800 Subject: [PATCH 107/108] Terminate pending state for opened file if pending option is false --- spec/workspace-spec.coffee | 16 ++++++++++++++++ src/workspace.coffee | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 534f2bf61..ef89636a8 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -585,6 +585,22 @@ describe "Workspace", -> open = -> workspace.open('file1', workspace.getActivePane()) expect(open).toThrow() + describe "when the file is already open in pending state", -> + it "should terminate the pending state", -> + editor = null + + waitsForPromise -> + atom.workspace.open('sample.js', pending: true).then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBe true + + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBe false + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.getActivePane() diff --git a/src/workspace.coffee b/src/workspace.coffee index b26383786..0bfff7e0f 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -476,7 +476,8 @@ class Workspace extends Model activateItem = options.activateItem ? true if uri? - item = pane.itemForURI(uri) + if item = pane.itemForURI(uri) + item.terminatePendingState?() if item.isPending?() and not options.pending item ?= opener(uri, options) for opener in @getOpeners() when not item try From d6132888faf4fbcc2a7a8ebbee7b89d122140938 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 18 Feb 2016 14:18:27 +0100 Subject: [PATCH 108/108] :green_heart: Attempt to fix specs --- spec/text-editor-component-spec.js | 2 +- src/text-editor-presenter.coffee | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 8aaccbd6c..08da07dd8 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -544,7 +544,7 @@ describe('TextEditorComponent', function () { editor.setSoftWrapped(true) await nextViewUpdatePromise() - componentNode.style.width = 17 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() await nextViewUpdatePromise() }) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 3266eea70..a3504caa8 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -90,7 +90,7 @@ class TextEditorPresenter @updateLineDecorations() @updateBlockDecorations() - @updateTilesState(true) + @updateTilesState() @updating = false @state @@ -112,7 +112,7 @@ class TextEditorPresenter @updateHiddenInputState() @updateContentState() @updateHighlightDecorations() if @shouldUpdateDecorations - @updateTilesState(false) + @updateTilesState() @updateCursorsState() @updateOverlaysState() @updateLineNumberGutterState() @@ -327,7 +327,7 @@ class TextEditorPresenter clearScreenRowsToMeasure: -> @screenRowsToMeasure = [] - updateTilesState: (updateLinesState) -> + updateTilesState: -> return unless @startRow? and @endRow? and @lineHeight? screenRows = @getScreenRows() @@ -367,9 +367,8 @@ class TextEditorPresenter gutterTile.display = "block" gutterTile.zIndex = zIndex - if updateLinesState - @updateLinesState(tile, rowsWithinTile) - @updateLineNumbersState(gutterTile, rowsWithinTile) + @updateLinesState(tile, rowsWithinTile) + @updateLineNumbersState(gutterTile, rowsWithinTile) visibleTiles[tileStartRow] = true zIndex++