Skip to content

Commit

Permalink
Merge branch 'master' into ie11-configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaswilburn committed Sep 4, 2018
2 parents edb2105 + aeb480e commit 79a6c98
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 64 deletions.
68 changes: 62 additions & 6 deletions can-define.js
Expand Up @@ -929,7 +929,8 @@ getDefinitionsAndMethods = function(defines, baseDefines, typePrototype) {
}
});
if(defaults) {
defines["*"] = defaults;
// we should move this property off the prototype.
defineConfigurableAndNotEnumerable(defines,"*", defaults);
}
return {definitions: definitions, methods: methods, defaultDefinition: defaultDefinition};
};
Expand Down Expand Up @@ -1013,11 +1014,7 @@ define.setup = function(props, sealed) {
if(definitions[prop] !== undefined) {
map[prop] = value;
} else {
var def = define.makeSimpleGetterSetter(prop);
instanceDefinitions[prop] = {};
Object_defineNamedPrototypeProperty(map, prop, def);
// possibly convert value to List or DefineMap
map[prop] = define.types.observable(value);
define.expando(map, prop, value);
}
});
if(canReflect.size(instanceDefinitions) > 0) {
Expand All @@ -1034,6 +1031,65 @@ define.setup = function(props, sealed) {
}
//!steal-remove-end
};


var returnFirstArg = function(arg){
return arg;
};

define.expando = function(map, prop, value) {
if(define._specialKeys[prop]) {
// ignores _data and _computed
return true;
}
// first check if it's already a constructor define
var constructorDefines = map._define.definitions;
if(constructorDefines && constructorDefines[prop]) {
return;
}
// next if it's already on this instances
var instanceDefines = map._instanceDefinitions;
if(!instanceDefines) {
if(Object.isSealed(map)) {
return;
}
Object.defineProperty(map, "_instanceDefinitions", {
configurable: true,
enumerable: false,
writable: true,
value: {}
});
instanceDefines = map._instanceDefinitions;
}
if(!instanceDefines[prop]) {
var defaultDefinition = map._define.defaultDefinition || {type: define.types.observable};
define.property(map, prop, defaultDefinition, {},{});
// possibly convert value to List or DefineMap
if(defaultDefinition.type) {
map._data[prop] = define.make.set.type(prop, defaultDefinition.type, returnFirstArg).call(map, value);
} else {
map._data[prop] = define.types.observable(value);
}

instanceDefines[prop] = defaultDefinition;
if(!map.__inSetup) {
queues.batch.start();
map.dispatch({
type: "can.keys",
target: map
});
if(map._data[prop] !== undefined) {
map.dispatch({
type: prop,
target: map,
patches: [{type: "set", key: prop, value: map._data[prop]}],
},[map._data[prop], undefined]);
}
queues.batch.stop();
}
return true;
}
};
define.replaceWith = defineLazyValue;
define.eventsProto = eventsProto;
define.defineConfigurableAndNotEnumerable = defineConfigurableAndNotEnumerable;
Expand Down
55 changes: 1 addition & 54 deletions define-helpers/define-helpers.js
Expand Up @@ -5,62 +5,9 @@ var queues = require("can-queues");
var dev = require("can-log/dev/dev");
var ensureMeta = require("../ensure-meta");

var returnFirstArg = function(arg){
return arg;
};
var defineHelpers = {
// returns `true` if the value was defined and set
defineExpando: function(map, prop, value) {
if(define._specialKeys[prop]) {
// ignores _data and _computed
return true;
}
// first check if it's already a constructor define
var constructorDefines = map._define.definitions;
if(constructorDefines && constructorDefines[prop]) {
return;
}
// next if it's already on this instances
var instanceDefines = map._instanceDefinitions;
if(!instanceDefines) {
if(Object.isSealed(map)) {
return;
}
Object.defineProperty(map, "_instanceDefinitions", {
configurable: true,
enumerable: false,
writable: true,
value: {}
});
instanceDefines = map._instanceDefinitions;
}
if(!instanceDefines[prop]) {
var defaultDefinition = map._define.defaultDefinition || {type: define.types.observable};
define.property(map, prop, defaultDefinition, {},{});
// possibly convert value to List or DefineMap
if(defaultDefinition.type) {
map._data[prop] = define.make.set.type(prop, defaultDefinition.type, returnFirstArg).call(map, value);
} else {
map._data[prop] = define.types.observable(value);
}

instanceDefines[prop] = defaultDefinition;
queues.batch.start();
map.dispatch({
type: "can.keys",
target: map
});
if(map._data[prop] !== undefined) {
map.dispatch({
type: prop,
target: map,
patches: [{type: "set", key: prop, value: map._data[prop]}],
},[map._data[prop], undefined]);
}
queues.batch.stop();
return true;
}
},
defineExpando: define.expando,
reflectSerialize: function(unwrapped){
var constructorDefinitions = this._define.definitions;
var defaultDefinition = this._define.defaultDefinition;
Expand Down
30 changes: 30 additions & 0 deletions map/map-test.js
Expand Up @@ -1426,3 +1426,33 @@ QUnit.test("type called with `this` as the map (#349)", function(){
var map = new Type();
QUnit.equal(map.foo, 5);
});

QUnit.test("expandos use default type (#383)", function(){
var AllNumbers = DefineMap.extend({
"*": {type: "number"}
});

var someNumbers = new AllNumbers({
version: "24"
});
QUnit.ok(someNumbers.version === 24, "is 24");
});

QUnit.test("do not enumerate anything other than key properties (#369)", function(){
var Type = DefineMap.extend({
aProp: "string",
aMethod: function(){}
});

var instance = new Type({aProp: "VALUE", anExpando: "VALUE"});

var props = {};
for(var prop in instance) {
props[prop] = true;
}
QUnit.deepEqual(props,{
aProp: true,
anExpando: true,
aMethod: true // TODO: this should be removed someday
});
});
5 changes: 2 additions & 3 deletions map/map.js
Expand Up @@ -86,14 +86,13 @@ var DefineMap = Construct.extend("DefineMap",{
for(key in DefineMap.prototype) {
define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
}

this.prototype.setup = function(props){
define.defineConfigurableAndNotEnumerable(prototype, "setup", function(props){
define.setup.call(
this,
props || {},
this.constructor.seal
);
};
});
} else {
for(key in prototype) {
define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]);
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "can-define",
"version": "2.5.9",
"version": "2.5.10",
"description": "Create observable objects with JS dot operator compatibility",
"main": "can-define.js",
"scripts": {
Expand Down

0 comments on commit 79a6c98

Please sign in to comment.