Created
November 20, 2014 21:56
-
-
Save imjoshdean/92e1126f9988f1e605fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*! | |
| * CanJS - 2.1.3 | |
| * http://canjs.us/ | |
| * Copyright (c) 2014 Bitovi | |
| * Mon, 25 Aug 2014 21:51:38 GMT | |
| * Licensed MIT | |
| * Includes: can/map/define | |
| * Download from: http://canjs.com | |
| */ | |
| (function(undefined) { | |
| // ## map/define/define.js | |
| var __m1 = (function(can) { | |
| can.Map.helpers.define = function(Map) { | |
| var define = Map.prototype.define; | |
| Map.defaultGenerators = {}; | |
| for (var prop in define) { | |
| if ("value" in define[prop]) { | |
| if (typeof define[prop].value === "function") { | |
| Map.defaultGenerators[prop] = define[prop].value; | |
| } else { | |
| Map.defaults[prop] = define[prop].value; | |
| } | |
| } | |
| if (typeof define[prop].Value === "function") { | |
| (function(Constructor) { | |
| Map.defaultGenerators[prop] = function() { | |
| return new Constructor(); | |
| }; | |
| })(define[prop].Value); | |
| } | |
| } | |
| }; | |
| var oldSetupDefaults = can.Map.prototype._setupDefaults; | |
| can.Map.prototype._setupDefaults = function() { | |
| var defaults = oldSetupDefaults.call(this), | |
| Map = this.constructor; | |
| for (var prop in Map.defaultGenerators) { | |
| defaults[prop] = Map.defaultGenerators[prop].call(this); | |
| } | |
| return defaults; | |
| }; | |
| var proto = can.Map.prototype, | |
| oldSet = proto.__set; | |
| proto.__set = function(prop, value, current, success, error) { | |
| // check if there's a setter | |
| var errorCallback = function(errors) { | |
| var stub = error && error.call(self, errors); | |
| // if 'validations' is on the page it will trigger | |
| // the error itself and we dont want to trigger | |
| // the event twice. :) | |
| if (stub !== false) { | |
| can.trigger(self, 'error', [ | |
| prop, | |
| errors | |
| ], true); | |
| } | |
| return false; | |
| }, | |
| self = this, | |
| define = this.define && this.define[prop], | |
| setter = define && define.set, | |
| getter = define && define.get; | |
| // if we have a setter | |
| if (setter) { | |
| // call the setter, if returned value is undefined, | |
| // this means the setter is async so we | |
| // do not call update property and return right away | |
| can.batch.start(); | |
| var setterCalled = false, | |
| setValue = setter.call(this, value, function(value) { | |
| oldSet.call(self, prop, value, current, success, errorCallback); | |
| setterCalled = true; | |
| }, errorCallback); | |
| if (getter) { | |
| // if there's a getter we do nothing | |
| can.batch.stop(); | |
| return; | |
| } | |
| // if it took a setter and returned nothing, don't set the value | |
| else if (setValue === undefined && !setterCalled && setter.length >= 2) { | |
| can.batch.stop(); | |
| return; | |
| } else { | |
| if (!setterCalled) { | |
| oldSet.call(self, prop, | |
| // if no arguments, we are side-effects only | |
| setter.length === 0 && setValue === undefined ? value : setValue, | |
| current, | |
| success, | |
| errorCallback); | |
| } | |
| can.batch.stop(); | |
| return this; | |
| } | |
| } else { | |
| oldSet.call(self, prop, value, current, success, errorCallback); | |
| } | |
| return this; | |
| }; | |
| var converters = { | |
| 'date': function(str) { | |
| var type = typeof str; | |
| if (type === 'string') { | |
| str = Date.parse(str); | |
| return isNaN(str) ? null : new Date(str); | |
| } else if (type === 'number') { | |
| return new Date(str); | |
| } else { | |
| return str; | |
| } | |
| }, | |
| 'number': function(val) { | |
| return +(val); | |
| }, | |
| 'boolean': function(val) { | |
| if (val === 'false' || val === '0' || !val) { | |
| return false; | |
| } | |
| return true; | |
| }, | |
| '*': function(val) { | |
| return val; | |
| }, | |
| 'string': function(val) { | |
| return '' + val; | |
| } | |
| }; | |
| // the old type sets up bubbling | |
| var oldType = proto.__type; | |
| proto.__type = function(value, prop) { | |
| var def = this.define && this.define[prop], | |
| type = def && def.type, | |
| Type = def && def.Type, | |
| newValue = value; | |
| if (typeof type === "string") { | |
| type = converters[type]; | |
| } | |
| if (type || Type) { | |
| // If there's a type, convert it. | |
| if (type) { | |
| newValue = type.call(this, newValue, prop); | |
| } | |
| // If there's a Type create a new instance of it | |
| if (Type && !(newValue instanceof Type)) { | |
| newValue = new Type(newValue); | |
| } | |
| // If the newValue is a Map, we need to hook it up | |
| return newValue; | |
| } | |
| // If we pass in a object with define | |
| else if(can.isPlainObject(newValue) && newValue.define) { | |
| newValue = can.Map.extend(newValue); | |
| newValue = new newValue(); | |
| } | |
| return oldType.call(this, newValue, prop); | |
| }; | |
| var oldRemove = proto._remove; | |
| proto._remove = function(prop, current) { | |
| var remove = this.define && this.define[prop] && this.define[prop].remove, | |
| res; | |
| if (remove) { | |
| can.batch.start(); | |
| res = remove.call(this, current); | |
| if (res === false) { | |
| can.batch.stop(); | |
| return; | |
| } else { | |
| res = oldRemove.call(this, prop, current); | |
| can.batch.stop(); | |
| return res; | |
| } | |
| } | |
| return oldRemove.call(this, prop, current); | |
| }; | |
| var oldSetupComputes = proto._setupComputes; | |
| proto._setupComputes = function(defaultsValues) { | |
| oldSetupComputes.apply(this, arguments); | |
| for (var attr in this.define) { | |
| var def = this.define[attr], | |
| get = def.get; | |
| if (get) { | |
| this[attr] = can.compute.async(defaultsValues[attr], get, this); | |
| this._computedBindings[attr] = { | |
| count: 0 | |
| }; | |
| } | |
| } | |
| }; | |
| // Overwrite the invidual property serializer b/c we will overwrite it. | |
| var oldSingleSerialize = can.Map.helpers._serialize; | |
| can.Map.helpers._serialize = function(map, name, val) { | |
| return serializeProp(map, name, val); | |
| }; | |
| // If the map has a define serializer for the given attr, run it. | |
| var serializeProp = function(map, attr, val) { | |
| var serializer = map.define && map.define[attr] && map.define[attr].serialize; | |
| if (serializer === undefined) { | |
| return oldSingleSerialize.apply(this, arguments); | |
| } else if (serializer !== false) { | |
| return typeof serializer === "function" ? serializer.call(map, val, attr) : oldSingleSerialize.apply(this, arguments); | |
| } | |
| }; | |
| // Overwrite serialize to add in any missing define serialized properties. | |
| var oldSerialize = proto.serialize; | |
| proto.serialize = function(property) { | |
| var serialized = oldSerialize.apply(this, arguments); | |
| if (property) { | |
| return serialized; | |
| } | |
| // add in properties not already serialized | |
| var serializer, | |
| val; | |
| // Go through each property. | |
| for (var attr in this.define) { | |
| // if it's not already defined | |
| if (!(attr in serialized)) { | |
| // check there is a serializer so we aren't doing extra work on serializer:false | |
| serializer = this.define && this.define[attr] && this.define[attr].serialize; | |
| if (serializer) { | |
| val = serializeProp(this, attr, this.attr(attr)); | |
| if (val !== undefined) { | |
| serialized[attr] = val; | |
| } | |
| } | |
| } | |
| } | |
| return serialized; | |
| }; | |
| return can.Map; | |
| })(window.can, undefined); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment