From 4dfada1da24a633c590921515ec49ddbbac81b3e Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Fri, 6 Nov 2015 16:06:48 -0500 Subject: [PATCH 01/21] .has.watcher and reference shortcuts --- nestedtypes.js | 73 ++++++++++++++++++++++++++++++++++++++---------- src/attribute.js | 54 +++++++++++++++++++++++++++++------ src/errors.js | 4 +++ src/model.js | 4 +++ src/relations.js | 11 ++++---- 5 files changed, 116 insertions(+), 30 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 2e65986..278418a 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -163,6 +163,10 @@ return /******/ (function(modules) { // webpackBootstrap return owner ? owner.getStore() : this._defaultStore; }, + getOwner : function(){ + return this._owner || ( this.collection && this.collection._owner ); + }, + sync : function(){ var store = this.getStore() || Backbone; return store.sync.apply( this, arguments ); @@ -2687,6 +2691,10 @@ return /******/ (function(modules) { // webpackBootstrap context.__class + '.set(', format( value ), '); this =', context ); }, + wrongWatcher : function( context, ref ){ + console.warn( "[Reference Error] Attribute's .has.watcher(", ref, ") must be string reference or function; attr=", context ); + }, + unknownAttribute : function( context, name, value ){ if( context.suppressTypeErrors ) return; @@ -2726,6 +2734,7 @@ return /******/ (function(modules) { // webpackBootstrap var trigger3 = __webpack_require__( 2 ).Events.trigger3, modelSet = __webpack_require__( 7 ), + error = __webpack_require__( 8 ), genericIsChanged = modelSet.isChanged, setSingleAttr = modelSet.setSingleAttr; @@ -2739,6 +2748,30 @@ return /******/ (function(modules) { // webpackBootstrap var availableOptions = [ 'triggerWhenChanged', 'changeEvents', 'parse', 'clone', 'toJSON', 'value', 'cast', 'create', 'name', 'value', 'type' ]; + function parseReference( ref ){ + switch( typeof ref ){ + case 'string' : + var path = 'self. ' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + callback = path.pop(), + context = new Function( 'self', 'return ' + path.join( '.' ) ); + + return function( value ){ + var self = context( this ); + + if( self && self[ callback ] ){ + self[ callback ]( value, this ); + } + + return value; + }; + case 'function' : + return function( value ){ + ref.call( this, value, this ); + return value; + }; + } + } + var Options = Object.extend( { _options : {}, // attribute options @@ -2766,6 +2799,16 @@ return /******/ (function(modules) { // webpackBootstrap this.options( spec ); }, + watcher : function( ref ){ + var callback = parseReference( ref ); + if( callback ){ + this.set( callback ); + } + else{ + error.wrongWatcher( this, ref ); + } + }, + proxy : function( attrs ){ this._options.proxy = attrs || true; return this; @@ -2809,10 +2852,10 @@ return /******/ (function(modules) { // webpackBootstrap if( options.proxy && typeof options.proxy === 'string' && !options.triggerWhenChanged ){ options.triggerWhenChanged = options.proxy - .split( ' ' ) - .map( function( attr ){ - return 'change:' + attr; - }).join( ' ' ); + .split( ' ' ) + .map( function( attr ){ + return 'change:' + attr; + } ).join( ' ' ); } return new Type( name, options ); @@ -2954,11 +2997,12 @@ return /******/ (function(modules) { // webpackBootstrap }, attachMixins : function( spec ){ - var type = this.type, + var type = this.type, proto = type && type.prototype; if( type && this.proxy ){ - var keys = typeof this.proxy === 'string' ? this.proxy.split( ' ' ) : _.allKeys( proto ).concat( _.keys( proto.properties ) ); + var keys = typeof this.proxy === 'string' ? this.proxy.split( ' ' ) : _.allKeys( proto ).concat( + _.keys( proto.properties ) ); // for each enumerable property... for( var i = 0; i < keys.length; i++ ){ @@ -3061,9 +3105,9 @@ return /******/ (function(modules) { // webpackBootstrap return function(){ for( var i = 0; i < arguments.length; i++ ){ - var Type = arguments[ i ]; + var Type = arguments[ i ]; Type.attribute = Type.options = options; - Type.value = value; + Type.value = value; Type.Attribute = this; Object.defineProperty( Type, 'has', { get : function(){ @@ -3084,7 +3128,7 @@ return /******/ (function(modules) { // webpackBootstrap return new Options( spec ); } - createOptions.Type = Attribute; + createOptions.Type = Attribute; createOptions.create = function( options, name ){ if( !( options && options instanceof Options ) ){ options = new Options( { typeOrValue : options } ); @@ -3252,13 +3296,12 @@ return /******/ (function(modules) { // webpackBootstrap case 'object' : return function(){ return collectionRef; }; case 'string' : - var path = collectionRef.split( '.' ); - if( path[ 0 ] === 'store' ){ - path[ 0 ] = 'getStore()'; - path[ 1 ] = 'get("' + path[ 1 ] + '")'; - } + var path = collectionRef + .replace( /\^/g, 'getOwner().' ) + .replace( /^\~/, 'store.' ) + .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); - return new Function( 'return this.' + path.join( '.' ) ); + return new Function( 'return this.' + path ); } } diff --git a/src/attribute.js b/src/attribute.js index 72f5a4d..d82c5cb 100644 --- a/src/attribute.js +++ b/src/attribute.js @@ -4,6 +4,7 @@ require( './object+' ); var trigger3 = require( './backbone+' ).Events.trigger3, modelSet = require( './modelset' ), + error = require( './errors' ), genericIsChanged = modelSet.isChanged, setSingleAttr = modelSet.setSingleAttr; @@ -17,6 +18,30 @@ var primitiveTypes = { var availableOptions = [ 'triggerWhenChanged', 'changeEvents', 'parse', 'clone', 'toJSON', 'value', 'cast', 'create', 'name', 'value', 'type' ]; +function parseReference( ref ){ + switch( typeof ref ){ + case 'string' : + var path = 'self. ' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + callback = path.pop(), + context = new Function( 'self', 'return ' + path.join( '.' ) ); + + return function( value ){ + var self = context( this ); + + if( self && self[ callback ] ){ + self[ callback ]( value, this ); + } + + return value; + }; + case 'function' : + return function( value ){ + ref.call( this, value, this ); + return value; + }; + } +} + var Options = Object.extend( { _options : {}, // attribute options @@ -44,6 +69,16 @@ var Options = Object.extend( { this.options( spec ); }, + watcher : function( ref ){ + var callback = parseReference( ref ); + if( callback ){ + this.set( callback ); + } + else{ + error.wrongWatcher( this, ref ); + } + }, + proxy : function( attrs ){ this._options.proxy = attrs || true; return this; @@ -87,10 +122,10 @@ var Options = Object.extend( { if( options.proxy && typeof options.proxy === 'string' && !options.triggerWhenChanged ){ options.triggerWhenChanged = options.proxy - .split( ' ' ) - .map( function( attr ){ - return 'change:' + attr; - }).join( ' ' ); + .split( ' ' ) + .map( function( attr ){ + return 'change:' + attr; + } ).join( ' ' ); } return new Type( name, options ); @@ -232,11 +267,12 @@ var Attribute = Object.extend( { }, attachMixins : function( spec ){ - var type = this.type, + var type = this.type, proto = type && type.prototype; if( type && this.proxy ){ - var keys = typeof this.proxy === 'string' ? this.proxy.split( ' ' ) : _.allKeys( proto ).concat( _.keys( proto.properties ) ); + var keys = typeof this.proxy === 'string' ? this.proxy.split( ' ' ) : _.allKeys( proto ).concat( + _.keys( proto.properties ) ); // for each enumerable property... for( var i = 0; i < keys.length; i++ ){ @@ -339,9 +375,9 @@ var Attribute = Object.extend( { return function(){ for( var i = 0; i < arguments.length; i++ ){ - var Type = arguments[ i ]; + var Type = arguments[ i ]; Type.attribute = Type.options = options; - Type.value = value; + Type.value = value; Type.Attribute = this; Object.defineProperty( Type, 'has', { get : function(){ @@ -362,7 +398,7 @@ function createOptions( spec ){ return new Options( spec ); } -createOptions.Type = Attribute; +createOptions.Type = Attribute; createOptions.create = function( options, name ){ if( !( options && options instanceof Options ) ){ options = new Options( { typeOrValue : options } ); diff --git a/src/errors.js b/src/errors.js index 4b8c8e6..97b04d1 100644 --- a/src/errors.js +++ b/src/errors.js @@ -11,6 +11,10 @@ Object.assign( Object.extend.error, { context.__class + '.set(', format( value ), '); this =', context ); }, + wrongWatcher : function( context, ref ){ + console.warn( "[Reference Error] Attribute's .has.watcher(", ref, ") must be string reference or function; attr=", context ); + }, + unknownAttribute : function( context, name, value ){ if( context.suppressTypeErrors ) return; diff --git a/src/model.js b/src/model.js index 7b2d2b1..0f7e7fa 100644 --- a/src/model.js +++ b/src/model.js @@ -42,6 +42,10 @@ var Model = BaseModel.extend( { return owner ? owner.getStore() : this._defaultStore; }, + getOwner : function(){ + return this._owner || ( this.collection && this.collection._owner ); + }, + sync : function(){ var store = this.getStore() || Backbone; return store.sync.apply( this, arguments ); diff --git a/src/relations.js b/src/relations.js index 2ea606c..c41521b 100644 --- a/src/relations.js +++ b/src/relations.js @@ -14,13 +14,12 @@ function parseReference( collectionRef ){ case 'object' : return function(){ return collectionRef; }; case 'string' : - var path = collectionRef.split( '.' ); - if( path[ 0 ] === 'store' ){ - path[ 0 ] = 'getStore()'; - path[ 1 ] = 'get("' + path[ 1 ] + '")'; - } + var path = collectionRef + .replace( /\^/g, 'getOwner().' ) + .replace( /^\~/, 'store.' ) + .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); - return new Function( 'return this.' + path.join( '.' ) ); + return new Function( 'return this.' + path ); } } From 06bbca0e6a4983cc4dc907d301d947a7bd7a346d Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Fri, 6 Nov 2015 16:51:03 -0500 Subject: [PATCH 02/21] Updated proposal --- docs/universal databinding proposal.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/universal databinding proposal.md b/docs/universal databinding proposal.md index 0601bf6..3fd5866 100644 --- a/docs/universal databinding proposal.md +++ b/docs/universal databinding proposal.md @@ -3,28 +3,28 @@ // for boolean -collection.toggler( model ) +collection.toggle_f( model ) get : m in collection set( true ) { encoders.map( encoder => ( - + ))} // for inputs -model.bind.attr +model.set_f.attr // for radio -model.bound.selected.eql( x ) +model.toggle_f( 'selected', x ) get : a === x, set( true ) : a = x set( false ): a = null // for clicks -model.setter.selected.to( x ) +model.set_f.selected.to( x ) get : a = x -model.setter.selected.toggle( y ) +model.set_f.selected.toggle( y /* , =null */ ) model.setter( 'attr', x ) From a1105303015a360d57f8c7f27923c06532aab0e0 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Sun, 8 Nov 2015 23:19:30 -0500 Subject: [PATCH 03/21] setters implementation --- docs/universal databinding proposal.md | 8 +++---- src/collection.js | 30 ++++++++++++++++++++++++++ src/model.js | 24 +++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/docs/universal databinding proposal.md b/docs/universal databinding proposal.md index 0601bf6..90b38cb 100644 --- a/docs/universal databinding proposal.md +++ b/docs/universal databinding proposal.md @@ -8,20 +8,20 @@ collection.toggler( model ) set( true ) { encoders.map( encoder => ( - + ))} // for inputs -model.bind.attr +model.setter( 'attr' ) // for radio -model.bound.selected.eql( x ) +model.toggler( 'selected', x ) get : a === x, set( true ) : a = x set( false ): a = null // for clicks -model.setter.selected.to( x ) +model.setter( 'selected', x ) get : a = x model.setter.selected.toggle( y ) diff --git a/src/collection.js b/src/collection.js index 98b49f3..d414f66 100644 --- a/src/collection.js +++ b/src/collection.js @@ -67,6 +67,36 @@ module.exports = Backbone.Collection.extend( { } ); }, + // create bool 'toggler' function property + toggle : function( model, a_next ){ + var prev = Boolean( this.get( model ) ); + + if( a_next !== void 0 ){ + var next = Boolean( a_next ); + + if( prev !== next ){ + if( prev ){ + this.remove( model ); + } + else{ + this.add( model ); + } + } + + return next; + } + + return prev; + }, + + toggler : function( model ){ + var collection = this; + + return function( next ){ + return collection.toggle( model, next ); + } + }, + // ATTENTION: Overriden backbone logic with bug fixes get : function( obj ){ if( obj == null ){ return void 0; } diff --git a/src/model.js b/src/model.js index 0f7e7fa..8f433f8 100644 --- a/src/model.js +++ b/src/model.js @@ -65,6 +65,30 @@ var Model = BaseModel.extend( { transaction : modelSet.transaction, + setter : function( name, val ){ + var model = this; + return val === void 0 ? function( val ){ + val === void 0 || ( model[ name ] = val ); + return model[ name ]; + } : function(){ + val === void 0 || ( model[ name ] = val ); + return model[ name ]; + } + }, + + toggler : function( name, asTrue ){ + var model = this; + + return function( isEql ){ + if( isEql !== void 0 ){ + model[ name ] = isEql ? asTrue : null; + return isEql; + } + + return model[ name ] === value; + } + }, + set : function( a, b, c ){ switch( typeof a ){ case 'string' : From 9a0d8e6f212cad4187b1998061ba025cb7ea5e2e Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 9 Nov 2015 15:39:13 -0500 Subject: [PATCH 04/21] Model/Collections data binding generators --- nestedtypes.js | 60 +++++++++++++++++++++++++++++++++++++++-------- src/collection.js | 30 ++++++++++-------------- src/model.js | 21 +++++++---------- src/relations.js | 13 +++------- 4 files changed, 75 insertions(+), 49 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 278418a..7ff7480 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -186,6 +186,27 @@ return /******/ (function(modules) { // webpackBootstrap transaction : modelSet.transaction, + // Create bound function property for an attribute + setter : function( name ){ + var model = this; + return function( val ){ + if( arguments.length ) model[ name ] = val; + + return model[ name ]; + } + }, + + // Create bound boolean function property for attribute + toggler : function( name, asTrue ){ + var model = this; + + return function( val ){ + if( arguments.length ) model[ name ] = val ? asTrue : null; + + return model[ name ] === asTrue; + } + }, + set : function( a, b, c ){ switch( typeof a ){ case 'string' : @@ -3213,6 +3234,32 @@ return /******/ (function(modules) { // webpackBootstrap } ); }, + // Toggle model in collection + toggle : function( model, a_next ){ + var prev = Boolean( this.get( model ) ), + next = a_next === void 0 ? !prev : Boolean( a_next ); + + if( prev !== next ){ + if( prev ){ + this.remove( model ); + } + else{ + this.add( model ); + } + } + + return next; + }, + + // Create function boolean property toggling the given model + toggler : function( model ){ + var collection = this; + + return function( next ){ + return typeof next === void 0 ? Boolean( this.get( model ) ) : collection.toggle( model, next ); + } + }, + // ATTENTION: Overriden backbone logic with bug fixes get : function( obj ){ if( obj == null ){ return void 0; } @@ -3430,16 +3477,9 @@ return /******/ (function(modules) { // webpackBootstrap return models; }, - toggle : function( modelOrId, inSet ){ - var model = this.resolvedWith.get( modelOrId ), - toggle = inSet === void 0; - - if( this.get( model ) ){ - if( toggle || !inSet ) this.remove( model ); - } - else{ - if( toggle || inSet ) this.add( model ); - } + toggle : function( modelOrId, val ){ + var model = this.resolvedWith.get( modelOrId ); + return CollectionProto.toggle.call( this, model, val ); }, addAll : function(){ diff --git a/src/collection.js b/src/collection.js index d414f66..079b427 100644 --- a/src/collection.js +++ b/src/collection.js @@ -67,33 +67,29 @@ module.exports = Backbone.Collection.extend( { } ); }, - // create bool 'toggler' function property + // Toggle model in collection toggle : function( model, a_next ){ - var prev = Boolean( this.get( model ) ); - - if( a_next !== void 0 ){ - var next = Boolean( a_next ); - - if( prev !== next ){ - if( prev ){ - this.remove( model ); - } - else{ - this.add( model ); - } - } + var prev = Boolean( this.get( model ) ), + next = a_next === void 0 ? !prev : Boolean( a_next ); - return next; + if( prev !== next ){ + if( prev ){ + this.remove( model ); + } + else{ + this.add( model ); + } } - return prev; + return next; }, + // Create function boolean property toggling the given model toggler : function( model ){ var collection = this; return function( next ){ - return collection.toggle( model, next ); + return typeof next === void 0 ? Boolean( this.get( model ) ) : collection.toggle( model, next ); } }, diff --git a/src/model.js b/src/model.js index 8f433f8..f8c7896 100644 --- a/src/model.js +++ b/src/model.js @@ -65,27 +65,24 @@ var Model = BaseModel.extend( { transaction : modelSet.transaction, - setter : function( name, val ){ + // Create bound function property for an attribute + setter : function( name ){ var model = this; - return val === void 0 ? function( val ){ - val === void 0 || ( model[ name ] = val ); - return model[ name ]; - } : function(){ - val === void 0 || ( model[ name ] = val ); + return function( val ){ + if( arguments.length ) model[ name ] = val; + return model[ name ]; } }, + // Create bound boolean function property for attribute toggler : function( name, asTrue ){ var model = this; - return function( isEql ){ - if( isEql !== void 0 ){ - model[ name ] = isEql ? asTrue : null; - return isEql; - } + return function( val ){ + if( arguments.length ) model[ name ] = val ? asTrue : null; - return model[ name ] === value; + return model[ name ] === asTrue; } }, diff --git a/src/relations.js b/src/relations.js index c41521b..5cce5dc 100644 --- a/src/relations.js +++ b/src/relations.js @@ -148,16 +148,9 @@ var refsCollectionSpec = { return models; }, - toggle : function( modelOrId, inSet ){ - var model = this.resolvedWith.get( modelOrId ), - toggle = inSet === void 0; - - if( this.get( model ) ){ - if( toggle || !inSet ) this.remove( model ); - } - else{ - if( toggle || inSet ) this.add( model ); - } + toggle : function( modelOrId, val ){ + var model = this.resolvedWith.get( modelOrId ); + return CollectionProto.toggle.call( this, model, val ); }, addAll : function(){ From 1935d41ceb07da83e75409b3e8fb4a2d51715384 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 9 Nov 2015 16:19:29 -0500 Subject: [PATCH 05/21] 1.1.8-0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0da87c..d270603 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.1.8", + "version": "1.1.8-0", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From 020df50bd30ce0966d31d3249dad4d161321bf6c Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 9 Nov 2015 16:20:43 -0500 Subject: [PATCH 06/21] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d270603..be9a3b3 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.1.8-0", + "version": "1.2.0-0", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From affe4d99a1ae1011f8293557f75e99df4e0c6844 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 9 Nov 2015 16:20:51 -0500 Subject: [PATCH 07/21] 1.2.0-1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be9a3b3..907ecaf 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.2.0-0", + "version": "1.2.0-1", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From c4de86146759364aec63995e63c12f8d0ca4a5c8 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 9 Nov 2015 19:44:31 -0500 Subject: [PATCH 08/21] Added array toggler --- nestedtypes.js | 31 +++++++++++++++++++++++++++++++ src/metatypes.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/nestedtypes.js b/nestedtypes.js index 7ff7480..683e36a 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -3561,6 +3561,7 @@ return /******/ (function(modules) { // webpackBootstrap modelSet = __webpack_require__( 7 ), Model = __webpack_require__( 1 ), errors = __webpack_require__( 8 ), + _ = __webpack_require__( 5 ), Collection = __webpack_require__( 10 ); // Constructors Attribute @@ -3656,6 +3657,36 @@ return /******/ (function(modules) { // webpackBootstrap } } ).attach( Array ); + function removeElement( self, element ){ + for( var i = 0; i < self.length;){ + var el = self[ i ]; + + if( el === element ) self.splice( i, 1 ); + else i++; + } + } + + Array.prototype.toggler = function( element ){ + var self = this; + + return function( val ){ + var prev = Boolean( _.contains( self, element ) ); + + if( arguments.length > 0 ){ + var next = Boolean( val ); + + if( prev !== next ){ + if( next ) this.push( element ); + else removeElement( self, element ); + + return next; + } + } + + return prev; + } + }; + // Backbone Attribute // ---------------- diff --git a/src/metatypes.js b/src/metatypes.js index e00bf2f..19518ca 100644 --- a/src/metatypes.js +++ b/src/metatypes.js @@ -8,6 +8,7 @@ var attribute = require( './attribute' ), modelSet = require( './modelset' ), Model = require( './model' ), errors = require( './errors' ), + _ = require( 'underscore' ), Collection = require( './collection' ); // Constructors Attribute @@ -103,6 +104,36 @@ attribute.Type.extend( { } } ).attach( Array ); +function removeElement( self, element ){ + for( var i = 0; i < self.length;){ + var el = self[ i ]; + + if( el === element ) self.splice( i, 1 ); + else i++; + } +} + +Array.prototype.toggler = function( element ){ + var self = this; + + return function( val ){ + var prev = Boolean( _.contains( self, element ) ); + + if( arguments.length > 0 ){ + var next = Boolean( val ); + + if( prev !== next ){ + if( next ) self.push( element ); + else removeElement( self, element ); + + return next; + } + } + + return prev; + } +}; + // Backbone Attribute // ---------------- From 92ec73d7f3c215493f07759842f02d4cda782aee Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 12:14:31 -0500 Subject: [PATCH 09/21] comma --- src/relations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relations.js b/src/relations.js index 5cce5dc..32c1c4b 100644 --- a/src/relations.js +++ b/src/relations.js @@ -63,7 +63,7 @@ exports.take = function( reference ){ options.Attribute = TakeAttribute; return options; -} +}; exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); From 5232dfd946ee3b54d53939986edf8dd249d795c4 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 13:20:54 -0500 Subject: [PATCH 10/21] removed unneded stuff --- nestedtypes.js | 63 +---------------------------------------------- src/collection.js | 9 ------- src/metatypes.js | 31 ----------------------- src/model.js | 21 ---------------- 4 files changed, 1 insertion(+), 123 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 683e36a..1625305 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -186,27 +186,6 @@ return /******/ (function(modules) { // webpackBootstrap transaction : modelSet.transaction, - // Create bound function property for an attribute - setter : function( name ){ - var model = this; - return function( val ){ - if( arguments.length ) model[ name ] = val; - - return model[ name ]; - } - }, - - // Create bound boolean function property for attribute - toggler : function( name, asTrue ){ - var model = this; - - return function( val ){ - if( arguments.length ) model[ name ] = val ? asTrue : null; - - return model[ name ] === asTrue; - } - }, - set : function( a, b, c ){ switch( typeof a ){ case 'string' : @@ -3251,15 +3230,6 @@ return /******/ (function(modules) { // webpackBootstrap return next; }, - // Create function boolean property toggling the given model - toggler : function( model ){ - var collection = this; - - return function( next ){ - return typeof next === void 0 ? Boolean( this.get( model ) ) : collection.toggle( model, next ); - } - }, - // ATTENTION: Overriden backbone logic with bug fixes get : function( obj ){ if( obj == null ){ return void 0; } @@ -3392,7 +3362,7 @@ return /******/ (function(modules) { // webpackBootstrap options.Attribute = TakeAttribute; return options; - } + }; exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); @@ -3561,7 +3531,6 @@ return /******/ (function(modules) { // webpackBootstrap modelSet = __webpack_require__( 7 ), Model = __webpack_require__( 1 ), errors = __webpack_require__( 8 ), - _ = __webpack_require__( 5 ), Collection = __webpack_require__( 10 ); // Constructors Attribute @@ -3657,36 +3626,6 @@ return /******/ (function(modules) { // webpackBootstrap } } ).attach( Array ); - function removeElement( self, element ){ - for( var i = 0; i < self.length;){ - var el = self[ i ]; - - if( el === element ) self.splice( i, 1 ); - else i++; - } - } - - Array.prototype.toggler = function( element ){ - var self = this; - - return function( val ){ - var prev = Boolean( _.contains( self, element ) ); - - if( arguments.length > 0 ){ - var next = Boolean( val ); - - if( prev !== next ){ - if( next ) this.push( element ); - else removeElement( self, element ); - - return next; - } - } - - return prev; - } - }; - // Backbone Attribute // ---------------- diff --git a/src/collection.js b/src/collection.js index 079b427..3eaa645 100644 --- a/src/collection.js +++ b/src/collection.js @@ -84,15 +84,6 @@ module.exports = Backbone.Collection.extend( { return next; }, - // Create function boolean property toggling the given model - toggler : function( model ){ - var collection = this; - - return function( next ){ - return typeof next === void 0 ? Boolean( this.get( model ) ) : collection.toggle( model, next ); - } - }, - // ATTENTION: Overriden backbone logic with bug fixes get : function( obj ){ if( obj == null ){ return void 0; } diff --git a/src/metatypes.js b/src/metatypes.js index 19518ca..e00bf2f 100644 --- a/src/metatypes.js +++ b/src/metatypes.js @@ -8,7 +8,6 @@ var attribute = require( './attribute' ), modelSet = require( './modelset' ), Model = require( './model' ), errors = require( './errors' ), - _ = require( 'underscore' ), Collection = require( './collection' ); // Constructors Attribute @@ -104,36 +103,6 @@ attribute.Type.extend( { } } ).attach( Array ); -function removeElement( self, element ){ - for( var i = 0; i < self.length;){ - var el = self[ i ]; - - if( el === element ) self.splice( i, 1 ); - else i++; - } -} - -Array.prototype.toggler = function( element ){ - var self = this; - - return function( val ){ - var prev = Boolean( _.contains( self, element ) ); - - if( arguments.length > 0 ){ - var next = Boolean( val ); - - if( prev !== next ){ - if( next ) self.push( element ); - else removeElement( self, element ); - - return next; - } - } - - return prev; - } -}; - // Backbone Attribute // ---------------- diff --git a/src/model.js b/src/model.js index f8c7896..0f7e7fa 100644 --- a/src/model.js +++ b/src/model.js @@ -65,27 +65,6 @@ var Model = BaseModel.extend( { transaction : modelSet.transaction, - // Create bound function property for an attribute - setter : function( name ){ - var model = this; - return function( val ){ - if( arguments.length ) model[ name ] = val; - - return model[ name ]; - } - }, - - // Create bound boolean function property for attribute - toggler : function( name, asTrue ){ - var model = this; - - return function( val ){ - if( arguments.length ) model[ name ] = val ? asTrue : null; - - return model[ name ] === asTrue; - } - }, - set : function( a, b, c ){ switch( typeof a ){ case 'string' : From 28747ee55ad865ee59f461ddf3a14753f7fdc5ed Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 13:48:14 -0500 Subject: [PATCH 11/21] Nested.valueLink --- nestedtypes.js | 90 +++++++++++++++++++++++++++++++++--------------- src/main.js | 2 ++ src/relations.js | 88 +++++++++++++++++++++++++++++++--------------- 3 files changed, 124 insertions(+), 56 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 1625305..2c092d2 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -85,6 +85,8 @@ return /******/ (function(modules) { // webpackBootstrap return attribute( { value : value } ); }, + valueLink : relations.valueLink, + Collection : Collection, Model : Model, Store : Store.Model, @@ -3308,24 +3310,24 @@ return /******/ (function(modules) { // webpackBootstrap function parseReference( collectionRef ){ switch( typeof collectionRef ){ - case 'function' : - return collectionRef; - case 'object' : - return function(){ return collectionRef; }; - case 'string' : - var path = collectionRef - .replace( /\^/g, 'getOwner().' ) - .replace( /^\~/, 'store.' ) - .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); - - return new Function( 'return this.' + path ); + case 'function' : + return collectionRef; + case 'object' : + return function(){ return collectionRef; }; + case 'string' : + var path = collectionRef + .replace( /\^/g, 'getOwner().' ) + .replace( /^\~/, 'store.' ) + .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); + + return new Function( 'return this.' + path ); } } var TakeAttribute = attribute.Type.extend( { - clone : function( value ){ return value; }, + clone : function( value ){ return value; }, isChanged : function( a, b ){ return a !== b; }, - set : function( value, name ){ + set : function( value, name ){ if( !value ) return null; error.hardRefNotAssignable( this, name, value ); @@ -3334,16 +3336,16 @@ return /******/ (function(modules) { // webpackBootstrap _update : function( val, options, model, attr ){ return this.delegateEvents( this.cast( val, options, model, attr ), options, model, attr ); } - }); + } ); exports.take = function( reference ){ var getMaster = parseReference( reference ); - var options = attribute({ - value : null, + var options = attribute( { + value : null, toJSON : false, - type : this, - get : function( ref, name ){ + type : this, + get : function( ref, name ){ if( !ref ){ // Resolve reference. var value = getMaster.call( this ); @@ -3358,12 +3360,44 @@ return /******/ (function(modules) { // webpackBootstrap return ref; } - }); + } ); options.Attribute = TakeAttribute; return options; }; + exports.valueLink = function( reference ){ + var getMaster = parseReference( reference ); + + function setLink( value ){ + var link = getMaster.call( this ); + link && link.requestChanges( value ); + } + + function getLink(){ + var link = getMaster.call( this ); + return link && link.value; + } + + var LinkAttribute = attribute.Type.extend( { + createPropertySpec : function(){ + return { + // call to optimized set function for single argument. Doesn't work for backbone types. + set : setLink, + + // attach get hook to the getter function, if present + get : getLink + } + }, + + set : setLink + } ); + + var options = attribute( { toJSON : false } ); + options.Attribute = LinkAttribute; + return options; + }; + exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); @@ -3390,7 +3424,7 @@ return /******/ (function(modules) { // webpackBootstrap if( master && master.length ){ // Silently update attribute with object form master. - objOrId = master.get( objOrId ) || null; + objOrId = master.get( objOrId ) || null; this.attributes[ name ] = objOrId; // Subscribe for events manually. delegateEvents won't be invoked. @@ -3406,7 +3440,7 @@ return /******/ (function(modules) { // webpackBootstrap } } ); - var options = attribute( { value : null } ); + var options = attribute( { value : null } ); options.Attribute = ModelRefAttribute; //todo: consider moving this to the attrSpec return options; }; @@ -3415,7 +3449,7 @@ return /******/ (function(modules) { // webpackBootstrap var refsCollectionSpec = { _listenToChanges : bbVersion >= '1.2.0' ? 'update reset' : 'add remove reset', // don't bubble changes from models - __class : 'Collection.SubsetOf', + __class : 'Collection.SubsetOf', resolvedWith : null, refs : null, @@ -3425,9 +3459,9 @@ return /******/ (function(modules) { // webpackBootstrap }, clone : function( options ){ - var copy = CollectionProto.clone.call( this, _.omit( options, 'deep' ) ); + var copy = CollectionProto.clone.call( this, _.omit( options, 'deep' ) ); copy.resolvedWith = this.resolvedWith; - copy.refs = this.refs; + copy.refs = this.refs; return copy; }, @@ -3452,7 +3486,7 @@ return /******/ (function(modules) { // webpackBootstrap return CollectionProto.toggle.call( this, model, val ); }, - addAll : function(){ + addAll : function(){ this.reset( this.resolvedWith.models ); }, @@ -3471,12 +3505,12 @@ return /******/ (function(modules) { // webpackBootstrap getModelIds : function(){ return this.refs || _.pluck( this.models, 'id' ); }, - justOne : function( arg ){ + justOne : function( arg ){ var model = arg instanceof Backbone.Model ? arg : this.resolvedWith.get( arg ); this.set( [ model ] ); }, - set : function( models, upperOptions ){ + set : function( models, upperOptions ){ var options = { merge : false }; if( models ){ @@ -3503,7 +3537,7 @@ return /******/ (function(modules) { // webpackBootstrap }; exports.subsetOf = function( masterCollection ){ - var SubsetOf = this.__subsetOf || ( this.__subsetOf = this.extend( refsCollectionSpec ) ); + var SubsetOf = this.__subsetOf || ( this.__subsetOf = this.extend( refsCollectionSpec ) ); var getMaster = parseReference( masterCollection ); return attribute( { diff --git a/src/main.js b/src/main.js index b2ce3a6..7529b14 100644 --- a/src/main.js +++ b/src/main.js @@ -29,6 +29,8 @@ _.extend( exports, Backbone, { return attribute( { value : value } ); }, + valueLink : relations.valueLink, + Collection : Collection, Model : Model, Store : Store.Model, diff --git a/src/relations.js b/src/relations.js index 32c1c4b..bb92278 100644 --- a/src/relations.js +++ b/src/relations.js @@ -9,24 +9,24 @@ var bbVersion = require( './backbone+' ).VERSION, function parseReference( collectionRef ){ switch( typeof collectionRef ){ - case 'function' : - return collectionRef; - case 'object' : - return function(){ return collectionRef; }; - case 'string' : - var path = collectionRef - .replace( /\^/g, 'getOwner().' ) - .replace( /^\~/, 'store.' ) - .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); - - return new Function( 'return this.' + path ); + case 'function' : + return collectionRef; + case 'object' : + return function(){ return collectionRef; }; + case 'string' : + var path = collectionRef + .replace( /\^/g, 'getOwner().' ) + .replace( /^\~/, 'store.' ) + .replace( /^store\.(\w+)/, 'getStore().get("$1")' ); + + return new Function( 'return this.' + path ); } } var TakeAttribute = attribute.Type.extend( { - clone : function( value ){ return value; }, + clone : function( value ){ return value; }, isChanged : function( a, b ){ return a !== b; }, - set : function( value, name ){ + set : function( value, name ){ if( !value ) return null; error.hardRefNotAssignable( this, name, value ); @@ -35,16 +35,16 @@ var TakeAttribute = attribute.Type.extend( { _update : function( val, options, model, attr ){ return this.delegateEvents( this.cast( val, options, model, attr ), options, model, attr ); } -}); +} ); exports.take = function( reference ){ var getMaster = parseReference( reference ); - var options = attribute({ - value : null, + var options = attribute( { + value : null, toJSON : false, - type : this, - get : function( ref, name ){ + type : this, + get : function( ref, name ){ if( !ref ){ // Resolve reference. var value = getMaster.call( this ); @@ -59,12 +59,44 @@ exports.take = function( reference ){ return ref; } - }); + } ); options.Attribute = TakeAttribute; return options; }; +exports.valueLink = function( reference ){ + var getMaster = parseReference( reference ); + + function setLink( value ){ + var link = getMaster.call( this ); + link && link.requestChanges( value ); + } + + function getLink(){ + var link = getMaster.call( this ); + return link && link.value; + } + + var LinkAttribute = attribute.Type.extend( { + createPropertySpec : function(){ + return { + // call to optimized set function for single argument. Doesn't work for backbone types. + set : setLink, + + // attach get hook to the getter function, if present + get : getLink + } + }, + + set : setLink + } ); + + var options = attribute( { toJSON : false } ); + options.Attribute = LinkAttribute; + return options; +}; + exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); @@ -91,7 +123,7 @@ exports.from = function( masterCollection ){ if( master && master.length ){ // Silently update attribute with object form master. - objOrId = master.get( objOrId ) || null; + objOrId = master.get( objOrId ) || null; this.attributes[ name ] = objOrId; // Subscribe for events manually. delegateEvents won't be invoked. @@ -107,7 +139,7 @@ exports.from = function( masterCollection ){ } } ); - var options = attribute( { value : null } ); + var options = attribute( { value : null } ); options.Attribute = ModelRefAttribute; //todo: consider moving this to the attrSpec return options; }; @@ -116,7 +148,7 @@ var CollectionProto = Collection.prototype; var refsCollectionSpec = { _listenToChanges : bbVersion >= '1.2.0' ? 'update reset' : 'add remove reset', // don't bubble changes from models - __class : 'Collection.SubsetOf', + __class : 'Collection.SubsetOf', resolvedWith : null, refs : null, @@ -126,9 +158,9 @@ var refsCollectionSpec = { }, clone : function( options ){ - var copy = CollectionProto.clone.call( this, _.omit( options, 'deep' ) ); + var copy = CollectionProto.clone.call( this, _.omit( options, 'deep' ) ); copy.resolvedWith = this.resolvedWith; - copy.refs = this.refs; + copy.refs = this.refs; return copy; }, @@ -153,7 +185,7 @@ var refsCollectionSpec = { return CollectionProto.toggle.call( this, model, val ); }, - addAll : function(){ + addAll : function(){ this.reset( this.resolvedWith.models ); }, @@ -172,12 +204,12 @@ var refsCollectionSpec = { getModelIds : function(){ return this.refs || _.pluck( this.models, 'id' ); }, - justOne : function( arg ){ + justOne : function( arg ){ var model = arg instanceof Backbone.Model ? arg : this.resolvedWith.get( arg ); this.set( [ model ] ); }, - set : function( models, upperOptions ){ + set : function( models, upperOptions ){ var options = { merge : false }; if( models ){ @@ -204,7 +236,7 @@ var refsCollectionSpec = { }; exports.subsetOf = function( masterCollection ){ - var SubsetOf = this.__subsetOf || ( this.__subsetOf = this.extend( refsCollectionSpec ) ); + var SubsetOf = this.__subsetOf || ( this.__subsetOf = this.extend( refsCollectionSpec ) ); var getMaster = parseReference( masterCollection ); return attribute( { From ecf6cdccdbbcabcbbc3883230ba25d0a41cf0106 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 13:58:22 -0500 Subject: [PATCH 12/21] moved valueLink to nestedreact --- src/main.js | 3 ++- src/relations.js | 34 ++-------------------------------- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/main.js b/src/main.js index 7529b14..bebc6f1 100644 --- a/src/main.js +++ b/src/main.js @@ -20,6 +20,7 @@ var Store = require( './store' ); Object.defineProperty( exports, 'store', Store.globalProp ); _.extend( exports, Backbone, { + Backbone : Backbone, Class : require( './object+' ), error : require( './errors' ), attribute : attribute, @@ -29,7 +30,7 @@ _.extend( exports, Backbone, { return attribute( { value : value } ); }, - valueLink : relations.valueLink, + parseReference : relations.parseReference, Collection : Collection, Model : Model, diff --git a/src/relations.js b/src/relations.js index bb92278..4462669 100644 --- a/src/relations.js +++ b/src/relations.js @@ -23,6 +23,8 @@ function parseReference( collectionRef ){ } } +exports.parseReference = parseReference; + var TakeAttribute = attribute.Type.extend( { clone : function( value ){ return value; }, isChanged : function( a, b ){ return a !== b; }, @@ -65,38 +67,6 @@ exports.take = function( reference ){ return options; }; -exports.valueLink = function( reference ){ - var getMaster = parseReference( reference ); - - function setLink( value ){ - var link = getMaster.call( this ); - link && link.requestChanges( value ); - } - - function getLink(){ - var link = getMaster.call( this ); - return link && link.value; - } - - var LinkAttribute = attribute.Type.extend( { - createPropertySpec : function(){ - return { - // call to optimized set function for single argument. Doesn't work for backbone types. - set : setLink, - - // attach get hook to the getter function, if present - get : getLink - } - }, - - set : setLink - } ); - - var options = attribute( { toJSON : false } ); - options.Attribute = LinkAttribute; - return options; -}; - exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); From fa677f228e612df2c7c2551cdbcd9670167e40d6 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 14:10:48 -0500 Subject: [PATCH 13/21] updated nestedtypes --- nestedtypes.js | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 2c092d2..1940c02 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -76,6 +76,7 @@ return /******/ (function(modules) { // webpackBootstrap Object.defineProperty( exports, 'store', Store.globalProp ); _.extend( exports, Backbone, { + Backbone : Backbone, Class : __webpack_require__( 3 ), error : __webpack_require__( 8 ), attribute : attribute, @@ -85,7 +86,7 @@ return /******/ (function(modules) { // webpackBootstrap return attribute( { value : value } ); }, - valueLink : relations.valueLink, + parseReference : relations.parseReference, Collection : Collection, Model : Model, @@ -3324,6 +3325,8 @@ return /******/ (function(modules) { // webpackBootstrap } } + exports.parseReference = parseReference; + var TakeAttribute = attribute.Type.extend( { clone : function( value ){ return value; }, isChanged : function( a, b ){ return a !== b; }, @@ -3366,38 +3369,6 @@ return /******/ (function(modules) { // webpackBootstrap return options; }; - exports.valueLink = function( reference ){ - var getMaster = parseReference( reference ); - - function setLink( value ){ - var link = getMaster.call( this ); - link && link.requestChanges( value ); - } - - function getLink(){ - var link = getMaster.call( this ); - return link && link.value; - } - - var LinkAttribute = attribute.Type.extend( { - createPropertySpec : function(){ - return { - // call to optimized set function for single argument. Doesn't work for backbone types. - set : setLink, - - // attach get hook to the getter function, if present - get : getLink - } - }, - - set : setLink - } ); - - var options = attribute( { toJSON : false } ); - options.Attribute = LinkAttribute; - return options; - }; - exports.from = function( masterCollection ){ var getMaster = parseReference( masterCollection ); From 83ce3d820528d9bbf60c62769195d2c5ee3bfab9 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Tue, 10 Nov 2015 17:38:44 -0500 Subject: [PATCH 14/21] createSubset ddn't resolved collection --- nestedtypes.js | 4 +++- src/collection.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 1940c02..5195cf6 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -3279,7 +3279,9 @@ return /******/ (function(modules) { // webpackBootstrap createSubset : function( models, options ){ var SubsetOf = this.constructor.subsetOf( this ).createAttribute().type; - return new SubsetOf( models, options ); + var subset = new SubsetOf( models, options ); + subset.resolve( this ); + return subset; } }, { // Cache for subsetOf collection subclass. diff --git a/src/collection.js b/src/collection.js index 3eaa645..8fc2ad3 100644 --- a/src/collection.js +++ b/src/collection.js @@ -130,7 +130,9 @@ module.exports = Backbone.Collection.extend( { createSubset : function( models, options ){ var SubsetOf = this.constructor.subsetOf( this ).createAttribute().type; - return new SubsetOf( models, options ); + var subset = new SubsetOf( models, options ); + subset.resolve( this ); + return subset; } }, { // Cache for subsetOf collection subclass. From ccd3cc452fbc8cb054ab9998bf3bef5b2714199a Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 12 Nov 2015 21:27:58 -0500 Subject: [PATCH 15/21] updated package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 907ecaf..7c24961 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.2.0-1", + "version": "1.2.0", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From fedbdac82fe8aa5d9f49c4f69764fe3f1c75ec81 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 12 Nov 2015 21:34:01 -0500 Subject: [PATCH 16/21] bumped package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c24961..cb9042a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.2.0", + "version": "1.2.1", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From c06472fa0576d0b7091360d64eee4382e5a17b45 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 12 Nov 2015 21:38:45 -0500 Subject: [PATCH 17/21] updated read --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec165f9..e7045ff 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ master: [![Master Build Status](https://travis-ci.org/Volicon/backbone.nestedTypes.svg?branch=master)](https://travis-ci.org/Volicon/backbone.nestedTypes) develop: [![Develop Build Status](https://travis-ci.org/Volicon/backbone.nestedTypes.svg?branch=develop)](https://travis-ci.org/Volicon/backbone.nestedTypes) -Version 1.1.5 highlights: +Version 1.2.0 highlights: +- React integration and data binding support. [npm install nestedreact](https://github.com/Volicon/react-backbone.glue/) - Fixed incompatibilities with backbone 1.2.x by removing backbone dependency, effective now and forever. Currently, stable backbone 1.1.2 is linked in. - npm package name is changed to just 'nestedtypes'. Thus, `npm install nestedtypes`. - Can be used as drop-in backbonejs replacement in your project. From 0380254c0ddb10a989ff17ccb3d613d9249c7c23 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 16 Nov 2015 21:14:03 -0500 Subject: [PATCH 18/21] fixed typo in watcher --- nestedtypes.js | 2 +- src/attribute.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 5195cf6..03209ad 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -2754,7 +2754,7 @@ return /******/ (function(modules) { // webpackBootstrap function parseReference( ref ){ switch( typeof ref ){ case 'string' : - var path = 'self. ' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + var path = 'self.' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), callback = path.pop(), context = new Function( 'self', 'return ' + path.join( '.' ) ); diff --git a/src/attribute.js b/src/attribute.js index d82c5cb..ea30f71 100644 --- a/src/attribute.js +++ b/src/attribute.js @@ -21,7 +21,7 @@ var availableOptions = [ 'triggerWhenChanged', 'changeEvents', 'parse', 'clone', function parseReference( ref ){ switch( typeof ref ){ case 'string' : - var path = 'self. ' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + var path = 'self.' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), callback = path.pop(), context = new Function( 'self', 'return ' + path.join( '.' ) ); From 9c4418773bee6e8ba80b03ccf87834bec04e2821 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 16 Nov 2015 21:32:29 -0500 Subject: [PATCH 19/21] fixed has.watcher --- nestedtypes.js | 4 +++- src/attribute.js | 4 +++- test/types.js | 12 +++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/nestedtypes.js b/nestedtypes.js index 03209ad..2726eb8 100644 --- a/nestedtypes.js +++ b/nestedtypes.js @@ -2754,7 +2754,7 @@ return /******/ (function(modules) { // webpackBootstrap function parseReference( ref ){ switch( typeof ref ){ case 'string' : - var path = 'self.' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + var path = ( 'self.' + ref.replace( /\^/g, 'getOwner().' ) ).split( '.' ), callback = path.pop(), context = new Function( 'self', 'return ' + path.join( '.' ) ); @@ -2810,6 +2810,8 @@ return /******/ (function(modules) { // webpackBootstrap else{ error.wrongWatcher( this, ref ); } + + return this; }, proxy : function( attrs ){ diff --git a/src/attribute.js b/src/attribute.js index ea30f71..0dae454 100644 --- a/src/attribute.js +++ b/src/attribute.js @@ -21,7 +21,7 @@ var availableOptions = [ 'triggerWhenChanged', 'changeEvents', 'parse', 'clone', function parseReference( ref ){ switch( typeof ref ){ case 'string' : - var path = 'self.' + ref.replace( /\^/g, 'getOwner().' ).split( '.' ), + var path = ( 'self.' + ref.replace( /\^/g, 'getOwner().' ) ).split( '.' ), callback = path.pop(), context = new Function( 'self', 'return ' + path.join( '.' ) ); @@ -77,6 +77,8 @@ var Options = Object.extend( { else{ error.wrongWatcher( this, ref ); } + + return this; }, proxy : function( attrs ){ diff --git a/test/types.js b/test/types.js index 33d5a34..f2e1a00 100644 --- a/test/types.js +++ b/test/types.js @@ -278,7 +278,8 @@ if( value !== 0 ){ return value * 2; } - }) + }), + b : Number.has.watcher( 'watcher' ) } }); @@ -313,6 +314,15 @@ expect( m.a ).to.be.equal( 66 ); }); + + it( 'may prevent attribute\'s assignment', function(){ + var m = new A(); + m.watcher = sinon.spy(); + + m.b = 77; + expect( m.watcher ).to.be.calledOnce; + expect( m.watcher ).to.be.calledWith( 77 ); + }); }); describe( 'toJSON hook', function(){ From 54a6af1c435cc5d4068a54db9d05e196eee2bd04 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 16 Nov 2015 21:33:44 -0500 Subject: [PATCH 20/21] 1.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb9042a..0edeb18 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "LICENSE" ], "license": "MIT", - "version": "1.2.1", + "version": "1.2.2", "scripts": { "test": "node_modules/.bin/mocha", "build": "./node_modules/.bin/webpack", From 5d593e09bb280ca085715b75d92466b017060428 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Mon, 16 Nov 2015 21:39:29 -0500 Subject: [PATCH 21/21] basic _owner test --- test/backboneTypes.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/backboneTypes.js b/test/backboneTypes.js index 73f23a8..18a9961 100644 --- a/test/backboneTypes.js +++ b/test/backboneTypes.js @@ -63,6 +63,19 @@ describe( 'Nested parse method', function(){ describe( 'Nested model', function(){ + it( 'set _owner property', function(){ + var m = new B(); + + expect( m.first._owner ).to.eql( m ); + expect( m.c._owner ).to.eql( m ); + + var a = new A(); + var _first = m.first; + m.first = a; + expect( _first._owner ).to.not.ok; + expect( m.first._owner ).to.eql( m ); + }); + it( 'invoke "parse" on construction', function(){ var spies = createSpies();