collaboration: statemachine fix test duplication

--- client/ide/test/collaborationstatemachine.test.coffee
+++ client/ide/test/collaborationstatemachine.test.coffee
@@ -24,176 +24,124 @@
   it 'tests Loading state transitions', ->

     machine = newSimpleMachine()
-
     expect(machine.state).to.equal 'Loading'

-    # illegal states
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
+    legalStates = ['NotStarted', 'ErrorLoading', 'Resuming']
+    illegalStates = [
+      'Active', 'Prepared', 'Creating'
+      'ErrorCreating', 'Ending', 'Loading'
+    ]

-    # legal states
-    machine = newSimpleMachine()
-    machine.transition 'NotStarted'
-    expect(machine.state).to.equal 'NotStarted'
-
-    machine = newSimpleMachine()
-    machine.transition 'ErrorLoading'
-    expect(machine.state).to.equal 'ErrorLoading'
-
-    machine = newSimpleMachine()
-    machine.transition 'Resuming'
-    expect(machine.state).to.equal 'Resuming'
+    assertLegalTransitions newSimpleMachine, legalStates
+    assertIllegalTransitions newSimpleMachine, illegalStates

   it 'tests Resuming state transitions', ->

-    machine = resumingMachine()
-    machine.transition 'Active'
-    expect(machine.state).to.equal 'Active'
+    legalStates = ['Active']
+    illegalStates = [
+      'Loading', 'ErrorLoading', 'Resuming', 'NotStarted'
+      'Prepared', 'Creating', 'ErrorCreating', 'Ending'
+    ]

-    # illegal states
-    machine = resumingMachine()
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
+    assertLegalTransitions resumingMachine, legalStates
+    assertIllegalTransitions resumingMachine, illegalStates

   it 'tests ErrorLoading state transitions', ->

-    machine = errorLoadingMachine()
-    machine.transition 'Loading'
-    expect(machine.state).to.equal 'Loading'
+    legalStates = ['Loading']
+    illegalStates = [
+      'Active', 'ErrorLoading', 'Resuming', 'NotStarted'
+      'Prepared', 'Creating', 'ErrorCreating', 'Ending'
+    ]

-    # illegal states
-    machine = errorLoadingMachine()
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
+    assertLegalTransitions errorLoadingMachine, legalStates
+    assertIllegalTransitions errorLoadingMachine, illegalStates

   it 'tests NotStarted state transitions', ->

-    machine = notStartedMachine()
-    machine.transition 'Prepared'
-    expect(machine.state).to.equal 'Prepared'
+    legalStates = ['Prepared']
+    illegalStates = [
+      'Active', 'ErrorLoading', 'Resuming', 'NotStarted'
+      'Loading', 'Creating', 'ErrorCreating', 'Ending'
+    ]

-    # illegal states
-    machine = notStartedMachine()
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
+    assertLegalTransitions notStartedMachine, legalStates
+    assertIllegalTransitions notStartedMachine, illegalStates

   it 'tests Prepared state transitions', ->

-    machine = preparedMachine()
-    machine.transition 'Creating'
-    expect(machine.state).to.equal 'Creating'
+    legalStates = ['Creating']
+    illegalStates = [
+      'Active', 'ErrorLoading', 'Resuming', 'NotStarted'
+      'Loading', 'Prepared', 'ErrorCreating', 'Ending'
+    ]

-    # illegal states
-    machine = preparedMachine()
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
+    assertLegalTransitions preparedMachine, legalStates
+    assertIllegalTransitions preparedMachine, illegalStates

   it 'tests Creating state transitions', ->

-    machine = creatingMachine()
-    machine.transition 'ErrorCreating'
-    expect(machine.state).to.equal 'ErrorCreating'
+    legalStates = ['Active', 'ErrorCreating']
+    illegalStates = [
+      'Creating', 'ErrorLoading', 'Resuming', 'NotStarted'
+      'Loading', 'Prepared', 'Ending'
+    ]

-    machine = creatingMachine()
-    machine.transition 'Active'
-    expect(machine.state).to.equal 'Active'
-
-    # illegal states
-    machine = creatingMachine()
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
+    assertLegalTransitions creatingMachine, legalStates
+    assertIllegalTransitions creatingMachine, illegalStates

   it 'tests ErrorCreating state transitions', ->

-    machine = errorCreatingMachine()
-    machine.transition 'NotStarted'
-    expect(machine.state).to.equal 'NotStarted'
+    legalStates = ['NotStarted', 'Creating']
+    illegalStates = [
+      'ErrorCreating', 'ErrorLoading', 'Resuming', 'Active'
+      'Loading', 'Prepared', 'Ending'
+    ]

-    machine = errorCreatingMachine()
-    machine.transition 'Creating'
-    expect(machine.state).to.equal 'Creating'
-
-    # illegal states
-    machine = errorCreatingMachine()
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
+    assertLegalTransitions errorCreatingMachine, legalStates
+    assertIllegalTransitions errorCreatingMachine, illegalStates

   it 'tests Active state transitions', ->

-    machine = activeMachine()
-    machine.transition 'Ending'
-    expect(machine.state).to.equal 'Ending'
+    legalStates = ['Ending']
+    illegalStates = [
+      'ErrorCreating', 'ErrorLoading', 'Resuming', 'Active'
+      'Loading', 'Prepared', 'NotStarted', 'Creating'
+    ]

-    # illegal states
-    machine = activeMachine()
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
+    assertLegalTransitions activeMachine, legalStates
+    assertIllegalTransitions activeMachine, illegalStates

   it 'tests Ending state transitions', ->

-    # illegal states
-    machine = endingMachine()
-    expect(-> machine.transition 'Creating').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorCreating').to.throw /illegal state transition/
-    expect(-> machine.transition 'Loading').to.throw /illegal state transition/
-    expect(-> machine.transition 'Resuming').to.throw /illegal state transition/
-    expect(-> machine.transition 'ErrorLoading').to.throw /illegal state transition/
-    expect(-> machine.transition 'NotStarted').to.throw /illegal state transition/
-    expect(-> machine.transition 'Prepared').to.throw /illegal state transition/
-    expect(-> machine.transition 'Active').to.throw /illegal state transition/
-    expect(-> machine.transition 'Ending').to.throw /illegal state transition/
+    legalStates = []
+    illegalStates = [
+      'ErrorCreating', 'ErrorLoading', 'Resuming', 'Active'
+      'Loading', 'Prepared', 'NotStarted', 'Creating', 'Ending'
+    ]

+    assertLegalTransitions endingMachine, legalStates
+    assertIllegalTransitions endingMachine, illegalStates
+
+
+assertLegalTransitions = (machineFactoryFn, states) ->
+  states.forEach (state) ->
+    machine = machineFactoryFn()
+    machine.transition state
+    expect(machine.state).to.equal state
+
+assertIllegalTransitions = (machineFactoryFn, states) ->
+  states.forEach (state) ->
+    machine = machineFactoryFn()
+    expect(-> machine.transition state).to.throw /illegal state transition/

 newSimpleMachine = -> new CollabStateMachine

@@ -238,3 +186,4 @@
   machine = activeMachine()
   machine.transition 'Ending'
   return machine
+


MainTabView: Temporary fix for maintabview, which does’t fit with new koding’s workflow

--- client/Main/maintabs/maintabview.coffee
+++ client/Main/maintabs/maintabview.coffee
@@ -96,9 +96,11 @@
     @emit "PaneRemoved"

     if rightPane
-      @appManager.showInstance @appManager.getByView rightPane.mainView
+      if rightPane.mainView
+        @appManager.showInstance @appManager.getByView rightPane.mainView
     else if leftPane
-      @appManager.showInstance @appManager.getByView leftPane.mainView
+      if leftPane.mainView
+        @appManager.showInstance @appManager.getByView leftPane.mainView
     else
       @router.handleRoute "/Activity"


removed another variable from members folder

--- client/members/lib/contentdisplays/profileview.coffee
+++ client/members/lib/contentdisplays/profileview.coffee
@@ -7,7 +7,6 @@
 ProfileContentEditableView = require './profilecontenteditableview'
 remote                     = require('app/remote').getInstance()
 globals                    = require 'globals'
-proxifyUrl                 = require 'app/util/proxifyUrl'
 checkFlag                  = require 'app/util/checkFlag'
 isMine                     = require 'app/util/isMine'
 whoami                     = require 'app/util/whoami'


TerminalSession: with vm creation/removal all vm stack subviews are deleted from start tab

--- client/Terminal/terminalstarttab.coffee
+++ client/Terminal/terminalstarttab.coffee
@@ -10,14 +10,14 @@

     KD.singletons.notificationController.on 'NotificationHasArrived', ({event}) =>
       if event is "VMCreated" or "VMRemoved"
-        @wmWrapper = {}
+
+        @vmWrapper.destroySubViews()
         @viewAppended yes

   viewAppended: (force = no) ->

     super

-    @wmWrapper = {}
     @fetchVMs force
     @prepareMessage()


Fix display bug after bootstrap

Fix display bug after bootstrap

--- client/app/js/views/sidebar_view.coffee
+++ client/app/js/views/sidebar_view.coffee
@@ -32,7 +32,7 @@
     $notifications.removeClass('hidden')

   addBattle: (battle) =>
-    @$(".header_battles, .nav_battles").show()
+    @$(".header_battles, .nav_battles").removeClass("hidden")
     $li = $("""

0


IDEView: add session option to createTerminal

--- client/ide/views/tabview/ideview.coffee
+++ client/ide/views/tabview/ideview.coffee
@@ -90,20 +90,12 @@
   createShortcutsView: ->
     @createPane_ new IDE.ShortcutsView, { name: 'Shortcuts' }

-  createTerminal: (machine, path) ->
-    ideApp = KD.getSingleton('appManager').getFrontApp()
-
-    unless machine
-      {machines} = KD.getSingleton 'computeController'
-      machineId  = ideApp.mountedMachineUId
-
-      machine = m for m in machines when m.uid is machineId
-
-    unless path
-      if ideApp.workspaceData?.rootPath
-        path = ideApp.workspaceData.rootPath
-
-    terminalPane = new IDE.TerminalPane { machine, path }
+  createTerminal: (machine, path, session) ->
+
+    machine ?= @getCurrentMachine()
+    path    ?= @getCurrentWorkspacePath()
+
+    terminalPane = new IDE.TerminalPane { machine, path, session }
     @createPane_ terminalPane, { name: 'Terminal' }

     terminalPane.once 'WebtermCreated', =>
@@ -268,6 +260,7 @@
         delete @menu

   createPlusContextMenu: ->
+
     offset      = @holderView.plusHandle.$().offset()
     offsetLeft  = offset.left - 133
     margin      = if offsetLeft >= -1 then -20 else 12
@@ -281,3 +274,20 @@
     contextMenu = new KDContextMenu options, @getPlusMenuItems()

     contextMenu.once 'ContextMenuItemReceivedClick', -> contextMenu.destroy()
+
+
+  getCurrentWorkspacePath:->
+
+    ideApp = KD.singletons.appManager.getFrontApp()
+
+    if ideApp.workspaceData?.rootPath
+      return ideApp.workspaceData.rootPath
+
+
+  getCurrentMachine:->
+
+    {appManager, computeController} = KD.singletons
+    machineId = appManager.getFrontApp().mountedMachineUId
+    machine = m for m in computeController.machines when m.uid is machineId
+
+    return machine


move running to separate function

move running to separate function

--- src/notebook.coffee
+++ src/notebook.coffee
@@ -312,6 +312,14 @@
       setTimeout ->
         $('html, body').scrollTop top
       , 10
+
+    result_handlers =[
+      ignored,
+      handle_cli_cmd,
+      handle_renderable,
+      handle_lead_node,
+      handle_any_object
+    ]

     output = ($target) ->
       (output) ->
@@ -359,6 +367,15 @@
         @cli.text 'Compiled JavaScript:'
         @cli.source 'javascript', compiled

+      error: (message) ->
+        $pre = $ '
'
+        $pre.text message
+        run_context.output $pre
+
+      display_object: (object) ->
+        for handler in result_handlers
+          return if handler.call run_context, object
+
       value: (value) -> _lead_cli_value: value
       open_file: -> open_file_picker run_context
       export_notebook: -> export_notebook input_cell
@@ -403,28 +420,18 @@

     run_context.cli = cli = bind_cli run_context

-    error = (message) ->
-      $pre = $ '
'
-      $pre.text message
-      run_context.output $pre
-
-    result_handlers =[
-      ignored,
-      handle_cli_cmd,
-      handle_renderable,
-      handle_lead_node,
-      handle_any_object
-    ]
-
-    display_object = (object) ->
-      for handler in result_handlers
-        return if handler.call run_context, object
-
+    run_in_context run_context, string
+
+    scroll_to_result $top
+
+    output_cell
+
+  run_in_context = (run_context, string) ->
     try
       compiled = CoffeeScript.compile(string, bare: true) + "\n//@ sourceURL=console-coffeescript.js"
     catch e
       if e instanceof SyntaxError
-        error "Syntax Error: #{e.message} at #{e.location.first_line + 1}:#{e.location.first_column + 1}"
+        run_context.error "Syntax Error: #{e.message} at #{e.location.first_line + 1}:#{e.location.first_column + 1}"
       else
         run_context.handle_exception e, compiled

@@ -433,13 +440,9 @@
         `with (run_context.cli) { with (run_context.functions) { with (run_context.vars) {`
         result = eval compiled
         `}}}`
-        display_object result
+        run_context.display_object result
       catch e
         run_context.handle_exception e, compiled
-
-      scroll_to_result $top
-
-    output_cell

   opening_run_context = null


unroll approved variable types

unroll approved variable types

--- src/reactive.coffee
+++ src/reactive.coffee
@@ -745,9 +745,15 @@
             [arg1, arg2]
           else if _.isString(arg1) and arg2?
             [mkAtts(arg1), arg2]
-          else if not arg2? and _.isString(arg1) or _.isNumber(arg1) or arg1 instanceof Element or
-              arg1 instanceof RawHtml or arg1 instanceof $ or _.isArray(arg1) or
-              arg1 instanceof ObsCell or arg1 instanceof ObsArray
+          else if not arg2? and
+              _.isString(arg1) or
+              _.isNumber(arg1) or
+              arg1 instanceof Element or
+              arg1 instanceof RawHtml or
+              arg1 instanceof $ or
+              _.isArray(arg1) or
+              arg1 instanceof ObsCell or
+              arg1 instanceof ObsArray
             [{}, arg1]
           else
             [arg1, null]


Reflected to upstream changes

Reflected to upstream changes

--- src/selenium.coffee
+++ src/selenium.coffee
@@ -32,14 +32,15 @@

   _startServer: =>
     deferred = do Q.defer
-    server = (require 'selenium-standalone') stdio: null, @_config.selenium.arguments
-    showLog = @_config.selenium.showLog
-    server.stderr.on 'data', (output) =>
-      @_log output if showLog
-
-      if not @started and output.toString().match /Started.+\.Server/
-        @started = true
-        do deferred.resolve
+    options =
+      spawnOptions: { stdio: null }
+      seleniumArgs: @_config.selenium.arguments
+    (require 'selenium-standalone').start options, (err, child) =>
+      showLog = @_config.selenium.showLog
+      return deferred.reject err if err
+      child.stderr.on 'data', (output) => @_log output if showLog
+      @started = true
+      do deferred.resolve

     deferred.promise

@@ -56,4 +57,3 @@
     line = line.replace /[\d:.\s]{13}\w+\s-\s(.+)/, '$1'

     @logger[level] "Selenium: #{line}"
-


renderDOM API for rendering DOM inputs into SVG

--- src/svgtiler.coffee
+++ src/svgtiler.coffee
@@ -658,6 +658,15 @@

 class Mappings
   constructor: (@maps = []) ->
+  @from: (data) ->
+    if data instanceof Mappings
+      data
+    else if data instanceof Mapping
+      new Mappings [data]
+    else if Array.isArray data
+      new Mappings data
+    else
+      throw new SVGTilerException "Could not convert into Mapping(s): #{data}"
   push: (map) ->
     @maps.push map
   lookup: (key) ->
@@ -1113,6 +1122,53 @@
   '.css': CSSStyle
   '.styl': StylusStyle

+renderDOMDefaults =
+  filename: 'drawing.asc'
+  keepParent: false
+  keepClass: false
+
+renderDOM = (mappings, elts, options) ->
+  mappings = Mappings.from mappings
+  if typeof elts == 'string'
+    elts = document.querySelectorAll elts
+  else if elts instanceof HTMLElement
+    elts = [elts]
+  option = (key) ->
+    elt.dataset[key] ? options?[key] ? renderDOMDefaults[key]
+  boolOption = (key) ->
+    switch value = option key
+      #when 'true', 'on', 'yes'
+      #  true
+      when 'false', 'off', 'no'#, ''
+        false
+      else
+        Boolean value
+  oldUseHref = Drawing.useHref
+  Drawing.useHref = true
+  try
+    for elt from elts
+      elt.style.whiteSpace = 'pre'
+      filename = option 'filename'
+      drawing = Input.recognize filename, elt.innerText
+      if drawing instanceof Drawing
+        dom = drawing.renderSVGDOM(mappings).documentElement
+        if boolOption 'keepParent'
+          elt.innerHTML = ''
+          elt.appendChild dom
+        else
+          elt.replaceWith dom
+          if boolOption 'keepClass'
+            dom.setAttribute 'class', elt.className
+      else
+        console.warn "Parsed element with filename '#{filename}' into #{drawing.constructor.name} instead of Drawing:", elt
+        dom = null
+      input: elt
+      output: dom
+      drawing: drawing
+      filename: filename
+  finally
+    Drawing.useHref = oldUseHref
+
 sanitize = true
 bufferSize = 16*1024

@@ -1333,7 +1389,7 @@
   Style, CSSStyle, StylusStyle,
   extensionMap, Input, Mappings, Context,
   SVGTilerException, SVGNS, XLINKNS, escapeId,
-  main, convertSVG,
+  main, convertSVG, renderDOM, renderDOMDefaults,
   version: metadata.version
 }
 module?.exports = svgtiler


Add infeedl--no-scroll to html as well

Add infeedl--no-scroll to html as well

--- src/creative.coffee
+++ src/creative.coffee
@@ -18,7 +18,7 @@
   _append_embedded: ->
     @loader = document.createElement("div")
     @loader.setAttribute("class", "infeedl--embedded--loader")
-    Infeedl.$("body").addClass("infeedl--no-scroll")
+    Infeedl.$("html, body").addClass("infeedl--no-scroll")
     Infeedl.$("body")[0].appendChild(@loader)

     @wrapper = document.createElement("div")
@@ -69,7 +69,7 @@

     Infeedl.$(".infeedl--embedded-close").remove()
     Infeedl.$(".infeedl--embedded-wrapper").remove()
-    Infeedl.$("body").removeClass("infeedl--no-scroll")
+    Infeedl.$("html, body").removeClass("infeedl--no-scroll")
     # console?.log("[INFEEDL] Creative ##{@creative.id}: embedded removed")

   _interpolations: ->


The action silo to use is selected relative to each site visited.

--- lib/action.coffee
+++ lib/action.coffee
@@ -31,10 +31,6 @@
       unless utilities.nameIsInArray(urlExtension,meta._allowed_url_extensions)
         return next()

-  actions= meta._actions
-  extLookup= actions[if req.method is 'HEAD' then 'GET' else req.method]
-  extSilo = extLookup[urlExtension] ? extLookup['*']
-
   malifi.next_layer= next_layer= next
   siteindex= 0
   nextSite= ()=>
@@ -42,6 +38,9 @@
     unless root
       next_layer()
     else
+      actions= malifi.meta_lookup(join(root,malifi.path.relative))._actions
+      extLookup= actions[if req.method is 'HEAD' then 'GET' else req.method]
+      extSilo = extLookup[urlExtension] ? extLookup['*']
       traverseActionList = (actionList)=>
         return nextSite() unless actionList?
         i= 0


watch(something).on('changed') was catching all the possible events anyway


Dropzones are properly stored in the element again.

Fixes #346

--- src/dropzone.coffee
+++ src/dropzone.coffee
@@ -415,7 +415,7 @@
     Dropzone.instances.push @

     # Put the dropzone inside the element itself.
-    element.dropzone = @
+    @element.dropzone = @

     elementOptions = Dropzone.optionsForElement(@element) ? { }


kernel: Honour transport and ip in config-manager

--- lib/kernel.coffee
+++ lib/kernel.coffee
@@ -73,9 +73,10 @@
         @controlSocket.identity = 'control' + @language + process.pid
         @ioSocket.identity = 'sub' + @language + process.pid

-        @shellSocket.connect('tcp://127.0.0.1:' + @config.shell_port)
-        @controlSocket.connect('tcp://127.0.0.1:' + @config.control_port)
-        @ioSocket.connect('tcp://127.0.0.1:' + @config.iopub_port)
+        address = "#{ @config.transport }://#{ @config.ip }:"
+        @shellSocket.connect(address + @config.shell_port)
+        @controlSocket.connect(address + @config.control_port)
+        @ioSocket.connect(address + @config.iopub_port)
         @ioSocket.subscribe('')

         @shellSocket.on 'message', @onShellMessage.bind(this)


return if package is disabled. fixes #82

--- lib/linter.coffee
+++ lib/linter.coffee
@@ -10,6 +10,7 @@

   constructor: (editor) ->
     @_manager = atom.packages.getLoadedPackage('atom-ternjs').mainModule.manager
+    return unless @_manager
     super(editor)

   lintFile: (filePath, callback) ->


Switch to microsecond in logger

Switch to microsecond in logger

--- lib/logger.coffee
+++ lib/logger.coffee
@@ -1,16 +1,18 @@
-Logger = require "devnull"
+Logger    = require "devnull"
+microtime = require "microtime"

 logLevel = process.env.LOG_LEVEL ? 6
 logger = new Logger timestamp: false, level: logLevel

 logger.http = (req, res, next) ->
   end = res.end
-  req._startTime = new Date
+  req._startTime = microtime.now()
   res.end = (chunk, encoding) ->
     status   = res.statusCode
     len      = parseInt(res.getHeader('Content-Length'), 10)
-    duration = new Date - req._startTime;
-    line = "#{req.method} #{req.originalUrl} #{res.statusCode} #{duration}ms #{len}"
+    len      = if isNaN len then "" else "- #{len}"
+    duration = (microtime.now() - req._startTime) / 1000000
+    line = "#{req.method} #{req.originalUrl} #{res.statusCode} #{duration}s #{len}"
     logger.log "http", line
     res.end = end
     res.end chunk, encoding


comments against ugly coffee syntax

comments against ugly coffee syntax

--- server/app/controllers/measurement.coffee
+++ server/app/controllers/measurement.coffee
@@ -6,7 +6,9 @@
 module.exports = (app) ->
   app.use '/measurement/', router

+# create a new measurement instance on POST /measurement/
 router.post '/', (req,res,next) ->
+  # find a corresponding close measurement
   Measurement.find
     location:
       $geoNear:
@@ -23,7 +25,7 @@
       return
     measurement = {}
     if measurements.length == 0
-      console.log('Adding new measurement entry.')
+      # add a new measurement
       measurement = new Measurement(
         type: req.body.type
         signalDBm: req.body.signalDBm
@@ -33,6 +35,7 @@
           coordinates: [req.body.lat, req.body.lng]
       )
     else
+      # replace the measurement
       console.log('Replacing available measurement entry.')
       measurement = measurements[0]
       measurement.signalDBm = req.body.signalDBm
@@ -45,7 +48,7 @@
       else
         res.end()

-
+# get measurements for wifi access points with GET /measurement/wifi
 router.get '/wifi', (req, res, next) ->
   points = []
   if req.query.nelat is undefined or req.query.swlat is undefined or req.query.nelng is undefined or req.query.swlng is undefined
@@ -66,6 +69,7 @@
     res.json(points)
   )

+# get measurements for signal strength with GET /measurement/signal
 router.get '/signal', (req, res, next) ->
   points = []
   if req.query.nelat is undefined or req.query.swlat is undefined or req.query.nelng is undefined or req.query.swlng is undefined
@@ -83,4 +87,5 @@
       return
     for point in data
       points.push([point.location.coordinates[0], point.location.coordinates[1],  parseFloat(point.signalDBm) / 31.0])
-    res.json(points)+    res.json(points)
+


Fix filtering

Fix filtering

--- conda_ui/static/conda_ui/history.coffee
+++ conda_ui/static/conda_ui/history.coffee
@@ -35,7 +35,7 @@

                     for op in ["install", "remove", "upgrade", "downgrade"]
                         for diff_item in history_item[op]
-                            if @pkgs.do_filter(diff_item.name)
+                            if @pkgs.do_filter(if typeof diff_item is "object" then diff_item.new else diff_item)
                                 continue

                             switch op


fix bind this

fix bind this

--- src/formdata.coffee
+++ src/formdata.coffee
@@ -37,7 +37,7 @@
     _readBlobAsArrayBuffer: ()->
       reader = new FileReader()
       reader.readAsArrayBuffer(@souce)
-      reader.onload = ()->
+      reader.onload = ()=>
         @_readArrayBufferAsString(reader.result)

     _readBlobAsBinary: ()->


Correctly fire viewDidDisappear when a view is dying.

--- src/view/view.coffee
+++ src/view/view.coffee
@@ -113,7 +113,7 @@

   removeFromParentNode: ->
     node = @get('node')
-    isInDOM = document.body.contains(node)
+    isInDOM = @wasInDOM ? document.body.contains(node)

     @propagateToSubviews('viewWillDisappear') if isInDOM

@@ -212,6 +212,8 @@
       return

     @fire('destroy')
+
+    @wasInDOM = document.body.contains(@node)
     Batman.DOM.destroyNode(@node)

     @forget()


replace buffer with require string

replace buffer with require string

--- lib/napalm.coffee
+++ lib/napalm.coffee
@@ -43,8 +43,22 @@
     if atom.config.get 'napalm.github.password'
       if editor = atom.workspace.getActiveTextEditor()
         selection = editor.getSelectedText()
+        useSelection = true
+        if selection.length is 0
+          useSelection = false
+          selection = editor.getText()
         ast = Acorn.parse selection
-        if func = @findFunction(ast)
+        removed = 0
+        for func in @findFunctions ast
+          requireString = "var #{func.name} = require('#{atom.config.get 'napalm.github.username'}-#{func.name}')"
+          if useSelection
+            editor.setTextInBufferRange editor.getSelectedBufferRange(), requireString
+          else
+            file = editor.getText()
+            sub = file.substr func.parent.start - removed, func.parent.end - func.parent.start
+            removed += sub.length - requireString.length
+            file = file.replace sub, requireString
+            editor.setText file
           console.log window.func = func
           text = Escodegen.generate(func.node)
           console.log("module.exports = " + text)
@@ -52,24 +66,26 @@
       @tried = true
       @modalPanel.show()

-    Github.updateFile('test', 'lol.js', 'console.log("YUHTLHHRUPWFP")')
-    .then (body) ->
-      console.log 'Github successfully processed with response: ', body
-    .catch (error) ->
-      console.log 'Github failed with error: ', error
+    # Github.updateFile('test', 'lol.js', 'console.log("YUHTLHHRUPWFP")')
+    # .then (body) ->
+    #   console.log 'Github successfully processed with response: ', body
+    # .catch (error) ->
+    #   console.log 'Github failed with error: ', error

-  findFunction: (node) ->
+  findFunctions: (node) ->
     if node.type is 'FunctionDeclaration'
       name = node.id.name
       node.id.name = ''
-      return name: name, node: node
+      return name: name, node: node, parent: node
     else if node.type is 'VariableDeclaration' and node.declarations.length == 1
       declaration = node.declarations[0]
       if declaration.type is 'VariableDeclarator' and declaration.init.type is 'FunctionExpression'
-        return name: declaration.id.name, node: declaration.init
+        return name: declaration.id.name, node: declaration.init, parent: node
     else if node.type is 'Program'
+      results = []
       for n in node.body
-        if result = @findFunction(n)
-          return result
+        if result = @findFunctions(n)
+          results.push result
+      return results

     return null


Remove gratuitous returns from object.coffee

--- lib/object.coffee
+++ lib/object.coffee
@@ -10,13 +10,13 @@
     @convert: (object) ->
         if Array.isArray object
             items = (PDFObject.convert e for e in object).join(' ')
-            return "[" + items + "]"
+            "[" + items + "]"

         else if typeof object is 'string'
-            return '/' + object
+            '/' + object

         else if object?.isString
-            return '(' + object + ')'
+            '(' + object + ')'

         else if object instanceof PDFReference
             return object.toString()
@@ -36,10 +36,10 @@
                 out.push '/' + key + ' ' + PDFObject.convert(val)

             out.push '>>'
-            return out.join '\n'
+            out.join '\n'

         else
-            return '' + object
+            '' + object

     @s: (string) ->
         string = string.replace(/\\/g, '\\\\\\\\')
@@ -48,7 +48,7 @@
             .replace(/</g, '<')
             .replace(/>/g, '>')
             .replace(/&/g, '&')
-
+
         isString: yes
         toString: -> string


add 1 to javascript month for pdf month num

--- lib/object.coffee
+++ lib/object.coffee
@@ -64,7 +64,7 @@

     else if object instanceof Date
       '(D:' + pad(object.getUTCFullYear(), 4) +
-              pad(object.getUTCMonth(), 2) +
+              pad(object.getUTCMonth() + 1, 2) +
               pad(object.getUTCDate(), 2) +
               pad(object.getUTCHours(), 2) +
               pad(object.getUTCMinutes(), 2) +


adjusting regex to better handle tags with no extra data, and braces inside of extraData

--- lib/parser.coffee
+++ lib/parser.coffee
@@ -73,7 +73,7 @@
     * @category Tag
     * @package Regex
   ###
-  @TAG_SPLIT = /@(\w+)\s(?:{(.+)})?\s?(.+?(?=\s\(|\n|$))?\s?(?:\((.+)\))?/g
+  @TAG_SPLIT = /@(\w+)\s?(?:{([^\s|.]+)})?\s?(.+?(?=\s\(|\n|$))?\s?(?:\((.+)\))?/g

 ###*
  * @desc This class contains all of the regular expressions used by Parser.
@@ -279,7 +279,7 @@
     * @category Function
     * @package TagParser
     * @internal
-    * @param {object} commentData (lineNumber, endLineNumber, file)
+    * @param {object} commentData ({lineNumber, endLineNumber, file})
     * @return {object} The new comment object
   ###
   handleComment: (commentData) ->
@@ -314,6 +314,8 @@
         type: tagType
         basicInfo: tagBasic
         extendedInfo: tagExtDesc
+
+      console.log tagData

       results.push tagData


Add destroy method

Add destroy method

--- src/workspace.coffee
+++ src/workspace.coffee
@@ -38,6 +38,9 @@
           @open(atom.config.getUserConfigPath())
         when 'atom://.atom/init-script'
           @open(atom.getUserInitScriptPath())
+
+  destroy: ->
+    @unsubscribe()

   # Called by the Serializable mixin during deserialization
   deserializeParams: (params) ->


Remove redundant non-public documentation

--- src/workspace.coffee
+++ src/workspace.coffee
@@ -54,13 +54,11 @@
     paneContainer: @paneContainer.serialize()
     fullScreen: atom.isFullScreen()

-  # Return and add the given {Editor}.
   addEditor: (editor) ->
     @editors.push editor
     @emit 'editor-created', editor
     editor

-  # Return and removes the given {Editor}.
   removeEditor: (editor) ->
     remove(@editors, editor)


Flip order of `move` arguments

Flip order of `move` arguments

Makes this new API call (likely private anyway) consistent with others.

--- src/svgtiler.coffee
+++ src/svgtiler.coffee
@@ -1184,7 +1184,7 @@
     @tiles =
       for row, i in @drawing.keys
         for key, j in row
-          context.move i, j
+          context.move j, i
           tile = @mappings.lookup key, context
           unless tile?
             missing.add key
@@ -1493,8 +1493,9 @@
     #@keys = @drawing.keys
     #@filename = @drawing.filename
     #@subname = @drawing.subname
-    @move i, j if i? and j?
-  move: (@i, @j) ->
+    @move j, i if i? and j?
+  move: (@j, @i) ->
+    ## Change location in-place
     @key = @drawing.keys[@i]?[@j]
   at: (j, i) ->
     if i < 0


Set default to true

Set default to true

--- lib/script.coffee
+++ lib/script.coffee
@@ -7,7 +7,7 @@
     enableExecTime:
       title: 'Output the time it took to execute the script'
       type: 'boolean'
-      default: false
+      default: true

   scriptView: null
   scriptOptionsView: null


emit a warning if given the wrong type

emit a warning if given the wrong type

--- lib/sentry.coffee
+++ lib/sentry.coffee
@@ -36,8 +36,8 @@

   error: (err, logger, culprit, extra = {}) =>
     unless err instanceof Error
-      console.error 'error must be an instance of Error', err
       err = new Error "WARNING: err not passed as Error! #{JSON.stringify(err, null, 2)}"
+      @emit 'warning', new Error err
     data =
       message: err.message # smaller text that appears right under culprit (and shows up in HipChat)
       logger: logger


just log re-assigns

just log re-assigns

--- lib/server.coffee
+++ lib/server.coffee
@@ -491,7 +491,7 @@
 									currentjob._otherhost ||= {}
 									currentjob._otherhost[host] = true
 								else
-									console.log jobId,currentjob._takenby, "->",host
+									console.log jobId,currentjob._takenby, "->",host if currentjob._takenby?
 									if currentjob._status is "onqueue" then forceQueuereSync = true
 									currentjob._takenby = host
 									currentjob._status = "working"
@@ -500,6 +500,7 @@
 							else # create a ghosth job
 								console.log "creating ghost job",jobId,"for", host
 								workque.push {
+									_takenby : host,
 									_id : jobId,
 									_rev : jobRv,
 									_status : "working",


fix a thing

fix a thing

--- lib/worker.coffee
+++ lib/worker.coffee
@@ -28,7 +28,7 @@
     @gearman.sendCommand "WORK_WARNING", @handle, warning

   done: (err) ->
-    return @complete() if not err?
+    return @success() if not err?
     @warn err
     @error()


removed unused function

removed unused function

--- src/jangular.coffee
+++ src/jangular.coffee
@@ -60,11 +60,6 @@

 flush = ->
   http_backend().flush()
-
-grab_data = (promise) ->
-  _actual_data = undefined
-  promise.then (data) -> _actual_data = data
-  _actual_data

 assert_unwrapped_data = (actual_data, expected_data) ->
   result =


JS: bower-concat.

JS: bower-concat.

--- src/js/index.coffee
+++ src/js/index.coffee
@@ -22,6 +22,12 @@
 				"#{@htdocs_prefix}js/*.js"
 			]

+	unless gf.hasSection 'bower'
+		gf.addSection 'bower',
+			main:
+				dest: "#{@htdocs_prefix}build/_bower.js"
+				exclude: 'jquery'
+
 	unless gf.hasSection 'traceur_build'
 		gf.addSection 'traceur_build',
 			options:
@@ -29,6 +35,7 @@
 				freeVariableChecker: false
 			main:
 				src: [
+					'<%= bower.main.dest %>'
 					"#{@htdocs_prefix}tamia/tamia/traceur-rt-light.js"
 					"#{@htdocs_prefix}tamia/tamia/tamia.js"
 					"#{@htdocs_prefix}tamia/tamia/component.js"
@@ -63,4 +70,4 @@
 	@copyIfNot '.jshintrc'

 Generator::dependencies = ->
-	@installFromNpm ['grunt', 'matchdep', 'grunt-contrib-jshint', 'grunt-traceur-build', 'grunt-contrib-uglify', 'grunt-contrib-watch']
+	@installFromNpm ['grunt', 'matchdep', 'grunt-contrib-jshint', 'grunt-traceur-build', 'grunt-contrib-uglify', 'grunt-contrib-watch', 'grunt-bower-concat']


menus: ToWatch: Fix items not being correctly marked to have the next episode listed

--- src/js/menus.coffee
+++ src/js/menus.coffee
@@ -169,7 +169,7 @@
               2000
             )

-            if element.isNextEpisodeListed
+            if data.isNextEpisodeListed
               return
             trakttv.fetchShowProgress data.showID,
               (err, show) =>
@@ -178,7 +178,7 @@
                 console.log "RELOADED ShowID: #{data.showID}"
                 if not isNextEpisodeForItemAired(show)
                   return
-                element.isNextEpisodeListed = true
+                data.isNextEpisodeListed = true

                 newItem = @_createItem(
                   data.showID


Add test for handle multiple initialisations.

--- tests/specs/SuperfishTest.coffee
+++ tests/specs/SuperfishTest.coffee
@@ -99,3 +99,13 @@
       $liHasUl.superfish('hide', true)
       expect($submenu).toBeHidden()
       expect($liHasUl).not.toBe '.sfHover'
+
+
+  describe "initialisation", ->
+    it "should fail silently if already initialised", ->
+      $menu.superfish('destroy')
+      init_count = 0
+      $.fn.superfish.defaults.onInit = -> init_count++
+      $menu.superfish().superfish()
+      expect(init_count).toEqual 1
+      $.fn.superfish.defaults.onInit = $.noop


edit docs

edit docs

--- src/util/obj.coffee
+++ src/util/obj.coffee
@@ -7,10 +7,10 @@
     # Create function which forwards to given constructor function.
     F = (args) ->
       constructor.apply @, args
-      @ # overwrite contructor return value.
+      @ # overwrite constructor return value
     # Set functions prototype field.
     F.prototype = prototype
-    # Create function which forwards to given constructor while setting prototype to new object.
+    # Create function which creates a new object with the given prototype and initializes with the given constructor.
     f = ->
       new F arguments
     # Add static fields to function.


Remove 'he' as supported language for now, not enough translations


keep it simple stupid

keep it simple stupid

--- static/index.coffee
+++ static/index.coffee
@@ -138,9 +138,8 @@
         }
       filesHtml = files.map ({date, time, filename}) ->
         return ''  unless filename?.length
-        "
#{date} #{time} #{filename}
"
+        "#{date} #{time} #{filename}\n"
       filesHtml = filesHtml.join ''
-      filesHtml = "
#{filesHtml}
"
       $list.html(filesHtml).css 'display', ''

     fail = () ->


activityticker : lower the ticker item size to 5 to avoid maximum call stack exceeded error.

--- workers/social/lib/social/models/activityticker.coffee
+++ workers/social/lib/social/models/activityticker.coffee
@@ -80,7 +80,7 @@
           group   : groupSlug

       relOptions  =    # do not fetch more than 15 at once
-        limit     : 10 # Math.min options.limit ? 15, 15
+        limit     : 5  # Math.min options.limit ? 15, 15
         sort      : timestamp : -1

       Relationship.some relSelector, relOptions, (err, relationships) ->


onboarding: misspelling fix

onboarding: misspelling fix

--- workers/social/lib/social/models/custompartials.coffee
+++ workers/social/lib/social/models/custompartials.coffee
@@ -65,8 +65,8 @@
     @checkPermission client, (err, res)=>
       return callback err if err

-      isPublishing     = data.isActive and not @isActive
-      data.publishedAt = new Date()  if isPublishing
+      isPublished      = data.isActive and not @isActive
+      data.publishedAt = new Date()  if isPublished

       @update {$set:data}, callback


Optimize startup, defer utils require until needed

--- lib/main.coffee
+++ lib/main.coffee
@@ -1,7 +1,6 @@
 {CompositeDisposable} = require 'atom'
 toggleStaged = GitDiffStagedView = repositoryForPath = null
 repositoryForEditor = null
-{diffAtLine} = require "./utils"

 getGitPath = ->
   git = atom.config.get("git-diff-staged.gitPath")
@@ -52,6 +51,7 @@

 _getHunkLines = (editor, {row})->
   return [-1, -1] unless d = getDiffs(editor)
+  {diffAtLine} = require "./utils"
   return [-1, -1] unless d = diffAtLine d, row
   return [d.newStart, d.newStart + d.newLines - (d.newLines isnt 0)]


Fix issues with suite reset

Fix issues with suite reset

--- source/javascripts/suite.js.coffee
+++ source/javascripts/suite.js.coffee
@@ -62,6 +62,7 @@
         .append($('<div />').attr('id', 'modal_layer'))
     reset: ->
       $('body > *').not("[id^='qunit-']").remove()
+      @$fixture = false
     use: (selector) ->
       @$fixture = $(selector)
       @$fixture.siblings().remove()
@@ -72,9 +73,9 @@
           overlay: 0
       if !@$fixture then @use('.link_trigger')
       @$trigger = $el || @$fixture.find('a').eq(0)
-      $(@$trigger).windoze($.extend(defaults, opts))
-
-  QUnit.testDone -> tester.reset()
+      @$trigger.windoze($.extend(defaults, opts))
+
+  QUnit.testDone $.proxy(tester.reset, tester)

   module 'Element Creation'

@@ -254,4 +255,5 @@
     equal wdz.delegate, true, 'delegate is set to true'
     equal wdz.init_shown, true, 'init_shown is set to true'
     equal wdz.container, '#foo', 'container is set to #foo'
+
 )(jQuery)


nestIt function added but not used.

nestIt function added but not used.

--- cakes.coffee
+++ cakes.coffee
@@ -80,6 +80,14 @@
 exports.Scenario = createScenario(['whitespace', 'label', 'style', 'pending'])

+nestIt = (message, callback, color='green')->  # So nesting works inside of Its
+	mocha.it message, callback  # Not using nesting, forgot what it does.
+	###
+	mocha.describe '◦'[color], ->
+		mocha.it message, callback
+	###
+
+
 createGiven = (options)->
 	return (message, callback)->
 		if 'label' in options
@@ -88,7 +96,7 @@
 				label = label.yellow
 			message = label+message

-		mocha.it message, callback
+		nestIt message, callback

 exports.Given = createGiven(['label', 'labelcolor'])

@@ -100,7 +108,7 @@
 				label = label.yellow
 			message = label+message

-		mocha.it message, callback
+		nestIt message, callback

 exports.When = createWhen(['label', 'labelcolor'])

@@ -112,7 +120,7 @@
 				label = label.yellow
 			message = label+message

-		mocha.it message, callback
+		nestIt message, callback

 exports.Then = createThen(['label', 'labelcolor'])

@@ -124,7 +132,7 @@
 				label = label.grey
 			message = label+message

-		mocha.it message, callback
+		nestIt message, callback, 'black'

 exports.And = createAnd(['label', 'labelcolor'])

@@ -136,7 +144,7 @@
 				label = label.grey
 			message = label+message

-		mocha.it message, callback
+		nestIt message, callback, 'black'

 exports.But = createBut(['label', 'labelcolor'])


Improvements to polling for bid placement

--- apps/auction/client/bid_form.coffee
+++ apps/auction/client/bid_form.coffee
@@ -10,7 +10,7 @@
 module.exports = class BidForm extends ErrorHandlingForm

   timesPolledForBidPlacement: 0
-  maxTimesPolledForBidPlacement: 8
+  maxTimesPolledForBidPlacement: 6

   events:
     'click .registration-form-content .avant-garde-button-black' : 'placeBid'
@@ -48,7 +48,9 @@
         max_bid_amount_cents : @getBidAmount()
       bidderPosition.save null,
         success   : =>
-          @pollForBidPlacement(@model.get('minimum_next_bid_cents'))
+          _.delay =>
+            @pollForBidPlacement(@saleArtwork.get('minimum_next_bid_cents'))
+          , 1000
         error     : @showError
     else
       @showError "Your bid must be higher than #{@saleArtwork.minBid()}"
@@ -59,10 +61,10 @@
         if @saleArtwork.get('highest_bid_amount_cents') >= minimumBidAmountInCents or @timesPolledForBidPlacement > @maxTimesPolledForBidPlacement
           @showSuccessfulBidMessage()
         else
+          @timesPolledForBidPlacement = @timesPolledForBidPlacement + 1
           _.delay =>
             @pollForBidPlacement minimumBidAmountInCents
           , 1000
-        @timesPolledForBidPlacement = @timesPolledForBidPlacement + 1

   showSuccessfulBidMessage: =>
     window.location = @saleArtwork.artwork().bidSuccessUrl()


sd missing

sd missing

--- apps/gallery_insights/routes.coffee
+++ apps/gallery_insights/routes.coffee
@@ -1,8 +1,8 @@
 request = require 'superagent'
-{ MAILCHIMP_KEY } = require '../../config'
+{ MAILCHIMP_KEY, CURRENT_USER, GALLERY_INSIGHTS_LIST } = require '../../config'

 @index = (req, res) ->
-  email = res.locals.sd.CURRENT_USER?.email
+  email = res.locals.CURRENT_USER?.email
   subscribed email, (cb) ->
     res.locals.sd.MAILCHIMP_SUBSCRIBED = if cb then 'subscribed' else 'unsubscribed'
     res.render 'index'
@@ -11,6 +11,6 @@
   request.get('https://us1.api.mailchimp.com/2.0/lists/member-info')
     .query(
       apikey: MAILCHIMP_KEY
-      id: sd.GALLERY_INSIGHTS_LIST
+      id: GALLERY_INSIGHTS_LIST
     ).query("emails[0][email]=#{email}").end (err, response) ->
       callback response.body.success_count is 1


Fixing rm's error message.

Fixing rm's error message.

--- browser/frontend.coffee
+++ browser/frontend.coffee
@@ -395,21 +395,21 @@
     if args[0] == '*'
       node.fs.readdir '.', (err, fnames) ->
         if err
-          controller.message "Could not remove '.': #{err}", 'error'
+          controller.message "Could not remove '.': #{err}\n", 'error'
         else
           for fname in fnames
             completed = 0
             node.fs.stat fname, (err, fstat) ->
               if err
-                controller.message "Could not remove '.': #{err}", 'error'
+                controller.message "Could not remove '.': #{err}\n", 'error'
               else if fstat.is_directory
-                controller.message "ERROR: '#{fname}' is a directory.", 'error'
+                controller.message "ERROR: '#{fname}' is a directory.\n", 'error'
               else
                 node.fs.unlink fname, (err) ->
-                  if err then controller.message "Could not remove file: #{err}", true
+                  if err then controller.message "Could not remove file: #{err}\n", 'error', true
                   if ++completed is fname.length then controller.reprompt()
     else node.fs.unlink args[0], (err) ->
-      if err then controller.message "Could not remove file: #{err}", true
+      if err then controller.message "Could not remove file: #{err}\n", 'error', true
       controller.reprompt()
     return null
   emacs: -> "Try 'vim'."


Update test

Update test

--- spec/PasswordValidationSpec.coffee
+++ spec/PasswordValidationSpec.coffee
@@ -41,7 +41,7 @@
   it 'dynamically add hat', ->
     input.value = 'muffin'
     pv = new PasswordValidation input
-    pv.validations.includes.hat = 'hat'
+    pv.set 'validations', includes: { hat: 'hat' }

     expect(pv.validate()).toContain { include: ['hat'] }


prevent selection when clicking on bar anchors

--- src/scripts/graph/Items.coffee
+++ src/scripts/graph/Items.coffee
@@ -147,10 +147,20 @@
       bar.selectAll('.bar-anchor--left')
         .filter(barWithStartAndEnd)
         .attr("x", (d) -> return self.timeline.x(d.start * 1000) - 1)
+        .on('mousedown', () ->
+          # Don't trigger mousedown on linescontainer else
+          # it create the selection rectangle
+          d3.event.stopPropagation()
+        )

       bar.selectAll('.bar-anchor--right')
         .filter(barWithStartAndEnd)
         .attr("x", (d) -> return self.timeline.x(d.end * 1000) - 1)
+        .on('mousedown', () ->
+          # Don't trigger mousedown on linescontainer else
+          # it create the selection rectangle
+          d3.event.stopPropagation()
+        )

       bar.selectAll('.bar')
         .filter(barWithStartAndEnd)


Apply syntax highlighting to Markdown previews

--- app/assets/javascripts/dropzone_input.js.coffee
+++ app/assets/javascripts/dropzone_input.js.coffee
@@ -167,6 +167,7 @@
           dataType: "json"
         ).success (data) ->
           preview.html data.body
+          preview.syntaxHighlight()

           renderReferencedUsers data.references.users


fix(user): fixed user model queries

fix(user): fixed user model queries

--- vue/src/shared/models/user_model.coffee
+++ vue/src/shared/models/user_model.coffee
@@ -34,12 +34,12 @@

   groups: ->
     @recordStore.groups.collection.chain().
-      find(id: { $in: @groupIds() }, archivedAt: null).
+      find(id: { $in: @groupIds() }, archivedAt: {'$exists': false}).
       simplesort('fullName').data()

   formalGroups: ->
     @recordStore.groups.collection.chain().
-      find(id: { $in: @groupIds() }, type: "FormalGroup", archivedAt: null).
+      find(id: { $in: @groupIds() }, type: "FormalGroup", archivedAt: {'$exists': false}).
       simplesort('fullName').data()

   adminGroups: ->


Capture originalText from the button that's been clicked, not from the array of all possible date-picker buttons.

Fixes #906

--- app/assets/javascripts/append_date.js.coffee
+++ app/assets/javascripts/append_date.js.coffee
@@ -10,12 +10,11 @@

   href = el.attr('href')

-  originalText = el.text()
-
   el.click (e) ->
     e.stopPropagation()
     e.preventDefault()

+    originalText = $(this).text()
     $(this).text('Confirm without date')

     $(this).bind('click.confirm', (e) ->


starting on obj-based destructuring assignments


Attempt to fix the other part of #149

Attempt to fix the other part of #149

--- app/assets/javascripts/channels/posts.coffee
+++ app/assets/javascripts/channels/posts.coffee
@@ -3,6 +3,7 @@

 $(document).on 'turbolinks:load', ->
   if location.pathname == '/posts'
+    App.posts.unsubscribe()
     App.posts = App.cable.subscriptions.create "PostsChannel",
       received: (data) ->
         $('table#posts-index-table tbody').prepend(data['row'])
@@ -11,6 +12,7 @@
           num_unseen_posts++
           document.title = "(#{num_unseen_posts}*) Recent posts - metasmoke"
   else if /^\/post\/(\d*)(\/)?$/.test(location.pathname)
+    App.posts.unsubscribe()
     App.posts = App.cable.subscriptions.create { channel: "PostsChannel", post_id: location.pathname.match(/^\/post\/(\d*)(\/)?$/)[1] },
       received: (data) ->
         $('strong.post-feedbacks').prepend(data['feedback'])


units: removed EUR, please use euro

units: removed EUR, please use euro

--- app/assets/javascripts/lib/models/metric.coffee
+++ app/assets/javascripts/lib/models/metric.coffee
@@ -8,7 +8,6 @@
       when "PJ"
         u = "joules"
         power += 3
-      when "EUR" then u = "euro"
       when "mln_euro"
         u = "euro"
         power += 2


Use nvd3 interactive guideline not voronoi tooltip

--- app/assets/javascripts/matches/goldxp.js.coffee
+++ app/assets/javascripts/matches/goldxp.js.coffee
@@ -9,6 +9,9 @@
     generate: ->
       id = '#chart'
       chart = nv.models.lineChart()
+
+      chart.tooltips(true)
+      chart.useInteractiveGuideline(true)

       # http://stackoverflow.com/a/11287084/751774
       formatTime = d3.time.format "%H:%M"


adding tap row to recent products

adding tap row to recent products

--- app/assets/javascripts/mobile/_mobile.js.coffee
+++ app/assets/javascripts/mobile/_mobile.js.coffee
@@ -1,6 +1,6 @@
 window.templates = {}

-if gon.page is 'stores_show' or gon.page is 'products_show'
+if gon.page is 'stores_show' or gon.page is 'products_show' or gon.page is 'products_index'
     dirty_commas = (num) ->
         String(num).replace /^\d+(?=\.|$)/, (int) ->
             int.replace /(?=(?:\d{3})+$)(?!^)/g, ','
@@ -12,7 +12,7 @@
         # at the position it was set to at page unload
         header_fix = -> scrollTo(0, 0)

-        if gon.page is 'stores_show'
+        if gon.page is 'stores_show' or gon.page is 'products_index'
             header_fix()

             ($ '.products').on('tap', '.product', ->


Added logging to console when route error

--- app/assets/javascripts/sprangular/module.coffee
+++ app/assets/javascripts/sprangular/module.coffee
@@ -63,7 +63,8 @@

   $rootScope.$on '$routeChangeError', (event, current, previous, rejection) ->
     Status.routeChanging = false
-    alert "Error changing route #{rejection}"
+    alert "Error changing route. See console for details."
+    console?.log "Error changing route", rejection

   Account.init()
     .success -> Status.initialized = true


Add current element and event as params to clicked callback

--- app/assets/javascripts/gl_dropdown.js.coffee
+++ app/assets/javascripts/gl_dropdown.js.coffee
@@ -171,10 +171,11 @@
         selector = ".dropdown-page-one .dropdown-content a"

       @dropdown.on "click", selector, (e) ->
-        selected = self.rowClicked $(@)
+        $el = $(@)
+        selected = self.rowClicked $el

         if self.options.clicked
-          self.options.clicked(selected, e)
+          self.options.clicked(selected, $el, e)

   # Finds an element inside wrapper element
   getElement: (selector) ->


fix bug

fix bug

--- app/assets/javascripts/s3_form_for.js.coffee
+++ app/assets/javascripts/s3_form_for.js.coffee
@@ -113,7 +113,7 @@
       if  validation_form
         $(forms_for_submit).submit()

-      if settings.allow_send_form_without_file && $uploadForm.find('#file_name_for_upload').text().length == 0
+      if settings.allow_send_form_without_file && $uploadForm.find('#file_name_for_upload').text() == 'No file selected'
         true
       else
         false