Merge branch 'Chinese_tanslation' (#90)

Thanks @idalin user language should be detected from browser, or otherwise with enabled anonymous browsing it can be selected as admin (configure language for user guest). Annymous browsing can be deactivated afterwards
This commit is contained in:
OzzieIsaacs
2017-01-14 15:05:49 +01:00
9 changed files with 1541 additions and 12 deletions
+147
View File
@@ -0,0 +1,147 @@
/*!
* context.js Library associated with > v0.9.6.2 of intention.js
* http://intentionjs.com/
*
* Copyright 2011, 2013 Dowjones and other contributors
* Released under the MIT license
*
*/
(function () {
'use strict';
var context = function($, Intention){
// create a brand spankin new intention object
var intent=new Intention(),
// placeholder for the horizontal axis
horizontal_axis,
orientation_axis;
// throttle funtion used for keeping calls to the resize responive
// callback to a minimum
function throttle(callback, interval){
var lastExec = new Date(),
timer = null;
return function(e){
var d = new Date();
if (d-lastExec < interval) {
if (timer) {
window.clearTimeout(timer);
}
var callbackWrapper = function(event){
return function(){
callback(event);
};
};
timer = window.setTimeout(callbackWrapper(e), interval);
return false;
}
callback(e);
lastExec = d;
};
}
// catchall
// =======================================================================
intent.responsive([{name:'base'}]).respond('base');
// width context?
// =======================================================================
horizontal_axis = intent.responsive({
ID:'width',
contexts: [
{name:'standard', min:840},
{name:'tablet', min:510},
{name:'mobile', min:0}],
// compare the return value of the callback to each context
// return true for a match
matcher: function(test, context){
if(typeof test === 'string'){
return test === context.name;
}
return test>=context.min;
},
// callback, return value is passed to matcher()
// to compare against current context
measure: function(arg){
if(typeof arg === 'string'){
return arg;
}
return $(window).width();
}});
// orientation context?
// =======================================================================
orientation_axis = intent.responsive({
ID:'orientation',
contexts: [{name:'portrait', rotation: 0},
{name:'landscape', rotation:90}],
matcher: function(measure, ctx){
return measure === ctx.rotation;
},
measure: function(){
var test = Math.abs(window.orientation);
if(test > 0) {
test = 180 - test;
}
return test;
}
});
// ONE TIME CHECK AXES:
// touch device?
// =======================================================================
intent.responsive({
ID:'touch',
contexts:[{name:'touch'}],
matcher: function() {
return "ontouchstart" in window;
}}).respond();
// retina display?
// =======================================================================
intent.responsive({
ID: 'highres',
// contexts
contexts:[{name:'highres'}],
// matching:
matcher: function(){
return window.devicePixelRatio > 1;
}}).respond();
// bind events to the window
$(window).on('resize', throttle(horizontal_axis.respond, 100))
.on('orientationchange', horizontal_axis.respond)
.on('orientationchange', orientation_axis.respond);
// register the current width and orientation without waiting for a window
// resize
horizontal_axis.respond();
orientation_axis.respond();
$(function(){
// at doc ready grab all of the elements in the doc
intent.elements(document);
});
// return the intention object so that it can be extended by other plugins
return intent;
};
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define('context', ['jquery', 'intention'], factory);
} else {
// Browser globals
root.intent = factory(root.jQuery, root.Intention);
}
}(this, function ($, Intention) {
return context($, Intention);
}));
}).call(this);
+564
View File
@@ -0,0 +1,564 @@
/*!
* intention.js Library v0.9.7.2
* http://intentionjs.com/
*
* Copyright 2011, 2013 Dowjones and other contributors
* Released under the MIT license
*
*/
(function(root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define('intention', ['jquery', 'underscore'], factory);
} else {
root.Intention = factory(root.jQuery, root._);
}
}(this, function($, _) {
'use strict';
var Intention = function(params){
var intent = _.extend(this, params,
{_listeners:{}, contexts:[], elms:$(), axes:{}, priority:[]});
return intent;
};
Intention.prototype = {
// public methods
responsive:function responsive(contexts, options){
// for generating random ids for axis when not specified
var idChars = 'abcdefghijklmnopqrstuvwxyz0123456789',
id='', i;
// create a random id for the axis
for(i=0; i<5; i++){
id += idChars[Math.floor(Math.random() * idChars.length)];
}
var defaults = {
// if no matcher function is specified expect to compare a
// string to the ctx.name property
matcher: function(measure, ctx){
return measure === ctx.name;
},
// function takes one arg and returns it
measure: _.identity,
ID: id
};
if(_.isObject(options) === false) {
options = {};
}
if((_.isArray(contexts)) && (_.isArray(contexts[0].contexts))){
_.each(contexts, function(axis){
responsive.apply(this, axis);
}, this);
return;
}
if((_.isArray(contexts) === false) && _.isObject(contexts)){
options = contexts;
} else {
options.contexts = contexts;
}
// fill in the options
options = _.extend({}, defaults, options);
// bind an the respond function to the axis ID and prefix it
// with an underscore so that it does not get whomped accidentally
this.on('_' + options.ID + ':', _.bind(
function(e){
this.axes = this._contextualize(
options.ID, e.context, this.axes);
this._respond(this.axes, this.elms);
}, this));
var axis = {
ID:options.ID,
current:null,
contexts:options.contexts,
respond:_.bind(this._responder(options.ID, options.contexts,
options.matcher, options.measure), this)
};
this.axes[options.ID] = axis;
this.axes.__keys__ = this.priority;
this.priority.unshift(options.ID);
return axis;
},
elements: function(scope){
// find all responsive elms in a specific dom scope
if(!scope){
scope = document;
}
$('[data-intent],[intent],[data-in],[in]',
scope).each(_.bind(function(i, elm){
this.add($(elm));
}, this));
return this;
},
add: function(elms, options){
var spec;
if(!options) {
options = {};
}
// is expecting a jquery object
elms.each(_.bind(function(i, elm){
var exists = false;
this.elms.each(function(i, respElm){
if(elm === respElm) {
exists=true;
return false;
}
return true;
});
if(exists === false){
// create the elements responsive data
spec = this._fillSpec(
_.extend(options, this._attrsToSpec(elm.attributes, this.axes)));
// make any appropriate changes based on the current contexts
this._makeChanges($(elm), spec, this.axes);
this.elms.push({
elm: elm,
spec: spec
});
}
}, this));
return this;
},
remove: function(elms){
// is expecting a jquery object
var respElms = this.elms;
// elms to remove
elms.each(function(i, elm){
// elms to check against
respElms.each(function(i, candidate){
if(elm === candidate.elm){
respElms.splice(i, 1);
// found the match, break the loop
return false;
}
return true;
});
});
return this;
},
is: function(ctxName){
var axes = this.axes;
return _.some(axes.__keys__, function(key){
return ctxName === axes[key].current;
});
},
current: function(axisName){
if(this.axes.hasOwnProperty(axisName)){
return this.axes[axisName].current;
} else {
return false;
}
},
// code and concept taken from simple implementation of
// observer pattern outlined here:
// http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/
on: function(type, listener){
var events = type.split(' '),
i=0;
for(i;i<events.length;i++){
if(this._listeners[events[i]] === undefined) {
this._listeners[events[i]]=[];
}
this._listeners[events[i]].push(listener);
}
return this;
},
off: function(type, listener){
if(_.isArray(this._listeners[type])){
var listeners = this._listeners[type],
i;
for(i=0;listeners.length; i++){
if(listeners[i] === listener){
listeners.splice(i,1);
break;
}
}
}
return this;
},
// privates
_responder: function(axisID, contexts, matcher, measure){
var currentContext;
// called to perform a check
return function(){
var measurement = measure.apply(this, arguments);
_.every(contexts, function(ctx){
if( matcher(measurement, ctx)) {
// first time, or different than last context
if( (currentContext===undefined) ||
(ctx.name !== currentContext.name)){
currentContext = ctx;
// event emitting!
// emit the private axis event
this._emitter(
{_type: '_' + axisID + ':', context:currentContext.name},
currentContext, this)
// emit the public axis event
._emitter({_type: axisID + ':', context:currentContext.name},
currentContext, this)
// attempt to trigger the axis to context pair
._emitter(_.extend({},
{_type: axisID + ':' + currentContext.name},
currentContext), currentContext, this)
// then emit the context event (second ensures the context
// changes happen after all dom manipulations)
._emitter(_.extend({}, {_type:currentContext.name},
currentContext), currentContext, this);
// done, break the loop
return false;
}
// same context, break the loop
return false;
}
return true;
}, this);
// return the intention object for chaining
return this;
};
},
_emitter: function(event){
if(typeof event === 'string') {
event={_type:event};
}
if(!event.target){
event.target=this;
}
if(!event._type){
throw new Error(event._type + ' is not a supported event.');
}
if(_.isArray(this._listeners[event._type])){
var listeners = this._listeners[event._type],
i;
for(i=0; i<listeners.length; i++){
listeners[i].apply(this, arguments);
}
}
return this;
},
_fillSpec: function(spec){
var applySpec = function(fn){
_.each(spec, function(axisOptions, axis){
_.each(axisOptions, function(ctxOptions, ctx){
fn(ctxOptions, ctx, axis);
});
});
}, filler={};
applySpec(function(options){
// check to see if the ctx val is an object, could be a string
if(_.isObject(options)){
_.each(options, function(val, func){
filler[func] = '';
});
}
});
applySpec(function(options, ctx, axis){
if(_.isObject(options)){
spec[axis][ctx] = _.extend({}, filler, options);
}
});
return spec;
},
_assocAxis: function(ctx, axes){
var match=false;
_.every(axes.__keys__, function(axis){
if(match === false){
_.every(axes[axis].contexts, function(ctxCandidate){
if(ctxCandidate.name === ctx){
match = axis;
return false;
}
return true;
});
return true;
}else {
return false;
}
});
return match;
},
_makeSpec: function(axis, ctx, sAttr, value, spec){
var axisObj,
ctxObj;
if(spec[axis] !== undefined){
axisObj = spec[axis];
if(axisObj[ctx] === undefined) {
axisObj[ctx] = {};
}
} else {
axisObj = {};
axisObj[ctx] = {};
spec[axis] = axisObj;
}
axisObj[ctx][sAttr] = value;
return spec;
},
_attrsToSpec: function(attrs, axes){
var spec={},
fullPattern = new RegExp(
'^(data-)?(in|intent)-(([a-zA-Z0-9][a-zA-Z0-9]*:)?([a-zA-Z0-9]*))-([A-Za-z:-]+)'),
axisPattern = new RegExp(
'^(data-)?(in|intent)-([a-zA-Z0-9][_a-zA-Z0-9]*):$');
_.each(attrs, function(attr){
var specMatch = attr.name.match(fullPattern),
axisName;
if(specMatch !== null) {
specMatch = specMatch.slice(-3);
axisName = specMatch[0];
if(specMatch[0] === undefined){
// if there is no axis find one:
specMatch[0] = this._assocAxis(specMatch[1], axes);
if(specMatch[0] === false) {
// there is no context, so get outa here
return; // skipt the attr
}
} else {
specMatch[0] = specMatch[0].replace(/:$/, '');}
specMatch.push(attr.value);
specMatch.push(spec);
spec = this._makeSpec.apply(this, specMatch);
} else if(axisPattern.test(attr.name)){
axisName = attr.name.match(axisPattern)[3];
_.each(axes[axisName].contexts,
function(context){
this._makeSpec(axisName, context.name, 'class', context.name +
' ' + attr.value, spec);
},
this);}},
this);
return spec;
},
_contextSpec: function(ctxObj, specs){
if(specs.hasOwnProperty(ctxObj.axis) &&
specs[ctxObj.axis].hasOwnProperty(ctxObj.ctx)){
return specs[ctxObj.axis][ctxObj.ctx];
}
return {};
},
_resolveSpecs: function(currentContexts, specs){
var changes={},
moveFuncs=['append', 'prepend', 'before', 'after'];
_.each(currentContexts, function(ctxObj){
// if the axis or the context to not exist in the specs object
// skip to the next one
_.each(this._contextSpec(ctxObj, specs), function(val, func){
if(func==='class'){
if(!changes[func]){
changes[func] = [];
}
changes[func] = _.union(changes[func], val.split(' '));
} else if(((changes.move === undefined) ||
(changes.move.value === '')) &&
($.inArray(func, moveFuncs) !== -1)){
changes.move = {value:val, placement:func};
} else {
if((changes[func] === undefined) || (changes[func] === '')){
changes[func]=val;
}
}
}, this);
}, this);
return changes;
},
_currentContexts: function(axes) {
var contexts = [];
_.each(axes.__keys__, function(ID){
if(axes[ID].current !== null) {
contexts.push({ctx:axes[ID].current, axis:ID});
return;
}
});
return contexts;
},
_removeClasses: function(specs, axes) {
var toRemove = [];
_.each(axes.__keys__, function(key){
var axis = axes[key];
_.each(axis.contexts, function(ctx){
// ignore the current context, those classes SHOULD be applied
if(ctx.name === axis.current) {
return;
}
var contextSpec = this._contextSpec(
{axis:axis.ID, ctx:ctx.name}, specs),
classes;
if(contextSpec !== undefined) {
if(contextSpec['class'] !== undefined) {
classes = contextSpec['class'].split(' ');
if(classes !== undefined){
toRemove = _.union(toRemove, classes);
}
}
}
}, this);
}, this);
return toRemove;
},
_contextConfig: function(specs, axes){
return this._resolveSpecs(this._currentContexts(axes), specs, axes);
},
_makeChanges: function(elm, specs, axes){
if(_.isEmpty(axes)===false){
var ctxConfig = this._contextConfig(specs, axes);
_.each(ctxConfig, function(change, func){
if(func==='move'){
if( (specs.__placement__ !== change.placement) ||
(specs.__move__ !== change.value)){
$(change.value)[change.placement](elm);
// save the last placement of the element so
// we're not moving it around for no good reason
specs.__placement__ = change.placement;
specs.__move__ = change.value;
}
} else if(func === 'class') {
var classes = elm.attr('class') || '';
// the class add/remove formula
classes = _.union(change,
_.difference(classes.split(' '),
this._removeClasses(specs, axes)));
elm.attr('class', classes.join(' '));
} else {
elm.attr(func, change);
}
}, this);
}
return elm;
},
_respond: function(axes, elms){
// go through all of the responsive elms
elms.each(_.bind(function(i, elm){
var $elm = $(elm.elm);
this._makeChanges($elm, elm.spec, axes);
$elm.trigger('intent', this);
}, this));
},
_contextualize: function(axisID, context, axes){
axes[axisID].current = context;
return axes;
},
// private props
// axis test, does it begin with an underscore? for testing inside
// spec objects
_axis_test_pattern: new RegExp("^_[a-zA-Z0-9]"),
// match a group after the underscore:
_axis_match_pattern: new RegExp("^_([a-zA-Z0-9][_a-zA-Z0-9]*)"),
// simple trim
_trim_pattern:new RegExp( "^\s+|\s+$", "g" )
};
return Intention;
}));