From becc864c20d30bfdaaf19cbd492b4f3e0a5d0d01 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sat, 1 Feb 2014 22:43:53 -0700 Subject: [PATCH 01/14] initial ui-i18n commit --- modules/i18n/ui-i18n.js | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 modules/i18n/ui-i18n.js diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js new file mode 100644 index 00000000..b5fca562 --- /dev/null +++ b/modules/i18n/ui-i18n.js @@ -0,0 +1,93 @@ +/** + * Created by Tim on 2/1/14. + */ +(function(){ + 'use strict'; + var MISSING = "[MISSING]: "; + var uiI18n = angular.module('ui.i18n', []); + uiI18n.value('uiI18n.packs', { + i18n: {}, + lang: null + }); + var getPack = function(){ + return angular.injector(['ng','ui.i18n']).get('uiI18n.packs'); + }; + uiI18n.i18n = { + add: function(langs, strings){ + var packs = getPack(); + if (typeof(langs) === "object"){ + angular.forEach(langs, function(lang){ + if (lang){ + var lower = lang.toLowerCase(); + var combined = angular.extend(packs.i18n[lang] || {}, strings); + packs.i18n[lower] = combined; + } + }); + } else { + var lower = langs.toLowerCase(); + var combined = angular.extend(packs.i18n[langs] || {}, strings); + packs.i18n[lower] = combined; + } + uiI18n.value('uiI18n.packs', packs); + }, + set: function(lang){ + if (lang){ + var pack = getPack(); + pack.lang = lang; + uiI18n.value('uiI18n.packs', pack); + } + } + }; + + uiI18n.directive('uiI18n',['uiI18n.packs', function(packs) { + return { + link: function($scope, $elm, $attrs) { + // check for watchable property + var lang = $scope.$eval($attrs.uiI18n); + if (lang){ + $scope.$watch($attrs.uiI18n, function(newLang){ + uiI18n.i18n.set(newLang); + $scope.$broadcast("$uiI18n", newLang); + }); + } else { + // fall back to the string value + lang = $attrs.uiI18n; + } + uiI18n.i18n.set(lang); + } + }; + }]); + + var uitDirective = function($parse, packs) { + return { + restrict: 'EA', + compile: function(){ + return function($scope, $elm, $attrs) { + var token = $attrs.uiT || $attrs.uiTranslate || $elm.html(); + var getter = $parse(token); + var missing = MISSING + token; + + var listener = $scope.$on("$uiI18n", function(evt, lang){ + // set text based on i18n current language + $elm.html(getter(packs.i18n[lang]) || missing); + }); + $scope.$on('$destroy', listener); + }; + } + }; + }; + // directive syntax + uiI18n.directive('uiT',['$parse', 'uiI18n.packs', uitDirective]); + uiI18n.directive('uiTranslate',['$parse', 'uiI18n.packs', uitDirective]); + + var uitFilter = function($parse, packs) { + return function(data) { + var getter = $parse(data); + // set text based on i18n current language + return getter(packs.i18n[packs.lang]) || MISSING + data; + }; + }; + // optional syntax + uiI18n.filter('t', ['$parse', 'uiI18n.packs', uitFilter]); + uiI18n.filter('translate', ['$parse', 'uiI18n.packs', uitFilter]); +})(); \ No newline at end of file From 4c7a7247221e98c15707a3fd6b5e6414fe1a5fed Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sat, 1 Feb 2014 23:17:01 -0700 Subject: [PATCH 02/14] tidy up --- modules/i18n/ui-i18n.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index b5fca562..def88097 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -3,7 +3,7 @@ */ (function(){ 'use strict'; - var MISSING = "[MISSING]: "; + var MISSING = '[MISSING]: '; var uiI18n = angular.module('ui.i18n', []); uiI18n.value('uiI18n.packs', { i18n: {}, @@ -15,7 +15,7 @@ uiI18n.i18n = { add: function(langs, strings){ var packs = getPack(); - if (typeof(langs) === "object"){ + if (typeof(langs) === 'object'){ angular.forEach(langs, function(lang){ if (lang){ var lower = lang.toLowerCase(); @@ -39,7 +39,7 @@ } }; - uiI18n.directive('uiI18n',['uiI18n.packs', function(packs) { + uiI18n.directive('uiI18n',function() { return { link: function($scope, $elm, $attrs) { // check for watchable property @@ -47,7 +47,7 @@ if (lang){ $scope.$watch($attrs.uiI18n, function(newLang){ uiI18n.i18n.set(newLang); - $scope.$broadcast("$uiI18n", newLang); + $scope.$broadcast('$uiI18n', newLang); }); } else { // fall back to the string value @@ -56,7 +56,7 @@ uiI18n.i18n.set(lang); } }; - }]); + }); var uitDirective = function($parse, packs) { return { @@ -67,7 +67,7 @@ var getter = $parse(token); var missing = MISSING + token; - var listener = $scope.$on("$uiI18n", function(evt, lang){ + var listener = $scope.$on('$uiI18n', function(evt, lang){ // set text based on i18n current language $elm.html(getter(packs.i18n[lang]) || missing); }); From 774016e0e05a847cc0179797fb17096dc205cd67 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sun, 2 Feb 2014 00:31:18 -0700 Subject: [PATCH 03/14] fixing bug with set(language) --- modules/i18n/ui-i18n.js | 46 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index def88097..cb0fbc97 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -5,36 +5,40 @@ 'use strict'; var MISSING = '[MISSING]: '; var uiI18n = angular.module('ui.i18n', []); - uiI18n.value('uiI18n.packs', { + + uiI18n.value('uiI18n.pack', { i18n: {}, lang: null }); + var injector = angular.injector(['ng','ui.i18n']); var getPack = function(){ - return angular.injector(['ng','ui.i18n']).get('uiI18n.packs'); + return injector.get('uiI18n.pack'); }; + var $root; uiI18n.i18n = { add: function(langs, strings){ - var packs = getPack(); + var pack = getPack(); if (typeof(langs) === 'object'){ angular.forEach(langs, function(lang){ if (lang){ var lower = lang.toLowerCase(); - var combined = angular.extend(packs.i18n[lang] || {}, strings); - packs.i18n[lower] = combined; + var combined = angular.extend(pack.i18n[lang] || {}, strings); + pack.i18n[lower] = combined; } }); } else { var lower = langs.toLowerCase(); - var combined = angular.extend(packs.i18n[langs] || {}, strings); - packs.i18n[lower] = combined; + var combined = angular.extend(pack.i18n[langs] || {}, strings); + pack.i18n[lower] = combined; } - uiI18n.value('uiI18n.packs', packs); + uiI18n.value('uiI18n.pack', pack); }, set: function(lang){ if (lang){ var pack = getPack(); pack.lang = lang; - uiI18n.value('uiI18n.packs', pack); + uiI18n.value('uiI18n.pack', pack); + if ($root) $root.$broadcast('$uiI18n', lang); } } }; @@ -45,10 +49,7 @@ // check for watchable property var lang = $scope.$eval($attrs.uiI18n); if (lang){ - $scope.$watch($attrs.uiI18n, function(newLang){ - uiI18n.i18n.set(newLang); - $scope.$broadcast('$uiI18n', newLang); - }); + $scope.$watch($attrs.uiI18n, uiI18n.i18n.set); } else { // fall back to the string value lang = $attrs.uiI18n; @@ -58,18 +59,21 @@ }; }); - var uitDirective = function($parse, packs) { + var uitDirective = function($parse, pack) { return { restrict: 'EA', compile: function(){ return function($scope, $elm, $attrs) { + // this is such a hack! I tried injector invoke $rootScope but its not the right one! + // TODO: make this not stupid... + if (!$root) $root = $scope.$root; var token = $attrs.uiT || $attrs.uiTranslate || $elm.html(); var getter = $parse(token); var missing = MISSING + token; var listener = $scope.$on('$uiI18n', function(evt, lang){ // set text based on i18n current language - $elm.html(getter(packs.i18n[lang]) || missing); + $elm.html(getter(pack.i18n[lang]) || missing); }); $scope.$on('$destroy', listener); }; @@ -77,17 +81,17 @@ }; }; // directive syntax - uiI18n.directive('uiT',['$parse', 'uiI18n.packs', uitDirective]); - uiI18n.directive('uiTranslate',['$parse', 'uiI18n.packs', uitDirective]); + uiI18n.directive('uiT',['$parse', 'uiI18n.pack', uitDirective]); + uiI18n.directive('uiTranslate',['$parse', 'uiI18n.pack', uitDirective]); - var uitFilter = function($parse, packs) { + var uitFilter = function($parse, pack) { return function(data) { var getter = $parse(data); // set text based on i18n current language - return getter(packs.i18n[packs.lang]) || MISSING + data; + return getter(pack.i18n[pack.lang]) || MISSING + data; }; }; // optional syntax - uiI18n.filter('t', ['$parse', 'uiI18n.packs', uitFilter]); - uiI18n.filter('translate', ['$parse', 'uiI18n.packs', uitFilter]); + uiI18n.filter('t', ['$parse', 'uiI18n.pack', uitFilter]); + uiI18n.filter('translate', ['$parse', 'uiI18n.pack', uitFilter]); })(); \ No newline at end of file From 51cd834625a020e23cf3b2a169c33d586125257a Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sun, 2 Feb 2014 13:52:06 -0700 Subject: [PATCH 04/14] simplify usage, bundle deepcopy --- modules/i18n/ui-i18n.js | 116 +++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index cb0fbc97..743ef899 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -2,96 +2,116 @@ * Created by Tim on 2/1/14. */ (function(){ + + // adding deep copy method until angularjs supports deep copy like everyone else. + // https://github.com/angular/angular.js/pull/5059 + function deepExtend(destination, source) { + for (var property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + arguments.callee(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; + } 'use strict'; var MISSING = '[MISSING]: '; var uiI18n = angular.module('ui.i18n', []); - uiI18n.value('uiI18n.pack', { - i18n: {}, - lang: null - }); - var injector = angular.injector(['ng','ui.i18n']); - var getPack = function(){ - return injector.get('uiI18n.pack'); + var langCache = { + _langs: {}, + current: null }; - var $root; - uiI18n.i18n = { - add: function(langs, strings){ - var pack = getPack(); - if (typeof(langs) === 'object'){ - angular.forEach(langs, function(lang){ - if (lang){ - var lower = lang.toLowerCase(); - var combined = angular.extend(pack.i18n[lang] || {}, strings); - pack.i18n[lower] = combined; - } - }); - } else { - var lower = langs.toLowerCase(); - var combined = angular.extend(pack.i18n[langs] || {}, strings); - pack.i18n[lower] = combined; - } - uiI18n.value('uiI18n.pack', pack); - }, - set: function(lang){ - if (lang){ - var pack = getPack(); - pack.lang = lang; - uiI18n.value('uiI18n.pack', pack); - if ($root) $root.$broadcast('$uiI18n', lang); - } + langCache.get = function(lang){ + return langCache._langs[lang.toLowerCase()]; + }; + langCache.add = function(lang, strings){ + var lower = lang.toLowerCase(); + var cache = langCache._langs; + cache[lower] = deepExtend(cache[lower] || {}, strings); + }; + langCache.setCurrent = function(lang){ + langCache.current = lang.toLowerCase(); + }; + langCache.getCurrent = function(){ + return langCache.get(langCache.current); + }; + + uiI18n._cache = langCache; + uiI18n.$broadcast = function(lang){ + if (lang && this.$root){ + uiI18n.$root.$broadcast('$uiI18n', lang); + } + }; + uiI18n.add = function(langs, strings){ + if (typeof(langs) === 'object'){ + angular.forEach(langs, function(lang){ + if (lang){ + langCache.add(lang, strings); + } + }); + } else { + langCache.add(langs, strings); + } + }; + uiI18n.set = function(lang){ + if (lang){ + langCache.setCurrent(lang); + uiI18n.$broadcast(lang); } }; uiI18n.directive('uiI18n',function() { return { link: function($scope, $elm, $attrs) { + if (!uiI18n.$root) uiI18n.$root = $scope.$root; // check for watchable property var lang = $scope.$eval($attrs.uiI18n); if (lang){ - $scope.$watch($attrs.uiI18n, uiI18n.i18n.set); + $scope.$watch($attrs.uiI18n, uiI18n.set); } else { // fall back to the string value lang = $attrs.uiI18n; } - uiI18n.i18n.set(lang); + uiI18n.set(lang); } }; }); - var uitDirective = function($parse, pack) { + // directive syntax + var uitDirective = function($parse) { return { restrict: 'EA', compile: function(){ return function($scope, $elm, $attrs) { - // this is such a hack! I tried injector invoke $rootScope but its not the right one! - // TODO: make this not stupid... - if (!$root) $root = $scope.$root; + if (!uiI18n.$root) uiI18n.$root = $scope.$root; var token = $attrs.uiT || $attrs.uiTranslate || $elm.html(); var getter = $parse(token); var missing = MISSING + token; var listener = $scope.$on('$uiI18n', function(evt, lang){ // set text based on i18n current language - $elm.html(getter(pack.i18n[lang]) || missing); + $elm.html(getter(langCache.get(lang)) || missing); }); $scope.$on('$destroy', listener); }; } }; }; - // directive syntax - uiI18n.directive('uiT',['$parse', 'uiI18n.pack', uitDirective]); - uiI18n.directive('uiTranslate',['$parse', 'uiI18n.pack', uitDirective]); + uiI18n.directive('uiT',['$parse', uitDirective]); + uiI18n.directive('uiTranslate',['$parse', uitDirective]); - var uitFilter = function($parse, pack) { + // optional filter syntax + var uitFilter = function($parse) { return function(data) { var getter = $parse(data); // set text based on i18n current language - return getter(pack.i18n[pack.lang]) || MISSING + data; + return getter(langCache.getCurrent()) || MISSING + data; }; }; - // optional syntax - uiI18n.filter('t', ['$parse', 'uiI18n.pack', uitFilter]); - uiI18n.filter('translate', ['$parse', 'uiI18n.pack', uitFilter]); + uiI18n.filter('t', ['$parse', uitFilter]); + uiI18n.filter('translate', ['$parse', uitFilter]); })(); \ No newline at end of file From fedbcbbb58ccbc49515a54e6cbacf4ee6e56502e Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sun, 2 Feb 2014 13:59:19 -0700 Subject: [PATCH 05/14] jshint! --- modules/i18n/ui-i18n.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 743ef899..3b35033a 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -2,7 +2,7 @@ * Created by Tim on 2/1/14. */ (function(){ - + 'use strict' // adding deep copy method until angularjs supports deep copy like everyone else. // https://github.com/angular/angular.js/pull/5059 function deepExtend(destination, source) { @@ -10,7 +10,7 @@ if (source[property] && source[property].constructor && source[property].constructor === Object) { destination[property] = destination[property] || {}; - arguments.callee(destination[property], source[property]); + arguments.callee(destination[property], source[property]); // jshint ignore:line } else { destination[property] = source[property]; } From 8a505932a4dcb88e9fc2d4cd427acac7208f6f89 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sun, 2 Feb 2014 14:03:55 -0700 Subject: [PATCH 06/14] ok... try again? --- modules/i18n/ui-i18n.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 3b35033a..dcb880e9 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -2,7 +2,7 @@ * Created by Tim on 2/1/14. */ (function(){ - 'use strict' + 'use strict'; // adding deep copy method until angularjs supports deep copy like everyone else. // https://github.com/angular/angular.js/pull/5059 function deepExtend(destination, source) { @@ -10,7 +10,9 @@ if (source[property] && source[property].constructor && source[property].constructor === Object) { destination[property] = destination[property] || {}; - arguments.callee(destination[property], source[property]); // jshint ignore:line + /* jshint ignore:start */ + arguments.callee(destination[property], source[property]); + /* jshint ignore:end */ } else { destination[property] = source[property]; } From 8327d7068642a62c53eac7561c3bfcb525b102b9 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Mon, 3 Feb 2014 10:07:58 -0700 Subject: [PATCH 07/14] forgot to check in observable support last night --- modules/i18n/ui-i18n.js | 141 ++++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 55 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index dcb880e9..dbfa740b 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -1,32 +1,23 @@ /** - * Created by Tim on 2/1/14. + * ui-i18n Created by Tim Sweet on 2/1/14. + * https://github.com/timothyswt + * MIT License */ -(function(){ +(function(deepExtend){ 'use strict'; - // adding deep copy method until angularjs supports deep copy like everyone else. - // https://github.com/angular/angular.js/pull/5059 - function deepExtend(destination, source) { - for (var property in source) { - if (source[property] && source[property].constructor && - source[property].constructor === Object) { - destination[property] = destination[property] || {}; - /* jshint ignore:start */ - arguments.callee(destination[property], source[property]); - /* jshint ignore:end */ - } else { - destination[property] = source[property]; - } - } - return destination; - } - 'use strict'; - var MISSING = '[MISSING]: '; - var uiI18n = angular.module('ui.i18n', []); + var MISSING = '[MISSING]: ', + UPDATE_EVENT = '$uiI18n', + FILTER_ALIASES = ['t', 'translate'], + DIRECTIVE_ALIASES = ['uiT', 'uiTranslate'], + LOCALE_DIRECTIVE_ALIAS = 'uiI18n', + // default to english + DEFAULT_LANG = 'en-US', + langCache = { + _langs: {}, + current: null + }, + uiI18n = angular.module('ui.i18n', []); - var langCache = { - _langs: {}, - current: null - }; langCache.get = function(lang){ return langCache._langs[lang.toLowerCase()]; }; @@ -45,7 +36,7 @@ uiI18n._cache = langCache; uiI18n.$broadcast = function(lang){ if (lang && this.$root){ - uiI18n.$root.$broadcast('$uiI18n', lang); + uiI18n.$root.$broadcast(UPDATE_EVENT, lang); } }; uiI18n.add = function(langs, strings){ @@ -66,45 +57,67 @@ } }; - uiI18n.directive('uiI18n',function() { + var localeDirective = function() { return { - link: function($scope, $elm, $attrs) { - if (!uiI18n.$root) uiI18n.$root = $scope.$root; - // check for watchable property - var lang = $scope.$eval($attrs.uiI18n); - if (lang){ - $scope.$watch($attrs.uiI18n, uiI18n.set); - } else { - // fall back to the string value - lang = $attrs.uiI18n; + compile: function(){ + return { + pre: function($scope, $elm, $attrs) { + var alias = LOCALE_DIRECTIVE_ALIAS; + if (!uiI18n.$root) uiI18n.$root = $scope.$root; + // check for watchable property + var lang = $scope.$eval($attrs[alias]); + if (lang){ + $scope.$watch($attrs[alias], uiI18n.set); + } else if ($attrs.$$observers){ + $scope.$on('$destroy', $attrs.$observe(alias, uiI18n.set)); + } else { + // fall back to the string value + lang = $attrs[alias]; + } + uiI18n.set(lang || DEFAULT_LANG); + } } - uiI18n.set(lang); } }; - }); + }; + uiI18n.directive(LOCALE_DIRECTIVE_ALIAS, localeDirective); // directive syntax var uitDirective = function($parse) { return { restrict: 'EA', compile: function(){ - return function($scope, $elm, $attrs) { - if (!uiI18n.$root) uiI18n.$root = $scope.$root; - var token = $attrs.uiT || $attrs.uiTranslate || $elm.html(); - var getter = $parse(token); - var missing = MISSING + token; - - var listener = $scope.$on('$uiI18n', function(evt, lang){ - // set text based on i18n current language - $elm.html(getter(langCache.get(lang)) || missing); - }); - $scope.$on('$destroy', listener); - }; + return { + pre: function($scope, $elm, $attrs) { + if (!uiI18n.$root) uiI18n.$root = $scope.$root; + var alias1 = DIRECTIVE_ALIASES[0], + alias2 = DIRECTIVE_ALIASES[1]; + var token = $attrs[alias1] || $attrs[alias2] || $elm.html(); + var missing = MISSING + token; + var observer; + if ($attrs.$$observers){ + var prop = $attrs[alias1] ? alias1 : alias2; + observer = $attrs.$observe(prop, function(result){ + if (result){ + $elm.html($parse(result)(langCache.getCurrent()) || missing); + } + }); + } + var getter = $parse(token); + var listener = $scope.$on(UPDATE_EVENT, function(evt, lang){ + if (observer){ + observer($attrs[alias1] || $attrs[alias2]); + } else { + // set text based on i18n current language + $elm.html(getter(langCache.get(lang)) || missing); + } + }); + $scope.$on('$destroy', listener); + } + } } }; }; - uiI18n.directive('uiT',['$parse', uitDirective]); - uiI18n.directive('uiTranslate',['$parse', uitDirective]); // optional filter syntax var uitFilter = function($parse) { @@ -114,6 +127,24 @@ return getter(langCache.getCurrent()) || MISSING + data; }; }; - uiI18n.filter('t', ['$parse', uitFilter]); - uiI18n.filter('translate', ['$parse', uitFilter]); -})(); \ No newline at end of file + + angular.forEach(DIRECTIVE_ALIASES, function(alias){ + uiI18n.directive(alias,['$parse', uitDirective]); + }); + angular.forEach(FILTER_ALIASES, function(alias){ + uiI18n.filter(alias,['$parse', uitFilter]); + }); +})(function(destination, source) { + // adding deep copy method until angularjs supports deep copy like everyone else. + // https://github.com/angular/angular.js/pull/5059 + for (var property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + arguments.callee(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; +}); \ No newline at end of file From 5afde4d3b8a8ff4c98f56fa0998cc28220ff5b93 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Mon, 3 Feb 2014 10:21:18 -0700 Subject: [PATCH 08/14] jshint you dirty dog... --- modules/i18n/ui-i18n.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index dbfa740b..eace0109 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -76,7 +76,7 @@ } uiI18n.set(lang || DEFAULT_LANG); } - } + }; } }; }; @@ -114,7 +114,7 @@ }); $scope.$on('$destroy', listener); } - } + }; } }; }; @@ -135,6 +135,7 @@ uiI18n.filter(alias,['$parse', uitFilter]); }); })(function(destination, source) { + 'user strict'; // adding deep copy method until angularjs supports deep copy like everyone else. // https://github.com/angular/angular.js/pull/5059 for (var property in source) { From 5b06d04ad030946f0deff4c40bbc927be04e54cf Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Mon, 3 Feb 2014 21:12:28 -0700 Subject: [PATCH 09/14] getting rid of callee --- modules/i18n/ui-i18n.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index eace0109..02dc07c7 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -63,7 +63,9 @@ return { pre: function($scope, $elm, $attrs) { var alias = LOCALE_DIRECTIVE_ALIAS; - if (!uiI18n.$root) uiI18n.$root = $scope.$root; + if (!uiI18n.$root){ + uiI18n.$root = $scope.$root; + } // check for watchable property var lang = $scope.$eval($attrs[alias]); if (lang){ @@ -89,7 +91,9 @@ compile: function(){ return { pre: function($scope, $elm, $attrs) { - if (!uiI18n.$root) uiI18n.$root = $scope.$root; + if (!uiI18n.$root){ + uiI18n.$root = $scope.$root; + } var alias1 = DIRECTIVE_ALIASES[0], alias2 = DIRECTIVE_ALIASES[1]; var token = $attrs[alias1] || $attrs[alias2] || $elm.html(); @@ -134,7 +138,7 @@ angular.forEach(FILTER_ALIASES, function(alias){ uiI18n.filter(alias,['$parse', uitFilter]); }); -})(function(destination, source) { +})(function deepExtend(destination, source) { 'user strict'; // adding deep copy method until angularjs supports deep copy like everyone else. // https://github.com/angular/angular.js/pull/5059 @@ -142,7 +146,7 @@ if (source[property] && source[property].constructor && source[property].constructor === Object) { destination[property] = destination[property] || {}; - arguments.callee(destination[property], source[property]); + deepExtend(destination[property], source[property]); } else { destination[property] = source[property]; } From 5291087049ce1730e80d619692c791ff259cd881 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Mon, 3 Feb 2014 21:16:33 -0700 Subject: [PATCH 10/14] user error, please replace user. --- modules/i18n/ui-i18n.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 02dc07c7..17f0facb 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -139,7 +139,7 @@ uiI18n.filter(alias,['$parse', uitFilter]); }); })(function deepExtend(destination, source) { - 'user strict'; + 'use strict'; // adding deep copy method until angularjs supports deep copy like everyone else. // https://github.com/angular/angular.js/pull/5059 for (var property in source) { @@ -152,4 +152,4 @@ } } return destination; -}); \ No newline at end of file +}); From c56034422e1bfa0f490b678fdfdee82208cda394 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Mon, 3 Feb 2014 22:00:27 -0700 Subject: [PATCH 11/14] adding docs and trying to write a test --- modules/i18n/test/i18nSpec.js | 39 +++++++++++ modules/i18n/ui-i18n.js | 120 +++++++++++++++++++++++++++++++++- 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 modules/i18n/test/i18nSpec.js diff --git a/modules/i18n/test/i18nSpec.js b/modules/i18n/test/i18nSpec.js new file mode 100644 index 00000000..dfd55679 --- /dev/null +++ b/modules/i18n/test/i18nSpec.js @@ -0,0 +1,39 @@ +/*describe('i18n', function() { + 'use strict'; + var uiI18n, element; + beforeEach(function(){ + uiI18n = angular.module('ui.i18n'); + uiI18n.add(['en', 'en-us'],{ + groupPanel:{ + testingMerge: 'some text', + otherText: 'some other group property text', + description:'Drag a column header here and drop it to group by that column.' + }, + example: 'I speak English', + anotherExample: 'I speak A Different Language' + }); + uiI18n.add('de',{ + groupPanel:{ + otherText: 'eine andere gruppe eigenschaft text', + description:'Ziehen Sie eine Spaltenuberschrift hierhin um nach dieser Spalte zu gruppieren.' + }, + example: 'Ich spreche Deutsch' + }); + uiI18n.add('de',{ + groupPanel:{ + testingMerge: 'falaffels are spelled horribly...', + }, + anotherExample: 'I speak A Different Language' + }); + uiI18n.set('en-us'); + }); + + it('should translate', function () { + inject(function ($rootScope, $compile) { + element = $compile('

')($rootScope); + console.log(element); + expect(element.html()).toBe('some other group property text'); + }); + }); +}); +*/ \ No newline at end of file diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 17f0facb..19fa3d48 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -3,6 +3,25 @@ * https://github.com/timothyswt * MIT License */ + /** + * @ngdoc directive + * @name ui-i18n + * @requires $parse + * + * @description + * Allows you to localize your project by being able to specify a language on any root-ish element + * this can be a bindable property or the string. + * if bound it will automatically update all children when update. + * @example + + + + + + + + */ + (function(deepExtend){ 'use strict'; var MISSING = '[MISSING]: ', @@ -83,7 +102,106 @@ }; }; uiI18n.directive(LOCALE_DIRECTIVE_ALIAS, localeDirective); +/** + * * @ngdoc directive + * @name ui-t,ui-Translate + * @requires $parse + * + * @description + * specify the i18n string to use + * this can be a bindable property, expression/partial expression, or the object token. + * @example + + +
+
+ + +
+ +

+ +

groupPanel.testingMerge

+ +

example

+ +

+ +

invalid.path

+ +

invalid.translation.again

+ + +

Using element:

+ example +
+ groupPanel.description +
+ invalid.path +
+ invalid.translation.again + +

Using Translate Filters:

+ +

{{"groupPanel.description" | t}}

+ +

{{"example" | t}}

+

{{"invalid.path" | t}}

+ +

{{"invalid.translation.again" | translate}}

+
+
+ + var app = angular.module('app', ['ui.i18n']); + + app.controller('main', ['$scope', function($scope){ + $scope.language = "en"; + $scope.hello = "ui-i18n Example"; + $scope.desc = "description"; + $scope.changeLanguage = function(){ + $scope.language = $scope.language == "de" ? "en" : "de"; + }; + $scope.changeDesc = function(){ + $scope.desc = $scope.desc == "description" ? "otherText" : "description"; + }; + }]); + //Declare your i18n strings, this is enclosed in order to show that this can be done anywhere in the application + (function(){ + var uiI18n = angular.module('ui.i18n'); + uiI18n.add(["en", "en-us"],{ + groupPanel:{ + testingMerge: 'some text', + otherText: 'some other group property text', + description:'Drag a column header here and drop it to group by that column.' + }, + example: "I speak English", + anotherExample: "I speak A Different Language" + }); + })(); + + (function(){ + var uiI18n = angular.module('ui.i18n'); + uiI18n.add("de",{ + groupPanel:{ + otherText: 'eine andere gruppe eigenschaft text', + description:'Ziehen Sie eine Spaltenüberschrift hierhin um nach dieser Spalte zu gruppieren.' + }, + example: "Ich spreche Deutsch" + }); + })(); + (function(){ + var uiI18n = angular.module('ui.i18n'); + uiI18n.add("de",{ + groupPanel:{ + testingMerge: 'falaffels are spelled horribly...', + }, + anotherExample: "I speak A Different Language" + }); + })(); + +
+ **/ // directive syntax var uitDirective = function($parse) { return { @@ -152,4 +270,4 @@ } } return destination; -}); +}); \ No newline at end of file From 3675e70ac51e5b47d6adfc83a9d34022693ebff3 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sat, 8 Mar 2014 15:22:58 -0700 Subject: [PATCH 12/14] adding service wrapper for module --- modules/i18n/ui-i18n.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 19fa3d48..c67c919f 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -256,6 +256,23 @@ angular.forEach(FILTER_ALIASES, function(alias){ uiI18n.filter(alias,['$parse', uitFilter]); }); + angular.service("$i18nService", function(){ + var uii18nService = { + getCache: function(){ + return uiI18n._cache; + }, + $broadcast: function(){ + uiI18n.$broadcast(arguments); + }, + add: function(langs, strings){ + uiI18n.add(langs, strings); + }, + set: function(lang){ + uiI18n.set(lang); + } + }; + return uii18nService; + }); })(function deepExtend(destination, source) { 'use strict'; // adding deep copy method until angularjs supports deep copy like everyone else. From 3d9f2ef01d3459cede304f22fdbc21979fc6d827 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sat, 8 Mar 2014 15:25:52 -0700 Subject: [PATCH 13/14] double quotes... --- modules/i18n/ui-i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index c67c919f..47084769 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -256,7 +256,7 @@ angular.forEach(FILTER_ALIASES, function(alias){ uiI18n.filter(alias,['$parse', uitFilter]); }); - angular.service("$i18nService", function(){ + angular.service('$i18nService', function(){ var uii18nService = { getCache: function(){ return uiI18n._cache; From 6aefca2439250af1d62db1b53e096c7944ba3ce7 Mon Sep 17 00:00:00 2001 From: Tim Sweet Date: Sat, 8 Mar 2014 15:30:48 -0700 Subject: [PATCH 14/14] module not angular duh... --- modules/i18n/ui-i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/i18n/ui-i18n.js b/modules/i18n/ui-i18n.js index 47084769..294d950d 100644 --- a/modules/i18n/ui-i18n.js +++ b/modules/i18n/ui-i18n.js @@ -256,7 +256,7 @@ angular.forEach(FILTER_ALIASES, function(alias){ uiI18n.filter(alias,['$parse', uitFilter]); }); - angular.service('$i18nService', function(){ + uiI18n.service('$i18nService', function(){ var uii18nService = { getCache: function(){ return uiI18n._cache;