2013-09-18 05:58:41 +04:00
|
|
|
require '../src/window'
|
2013-12-12 08:37:52 +04:00
|
|
|
atom.initialize()
|
|
|
|
atom.restoreWindowDimensions()
|
2013-02-20 23:44:39 +04:00
|
|
|
|
2014-10-08 02:19:55 +04:00
|
|
|
require 'jasmine-json'
|
2013-09-17 22:33:56 +04:00
|
|
|
require '../vendor/jasmine-jquery'
|
2013-09-04 04:01:35 +04:00
|
|
|
path = require 'path'
|
2014-02-24 05:09:05 +04:00
|
|
|
_ = require 'underscore-plus'
|
|
|
|
fs = require 'fs-plus'
|
2014-04-22 21:11:52 +04:00
|
|
|
Grim = require 'grim'
|
2014-04-01 01:45:01 +04:00
|
|
|
KeymapManager = require '../src/keymap-extensions'
|
2014-11-19 04:48:28 +03:00
|
|
|
|
2014-01-04 03:23:23 +04:00
|
|
|
{Point} = require 'text-buffer'
|
2013-09-18 05:58:41 +04:00
|
|
|
Project = require '../src/project'
|
2014-11-19 04:48:28 +03:00
|
|
|
Workspace = require '../src/workspace'
|
2015-02-02 21:01:34 +03:00
|
|
|
ServiceHub = require 'service-hub'
|
2014-09-23 01:35:13 +04:00
|
|
|
TextEditor = require '../src/text-editor'
|
2014-11-27 03:51:13 +03:00
|
|
|
TextEditorElement = require '../src/text-editor-element'
|
2013-09-18 05:58:41 +04:00
|
|
|
TokenizedBuffer = require '../src/tokenized-buffer'
|
2014-09-23 01:35:13 +04:00
|
|
|
TextEditorComponent = require '../src/text-editor-component'
|
2013-04-07 12:18:08 +04:00
|
|
|
pathwatcher = require 'pathwatcher'
|
2015-04-14 20:34:43 +03:00
|
|
|
clipboard = require '../src/safe-clipboard'
|
2013-09-04 23:38:20 +04:00
|
|
|
|
2013-09-25 19:39:16 +04:00
|
|
|
atom.themes.loadBaseStylesheets()
|
|
|
|
atom.themes.requireStylesheet '../static/jasmine'
|
2014-09-12 02:49:44 +04:00
|
|
|
atom.themes.initialLoadComplete = true
|
2013-09-04 23:38:20 +04:00
|
|
|
|
2013-09-18 01:54:33 +04:00
|
|
|
fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
|
2013-10-08 01:52:30 +04:00
|
|
|
atom.packages.packageDirPaths.unshift(fixturePackagesPath)
|
2014-04-01 02:28:55 +04:00
|
|
|
atom.keymaps.loadBundledKeymaps()
|
|
|
|
keyBindingsToRestore = atom.keymaps.getKeyBindings()
|
2014-09-24 01:41:44 +04:00
|
|
|
commandsToRestore = atom.commands.getSnapshot()
|
2014-10-14 20:08:46 +04:00
|
|
|
styleElementsToRestore = atom.styles.getSnapshot()
|
2012-12-19 06:47:20 +04:00
|
|
|
|
2014-09-26 06:57:09 +04:00
|
|
|
window.addEventListener 'core:close', -> window.close()
|
|
|
|
window.addEventListener 'beforeunload', ->
|
2013-12-12 08:37:52 +04:00
|
|
|
atom.storeWindowDimensions()
|
|
|
|
atom.saveSync()
|
2015-09-04 19:21:00 +03:00
|
|
|
|
|
|
|
document.querySelector('html').style.overflow = 'auto'
|
|
|
|
document.body.style.overflow = 'auto'
|
2013-02-20 23:44:50 +04:00
|
|
|
|
2014-09-25 01:56:50 +04:00
|
|
|
# Allow document.title to be assigned in specs without screwing up spec window title
|
|
|
|
documentTitle = null
|
|
|
|
Object.defineProperty document, 'title',
|
|
|
|
get: -> documentTitle
|
|
|
|
set: (title) -> documentTitle = title
|
|
|
|
|
2015-05-30 03:18:48 +03:00
|
|
|
Set.prototype.jasmineToString = ->
|
|
|
|
result = "Set {"
|
|
|
|
first = true
|
|
|
|
@forEach (element) ->
|
|
|
|
result += ", " unless first
|
|
|
|
result += element.toString()
|
|
|
|
first = false
|
|
|
|
result + "}"
|
|
|
|
|
|
|
|
Set.prototype.isEqual = (other) ->
|
|
|
|
if other instanceof Set
|
|
|
|
return false if @size isnt other.size
|
|
|
|
values = @values()
|
|
|
|
until (next = values.next()).done
|
|
|
|
return false unless other.has(next.value)
|
|
|
|
true
|
|
|
|
else
|
|
|
|
false
|
|
|
|
|
2013-02-20 23:44:50 +04:00
|
|
|
jasmine.getEnv().addEqualityTester(_.isEqual) # Use underscore's definition of equality for toEqual assertions
|
2014-06-18 21:04:07 +04:00
|
|
|
|
2015-04-16 10:15:46 +03:00
|
|
|
if process.env.CI
|
2014-07-07 21:14:38 +04:00
|
|
|
jasmine.getEnv().defaultTimeoutInterval = 60000
|
2014-06-18 21:04:07 +04:00
|
|
|
else
|
|
|
|
jasmine.getEnv().defaultTimeoutInterval = 5000
|
2013-02-20 23:44:50 +04:00
|
|
|
|
2013-10-11 00:03:44 +04:00
|
|
|
specPackageName = null
|
|
|
|
specPackagePath = null
|
2013-10-14 22:15:40 +04:00
|
|
|
specProjectPath = null
|
2014-04-25 00:47:01 +04:00
|
|
|
isCoreSpec = false
|
2013-10-11 00:03:44 +04:00
|
|
|
|
2013-12-14 00:02:48 +04:00
|
|
|
{specDirectory, resourcePath} = atom.getLoadSettings()
|
2013-11-22 02:55:25 +04:00
|
|
|
|
|
|
|
if specDirectory
|
2013-10-11 00:03:44 +04:00
|
|
|
specPackagePath = path.resolve(specDirectory, '..')
|
|
|
|
try
|
2014-02-18 03:25:51 +04:00
|
|
|
specPackageName = JSON.parse(fs.readFileSync(path.join(specPackagePath, 'package.json')))?.name
|
2013-10-14 22:15:40 +04:00
|
|
|
specProjectPath = path.join(specDirectory, 'fixtures')
|
2013-09-26 23:19:02 +04:00
|
|
|
|
2015-04-07 06:45:02 +03:00
|
|
|
isCoreSpec = specDirectory is fs.realpathSync(__dirname)
|
2014-04-25 00:47:01 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
beforeEach ->
|
2014-09-25 01:56:50 +04:00
|
|
|
documentTitle = null
|
2013-11-13 05:34:13 +04:00
|
|
|
projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures')
|
2015-02-13 04:11:06 +03:00
|
|
|
atom.packages.serviceHub = new ServiceHub
|
2014-10-01 20:37:27 +04:00
|
|
|
atom.project = new Project(paths: [projectPath])
|
2014-04-03 00:23:50 +04:00
|
|
|
atom.workspace = new Workspace()
|
2015-09-29 00:58:50 +03:00
|
|
|
atom.themes.workspace = atom.workspace
|
2014-04-01 02:28:55 +04:00
|
|
|
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
|
2014-09-24 01:41:44 +04:00
|
|
|
atom.commands.restoreSnapshot(commandsToRestore)
|
2014-10-14 20:08:46 +04:00
|
|
|
atom.styles.restoreSnapshot(styleElementsToRestore)
|
2015-02-20 00:57:30 +03:00
|
|
|
atom.views.clearDocumentRequests()
|
2013-02-28 05:50:37 +04:00
|
|
|
|
2015-09-03 19:50:56 +03:00
|
|
|
atom.workspaceParentSelectorctor = '#jasmine-content'
|
2014-11-27 20:30:50 +03:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
window.resetTimeouts()
|
2014-12-30 10:52:16 +03:00
|
|
|
spyOn(_._, "now").andCallFake -> window.now
|
|
|
|
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
|
|
|
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
|
|
|
|
|
2013-09-30 23:14:30 +04:00
|
|
|
atom.packages.packageStates = {}
|
2013-12-07 00:38:46 +04:00
|
|
|
|
|
|
|
serializedWindowState = null
|
2013-12-12 08:37:52 +04:00
|
|
|
|
|
|
|
spyOn(atom, 'saveSync')
|
2014-11-20 21:42:49 +03:00
|
|
|
atom.grammars.clearGrammarOverrides()
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2013-10-31 02:44:18 +04:00
|
|
|
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
|
|
|
|
if specPackageName and packageName is specPackageName
|
|
|
|
resolvePackagePath(specPackagePath)
|
|
|
|
else
|
|
|
|
resolvePackagePath(packageName)
|
|
|
|
resolvePackagePath = _.bind(spy.originalValue, atom.packages)
|
2013-10-11 00:03:44 +04:00
|
|
|
|
2013-10-09 03:23:34 +04:00
|
|
|
# prevent specs from modifying Atom's menus
|
|
|
|
spyOn(atom.menu, 'sendToBrowserProcess')
|
|
|
|
|
2013-01-04 02:10:11 +04:00
|
|
|
# reset config before each spec; don't load or save from/to `config.json`
|
2015-09-28 22:21:50 +03:00
|
|
|
spyOn(atom.config, 'load')
|
|
|
|
spyOn(atom.config, 'save')
|
|
|
|
atom.config.set "core.destroyEmptyPanes", false
|
|
|
|
atom.config.set "editor.fontFamily", "Courier"
|
|
|
|
atom.config.set "editor.fontSize", 16
|
|
|
|
atom.config.set "editor.autoIndent", false
|
|
|
|
atom.config.set "core.disabledPackages", ["package-that-throws-an-exception",
|
2013-10-11 22:56:12 +04:00
|
|
|
"package-with-broken-package-json", "package-with-broken-keymap"]
|
2015-09-28 22:21:50 +03:00
|
|
|
atom.config.set "editor.useShadowDOM", true
|
2014-12-30 10:52:41 +03:00
|
|
|
advanceClock(1000)
|
2015-01-13 20:17:48 +03:00
|
|
|
window.setTimeout.reset()
|
2015-09-28 22:21:50 +03:00
|
|
|
atom.config.load.reset()
|
|
|
|
atom.config.save.reset()
|
2012-12-13 03:23:36 +04:00
|
|
|
|
2012-11-15 00:13:57 +04:00
|
|
|
# make editor display updates synchronous
|
2014-11-27 03:51:13 +03:00
|
|
|
TextEditorElement::setUpdatedSynchronously(true)
|
2014-06-20 03:31:06 +04:00
|
|
|
|
2014-09-25 01:56:50 +04:00
|
|
|
spyOn(atom, "setRepresentedFilename")
|
2014-02-19 22:01:56 +04:00
|
|
|
spyOn(pathwatcher.File.prototype, "detectResurrectionAfterDelay").andCallFake -> @detectResurrection()
|
2014-09-23 01:35:13 +04:00
|
|
|
spyOn(TextEditor.prototype, "shouldPromptToSave").andReturn false
|
2012-11-15 00:13:57 +04:00
|
|
|
|
2012-11-21 19:22:13 +04:00
|
|
|
# make tokenization synchronous
|
|
|
|
TokenizedBuffer.prototype.chunkSize = Infinity
|
|
|
|
spyOn(TokenizedBuffer.prototype, "tokenizeInBackground").andCallFake -> @tokenizeNextChunk()
|
|
|
|
|
2014-02-04 01:12:33 +04:00
|
|
|
clipboardContent = 'initial clipboard content'
|
|
|
|
spyOn(clipboard, 'writeText').andCallFake (text) -> clipboardContent = text
|
|
|
|
spyOn(clipboard, 'readText').andCallFake -> clipboardContent
|
2013-01-10 22:56:55 +04:00
|
|
|
|
2013-03-07 23:04:17 +04:00
|
|
|
addCustomMatchers(this)
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
afterEach ->
|
2013-11-20 05:31:41 +04:00
|
|
|
atom.packages.deactivatePackages()
|
2013-10-18 22:34:19 +04:00
|
|
|
atom.menu.template = []
|
2014-09-30 06:25:55 +04:00
|
|
|
atom.contextMenu.clear()
|
2015-07-02 00:35:59 +03:00
|
|
|
atom.notifications.clear()
|
2013-10-03 02:50:47 +04:00
|
|
|
|
2014-11-20 03:51:00 +03:00
|
|
|
atom.workspace?.destroy()
|
|
|
|
atom.workspace = null
|
2015-09-29 00:58:50 +03:00
|
|
|
atom.themes.workspace = null
|
2014-01-15 00:06:42 +04:00
|
|
|
delete atom.state.workspace
|
2013-10-03 02:50:47 +04:00
|
|
|
|
2014-04-03 01:19:06 +04:00
|
|
|
atom.project?.destroy()
|
2013-10-03 02:50:47 +04:00
|
|
|
atom.project = null
|
|
|
|
|
2014-07-28 21:23:36 +04:00
|
|
|
atom.themes.removeStylesheet('global-editor-styles')
|
|
|
|
|
2014-01-04 04:42:11 +04:00
|
|
|
delete atom.state.packageStates
|
2015-09-30 23:04:09 +03:00
|
|
|
atom.reset()
|
2013-12-12 08:37:52 +04:00
|
|
|
|
2015-09-04 19:21:00 +03:00
|
|
|
document.getElementById('jasmine-content').innerHTML = '' unless window.debugContent
|
2013-12-12 08:37:52 +04:00
|
|
|
|
|
|
|
jasmine.unspy(atom, 'saveSync')
|
2012-11-29 04:16:15 +04:00
|
|
|
ensureNoPathSubscriptions()
|
|
|
|
waits(0) # yield to ui thread to make screen update more frequently
|
2012-11-29 00:40:37 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
ensureNoPathSubscriptions = ->
|
2013-04-07 12:18:08 +04:00
|
|
|
watchedPaths = pathwatcher.getWatchedPaths()
|
|
|
|
pathwatcher.closeAllWatchers()
|
2012-11-29 04:16:15 +04:00
|
|
|
if watchedPaths.length > 0
|
|
|
|
throw new Error("Leaking subscriptions for paths: " + watchedPaths.join(", "))
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2014-04-22 21:43:55 +04:00
|
|
|
ensureNoDeprecatedFunctionsCalled = ->
|
|
|
|
deprecations = Grim.getDeprecations()
|
|
|
|
if deprecations.length > 0
|
|
|
|
originalPrepareStackTrace = Error.prepareStackTrace
|
|
|
|
Error.prepareStackTrace = (error, stack) ->
|
|
|
|
output = []
|
|
|
|
for deprecation in deprecations
|
2014-04-22 22:01:05 +04:00
|
|
|
output.push "#{deprecation.originName} is deprecated. #{deprecation.message}"
|
2014-04-22 21:43:55 +04:00
|
|
|
output.push _.multiplyString("-", output[output.length - 1].length)
|
|
|
|
for stack in deprecation.getStacks()
|
|
|
|
for {functionName, location} in stack
|
|
|
|
output.push "#{functionName} -- #{location}"
|
|
|
|
output.push ""
|
|
|
|
output.join("\n")
|
|
|
|
|
|
|
|
error = new Error("Deprecated function(s) #{deprecations.map(({originName}) -> originName).join ', '}) were called.")
|
|
|
|
error.stack
|
|
|
|
Error.prepareStackTrace = originalPrepareStackTrace
|
|
|
|
|
|
|
|
throw error
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
emitObject = jasmine.StringPrettyPrinter.prototype.emitObject
|
|
|
|
jasmine.StringPrettyPrinter.prototype.emitObject = (obj) ->
|
|
|
|
if obj.inspect
|
|
|
|
@append obj.inspect()
|
|
|
|
else
|
|
|
|
emitObject.call(this, obj)
|
|
|
|
|
2012-11-17 04:12:04 +04:00
|
|
|
jasmine.unspy = (object, methodName) ->
|
2013-12-12 08:37:52 +04:00
|
|
|
throw new Error("Not a spy") unless object[methodName].hasOwnProperty('originalValue')
|
2012-11-17 04:12:04 +04:00
|
|
|
object[methodName] = object[methodName].originalValue
|
|
|
|
|
2014-11-20 03:20:39 +03:00
|
|
|
jasmine.attachToDOM = (element) ->
|
|
|
|
jasmineContent = document.querySelector('#jasmine-content')
|
|
|
|
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
|
|
|
|
|
2014-11-26 00:51:56 +03:00
|
|
|
deprecationsSnapshot = null
|
|
|
|
jasmine.snapshotDeprecations = ->
|
2015-01-07 20:11:55 +03:00
|
|
|
deprecationsSnapshot = _.clone(Grim.deprecations)
|
2014-11-26 00:51:56 +03:00
|
|
|
|
|
|
|
jasmine.restoreDeprecationsSnapshot = ->
|
2015-01-07 20:11:55 +03:00
|
|
|
Grim.deprecations = deprecationsSnapshot
|
2014-11-26 00:51:56 +03:00
|
|
|
|
2015-01-23 04:59:18 +03:00
|
|
|
jasmine.useRealClock = ->
|
|
|
|
jasmine.unspy(window, 'setTimeout')
|
|
|
|
jasmine.unspy(window, 'clearTimeout')
|
|
|
|
jasmine.unspy(_._, 'now')
|
|
|
|
|
2013-03-07 23:04:17 +04:00
|
|
|
addCustomMatchers = (spec) ->
|
|
|
|
spec.addMatchers
|
|
|
|
toBeInstanceOf: (expected) ->
|
|
|
|
notText = if @isNot then " not" else ""
|
|
|
|
this.message = => "Expected #{jasmine.pp(@actual)} to#{notText} be instance of #{expected.name} class"
|
|
|
|
@actual instanceof expected
|
|
|
|
|
|
|
|
toHaveLength: (expected) ->
|
2013-09-09 20:28:36 +04:00
|
|
|
if not @actual?
|
|
|
|
this.message = => "Expected object #{@actual} has no length method"
|
|
|
|
false
|
|
|
|
else
|
|
|
|
notText = if @isNot then " not" else ""
|
|
|
|
this.message = => "Expected object with length #{@actual.length} to#{notText} have length #{expected}"
|
2015-04-07 06:45:02 +03:00
|
|
|
@actual.length is expected
|
2013-03-07 23:04:17 +04:00
|
|
|
|
2013-03-13 03:55:28 +04:00
|
|
|
toExistOnDisk: (expected) ->
|
|
|
|
notText = this.isNot and " not" or ""
|
|
|
|
@message = -> return "Expected path '" + @actual + "'" + notText + " to exist."
|
2013-11-01 00:43:44 +04:00
|
|
|
fs.existsSync(@actual)
|
2013-03-13 03:55:28 +04:00
|
|
|
|
2014-02-05 01:06:47 +04:00
|
|
|
toHaveFocus: ->
|
|
|
|
notText = this.isNot and " not" or ""
|
|
|
|
if not document.hasFocus()
|
|
|
|
console.error "Specs will fail because the Dev Tools have focus. To fix this close the Dev Tools or click the spec runner."
|
|
|
|
|
|
|
|
@message = -> return "Expected element '" + @actual + "' or its descendants" + notText + " to have focus."
|
|
|
|
element = @actual
|
|
|
|
element = element.get(0) if element.jquery
|
2014-10-16 23:53:17 +04:00
|
|
|
element is document.activeElement or element.contains(document.activeElement)
|
2014-02-05 01:06:47 +04:00
|
|
|
|
2014-08-14 00:41:56 +04:00
|
|
|
toShow: ->
|
|
|
|
notText = if @isNot then " not" else ""
|
|
|
|
element = @actual
|
|
|
|
element = element.get(0) if element.jquery
|
2014-10-17 04:31:30 +04:00
|
|
|
@message = -> return "Expected element '#{element}' or its descendants#{notText} to show."
|
2014-08-14 00:41:56 +04:00
|
|
|
element.style.display in ['block', 'inline-block', 'static', 'fixed']
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
window.waitsForPromise = (args...) ->
|
|
|
|
if args.length > 1
|
2015-04-07 06:45:02 +03:00
|
|
|
{shouldReject, timeout} = args[0]
|
2012-08-28 02:36:36 +04:00
|
|
|
else
|
|
|
|
shouldReject = false
|
|
|
|
fn = _.last(args)
|
|
|
|
|
2013-09-24 03:44:59 +04:00
|
|
|
window.waitsFor timeout, (moveOn) ->
|
2012-08-28 02:36:36 +04:00
|
|
|
promise = fn()
|
|
|
|
if shouldReject
|
2015-02-10 01:22:11 +03:00
|
|
|
promise.catch.call(promise, moveOn)
|
2015-01-23 04:26:15 +03:00
|
|
|
promise.then ->
|
2012-08-28 02:36:36 +04:00
|
|
|
jasmine.getEnv().currentSpec.fail("Expected promise to be rejected, but it was resolved")
|
|
|
|
moveOn()
|
|
|
|
else
|
2015-01-23 04:26:15 +03:00
|
|
|
promise.then(moveOn)
|
2015-02-10 01:22:11 +03:00
|
|
|
promise.catch.call promise, (error) ->
|
2015-05-08 21:16:19 +03:00
|
|
|
jasmine.getEnv().currentSpec.fail("Expected promise to be resolved, but it was rejected with: #{error?.message} #{jasmine.pp(error)}")
|
2012-08-28 02:36:36 +04:00
|
|
|
moveOn()
|
|
|
|
|
|
|
|
window.resetTimeouts = ->
|
|
|
|
window.now = 0
|
|
|
|
window.timeoutCount = 0
|
2014-05-21 00:03:44 +04:00
|
|
|
window.intervalCount = 0
|
2012-08-28 02:36:36 +04:00
|
|
|
window.timeouts = []
|
2014-05-21 00:03:44 +04:00
|
|
|
window.intervalTimeouts = {}
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2012-11-17 04:13:08 +04:00
|
|
|
window.fakeSetTimeout = (callback, ms) ->
|
2012-08-28 02:36:36 +04:00
|
|
|
id = ++window.timeoutCount
|
|
|
|
window.timeouts.push([id, window.now + ms, callback])
|
|
|
|
id
|
|
|
|
|
2012-11-17 04:13:08 +04:00
|
|
|
window.fakeClearTimeout = (idToClear) ->
|
2015-04-07 06:45:02 +03:00
|
|
|
window.timeouts = window.timeouts.filter ([id]) -> id isnt idToClear
|
2012-08-28 02:36:36 +04:00
|
|
|
|
2014-04-07 23:51:25 +04:00
|
|
|
window.fakeSetInterval = (callback, ms) ->
|
2014-05-21 00:03:44 +04:00
|
|
|
id = ++window.intervalCount
|
2014-04-07 23:51:25 +04:00
|
|
|
action = ->
|
|
|
|
callback()
|
2014-05-21 00:03:44 +04:00
|
|
|
window.intervalTimeouts[id] = window.fakeSetTimeout(action, ms)
|
|
|
|
window.intervalTimeouts[id] = window.fakeSetTimeout(action, ms)
|
|
|
|
id
|
2014-04-07 23:51:25 +04:00
|
|
|
|
|
|
|
window.fakeClearInterval = (idToClear) ->
|
2014-05-21 00:03:44 +04:00
|
|
|
window.fakeClearTimeout(@intervalTimeouts[idToClear])
|
2014-04-07 23:51:25 +04:00
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
window.advanceClock = (delta=1) ->
|
|
|
|
window.now += delta
|
2012-11-20 03:50:07 +04:00
|
|
|
callbacks = []
|
|
|
|
|
2012-08-28 02:36:36 +04:00
|
|
|
window.timeouts = window.timeouts.filter ([id, strikeTime, callback]) ->
|
|
|
|
if strikeTime <= window.now
|
2012-11-20 03:50:07 +04:00
|
|
|
callbacks.push(callback)
|
2012-08-28 02:36:36 +04:00
|
|
|
false
|
|
|
|
else
|
|
|
|
true
|
|
|
|
|
2012-11-20 03:50:07 +04:00
|
|
|
callback() for callback in callbacks
|