From 48a1a67dc15c627ecd285743bfae03e14b80f41b Mon Sep 17 00:00:00 2001
From: Nicolas Bevacqua <nicolasbevacqua@gmail.com>
Date: Sun, 11 Jan 2015 14:12:37 -0300
Subject: [PATCH] rm start-up need for .on('ready', fn)

---
 .jshintignore                  |  1 +
 .jshintrc                      |  3 +-
 CHANGELOG.md                   |  6 ++++
 README.md                      | 10 +-----
 package.json                   |  2 +-
 src/calendar.js                | 28 ++++++++-------
 src/defaults.js                |  2 +-
 src/input.js                   | 33 ++++++++++-------
 src/polyfills/array.every.js   | 33 -----------------
 src/polyfills/array.filter.js  |  2 ++
 src/polyfills/array.foreach.js |  2 ++
 src/polyfills/array.indexof.js |  2 ++
 src/polyfills/array.isarray.js |  2 ++
 src/polyfills/array.map.js     |  2 ++
 src/polyfills/array.some.js    |  2 ++
 src/polyfills/function.bind.js |  2 ++
 src/polyfills/object.keys.js   | 65 +++++++++++++++++-----------------
 src/polyfills/string.trim.js   |  2 ++
 src/rome.js                    |  1 -
 19 files changed, 97 insertions(+), 103 deletions(-)
 delete mode 100644 src/polyfills/array.every.js

diff --git a/.jshintignore b/.jshintignore
index d781733..52727ab 100644
--- a/.jshintignore
+++ b/.jshintignore
@@ -1,3 +1,4 @@
 node_modules
 bower_components
 dist
+example
diff --git a/.jshintrc b/.jshintrc
index de375cf..b51347f 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -18,5 +18,6 @@
   "quotmark": "single",
   "validthis": true,
   "indent": 2,
-  "node": true
+  "node": true,
+  "browser": true
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47cf672..5a0b6fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 2.0.0 Invasion
+
+- Removed necessity to wait until `'ready'` event was fired in order to interact with calendar
+- Event listeners registered on a `'destroy'` event handler will no longer be immediately removed
+- Introduced ability to pass `weekdayFormat` as an array with 7 strings
+
 # 1.2.4 Tunnel Vision
 
 - Fixed [an issue](https://github.com/bevacqua/rome/issues/30) where `autoHideOnBlur` wouldn't work on Firefox
diff --git a/README.md b/README.md
index 990fd22..417ad03 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ Option             | Description
 `timeFormat`       | Format string used to display the time on the calendar
 `timeInterval`     | Seconds between each option in the time dropdown
 `timeValidator`    | Function to validate that a given time is considered valid. Receives a native `Date` parameter.
-`weekdayFormat`    | Format used to display weekdays. Takes `min` -> Mo, `short` -> Mon, or `long` -> Monday.
+`weekdayFormat`    | Format used to display weekdays. Takes `min` _(Mo)_, `short` _(Mon)_, `long` _(Monday)_, or an array with seven strings of your choosing.
 `weekStart`        | Day considered the first of the week. Range: Sunday `0` - Saturday `6`
 
 Note that in the case of input fields, when `initialValue` isn't provided the initial value is inferred from `elem.value` instead. In the case of inline calendars, `Date.now` will be used as a default if none is provided.
@@ -236,14 +236,6 @@ Event       | Arguments   | Description
 `show`      | `[]`        | The calendar has been displayed
 `hide`      | `[]`        | The calendar has been hidden
 
-Please note that you may need to wait for the calendar's `'ready'` event before interacting with it, otherwise most of the API will result in a no-op.
-
-```js
-rome(elem).once('ready', function () {
-  this.show();
-});
-```
-
 #### Date and Time Validator
 
 Please note that `dateValidator` and `timeValidator` both receive a native `Date` object as a parameter. These methods are expected to return `undefined` or `true` if the date is deemed valid, and `false` in case the date is invalid. If `dateValidator` returns `false`, the validation process will try to find a valid date near the desired date.
diff --git a/package.json b/package.json
index 05f49e7..9ffe3c5 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
   },
   "main": "src/rome.moment.js",
   "dependencies": {
-    "contra.emitter": "^1.0.0",
+    "contra.emitter": "^1.1.0",
     "lodash.throttle": "^2.4.1",
     "moment": "^2.8.2",
     "raf": "^2.0.1"
diff --git a/src/calendar.js b/src/calendar.js
index 2a058bb..688f003 100644
--- a/src/calendar.js
+++ b/src/calendar.js
@@ -39,11 +39,10 @@ function calendar (calendarOptions) {
   var time;
   var timelist;
 
-  destroy(true);
+  init();
+  raf(ready);
 
-  raf(function () {
-    init();
-  });
+  return api;
 
   function napi () { return api; }
 
@@ -78,14 +77,20 @@ function calendar (calendarOptions) {
     api.setValue = setValue;
     api.show = show;
 
-    hideCalendar();
-    eventListening();
+    if (o._input !== true) {
+      show();
+    }
 
-    api.emit('ready', clone(o));
+    eventListening();
+    ready();
 
     return api;
   }
 
+  function ready () {
+    api.emit('ready', clone(o));
+  }
+
   function destroy (silent) {
     if (container) {
       container.parentNode.removeChild(container);
@@ -95,6 +100,7 @@ function calendar (calendarOptions) {
       eventListening(true);
     }
 
+    var destroyed = api.emitterSnapshot('destroyed');
     api.destroyed = true;
     api.destroy = napi;
     api.emitValues = napi;
@@ -108,11 +114,11 @@ function calendar (calendarOptions) {
     api.restore = init;
     api.setValue = napi;
     api.show = napi;
+    api.off();
 
     if (silent !== true) {
-      api.emit('destroyed');
+      destroyed();
     }
-    api.off();
 
     return api;
   }
@@ -305,7 +311,7 @@ function calendar (calendarOptions) {
     var bound;
     var direction = op === 'add' ? -1 : 1;
     var offset = o.monthsInCalendar + direction * getMonthOffset(lastDayElement);
-    refCal[op]('months', offset);
+    refCal[op](offset, 'months');
     bound = inRange(refCal.clone());
     ref = bound || ref;
     if (bound) { refCal = bound.clone(); }
@@ -648,8 +654,6 @@ function calendar (calendarOptions) {
   function getMoment () {
     return ref.clone();
   }
-
-  return api;
 }
 
 module.exports = calendar;
diff --git a/src/defaults.js b/src/defaults.js
index d7b3f1f..2117b92 100644
--- a/src/defaults.js
+++ b/src/defaults.js
@@ -66,7 +66,7 @@ function defaults (options, cal) {
     o.weekdayFormat = momentum.moment.weekdaysShort();
   } else if (o.weekdayFormat === 'min') {
     o.weekdayFormat = momentum.moment.weekdaysMin();
-  } else {
+  } else if (!Array.isArray(o.weekdayFormat) || o.weekdayFormat.length < 7) {
     throw new Error('`weekdays` must be `min`, `short`, or `long`');
   }
   if (o.monthsInCalendar === no) { o.monthsInCalendar = 1; }
diff --git a/src/input.js b/src/input.js
index 54f101f..c7d6479 100644
--- a/src/input.js
+++ b/src/input.js
@@ -3,6 +3,7 @@
 var throttle = require('lodash.throttle');
 var raf = require('raf');
 var clone = require('./clone');
+var defaults = require('./defaults');
 var calendar = require('./calendar');
 var momentum = require('./momentum');
 var classes = require('./classes');
@@ -10,16 +11,24 @@ var events = require('./events');
 
 function inputCalendar (input, calendarOptions) {
   var o;
-  var api = calendar(calendarOptions);
+  var api = calendar(asInput(calendarOptions));
   var throttledTakeInput = throttle(takeInput, 50);
   var throttledPosition = throttle(position, 30);
   var ignoreInvalidation;
   var ignoreShow;
 
-  bindEvents();
+  init(calendarOptions);
 
-  function init (superOptions) {
-    o = clone(superOptions);
+  return api;
+
+  function asInput (options) {
+    var o = options || {};
+    o._input = true;
+    return o;
+  }
+
+  function init (initOptions) {
+    o = defaults(asInput(initOptions || calendarOptions), api);
 
     classes.add(api.container, o.styles.positioned);
     events.add(api.container, 'mousedown', containerMouseDown);
@@ -42,12 +51,6 @@ function inputCalendar (input, calendarOptions) {
 
   function destroy () {
     eventListening(true);
-    raf(bindEvents);
-  }
-
-  function bindEvents () {
-    api.once('ready', init);
-    api.once('destroyed', destroy);
   }
 
   function eventListening (remove) {
@@ -61,6 +64,14 @@ function inputCalendar (input, calendarOptions) {
     events[op](input, 'input', throttledTakeInput);
     if (o.invalidate) { events[op](input, 'blur', invalidateInput); }
     events[op](window, 'resize', throttledPosition);
+
+    if (remove) {
+      api.once('ready', init);
+      api.off('destroyed', destroy);
+    } else {
+      api.off('ready', init);
+      api.once('destroyed', destroy);
+    }
   }
 
   function containerClick () {
@@ -120,8 +131,6 @@ function inputCalendar (input, calendarOptions) {
       return isEmpty() ? null : fn.apply(this, arguments);
     };
   }
-
-  return api;
 }
 
 module.exports = inputCalendar;
diff --git a/src/polyfills/array.every.js b/src/polyfills/array.every.js
deleted file mode 100644
index b4426de..0000000
--- a/src/polyfills/array.every.js
+++ /dev/null
@@ -1,33 +0,0 @@
-if (!Array.prototype.every) {
-  Array.prototype.every = function (fn, ctx) {
-    var context, i;
-
-    if (this == null) {
-      throw new TypeError('this is null or not defined');
-    }
-
-    var source = Object(this);
-    var len = source.length >>> 0;
-
-    if (typeof fn !== 'function') {
-      throw new TypeError(fn + ' is not a function');
-    }
-
-    if (arguments.length > 1) {
-      context = ctx;
-    }
-
-    i = 0;
-
-    while (i < len) {
-      if (i in source) {
-        var test = fn.call(context, source[i], i, source);
-        if (!test) {
-          return false;
-        }
-      }
-      i++;
-    }
-    return true;
-  };
-}
diff --git a/src/polyfills/array.filter.js b/src/polyfills/array.filter.js
index c3bd71f..d00065d 100644
--- a/src/polyfills/array.filter.js
+++ b/src/polyfills/array.filter.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Array.prototype.filter) {
   Array.prototype.filter = function (fn, ctx) {
     var f = [];
diff --git a/src/polyfills/array.foreach.js b/src/polyfills/array.foreach.js
index 66af428..d9163d8 100644
--- a/src/polyfills/array.foreach.js
+++ b/src/polyfills/array.foreach.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Array.prototype.forEach) {
   Array.prototype.forEach = function (fn, ctx) {
     if (this === void 0 || this === null || typeof fn !== 'function') {
diff --git a/src/polyfills/array.indexof.js b/src/polyfills/array.indexof.js
index 49d4a7f..5ccec91 100644
--- a/src/polyfills/array.indexof.js
+++ b/src/polyfills/array.indexof.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function (what, start) {
     if (this === undefined || this === null) {
diff --git a/src/polyfills/array.isarray.js b/src/polyfills/array.isarray.js
index 7f7f870..ec9aada 100644
--- a/src/polyfills/array.isarray.js
+++ b/src/polyfills/array.isarray.js
@@ -1,3 +1,5 @@
+'use strict';
+
 Array.isArray || (Array.isArray = function (a) {
   return '' + a !== a && Object.prototype.toString.call(a) === '[object Array]';
 });
diff --git a/src/polyfills/array.map.js b/src/polyfills/array.map.js
index c2dda55..d80c5a5 100644
--- a/src/polyfills/array.map.js
+++ b/src/polyfills/array.map.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Array.prototype.map) {
   Array.prototype.map = function (fn, ctx) {
     var context, result, i;
diff --git a/src/polyfills/array.some.js b/src/polyfills/array.some.js
index ed43eb1..6959e37 100644
--- a/src/polyfills/array.some.js
+++ b/src/polyfills/array.some.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Array.prototype.some) {
   Array.prototype.some = function (fn, ctx) {
     var context, i;
diff --git a/src/polyfills/function.bind.js b/src/polyfills/function.bind.js
index 52866bc..aafb367 100644
--- a/src/polyfills/function.bind.js
+++ b/src/polyfills/function.bind.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!Function.prototype.bind) {
   Function.prototype.bind = function (context) {
     if (typeof this !== 'function') {
diff --git a/src/polyfills/object.keys.js b/src/polyfills/object.keys.js
index 1162766..9feafb4 100644
--- a/src/polyfills/object.keys.js
+++ b/src/polyfills/object.keys.js
@@ -1,40 +1,39 @@
-if (!Object.keys) {
-  Object.keys = (function() {
-    'use strict';
-    var hasOwnProperty = Object.prototype.hasOwnProperty,
-        hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
-        dontEnums = [
-          'toString',
-          'toLocaleString',
-          'valueOf',
-          'hasOwnProperty',
-          'isPrototypeOf',
-          'propertyIsEnumerable',
-          'constructor'
-        ],
-        dontEnumsLength = dontEnums.length;
+'use strict';
 
-    return function(obj) {
-      if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
-        throw new TypeError('Object.keys called on non-object');
-      }
+var hasOwn = Object.prototype.hasOwnProperty;
+var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
+var dontEnums = [
+  'toString',
+  'toLocaleString',
+  'valueOf',
+  'hasOwnProperty',
+  'isPrototypeOf',
+  'propertyIsEnumerable',
+  'constructor'
+];
+var dontEnumsLength = dontEnums.length;
 
-      var result = [], prop, i;
+if (!Object.keys) {
+  Object.keys = function(obj) {
+    if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
+      throw new TypeError('Object.keys called on non-object');
+    }
 
-      for (prop in obj) {
-        if (hasOwnProperty.call(obj, prop)) {
-          result.push(prop);
-        }
+    var result = [], prop, i;
+
+    for (prop in obj) {
+      if (hasOwn.call(obj, prop)) {
+        result.push(prop);
       }
+    }
 
-      if (hasDontEnumBug) {
-        for (i = 0; i < dontEnumsLength; i++) {
-          if (hasOwnProperty.call(obj, dontEnums[i])) {
-            result.push(dontEnums[i]);
-          }
+    if (hasDontEnumBug) {
+      for (i = 0; i < dontEnumsLength; i++) {
+        if (hasOwn.call(obj, dontEnums[i])) {
+          result.push(dontEnums[i]);
         }
       }
-      return result;
-    };
-  }());
-}
\ No newline at end of file
+    }
+    return result;
+  };
+}
diff --git a/src/polyfills/string.trim.js b/src/polyfills/string.trim.js
index 62df229..5687e5b 100644
--- a/src/polyfills/string.trim.js
+++ b/src/polyfills/string.trim.js
@@ -1,3 +1,5 @@
+'use strict';
+
 if (!String.prototype.trim) {
   String.prototype.trim = function () {
     return this.replace(/^\s+|\s+$/g, '');
diff --git a/src/rome.js b/src/rome.js
index 737d174..52dc558 100644
--- a/src/rome.js
+++ b/src/rome.js
@@ -8,7 +8,6 @@ require('./polyfills/array.map');
 require('./polyfills/array.filter');
 require('./polyfills/array.isarray');
 require('./polyfills/array.indexof');
-require('./polyfills/array.every');
 require('./polyfills/array.some');
 require('./polyfills/string.trim');
 require('./polyfills/object.keys');