From 64fb687e8ae38199daeaf00c3d4f90d745c23946 Mon Sep 17 00:00:00 2001 From: mde Date: Mon, 26 Jul 2010 16:09:21 -0700 Subject: [PATCH 1/4] Improved mixin, allows multiple source objects. --- geddy-util/lib/meta.js | 69 ++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/geddy-util/lib/meta.js b/geddy-util/lib/meta.js index 8819c78f..680dbe03 100644 --- a/geddy-util/lib/meta.js +++ b/geddy-util/lib/meta.js @@ -52,33 +52,56 @@ geddy.util.meta = new function () { return constructors; }; - this.mixin = function (/* Target obj */ target, - /* Obj of props or constructor */ mixin, /* Deep-copy flag */ recurse) { - // Create an instance if we get a constructor - var m; - if (typeof mixin == 'function') { - m = new mixin(); - } - else { - m = mixin; - } - for (var p in m) { - // Don't copy anything from Object.prototype - if (m.hasOwnProperty(p)) { - if (recurse && (typeof m[p] == 'object') && (m[p] !== null) && - !(m[p] instanceof Array)) { - if (typeof target[p] == 'undefined') { - target[p] = {}; + /* + * Mix in the properties on an object to another object + * yam.mixin(target, source, [source,] [source, etc.] [merge-flag]); + * 'merge' recurses, to merge object sub-properties together instead + * of just overwriting with the source object. + */ + this.mixin = (function () { + var _mix = function (targ, src, merge) { + for (var p in src) { + // Don't copy stuff from the prototype + if (src.hasOwnProperty(p)) { + if (merge && + // Assumes the source property is an Object you can + // actually recurse down into + (typeof src[p] == 'object') && + (src[p] !== null) && + !(src[p] instanceof Array)) { + // Create the source property if it doesn't exist + // TODO: What if it's something weird like a String or Number? + if (typeof targ[p] == 'undefined') { + targ[p] = {}; + } + _mix(targ[p], src[p], merge); // Recurse + } + // If it's not a merge-copy, just set and forget + else { + targ[p] = src[p]; } - geddy.util.meta.mixin(target[p], m[p], recurse); } - else { - target[p] = m[p]; + } + }; + + return function () { + var args = Array.prototype.slice.apply(arguments), + merge = false, + targ, sources; + if (args.length > 2) { + if (typeof args[args.length - 1] == 'boolean') { + merge = args.pop(); } } - } - return target; - }; + targ = args.shift(); + sources = args; + for (var i = 0, ii = sources.length; i < ii; i++) { + _mix(targ, sources[i], merge); + } + return targ; + }; + })(); + }(); From 2f45ec00c97f4480b201a664d0a45436804a6579 Mon Sep 17 00:00:00 2001 From: mde Date: Mon, 26 Jul 2010 16:11:52 -0700 Subject: [PATCH 2/4] Fixed erroneous line in docs. --- geddy-util/lib/meta.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geddy-util/lib/meta.js b/geddy-util/lib/meta.js index 680dbe03..20800f28 100644 --- a/geddy-util/lib/meta.js +++ b/geddy-util/lib/meta.js @@ -54,7 +54,7 @@ geddy.util.meta = new function () { /* * Mix in the properties on an object to another object - * yam.mixin(target, source, [source,] [source, etc.] [merge-flag]); + * geddy.util.mixin(target, source, [source,] [source, etc.] [merge-flag]); * 'merge' recurses, to merge object sub-properties together instead * of just overwriting with the source object. */ From 9fa247dba788b5e7fdb697c4d0f5450e1c32ca3c Mon Sep 17 00:00:00 2001 From: mde Date: Mon, 26 Jul 2010 16:57:27 -0700 Subject: [PATCH 3/4] Fixed browser-specific bugs in US-style Date parsing. --- geddy-util/lib/date.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geddy-util/lib/date.js b/geddy-util/lib/date.js index 53390762..965939c7 100644 --- a/geddy-util/lib/date.js +++ b/geddy-util/lib/date.js @@ -614,9 +614,9 @@ geddy.util.date = new function () { // Stupid US-only format? if (!matches) { - val.match(_US_DATE_PAT); + matches = val.match(_US_DATE_PAT); if (matches) { - reordered = [null, matches[2], matches[0], matches[1]]; + reordered = [matches[0], matches[3], matches[1], matches[2]]; // Pad the results to the same length as ISO8601 reordered[8] = null; matches = reordered; From ca8abfacdcf87239255ac500d07c74e276dd27fb Mon Sep 17 00:00:00 2001 From: mde Date: Mon, 26 Jul 2010 18:04:11 -0700 Subject: [PATCH 4/4] Added tests for time datatype, fixed bugs. --- geddy-model/tests/datatypes.js | 27 ++++++++++++++++++++++++++- geddy-util/lib/date.js | 7 ++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/geddy-model/tests/datatypes.js b/geddy-model/tests/datatypes.js index a5b8ee9c..30082014 100644 --- a/geddy-model/tests/datatypes.js +++ b/geddy-model/tests/datatypes.js @@ -12,7 +12,8 @@ global.ByTor = function () { this.property('objectProp', 'object'); this.property('arrayProp', 'array'); this.property('dateProp', 'date'); - this.property('datetimeProp', 'date'); + this.property('datetimeProp', 'datetime'); + this.property('timeProp', 'time'); }; geddy.model.registerModel('ByTor'); @@ -166,6 +167,30 @@ var testDatatypes = new function () { } }; + + this.testTime = function () { + var byTor; + var dates, dt, vals; + // Obj key is the input string, value is the list of values + // for the parse Date object's h/m/s/ms + dates = { + '21:12' : [21, 12, 0, 0] + , '1:11': [1, 11, 0, 0] + , '1:11:03': [1, 11, 3, 0] + , '1:11:03.999': [1, 11, 3, 999] + }; + for (var p in dates) { + dt = p; + vals = dates[p]; + byTor = ByTor.create({timeProp: dt}); + assert.ok(byTor.valid()); + assert.equal(byTor.timeProp.getHours(), vals[0]); + assert.equal(byTor.timeProp.getMinutes(), vals[1]); + assert.equal(byTor.timeProp.getSeconds(), vals[2]); + assert.equal(byTor.timeProp.getMilliseconds(), vals[3]); + } + + }; }(); diff --git a/geddy-util/lib/date.js b/geddy-util/lib/date.js index 965939c7..38d209ee 100644 --- a/geddy-util/lib/date.js +++ b/geddy-util/lib/date.js @@ -23,7 +23,8 @@ geddy.util.date = new function () { var _US_DATE_PAT = /^(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{4})/; var _DATETIME_PAT = /^(\d{4})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:T| )?(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?(Z|[+-]\d{4}|[+-]\d{2}:\d{2}|[+-]\d{2})?/; - var _TIME_PAT = /^(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?$/; + // TODO Add am/pm parsing instead of dumb, 24-hour clock. + var _TIME_PAT = /^(\d{1,2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?$/; var _dateMethods = [ 'FullYear' @@ -625,9 +626,9 @@ geddy.util.date = new function () { // Time-stored-in-Date hack? if (!matches) { - val.match(_TIME_PAT); + matches = val.match(_TIME_PAT); if (matches) { - reordered = [null, 0, 0, 0, matches[0], matches[1], matches[2], matches[3], null]; + reordered = [matches[0], 0, 1, 0, matches[1], matches[2], matches[3], matches[4], null]; matches = reordered; } }