tweaks

tweaks

--- src/editor.coffee
+++ src/editor.coffee
@@ -21,12 +21,12 @@

   constructor: (@container, enabled = true) ->
     @container = document.getElementById(@container) if _.isString(@container)
-    this.reset()
+    this.reset(true)
     this.enable() if enabled

   reset: (keepHTML = false) ->
     @ignoreDomChanges = true
-    @iframe = this.createIframe(@container)
+    @iframe = this.createIframe(@container, keepHTML)
     @doc = new Tandem.Document(this, @iframe.contentWindow.document.getElementById(TandemEditor.CONTAINER_ID))
     @currentSelection = null
     @keyboard = new Tandem.Keyboard(this)
@@ -35,7 +35,7 @@
     @ignoreDomChanges = false
     TandemEditor.editors.push(this)

-  createIframe: (parent) ->
+  createIframe: (parent, keepHTML) ->
     html = parent.innerHTML
     parent.innerHTML = ''
     iframe = document.createElement('iframe')
@@ -54,6 +54,7 @@
         line-height: 15px;
         margin: 0px;
         padding: 10px 15px;
+        white-space: pre;
       }

       ##{TandemEditor.CONTAINER_ID} { outline: none; }
@@ -101,7 +102,7 @@
       .indent-8 { margin-left: 16em; }
       .indent-9 { margin-left: 18em; }

-      .tab { display: inline-block; margin: 0px; white-space: pre; }
+      .tab { display: inline-block; margin: 0px; }
     "
     if style.styleSheet?
       style.styleSheet.cssText = css
@@ -111,7 +112,7 @@
     contentContainer = doc.createElement('div')
     contentContainer.id = Tandem.Editor.CONTAINER_ID
     doc.body.appendChild(contentContainer)
-    contentContainer.innerHTML = html
+    contentContainer.innerHTML = html if keepHTML
     return iframe

   disable: ->


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/engine.coffee
+++ src/engine.coffee
@@ -286,6 +286,6 @@

     return self

-  Engine.
+  Engine.defaultModules = ["Keyboard", "Mouse", "Background", "Delay", "GameState", "Selector", "Collision"]
   (exports ? this)["Engine"] = Engine
 )()


follow docs

follow docs

--- src/follow.coffee
+++ src/follow.coffee
@@ -11,7 +11,7 @@
   height: 10

 enemy = GameObject
-
+  x:

 player.update()
 </pre></code>


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/follow.coffee
+++ src/follow.coffee
@@ -3,7 +3,7 @@
     color: "blue"
     height: 32
     width: 32
-    # spriteName: "block" # Use the name of a sprite in the images folder
+    velco

   # Inherit from game object
   self = GameObject(I)


cleanup vectors

cleanup vectors

--- src/god/vector.coffee
+++ src/god/vector.coffee
@@ -12,8 +12,10 @@
 DIR_LEFT  =  1
 DIR_RIGHT = -1

-get_x = (v) -> if _.isArray(v) then v[X_INDEX] else v.at(X_INDEX)
-get_y = (v) -> if _.isArray(v) then v[Y_INDEX] else v.at(Y_INDEX)
+check = (v) -> if v then _.isArray(v) else throw 'invalid vector'
+
+get_x = (v) -> if check(v) then v[X_INDEX] else v.at(X_INDEX)
+get_y = (v) -> if check(v) then v[Y_INDEX] else v.at(Y_INDEX)

 exports.vector = {


fix github

fix github

--- src/github.coffee
+++ src/github.coffee
@@ -36,21 +36,21 @@
         error: options.error

     to_gist_url: (gist) ->
-      build_url = (github, id) ->
-        url = github.api_base_url + "/gists/#{id}"
-        if github.access_token
-          url += "?access_token=#{github.access_token}"
+      build_url = (site, id) ->
+        url = site.api_base_url + "/gists/#{id}"
+        if site.access_token
+          url += "?access_token=#{site.access_token}"
         url
       gist = gist.toString()
       if gist.indexOf('http') != 0
-        github = github.githubs[github.default]
-        build_url github, gist
+        site = github.githubs[github.default]
+        build_url site, gist
       else
         uri = URI gist
-        github = github.get_github uri
+        site = github.get_github uri

         if github?
           [id, _...] = uri.filename().split '.'
-          build_url github, id
+          build_url site, id
         else
           gist


modified

modified

--- src/jisilu.coffee
+++ src/jisilu.coffee
@@ -4,30 +4,33 @@
   constructor:()->

   # 分级A的接口
-  funda_url: "http://www.jisilu.cn/data/sfnew/funda_list/?___t="
+  funda: "https://www.jisilu.cn/data/sfnew/funda_list/?___t="

   # 分级B的接口
-  fundb_url: "http://www.jisilu.cn/data/sfnew/fundb_list/?___t="
+  fundb: "https://www.jisilu.cn/data/sfnew/fundb_list/?___t="
+
+  # 可交易母基金, 不明原因,出錯
+  fundmt: "https://www.jisilu.cn/data/sfnew/arbitrage_mtrade_list/?___t="

   # 母基接口
-  fundm_url: "https://www.jisilu.cn/data/sfnew/fundm_list/?___t="
+  fundm: "https://www.jisilu.cn/data/sfnew/fundm_list/?___t="

   # 分级套利的接口
-  fundarb_url: "http://www.jisilu.cn/data/sfnew/arbitrage_vip_list/?___t="
+  fundarb: "http://www.jisilu.cn/data/sfnew/arbitrage_vip_list/?___t="

   # 集思录登录接口
-  jsl_login_url: "https://www.jisilu.cn/account/ajax/login_process/"
+  jsl_login: "https://www.jisilu.cn/account/ajax/login_process/"

   # 集思录 ETF 接口
-  etf_index_url: "https://www.jisilu.cn/jisiludata/etf.php?___t="
+  etf_index: "https://www.jisilu.cn/jisiludata/etf.php?___t="
   # 黄金 ETF
-  etf_gold_url: "https://www.jisilu.cn/jisiludata/etf.php?qtype=pmetf&___t="
-  etf_money_url: "https://www.jisilu.cn/data/money_fund/list/?___t="
+  etf_gold: "https://www.jisilu.cn/jisiludata/etf.php?qtype=pmetf&___t="
+  etf_money: "https://www.jisilu.cn/data/money_fund/list/?___t="

   now: -> (new Date()).getTime()

   get: (urlname, callback)->
-    url = @["#{urlname}_url"]
+    url = @["#{urlname}"]
     options =
       url: "#{url}#{@now()}"
       json: true
@@ -35,22 +38,23 @@
     request options, (err,res, body)->
       callback(err, body) # unless err?
       #jj = (each for each in body.rows when each.id is "150152")
-      #console.log jj[0].cell
+      #console.log res,body

   getSymbols: (category, callback)->
     @get category, (err, body)->
       if err?
         callback err,null
         return
-
+
       cell = switch category
-        when 'fundm' then "base_fund_id"
+        when 'fundmt' then "base_fund_id"
         else "#{category}_id"
+
       callback null, (each.cell[cell] for each in body.rows)

 module.exports = JisiluData
 ###
-(new JisiluData()).getSymbols 'fundb', (symbols)->
+(new JisiluData()).getSymbols 'fundmt', (err, symbols)->
   console.log symbols
 ###


delete elems structure when not needed

delete elems structure when not needed

--- src/linker.coffee
+++ src/linker.coffee
@@ -77,6 +77,7 @@
             else if match tag, el
                 elems.shift() # rm el
                 mask tag, el # apply
+                delete parent._elems if elems.length is 0
                 next(tag)

             else # create new tag
@@ -102,6 +103,7 @@
                 new_tag(tag, el, repeat)

             else # list is empty
+                delete tag._elems
                 next(tag)
         do repeat


(feature) Add activation and due date parser

--- src/manage.coffee
+++ src/manage.coffee
@@ -17,6 +17,8 @@
     rdb.table('Exercises').get(id).run(con)

   storeExercise: (exercise) ->
+    exercise.activationDate = rdb.ISO8601(exercise.activationDate)
+    exercise.dueDate = rdb.ISO8601(exercise.dueDate)
     (rdb.table("Exercises").insert exercise, conflict: "update").run con

   listExercises: ->


Client: Activity: DesktopNotifications: Added new classnames to notification settings modal

--- client/activity/lib/components/publicchannelnotificationsettingsmodal/index.coffee
+++ client/activity/lib/components/publicchannelnotificationsettingsmodal/index.coffee
@@ -125,15 +125,20 @@
     buttonConfirmClassName : 'Button--primary'

+  getContentClassName: -> classnames
+    'ChannelNotifications-content': yes
+    'isMuted' : @state.channelNotificationSettings.get 'isMuted'
+
+
   render: ->

     return null  unless @state.channelNotificationSettings

     <ActivityModal {...@getModalProps()}>
-

-        <fieldset className='Reactivity-fieldset'>
+

+        <fieldset className='Reactivity-fieldset desktopNotifications'>
           <legend className='Reactivity-legend'>Web notifications:</legend>
-          <RadioGroup name="webNotifications" ref='webNotifications'
+          <RadioGroup name='webNotifications' ref='webNotifications'
             value={ @state.channelNotificationSettings.get 'desktopSetting' }
             onChange={@bound 'onWebNotificationsChange'}>

@@ -156,7 +161,7 @@

           </RadioGroup>
         </fieldset>
-        <fieldset className='Reactivity-fieldset'>
+        <fieldset className='Reactivity-fieldset channelNotifications'>
           <legend className='Reactivity-legend'>@channel notifications:</legend>


[Block] changed user unblocking method

[Block] changed user unblocking method

--- client/app/Applications/Groups.kdapplication/Views/blockeduserslistitemview.coffee
+++ client/app/Applications/Groups.kdapplication/Views/blockeduserslistitemview.coffee
@@ -25,7 +25,7 @@
     @unblockButton   = new KDButtonView
       title          : "Unblock"
       callback       : =>
-        @blockUser @getData().getId(), '1S', (err, res)=>
+        KD.whoami().unblockUser @getData().getId(), (err)=>
           if err
             warn err
           else


default-apps: Changed event handler for open with menu items.

--- client/landing/app/MainApp/filetree/controllers/findercontextmenucontroller.coffee
+++ client/landing/app/MainApp/filetree/controllers/findercontextmenucontroller.coffee
@@ -364,7 +364,7 @@
     {extensionToApp} = appsController
     possibleApps     = extensionToApp[fileExtension] or extensionToApp.txt
     for appName in possibleApps
-      items[appName] = action: "openFile"
+      items[appName] = action: "openFileWithApp"

     items["separator"]            = type     : "separator"
     items["Other Apps"]           = action   : "showOpenWithModal", separator : yes


Change logging from error to normal

Change logging from error to normal

--- app/scripts/services.coffee
+++ app/scripts/services.coffee
@@ -65,7 +65,7 @@
               .pluck("Both_Sexes")
               .value())
         catch e
-          console.error("Failed to lookup population for " +
+          console.log("Warning: Failed to lookup population for " +
             r + ", " + d + ", " + w)
           return -1


no query string to update.

no query string to update.

:best:

--- resources/assets/coffee/_classes/forum.coffee
+++ resources/assets/coffee/_classes/forum.coffee
@@ -202,7 +202,7 @@
           forum_posts_show_deleted: +!@showDeleted()
     .done (user) =>
       $.publish 'user:update', user
-      Turbolinks.visit osu.updateQueryString @postUrlN(@currentPostPosition)
+      Turbolinks.visit @postUrlN(@currentPostPosition)

   initialScrollTo: =>


:fire:

:fire:

--- src/marker.coffee
+++ src/marker.coffee
@@ -368,6 +368,3 @@
     @wasValid = isValid

     @emitter.emit 'did-change', changeEvent
-
-  getPixelRange: ->
-    @displayBuffer.pixelRangeForScreenRange(@getScreenRange(), false)


inport: better error message for invalid value

Tell what we expect when the value was not part of the expected values.

--- src/lib/InPort.coffee
+++ src/lib/InPort.coffee
@@ -86,7 +86,7 @@
   validateData: (data) ->
     return unless @options.values
     if @options.values.indexOf(data) is -1
-      throw new Error 'Invalid data received'
+      throw new Error "Invalid data='#{data}' received, not in [#{@options.values}]"

   # Returns the next packet in the buffer
   receive: ->


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/matrix.coffee
+++ src/matrix.coffee
@@ -301,7 +301,6 @@
   Matrix.VERTICAL_FLIP = Matrix(1, 0, 0, -1)

   # Export to window
-  window["Point"] = $.noop #TODO: Figure out why things barf without this line
   window["Matrix"] = Matrix
 )()


fixed missing progress option for loadFiles step

--- src/lib/docpad.coffee
+++ src/lib/docpad.coffee
@@ -3300,7 +3300,7 @@
 		database = docpad.getDatabase()

 		# Perform the reload of the selected files
-		docpad.loadFiles {collection:opts.collection}, (err) ->
+		docpad.loadFiles {collection:opts.collection, progress:opts.progress}, (err) ->
 			# Check
 			return next(err)  if err


format updates

format updates

--- src/lib/docpad.coffee
+++ src/lib/docpad.coffee
@@ -1204,7 +1204,7 @@

 				# Hash with salt
 				try
-					macAddressHash = require('crypto').createHmac('sha1',config.hashKey).update(macAddress).digest('hex')
+					macAddressHash = require('crypto').createHmac('sha1', config.hashKey).update(macAddress).digest('hex')
 				catch err
 					return complete()  if err

@@ -2090,7 +2090,7 @@
 		},options)

 		# Create and return
-		document = new DocumentModel(data,options)
+		document = new DocumentModel(data, options)

 		# Log
 		document.on 'log', (args...) ->
@@ -2099,8 +2099,8 @@
 		# Fetch a layout
 		document.on 'getLayout', (opts={},next) ->
 			opts.collection = docpad.getCollection('layouts')
-			layout = docpad.getFileBySelector(opts.selector,opts)
-			next(null,{layout})
+			layout = docpad.getFileBySelector(opts.selector, opts)
+			next(null, {layout})

 		# Render
 		document.on 'render', (args...) ->
@@ -2118,7 +2118,7 @@
 		database = @getDatabase()
 		result = database.findOne(fullPath: data.fullPath)
 		unless result
-			result = @createFile(data,options)
+			result = @createFile(data, options)
 			database.add(result)
 		result

@@ -2127,7 +2127,7 @@
 		database = @getDatabase()
 		result = database.findOne(fullPath: data.fullPath)
 		unless result
-			result = @createDocument(data,options)
+			result = @createDocument(data, options)
 			database.add(result)
 		result

@@ -2146,21 +2146,21 @@
 				# Check if we have a document or layout
 				for dirPath in config.documentsPaths.concat(config.layoutsPaths)
 					if fileFullPath.indexOf(dirPath) is 0
-						data.relativePath or= fileFullPath.replace(dirPath,'').replace(/^[\/\\]/,'')
-						result = @createDocument(data,options)
+						data.relativePath or= fileFullPath.replace(dirPath, '').replace(/^[\/\\]/,'')
+						result = @createDocument(data, options)
 						break

 				# Check if we have a file
 				unless result
 					for dirPath in config.filesPaths
 						if fileFullPath.indexOf(dirPath) is 0
-							data.relativePath or= fileFullPath.replace(dirPath,'').replace(/^[\/\\]/,'')
-							result = @createFile(data,options)
+							data.relativePath or= fileFullPath.replace(dirPath, '').replace(/^[\/\\]/,'')
+							result = @createFile(data, options)
 							break

 			# Otherwise, create a file anyway
 			unless result
-				result = @createDocument(data,options)
+				result = @createDocument(data, options)

 			# Add result to database
 			database.add(result)
@@ -2172,13 +2172,13 @@
 	# next(err)
 	parseFileDirectory: (opts={},next) ->
 		opts.createFunction ?= @createFile
-		return @parseDirectory(opts,next)
+		return @parseDirectory(opts, next)

 	# Parse a document directory
 	# next(err)
 	parseDocumentDirectory: (opts={},next) ->
 		opts.createFunction ?= @createDocument
-		return @parseDirectory(opts,next)
+		return @parseDirectory(opts, next)

 	# Parse a directory
 	# next(err)
@@ -2217,7 +2217,7 @@
 					stat: fileStat

 				# Create file
-				file = createFunction(data,options)
+				file = createFunction(data, options)
 				filesToLoad.add(file)

 				# Next


Server is now able to serve cached pages while a non-initial generation is occuring

--- src/lib/docpad.coffee
+++ src/lib/docpad.coffee
@@ -213,7 +213,9 @@

 	# Database collection
 	database: null  # QueryEngine Collection
+	databaseCache: null
 	getDatabase: -> @database
+	getDatabaseCache: -> @databaseCache or @database

 	# Files by URL
 	# Used to speed up fetching
@@ -318,42 +320,43 @@
 	# Get Files (will use live collections)
 	getFiles: (query,sorting,paging) ->
 		key = JSON.stringify({query,sorting,paging})
-		result = @getCollection(key)
-		unless result
-			result = @getDatabase().findAllLive(query,sorting,paging)
-			@setCollection(key, result)
-		return result
+		files = @getCollection(key)
+		unless files
+			files = @getDatabase().findAllLive(query,sorting,paging)
+			@setCollection(key, files)
+		return files

 	# Get another file's model based on a relative path
 	getFile: (query,sorting,paging) ->
-		result = @getDatabase().findOne(query,sorting,paging)
-		return result
+		file = @getDatabase().findOne(query,sorting,paging)
+		return file

 	# Get Files At Path
 	getFilesAtPath: (path,sorting,paging) ->
 		query = $or: [{relativePath: $startsWith: path}, {fullPath: $startsWith: path}]
-		result = @getFiles(query,sorting,paging)
-		return result
+		files = @getFiles(query,sorting,paging)
+		return files

 	# Get another file's model based on a relative path
 	getFileAtPath: (path,sorting,paging) ->
-		result = @getDatabase().fuzzyFindOne(path,sorting,paging)
-		return result
+		file = @getDatabase().fuzzyFindOne(path,sorting,paging)
+		return file

 	# Get a file by its url
-	getFileByUrl: (url) ->
-		result = @getDatabase().get(@filesByUrl[url])
-		return result
+	getFileByUrl: (url,opts={}) ->
+		opts.collection ?= @getDatabase()
+		file = opts.collection.get(@filesByUrl[url])
+		return file

 	# Get a file by its selector
-	getFileBySelector: (selector,opts) ->
+	getFileBySelector: (selector,opts={}) ->
 		opts.collection ?= @getDatabase()
-		result = collection.get(@filesBySelector[selector])
-		unless result
-			result = collection.fuzzyFindOne(selector)
-			if result
-				@filesBySelector[selector] = result.id
-		return result
+		file = opts.collection.get(@filesBySelector[selector])
+		unless file
+			file = opts.collection.fuzzyFindOne(selector)
+			if file
+				@filesBySelector[selector] = file.id
+		return file

 	# ---------------------------------
@@ -998,12 +1001,6 @@
 					message = "You have files that share the same relativePath, this will cause unexpected results, please rename one of these files:\n  #{modelPath}\n  #{existingModelPath}"
 					docpad.warn(message)
 			)
-			.on('reset', =>
-				@filesByUrl = {}
-				@filesBySelector = {}
-				@filesByRelativePath = {}
-			)
-			.trigger('reset')
 		@locales = extendr.dereference(@locales)
 		@userConfig = extendr.dereference(@userConfig)
 		@initialConfig = extendr.dereference(@initialConfig)
@@ -1687,13 +1684,24 @@
 	# Reset Collections
 	# next(err)
 	resetCollections: (next) ->
+		# Prepare
+		database = @getDatabase()
+
+		# Update the cached database
+		@databaseCache = new FilesCollection(database.models)
+
 		# Perform a complete clean of our collections
-		@getDatabase().reset([])
+		database.reset([])
 		@getBlock('meta').reset([]).add([
 			'<meta http-equiv="X-Powered-By" content="DocPad"/>'
 		])
 		@getBlock('scripts').reset([])
 		@getBlock('styles').reset([])
+
+		# Reset caches
+		@filesByUrl = {}
+		@filesBySelector = {}
+		@filesByRelativePath = {}

 		# Perform any plugin extensions to what we just cleaned
 		# and forward
@@ -2599,7 +2607,7 @@
 			docpad.fatal(err)  if err
 		forward = (args...) =>
 			@log 'debug', util.format(locale.actionFinished, action)
-			balUtil.wait 0, -> next(args...)
+			process.nextTick -> next(args...)  # not sure why we do this, but we do

 		# Wrap
 		runner.addTask (complete) ->
@@ -2772,17 +2780,20 @@

 		# Update generating flag
 		docpad.generating = false
+		docpad.generateEnded = new Date()
+
+		# Update caches
+		docpad.databaseCache = null
 		collection.each (file) ->
 			for url in file.get('urls')
 				docpad.filesByUrl[url] = file.cid
-		docpad.filesByUrlCache = docpad.filesByUrl

 		# Fire plugins
 		docpad.emitSync 'generateAfter', server:docpad.getServer(), (err) ->
 			return next(err)  if err

 			# Log generated
-			seconds = (new Date() - docpad.lastGenerate) / 1000
+			seconds = (docpad.generateEnded - docpad.generateStarted) / 1000
 			howMany =
 				if collection is database
 					"all #{collection.length}"
@@ -2797,8 +2808,9 @@
 		# Chain
 		@

-	# Date object of the last generate
-	lastGenerate: null
+	# Generate times
+	generateStarted: null
+	generateEnded: null

 	# Flag for whether or not we are generating
 	generating: false
@@ -2809,7 +2821,6 @@
 		# Prepare
 		[opts,next] = balUtil.extractOptsAndCallback(opts,next)
 		docpad = @
-		docpad.lastGenerate ?= new Date('1970')
 		locale = @getLocale()
 		opts.reset ?= true

@@ -2841,10 +2852,10 @@
 				# Create a colelction for the files to reload
 				filesToReload = opts.filesToReload or new FilesCollection()
 				# Add anything which was modified since our last generate
-				filesToReload.add(database.findAll(mtime: $gte: docpad.lastGenerate).models)
+				filesToReload.add(database.findAll(mtime: $gte: docpad.generateStarted).models)

 				# Update our generate time
-				docpad.lastGenerate = new Date()
+				docpad.generateStarted = new Date()

 				# Perform the reload of the selected files
 				docpad.loadFiles {collection:filesToReload}, (err) ->
@@ -2879,7 +2890,7 @@
 		# Re-load and re-render everything
 		else
 			# Prepare
-			docpad.lastGenerate = new Date()
+			docpad.generateStarted = new Date()
 			balUtil.flow(
 				object: docpad
 				action: 'generateCheck generatePrepare generateParse generateRender generatePostpare'
@@ -3443,15 +3454,16 @@
 		# Prepare
 		docpad = @

-		# If we are generating then wait until generation is complete before continuing
-		if docpad.lastGenerate is null or docpad.generating is true
+		# If we have not performed a generation yet then wait until the initial generation has completed
+		if docpad.generateEnded is null # or docpad.generating is true
 			docpad.once 'generateAfter', ->
 				return docpad.serverMiddlewareRouter(req,res,next)
 			return @

 		# Prepare
+		database = docpad.getDatabaseCache()
 		cleanUrl = req.url.replace(/\?.*/,'')
-		file = docpad.getFileByUrl(req.url) or docpad.getFileByUrl(cleanUrl)
+		file = docpad.getFileByUrl(req.url,{collection:database}) or docpad.getFileByUrl(cleanUrl,{collection:database})
 		return next()  if file? is false

 		# Check if we are the desired url
@@ -3470,7 +3482,7 @@
 	serverMiddleware404: (req,res,next) =>
 		# Prepare
 		docpad = @
-		database = docpad.getDatabase()
+		database = docpad.getDatabaseCache()

 		# Check
 		return res.send(500)  unless database
@@ -3486,7 +3498,7 @@
 	serverMiddleware500: (err,req,res,next) =>
 		# Prepare
 		docpad = @
-		database = docpad.getDatabase()
+		database = docpad.getDatabaseCache()

 		# Check
 		return res.send(500)  unless database