diff --git a/.gitignore b/.gitignore index 8d4ae25..8c31602 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +.idea bower_components +node_modules \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7ce6dda --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: node_js + +node_js: + - "0.10" + +script: + - npm test diff --git a/README.md b/README.md index e71f10d..588d28d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ -TimezoneJS for AngularJS -======================== +# TimezoneJS for AngularJS [![Build Status](https://secure.travis-ci.org/michaelahlers/angular-timezone-js.png)](http://travis-ci.org/michaelahlers/angular-timezone-js) You need: - -- npm -- bower -TODO ----- +- NPM +- Bower -- Angular Date detection prevents using date filter for TimezoneJS instances – now using patched version of Angular +## Developers + +_TimezoneJS for Angular_ is tested with [Karma](http://karma-runner.github.io/) and [PhantomJS](http://phantomjs.org/) against the latest available release of [jQuery](http://jquery.com/) (1.9.1) and [AngularJS](http://angularjs.com/) (1.1.4). + +``` +$ npm install --dev +$ npm test +``` diff --git a/index.html b/index.html index 7aa0ff4..4cfb99a 100644 --- a/index.html +++ b/index.html @@ -12,6 +12,6 @@

Angular.js TimezoneJS demo

-

Hey folks! Today is {{ today | tzDate:timezone | date:"yyyy-MM-dd" }}

+

Hey folks! Today is {{ today | tzDate:timezone | date:"yyyy-MM-dd HH:mm:ss Z" }}

diff --git a/js/bower.json b/js/bower.json index e1747cc..d389fa7 100644 --- a/js/bower.json +++ b/js/bower.json @@ -4,6 +4,7 @@ "dependencies": { "angular": "latest", "jquery": "latest", - "angular-filters": "latest" + "angular-filters": "latest", + "timezone-js": "git@github.com:mde/timezone-js.git" } } \ No newline at end of file diff --git a/js/timezone.js b/js/timezone.js index 444bb83..88ff4eb 100644 --- a/js/timezone.js +++ b/js/timezone.js @@ -1,10 +1,28 @@ +(function(){ + +var toExtendedNative = function (wrapped) { + /* Tricks the isDate method in Angular into treating these objects like it + * would any other Date. May be horribly slow. */ + var native = new Date() + for (key in wrapped) { + native[key] = wrapped[key] + } + return native +} + var timezonejs = angular.module('timezonejs', []); -timezonejs.factory('Timezone', function() { +timezonejs.factory('Timezone', function($injector) { var _tz = timezoneJS.timezone; _tz.loadingScheme = _tz.loadingSchemes.MANUAL_LOAD; // TODO: load with ang? - _tz.loadZoneJSONData('js/lib/timezones.json', true); + + try { + _tz.loadZoneJSONData($injector.get('timezonesURL'), true); + } catch (e) { + _tz.loadZoneJSONData('js/lib/timezones.json', true); + } + timezoneJS.fromLocalString = function(str, tz) { // https://github.com/csnover/js-iso8601/blob/master/iso8601.js – MIT license @@ -20,7 +38,7 @@ timezonejs.factory('Timezone', function() { struct[2] = (+struct[2] || 1) - 1; struct[3] = +struct[3] || 1; - return new timezoneJS.Date(struct[1], struct[2], struct[3], struct[4], struct[5], struct[6], struct[7], tz); + return toExtendedNative(new timezoneJS.Date(struct[1], struct[2], struct[3], struct[4], struct[5], struct[6], struct[7], tz)); }; return timezoneJS; }); @@ -28,6 +46,8 @@ timezonejs.factory('Timezone', function() { timezonejs.filter('tzDate', function(Timezone) { return function(dt, tz) { console.log('ar', arguments); - return new Timezone.Date(dt, tz); + return toExtendedNative(new Timezone.Date(dt, tz)); }; }); + +})(angular) \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..8c2b24e --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name" : "angular-timezone-js", + "description" : "TimezoneJS for AngularJS", + "version" : "0.1.0", + "homepage" : "https://github.com/LeZuse/angular-timezone-js", + "author" : "Tomas Ruzicka ", + + "repository" : { + "type" : "git", + "url" : "git@github.com:LeZuse/angular-timezone-js.git" + }, + + "engines" : { + "node" : ">= 0.8" + }, + + "dependencies" : {}, + + "devDependencies" : { + "karma" : "0.8.x", + "phantomjs" : "1.9.x" + }, + + "scripts" : { + "test" : "karma start test/karma.conf.js" + }, + + "contributors" : [ + { + "name" : "Michael Ahlers", + "email" : "michael@ahlers.co" + } + ] +} \ No newline at end of file diff --git a/test/directives/tzDateSpec.js b/test/directives/tzDateSpec.js new file mode 100644 index 0000000..085ee4e --- /dev/null +++ b/test/directives/tzDateSpec.js @@ -0,0 +1,92 @@ +'use strict' + +describe('tzDate', function () { + var scope, $filter, $compile, $timeout, $sandbox + + beforeEach(module('timezonejs', function ($provide) { + $provide.value('timezonesURL', 'base/js/lib/timezones.json') + })) + + beforeEach(inject(function ($injector, $rootScope, _$filter_, _$compile_, _$timeout_) { + scope = $rootScope + $filter = _$filter_ + $compile = _$compile_ + $timeout = _$timeout_ + + $sandbox = $('
').appendTo($('body')) + })) + + var compile = function (scenario) { + angular.extend(scope, scenario.scope) + + var $element = $(scenario.markup).appendTo($sandbox) + + $element = $compile($element)(scope) + scope.$digest() + + return $element + } + + afterEach(function () { + $sandbox.remove() + scope.$destroy() + }) + + var scenarios = [ + { + scope : { + reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')), + timezone : 'America/New_York' + }, + markup : '{{reference|tzDate:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}', + expected : { + fullYear : 1969, + month : 11, + date : 31, + hours : 20, + text : '1969-12-31 20:00:00 -0400' + } + }, + { + scope : { + reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')), + timezone : 'America/Los_Angeles' + }, + markup : '{{reference|tzDate:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}', + expected : { + fullYear : 1969, + month : 11, + date : 31, + hours : 17, + text : '1969-12-31 17:00:00 -0700' + } + } + ] + + it('should align dates to expected timezones', function () { + scenarios.forEach(function (scenario) { + var timezone = scenario.scope.timezone + , reference = scenario.scope.reference + , expected = scenario.expected + + var aligned = $filter('tzDate')(reference, timezone) + + expect(aligned.getTimezone()).toEqual(timezone) + + expect(aligned.getFullYear()).toEqual(expected.fullYear) + expect(aligned.getMonth()).toEqual(expected.month) + expect(aligned.getDate()).toEqual(expected.date) + expect(aligned.getHours()).toEqual(expected.hours) + }) + }) + + it('should support formatting dates to expected timezones', function () { + scenarios.forEach(function (scenario) { + var expected = scenario.expected + , el = compile(scenario) + + expect(el.text()).toEqual(expected.text) + }) + }) + +}) \ No newline at end of file diff --git a/test/karma.conf.js b/test/karma.conf.js new file mode 100644 index 0000000..6143c5b --- /dev/null +++ b/test/karma.conf.js @@ -0,0 +1,71 @@ +/** + * Testacular configuration. Visit https://github.com/vojtajina/testacular/blob/stable/lib/config.js#L54 + * for all available config options and defaults. + */ + +/* Base path, that will be used to resolve files and exclude. */ +basePath = './..' + +/* Files and patterns to load in the browser. */ +files = [ + JASMINE, + JASMINE_ADAPTER, + + 'http://code.jquery.com/jquery-1.9.1.js', + 'http://code.angularjs.org/1.1.4/angular.js', + 'http://code.angularjs.org/1.1.4/angular-mocks.js', + 'https://raw.github.com/mde/timezone-js/master/src/date.js', + + { pattern : 'js/lib/timezones.json', included : false }, + 'js/timezone.js', + + 'test/directives/*Spec.js' +] + +/* Files to exclude. */ +exclude = [] + +/* CLI progress reporters. Use dots, Travis terminal does not support escaping + * sequences. Legal values: 'dots', 'progress', 'junit'. */ +reporters = ['progress'] + +/* web server port */ +// --port 9876 +port = 9876 + +/* CLI runner port. */ +// --runner-port 9100 +runnerPort = 9100 + +/* Enable colors in the output (reporters and logs). */ +// --colors +// --no-colors +colors = true + +/* Logging level. Possible values: LOG_DISABLE, LOG_ERROR, LOG_WARN, LOG_INFO, + * LOG_DEBUG. */ +// --log-level debug +logLevel = LOG_INFO + +/* Enable watching file and executing tests whenever any file changes. */ +// --auto-watch +// --no-auto-watch +autoWatch = true + +/* Testing environment. Options are (as available) Chrome, ChromeCanary, + * Firefox, Opera, Safari, PhantomJS, and IE. */ +// --browsers Chrome,Firefox,Safari +browsers = ['PhantomJS'] + +/* Timeout (in milliseconds) for browser capture. */ +// --capture-timeout 5000 +captureTimeout = 5000 + +/* Run tests on start (when browsers are captured) and exit. */ +// --single-run +// --no-single-run +singleRun = true + +/* Report which specs are take longer than 500 ms to complete. */ +// --report-slower-than 500 +reportSlowerThan = 500