mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge remote-tracking branch 'origin/master' into cefode
Conflicts: native/v8_extensions/native.mm spec/app/config-spec.coffee spec/app/window-spec.coffee spec/spec-helper.coffee spec/stdlib/fs-utils-spec.coffee src/app/atom-package.coffee src/app/config.coffee src/app/window.coffee src/packages/fuzzy-finder/lib/load-paths-handler.coffee src/packages/markdown-preview/lib/markdown-preview-view.coffee src/packages/tree-view/spec/tree-view-spec.coffee src/stdlib/require.coffee
This commit is contained in:
@@ -7,70 +7,22 @@ CSON = require 'cson'
|
||||
module.exports =
|
||||
class AtomPackage extends Package
|
||||
metadata: null
|
||||
packageMain: null
|
||||
mainModule: null
|
||||
deferActivation: false
|
||||
|
||||
load: ({activateImmediately}={}) ->
|
||||
load: ->
|
||||
try
|
||||
@loadMetadata()
|
||||
@loadKeymaps()
|
||||
@loadStylesheets()
|
||||
if @metadata.activationEvents and not activateImmediately
|
||||
@subscribeToActivationEvents()
|
||||
if @deferActivation = @metadata.activationEvents?
|
||||
@registerDeferredDeserializers()
|
||||
else
|
||||
@activatePackageMain()
|
||||
@requireMainModule()
|
||||
catch e
|
||||
console.warn "Failed to load package named '#{@name}'", e.stack
|
||||
this
|
||||
|
||||
disableEventHandlersOnBubblePath: (event) ->
|
||||
bubblePathEventHandlers = []
|
||||
disabledHandler = ->
|
||||
element = $(event.target)
|
||||
while element.length
|
||||
if eventHandlers = element.data('events')?[event.type]
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.disabledHandler = eventHandler.handler
|
||||
eventHandler.handler = disabledHandler
|
||||
bubblePathEventHandlers.push(eventHandler)
|
||||
element = element.parent()
|
||||
bubblePathEventHandlers
|
||||
|
||||
restoreEventHandlersOnBubblePath: (eventHandlers) ->
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.handler = eventHandler.disabledHandler
|
||||
delete eventHandler.disabledHandler
|
||||
|
||||
unsubscribeFromActivationEvents: (activateHandler) ->
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
rootView.off(event, activateHandler) for event in @metadata.activationEvents
|
||||
else
|
||||
rootView.off(event, selector, activateHandler) for event, selector of @metadata.activationEvents
|
||||
|
||||
subscribeToActivationEvents: () ->
|
||||
activateHandler = (event) =>
|
||||
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
|
||||
@activatePackageMain()
|
||||
$(event.target).trigger(event)
|
||||
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
|
||||
@unsubscribeFromActivationEvents(activateHandler)
|
||||
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
rootView.command(event, activateHandler) for event in @metadata.activationEvents
|
||||
else
|
||||
rootView.command(event, selector, activateHandler) for event, selector of @metadata.activationEvents
|
||||
|
||||
activatePackageMain: ->
|
||||
mainPath = @path
|
||||
mainPath = fs.join(mainPath, @metadata.main) if @metadata.main
|
||||
try
|
||||
mainPath = require.resolve(mainPath)
|
||||
catch e
|
||||
return
|
||||
if fs.isFile(mainPath)
|
||||
@packageMain = require(mainPath)
|
||||
config.setDefaults(@name, @packageMain.configDefaults)
|
||||
atom.activateAtomPackage(this)
|
||||
|
||||
loadMetadata: ->
|
||||
if metadataPath = fs.resolveExtension(fs.join(@path, 'package'), ['cson', 'json'])
|
||||
@metadata = CSON.readObject(metadataPath)
|
||||
@@ -90,3 +42,68 @@ class AtomPackage extends Package
|
||||
stylesheetDirPath = fs.join(@path, 'stylesheets')
|
||||
for stylesheetPath in fs.list(stylesheetDirPath)
|
||||
requireStylesheet(stylesheetPath)
|
||||
|
||||
activate: ->
|
||||
if @deferActivation
|
||||
@subscribeToActivationEvents()
|
||||
else
|
||||
try
|
||||
if @requireMainModule()
|
||||
config.setDefaults(@name, @mainModule.configDefaults)
|
||||
atom.activateAtomPackage(this)
|
||||
catch e
|
||||
console.warn "Failed to activate package named '#{@name}'", e.stack
|
||||
|
||||
requireMainModule: ->
|
||||
return @mainModule if @mainModule
|
||||
mainPath =
|
||||
if @metadata.main
|
||||
fs.join(@path, @metadata.main)
|
||||
else
|
||||
fs.join(@path, 'index')
|
||||
mainPath = fs.resolveExtension(mainPath, ["", _.keys(require.extensions)...])
|
||||
@mainModule = require(mainPath) if fs.isFile(mainPath)
|
||||
|
||||
registerDeferredDeserializers: ->
|
||||
for deserializerName in @metadata.deferredDeserializers ? []
|
||||
registerDeferredDeserializer deserializerName, => @requireMainModule()
|
||||
|
||||
subscribeToActivationEvents: () ->
|
||||
return unless @metadata.activationEvents?
|
||||
|
||||
activateHandler = (event) =>
|
||||
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
|
||||
@deferActivation = false
|
||||
@activate()
|
||||
$(event.target).trigger(event)
|
||||
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
|
||||
@unsubscribeFromActivationEvents(activateHandler)
|
||||
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
rootView.command(event, activateHandler) for event in @metadata.activationEvents
|
||||
else
|
||||
rootView.command(event, selector, activateHandler) for event, selector of @metadata.activationEvents
|
||||
|
||||
unsubscribeFromActivationEvents: (activateHandler) ->
|
||||
if _.isArray(@metadata.activationEvents)
|
||||
rootView.off(event, activateHandler) for event in @metadata.activationEvents
|
||||
else
|
||||
rootView.off(event, selector, activateHandler) for event, selector of @metadata.activationEvents
|
||||
|
||||
disableEventHandlersOnBubblePath: (event) ->
|
||||
bubblePathEventHandlers = []
|
||||
disabledHandler = ->
|
||||
element = $(event.target)
|
||||
while element.length
|
||||
if eventHandlers = element.data('events')?[event.type]
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.disabledHandler = eventHandler.handler
|
||||
eventHandler.handler = disabledHandler
|
||||
bubblePathEventHandlers.push(eventHandler)
|
||||
element = element.parent()
|
||||
bubblePathEventHandlers
|
||||
|
||||
restoreEventHandlersOnBubblePath: (eventHandlers) ->
|
||||
for eventHandler in eventHandlers
|
||||
eventHandler.handler = eventHandler.disabledHandler
|
||||
delete eventHandler.disabledHandler
|
||||
|
||||
@@ -6,10 +6,10 @@ module.exports =
|
||||
class AtomTheme extends Theme
|
||||
|
||||
loadStylesheet: (stylesheetPath)->
|
||||
@stylesheets[stylesheetPath] = fs.read(stylesheetPath)
|
||||
@stylesheets[stylesheetPath] = window.loadStylesheet(stylesheetPath)
|
||||
|
||||
load: ->
|
||||
if fs.extension(@path) is '.css'
|
||||
if fs.extension(@path) in ['.css', '.less']
|
||||
@loadStylesheet(@path)
|
||||
else
|
||||
metadataPath = fs.resolveExtension(fs.join(@path, 'package'), ['cson', 'json'])
|
||||
@@ -18,6 +18,6 @@ class AtomTheme extends Theme
|
||||
if stylesheetNames
|
||||
@loadStylesheet(fs.join(@path, name)) for name in stylesheetNames
|
||||
else
|
||||
@loadStylesheet(stylesheetPath) for stylesheetPath in fs.list(@path, ['.css'])
|
||||
@loadStylesheet(stylesheetPath) for stylesheetPath in fs.list(@path, ['.css', '.less'])
|
||||
|
||||
super
|
||||
|
||||
@@ -24,10 +24,10 @@ _.extend atom,
|
||||
|
||||
activateAtomPackage: (pack) ->
|
||||
@activatedAtomPackages.push(pack)
|
||||
pack.packageMain.activate(@atomPackageStates[pack.name] ? {})
|
||||
pack.mainModule.activate(@atomPackageStates[pack.name] ? {})
|
||||
|
||||
deactivateAtomPackages: ->
|
||||
pack.packageMain.deactivate?() for pack in @activatedAtomPackages
|
||||
pack.mainModule.deactivate?() for pack in @activatedAtomPackages
|
||||
@activatedAtomPackages = []
|
||||
|
||||
serializeAtomPackages: ->
|
||||
@@ -35,7 +35,7 @@ _.extend atom,
|
||||
for pack in @loadedPackages
|
||||
if pack in @activatedAtomPackages
|
||||
try
|
||||
packageStates[pack.name] = pack.packageMain.serialize?()
|
||||
packageStates[pack.name] = pack.mainModule.serialize?()
|
||||
catch e
|
||||
console?.error("Exception serializing '#{pack.name}' package's module\n", e.stack)
|
||||
else
|
||||
@@ -61,6 +61,9 @@ _.extend atom,
|
||||
|
||||
new LoadTextMatePackagesTask(textMatePackages).start() if textMatePackages.length > 0
|
||||
|
||||
activatePackages: ->
|
||||
pack.activate() for pack in @loadedPackages
|
||||
|
||||
getLoadedPackages: ->
|
||||
_.clone(@loadedPackages)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ class Config
|
||||
userPackagesDirPath: userPackagesDirPath
|
||||
defaultSettings: null
|
||||
settings: null
|
||||
configFileHasErrors: null
|
||||
|
||||
constructor: ->
|
||||
@defaultSettings =
|
||||
@@ -34,18 +35,17 @@ class Config
|
||||
fs.makeDirectory(@configDirPath)
|
||||
|
||||
templateConfigDirPath = fs.resolve(window.resourcePath, 'dot-atom')
|
||||
|
||||
onConfigDirFile = (path) =>
|
||||
templatePath = fs.join(templateConfigDirPath, path)
|
||||
configPath = fs.join(@configDirPath, path)
|
||||
fs.write(configPath, fs.read(templatePath))
|
||||
relativePath = path.substring(templateConfigDirPath.length + 1)
|
||||
configPath = fs.join(@configDirPath, relativePath)
|
||||
fs.write(configPath, fs.read(path))
|
||||
fs.traverseTreeSync(templateConfigDirPath, onConfigDirFile, (path) -> true)
|
||||
|
||||
configThemeDirPath = fs.join(@configDirPath, 'themes')
|
||||
onThemeDirFile = (path) ->
|
||||
templatePath = fs.join(bundledThemesDirPath, path)
|
||||
configPath = fs.join(configThemeDirPath, path)
|
||||
fs.write(configPath, fs.read(templatePath))
|
||||
relativePath = path.substring(bundledThemesDirPath.length + 1)
|
||||
configPath = fs.join(configThemeDirPath, relativePath)
|
||||
fs.write(configPath, fs.read(path))
|
||||
fs.traverseTreeSync(bundledThemesDirPath, onThemeDirFile, (path) -> true)
|
||||
|
||||
load: ->
|
||||
@@ -54,8 +54,13 @@ class Config
|
||||
|
||||
loadUserConfig: ->
|
||||
if fs.exists(@configFilePath)
|
||||
userConfig = CSON.readObject(@configFilePath)
|
||||
_.extend(@settings, userConfig)
|
||||
try
|
||||
userConfig = CSON.readObject(@configFilePath)
|
||||
_.extend(@settings, userConfig)
|
||||
catch e
|
||||
@configFileHasErrors = true
|
||||
console.error "Failed to load user config '#{@configFilePath}'", e.message
|
||||
console.error e.stack
|
||||
|
||||
get: (keyPath) ->
|
||||
_.valueForKeyPath(@settings, keyPath) ?
|
||||
@@ -91,6 +96,7 @@ class Config
|
||||
subscription
|
||||
|
||||
update: ->
|
||||
return if @configFileHasErrors
|
||||
@save()
|
||||
@trigger 'updated'
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class Editor extends View
|
||||
else
|
||||
{editSession, @mini} = (editSessionOrOptions ? {})
|
||||
|
||||
requireStylesheet 'editor.css'
|
||||
requireStylesheet 'editor.less'
|
||||
|
||||
@id = Editor.nextEditorId++
|
||||
@lineCache = []
|
||||
|
||||
@@ -9,6 +9,7 @@ class PaneContainer extends View
|
||||
@deserialize: ({root}) ->
|
||||
container = new PaneContainer
|
||||
container.append(deserialize(root)) if root
|
||||
container.removeEmptyPanes()
|
||||
container
|
||||
|
||||
@content: ->
|
||||
@@ -61,6 +62,23 @@ class PaneContainer extends View
|
||||
saveAll: ->
|
||||
pane.saveItems() for pane in @getPanes()
|
||||
|
||||
confirmClose: ->
|
||||
deferred = $.Deferred()
|
||||
modifiedItems = []
|
||||
for pane in @getPanes()
|
||||
modifiedItems.push(item) for item in pane.getItems() when item.isModified?()
|
||||
|
||||
cancel = => deferred.reject()
|
||||
saveNextModifiedItem = =>
|
||||
if modifiedItems.length == 0
|
||||
deferred.resolve()
|
||||
else
|
||||
item = modifiedItems.pop()
|
||||
@paneAtIndex(0).promptToSaveItem item, saveNextModifiedItem, cancel
|
||||
|
||||
saveNextModifiedItem()
|
||||
deferred.promise()
|
||||
|
||||
getPanes: ->
|
||||
@find('.pane').views()
|
||||
|
||||
@@ -93,5 +111,9 @@ class PaneContainer extends View
|
||||
root.css(width: '100%', height: '100%', top: 0, left: 0)
|
||||
root.adjustDimensions()
|
||||
|
||||
removeEmptyPanes: ->
|
||||
for pane in @getPanes() when pane.getItems().length == 0
|
||||
pane.remove()
|
||||
|
||||
afterAttach: ->
|
||||
@adjustPaneDimensions()
|
||||
|
||||
@@ -11,7 +11,8 @@ class Pane extends View
|
||||
@div class: 'item-views', outlet: 'itemViews'
|
||||
|
||||
@deserialize: ({items, focused, activeItemUri}) ->
|
||||
pane = new Pane(items.map((item) -> deserialize(item))...)
|
||||
deserializedItems = _.compact(items.map((item) -> deserialize(item)))
|
||||
pane = new Pane(deserializedItems...)
|
||||
pane.showItemForUri(activeItemUri) if activeItemUri
|
||||
pane.focusOnAttach = true if focused
|
||||
pane
|
||||
@@ -21,7 +22,7 @@ class Pane extends View
|
||||
|
||||
initialize: (@items...) ->
|
||||
@viewsByClassName = {}
|
||||
@showItem(@items[0])
|
||||
@showItem(@items[0]) if @items.length > 0
|
||||
|
||||
@command 'core:close', @destroyActiveItem
|
||||
@command 'core:save', @saveActiveItem
|
||||
@@ -46,7 +47,7 @@ class Pane extends View
|
||||
@command 'pane:split-down', => @splitDown()
|
||||
@command 'pane:close', => @destroyItems()
|
||||
@command 'pane:close-other-items', => @destroyInactiveItems()
|
||||
@on 'focus', => @activeView.focus(); false
|
||||
@on 'focus', => @activeView?.focus(); false
|
||||
@on 'focusin', => @makeActive()
|
||||
@on 'focusout', => @autosaveActiveItem()
|
||||
|
||||
@@ -72,6 +73,12 @@ class Pane extends View
|
||||
isActive: ->
|
||||
@hasClass('active')
|
||||
|
||||
getNextPane: ->
|
||||
panes = @getContainer()?.getPanes()
|
||||
return unless panes.length > 1
|
||||
nextIndex = (panes.indexOf(this) + 1) % panes.length
|
||||
panes[nextIndex]
|
||||
|
||||
getItems: ->
|
||||
new Array(@items...)
|
||||
|
||||
@@ -152,13 +159,13 @@ class Pane extends View
|
||||
destroyInactiveItems: ->
|
||||
@destroyItem(item) for item in @getItems() when item isnt @activeItem
|
||||
|
||||
promptToSaveItem: (item, nextAction) ->
|
||||
promptToSaveItem: (item, nextAction, cancelAction) ->
|
||||
uri = item.getUri()
|
||||
atom.confirm(
|
||||
"'#{item.getTitle()}' has changes, do you want to save them?"
|
||||
"'#{item.getTitle?() ? item.getUri()}' has changes, do you want to save them?"
|
||||
"Your changes will be lost if close this item without saving."
|
||||
"Save", => @saveItem(item, nextAction)
|
||||
"Cancel", null
|
||||
"Cancel", cancelAction
|
||||
"Don't Save", nextAction
|
||||
)
|
||||
|
||||
|
||||
@@ -75,6 +75,9 @@ class RootView extends View
|
||||
panes: @panes.serialize()
|
||||
packages: atom.serializeAtomPackages()
|
||||
|
||||
confirmClose: ->
|
||||
@panes.confirmClose()
|
||||
|
||||
handleFocus: (e) ->
|
||||
if @getActivePane()
|
||||
@getActivePane().focus()
|
||||
@@ -115,7 +118,7 @@ class RootView extends View
|
||||
updateTitle: ->
|
||||
if projectPath = project.getPath()
|
||||
if item = @getActivePaneItem()
|
||||
@setTitle("#{item.getTitle()} - #{projectPath}")
|
||||
@setTitle("#{item.getTitle?() ? 'untitled'} - #{projectPath}")
|
||||
else
|
||||
@setTitle(projectPath)
|
||||
else
|
||||
|
||||
@@ -20,7 +20,7 @@ class SelectList extends View
|
||||
cancelling: false
|
||||
|
||||
initialize: ->
|
||||
requireStylesheet 'select-list.css'
|
||||
requireStylesheet 'select-list.less'
|
||||
|
||||
@miniEditor.getBuffer().on 'changed', => @schedulePopulateList()
|
||||
@miniEditor.on 'focusout', => @cancel() unless @cancelling
|
||||
|
||||
@@ -32,6 +32,8 @@ class TextMatePackage extends Package
|
||||
console.warn "Failed to load package at '#{@path}'", e.stack
|
||||
this
|
||||
|
||||
activate: -> # no-op
|
||||
|
||||
getGrammars: -> @grammars
|
||||
|
||||
readGrammars: ->
|
||||
|
||||
@@ -11,7 +11,7 @@ class Theme
|
||||
if fs.exists(name)
|
||||
path = name
|
||||
else
|
||||
path = fs.resolve(config.themeDirPaths..., name, ['', '.tmTheme', '.css'])
|
||||
path = fs.resolve(config.themeDirPaths..., name, ['', '.tmTheme', '.css', 'less'])
|
||||
|
||||
throw new Error("No theme exists named '#{name}'") unless path
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
fs = require 'fs-utils'
|
||||
$ = require 'jquery'
|
||||
ChildProcess = require 'child_process'
|
||||
{less} = require 'less'
|
||||
{spawn} = require 'child_process'
|
||||
require 'jquery-extensions'
|
||||
require 'underscore-extensions'
|
||||
require 'space-pen-extensions'
|
||||
|
||||
deserializers = {}
|
||||
deferredDeserializers = {}
|
||||
|
||||
# This method is called in any window needing a general environment, including specs
|
||||
window.setUpEnvironment = ->
|
||||
@@ -23,17 +25,17 @@ window.setUpEnvironment = ->
|
||||
$(document).on 'keydown', keymap.handleKeyEvent
|
||||
keymap.bindDefaultKeys()
|
||||
|
||||
requireStylesheet 'reset.css'
|
||||
requireStylesheet 'atom.css'
|
||||
requireStylesheet 'tabs.css'
|
||||
requireStylesheet 'tree-view.css'
|
||||
requireStylesheet 'status-bar.css'
|
||||
requireStylesheet 'command-panel.css'
|
||||
requireStylesheet 'fuzzy-finder.css'
|
||||
requireStylesheet 'overlay.css'
|
||||
requireStylesheet 'popover-list.css'
|
||||
requireStylesheet 'notification.css'
|
||||
requireStylesheet 'markdown.css'
|
||||
requireStylesheet 'reset.less'
|
||||
requireStylesheet 'atom.less'
|
||||
requireStylesheet 'tabs.less'
|
||||
requireStylesheet 'tree-view.less'
|
||||
requireStylesheet 'status-bar.less'
|
||||
requireStylesheet 'command-panel.less'
|
||||
requireStylesheet 'fuzzy-finder.less'
|
||||
requireStylesheet 'overlay.less'
|
||||
requireStylesheet 'popover-list.less'
|
||||
requireStylesheet 'notification.less'
|
||||
requireStylesheet 'markdown.less'
|
||||
|
||||
if nativeStylesheetPath = require.resolve("#{platform}.css")
|
||||
requireStylesheet(nativeStylesheetPath)
|
||||
@@ -52,10 +54,11 @@ window.startup = ->
|
||||
handleWindowEvents()
|
||||
config.load()
|
||||
atom.loadTextPackage()
|
||||
buildProjectAndRootView()
|
||||
keymap.loadBundledKeymaps()
|
||||
atom.loadThemes()
|
||||
atom.loadPackages()
|
||||
buildProjectAndRootView()
|
||||
atom.activatePackages()
|
||||
keymap.loadUserKeymaps()
|
||||
atom.requireUserInitScript()
|
||||
$(window).on 'beforeunload', -> shutdown(); false
|
||||
@@ -81,14 +84,13 @@ window.installAtomCommand = (commandPath) ->
|
||||
bundledCommandPath = fs.resolve(window.resourcePath, 'atom.sh')
|
||||
if bundledCommandPath?
|
||||
fs.write(commandPath, fs.read(bundledCommandPath))
|
||||
ChildProcess.exec("chmod u+x '#{commandPath}'")
|
||||
spawn("chmod u+x '#{commandPath}'")
|
||||
|
||||
window.handleWindowEvents = ->
|
||||
$(window).on 'core:close', => window.close()
|
||||
$(window).command 'window:close', => window.close()
|
||||
$(window).command 'window:toggle-full-screen', => atom.toggleFullScreen()
|
||||
$(window).on 'focus', -> $("body").removeClass('is-blurred')
|
||||
$(window).on 'blur', -> $("body").addClass('is-blurred')
|
||||
$(window).command 'window:close', => confirmClose()
|
||||
|
||||
window.buildProjectAndRootView = ->
|
||||
RootView = require 'root-view'
|
||||
@@ -115,10 +117,21 @@ window.stylesheetElementForId = (id) ->
|
||||
|
||||
window.requireStylesheet = (path) ->
|
||||
if fullPath = require.resolve(path)
|
||||
window.applyStylesheet(fullPath, fs.read(fullPath))
|
||||
unless fullPath
|
||||
content = window.loadStylesheet(fullPath)
|
||||
window.applyStylesheet(fullPath, content)
|
||||
else
|
||||
console.log "bad", path
|
||||
throw new Error("Could not find a file at path '#{path}'")
|
||||
|
||||
window.loadStylesheet = (path) ->
|
||||
content = fs.read(path)
|
||||
if fs.extension(path) == '.less'
|
||||
(new less.Parser).parse content, (e, tree) ->
|
||||
throw new Error(e.message, file, e.line) if e
|
||||
content = tree.toCSS()
|
||||
|
||||
content
|
||||
|
||||
window.removeStylesheet = (path) ->
|
||||
unless fullPath = require.resolve(path)
|
||||
throw new Error("Could not find a file at path '#{path}'")
|
||||
@@ -151,6 +164,9 @@ window.registerDeserializers = (args...) ->
|
||||
window.registerDeserializer = (klass) ->
|
||||
deserializers[klass.name] = klass
|
||||
|
||||
window.registerDeferredDeserializer = (name, fn) ->
|
||||
deferredDeserializers[name] = fn
|
||||
|
||||
window.unregisterDeserializer = (klass) ->
|
||||
delete deserializers[klass.name]
|
||||
|
||||
@@ -160,7 +176,11 @@ window.deserialize = (state) ->
|
||||
deserializer.deserialize(state)
|
||||
|
||||
window.getDeserializer = (state) ->
|
||||
deserializers[state?.deserializer]
|
||||
name = state?.deserializer
|
||||
if deferredDeserializers[name]
|
||||
deferredDeserializers[name]()
|
||||
delete deferredDeserializers[name]
|
||||
deserializers[name]
|
||||
|
||||
window.measure = (description, fn) ->
|
||||
start = new Date().getTime()
|
||||
@@ -175,3 +195,6 @@ window.profile = (description, fn) ->
|
||||
value = fn()
|
||||
console.profileEnd(description)
|
||||
value
|
||||
|
||||
confirmClose = ->
|
||||
rootView.confirmClose().done -> window.close()
|
||||
|
||||
Reference in New Issue
Block a user