Skip to content
This repository was archived by the owner on Nov 25, 2020. It is now read-only.

KDData: revamp #180

Merged
merged 6 commits into from
Aug 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ css:

clean: clean_dist
@rm -fr build
@rm -fr coverage

clean_dist:
@echo ' - Cleanup...'
Expand Down
4 changes: 2 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Build Status](https://img.shields.io/travis/koding/kd.svg?style=flat)](https://travis-ci.org/koding/kd) [![Coverage Status](https://img.shields.io/coveralls/koding/kd.svg?style=flat)](https://coveralls.io/github/koding/kd?branch=master)
[![Build Status](https://img.shields.io/travis/koding/kd.svg?style=flat)](https://travis-ci.org/koding/kd) [![npm](https://img.shields.io/npm/v/kd.js.svg)](https://www.npmjs.com/package/kd.js) [![Coverage Status](https://img.shields.io/coveralls/koding/kd.svg?style=flat)](https://coveralls.io/github/koding/kd?branch=master)

# kd.js

Expand Down Expand Up @@ -44,7 +44,7 @@ main.addSubView(tabs);

# example

Type `make example` and go to http://localhost:3000/example. This also starts a `watchify` process, so any changes you make in `example/index.js` will be recompiled on the spot.
Type `make example` to checkout some examples.

# development

Expand Down
2 changes: 2 additions & 0 deletions gulpfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ gulp.task 'test', (done) ->
gulp.task 'test-watch', (done) ->

options.singleRun = false
options.browsers = ['Chrome']

server(options, ->
done() if not doneBefore
doneBefore = yes
Expand Down
5 changes: 3 additions & 2 deletions lib/components/dia/diascene.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = class KDDiaScene extends KDView
options.updateEvery ?= 10
options.prependCanvas ?= no

super
super options, data

@containers = []
@connections = []
Expand Down Expand Up @@ -523,7 +523,8 @@ module.exports = class KDDiaScene extends KDView

createCanvas: ->

return if @realCanvas
@realCanvas?.destroy()
@fakeCanvas?.destroy()

@addSubView @realCanvas = new KDCustomHTMLView
tagName : 'canvas'
Expand Down
113 changes: 71 additions & 42 deletions lib/core/data.coffee
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
debug = require('debug') 'kd:data'
KD = require './kd'
KDEventEmitter = require './eventemitter'

Expand All @@ -11,24 +12,46 @@ createProxy = (data, handler) ->
console.warn 'Proxies are not supported on this platform!'
return new Object data

isValid = (value) ->
value and typeof value is 'object' and value not instanceof Date


module.exports = class KDData

@EMITTER = createSymbol 'kddata'
@NAME = createSymbol 'name'

constructor: (data = {}) ->
constructor: (data = {}, options = {}) ->

@emitter = new KDEventEmitter
@emitter.__data__ = data
@emitter.__event__ = options.updateEvent ? 'update'
@emitter.maxdepth = options.max_depth ? 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emitter.maxDepth = options.maxDepth for consistency?


@proxy = createProxy data, KDData::proxyHandler.call this
Object.defineProperty @proxy, KDData.EMITTER, {
value: @emitter, configurable: yes
}

initialize = (data, key = null, depth = 0) =>
return if not isValid data

emitter = new KDEventEmitter
emitter.__data__ = data
emitter.isArray = Array.isArray data
depth += 1
for _key, child of data
path = if key then "#{key}.#{_key}" else _key
if depth < @emitter.maxdepth and isValid child
initialize child, path, depth
KD.utils.JsPath.setAt @proxy, path, child

proxy = createProxy data, proxyHandler emitter
Object.defineProperty proxy, KDData.EMITTER, value: emitter
initialize data
@initialized = yes

return @proxy

return proxy

@isSupported = -> !!window.Proxy?


@getEmitter = (data) ->

return unless data?
Expand All @@ -38,59 +61,65 @@ module.exports = class KDData
return data


getFullPath = (parent, child) ->
emit: (updates) ->

return if not @initialized
@emitter.emit @emitter.__event__, [ updates ]


if root = parent[KDData.NAME]
return "#{root}.#{child}"
return child
createObjectProxy: (obj, key) ->

value = createProxy obj, @proxyHandler.call this
return value unless key

proxyHandler = (base) ->
Object.defineProperty value, KDData.NAME, {
value: key, configurable: yes
}
return value

get: (target, key) ->

value = target[key]
return value if typeof key isnt 'string'
proxify: (value, key, depth = 0) ->

key = getFullPath target, key
return value if not isValid value

if value and dataValue = KD.utils.JsPath.getAt base.__data__, key
if dataValue instanceof Object and value not instanceof Date
proxy = createProxy value, proxyHandler base
Object.defineProperty proxy, KDData.NAME, {
value: key, configurable: yes
}
return proxy
depth += 1

for _key, child of value
path = if key then "#{key}.#{_key}" else _key
debug 'path on', _key, path
if depth < @emitter.maxdepth and isValid child
value[_key] = @createObjectProxy child, path
@proxify child, path, depth

debug 'creating proxy', value, key

if isValid value
return @createObjectProxy value, key
else
return value


set: (target, key, value, receiver) ->
proxyHandler: ->

set: (target, key, value, receiver) =>

if base.isArray
debug 'setting', key, value

if isArray = Array.isArray target
currentLength = target.length

target[key] = value
if parent = receiver[KDData.NAME] ? ''
path = "#{parent}.#{key}"

target[key] = @proxify value, path ? key

if base.isArray
if isArray
lengthChanged = target.length isnt currentLength
return true if key is 'length' and not lengthChanged

if root = receiver[KDData.NAME]
key = "#{root}.#{key}"
else
root = ''
@emit path ? key

return true if typeof key is 'symbol' or /^__|__$/.test key
if lengthChanged and key isnt 'length'
@emit if parent then "#{parent}.length" else 'length'

if lengthChanged
prefix = if key.indexOf('.') >= 0 then "#{root}." else ''
base.emit 'update', [ "#{prefix}length" ]

base.emit 'update', [ key ]
return true


getPrototypeOf: (target) ->

return KDData.prototype
Loading