Skip to content

Commit

Permalink
Merge pull request #2300 from Leaflet/prototypal-options
Browse files Browse the repository at this point in the history
Make options object prototype-inherited
  • Loading branch information
mourner committed Dec 16, 2013
2 parents f619e3b + e44b8d9 commit a78dc74
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 19 deletions.
20 changes: 15 additions & 5 deletions spec/suites/core/ClassSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,22 @@ describe("Class", function () {
});

var a = new KlassWithOptions2();
expect(a.options.foo1).to.eql(1);
expect(a.options.foo2).to.eql(3);
expect(a.options.foo3).to.eql(4);
});

expect(a.options).to.eql({
foo1: 1,
foo2: 3,
foo3: 4
});
it("gives new classes a distinct options object", function () {
var K1 = L.Class.extend({options: {}});
var K2 = K1.extend({});
expect(K2.prototype.options).not.to.equal(K1.prototype.options);
});

it("inherits options prototypally", function () {
var K1 = L.Class.extend({options: {}});
var K2 = K1.extend({options: {}});
K1.prototype.options.foo = 'bar';
expect(K2.prototype.options.foo).to.eql('bar');
});

it("adds constructor hooks correctly", function () {
Expand Down
42 changes: 41 additions & 1 deletion spec/suites/core/UtilSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,47 @@ describe('Util', function () {
});
});

// TODO setOptions
describe('#setOptions', function () {
it('sets specified options on object', function () {
var o = {};
L.Util.setOptions(o, {foo: 'bar'});
expect(o.options.foo).to.eql('bar');
});

it('returns options', function () {
var o = {};
var r = L.Util.setOptions(o, {foo: 'bar'});
expect(r).to.equal(o.options);
});

it('accepts undefined', function () {
var o = {};
L.Util.setOptions(o, undefined);
expect(o.options).to.eql({});
});

it('creates a distinct options object', function () {
var opts = {},
o = L.Util.create({options: opts});
L.Util.setOptions(o, {});
expect(o.options).not.to.equal(opts);
});

it("doesn't create a distinct options object if object already has own options", function () {
var opts = {},
o = {options: opts};
L.Util.setOptions(o, {});
expect(o.options).to.equal(opts);
});

it('inherits options prototypally', function () {
var opts = {},
o = L.Util.create({options: opts});
L.Util.setOptions(o, {});
opts.foo = 'bar';
expect(o.options.foo).to.eql('bar');
});
});

describe('#template', function () {
it('evaluates templates with a given data object', function () {
Expand Down
10 changes: 3 additions & 7 deletions src/core/Class.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ L.Class.extend = function (props) {
}
};

// instantiate class without calling constructor
var F = function () {};
F.prototype = this.prototype;

var proto = new F();
var proto = L.Util.create(this.prototype);
proto.constructor = NewClass;

NewClass.prototype = proto;
Expand All @@ -50,8 +46,8 @@ L.Class.extend = function (props) {
}

// merge options
if (props.options && proto.options) {
props.options = L.extend({}, proto.options, props.options);
if (proto.options) {
props.options = L.Util.extend(L.Util.create(proto.options), props.options);
}

// mix given properties into the prototype
Expand Down
23 changes: 17 additions & 6 deletions src/core/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@
*/

L.Util = {
extend: function (dest) { // (Object[, Object, ...]) ->
extend: function (dest) {
var sources = Array.prototype.slice.call(arguments, 1),
i, j, len, src;

for (j = 0, len = sources.length; j < len; j++) {
src = sources[j] || {};
src = sources[j];
for (i in src) {
if (src.hasOwnProperty(i)) {
dest[i] = src[i];
}
dest[i] = src[i];
}
}
return dest;
},

create: Object.create || (function () {
function F() {}
return function (proto) {
F.prototype = proto;
return new F();
};
})(),

bind: function (fn, obj) {
var slice = Array.prototype.slice;

Expand Down Expand Up @@ -107,7 +113,12 @@ L.Util = {
},

setOptions: function (obj, options) {
obj.options = options ? L.extend({}, obj.options, options) : obj.options || {};
if (!obj.hasOwnProperty('options')) {
obj.options = obj.options ? L.Util.create(obj.options) : {};
}
for (var i in options) {
obj.options[i] = options[i];
}
return obj.options;
},

Expand Down

0 comments on commit a78dc74

Please sign in to comment.