Adjusts atom outline view.

Adjusts atom outline view.

--- .atom/config.cson
+++ .atom/config.cson
@@ -5,6 +5,7 @@
       formatOnType: false
     "atom-ide-diagnostics-ui":
       autoVisibility: true
+    "atom-ide-outline-view": {}
     "atom-ide-terminal":
       allowTransparency: true
       black: "#3f3f3f"


integrate ebook-convert api

integrate ebook-convert api

--- lib/markdown-preview-enhanced-view.coffee
+++ lib/markdown-preview-enhanced-view.coffee
@@ -8,6 +8,7 @@

 {getMarkdownPreviewCSS} = require './style'
 plantumlAPI = require './puml'
+ebookConvert = require './ebook-convert'
 {loadMathJax} = require './mathjax-wrapper'

 module.exports =
@@ -1013,7 +1014,7 @@
       useGitHubSyntaxTheme = atom.config.get('markdown-preview-enhanced.useGitHubSyntaxTheme')

       title = ebookConfig.title || 'no title'
-      mathStyle = ''
+      mathStyle = if outputHTML.indexOf('class="katex"') > 0 then "<link rel=\"stylesheet\" href=\"file:///#{path.resolve(__dirname, '../node_modules/katex/dist/katex.min.css')}\">" else ''

       outputHTML = """
   <!DOCTYPE html>
@@ -1038,6 +1039,9 @@
   </html>
       """

+      fileName = 'test.epub'
+      dist = '/Users/wangyiyi/Desktop/test.epub'
+
       temp.open
         prefix: 'markdown-preview-enhanced',
         suffix: '.html', (err, info)=>
@@ -1046,6 +1050,9 @@
           fs.write info.fd, outputHTML, (err)=>
             throw err if err
             @openFile info.path
+            ebookConvert info.path, dist, ebookConfig, (err)=>
+              throw err if err
+              atom.notifications.addInfo "File #{fileName} was created in the same directory", detail: "path: #{dist}"


Clean up

Clean up

--- SingularityUI/app/controllers/DeployDetail.coffee
+++ SingularityUI/app/controllers/DeployDetail.coffee
@@ -42,11 +42,11 @@
       model:      @models.deploy
       template:   @templates.info

-    @subviews.taskHistory = new ExpandableTableSubview
+    @subviews.taskHistory = new SimpleSubview
       collection: @collections.taskHistory
       template:   @templates.taskHistory

-    @subviews.activeTasks = new ExpandableTableSubview
+    @subviews.activeTasks = new SimpleSubview
       collection: @collections.activeTasks
       template:   @templates.activeTasks


Fix HC json view

Fix HC json view

--- SingularityUI/app/models/HealthCheckResult.coffee
+++ SingularityUI/app/models/HealthCheckResult.coffee
@@ -10,7 +10,7 @@
     parse: (task) ->
         latest =  _.last(task.healthcheckResults)
         if latest
-            @id = latest.taskId.id
+            latest.id = latest.taskId.id
         latest

 module.exports = HealthCheckResult


Client: Activity: Feed: Passed channelId to feedItem as a prop

--- client/activity/lib/components/publicfeedpane/feedlist.coffee
+++ client/activity/lib/components/publicfeedpane/feedlist.coffee
@@ -1,14 +1,19 @@
-kd = require 'kd'
-React = require 'kd-react'
-
+kd       = require 'kd'
+React    = require 'kd-react'
 FeedItem = require './feeditem'

 module.exports = class FeedList extends React.Component

+  defaultProps =
+    channelId : null
+
+
   renderChildren: ->

-    @props.messages.map (msg) ->
-      <FeedItem key={msg.get 'id'} message={msg} />
+    { channelId } = @props
+
+    @props.messages.toList().map (msg) ->
+      <FeedItem channelId={channelId} key={msg.get 'id'} message={msg} />

   render: ->


Set starting point for hatching enemies

Set starting point for hatching enemies

--- src/lazerscripts/stage1/ship_boss.coffee
+++ src/lazerscripts/stage1/ship_boss.coffee
@@ -128,20 +128,22 @@
           @parallel(
             # Open hatch 1
             @action 'open1'
-              @placeSquad Shooter,
-                amount: 5,
-                delay: 200
-                options: {
-                  x: 545
-                  y: Crafty.viewport.height + 100
-                }
-              @sequence(
-                @wait(3000)
-                # close hatch 1
-                @action 'close1'
-                @moveTo(x: -2)
-              )
+            @placeSquad Shooter,
+              amount: 5,
+              delay: 200
+              options: {
+                startAt: 'ShipHatch1'
+                hatchReveal: 'ShipHatch1'
+                dx: 25
+                dy: 20
+              }
+            @sequence(
               @wait(3000)
+              # close hatch 1
+              @action 'close1'
+              @moveTo(x: -2)
+            )
+            @wait(3000)

           )
           @sequence(
@@ -153,8 +155,10 @@
                 amount: 3,
                 delay: 200
                 options: {
-                  x: 615
-                  y: Crafty.viewport.height + 100
+                  startAt: 'ShipHatch2'
+                  hatchReveal: 'ShipHatch2'
+                  dx: 25
+                  dy: 20
                 }
               @placeSquad CrewShooters,
                 amount: 8,
@@ -168,8 +172,10 @@
                 amount: 3,
                 delay: 200
                 options: {
-                  x: 615
-                  y: Crafty.viewport.height + 100
+                  startAt: 'ShipHatch2'
+                  hatchReveal: 'ShipHatch2'
+                  dx: 25
+                  dy: 20
                 }
               @placeSquad ScraperFlyer,
                 amount: 8,
@@ -207,8 +213,10 @@
               amount: 6,
               delay: 200
               options: {
-                x: 565
-                y: Crafty.viewport.height + 100
+                startAt: 'ShipHatch2'
+                hatchReveal: 'ShipHatch2'
+                dx: 25
+                dy: 20
               }
             @wait(2000)
             @action 'open1'
@@ -216,16 +224,20 @@
               amount: 3,
               delay: 200
               options: {
-                x: 565
-                y: Crafty.viewport.height + 100
+                startAt: 'ShipHatch1'
+                hatchReveal: 'ShipHatch1'
+                dx: 25
+                dy: 20
               }
             @wait(1000)
             @placeSquad Shooter, # 1
               amount: 6,
               delay: 200
               options: {
-                x: 565
-                y: Crafty.viewport.height + 100
+                startAt: 'ShipHatch1'
+                hatchReveal: 'ShipHatch1'
+                dx: 25
+                dy: 20
               }
               @wait(1000)
               @action 'close1'


moved check to the correct place

moved check to the correct place

otherwise after loading new facts, it would load more new facts, even if it wasn't in view

--- core/app/backbone/factlink/auto_loading_composite_view.coffee
+++ core/app/backbone/factlink/auto_loading_composite_view.coffee
@@ -26,7 +26,7 @@
     # this function sets the correct state after loading is done, tries to load more if applicable
     # and sets empty state if we are not loading and we have no items
     afterLoad: ->
-      unless @collection._loading
+      unless @collection._loading or not @$el.is(":visible")
         @emptyViewOnWrapper()  if @collection.length is 0
         @collection.loadMore() if @bottomOfViewReached()

@@ -34,7 +34,7 @@
       @unbindScroll()

       $(window).on "scroll.#{@cid}", =>
-        @afterLoad() if @$el.is(":visible")
+        @afterLoad()

     unbindScroll: ->
       $(window).off "scroll.#{@cid}"


Move attribute nesting in ESRI indicator to own function

--- indicatorators/esri.coffee
+++ indicatorators/esri.coffee
@@ -109,6 +109,14 @@
   else
     return rows

+# ESRI responses put their attribute data inside an object under an 'attribute'
+# key
+nestRowsInsideAttributesObject = (rows)->
+  nestedRows = []
+  for row in rows
+    nestedRows.push(attributes: row)
+
+  return nestedRows

 exports.indicatorate = (indicatorCode, data) ->
   data = JSON.parse(data)
@@ -119,9 +127,11 @@

   indicatorDefinition = indicatorDefinitions[indicatorCode]

+  rows = exports.addIndicatorTextToData(rows, indicatorCode, indicatorDefinition)
+
   rows = exports.averageRows(rows, indicatorDefinition)

-  rows = addIndicatorTextToData(rows, indicatorCode, indicatorDefinition)
+  rows = nestRowsInsideAttributesObject(rows)

   return {
     features: rows


improved mime-type support

improved mime-type support

--- src/hooks/datauris.coffee
+++ src/hooks/datauris.coffee
@@ -10,10 +10,18 @@
     if err
       callback err
       return
+
+    mimes =
+      png:  'image/png'
+      jpeg: 'image/jpeg'
+      jpg:  'image/jpg'
+      gif:  'image/gif'
+      woff: 'application/x-font-woff'
+
     format = path.extname(filename).slice(1)
     enc = data.toString("base64")
     console.log "Warning: Very long encoded string; IE (and possibly other browsers) wont like this!"  if enc.length >= Math.pow(2, 15)
-    callback null, "url(data:image/" + format + ";base64," + enc + ")"
+    callback null, "url(data:" + mimes[format] + ";base64," + enc + ")"

 module.exports = (hooks) ->
   hooks.preproc = (files, meta, callback) ->
@@ -30,7 +38,7 @@
         if err
           callback err
           return
-        exp = "url\\(\\s*['\"]?([^\\)'\"]*)\\.(png|jpeg|jpg|gif)['\"]?\\s*\\)"
+        exp = "url\\(\\s*['\"]?([^\\)'\"]*)\\.(png|jpeg|jpg|gif|woff)['\"]?\\s*\\)"
         matches = data.match(new RegExp(exp, "g")) or []
         async.forEachSeries matches, ((match, callback) ->
           filename = match.match(exp).slice(1).join(".")


Fix coffeelint

Fix coffeelint

--- src/keymap-manager.coffee
+++ src/keymap-manager.coffee
@@ -80,10 +80,10 @@
   #   * `which`  A {Number} indicating `which` value of the event. See
   #     the docs for KeyboardEvent for more information.
   #   * `target` The target element of the event.
-  KeymapManager.buildKeydownEvent = (key, options) ->
+  KeymapManager.buildKeydownEvent = (key, options) ->
     keydownEvent(key, options)

-  KeymapManager.buildKeyupEvent = (key, options) ->
+  KeymapManager.buildKeyupEvent = (key, options) ->
     keyupEvent(key, options)

   ###
@@ -283,7 +283,7 @@
   findKeyBindings: (params={}) ->
     {keystrokes, command, target, keyBindings} = params

-    bindings = keyBindings ? @keyBindings
+    bindings = keyBindings ? this.keyBindings

     if command?
       bindings = bindings.filter (binding) -> binding.command is command
@@ -324,7 +324,7 @@
         if this.filePathMatchesPlatform(filePath)
           this.loadKeymap(filePath, checkIfDirectory: false)
     else
-      this.add(bindingsPath, @readKeymap(bindingsPath, options?.suppressErrors), options?.priority)
+      this.add(bindingsPath, this.readKeymap(bindingsPath, options?.suppressErrors), options?.priority)
       this.watchKeymap(bindingsPath, options) if options?.watch

     undefined
@@ -382,7 +382,7 @@
   # <platform> does not match the current platform, returns false. Otherwise
   # returns true.
   filePathMatchesPlatform: (filePath) ->
-    otherPlatforms = @getOtherPlatforms()
+    otherPlatforms = this.getOtherPlatforms()
     for component in path.basename(filePath).split('.')[0...-1]
       return false if component in otherPlatforms
     true
@@ -495,7 +495,7 @@
     keystroke = this.keystrokeForKeyboardEvent(event)

     # We dont care about bare modifier keys in the bindings. e.g. `ctrl y` isnt going to work.
-    if event.type is 'keydown' and @queuedKeystrokes.length > 0 and isBareModifier(keystroke)
+    if event.type is 'keydown' and this.queuedKeystrokes.length > 0 and isBareModifier(keystroke)
       event.preventDefault()
       return

@@ -506,12 +506,12 @@
     # If the event's target is document.body, assign it to defaultTarget instead
     # to provide a catch-all element when nothing is focused.
     target = if replay then document.activeElement else event.target
-    target = this.defaultTarget if event.target is document.body and @defaultTarget?
+    target = this.defaultTarget if event.target is document.body and this.defaultTarget?

     # First screen for any bindings that match the current keystrokes,
     # regardless of their current selector. Matching strings is cheaper than
     # matching selectors.
-    {partialMatchCandidates, keydownExactMatchCandidates, exactMatchCandidates} = @findMatchCandidates(@queuedKeystrokes, disabledBindings)
+    {partialMatchCandidates, keydownExactMatchCandidates, exactMatchCandidates} = this.findMatchCandidates(this.queuedKeystrokes, disabledBindings)
     dispatchedExactMatch = null
     partialMatches = this.findPartialMatches(partialMatchCandidates, target)

@@ -535,7 +535,7 @@
       currentTarget = target
       eventHandled = false
       while not eventHandled and currentTarget? and currentTarget isnt document
-        exactMatches = @findExactMatches(exactMatchCandidates, currentTarget)
+        exactMatches = this.findExactMatches(exactMatchCandidates, currentTarget)
         for exactMatchCandidate in exactMatches
           if exactMatchCandidate.command is 'native!'
             shouldUsePartialMatches = false
@@ -563,7 +563,7 @@
           else
             shouldUsePartialMatches = false

-          if @dispatchCommandEvent(exactMatchCandidate.command, target, event)
+          if this.dispatchCommandEvent(exactMatchCandidate.command, target, event)
             dispatchedExactMatch = exactMatchCandidate
             eventHandled = true
             break
@@ -610,7 +610,7 @@
       )
       enableTimeout = false if replay
       this.enterPendingState(partialMatches, enableTimeout)
-    else if not dispatchedExactMatch? and not hasPartialMatches and @pendingPartialMatches?
+    else if not dispatchedExactMatch? and not hasPartialMatches and this.pendingPartialMatches?
       # There are partial matches from a previous event, but none from this
       # event. This means the current event has removed any hope that the queued
       # key events will ever match any binding. So we will clear the state and
@@ -742,7 +742,7 @@
       # We can safely re-enable the bindings when we no longer have any partial matches
       bindingsToDisable = null if bindingsToDisable? and not this.pendingPartialMatches?

-    if fromTimeout and @pendingPartialMatches?
+    if fromTimeout and this.pendingPartialMatches?
       this.terminatePendingState(true)

     return


Throw error that ranges are not supported

--- src/liquid/context.coffee
+++ src/liquid/context.coffee
@@ -135,7 +135,7 @@
     else if match = /^\((\S+)\.\.(\S+)\)$/.exec(key) # Ranges
       lo = Number(resolve(match[1]))
       hi = Number(resolve(match[2]))
-      # TODO: generate Range
+      throw new Error "Ranges are not supported."
     else if match = /^(\d[\d\.]+)$/.exec(key) # Floats
       Number(match[1])
     else


Clear ssh key adder value on cancel

Clear ssh key adder value on cancel

--- src/smc-webapp/widget-ssh-keys/main.cjsx
+++ src/smc-webapp/widget-ssh-keys/main.cjsx
@@ -58,6 +58,12 @@
         key_value  : ""
         show_panel : false

+    cancel_and_close: ->
+        @setState
+            key_title  : ""
+            key_value  : ""
+            show_panel : false
+
     trigger_error: (err) ->
         @setState(error : err)

@@ -83,6 +89,8 @@
             fingerprint   : compute_fingerprint(validated_key.pubkey)
             creation_date : Date.now()
             creator_id    : @props.account_id
+
+        @cancel_and_close() if @props.toggleable

     render_panel: ->
         <Panel header={<h2> <Icon name='plus-circle' /> Add an SSH Key</h2>} style={@props.style}>
@@ -119,7 +127,7 @@
                     >
                         Add SSH Key
                     </Button>
-                    {<Button onClick={=>@setState(show_panel:false)}>
+                    {<Button onClick={@cancel_and_close}>
                         Cancel
                     </Button> if @props.toggleable }
                 </ButtonToolbar>


Fix indentation in data_table.coffee

Fix indentation in data_table.coffee

--- bokehjs/src/coffee/widget/data_table.coffee
+++ bokehjs/src/coffee/widget/data_table.coffee
@@ -53,7 +53,7 @@
         field: column.get("field")
         name: column.get("title")
         width: column.get("width")
-        #formatter: column.get("formatter")
+        # formatter: column.get("formatter")
         editor: column.get("editor").default_view

       width = @mget("width")
@@ -68,9 +68,9 @@
         autoEdit: false

       if width?
-          @$el.css(width: "#{@mget("width")}px")
+        @$el.css(width: "#{@mget("width")}px")
       if height? and height != "auto"
-          @$el.css(height: "#{@mget("height")}px")
+        @$el.css(height: "#{@mget("height")}px")

       @data = new DataProvider(@mget("source"))
       @grid = new SlickGrid(@el, @data, columns, options)


fix metrics.this

fix metrics.this


Tests: Enable collab tests.

Tests: Enable collab tests.

--- scripts/test-instance/parallel-sets.coffee
+++ scripts/test-instance/parallel-sets.coffee
@@ -69,17 +69,17 @@
     { name: 'environments snapshot' }
   ]

-  # [
-  #   { name: 'collaboration start', NIGHTWATCH_OPTIONS: '--env host,participant' }
-  # ]
+  [
+    { name: 'collaboration start', NIGHTWATCH_OPTIONS: '--env host,participant' }
+  ]

-  # [
-  #   { name: 'collaboration collaborationsession', NIGHTWATCH_OPTIONS: '--env host,participant' }
-  # ]
+  [
+    { name: 'collaboration collaborationsession', NIGHTWATCH_OPTIONS: '--env host,participant' }
+  ]

-  # [
-  #   { name: 'collaboration collaborationfile', NIGHTWATCH_OPTIONS: '--env host,participant' }
-  # ]
+  [
+    { name: 'collaboration collaborationfile', NIGHTWATCH_OPTIONS: '--env host,participant' }
+  ]

   [
     { name: 'vmsharing vmsharing', NIGHTWATCH_OPTIONS: '--env host,participant' }
@@ -102,4 +102,4 @@
     # { name: 'environments vm-advanced' }
     { name: 'environments paidaccountvm' }
   ]
-]+]


very small syntax update

very small syntax update

--- src/mist-client-js.coffee
+++ src/mist-client-js.coffee
@@ -1,7 +1,7 @@
 ;class Mist

   # constructor
-  constructor : ( @options={} ) ->
+  constructor : (@options={}) ->

     # check for dependencies
     if typeof(Eventify) == "undefined" || typeof(Logify) == "undefined"


Search for subject selected from dropdown

--- src/scripts/modules/find-content/find-content.coffee
+++ src/scripts/modules/find-content/find-content.coffee
@@ -10,15 +10,17 @@
     template: template

     events:
-      'click .dropdown-toggle': 'clickToggle'
+      'click .dropdown-menu > li': 'selectSubject'
       'keyup input': 'triggerSearch'

-    clickToggle: (e) ->
+    selectSubject: (e) ->
       e.preventDefault()
+
+      @search("subject:\"#{$(e.currentTarget).text()}\"")

     triggerSearch: (e) ->
       if e.keyCode is 13
         @search($(e.currentTarget).val())
-
+
     search: (query) ->
       router.navigate("search?q=#{query}", {trigger: true})


Fix integration spec for products

Fix integration spec for products

--- src/spec/integration/integration-product.spec.coffee
+++ src/spec/integration/integration-product.spec.coffee
@@ -59,7 +59,7 @@
       @oldProduct.version = product.version
       @newProduct.id = product.id
       done()
-    .fail (msg) -> done(msg)
+    .fail (error) -> done(_.prettify(error))
   , 10000 # 10sec

   afterEach (done) ->
@@ -83,7 +83,7 @@
     .then (result) ->
       expect(result.statusCode).toBe 304
       done()
-    .fail (error) -> done(error)
+    .fail (error) -> done(_.prettify(error))

   it 'should update name', (done) ->
     @newProduct.name.en = 'Hello'
@@ -95,11 +95,11 @@
       expect(result.body.masterData.staged.name.en).toBe 'Hello'
       expect(result.body.masterData.staged.name.de).toBe 'Hallo'
       done()
-    .fail (error) -> done(error)
+    .fail (error) -> done(_.prettify(error))

   it 'should add, update and delete tax category', (done) ->
     tax =
-      name: "myTax-#{@unique}"
+      name: _.uniqueId 'myTax'
       rates: []

     # addition
@@ -120,7 +120,7 @@

     # change
       tax =
-        name: "myTax2-#{@unique}"
+        name: _.uniqueId 'myTax2'
         rates: []
       @client.taxCategories.save(tax)
     .then (result) =>
@@ -145,7 +145,7 @@
       expect(result.statusCode).toBe 200
       expect(result.body.taxCategory).not.toBeDefined()
       done()
-    .fail (msg) -> done(msg)
+    .fail (error) -> done(_.prettify(error))

   it 'should add, change and remove image', (done) ->
     @newProduct.masterVariant.images = [
@@ -183,7 +183,7 @@
       expect(result.statusCode).toBe 200
       expect(_.size result.body.masterData.staged.masterVariant.images).toBe 0
       done()
-    .fail (msg) -> done(JSON.stringify(msg))
+    .fail (error) -> done(_.prettify(error))

 describe 'Integration test :: Products :: between projects', ->

@@ -242,4 +242,4 @@
         done(JSON.stringify(errors))
       else
         done()
-    .fail (err) -> done(JSON.stringify(err))
+    .fail (error) -> done(_.prettify(error))


render CCDashboard if course is CC

render CCDashboard if course is CC

--- tutor/src/helpers/route-handlers.cjsx
+++ tutor/src/helpers/route-handlers.cjsx
@@ -7,7 +7,7 @@
 TeacherTaskPlans        = require '../components/task-plan/teacher-task-plans-listing'
 CCStudentRedirect       = require '../components/cc-student-redirect'
 {StudentDashboardShell} = require '../components/student-dashboard'
-
+CCDashboard = require '../components/cc-dashboard'
 {CourseStore} = require '../flux/course'

 RoutingHelper = require './routing'
@@ -34,7 +34,7 @@

     if CourseStore.isTeacher(courseId)
       if CourseStore.isConceptCoach(courseId)
-        <TeacherComponent courseId={courseId} {...props} />
+        <CCDashboard  courseId={courseId} {...props} />
       else
         <TeacherTaskPlans {...props} />
     else


Added test for merge of converters setting

--- test/tb/lib/ti/ajax/settings_test.coffee
+++ test/tb/lib/ti/ajax/settings_test.coffee
@@ -281,6 +281,18 @@
         done()

   describe 'converters', ->
+
+    it 'should add the converter while preserving the existing converters', (done) ->
+
+      settings =
+        converters:
+          '* custom': ->
+
+      $.ajax('/test', settings).done (data, textStatus, xhr) ->
+        assert.ok @converters['* custom']
+        assert.ok @converters['* text']
+        done()
+
   describe 'data', ->
   describe 'dataFilter', ->
   describe 'dataType', ->


Determine mutation expectations using the composition's revision instead of a brittle input counter

--- src/trix/controllers/level_2_input_controller.coffee
+++ src/trix/controllers/level_2_input_controller.coffee
@@ -1,24 +1,19 @@
 #= require trix/controllers/input_controller

-{dataTransferIsPlainText} = Trix
+{dataTransferIsPlainText, defer} = Trix

 class Trix.Level2InputController extends Trix.InputController
-  constructor: ->
-    super
-    @inputCount = 0
-
   elementDidMutate: (mutationSummary) ->
-    @handleInput ->
-      if @inputCount > 0
-        if --@inputCount is 0
-          if @composing
-            @delegate?.inputControllerDidAllowUnhandledInput?()
-          else
-            @requestRender()
-      else
-        console.log("unexpected mutation! #{JSON.stringify(mutationSummary)}")
-        @inputCount = 0
-        @requestReparse()
+    if @composing
+      @delegate?.inputControllerDidAllowUnhandledInput?()
+    else if @inputRevision is @responder.revision
+      @rendering ?= defer =>
+        @rendering = null
+        @inputRevision = null
+        @handleInput(@requestRender)
+    else
+      console.log("unexpected mutation! #{JSON.stringify(mutationSummary)}")
+      @handleInput(@requestReparse)

   events:
     keydown: (event) ->
@@ -28,9 +23,9 @@

     beforeinput: (event) ->
       if handler = @inputTypes[event.inputType]
-        @inputCount++
         @event = event
         handler.call(this)
+        @inputRevision = @responder.revision

     dragenter: (event) ->
       if dragEventHasFiles(event)


Add string case to unsubscribeFromActivationEvents()

--- src/app/atom-package.coffee
+++ src/app/atom-package.coffee
@@ -152,6 +152,8 @@
   unsubscribeFromActivationEvents: ->
     if _.isArray(@metadata.activationEvents)
       rootView.off(event, @handleActivationEvent) for event in @metadata.activationEvents
+    else if _.isString(@metadata.activationEvents)
+      rootView.off(@metadata.activationEvents, @handleActivationEvent)
     else
       rootView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents


Add emacs bindings for add selection commands: alt-ctrl-n/p

--- src/app/keymaps/emacs.cson
+++ src/app/keymaps/emacs.cson
@@ -7,6 +7,8 @@
   'ctrl-N': 'core:select-down'
   'ctrl-F': 'core:select-right'
   'ctrl-B': 'core:select-left'
+  'alt-ctrl-n': 'editor:add-selection-below'
+  'alt-ctrl-p': 'editor:add-selection-above'
   'ctrl-h': 'core:backspace'
   'ctrl-d': 'core:delete'


Ignore redundant destructions of EditSessions

--- src/app/edit-session.coffee
+++ src/app/edit-session.coffee
@@ -56,7 +56,7 @@
     require 'editor'

   destroy: ->
-    throw new Error("Edit session already destroyed") if @destroyed
+    return if @destroyed
     @destroyed = true
     @unsubscribe()
     @buffer.release()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/array_extensions.coffee
+++ src/array_extensions.coffee
@@ -118,7 +118,7 @@
   this[rand(this.length)]

 ###*
-Remove the first occurance of the given object from the array if it is
+Remove the first occurrence of the given object from the array if it is
 present.

 @name remove


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/array_extensions.coffee
+++ src/array_extensions.coffee
@@ -162,7 +162,6 @@
 ###
 Array::include = (element) ->
   this.indexOf(element) != -1
-

 ###*
 Call the given iterator once for each element in the array,


Add some log statements.

Add some log statements.

--- app/assets/javascripts/pods/pods_store.js.coffee
+++ app/assets/javascripts/pods/pods_store.js.coffee
@@ -37,7 +37,9 @@
       for pod in pods
         r = s.put(pod)
   countAll: () ->
+    logger.verbose 'PodsStore.countAll.start'
     promise = new Promise (resolve, reject) =>
+      logger.verbose 'PodsStore.countAll.promise'
       @database().then (db) ->
         t = db.transaction 'pods', 'readonly'
         s = t.objectStore('pods')


fix(import): Disable debug mode

fix(import): Disable debug mode

--- src/coffee/io/reader.coffee
+++ src/coffee/io/reader.coffee
@@ -6,7 +6,7 @@
 fs = Promise.promisifyAll require('fs')
 Excel = require 'exceljs'

-DEBUG = true
+DEBUG = false
 debugLog = if DEBUG then console.log else _.noop

 class Reader


Revert "Write resulting body to console."

This reverts commit 5698d6e39d2394a1a5a12c299c43084a7375bf6c.

--- src/coffee/pricesync.coffee
+++ src/coffee/pricesync.coffee
@@ -79,8 +79,7 @@
         actions: actions

       @masterClient.products.byId(variantDataInMaster.productId).save(data)
-      .then (result) ->
-        console.error "PriceSync %j", result
+      .then ->
         Q({ updates: _.size(actions) })

   getPublishedProducts: (client, pageProcessedCb, processFn) ->


updated cacheit - creating generated files

--- src/commands/cacheit.coffee
+++ src/commands/cacheit.coffee
@@ -60,10 +60,20 @@
     # wrench returned file list
     matchFiles files

-# default cachebust filename gen function
-defaultCbfn = (root, file) ->
-  # replace this with checksum
-  return "#{file}.cacheout"
+# default cachebust file generator
+defaultFileGen = (root, dest, filePath, callback) ->
+  # read in file
+  file = fs.readFileSync("#{root}/#{filePath}")
+
+  # generate new filename
+  genFilePath = "#{filePath}.cacheout"
+
+  # write new file
+  writeFile "#{dest}/#{genFilePath}", file, (error) ->
+    return callback error, null if error?
+
+    # return generated file path
+    callback null, genFilePath

 # Create copy of asset files in `root` that match any of the regex patterns
 # passed in `match` with cache busting filename in `dest` folder.
@@ -73,28 +83,33 @@
 #
 # root (string) Root path to search for asset files.
 # dest (string) Path to create new cache busting asset files.
-# callback (function) Function called on error or success, cb(error, createdFiles)
-#                 - On error called with error set, createdFiles null
-#                 - On success error null and createdFiles set as dict
+# callback (function) Function called on error or success, cb(error, genFiles)
+#                 - On error called with error set, genFiles null
+#                 - On success error null and genFiles set as dict
 #                   original file path key and the value being the new
-# fngen (function) Function that generates cache busting filename taking the
+# fileGenFn (function) Function that generates cache busting file taking the
 #                 following arguments:
 #                     root (str) Root path searched in
 #                     file (str) Path to file from `root`
-createCachebustedAssets = (root, dest, match, callback, fngen = defaultCbfn) ->
-  console.log 0, root, dest, match, callback, fngen
-  createdFiles = {}
+createCachebustedAssets = (root, dest, match, callback, fileGenFn = defaultFileGen) ->
+  genFiles = {}
+
+  findFilesComplete = ->
+    callback null, genFiles

   findFiles root, match, (error, file) ->
     # error: pass error back to callback
     return callback e, null if error?

-    # finished: pass created files dict back to callback
-    return callback null, createdFiles unless file?
+    # finished
+    return findFilesComplete() unless file? or error?

     # match: create new cachebust file and store details
-    genFile = fngen(root, file)
-    createdFiles[file] = genFile
+    fileGenFn root, dest, file, (error, gfile) ->
+      # error: pass error back to callback
+      return callback error, null if error?
+
+      genFiles[file] = gfile

 module.exports = cacheit = (options, callback = (->)) ->
   config = helpers.loadConfig options.configPath
@@ -104,11 +119,7 @@
   console.log [srcPath, outPath, assetFiles, sourceFiles]

   createCachebustedAssets srcPath, outPath, assetFiles, (e, f) ->
+    return logger.error e if error?
+
+    # TODO: create function to update sources (*.html) with new generated files
     console.log "cacheit::createCachebustedAssets: response", e, f
-
-  return
-  # get list of assets
-  findFiles srcPath, assetFiles, (error, foundFiles) ->
-    return logger.error error if error?
-    console.log "Asset Files:", foundFiles
-


fix: take scrollable elements into account when calculating position


Remove debug addition

Remove debug addition

--- client/app/views/config_applications.coffee
+++ client/app/views/config_applications.coffee
@@ -54,7 +54,6 @@
             @updateBtn.show()
         else
             @updateBtn.hide()
-            @updateBtn.show()

     openUpdatePopover: (slug) ->


Better promise chain for handling reorg

Better promise chain for handling reorg

--- app/src/tasks/wallet_layout_recovery_task.coffee
+++ app/src/tasks/wallet_layout_recovery_task.coffee
@@ -7,9 +7,18 @@
   @instance: new @()

   onStart: () ->
-    @_performRecovery()
-
-  _performRecovery: ->
+    @_performRecovery().then () =>
+      l "Recovery completed"
+      @emit 'done'
+    .fail (er) =>
+      e "Serious error during synchro", er
+      @emit 'fatal_error'
+    .fin =>
+      # Delete sync token and stop
+      @_deleteSynchronizationToken(syncToken) if syncToken?
+      @stopIfNeccessary()
+
+  _performRecovery: () ->
     syncToken = null
     savedState = {}
     @_loadSynchronizationData().then (data) =>
@@ -24,15 +33,12 @@
       iterate(0)
     .fail (er) ->
       # Handle reorgs
-      @emit 'fatal_error'
-      e er
-    .then () =>
-      l "Recovery completed"
-      @emit 'done'
-    .fin =>
-      # Delete sync token and stop
-      @_deleteSynchronizationToken(syncToken) if syncToken?
-      @stopIfNeccessary()
+      e "Failure during synchro", er
+      if er?.getStatusCode?() is 404
+        @_handlerReorgs(savedState, er.block).then () =>
+          @_performRecovery()
+      else
+        throw er

   _recoverAccount: (accountIndex, savedState, syncToken) ->
     savedAccountState = savedState["account_#{accountIndex}"] or {}
@@ -84,6 +90,9 @@
       ledger.tasks.TransactionConsumerTask.instance.pushTransactions(result['txs'])
       ledger.tasks.TransactionConsumerTask.instance.pushCallback =>
         d.resolve({hasNext, block})
+    .fail (er) ->
+      er.block = block
+      throw er
     d.promise

   _recoverAddresses: (root, from, to, blockHash, syncToken) ->
@@ -140,7 +149,10 @@
       d.resolve()
     d.promise

-  _handlerReorgs: ->
+  _handlerReorgs: (state, failedBlock) ->
+    # Iterate through the state and delete any block heigher or equal to block.height
+    # Remove from the database all orphan transaction and blocks
+    # Save the new state

   ###
   onStart: () ->


overlay_spec: To prevent confusing failures due to the window not being in focus, throw an error with an explanation

--- spec_app/spec/javascripts/up/classes/layer/overlay_spec.coffee
+++ spec_app/spec/javascripts/up/classes/layer/overlay_spec.coffee
@@ -191,6 +191,10 @@

     describe 'focus', ->

+      beforeEach ->
+        unless document.hasFocus()
+          throw "The Jasmine spec runner must be focused for focus-related specs to pass"
+
       it 'traps focus within the overlay', asyncSpec (next) ->
         makeLayers(2)


masterArtForm.

masterArtForm.

--- src/Acme/FindMartialBundle/Resources/public/coffee/main.coffee
+++ src/Acme/FindMartialBundle/Resources/public/coffee/main.coffee
@@ -28,7 +28,13 @@
 		iconCancel 		= $('<i />', {class: 'fa fa-times fa-fw'})

 		buttonEdit 		= $('<a />', {class : 'buttonEdit', href: '#'}).append iconEdit.clone false
-		buttonDelete 	= $('<a />', {class : 'buttonDelete', action: '/'}).append iconDel.clone false
+
+
+		buttonDelete 	= $('<a />', {class : 'buttonDelete', href: '#'}).append iconDel.clone false
+		formDelete		= $('<form />', {class : 'buttonDelete', href: '#'})
+
+
+
 		spanTools 		= $('<span />', {class : 'artListItemAcc'})
 		spanTools.append buttonEdit
 		spanTools.append ' '


hooray for idioms

hooray for idioms

--- client/coffeescript/templates/tagbox.coffee
+++ client/coffeescript/templates/tagbox.coffee
@@ -4,10 +4,8 @@
     suggestions = {}
     for post in Posts.find( 'parent_id': @parent_id ).fetch() #get siblings
       for name,info of post.tags #Change to only graduated tags
-        if suggestions[name]?
-          suggestions[name] += info.weight
-        else
-          suggestions[name] = info.weight
+        suggestions[name] ?= 0
+        suggestions[name] += info.weight
     sug_list = ({'name':name, 'weight':weight} for name,weight of suggestions) #get as list
     return (sug_list.sort (a,b) -> return a.weight-b.weight).map (a) -> a.name #sort by weight, then return list of names
 )


IDE Settings: Wait ready state of appStorage

--- client/ide/lib/views/tabview/ideview.coffee
+++ client/ide/lib/views/tabview/ideview.coffee
@@ -138,11 +138,13 @@

     if not paneLength and not frontApp.targetTabView

-      if not appStorage.getValue 'IsAutoRemovePaneSuggested'
-        appStorage.setValue 'IsAutoRemovePaneSuggested', yes
-        return @showSuggestAutoRemovePaneModal()
-
-      @closeSplitView()  if appStorage.getValue 'enableAutoRemovePane'
+      appStorage.ready =>
+
+        if not appStorage.getValue 'IsAutoRemovePaneSuggested'
+          appStorage.setValue 'IsAutoRemovePaneSuggested', yes
+          return @showSuggestAutoRemovePaneModal()
+
+        @closeSplitView()  if appStorage.getValue 'enableAutoRemovePane'

   showSuggestAutoRemovePaneModal: ->


Cleanup strategy

Cleanup strategy

--- src/config/inspector.coffee
+++ src/config/inspector.coffee
@@ -85,10 +85,7 @@
     program = programs.get('program')
     my.assert program, "no current program"

-
-    strategy = world.find_child(STRATEGY)
-    strategy.authority = world.make_world ROW_AUTHORITY
-    display_strategy strategy, programs
+    display_strategy world.find_child(STRATEGY), programs

   i: (world) -> world.get('split')
   width: (world) -> world.get('device').width - world.get('size')
@@ -125,7 +122,10 @@
       ]
     }
     COMMANDS
-    {_LABEL: STRATEGY}
+    {
+      _LABEL: STRATEGY
+      _AUTHORITY: ROW_AUTHORITY
+    }
   ]

 }


Add showError to KD.extend

Add showError to KD.extend

--- client/landing/app/MainApp/KD.extend.coffee
+++ client/landing/app/MainApp/KD.extend.coffee
@@ -99,3 +99,31 @@
           if flag in account.globalFlags
             return yes
     no
+
+  showError:(err, messages)->
+    return  unless err
+
+    messages or=
+      AccessDenied : 'Permission denied'
+      KodingError  : 'Something went wrong'
+
+    if 'string' is typeof err
+      message  = err
+      err      = {message}
+
+    err.name or= 'KodingError'
+
+    content    = ''
+    errMessage = message or messages[err.name]
+    if errMessage?
+      if 'string' is typeof errMessage
+        title = errMessage
+      else if errMessage.title? and errMessage.content?
+        {title, content} = errMessage
+
+    duration = errMessage.duration or 2500
+    title  or= err.message or 'Something went wrong'
+
+    new KDNotificationView {title, content, duration}
+
+    warn "KodingError:", err.message  unless err.name is 'AccessDenied'


Search substrings for GL Accounts

Search substrings for GL Accounts

This enables searching for either the number or description.

Fixes # 28

--- client/skr/components/GlAccountChooser.cjsx
+++ client/skr/components/GlAccountChooser.cjsx
@@ -34,5 +34,6 @@
                 choices={Skr.Models.GlAccount.all.models}
                 labelField="combined_name"
                 model={@props.model}
+                filter='contains'
                 {...props}
             />


subscribed to stations now

subscribed to stations now

--- client/templates/views/market/market.coffee
+++ client/templates/views/market/market.coffee
@@ -1,4 +1,5 @@
 Meteor.subscribe "System"
+Meteor.subscribe "Stations"

 Template.market.events


List only channels

List only channels

--- client/views/app/chatWindowDashboard.coffee
+++ client/views/app/chatWindowDashboard.coffee
@@ -282,7 +282,7 @@
 			getInput: ->
 				return template.find('.input-message')
 			getFilter: (collection, filter) ->
-				return collection.find({name: new RegExp(filter, 'i')}, {limit: 10})
+				return collection.find({t: 'c', name: new RegExp(filter, 'i')}, {limit: 10})
 			getValue: (_id, collection) ->
 				return collection.findOne(_id)?.name


Disable additional Nuclide packages in Atom config.

--- home/.atom/config.cson
+++ home/.atom/config.cson
@@ -28,6 +28,10 @@
       "nuclide-click-to-symbol"
       "vim-mode-plus"
       "box-edit"
+      "nuclide-blame-provider-hg"
+      "hyperclick"
+      "nuclide-arcanist"
+      "nuclide-blame"
     ]
     themes: [
       "atom-material-ui"


Updated

Updated

--- home/.atom/config.cson
+++ home/.atom/config.cson
@@ -69,3 +69,4 @@
   "autocomplete-plus": {}
   "open-in":
     applications: "SourceTree,Terminal,Finder,WebStorm"
+  bookmarklet: {}


Avoid treating first Control JSON key as special; this is too fragile.

--- src/json.coffee
+++ src/json.coffee
@@ -75,16 +75,17 @@
 The third form is any other JSON dictionary object, returned as is.
 ###
 evaluateControlJson = ( json, logicalParent ) ->
-  # Get the first key in the JSON.
-  for firstKey of json
-    break
-  return json if firstKey isnt "html" and firstKey isnt "control"  # Regular object, return as is.
-  reservedKeys = { ref: true } # "ref" handled specially, see below.
-  reservedKeys[firstKey] = true
+  if json.html?
+    reservedKeys = html: true
+  else if json.control?
+    reservedKeys = control: true
+  else
+    return # Regular object, return as is.
+  reservedKeys.ref = true # "ref" handled specially, see below.
   stripped = copyExcludingKeys json, reservedKeys
   properties = evaluateControlJsonProperties stripped, logicalParent
   control = undefined
-  if firstKey is "html"
+  if json.html?
     html = json.html
     if /^\w+$/.test html
       # HTML tag singleton. Map tag like "div" to "<div>".


JAccount: remove not used counts from schema

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -235,27 +235,6 @@
           type              : Number
           default           : 0
         likes               :
-          type              : Number
-          default           : 0
-        statusUpdates       :
-          type              : Number
-          default           : 0
-        staffLikes          :
-          type              : Number
-          default           : 0
-        comments            :
-          type              : Number
-          default           : 0
-        referredUsers       :
-          type              : Number
-          default           : 0
-        invitations         :
-          type              : Number
-          default           : 0
-        lastLoginDate       :
-          type              : Date
-          default           : new Date
-        twitterFollowers    :
           type              : Number
           default           : 0


DockController: Disable fetching dock preferences, instead use default ones for now

--- client/Main/maincontroller/dockcontroller.coffee
+++ client/Main/maincontroller/dockcontroller.coffee
@@ -39,41 +39,47 @@
       title        : 'navigation'
       items        : []

-    @storage.fetchStorage (err, storage)=>
+    KD.setNavItems defaultItems
+    @navController.reset()

-      usersNavItems = @storage.getValue 'navItems'
-      ourNavItems   = defaultItems
-      ourNavObj     = createHash ourNavItems
-      KD.setNavItems ourNavItems
+    # Disabled until we figure out the flow of dock controller ~ GG
+    #
+    # @storage.fetchStorage (err, storage)=>

-      unless usersNavItems
+      # usersNavItems = @storage.getValue 'navItems'
+      # ourNavItems   = defaultItems
+      # ourNavObj     = createHash ourNavItems
+      # KD.setNavItems ourNavItems

-        @navController.reset()
-        log ourNavItems, 'ready'
-        return @emit 'ready'
+      # unless usersNavItems

-      usersNavObj = createHash usersNavItems
+      #   @navController.reset()
+      #   log ourNavItems, 'ready'
+      #   return @emit 'ready'

-      # reset default items' orders if user has customized them
-      for ourItem in ourNavItems
-        continue unless usersItem = usersNavObj[ourItem.title]
-        log 'changing order for:', ourItem.title
-        ourItem.order = usersItem.order
+      # usersNavObj = createHash usersNavItems

-      # add user's custom items in nav items
-      for usersItem in usersNavItems
-        continue if ourNavObj[usersItem.title]
-        KD.registerNavItem usersItem
+      # # reset default items' orders if user has customized them
+      # for ourItem in ourNavItems
+      #   continue unless usersItem = usersNavObj[ourItem.title]
+      #   log 'changing order for:', ourItem.title
+      #   ourItem.order = usersItem.order

-      # re-sort the navitems
-      KD.setNavItems KD.getNavItems()
-      @navController.reset()
+      # # add user's custom items in nav items
+      # for usersItem in usersNavItems
+      #   continue if ourNavObj[usersItem.title]
+      #   KD.registerNavItem usersItem

-      @emit 'ready'
+      # # re-sort the navitems
+      # KD.setNavItems KD.getNavItems()
+      # @navController.reset()
+
+      # @emit 'ready'

     mainController = KD.getSingleton 'mainController'
     mainController.ready @bound 'accountChanged'

+    @emit 'ready'

   setItemOrder:(item, order = 0)->


activity: define `MessageEventHelper::addReply` method

--- client/Social/Activity/messageeventhelper.coffee
+++ client/Social/Activity/messageeventhelper.coffee
@@ -56,3 +56,14 @@

     message.emit "LikeRemoved"
     message.emit "update"
+
+
+  addReply: (message, plain) ->
+
+    reply = KD.singleton("socialapi").message.revive plain
+
+    message.replies.push reply
+    message.repliesCount++
+
+    message.emit "AddReply", reply
+    message.emit "update"


activity: add follow action/owner/admin menus if permission is granted

--- client/Social/Activity/views/settingsview.coffee
+++ client/Social/Activity/views/settingsview.coffee
@@ -85,11 +85,8 @@
     @menu = {}

     @addFollowActionMenu()
-
-    if KD.isMyPost @getData()
-    then @addOwnerMenu()
-    else if KD.checkFlag('super-admin') or KD.hasAccess('delete posts')
-    then @addAdminMenu()
+    @addOwnerMenu()  if KD.isMyPost @getData()
+    @addAdminMenu()  if KD.checkFlag('super-admin') or KD.hasAccess('delete posts')

     return @menu


Implemented IDEEditorTabView for able to create new terminal and editor pane.

--- client/ide/views/tabview/ideeditortabview.coffee
+++ client/ide/views/tabview/ideeditortabview.coffee
@@ -1 +1,46 @@
-class IDEEditorTabView extends WorkspaceTabView
+ class IDEEditorTabView extends WorkspaceTabView
+
+  constructor: (options = {}, data) ->
+
+    super options, data
+
+    @on "PlusHandleClicked", =>
+      offset        = @holderView.plusHandle.$().offset()
+      contextMenu   = new KDContextMenu
+        delegate    : this
+        x           : offset.left - 125
+        y           : offset.top  + 30
+        arrow       :
+          placement : "top"
+          margin    : -20
+      , @getPlusMenuItems()
+
+      contextMenu.once "ContextMenuItemReceivedClick", ->
+        contextMenu.destroy()
+
+  getPlusMenuItems: ->
+    return {
+      "Editor"    :
+        callback  : => @createEditor()
+      "Terminal"  :
+        callback  : => @createTerminal()
+    }
+
+  createEditor: ->
+    file       = FSHelper.createFileFromPath "localfile://Untitled.txt"
+    content    = "This is my localfile"
+    editor     = new EditorPane { file, content }
+    pane       = new KDTabPaneView
+      closable : yes
+      name     : file.name
+
+    pane.addSubView editor
+    @tabView.addPane pane
+
+  createTerminal: ->
+    pane       = new KDTabPaneView
+      closable : yes
+      name     : "Terminal"
+
+    pane.addSubView new TerminalPane
+    @tabView.addPane pane


test/teamsHelpers: VM on off from VMPower toggle

--- client/test/lib/dashboard/virtualmachines.coffee
+++ client/test/lib/dashboard/virtualmachines.coffee
@@ -133,4 +133,12 @@
       .waitForElementVisible closeAddYourOwnMachineModal, 20000
       .click closeAddYourOwnMachineModal
       .pause 1000
-      .end()
+
+    # vm off by using VM Power toggle
+    browser
+      .click vmPowerToggleSelector, ->
+        teamsHelpers.waitUntilVmStopping browser, ->
+          browser
+            .click vmPowerToggleSelector, ->
+              teamsHelpers.waitUntilVmRunning browser, ->
+                browser.end()


add some scroll transitions

add some scroll transitions

--- app/assets/javascripts/components/subject-viewer.cjsx
+++ app/assets/javascripts/components/subject-viewer.cjsx
@@ -235,7 +235,8 @@
     scale = @getScale()

     if @props.workflow.name is 'transcribe'
-      window.scrollTo 0, @props.subject.data.y * @getScale().vertical - window.innerHeight/2
+      yPos = @props.subject.data.y * @getScale().vertical - window.innerHeight/2
+      $('html, body').animate({scrollTop: yPos}, 300);

     actionButton =
       if @state.loading


binding `step` to Ember.TextField's

binding `step` to Ember.TextField's

--- app/assets/javascripts/components/textfield.js.coffee
+++ app/assets/javascripts/components/textfield.js.coffee
@@ -1,2 +1,2 @@
 Ember.TextField.reopen
-  attributeBindings: ['required']
+  attributeBindings: ["required", "step"]


the dropdown subTask is available if the dropdown task is admin enabled

--- app/classifier/tasks/drawing-task-details-editor.cjsx
+++ app/classifier/tasks/drawing-task-details-editor.cjsx
@@ -97,12 +97,14 @@

                 Text
               </button>{' '}
-
-              <button type="submit" className="minor-button" onClick={@handleAddTask.bind this, 'dropdown'} title="Dropdown tasks: the volunteer selects a text label from a list.">
-
-

-                Dropdown
-              </button>
+              {
+                if 'dropdown' in @props.project.experimental_tools
+                  <button type="submit" className="minor-button" onClick={@handleAddTask.bind this, 'dropdown'} title="Dropdown tasks: the volunteer selects a text label from a list.">
+
+

+                    Dropdown
+                  </button>
+              }
           </TriggeredModalForm>


Map coffee-script fence to coffee extension

--- src/packages/markdown-preview/lib/markdown-preview-view.coffee
+++ src/packages/markdown-preview/lib/markdown-preview-view.coffee
@@ -9,6 +9,7 @@
   'bash': 'sh'
   'coffee': 'coffee'
   'coffeescript': 'coffee'
+  'coffee-script': 'coffee'
   'css': 'css'
   'go': 'go'
   'java': 'java'


Re-enabled prototype extension

Re-enabled prototype extension

--- src/coffee/config.coffee
+++ src/coffee/config.coffee
@@ -59,6 +59,6 @@
         q.done -> console.log 'QUnit done'
         q.load()

-# Disable Emberjs Prototype Extensions
-# This may cause the r.js optimizer to fail
-(window.ENV = {}).EXTEND_PROTOTYPES = false
+# # Disable Emberjs Prototype Extensions
+# # This may cause the r.js optimizer to fail
+# (window.ENV = {}).EXTEND_PROTOTYPES = false


Add fast click.

Add fast click.

* Need to prevent ghost clicks.

--- src/coffee/flight.coffee
+++ src/coffee/flight.coffee
@@ -6,6 +6,7 @@
   startPage: ''
   os: ''
   iScroll: {}
+  moved: false

   isTransitioning: false
   menuOpen: false
@@ -32,11 +33,12 @@

     @detectUserAgent()

-    @noClickDelay(document.body)
-
     @transitionAnimation = false if @os.android and @os.version <= '2.1'

     @hideUrlBar() if options.hideUrlbar
+
+    # if window.Touch // need to add this back in when finished
+    document.body.addEventListener('touchstart', @handleEvents, false)

   # Public: Go to a specific page.
   #
@@ -230,11 +232,6 @@
     str = str += content
     debug.innerHTML = str

-  noClickDelay: (el) ->
-    if typeof (el) is "string"
-      el = document.getElementById(el)
-    el.addEventListener('touchstart', @handleEvents, false)
-
   handleEvents: (e) =>
     switch e.type
       when 'touchstart' then @onTouchStart(e)
@@ -242,17 +239,24 @@
       when 'touchend' then @onTouchEnd(e)

   onTouchStart: (e) ->
-    if @os.android
-      @iScroll.refresh()
-
-    @fixInput(e)
-
-    if flight.prevClick? and @os.android
-      flight.prevClick.blur(); #We need to blur any input fields on android
-      flight.prevClick = null;
+    e.stopPropagation();
+    @moved = false
+    e.target.addEventListener('touchmove', @onTouchMove, false);
+    e.target.addEventListener('touchend', @onTouchEnd, false)
+    document.getElementById('result').innerHTML += ' ' + e.type
+
+  onTouchMove: (e) ->
+    @moved = true

   onTouchEnd: (e) ->
-    console.log "End"
+    e.target.removeEventListener('touchmove', @onTouchMove, false);
+    e.target.removeEventListener('touchend', @onTouchEnd, false);
+
+    if not @moved
+      e.preventDefault()
+      theEvent = document.createEvent('MouseEvents')
+      theEvent.initEvent('click', true, true)
+      e.target.dispatchEvent(theEvent)

   fixInput: (e) =>
     if not @os.android


fix: hard code check for material attribute

--- src/coffee/header.coffee
+++ src/coffee/header.coffee
@@ -71,11 +71,13 @@
         parts = head.split GLOBALS.DELIM_HEADER_LANGUAGE
         if _.size(parts) >= 2
           nameRegexp = new RegExp("^#{langAttribName}\.")
-          if head.match(nameRegexp) && _.first(parts) == langAttribName # because materialType override material attribute because of sub string match
+          if head.match(nameRegexp)
             lang = _.last(parts)
             # TODO: check language
-            langH2i[langAttribName] or= {}
-            langH2i[langAttribName][lang] = index
+            # hard coded because materialType override material attribute because of sub string match
+            if not (langAttribName == "material" && _.first(parts) != langAttribName)
+              langH2i[langAttribName] || (langH2i[langAttribName] = {})
+              langH2i[langAttribName][lang] = index

     langH2i


return null from remote functions

return null from remote functions

remote function are by nature async, return null to prevent some one
use the return value by accident

--- src/main.coffee
+++ src/main.coffee
@@ -445,6 +445,7 @@
                 return
             # TODO parse error requests
         )
+        return null

     invokeRemoteMethod : (host, port, id, methodName, args) ->
         serializedArgs = []


'window' module is renamed to 'browser_window'.

--- src/main.coffee
+++ src/main.coffee
@@ -1,7 +1,7 @@
 app = require 'app'
 delegate = require 'atom_delegate'
 path = require 'path'
-Window = require 'window'
+BrowserWindow = require 'browser_window'

 # Quit when all windows are closed.
 app.on 'window-all-closed', ->
@@ -55,7 +55,7 @@
     process.env['NODE_PATH'] = resourcePaths.join path.delimiter

   openWithParams: (pairs) ->
-    win = new Window width: 800, height: 600, show: false, title: 'Atom'
+    win = new BrowserWindow width: 800, height: 600, show: false, title: 'Atom'

     AtomWindow.windows.push win
     win.on 'destroyed', =>


Fix an encoding bug.

Fix an encoding bug.

--- src/main.coffee
+++ src/main.coffee
@@ -15,7 +15,10 @@
         if rawCodeType == "js"
             rawCode
         else
-            cp.execSync(compileCommands[rawCodeType], {input: rawCode})
+            cp.execSync(compileCommands[rawCodeType], {
+                encoding: "utf8"
+                input: rawCode
+            })
     mod = {}
     mods.push(mod)
     mod.code = code


Fix variable allocation

Fix variable allocation

--- src/main.coffee
+++ src/main.coffee
@@ -6,8 +6,14 @@
 	mapping = new Map

 	resolve = (name) ->
-		mapping.set name, count
-		count++
+		if mapping.has name
+			mapping.get name
+		else
+			prevCount = count
+			mapping.set name, count
+			count++
+			prevCount
+

 	{ resolve }


Increase default line height

Increase default line height

--- src/config-schema.coffee
+++ src/config-schema.coffee
@@ -108,7 +108,7 @@
         maximum: 100
       lineHeight:
         type: ['string', 'number']
-        default: 1.4
+        default: 1.44
       showInvisibles:
         type: 'boolean'
         default: false


fixed mist arg passing to commander

fixed mist arg passing to commander

--- src/mist.coffee
+++ src/mist.coffee
@@ -29,7 +29,7 @@

 config
   .version packageJson.version
-  .parse mistArgs
+  .parse process.argv.slice(0, 2).concat mistArgs

 try
   mistfile = Mistfile.find()


app-updates: Renamed open app button.

app-updates: Renamed open app button.

--- client/landing/app/Applications/Apps.kdapplication/Views/appview.coffee
+++ client/landing/app/Applications/Apps.kdapplication/Views/appview.coffee
@@ -146,18 +146,19 @@
           appsController.installApp app, 'latest', (err)=>
             @hideLoader()

-    @openAppButton = new KDButtonView
-      title     : "Open App"
+    @openButton = new KDButtonView
+      title     : "Open"
       style     : "cupid-green"
       callback  : =>
         @getSingleton("appManager").open app.title

-    @openAppButton.hide()
+    @openButton.hide()

     appsController.fetchApps (err, manifests) =>
+      # user have the app, show just show open button
       if app.title in Object.keys manifests
         @installButton.hide()
-        @openAppButton.show()
+        @openButton.show()

     {icns, name, version, authorNick} = app.manifest
     thumb = if icns and (icns['256'] or icns['512'] or icns['128'] or icns['160'] or icns['64'])
@@ -188,7 +189,7 @@

{{#(title)}}by {{#(manifest.author)}}

         {{> @installButton}}
-        {{> @openAppButton}}
+        {{> @openButton}}

Version {{ #(manifest.version) || "---" }}
Updated: ---

{{#(counts.installed) || 0}}
INSTALLS


terminal moved, chatter added

terminal moved, chatter added

--- client/landing/app/Applications/Chat.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Chat.kdapplication/AppController.coffee
@@ -1,14 +1,59 @@
-class Chat12345 extends AppController
+# class Chat12345 extends AppController
+#   constructor:()->
+#     mainViewClass = KDView
+#     mainViewClass = KD.getPageClass('Activity') if KD.getPageClass('Activity')?
+#
+#     @mainView = new mainViewClass {cssClass : "content-page" }
+#     super
+#
+#   bringToFront:()->
+#     @propagateEvent (KDEventType : 'ApplicationWantsToBeShown', globalEvent : yes), options : {}, data : @mainView
+#
+#   initAndBringToFront:(options,callback)->
+#     @bringToFront()
+#     callback()
+
+class ChatRoom
+
+
+  constructor:(options,callback)->
+
+
+  fetchRoom :({id},callback)->
+
+
+
+
+class @Chatter
+  {mq} = bongo
+
   constructor:()->
-    mainViewClass = KDView
-    mainViewClass = KD.getPageClass('Activity') if KD.getPageClass('Activity')?

-    @mainView = new mainViewClass {cssClass : "content-page" }
-    super

-  bringToFront:()->
-    @propagateEvent (KDEventType : 'ApplicationWantsToBeShown', globalEvent : yes), options : {}, data : @mainView
+  joinRoom:(options,callback)->

-  initAndBringToFront:(options,callback)->
-    @bringToFront()
-    callback()+    {id,callbacks} = options
+
+
+    @name = "private-chat-#{__utils.getRandomNumber}"
+    @room = mq.channel(@name)
+
+    if @room?
+      callback @room
+    else
+      mq.subscribe(@name)
+      @room.bind 'pusher:subscription_succeeded', ->
+        console.log('success', arguments)
+        callback null,@room
+
+
+        room.bind 'client-chat-msg',->
+          console.log arguments
+
+
+  sendMsg : (options,callback)->
+    {msg} = options
+    @room.trigger 'client-chat-msg',msg
+
+
+


removed title property after getting warning messages

--- examples/app/crossfilter/models/stats_box.coffee
+++ examples/app/crossfilter/models/stats_box.coffee
@@ -62,7 +62,6 @@
     return _.extend {}, super(), {
       children: []
       display_items: {}
-      title: null
       styles: null
     }


Tweak #2941.

Tweak #2941.

--- content_scripts/injected.coffee
+++ content_scripts/injected.coffee
@@ -13,9 +13,8 @@

   addEventListener = (type, listener, useCapture) ->
     if type == "click" and this instanceof EL
-      try
-        unless this instanceof Anchor # just skip <a>
-          @setAttribute "_vimium-has-onclick-listener", ""
+      unless this instanceof Anchor # Just skip <a>.
+        try @setAttribute "_vimium-has-onclick-listener", ""
     _addEventListener?.apply this, arguments

   newToString = () ->
@@ -28,7 +27,7 @@
   # Libraries like Angular/Zone and CKEditor check if element.addEventListener is native,
   # so here we hook it to tell outsides it is exactly native.
   # This idea is from https://github.com/angular/zone.js/pull/686,
-  # and see more discussions in https://github.com/ckeditor/ckeditor5-build-classic/issues/34
+  # and see more discussions in https://github.com/ckeditor/ckeditor5-build-classic/issues/34.
   Function::toString = newToString

 script = document.createElement "script"


Log command results for Develop::cloneRepository

Signed-off-by: Michelle Tilley <19f7a7eb6786def4c39d6d86c40af5dbc6589663@github.com>

--- src/develop.coffee
+++ src/develop.coffee
@@ -61,7 +61,8 @@
       args = ['clone', '--recursive', repoUrl, packageDirectory]
       process.stdout.write "Cloning #{repoUrl} "
       git.addGitToEnv(process.env)
-      @spawn command, args, callback
+      @spawn command, args, (args...) =>
+        @logCommandResults(callback, args...)

   installDependencies: (packageDirectory, options, callback = ->) ->
     process.chdir(packageDirectory)
@@ -94,13 +95,7 @@
           options.callback(error)
         else
           tasks = []
-          tasks.push (callback) => @cloneRepository repoUrl, packageDirectory, options, (code, stderr='', stdout='') =>
-            if code is 0
-              @logSuccess()
-              callback()
-            else
-              @logFailure()
-              callback("#{stdout}\n#{stderr}".trim())
+          tasks.push (callback) => @cloneRepository repoUrl, packageDirectory, options, callback

           tasks.push (callback) => @installDependencies packageDirectory, options, callback


NAM-216 grunt serverを任意のポートで実行できるようにする

NAM-216 grunt serverを任意のポートで実行できるようにする

--- www_dev/build/tasks/server.coffee
+++ www_dev/build/tasks/server.coffee
@@ -4,7 +4,7 @@
   @config "server",
     options:
       host: "0.0.0.0"
-      port: 8000
+      port: process.env.PORT || 8000

     development: {}


fixed issue with fetch value regarding nodes

--- src/core/fetch/value.coffee
+++ src/core/fetch/value.coffee
@@ -36,7 +36,7 @@
         if vars[m].changed
           changed = true
           break
-      if d3plus of node and variable of node.d3plus.data and !changed
+      if d3plus of node and "data" of node.d3plus and variable of node.d3plus.data and !changed
         return node.d3plus.data[variable]

     node = node[depth]
@@ -89,6 +89,7 @@

   if (nodeObject and typeof variable is "string" and
       variable not of node and "d3plus" of node)
+    node.d3plus.data = {} unless "data" of node.d3plus
     node.d3plus.data[variable] = val

   if val instanceof Array and val.length is 1 then val[0] else val


Fix to sentence.

Fix to sentence.

--- js/data.coffee
+++ js/data.coffee
@@ -322,7 +322,7 @@
 北京比伦敦热吗？上海比不比伦敦热？
 That is teacher Wang, he is not a Japanese teacher, is an English teacher.
 那是王老师，他不是日文老师，是英文老师。
-Here isn't good, there isn't good, here-there both aren't good.
+Here not good, there also not good, here-there both are not good.
 这儿不好，那儿也不好，这儿那儿都不好。
 Although I like reading Chinese books I don't have Chinese books
 虽然我喜欢看中文书，可是我没有中文书。


add every and all utility to generate component for list and hash

--- src/core/instantiate.coffee
+++ src/core/instantiate.coffee
@@ -99,4 +99,34 @@
 ###
 exports.each = (attrs, list, itemFn, options) ->
   if isAttrs(attrs) then new Tag('div', attrs, [new Each(list, itemFn, options)])
-  else new Each(attrs, list, itemFn)+  else new Each(attrs, list, itemFn)
+
+exports.every = (attrs, list, itemFn) ->
+  if isAttrs(attrs)
+    children = []
+    for item, i in list
+      children.push itemFn(item, i, list)
+    new Tag('div', attrs, [new List(children)])
+  else
+    # attrs become list, list become itemFn
+    children = []
+    for item, i in attrs
+      children.push list(item, i, attrs)
+    new List(children)
+
+exports.all = (attrs, hash, itemFn) ->
+  if isAttrs(attrs)
+    children = []
+    i = 0
+    for key, value of hash
+      children.push itemFn(key, value, i, hash)
+      i++
+    new Tag('div', attrs, [new List(children)])
+  else
+    # attrs become list, list become itemFn
+    children = []
+    i = 0
+    for key, value of attrs
+      children.push itemFn(key, value, i, hash)
+      i++
+    new List(children)


timing is everyting

timing is everyting

--- client.coffee
+++ client.coffee
@@ -14,7 +14,7 @@
 Plugin = require 'plugin'

 BUFFER_TIME = 1000
-MAGICNUMBER = 275
+MAGICNUMBER = 300

 exports.render = ->
 	# create local copy of the scores
@@ -39,7 +39,7 @@

 	Ui.card !->
 		renderButton buffer
-		renderMagic buffer, localScores
+		renderMagic localScores
 		renderFunny()

 	Obs.observe !->
@@ -70,9 +70,10 @@
 				Db.shared.incr 'counters', App.userId(), bufferedClicks
 			buffering.set false

-renderMagic = (buffer, localScores) !->
+renderMagic = (localScores) !->
 	Obs.observe !->
-		if localScores.get('counters', App.userId()) is MAGICNUMBER
+		userCurrent = localScores.get('counters', App.userId())
+		if userCurrent >= MAGICNUMBER and userCurrent < MAGICNUMBER + 25
 			Dom.div !->
 				Dom.animate
 						create:


Fix issues with bootstrap popovers not appearing properly due to data not being populated prior to update being called.

--- app/assets/javascripts/population_chart.js.coffee
+++ app/assets/javascripts/population_chart.js.coffee
@@ -14,15 +14,32 @@

       boxGroup.append('rect')
         .attr('class', 'denom')
+        # popover reports on the performance denominator, which doesn't include exclusions/exceptions
+        .attr('data-content', "Denominator: #{data.performanceDenominator}")
+        .attr('data-trigger', "hover focus")
+        .attr('data-placement', "bottom")
+        .attr('data-container', 'body')

       boxGroup.append('rect')
         .attr('class', 'numer')
+        .attr('data-content', "Numerator: #{data.NUMER}")
+        .attr('data-trigger', "hover focus")
+        .attr('data-placement', "bottom")
+        .attr('data-container', 'body')

       boxGroup.append('rect')
         .attr('class', 'denex')
+        .attr('data-content', "Exclusion: #{data.DENEX}")
+        .attr('data-trigger', "hover focus")
+        .attr('data-placement', "bottom")
+        .attr('data-container', 'body') if data.DENEX > 0

       boxGroup.append('rect')
         .attr('class', 'denexc')
+        .attr('data-content', "Exceptions: #{data.DENEXCEP}")
+        .attr('data-trigger', "hover focus")
+        .attr('data-placement', "bottom")
+        .attr('data-container', 'body') if data.DENEXCEP > 0

       if data.lower_is_better?
         arrow = gEnter.append('g')
@@ -94,34 +111,26 @@
       .attr('width', xScale(data.DENOM))
       .attr('height', height)
       .attr('x', margin.left)
-      # popover reports on the performance denominator, which doesn't include exclusions/exceptions
-      .attr('data-content', "Denominator: #{data.performanceDenominator}")
-      .attr('data-trigger', "hover focus")
-      .attr('data-container', 'body')
+
+

     this.svg.selectAll(".numer").transition()
       .attr('width', xScale(data.NUMER))
       .attr('height', height)
       .attr('x', margin.left)
-      .attr('data-content', "Numerator: #{data.NUMER}")
-      .attr('data-trigger', "hover focus")
-      .attr('data-container', 'body')
+

     this.svg.selectAll(".denex").transition()
       .attr('width', xScale(data.DENEX))
       .attr('height', height)
       .attr('x', margin.left + xScale(data.NUMER))
-      .attr('data-content', "Exclusion: #{data.DENEX}")
-      .attr('data-trigger', "hover focus")
-      .attr('data-container', 'body') if data.DENEX > 0
+

     this.svg.selectAll(".denexc").transition()
       .attr('width', xScale(data.DENEXCEP))
       .attr('height', height)
       .attr('x', margin.left + xScale(data.NUMER + data.DENEX))
-      .attr('data-content', "Exceptions: #{data.DENEXCEP}")
-      .attr('data-trigger', "hover focus")
-      .attr('data-container', 'body') if data.DENEXCEP > 0
+

     if data.lower_is_better?
       arrowOffset = if data.lower_is_better then margin.left else margin.left + xScale(data.DENOM)


Fidgeting

Fidgeting

--- app/assets/javascripts/roofpig/Pieces3D.js.coffee
+++ app/assets/javascripts/roofpig/Pieces3D.js.coffee
@@ -59,27 +59,27 @@
           scene.add(new_3d_piece)

   _add_sticker: (side, piece_3d, sticker) ->
-    [dx, dy] = this._offsets(side, 0.90, false)
+    [dx, dy] = this._offsets(side.normal, 0.90, false)
     piece_3d.add(this._3d_diamond(this._square_center(side, piece_3d.middle, 1.0002), dx, dy, sticker.color))

     if sticker.x_color
       this._add_X(side, piece_3d, sticker.x_color, 1.0004, true)

   _add_hover_sticker: (side, piece_3d, sticker, hover) ->
-    [dx, dy] = this._offsets(side, 0.98, true)
+    [dx, dy] = this._offsets(side.normal, 0.98, true)
     piece_3d.add(this._3d_diamond(this._square_center(side, piece_3d.middle, hover), dx, dy, sticker.color))

     if sticker.x_color
       this._add_X(side, piece_3d, sticker.x_color, hover - 0.0002, false)

   _add_X: (side, piece_3d, color, hover, reversed) ->
-    [dx, dy] = this._offsets(side, 0.54, reversed)
+    [dx, dy] = this._offsets(side.normal, 0.54, reversed)
     center = this._square_center(side, piece_3d.middle, hover)
     piece_3d.add(this._3d_rect(center, dx, v3_x(dy, 0.14), color))
     piece_3d.add(this._3d_rect(center, v3_x(dx, 0.14), dy, color))

   _add_plastic: (side, piece_3d, color) ->
-    [dx, dy] = this._offsets(side, 1.0, true)
+    [dx, dy] = this._offsets(side.normal, 1.0, true)
     piece_3d.add(this._3d_diamond(this._square_center(side, piece_3d.middle, 1), dx, dy, color))

   _square_center: (side, piece_center, distance) ->
@@ -102,10 +102,10 @@

     new THREE.Mesh(geo, new THREE.MeshBasicMaterial(color: color))

-  _offsets: (side, sticker_size, reversed) ->
-    axis2 = v3(side.normal.y, side.normal.z, side.normal.x)
-    axis3 = v3(side.normal.z, side.normal.x, side.normal.y)
-    flip = (side.normal.y + side.normal.z + side.normal.x) * (if reversed then -1.0 else 1.0)
+  _offsets: (axis1, sticker_size, reversed) ->
+    axis2 = v3(axis1.y, axis1.z, axis1.x)
+    axis3 = v3(axis1.z, axis1.x, axis1.y)
+    flip = (axis1.y + axis1.z + axis1.x) * (if reversed then -1.0 else 1.0)

     dx = v3_add(axis2, axis3).multiplyScalar(sticker_size * flip)
     dy = v3_sub(axis2, axis3).multiplyScalar(sticker_size)


(feature) Get using multiple params.

(feature) Get using multiple params.

--- src/rest.coffee
+++ src/rest.coffee
@@ -11,6 +11,11 @@
       (app, config) ->
         app.get rest.path, (req,res) ->
           promisedCallback rest.dataCall(req.params[rest.param]), res, config, rest.errStatus
+    getByParams: (rest) ->
+      (app, config) ->
+        app.get rest.path, (req,res) ->
+          args = _.map rest.params, (p) -> req.params[p]
+          promisedCallback rest.dataCall.apply(null, args), res, config, rest.errStatus
     getBySessionUID: (rest) ->
       (app, config) ->
         app.get rest.path, (req,res) ->


FormFor depends on ui.select

FormFor depends on ui.select

--- src/formFor/form-for.coffee
+++ src/formFor/form-for.coffee
@@ -1,4 +1,4 @@
-app = angular.module 'metovular.formFor', [ 'classy', 'ui-select' ]
+app = angular.module 'metovular.formFor', [ 'classy', 'ui.select' ]

 app.directive 'maFormFor', [ ->
   {


Change writable => isRunning for clarity.

--- lib/analysis_server.coffee
+++ lib/analysis_server.coffee
@@ -10,7 +10,7 @@
 class AnalysisServer
   id: 1
   promiseMap = {}
-  writable: false
+  isRunning: false

   constructor: ->
     @emitter = new Emitter()
@@ -28,10 +28,10 @@
     cmd = Utils.getExecPath 'dart'
     Utils.whenDartSdkFound =>
       @process = spawn cmd, args
-      @writable = true
+      @isRunning = true
       @process.stdout.pipe(StreamSplitter("\n")).on 'token', @processMessage
       @process.on 'exit', =>
-        @writable = false
+        @isRunning = false

       # Set analysis root.
       @setAnalysisRoots analysisRoots
@@ -42,7 +42,7 @@
   sendMessage: (obj) =>
     obj.id ||= "dart-tools-#{(@id++)}"
     msg = JSON.stringify(obj)
-    if @writable
+    if @isRunning
       @process?.stdin?.write(msg + "\n")

     deferred = Q.defer()


More classes

More classes

--- resources/assets/coffee/react/beatmap-discussions/new-discussion.coffee
+++ resources/assets/coffee/react/beatmap-discussions/new-discussion.coffee
@@ -21,25 +21,23 @@

 bn = 'beatmap-discussion-new'

-BeatmapDiscussions.NewDiscussion = React.createClass
-  mixins: [React.addons.PureRenderMixin]
+class BeatmapDiscussions.NewDiscussion extends React.PureComponent
+  constructor: (props) ->
+    super props
+
+    @throttledPost = _.throttle @post, 1000
+
+    @state =
+      message: ''
+      timestamp: null

-  getInitialState: ->
-    message: ''
-    timestamp: null
-
-
-  componentDidMount: ->
-    @throttledPost = _.throttle @post, 1000
-
-
-  componentWillUnmount: ->
+  componentWillUnmount: =>
     @postXhr?.abort()
     @throttledPost.cancel()

-  render: ->
+  render: =>
     div
       className: 'osu-page osu-page--small'
       div
@@ -91,18 +89,18 @@
                   onClick: @post

-  setTimestamp: (e) ->
+  setTimestamp: (e) =>
     @setState timestamp: e.currentTarget.value

-  setMessage: (e) ->
+  setMessage: (e) =>
     if @props.mode == 'timeline'
       callback = @parseTimestamp

     @setState message: e.currentTarget.value, callback

-  post: (e) ->
+  post: (e) =>
     return unless @validPost()

     @postXhr?.abort()
@@ -143,7 +141,7 @@
     .always LoadingOverlay.hide

-  submitButton: (type) ->
+  submitButton: (type) =>
     el BigButton,
       key: type
       modifiers: ['beatmap-discussion']
@@ -155,7 +153,7 @@
         onClick: @post

-  validPost: ->
+  validPost: =>
     return false if @state.message.length == 0

     if @props.mode == 'timeline'
@@ -164,7 +162,7 @@
       true

-  parseTimestamp: ->
+  parseTimestamp: =>
     timestampRe = @state.message.match /\b(\d{2,}):(\d{2})[:.](\d{3})\b/

     @setState timestamp:


fixed other properties not read from docpad.coffee

--- src/sitemap.plugin.coffee
+++ src/sitemap.plugin.coffee
@@ -64,8 +64,8 @@
 					# create document's sitemap data
 					data =
 						url: document.get('url')
-						changefreq: document.get('changefreq') ? defaultConfig.changefreq
-						priority: document.get('priority') ? defaultConfig.priority
+						changefreq: document.get('changefreq') ? sitemapData.changefreq
+						priority: document.get('priority') ? sitemapData.priority

 					docpad.log "debug", data
 					sitemapData.urls.push data


Permissions: All permissions are retrieved for admin users

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -21,6 +21,7 @@
   @trait __dirname, '../traits/taggable'
   @trait __dirname, '../traits/notifying'
   @trait __dirname, '../traits/flaggable'
+  @trait __dirname, '../traits/protected'

   JStorage         = require './storage'
   JAppStorage      = require './appstorage'
@@ -40,6 +41,8 @@
   Validators = require './group/validators'

   @share()
+
+  allPerms = @getAllPermissions()

   @set
     softDelete          : yes
@@ -1357,24 +1360,26 @@
     slug = client.context.group ? 'koding'
     JGroup.one {slug}, (err, group)=>
       return callback err  if err
-      group.fetchPermissionSet (err, permissionSet)=>
+      cb = (err, roles)=>
         return callback err  if err
-        cb = (err, roles)=>
-          return callback err  if err
-
-          perms = (perm.permissions.slice()\
+        {flatten} = require 'underscore'
+        if "admin" in roles
+          callback null, flatten(allPerms), roles
+        else
+          group.fetchPermissionSet (err, permissionSet)=>
+            return callback err  if err
+            perms = (perm.permissions.slice()\
                   for perm in permissionSet.permissions\
                     # if user is an admin, add all
                     # roles into permission set
                   when perm.role in roles or 'admin' in roles)

-          {flatten} = require 'underscore'
-          callback null, flatten(perms), roles
-
-        if this instanceof JAccount
-          group.fetchMyRoles client, cb
-        else
-          cb null, ['guest']
+            callback null, flatten(perms), roles
+
+      if this instanceof JAccount
+        group.fetchMyRoles client, cb
+      else
+        cb null, ['guest']

   oldAddTags = @::addTags
   addTags: secure (client, tags, options, callback)->


store suggestions as language:word instead of word

avoid words like 'constructor' from accessing properties of
suggestions object.

--- services/spelling/app/coffee/ASpell.coffee
+++ services/spelling/app/coffee/ASpell.coffee
@@ -11,9 +11,10 @@
 		@runAspellOnWords language, words, (error, output) =>
 			return callback(error) if error?
 			#output = @removeAspellHeader(output)
-			suggestions = @getSuggestions(output)
+			suggestions = @getSuggestions(language, output)
 			results = []
 			hits = 0
+			addToCache = {}
 			for word, i in words
 				key = language + ':' + word
 				cached = cache.get(key)
@@ -25,16 +26,22 @@
 					else
 						results.push index: i, suggestions: cached
 				else
-					if suggestions[word]?
-						cache.set(key, suggestions[word])
-						results.push index: i, suggestions: suggestions[word]
+					if suggestions[key]?
+						addToCache[key] = suggestions[key]
+						results.push index: i, suggestions: suggestions[key]
 					else
 						# a valid word, but uncached
-						cache.set(key, true)
+						addToCache[key] = true
+
+			# update the cache after processing all words, to avoid cache
+			# changing while we use it
+			for k, v in addToCache
+				cache.set(k, v)
+
 			logger.log hits: hits, total: words.length, hitrate: hits/words.length, "cache hit rate"
 			callback null, results

-	getSuggestions: (output) ->
+	getSuggestions: (language, output) ->
 		lines = output.split("\n")
 		suggestions = {}
 		for line in lines
@@ -43,12 +50,12 @@
 				if parts.length > 1
 					word = parts[1]
 					suggestionsString = line.slice(line.indexOf(":") + 2)
-					suggestions[word] = suggestionsString.split(", ")
+					suggestions[language + ":" + word] = suggestionsString.split(", ")
 			else if line[0] == "#" # No suggestions
 				parts = line.split(" ")
 				if parts.length > 1
 					word = parts[1]
-					suggestions[word] = []
+					suggestions[language + ":" + word] = []
 		return suggestions

 	#removeAspellHeader: (output) -> output.slice(1)


Allow switching between versions in the same set

For example, the multiple versions of Fallen Empires cards.

DFCs and flip cards won't switch printings. This isn't a problem for now
since a DFC or flip card has yet to be reprinted.

--- src/scry.coffee
+++ src/scry.coffee
@@ -117,7 +117,8 @@
             printings.append p
     printings.on 'click.scry', '.scry-printing', (e) ->
         set = $(this).data('scry')
-        return if set.setcode == card.setcode
+        return if set.multiverseid == card.multiverseid
+        return if set.setcode == card.setcode and (card.layout == 'flip' or card.layout == 'double-faced')
         $.extend true, card, set
         content.call $(this).parents('.scry'), card


SocialWorker: export session username

SocialWorker: export session username

--- workers/social/lib/social/main.coffee
+++ workers/social/lib/social/main.coffee
@@ -90,10 +90,10 @@

         usertracker.track account.profile.nickname

-        { clientIP, clientId: sessionToken } = session
+        { clientIP, clientId: sessionToken, username } = session

         callback {
-          sessionToken, context, clientIP,
+          sessionToken, context, clientIP, username
           connection:{ delegate : account }
         }


Removed path.join call in phantom_runner to fix failing dom tests

--- tests/dom_tests/phantom_runner.coffee
+++ tests/dom_tests/phantom_runner.coffee
@@ -21,7 +21,7 @@
 page.onResourceError = (resourceError) ->
   console.log(resourceError.errorString)

-testfile = path.join(path.dirname(system.args[0]), 'dom_tests.html')
+testfile = path.dirname(system.args[0]) + '/dom_tests.html'
 page.open testfile, (status) ->
   if status != 'success'
     console.log 'Unable to load tests.'


:fire: Remove old coffee file

:fire: Remove old coffee file

--- lib/editor-registry.coffee
+++ lib/editor-registry.coffee
@@ -1,51 +0,0 @@
-{Emitter, CompositeDisposable} = require('atom')
-EditorLinter = require('./editor-linter')
-
-class EditorRegistry
-  constructor: ->
-    @emitter = new Emitter
-    @subscriptions = new CompositeDisposable
-    @subscriptions.add @emitter
-    @editorLinters = new Map()
-    @editorLintersByPath = new Map()
-
-  create: (textEditor) ->
-    editorLinter = new EditorLinter(textEditor)
-    if currentPath = textEditor.getPath()
-      @editorLintersByPath.set(currentPath, editorLinter)
-    textEditor.onDidChangePath (path) =>
-      @editorLintersByPath.delete(currentPath)
-      @editorLintersByPath.set(currentPath = path, editorLinter)
-
-    @editorLinters.set(textEditor, editorLinter)
-    editorLinter.onDidDestroy =>
-      @editorLinters.delete(textEditor)
-    @emitter.emit('observe', editorLinter)
-    return editorLinter
-
-  has: (textEditor) ->
-    return @editorLinters.has(textEditor)
-
-  forEach: (callback) ->
-    @editorLinters.forEach(callback)
-
-  ofPath: (path) ->
-    return @editorLintersByPath.get(path)
-
-  ofTextEditor: (editor) ->
-    return @editorLinters.get(editor)
-
-  ofActiveTextEditor: ->
-    return @ofTextEditor(atom.workspace.getActiveTextEditor())
-
-  observe: (callback) ->
-    @forEach(callback)
-    @emitter.on('observe', callback)
-
-  dispose: ->
-    @subscriptions.dispose()
-    @editorLinters.forEach (editorLinter) ->
-      editorLinter.dispose()
-    @editorLinters.clear()
-
-module.exports = EditorRegistry


Adds non case-sensitive sort to list()

Adds non case-sensitive sort to list()

--- src/fs-plus.coffee
+++ src/fs-plus.coffee
@@ -130,8 +130,9 @@
     return [] unless fsPlus.isDirectorySync(rootPath)
     paths = fs.readdirSync(rootPath)
     paths = fsPlus.filterExtensions(paths, extensions) if extensions
+    paths = paths.sort (a, b) -> a.toLowerCase().localeCompare(b.toLowerCase())
     paths = paths.map (childPath) -> path.join(rootPath, childPath)
-    paths.sort (a, b) -> a.toLowerCase().localeCompare(b.toLowerCase())
+    paths

   # Public: Asynchronously lists the files and directories in the given path.
   # The listing is not recursive.
@@ -148,6 +149,7 @@
         done(error)
       else
         paths = fsPlus.filterExtensions(paths, extensions) if extensions
+        paths = paths.sort (a, b) -> a.toLowerCase().localeCompare(b.toLowerCase())
         paths = paths.map (childPath) -> path.join(rootPath, childPath)
         done(null, paths)


fix config

fix config

--- app/config.coffee
+++ app/config.coffee
@@ -25,7 +25,7 @@
       type: 'octoblu:user'

     getDeviceToken = (uuid) =>
-      @meshbludb.generateAndStoreToken uuid, (device) =>
+      @meshbludb.generateAndStoreToken uuid, (error, device) =>
         device.id = profileId
         done null, device


reduce testing

reduce testing

--- src/test.coffee
+++ src/test.coffee
@@ -19,8 +19,8 @@
 {test_render} = require './test/test_render'

 run_tests = (rx) ->
-  test_god(test, rx)
-  test_world(test, rx)
+#  test_god(test, rx)
+#  test_world(test, rx)
 #  test_config(test, rx)
 #  test_draw(test, rx)
   test_game(test, rx)


Add support for contentRegex

Add support for contentRegex

--- src/grammar.coffee
+++ src/grammar.coffee
@@ -21,7 +21,7 @@

   constructor: (@registry, options={}) ->
     {@name, @fileTypes, @scopeName, @foldingStopMarker, @maxTokensPerLine, @maxLineLength} = options
-    {injections, injectionSelector, patterns, repository, firstLineMatch} = options
+    {injections, injectionSelector, patterns, repository, firstLineMatch, contentRegex} = options

     @emitter = new Emitter
     @repository = null
@@ -36,6 +36,11 @@
       @firstLineRegex = new OnigRegExp(firstLineMatch)
     else
       @firstLineRegex = null
+
+    if contentRegex
+      @contentRegex = new OnigRegExp(contentRegex)
+    else
+      @contentRegex = null

     @fileTypes ?= []
     @includedGrammarScopes = []


:memo: doc Grammar class

:memo: doc Grammar class

--- src/grammar.coffee
+++ src/grammar.coffee
@@ -12,6 +12,10 @@

 pathSplitRegex = new RegExp("[#{_.escapeRegExp(path.sep)}.]")

+# Public: Grammar that tokenizes lines of text.
+#
+# This class should not be instantiated directly but instead obtained from
+# a {GrammarRegistry} by calling {GrammarRegistry.loadGrammar}.
 module.exports =
 class Grammar
   Emitter.includeInto(this)
@@ -40,6 +44,101 @@

     @fileTypes ?= []
     @includedGrammarScopes = []
+
+  # Public: Tokenize all lines in the given text.
+  #
+  # * text: A {String} containing one or more lines.
+  #
+  # Returns an {Array} of token arrays for each line tokenized.
+  tokenizeLines: (text) ->
+    lines = text.split('\n')
+    ruleStack = null
+    for line, lineNumber in lines
+      {tokens, ruleStack} = @tokenizeLine(line, ruleStack, lineNumber is 0)
+      tokens
+
+  # Public: Tokenize the line of text.
+  #
+  # * line: A {String} of text to tokenize.
+  #
+  # * ruleStack: An optional {Array} of rules previously returned from this
+  #              method. This should be null when tokenizing the first line in
+  #              the file.
+  #
+  # * firstLine: A {Boolean} denoting whether this is the first line in the file
+  #              which defaults to `false`. This should be `true` when
+  #              tokenizing the first line in the file.
+  #
+  # Returns an {Object} containing `tokens` and `ruleStack` properties:
+  #   * tokens: An {Array} of tokens covering the entire line of text.
+  #
+  #   * ruleStack: An {Array} of rules representing the tokenized state at the
+  #                end of the line. These should be passed back into this method
+  #                when tokenizing the next line in the file.
+  tokenizeLine: (line, ruleStack, firstLine=false) ->
+    if ruleStack?
+      ruleStack = ruleStack.slice()
+    else
+      ruleStack = [@getInitialRule()]
+    originalRuleStack = ruleStack
+
+    tokens = []
+    position = 0
+
+    loop
+      scopes = @scopesFromStack(ruleStack)
+      previousRuleStackLength = ruleStack.length
+      previousPosition = position
+
+      if tokens.length >= @getMaxTokensPerLine() - 1
+        token = @createToken(line[position..], scopes)
+        tokens.push token
+        ruleStack = originalRuleStack
+        break
+
+      break if position == line.length + 1 # include trailing newline position
+
+      if match = _.last(ruleStack).getNextTokens(ruleStack, line, position, firstLine)
+        { nextTokens, tokensStartPosition, tokensEndPosition } = match
+        if position < tokensStartPosition # unmatched text before next tokens
+          tokens.push(@createToken(line[position...tokensStartPosition], scopes))
+
+        tokens.push(nextTokens...)
+        position = tokensEndPosition
+
+        # break if at end of the line and no tokens were in the match and no rule was pushed to the stack
+        if position is line.length and nextTokens.length is 0 and ruleStack.length is previousRuleStackLength
+          if tokens.length is 0 # push filler token for unmatched text
+            tokens.push(@createToken(line[position...line.length], scopes))
+          break
+
+      else # push filler token for unmatched text at end of line
+        if position < line.length or line.length == 0
+          tokens.push(@createToken(line[position...line.length], scopes))
+        break
+
+      if position == previousPosition
+        if ruleStack.length == previousRuleStackLength
+          console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack))
+          ruleStack.pop()
+        else if ruleStack.length > previousRuleStackLength # Stack size increased with zero length match
+          [penultimateRule, lastRule] = ruleStack[-2..]
+
+          # Same exact rule was pushed but position wasn't advanced
+          if lastRule? and lastRule == penultimateRule
+            popStack = true
+
+          # Rule with same scope name as previous rule was pushed but position wasn't advanced
+          if lastRule?.scopeName? and penultimateRule.scopeName == lastRule.scopeName
+            popStack = true
+
+          if popStack
+            ruleStack.pop()
+            tokens.push(@createToken(line[position...line.length], scopes))
+            break
+
+    rule.clearAnchorPosition() for rule in ruleStack
+    {tokens, ruleStack}

   activate: ->
     @registry.addGrammar(this)
@@ -118,78 +217,6 @@

   createPattern: (options) -> new Pattern(this, @registry, options)

-  tokenizeLine: (line, ruleStack, firstLine=false) ->
-    if ruleStack?
-      ruleStack = ruleStack.slice()
-    else
-      ruleStack = [@getInitialRule()]
-    originalRuleStack = ruleStack
-
-    tokens = []
-    position = 0
-
-    loop
-      scopes = @scopesFromStack(ruleStack)
-      previousRuleStackLength = ruleStack.length
-      previousPosition = position
-
-      if tokens.length >= @getMaxTokensPerLine() - 1
-        token = @createToken(line[position..], scopes)
-        tokens.push token
-        ruleStack = originalRuleStack
-        break
-
-      break if position == line.length + 1 # include trailing newline position
-
-      if match = _.last(ruleStack).getNextTokens(ruleStack, line, position, firstLine)
-        { nextTokens, tokensStartPosition, tokensEndPosition } = match
-        if position < tokensStartPosition # unmatched text before next tokens
-          tokens.push(@createToken(line[position...tokensStartPosition], scopes))
-
-        tokens.push(nextTokens...)
-        position = tokensEndPosition
-
-        # break if at end of the line and no tokens were in the match and no rule was pushed to the stack
-        if position is line.length and nextTokens.length is 0 and ruleStack.length is previousRuleStackLength
-          if tokens.length is 0 # push filler token for unmatched text
-            tokens.push(@createToken(line[position...line.length], scopes))
-          break
-
-      else # push filler token for unmatched text at end of line
-        if position < line.length or line.length == 0
-          tokens.push(@createToken(line[position...line.length], scopes))
-        break
-
-      if position == previousPosition
-        if ruleStack.length == previousRuleStackLength
-          console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack))
-          ruleStack.pop()
-        else if ruleStack.length > previousRuleStackLength # Stack size increased with zero length match
-          [penultimateRule, lastRule] = ruleStack[-2..]
-
-          # Same exact rule was pushed but position wasn't advanced
-          if lastRule? and lastRule == penultimateRule
-            popStack = true
-
-          # Rule with same scope name as previous rule was pushed but position wasn't advanced
-          if lastRule?.scopeName? and penultimateRule.scopeName == lastRule.scopeName
-            popStack = true
-
-          if popStack
-            ruleStack.pop()
-            tokens.push(@createToken(line[position...line.length], scopes))
-            break
-
-    rule.clearAnchorPosition() for rule in ruleStack
-    {tokens, ruleStack}
-
-  tokenizeLines: (text) ->
-    lines = text.split('\n')
-    ruleStack = null
-    for line, lineNumber in lines
-      {tokens, ruleStack} = @tokenizeLine(line, ruleStack, lineNumber is 0)
-      tokens
-
   getMaxTokensPerLine: ->
     @maxTokensPerLine


avoid silent failure for TeX 'No pages of output.'

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -112,15 +112,17 @@
   log "#{xelatex_command} #{parameters.join ' '}"
   #.........................................................................................................
   pdf_from_tex = ( next ) =>
-    count += 1
+    count          += 1
+    cp              = ( require 'child_process' ).spawn xelatex_command, parameters
+    error_detected  = false
     urge "run ##{count}"
-    # CND.spawn xelatex_command, parameters, ( error, data ) =>
-    cp = ( require 'child_process' ).spawn xelatex_command, parameters
     #.......................................................................................................
     cp.stdout
       .pipe D.$split()
-      .pipe D.$observe ( line ) =>
-        echo CND.grey line
+      #.....................................................................................................
+      .pipe D.$observe ( line ) => error_detected = true if line is 'No pages of output.'
+      .pipe D.$observe ( line ) => alert line if error_detected
+      .pipe D.$observe ( line ) => echo ( if error_detected then CND.red else CND.grey ) line
     #.......................................................................................................
     cp.stderr
       .pipe D.$split()
@@ -139,6 +141,8 @@
         if message.length > 0
           alert message
           return handler message
+      if error_detected
+        return handler new Error "detected unknown error, see transcript"
       digest = CND.id_from_route aux_locator
       if digest is last_digest
         echo ( CND.grey badge ), CND.lime "done."


Remove stray debugger

Remove stray debugger

Signed-off-by: Nathan Sobo <2e8aa918660411855c6d44d5bb2da677aa033255@github.com>

--- src/history.coffee
+++ src/history.coffee
@@ -287,7 +287,6 @@
           throw new Error("Unexpected undoStack entry type during serialization: #{entry.constructor.name}")

   deserializeStack: (stack) ->
-    debugger
     for entry in stack
       switch entry.type
         when 'checkpoint'


ActivitySidebar: Cache machinelist instances by name.

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -721,9 +721,11 @@

     KD.remote.api.Sidebar.fetchEnvironment (err, data) =>
       @machineLists = []
+      @machineListsByName = {}
       @addSubView @ownMachinesList = new SidebarOwnMachinesList {}, data.own

       @machineLists.push @ownMachinesList
+      @machineListsByName.own = @ownMachinesList

   # handleMachineItemClick: (machineItem, event) ->


Activity: sidebar indentation fix

Activity: sidebar indentation fix

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -209,7 +209,7 @@
     return item

-   removeItem: (id) ->
+  removeItem: (id) ->

     if item = @itemsById[id]


add whole formulas lib as calc

add whole formulas lib as calc

--- src/core/Renderer.coffee
+++ src/core/Renderer.coffee
@@ -8,7 +8,7 @@
 		options ?= {}
 		options.pretty = true
 		options.compileDebug = true
-		options.convert = calc.convert.convert
+		options.calc = calc
 		options.country = country
 		return jade.renderFile(renderObj.template, options)
 	else


Remove test file reference from paths.coffee

--- config/paths.coffee
+++ config/paths.coffee
@@ -9,7 +9,6 @@
       "app/**/*service.coffee"
     ]
     scripts:  [ "app/app.js"
-      "app/app2.js"
       "app/**/*controller.js"
       "app/**/*directive.js"
       "app/**/*filter.js"
@@ -69,4 +68,4 @@
     'docs'
     '../agt-build'
     '../agt-dist'
-  ]+  ]


Unsubscribe on view close.

Unsubscribe on view close.

--- lib/stacktrace-view.coffee
+++ lib/stacktrace-view.coffee
@@ -28,6 +28,9 @@
         @addClass 'activated'
       else
         @removeClass 'activated'
+
+  beforeRemove: ->
+    @unsubscribe Stacktrace

   # Internal: Return the window title.
   #


Fix feed items slicing.

Fix feed items slicing.

--- scripts/chat-logger.coffee
+++ scripts/chat-logger.coffee
@@ -216,7 +216,7 @@
     catch e
       throw e if e != "break"

-    result.slice(0, ITEM_COUNT).map (v) ->
+    result.reverse().slice(0, ITEM_COUNT).map (v) ->
       d = new Date _.first(v).date

       title: d.toUTCString()


Syle up the fundraising command

Syle up the fundraising command

--- scripts/fundraising.coffee
+++ scripts/fundraising.coffee
@@ -30,7 +30,7 @@
           robot.send "I had trouble fetching the total, try again later?"
         else
           data = JSON.parse body
-          robot.send "We've raised $#{data.sum.formatMoney()} \\o/"
+          robot.send "## We've raised\n# #{data.sum.formatMoney()}\n:parrotbeer:"

   robot.respond /fundraising/i, getTotal
   robot.respond /show me the money/i, getTotal


Better example naming

Better example naming

--- test.coffee
+++ test.coffee
@@ -36,23 +36,22 @@
       liar.funkyFunction('apples')
         .should.equal 98

-  describe 'Expectations should be nestable', ->
+  describe 'x', ->

-    # TODO Better example naming
     liar = create_liar
-      function_called: 'outer_function'
+      function_called: 'connect'
       returns:
-        value: { aProperty: 9 }
+        value: { status: 'open' }
         on_value:
-          function_called: 'inner_function'
+          function_called: 'query'
           returns:
-            value: 'inner_return_value'
+            value: '5 little pigs'

     it 'should be possible to call inner functions', ->

-      outer = liar.outer_function()
-      outer.aProperty.should.equal 9
-      outer.inner_function().should.equal 'inner_return_value'
+      connection = liar.connect()
+      connection.status.should.equal 'open'
+      connection.query().should.equal 'inner_return_value'


Deprecate custom events on PaneView

Deprecate custom events on PaneView

--- src/workspace-view.coffee
+++ src/workspace-view.coffee
@@ -170,7 +170,7 @@
     @deprecatedViewEvents()

   deprecatedViewEvents: ->
-    originalOn = @on
+    originalWorkspaceViewOn = @on

     @on = (eventName) =>
       switch eventName
@@ -196,17 +196,40 @@
           deprecate('Use Editor::onDidChangeSelectionRange instead')
         when 'uri-opened'
           deprecate('Use Workspace::onDidOpen instead')
-      originalOn.apply(this, arguments)
+      originalWorkspaceViewOn.apply(this, arguments)

     EditorView = require './editor-view'
-    originalEditorOn = EditorView::on
+    originalEditorViewOn = EditorView::on
     EditorView::on = (eventName) ->
       switch eventName
         when 'cursor:moved'
           deprecate('Use Editor::onDidChangeCursorPosition instead')
         when 'selection:changed'
           deprecate('Use Editor::onDidChangeSelectionRange instead')
-      originalEditorOn.apply(this, arguments)
+      originalEditorViewOn.apply(this, arguments)
+
+    originalPaneViewOn = PaneView::on
+    PaneView::on = (eventName) ->
+      switch eventName
+        when 'cursor:moved'
+          deprecate('Use Editor::onDidChangeCursorPosition instead')
+        when 'pane:active-item-changed'
+          deprecate('Use Pane::onDidChangeActiveItem instead')
+        when 'pane:became-active'
+          deprecate('Use Pane::onDidActivate instead')
+        when 'pane:became-inactive'
+          deprecate('Use Pane::onDidChangeActive instead')
+        when 'pane:item-added'
+          deprecate('Use Pane::onDidAddItem instead')
+        when 'pane:item-moved'
+          deprecate('Use Pane::onDidMoveItem instead')
+        when 'pane:item-removed'
+          deprecate('Use Pane::onDidRemoveItem instead')
+        when 'pane:removed'
+          deprecate('Use Pane::onDidDestroy instead')
+        when 'selection:changed'
+          deprecate('Use Editor::onDidChangeSelectionRange instead')
+      originalPaneViewOn.apply(this, arguments)

   ###
   Section: Accessing the Workspace Model