From f023cbce3d8d1dfc73c3e40aabd809d4ca2048c6 Mon Sep 17 00:00:00 2001 From: Bradley Momberger Date: Mon, 1 May 2017 13:01:33 -0600 Subject: [PATCH] Don't attempt to redefine _data or _computed on DefineMaps if they're already defined --- can-define.js | 40 ++++++++++++++++++++++++++-------------- map/map-test.js | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/can-define.js b/can-define.js index 9971fad..60d381a 100644 --- a/can-define.js +++ b/can-define.js @@ -72,26 +72,38 @@ module.exports = define = ns.define = function(objPrototype, defines, baseDefine // Places a `_data` on the prototype that when first called replaces itself // with a `_data` object local to the instance. It also defines getters // for any value that has a default value. - replaceWith(objPrototype, "_data", function() { - var map = this; - var data = {}; + if(objPrototype.hasOwnProperty("_data")) { for (var prop in dataInitializers) { - replaceWith(data, prop, dataInitializers[prop].bind(map), true); - } - return data; - }); + replaceWith(objPrototype._data, prop, dataInitializers[prop].bind(objPrototype), true); + } + } else { + replaceWith(objPrototype, "_data", function() { + var map = this; + var data = {}; + for (var prop in dataInitializers) { + replaceWith(data, prop, dataInitializers[prop].bind(map), true); + } + return data; + }); + } // Places a `_computed` on the prototype that when first called replaces itself // with a `_computed` object local to the instance. It also defines getters // that will create the property's compute when read. - replaceWith(objPrototype, "_computed", function() { - var map = this; - var data = Object.create(null); - for (var prop in computedInitializers) { - replaceWith(data, prop, computedInitializers[prop].bind(map)); + if(objPrototype.hasOwnProperty("_computed")) { + for (prop in computedInitializers) { + replaceWith(objPrototype._computed, prop, computedInitializers[prop].bind(objPrototype)); } - return data; - }); + } else { + replaceWith(objPrototype, "_computed", function() { + var map = this; + var data = Object.create(null); + for (var prop in computedInitializers) { + replaceWith(data, prop, computedInitializers[prop].bind(map)); + } + return data; + }); + } // Add necessary event methods to this object. diff --git a/map/map-test.js b/map/map-test.js index 03afe0d..6589e84 100644 --- a/map/map-test.js +++ b/map/map-test.js @@ -1,6 +1,7 @@ "use strict"; var QUnit = require("steal-qunit"); var DefineMap = require("can-define/map/map"); +var define = require("can-define"); var Observation = require("can-observation"); var canTypes = require("can-types"); var each = require("can-util/js/each/each"); @@ -662,4 +663,26 @@ QUnit.test(".value values are overwritten by props in DefineMap construction", f }); equal(foo.bar, "quux", "Value set properly"); +}); + +QUnit.test("Does not attempt to redefine _data if already defined", function() { + var Bar = DefineMap.extend({seal: false}, { + baz: { value : "thud" } + }); + + var baz = new Bar(); + + define(baz, { + quux: { value: "jeek" }, + plonk: { + get: function() { + return "waldo"; + } + } + }, baz._define); + + QUnit.equal(baz.quux, "jeek", "New definitions successful"); + QUnit.equal(baz.plonk, "waldo", "New computed definitions successful"); + QUnit.equal(baz.baz, "thud", "Old definitions still available"); + }); \ No newline at end of file