New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

x18n

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

x18n - npm Package Compare versions

Comparing version 1.0.7 to 2.0.0

bower.json

14

History.md
# Changelog
# 2.0.0 / 2016-04-25
This is a major update with some incompatible changes:
- `window.t` is no longer available per default. It's easy to get back if you
want it to: 'window.t = x18n.t'
- Dynamic data bindings were removed
- Upgrade to Observable v2.0.0 which makes the event system a lot more stable
and predictable. However this also changed how `.off` works
Other changes:
- It's now suggested to use NPM. There's still a browser/AMD build available in
the `lib` folder though
- Fixed some bugs
## 1.0.3 / 2013-03-12

@@ -4,0 +18,0 @@

254

lib/x18n.js
(function() {
var Observable;
Observable = (function() {
var utils;
utils = {
is: function(type, value) {
return Object.prototype.toString.call(value).match(/\s(\w+)/)[1].toLowerCase() === type;
},
isPlainObject: function(value) {
return !!value && utils.is('object', value);
},
toArray: function(value) {
if (utils.is('array', value)) {
return value;
} else {
return [value];
}
}
};
function Observable(host) {
var fn, key, _ref;
if (host == null) {
host = {};
}
host.__observable = {
lastIds: {},
events: {},
ids: []
};
_ref = Observable.prototype;
for (key in _ref) {
fn = _ref[key];
host[key] = fn;
}
return host;
}
Observable.prototype.on = function(topics, fn, once) {
var id, topic, _base, _base1, _i, _len;
if (utils.isPlainObject(topics)) {
once = fn;
for (topic in topics) {
fn = topics[topic];
this.on(topic, fn, once);
}
} else {
topics = utils.toArray(topics);
this.__observable.ids.length = 0;
for (_i = 0, _len = topics.length; _i < _len; _i++) {
topic = topics[_i];
(_base = this.__observable.lastIds)[topic] || (_base[topic] = 0);
id = "" + topic + ";" + (++this.__observable.lastIds[topic]);
if (once) {
id += ' once';
}
this.__observable.ids.push(id);
(_base1 = this.__observable.events)[topic] || (_base1[topic] = {});
this.__observable.events[topic][id] = fn;
}
}
return this;
};
Observable.prototype.once = function(topics, fn) {
return this.on(topics, fn, true);
};
Observable.prototype.off = function(obj) {
var id, topic, _i, _len, _ref;
if (obj === void 0) {
this.__observable.events = {};
} else {
_ref = obj.__observable.ids;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
id = _ref[_i];
topic = id.substr(0, id.lastIndexOf(';')).split(' ')[0];
if (obj.__observable.events[topic]) {
delete obj.__observable.events[topic][id];
}
}
}
return this;
};
Observable.prototype.trigger = function(topic, args) {
var fn, id, _ref;
if (args == null) {
args = [];
}
_ref = this.__observable.events[topic];
for (id in _ref) {
fn = _ref[id];
fn.apply(null, args);
if (id.lastIndexOf(' once') === id.length - 1) {
this.off(id);
}
}
return this;
};
return Observable;
})();
if (typeof define === 'function' && define.amd) {
define('observable', [], function() {
return Observable;
});
} else if (typeof exports !== 'undefined') {
module.exports = Observable;
} else {
window.Observable = Observable;
}
}).call(this);
(function() {
var Observable, base,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice,

@@ -126,35 +10,23 @@ indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

base = function(Observable) {
var x18n;
return x18n = (function() {
var eventSystem, oldT;
var X18n;
X18n = (function(superClass) {
extend(X18n, superClass);
function x18n() {}
function X18n() {
this.t = bind(this.t, this);
X18n.__super__.constructor.call(this);
this.dict = {};
this.defaultlocal = 'en';
this.chosenLocal = void 0;
this.availableLocales = [];
this.locales = [];
this.missingTranslations = {};
this.on('dict:change', (function(_this) {
return function() {
return _this.sortLocales();
};
})(this));
}
x18n.dict = {};
x18n.defaultlocal = 'en';
x18n.chosenLocal = void 0;
x18n.availableLocales = [];
x18n.locales = [];
x18n.dynamicBindings = true;
x18n.missingTranslations = {};
eventSystem = new Observable;
x18n.__observable = eventSystem.__observable;
x18n.on = eventSystem.on;
x18n.once = eventSystem.once;
x18n.off = eventSystem.off;
x18n.trigger = eventSystem.trigger;
x18n.utils = {
X18n.prototype.utils = {
merge: function(one, two) {

@@ -212,3 +84,3 @@ var k, results, v;

x18n.register = function(local, dict) {
X18n.prototype.register = function(local, dict) {
if (!(local in this.dict)) {

@@ -219,6 +91,6 @@ this.dict[local] = {};

this.utils.merge(this.dict[local], dict);
return this.trigger('dict:change');
return this.trigger('dict:change', [local]);
};
x18n.set = function(local) {
X18n.prototype.set = function(local) {
this.chosenLocal = local;

@@ -228,3 +100,3 @@ return this.sortLocales();

x18n.setDefault = function(local) {
X18n.prototype.setDefault = function(local) {
this.defaultLocal = local;

@@ -234,7 +106,7 @@ return this.sortLocales();

x18n.detectLocal = function() {
X18n.prototype.detectLocal = function() {
return navigator.userLanguage || navigator.language;
};
x18n.similiarLocales = function(local) {
X18n.prototype.similiarLocales = function(local) {
local = String(local).slice(0, 2).toLowerCase();

@@ -249,5 +121,6 @@ return this.utils.filter(this.availableLocales, function(l) {

x18n.sortLocales = function() {
var _locales, i, len, local, locales;
_locales = [this.chosenLocal].concat(slice.call(this.similiarLocales(this.chosenLocal)), [this.detectLocal()], slice.call(this.similiarLocales(this.detectLocal)), [this.defaultlocal], [this.similiarLocales(this.defaultlocal)], ['en'], slice.call(this.similiarLocales('en')));
X18n.prototype.sortLocales = function() {
var _locales, i, len, local, locales, oldLocales;
oldLocales = this.locales.slice();
_locales = [this.chosenLocal].concat(slice.call(this.similiarLocales(this.chosenLocal)), [this.detectLocal()], slice.call(this.similiarLocales(this.detectLocal())), [this.defaultLocal], slice.call(this.similiarLocales(this.defaultlocal)), ['en'], slice.call(this.similiarLocales('en')));
locales = [];

@@ -262,16 +135,8 @@ for (i = 0, len = _locales.length; i < len; i++) {

this.locales = this.utils.unique(locales);
return this.trigger('lang:change');
};
x18n.resolveBindings = function(str) {
str = String(str);
if (!this.dynamicBindings) {
return str;
if (oldLocales.join(',') !== this.locales.join(',')) {
return this.trigger('lang:change', [this.locales, oldLocales]);
}
return str.replace(/\$\{([^}]+)\}/g, function(_, src) {
return x18n.globalEval(src);
});
};
x18n.interpolate = function() {
X18n.prototype.interpolate = function() {
var interpolation, str;

@@ -288,37 +153,28 @@ str = arguments[0], interpolation = 2 <= arguments.length ? slice.call(arguments, 1) : [];

}
return this.resolveBindings(str);
return str;
};
x18n.globalEval = function(src) {
return ((typeof window !== "undefined" && window !== null ? window.execScript : void 0) || function(src) {
return eval.call(typeof window !== "undefined" && window !== null, src);
})(src);
};
oldT = typeof window !== "undefined" && window !== null ? window.t : void 0;
x18n.t = function() {
X18n.prototype.t = function() {
var i, interpolation, key, len, local, ref, tr;
key = arguments[0], interpolation = 2 <= arguments.length ? slice.call(arguments, 1) : [];
tr = void 0;
ref = x18n.locales;
ref = this.locales;
for (i = 0, len = ref.length; i < len; i++) {
local = ref[i];
tr = x18n.utils.getByDotNotation(x18n.dict[local], key);
tr = this.utils.getByDotNotation(this.dict[local], key);
if (tr) {
break;
} else {
if (!(local in x18n.missingTranslations)) {
x18n.missingTranslations[local] = [];
if (!(local in this.missingTranslations)) {
this.missingTranslations[local] = [];
}
x18n.missingTranslations[local].push(key);
x18n.missingTranslations[local] = x18n.utils.unique(x18n.missingTranslations[local]);
x18n.trigger('missing-translation', [local, key]);
this.missingTranslations[local].push(key);
this.missingTranslations[local] = this.utils.unique(this.missingTranslations[local]);
this.trigger('missing-translation', [local, key]);
}
}
if (typeof tr === 'string') {
tr = x18n.interpolate.apply(x18n, [x18n.resolveBindings(tr)].concat(slice.call(interpolation)));
tr = this.interpolate.apply(this, [tr].concat(slice.call(interpolation)));
} else if (tr !== void 0) {
tr.plural = function(n) {
n = x18n.resolveBindings(n);
if (n in tr) {

@@ -334,20 +190,6 @@ return tr[n];

x18n.t.noConflict = function() {
if (typeof window !== "undefined" && window !== null) {
window.t = oldT;
}
return x18n.t;
};
return X18n;
if (typeof window !== "undefined" && window !== null) {
window.t = x18n.t;
}
x18n.on('dict:change', function() {
return x18n.sortLocales();
});
return x18n;
})();
})(Observable);
return new X18n();
};

@@ -354,0 +196,0 @@

{
"name": "x18n",
"version": "1.0.7",
"version": "2.0.0",
"description": "A JavaScript internationalisation library",

@@ -19,3 +19,3 @@ "github": "https://github.com/florian/x18n",

"dependencies": {
"observable_js": "^1.2.1"
"observable_js": "^2.0.1"
},

@@ -26,4 +26,5 @@ "devDependencies": {

"grunt-contrib-concat": "^1.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-mocha": "^1.0.1"
}
}

@@ -54,4 +54,8 @@ # X18n [![Build Status](https://travis-ci.org/florian/x18n.png)](https://travis-ci.org/florian/x18n)

The idea is that you are only responsible for registering translations, optionaly defining the user's language and adding data bindings to your HTML elements. The adapter will then, nearly instantly, update your HTML whenever the language changes or the dictionary is updated.
The idea is that you are only responsible for registering translations, optionaly defining the user's language and adding data bindings to your HTML elements. The adapter will then update your HTML whenever the language changes or the dictionary is updated.
Currently there's just a [jQuery adapter](https://github.com/florian/jQuery.x18n/). An adapter using [component](https://github.com/component)'s DOM libraries and an adapter for express.js are planned.
Currently there are adapters available for:
- [React](https://github.com/marco-a/react-x18n) (*recommended*)
- [Handlebars](https://github.com/SBoudrias/handlebars-x18n)
- [jQuery](https://github.com/florian/jQuery.x18n/)
(function() {
var dict, utils;
var dict, t, utils;

@@ -8,2 +8,6 @@ utils = x18n.utils;

t = x18n.t;
x18n.__asyncEvents = false;
describe('x18n', function() {

@@ -95,3 +99,2 @@ afterEach(function() {

return it('should be available', function() {
expect(x18n.__observable).to.be.an('object');
expect(x18n.on).to.be.a('function');

@@ -161,2 +164,8 @@ expect(x18n.once).to.be.a('function');

var called;
x18n.register('test', {
a: 'a'
});
x18n.register('en', {
a: 'a'
});
called = false;

@@ -166,4 +175,7 @@ x18n.on('lang:change', function() {

});
x18n.defaultLocal = 'test';
x18n.sortLocales();
return expect(called).to.be["true"];
expect(called).to.be["true"];
x18n.defaultLocal = 'en';
return x18n.sortLocales();
});

@@ -196,21 +208,4 @@

});
describe('resolveBindings', function() {
it('should return the string if dynamic bindings are disabled', function() {
var str;
x18n.dynamicBindings = false;
str = '2 + 2 = ${2 + 2}';
expect(x18n.resolveBindings(str)).to.equal(str);
return x18n.dynamicBindings = true;
});
return it('should evaluate dynamic bindings', function() {
expect(x18n.resolveBindings('2 + 2 = ${2 + 2}')).to.equal('2 + 2 = 4');
window.user = {
name: 'John'
};
return expect(x18n.resolveBindings('Hello ${user.name}')).to.equal('Hello John');
});
});
return describe('t', function() {
it('should be defined in the global and x18n scope', function() {
expect(window).to.have.property('t');
it('should be defined', function() {
return expect(x18n).to.have.property('t');

@@ -274,11 +269,2 @@ });

});
it('should support dynamic bindings', function() {
window.user = {
name: 'John'
};
x18n.register('en', {
welcome: 'Welcome ${user.name}'
});
return expect(t('welcome')).to.equal('Welcome John');
});
it('should return an object with a plural method when requesting a plural', function() {

@@ -293,3 +279,3 @@ x18n.register('en', {

});
it('should support pluralisation', function() {
return it('should support pluralisation', function() {
x18n.register('en', {

@@ -304,37 +290,2 @@ users: {

});
it('should support dynamic bindings for interpolation', function() {
window.user = {
name: 'John'
};
x18n.register('en', {
welcome: 'Welcome %1'
});
expect(t('welcome', '${user.name}')).to.equal('Welcome John');
x18n.register('en', {
welcome: 'Welcome %{name}'
});
return expect(t('welcome', {
name: '${user.name}'
})).to.equal('Welcome John');
});
it('should support dynamic bindings for plurals', function() {
window.users = {
length: 50
};
x18n.register('en', {
users: {
1: 'There is 1 user online',
n: 'There are %1 users online'
}
});
return expect(t('users').plural('${users.length}')).to.equal('There are 50 users online');
});
return describe('noConflict', function() {
return it('should restore the old t and return t', function() {
var t;
t = window.t.noConflict();
expect(t).to.equal(x18n.t);
return window.t = t;
});
});
});

@@ -341,0 +292,0 @@ });

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc