[IMP] Upgraded unserscore version from 1.1.7 to 1.2.2 and underscore.string from 1.1.6 to 1.2.0
WARNING: underscore string does not mixin to underscore by default. Use _.str.* bzr revid: fme@openerp.com-20111115123059-k31lhp0db2d8h22k
This commit is contained in:
parent
2b7a072a3e
commit
db2c85635b
|
@ -0,0 +1,30 @@
|
||||||
|
// Underscore.js 1.2.2
|
||||||
|
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
|
// Underscore is freely distributable under the MIT license.
|
||||||
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||||
|
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||||
|
// For all details and documentation:
|
||||||
|
// http://documentcloud.github.com/underscore
|
||||||
|
(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||||
|
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
|
||||||
|
h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
|
||||||
|
define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(b,a[e],e,a)===o)break}else for(e in a)if(m.call(a,e)&&c.call(b,a[e],e,a)===o)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.map===w)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=
|
||||||
|
d!==void 0;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;
|
||||||
|
D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});
|
||||||
|
return e};var D=b.some=b.any=function(a,c,d){var c=c||b.identity,e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
|
||||||
|
b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var c=[],b;
|
||||||
|
j(a,function(a,f){f==0?c[0]=a:(b=Math.floor(Math.random()*(f+1)),c[f]=c[b],c[b]=a)});return c};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b<d?-1:b>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<
|
||||||
|
f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||
|
||||||
|
d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,
|
||||||
|
true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(q&&a.indexOf===q)return a.indexOf(c);
|
||||||
|
for(d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(C&&a.lastIndexOf===C)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};var E=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;
|
||||||
|
e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));E.prototype=a.prototype;var b=new E,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return m.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
|
||||||
|
function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=
|
||||||
|
null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=i.call(arguments);return function(){for(var b=i.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==
|
||||||
|
Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
|
||||||
|
a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:
|
||||||
|
function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};
|
||||||
|
b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
|
||||||
|
interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,
|
||||||
|
"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,
|
||||||
|
arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
|
|
@ -1,4 +1,4 @@
|
||||||
// Underscore.js 1.1.7
|
// Underscore.js 1.2.2
|
||||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
// Underscore is freely distributable under the MIT license.
|
// Underscore is freely distributable under the MIT license.
|
||||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||||
|
@ -48,19 +48,26 @@
|
||||||
// Create a safe reference to the Underscore object for use below.
|
// Create a safe reference to the Underscore object for use below.
|
||||||
var _ = function(obj) { return new wrapper(obj); };
|
var _ = function(obj) { return new wrapper(obj); };
|
||||||
|
|
||||||
// Export the Underscore object for **CommonJS**, with backwards-compatibility
|
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
|
||||||
// for the old `require()` API. If we're not in CommonJS, add `_` to the
|
// backwards-compatibility for the old `require()` API. If we're not in
|
||||||
// global object.
|
// CommonJS, add `_` to the global object.
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
if (typeof exports !== 'undefined') {
|
||||||
module.exports = _;
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
_._ = _;
|
exports = module.exports = _;
|
||||||
|
}
|
||||||
|
exports._ = _;
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
// Register as a named module with AMD.
|
||||||
|
define('underscore', function() {
|
||||||
|
return _;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Exported as a string, for Closure Compiler "advanced" mode.
|
// Exported as a string, for Closure Compiler "advanced" mode.
|
||||||
root['_'] = _;
|
root['_'] = _;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current version.
|
// Current version.
|
||||||
_.VERSION = '1.1.7';
|
_.VERSION = '1.2.2';
|
||||||
|
|
||||||
// Collection Functions
|
// Collection Functions
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -187,7 +194,7 @@
|
||||||
if (obj == null) return result;
|
if (obj == null) return result;
|
||||||
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
||||||
each(obj, function(value, index, list) {
|
each(obj, function(value, index, list) {
|
||||||
if (result |= iterator.call(context, value, index, list)) return breaker;
|
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
||||||
});
|
});
|
||||||
return !!result;
|
return !!result;
|
||||||
};
|
};
|
||||||
|
@ -198,8 +205,8 @@
|
||||||
var found = false;
|
var found = false;
|
||||||
if (obj == null) return found;
|
if (obj == null) return found;
|
||||||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||||||
any(obj, function(value) {
|
found = any(obj, function(value) {
|
||||||
if (found = value === target) return true;
|
return value === target;
|
||||||
});
|
});
|
||||||
return found;
|
return found;
|
||||||
};
|
};
|
||||||
|
@ -220,6 +227,7 @@
|
||||||
// Return the maximum element or (element-based computation).
|
// Return the maximum element or (element-based computation).
|
||||||
_.max = function(obj, iterator, context) {
|
_.max = function(obj, iterator, context) {
|
||||||
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
|
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
|
||||||
|
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
||||||
var result = {computed : -Infinity};
|
var result = {computed : -Infinity};
|
||||||
each(obj, function(value, index, list) {
|
each(obj, function(value, index, list) {
|
||||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||||
|
@ -231,6 +239,7 @@
|
||||||
// Return the minimum element (or element-based computation).
|
// Return the minimum element (or element-based computation).
|
||||||
_.min = function(obj, iterator, context) {
|
_.min = function(obj, iterator, context) {
|
||||||
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
|
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
|
||||||
|
if (!iterator && _.isEmpty(obj)) return Infinity;
|
||||||
var result = {computed : Infinity};
|
var result = {computed : Infinity};
|
||||||
each(obj, function(value, index, list) {
|
each(obj, function(value, index, list) {
|
||||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||||
|
@ -239,6 +248,21 @@
|
||||||
return result.value;
|
return result.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Shuffle an array.
|
||||||
|
_.shuffle = function(obj) {
|
||||||
|
var shuffled = [], rand;
|
||||||
|
each(obj, function(value, index, list) {
|
||||||
|
if (index == 0) {
|
||||||
|
shuffled[0] = value;
|
||||||
|
} else {
|
||||||
|
rand = Math.floor(Math.random() * (index + 1));
|
||||||
|
shuffled[index] = shuffled[rand];
|
||||||
|
shuffled[rand] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return shuffled;
|
||||||
|
};
|
||||||
|
|
||||||
// Sort the object's values by a criterion produced by an iterator.
|
// Sort the object's values by a criterion produced by an iterator.
|
||||||
_.sortBy = function(obj, iterator, context) {
|
_.sortBy = function(obj, iterator, context) {
|
||||||
return _.pluck(_.map(obj, function(value, index, list) {
|
return _.pluck(_.map(obj, function(value, index, list) {
|
||||||
|
@ -252,9 +276,11 @@
|
||||||
}), 'value');
|
}), 'value');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Groups the object's values by a criterion produced by an iterator
|
// Groups the object's values by a criterion. Pass either a string attribute
|
||||||
_.groupBy = function(obj, iterator) {
|
// to group by, or a function that returns the criterion.
|
||||||
|
_.groupBy = function(obj, val) {
|
||||||
var result = {};
|
var result = {};
|
||||||
|
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||||
each(obj, function(value, index) {
|
each(obj, function(value, index) {
|
||||||
var key = iterator(value, index);
|
var key = iterator(value, index);
|
||||||
(result[key] || (result[key] = [])).push(value);
|
(result[key] || (result[key] = [])).push(value);
|
||||||
|
@ -298,6 +324,24 @@
|
||||||
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
|
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returns everything but the last entry of the array. Especcialy useful on
|
||||||
|
// the arguments object. Passing **n** will return all the values in
|
||||||
|
// the array, excluding the last N. The **guard** check allows it to work with
|
||||||
|
// `_.map`.
|
||||||
|
_.initial = function(array, n, guard) {
|
||||||
|
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the last element of an array. Passing **n** will return the last N
|
||||||
|
// values in the array. The **guard** check allows it to work with `_.map`.
|
||||||
|
_.last = function(array, n, guard) {
|
||||||
|
if ((n != null) && !guard) {
|
||||||
|
return slice.call(array, Math.max(array.length - n, 0));
|
||||||
|
} else {
|
||||||
|
return array[array.length - 1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Returns everything but the first entry of the array. Aliased as `tail`.
|
// Returns everything but the first entry of the array. Aliased as `tail`.
|
||||||
// Especially useful on the arguments object. Passing an **index** will return
|
// Especially useful on the arguments object. Passing an **index** will return
|
||||||
// the rest of the values in the array from that index onward. The **guard**
|
// the rest of the values in the array from that index onward. The **guard**
|
||||||
|
@ -306,20 +350,15 @@
|
||||||
return slice.call(array, (index == null) || guard ? 1 : index);
|
return slice.call(array, (index == null) || guard ? 1 : index);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the last element of an array.
|
|
||||||
_.last = function(array) {
|
|
||||||
return array[array.length - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Trim out all falsy values from an array.
|
// Trim out all falsy values from an array.
|
||||||
_.compact = function(array) {
|
_.compact = function(array) {
|
||||||
return _.filter(array, function(value){ return !!value; });
|
return _.filter(array, function(value){ return !!value; });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a completely flattened version of an array.
|
// Return a completely flattened version of an array.
|
||||||
_.flatten = function(array) {
|
_.flatten = function(array, shallow) {
|
||||||
return _.reduce(array, function(memo, value) {
|
return _.reduce(array, function(memo, value) {
|
||||||
if (_.isArray(value)) return memo.concat(_.flatten(value));
|
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
|
||||||
memo[memo.length] = value;
|
memo[memo.length] = value;
|
||||||
return memo;
|
return memo;
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -333,17 +372,23 @@
|
||||||
// Produce a duplicate-free version of the array. If the array has already
|
// Produce a duplicate-free version of the array. If the array has already
|
||||||
// been sorted, you have the option of using a faster algorithm.
|
// been sorted, you have the option of using a faster algorithm.
|
||||||
// Aliased as `unique`.
|
// Aliased as `unique`.
|
||||||
_.uniq = _.unique = function(array, isSorted) {
|
_.uniq = _.unique = function(array, isSorted, iterator) {
|
||||||
return _.reduce(array, function(memo, el, i) {
|
var initial = iterator ? _.map(array, iterator) : array;
|
||||||
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
|
var result = [];
|
||||||
|
_.reduce(initial, function(memo, el, i) {
|
||||||
|
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
|
||||||
|
memo[memo.length] = el;
|
||||||
|
result[result.length] = array[i];
|
||||||
|
}
|
||||||
return memo;
|
return memo;
|
||||||
}, []);
|
}, []);
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Produce an array that contains the union: each distinct element from all of
|
// Produce an array that contains the union: each distinct element from all of
|
||||||
// the passed-in arrays.
|
// the passed-in arrays.
|
||||||
_.union = function() {
|
_.union = function() {
|
||||||
return _.uniq(_.flatten(arguments));
|
return _.uniq(_.flatten(arguments, true));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Produce an array that contains every item shared between all the
|
// Produce an array that contains every item shared between all the
|
||||||
|
@ -391,7 +436,6 @@
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||||||
_.lastIndexOf = function(array, item) {
|
_.lastIndexOf = function(array, item) {
|
||||||
if (array == null) return -1;
|
if (array == null) return -1;
|
||||||
|
@ -426,15 +470,25 @@
|
||||||
// Function (ahem) Functions
|
// Function (ahem) Functions
|
||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
|
// Reusable constructor function for prototype setting.
|
||||||
|
var ctor = function(){};
|
||||||
|
|
||||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||||
// optionally). Binding with arguments is also known as `curry`.
|
// optionally). Binding with arguments is also known as `curry`.
|
||||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||||
_.bind = function(func, obj) {
|
_.bind = function bind(func, context) {
|
||||||
|
var bound, args;
|
||||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||||
var args = slice.call(arguments, 2);
|
if (!_.isFunction(func)) throw new TypeError;
|
||||||
return function() {
|
args = slice.call(arguments, 2);
|
||||||
return func.apply(obj, args.concat(slice.call(arguments)));
|
return bound = function() {
|
||||||
|
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||||
|
ctor.prototype = func.prototype;
|
||||||
|
var self = new ctor;
|
||||||
|
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||||
|
if (Object(result) === result) return result;
|
||||||
|
return self;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -470,31 +524,43 @@
|
||||||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Internal function used to implement `_.throttle` and `_.debounce`.
|
|
||||||
var limit = function(func, wait, debounce) {
|
|
||||||
var timeout;
|
|
||||||
return function() {
|
|
||||||
var context = this, args = arguments;
|
|
||||||
var throttler = function() {
|
|
||||||
timeout = null;
|
|
||||||
func.apply(context, args);
|
|
||||||
};
|
|
||||||
if (debounce) clearTimeout(timeout);
|
|
||||||
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a function, that, when invoked, will only be triggered at most once
|
// Returns a function, that, when invoked, will only be triggered at most once
|
||||||
// during a given window of time.
|
// during a given window of time.
|
||||||
_.throttle = function(func, wait) {
|
_.throttle = function(func, wait) {
|
||||||
return limit(func, wait, false);
|
var context, args, timeout, throttling, more;
|
||||||
|
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
||||||
|
return function() {
|
||||||
|
context = this; args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (more) func.apply(context, args);
|
||||||
|
whenDone();
|
||||||
|
};
|
||||||
|
if (!timeout) timeout = setTimeout(later, wait);
|
||||||
|
if (throttling) {
|
||||||
|
more = true;
|
||||||
|
} else {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
whenDone();
|
||||||
|
throttling = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a function, that, as long as it continues to be invoked, will not
|
// Returns a function, that, as long as it continues to be invoked, will not
|
||||||
// be triggered. The function will be called after it stops being called for
|
// be triggered. The function will be called after it stops being called for
|
||||||
// N milliseconds.
|
// N milliseconds.
|
||||||
_.debounce = function(func, wait) {
|
_.debounce = function(func, wait) {
|
||||||
return limit(func, wait, true);
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
func.apply(context, args);
|
||||||
|
};
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a function that will be executed at most one time, no matter how
|
// Returns a function that will be executed at most one time, no matter how
|
||||||
|
@ -533,12 +599,12 @@
|
||||||
|
|
||||||
// Returns a function that will only be executed after being called N times.
|
// Returns a function that will only be executed after being called N times.
|
||||||
_.after = function(times, func) {
|
_.after = function(times, func) {
|
||||||
|
if (times <= 0) return func();
|
||||||
return function() {
|
return function() {
|
||||||
if (--times < 1) { return func.apply(this, arguments); }
|
if (--times < 1) { return func.apply(this, arguments); }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Object Functions
|
// Object Functions
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
|
@ -588,6 +654,7 @@
|
||||||
|
|
||||||
// Create a (shallow-cloned) duplicate of an object.
|
// Create a (shallow-cloned) duplicate of an object.
|
||||||
_.clone = function(obj) {
|
_.clone = function(obj) {
|
||||||
|
if (!_.isObject(obj)) return obj;
|
||||||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -599,47 +666,103 @@
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Perform a deep comparison to check if two objects are equal.
|
// Internal recursive comparison function.
|
||||||
_.isEqual = function(a, b) {
|
function eq(a, b, stack) {
|
||||||
// Check object identity.
|
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||||
if (a === b) return true;
|
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
||||||
// Different types?
|
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||||||
var atype = typeof(a), btype = typeof(b);
|
// A strict comparison is necessary because `null == undefined`.
|
||||||
if (atype != btype) return false;
|
if (a == null || b == null) return a === b;
|
||||||
// Basic equality test (watch out for coercions).
|
|
||||||
if (a == b) return true;
|
|
||||||
// One is falsy and the other truthy.
|
|
||||||
if ((!a && b) || (a && !b)) return false;
|
|
||||||
// Unwrap any wrapped objects.
|
// Unwrap any wrapped objects.
|
||||||
if (a._chain) a = a._wrapped;
|
if (a._chain) a = a._wrapped;
|
||||||
if (b._chain) b = b._wrapped;
|
if (b._chain) b = b._wrapped;
|
||||||
// One of them implements an isEqual()?
|
// Invoke a custom `isEqual` method if one is provided.
|
||||||
if (a.isEqual) return a.isEqual(b);
|
if (_.isFunction(a.isEqual)) return a.isEqual(b);
|
||||||
if (b.isEqual) return b.isEqual(a);
|
if (_.isFunction(b.isEqual)) return b.isEqual(a);
|
||||||
// Check dates' integer values.
|
// Compare `[[Class]]` names.
|
||||||
if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
|
var className = toString.call(a);
|
||||||
// Both are NaN?
|
if (className != toString.call(b)) return false;
|
||||||
if (_.isNaN(a) && _.isNaN(b)) return false;
|
switch (className) {
|
||||||
// Compare regular expressions.
|
// Strings, numbers, dates, and booleans are compared by value.
|
||||||
if (_.isRegExp(a) && _.isRegExp(b))
|
case '[object String]':
|
||||||
return a.source === b.source &&
|
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||||||
a.global === b.global &&
|
// equivalent to `new String("5")`.
|
||||||
a.ignoreCase === b.ignoreCase &&
|
return String(a) == String(b);
|
||||||
a.multiline === b.multiline;
|
case '[object Number]':
|
||||||
// If a is not an object by this point, we can't handle it.
|
a = +a;
|
||||||
if (atype !== 'object') return false;
|
b = +b;
|
||||||
// Check for different array lengths before comparing contents.
|
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||||||
if (a.length && (a.length !== b.length)) return false;
|
// other numeric values.
|
||||||
// Nothing else worked, deep compare the contents.
|
return a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);
|
||||||
var aKeys = _.keys(a), bKeys = _.keys(b);
|
case '[object Date]':
|
||||||
// Different object sizes?
|
case '[object Boolean]':
|
||||||
if (aKeys.length != bKeys.length) return false;
|
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||||||
// Recursive comparison of contents.
|
// millisecond representations. Note that invalid dates with millisecond representations
|
||||||
for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
|
// of `NaN` are not equivalent.
|
||||||
return true;
|
return +a == +b;
|
||||||
|
// RegExps are compared by their source patterns and flags.
|
||||||
|
case '[object RegExp]':
|
||||||
|
return a.source == b.source &&
|
||||||
|
a.global == b.global &&
|
||||||
|
a.multiline == b.multiline &&
|
||||||
|
a.ignoreCase == b.ignoreCase;
|
||||||
|
}
|
||||||
|
if (typeof a != 'object' || typeof b != 'object') return false;
|
||||||
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||||
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||||
|
var length = stack.length;
|
||||||
|
while (length--) {
|
||||||
|
// Linear search. Performance is inversely proportional to the number of
|
||||||
|
// unique nested structures.
|
||||||
|
if (stack[length] == a) return true;
|
||||||
|
}
|
||||||
|
// Add the first object to the stack of traversed objects.
|
||||||
|
stack.push(a);
|
||||||
|
var size = 0, result = true;
|
||||||
|
// Recursively compare objects and arrays.
|
||||||
|
if (className == '[object Array]') {
|
||||||
|
// Compare array lengths to determine if a deep comparison is necessary.
|
||||||
|
size = a.length;
|
||||||
|
result = size == b.length;
|
||||||
|
if (result) {
|
||||||
|
// Deep compare the contents, ignoring non-numeric properties.
|
||||||
|
while (size--) {
|
||||||
|
// Ensure commutative equality for sparse arrays.
|
||||||
|
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Objects with different constructors are not equivalent.
|
||||||
|
if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;
|
||||||
|
// Deep compare objects.
|
||||||
|
for (var key in a) {
|
||||||
|
if (hasOwnProperty.call(a, key)) {
|
||||||
|
// Count the expected number of properties.
|
||||||
|
size++;
|
||||||
|
// Deep compare each member.
|
||||||
|
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ensure that both objects contain the same number of properties.
|
||||||
|
if (result) {
|
||||||
|
for (key in b) {
|
||||||
|
if (hasOwnProperty.call(b, key) && !(size--)) break;
|
||||||
|
}
|
||||||
|
result = !size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove the first object from the stack of traversed objects.
|
||||||
|
stack.pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a deep comparison to check if two objects are equal.
|
||||||
|
_.isEqual = function(a, b) {
|
||||||
|
return eq(a, b, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given array or object empty?
|
// Is a given array, string, or object empty?
|
||||||
|
// An "empty" object has no enumerable own-properties.
|
||||||
_.isEmpty = function(obj) {
|
_.isEmpty = function(obj) {
|
||||||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
||||||
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
||||||
|
@ -654,7 +777,7 @@
|
||||||
// Is a given value an array?
|
// Is a given value an array?
|
||||||
// Delegates to ECMA5's native Array.isArray
|
// Delegates to ECMA5's native Array.isArray
|
||||||
_.isArray = nativeIsArray || function(obj) {
|
_.isArray = nativeIsArray || function(obj) {
|
||||||
return toString.call(obj) === '[object Array]';
|
return toString.call(obj) == '[object Array]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given variable an object?
|
// Is a given variable an object?
|
||||||
|
@ -663,44 +786,50 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given variable an arguments object?
|
// Is a given variable an arguments object?
|
||||||
_.isArguments = function(obj) {
|
if (toString.call(arguments) == '[object Arguments]') {
|
||||||
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
_.isArguments = function(obj) {
|
||||||
};
|
return toString.call(obj) == '[object Arguments]';
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
_.isArguments = function(obj) {
|
||||||
|
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Is a given value a function?
|
// Is a given value a function?
|
||||||
_.isFunction = function(obj) {
|
_.isFunction = function(obj) {
|
||||||
return !!(obj && obj.constructor && obj.call && obj.apply);
|
return toString.call(obj) == '[object Function]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given value a string?
|
// Is a given value a string?
|
||||||
_.isString = function(obj) {
|
_.isString = function(obj) {
|
||||||
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
return toString.call(obj) == '[object String]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given value a number?
|
// Is a given value a number?
|
||||||
_.isNumber = function(obj) {
|
_.isNumber = function(obj) {
|
||||||
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
|
return toString.call(obj) == '[object Number]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
|
// Is the given value `NaN`?
|
||||||
// that does not equal itself.
|
|
||||||
_.isNaN = function(obj) {
|
_.isNaN = function(obj) {
|
||||||
|
// `NaN` is the only value for which `===` is not reflexive.
|
||||||
return obj !== obj;
|
return obj !== obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given value a boolean?
|
// Is a given value a boolean?
|
||||||
_.isBoolean = function(obj) {
|
_.isBoolean = function(obj) {
|
||||||
return obj === true || obj === false;
|
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given value a date?
|
// Is a given value a date?
|
||||||
_.isDate = function(obj) {
|
_.isDate = function(obj) {
|
||||||
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
|
return toString.call(obj) == '[object Date]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is the given value a regular expression?
|
// Is the given value a regular expression?
|
||||||
_.isRegExp = function(obj) {
|
_.isRegExp = function(obj) {
|
||||||
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
|
return toString.call(obj) == '[object RegExp]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is a given value equal to null?
|
// Is a given value equal to null?
|
||||||
|
@ -733,6 +862,11 @@
|
||||||
for (var i = 0; i < n; i++) iterator.call(context, i);
|
for (var i = 0; i < n; i++) iterator.call(context, i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Escape a string for HTML interpolation.
|
||||||
|
_.escape = function(string) {
|
||||||
|
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
||||||
|
};
|
||||||
|
|
||||||
// Add your own custom functions to the Underscore object, ensuring that
|
// Add your own custom functions to the Underscore object, ensuring that
|
||||||
// they're correctly added to the OOP wrapper as well.
|
// they're correctly added to the OOP wrapper as well.
|
||||||
_.mixin = function(obj) {
|
_.mixin = function(obj) {
|
||||||
|
@ -753,7 +887,8 @@
|
||||||
// following template settings to use alternative delimiters.
|
// following template settings to use alternative delimiters.
|
||||||
_.templateSettings = {
|
_.templateSettings = {
|
||||||
evaluate : /<%([\s\S]+?)%>/g,
|
evaluate : /<%([\s\S]+?)%>/g,
|
||||||
interpolate : /<%=([\s\S]+?)%>/g
|
interpolate : /<%=([\s\S]+?)%>/g,
|
||||||
|
escape : /<%-([\s\S]+?)%>/g
|
||||||
};
|
};
|
||||||
|
|
||||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||||
|
@ -765,19 +900,22 @@
|
||||||
'with(obj||{}){__p.push(\'' +
|
'with(obj||{}){__p.push(\'' +
|
||||||
str.replace(/\\/g, '\\\\')
|
str.replace(/\\/g, '\\\\')
|
||||||
.replace(/'/g, "\\'")
|
.replace(/'/g, "\\'")
|
||||||
|
.replace(c.escape, function(match, code) {
|
||||||
|
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
|
||||||
|
})
|
||||||
.replace(c.interpolate, function(match, code) {
|
.replace(c.interpolate, function(match, code) {
|
||||||
return "'," + code.replace(/\\'/g, "'") + ",'";
|
return "'," + code.replace(/\\'/g, "'") + ",'";
|
||||||
})
|
})
|
||||||
.replace(c.evaluate || null, function(match, code) {
|
.replace(c.evaluate || null, function(match, code) {
|
||||||
return "');" + code.replace(/\\'/g, "'")
|
return "');" + code.replace(/\\'/g, "'")
|
||||||
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
|
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
||||||
})
|
})
|
||||||
.replace(/\r/g, '\\r')
|
.replace(/\r/g, '\\r')
|
||||||
.replace(/\n/g, '\\n')
|
.replace(/\n/g, '\\n')
|
||||||
.replace(/\t/g, '\\t')
|
.replace(/\t/g, '\\t')
|
||||||
+ "');}return __p.join('');";
|
+ "');}return __p.join('');";
|
||||||
var func = new Function('obj', tmpl);
|
var func = new Function('obj', '_', tmpl);
|
||||||
return data ? func(data) : func;
|
return data ? func(data, _) : function(data) { return func(data, _) };
|
||||||
};
|
};
|
||||||
|
|
||||||
// The OOP Wrapper
|
// The OOP Wrapper
|
||||||
|
@ -836,4 +974,4 @@
|
||||||
return this._wrapped;
|
return this._wrapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
// Underscore.string
|
// Underscore.string
|
||||||
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
|
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
|
||||||
// Underscore.strings is freely distributable under the terms of the MIT license.
|
// Underscore.strings is freely distributable under the terms of the MIT license.
|
||||||
// Documentation: https://github.com/edtsech/underscore.string
|
// Documentation: https://github.com/epeli/underscore.string
|
||||||
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
||||||
|
|
||||||
// Version 1.1.6
|
// Version 1.2.0
|
||||||
|
|
||||||
|
|
||||||
(function(root){
|
(function(root){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
if (typeof _ != 'undefined') {
|
|
||||||
var _reverse = _().reverse,
|
|
||||||
_include = _.include;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defining helper functions.
|
// Defining helper functions.
|
||||||
|
|
||||||
var nativeTrim = String.prototype.trim;
|
var nativeTrim = String.prototype.trim;
|
||||||
|
@ -22,7 +16,7 @@
|
||||||
var parseNumber = function(source) { return source * 1 || 0; };
|
var parseNumber = function(source) { return source * 1 || 0; };
|
||||||
|
|
||||||
var strRepeat = function(i, m) {
|
var strRepeat = function(i, m) {
|
||||||
for (var o = []; m > 0; o[--m] = i);
|
for (var o = []; m > 0; o[--m] = i) {}
|
||||||
return o.join('');
|
return o.join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,6 +168,8 @@
|
||||||
|
|
||||||
var _s = {
|
var _s = {
|
||||||
|
|
||||||
|
VERSION: '1.2.0',
|
||||||
|
|
||||||
isBlank: sArgs(function(str){
|
isBlank: sArgs(function(str){
|
||||||
return (/^\s*$/).test(str);
|
return (/^\s*$/).test(str);
|
||||||
}),
|
}),
|
||||||
|
@ -235,18 +231,10 @@
|
||||||
return arr.join('');
|
return arr.join('');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
includes: sArgs(function(str, needle){
|
include: sArgs(function(str, needle){
|
||||||
return str.indexOf(needle) !== -1;
|
return str.indexOf(needle) !== -1;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
include: function(obj, needle) {
|
|
||||||
if (!_include || (/string|number/).test(typeof obj)) {
|
|
||||||
return this.includes(obj, needle);
|
|
||||||
} else {
|
|
||||||
return _include(obj, needle);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
join: sArgs(function(sep) {
|
join: sArgs(function(sep) {
|
||||||
var args = slice(arguments);
|
var args = slice(arguments);
|
||||||
return args.join(args.shift());
|
return args.join(args.shift());
|
||||||
|
@ -256,13 +244,9 @@
|
||||||
return str.split("\n");
|
return str.split("\n");
|
||||||
}),
|
}),
|
||||||
|
|
||||||
reverse: function(obj){
|
reverse: sArgs(function(str){
|
||||||
if (!_reverse || (/string|number/).test(typeof obj)) {
|
return Array.prototype.reverse.apply(String(str).split('')).join('');
|
||||||
return Array.prototype.reverse.apply(String(obj).split('')).join('');
|
}),
|
||||||
} else {
|
|
||||||
return _reverse.call(_(obj));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
splice: sArgs(function(str, i, howmany, substr){
|
splice: sArgs(function(str, i, howmany, substr){
|
||||||
var arr = str.split('');
|
var arr = str.split('');
|
||||||
|
@ -309,6 +293,10 @@
|
||||||
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
|
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
humanize: function(str){
|
||||||
|
return _s.capitalize(this.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
|
||||||
|
},
|
||||||
|
|
||||||
trim: sArgs(function(str, characters){
|
trim: sArgs(function(str, characters){
|
||||||
if (!characters && nativeTrim) {
|
if (!characters && nativeTrim) {
|
||||||
return nativeTrim.call(str);
|
return nativeTrim.call(str);
|
||||||
|
@ -333,6 +321,27 @@
|
||||||
return str.length > length ? str.slice(0,length) + truncateStr : str;
|
return str.length > length ? str.slice(0,length) + truncateStr : str;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _s.prune: a more elegant version of truncate
|
||||||
|
* prune extra chars, never leaving a half-chopped word.
|
||||||
|
* @author github.com/sergiokas
|
||||||
|
*/
|
||||||
|
prune: sArgs(function(str, length, pruneStr){
|
||||||
|
pruneStr = pruneStr || '...';
|
||||||
|
length = parseNumber(length);
|
||||||
|
var pruned = '';
|
||||||
|
|
||||||
|
// Check if we're in the middle of a word
|
||||||
|
if( str.substring(length-1, length+1).search(/^\w\w$/) === 0 )
|
||||||
|
pruned = _s.rtrim(str.slice(0,length).replace(/([\W][\w]*)$/,''));
|
||||||
|
else
|
||||||
|
pruned = _s.rtrim(str.slice(0,length));
|
||||||
|
|
||||||
|
pruned = pruned.replace(/\W+$/,'');
|
||||||
|
|
||||||
|
return (pruned.length+pruneStr.length>str.length) ? str : pruned + pruneStr;
|
||||||
|
}),
|
||||||
|
|
||||||
words: function(str, delimiter) {
|
words: function(str, delimiter) {
|
||||||
return String(str).split(delimiter || " ");
|
return String(str).split(delimiter || " ");
|
||||||
},
|
},
|
||||||
|
@ -409,31 +418,51 @@
|
||||||
strLeftBack: sArgs(function(sourceStr, sep){
|
strLeftBack: sArgs(function(sourceStr, sep){
|
||||||
var pos = sourceStr.lastIndexOf(sep);
|
var pos = sourceStr.lastIndexOf(sep);
|
||||||
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
|
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
exports: function() {
|
||||||
|
var result = {};
|
||||||
|
|
||||||
|
for (var prop in this) {
|
||||||
|
if (!this.hasOwnProperty(prop) || prop == 'include' || prop == 'contains' || prop == 'reverse') continue;
|
||||||
|
result[prop] = this[prop];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Aliases
|
// Aliases
|
||||||
|
|
||||||
_s.strip = _s.trim;
|
_s.strip = _s.trim;
|
||||||
_s.lstrip = _s.ltrim;
|
_s.lstrip = _s.ltrim;
|
||||||
_s.rstrip = _s.rtrim;
|
_s.rstrip = _s.rtrim;
|
||||||
_s.center = _s.lrpad;
|
_s.center = _s.lrpad;
|
||||||
_s.ljust = _s.lpad;
|
_s.ljust = _s.lpad;
|
||||||
_s.rjust = _s.rpad;
|
_s.rjust = _s.rpad;
|
||||||
|
_s.contains = _s.include;
|
||||||
|
|
||||||
// CommonJS module is defined
|
// CommonJS module is defined
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
if (typeof exports !== 'undefined') {
|
||||||
// Export module
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
module.exports = _s;
|
// Export module
|
||||||
|
module.exports = _s;
|
||||||
|
}
|
||||||
|
exports._s = _s;
|
||||||
|
|
||||||
// Integrate with Underscore.js
|
// Integrate with Underscore.js
|
||||||
} else if (typeof root._ !== 'undefined') {
|
} else if (typeof root._ !== 'undefined') {
|
||||||
root._.mixin(_s);
|
// root._.mixin(_s);
|
||||||
|
root._.string = _s;
|
||||||
|
root._.str = root._.string;
|
||||||
|
|
||||||
// Or define it
|
// Or define it
|
||||||
} else {
|
} else {
|
||||||
root._ = _s;
|
root._ = {
|
||||||
|
string: _s,
|
||||||
|
str: _s
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}(this || window));
|
}(this || window));
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
(function(k){var o=String.prototype.trim,l=function(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")},d=function(a){return function(){for(var b=Array.prototype.slice.call(arguments),c=0;c<b.length;c++)b[c]=b[c]==null?"":""+b[c];return a.apply(null,b)}},m=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}var b=function(){b.cache.hasOwnProperty(arguments[0])||(b.cache[arguments[0]]=b.parse(arguments[0]));return b.format.call(null,b.cache[arguments[0]],arguments)};
|
||||||
|
b.format=function(b,n){var e=1,d=b.length,f="",j=[],h,i,g,k;for(h=0;h<d;h++)if(f=a(b[h]),f==="string")j.push(b[h]);else if(f==="array"){g=b[h];if(g[2]){f=n[e];for(i=0;i<g[2].length;i++){if(!f.hasOwnProperty(g[2][i]))throw m('[_.sprintf] property "%s" does not exist',g[2][i]);f=f[g[2][i]]}}else f=g[1]?n[g[1]]:n[e++];if(/[^s]/.test(g[8])&&a(f)!="number")throw m("[_.sprintf] expecting number but found %s",a(f));switch(g[8]){case "b":f=f.toString(2);break;case "c":f=String.fromCharCode(f);break;case "d":f=
|
||||||
|
parseInt(f,10);break;case "e":f=g[7]?f.toExponential(g[7]):f.toExponential();break;case "f":f=g[7]?parseFloat(f).toFixed(g[7]):parseFloat(f);break;case "o":f=f.toString(8);break;case "s":f=(f=String(f))&&g[7]?f.substring(0,g[7]):f;break;case "u":f=Math.abs(f);break;case "x":f=f.toString(16);break;case "X":f=f.toString(16).toUpperCase()}f=/[def]/.test(g[8])&&g[3]&&f>=0?"+"+f:f;i=g[4]?g[4]=="0"?"0":g[4].charAt(1):" ";k=g[6]-String(f).length;i=g[6]?l(i,k):"";j.push(g[5]?f+i:i+f)}return j.join("")};b.cache=
|
||||||
|
{};b.parse=function(a){for(var b=[],e=[],d=0;a;){if((b=/^[^\x25]+/.exec(a))!==null)e.push(b[0]);else if((b=/^\x25{2}/.exec(a))!==null)e.push("%");else if((b=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(a))!==null){if(b[2]){d|=1;var f=[],j=b[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(j))!==null)for(f.push(h[1]);(j=j.substring(h[0].length))!=="";)if((h=/^\.([a-z_][a-z_\d]*)/i.exec(j))!==null)f.push(h[1]);else if((h=/^\[(\d+)\]/.exec(j))!==null)f.push(h[1]);
|
||||||
|
else throw"[_.sprintf] huh?";else throw"[_.sprintf] huh?";b[2]=f}else d|=2;if(d===3)throw"[_.sprintf] mixing positional and named placeholders is not (yet) supported";e.push(b)}else throw"[_.sprintf] huh?";a=a.substring(b[0].length)}return e};return b}(),e={VERSION:"1.2.0",isBlank:d(function(a){return/^\s*$/.test(a)}),stripTags:d(function(a){return a.replace(/<\/?[^>]+>/ig,"")}),capitalize:d(function(a){return a.charAt(0).toUpperCase()+a.substring(1).toLowerCase()}),chop:d(function(a,b){for(var b=
|
||||||
|
b*1||0||a.length,c=[],e=0;e<a.length;)c.push(a.slice(e,e+b)),e+=b;return c}),clean:d(function(a){return e.strip(a.replace(/\s+/g," "))}),count:d(function(a,b){for(var c=0,e,d=0;d<a.length;)e=a.indexOf(b,d),e>=0&&c++,d=d+(e>=0?e:0)+b.length;return c}),chars:d(function(a){return a.split("")}),escapeHTML:d(function(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}),unescapeHTML:d(function(a){return a.replace(/</g,"<").replace(/>/g,
|
||||||
|
">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&")}),escapeRegExp:d(function(a){return a.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")}),insert:d(function(a,b,c){a=a.split("");a.splice(b*1||0,0,c);return a.join("")}),include:d(function(a,b){return a.indexOf(b)!==-1}),join:d(function(a){var b=Array.prototype.slice.call(arguments);return b.join(b.shift())}),lines:d(function(a){return a.split("\n")}),reverse:d(function(a){return Array.prototype.reverse.apply(String(a).split("")).join("")}),
|
||||||
|
splice:d(function(a,b,c,e){a=a.split("");a.splice(b*1||0,c*1||0,e);return a.join("")}),startsWith:d(function(a,b){return a.length>=b.length&&a.substring(0,b.length)===b}),endsWith:d(function(a,b){return a.length>=b.length&&a.substring(a.length-b.length)===b}),succ:d(function(a){var b=a.split("");b.splice(a.length-1,1,String.fromCharCode(a.charCodeAt(a.length-1)+1));return b.join("")}),titleize:d(function(a){for(var a=a.split(" "),b,c=0;c<a.length;c++)b=a[c].split(""),typeof b[0]!=="undefined"&&(b[0]=
|
||||||
|
b[0].toUpperCase()),c+1===a.length?a[c]=b.join(""):a[c]=b.join("")+" ";return a.join("")}),camelize:d(function(a){return e.trim(a).replace(/(\-|_|\s)+(.)?/g,function(a,c,e){return e?e.toUpperCase():""})}),underscored:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/\-|\s+/g,"_").toLowerCase()},dasherize:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1-$2").replace(/^([A-Z]+)/,"-$1").replace(/\_|\s+/g,"-").toLowerCase()},humanize:function(a){return e.capitalize(this.underscored(a).replace(/_id$/,
|
||||||
|
"").replace(/_/g," "))},trim:d(function(a,b){if(!b&&o)return o.call(a);b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+|["+b+"]+$","g"),"")}),ltrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+","g"),"")}),rtrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("["+b+"]+$","g"),"")}),truncate:d(function(a,b,c){b=b*1||0;return a.length>b?a.slice(0,b)+(c||"..."):a}),prune:d(function(a,b,c){var c=c||"...",b=b*1||0,d="",d=a.substring(b-
|
||||||
|
1,b+1).search(/^\w\w$/)===0?e.rtrim(a.slice(0,b).replace(/([\W][\w]*)$/,"")):e.rtrim(a.slice(0,b)),d=d.replace(/\W+$/,"");return d.length+c.length>a.length?a:d+c}),words:function(a,b){return String(a).split(b||" ")},pad:d(function(a,b,c,e){var d="",d=0,b=b*1||0;c?c.length>1&&(c=c.charAt(0)):c=" ";switch(e){case "right":d=b-a.length;d=l(c,d);a+=d;break;case "both":d=b-a.length;d={left:l(c,Math.ceil(d/2)),right:l(c,Math.floor(d/2))};a=d.left+a+d.right;break;default:d=b-a.length,d=l(c,d),a=d+a}return a}),
|
||||||
|
lpad:function(a,b,c){return e.pad(a,b,c)},rpad:function(a,b,c){return e.pad(a,b,c,"right")},lrpad:function(a,b,c){return e.pad(a,b,c,"both")},sprintf:m,vsprintf:function(a,b){b.unshift(a);return m.apply(null,b)},toNumber:function(a,b){var c;c=(a*1||0).toFixed(b*1||0)*1||0;return!(c===0&&a!=="0"&&a!==0)?c:Number.NaN},strRight:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(c+b.length,a.length):a}),strRightBack:d(function(a,b){var c=!b?-1:a.lastIndexOf(b);return c!=-1?a.slice(c+b.length,
|
||||||
|
a.length):a}),strLeft:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(0,c):a}),strLeftBack:d(function(a,b){var c=a.lastIndexOf(b);return c!=-1?a.slice(0,c):a}),exports:function(){var a={},b;for(b in this)if(this.hasOwnProperty(b)&&!(b=="include"||b=="contains"||b=="reverse"))a[b]=this[b];return a}};e.strip=e.trim;e.lstrip=e.ltrim;e.rstrip=e.rtrim;e.center=e.lrpad;e.ljust=e.lpad;e.rjust=e.rpad;e.contains=e.include;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)module.exports=
|
||||||
|
e;exports._s=e}else typeof k._!=="undefined"?(k._.string=e,k._.str=k._.string):k._={string:e,str:e}})(this||window);
|
|
@ -158,7 +158,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
|
||||||
},
|
},
|
||||||
on_managed_error: function(error) {
|
on_managed_error: function(error) {
|
||||||
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
|
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
|
||||||
title: "OpenERP " + _.capitalize(error.type),
|
title: "OpenERP " + _.str.capitalize(error.type),
|
||||||
buttons: {
|
buttons: {
|
||||||
Ok: function() {
|
Ok: function() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
|
@ -168,7 +168,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
|
||||||
},
|
},
|
||||||
on_traceback: function(error) {
|
on_traceback: function(error) {
|
||||||
var dialog = new openerp.web.Dialog(this, {
|
var dialog = new openerp.web.Dialog(this, {
|
||||||
title: "OpenERP " + _.capitalize(error.type),
|
title: "OpenERP " + _.str.capitalize(error.type),
|
||||||
autoOpen: true,
|
autoOpen: true,
|
||||||
width: '90%',
|
width: '90%',
|
||||||
height: '90%',
|
height: '90%',
|
||||||
|
@ -242,8 +242,10 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
this.$option_id = $('#' + option_id);
|
this.$option_id = $('#' + option_id);
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
this._super();
|
|
||||||
this.$element.html(QWeb.render("Database", this));
|
this.$element.html(QWeb.render("Database", this));
|
||||||
|
this.$element.closest(".openerp")
|
||||||
|
.removeClass("login-mode")
|
||||||
|
.addClass("database_block");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
|
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
|
||||||
|
@ -264,29 +266,22 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
this.$element.find('#db-restore').click(this.do_restore);
|
this.$element.find('#db-restore').click(this.do_restore);
|
||||||
this.$element.find('#db-change-password').click(this.do_change_password);
|
this.$element.find('#db-change-password').click(this.do_change_password);
|
||||||
this.$element.find('#back-to-login').click(function() {
|
this.$element.find('#back-to-login').click(function() {
|
||||||
self.hide();
|
self.stop();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
stop: function () {
|
stop: function () {
|
||||||
this.hide();
|
|
||||||
this.$option_id.empty();
|
this.$option_id.empty();
|
||||||
|
|
||||||
this.$element
|
this.$element
|
||||||
.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
|
.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
|
||||||
.unbind('click')
|
.unbind('click')
|
||||||
.end()
|
.end()
|
||||||
.empty();
|
.closest(".openerp")
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
show: function () {
|
|
||||||
this.$element.closest(".openerp")
|
|
||||||
.removeClass("login-mode")
|
|
||||||
.addClass("database_block");
|
|
||||||
},
|
|
||||||
hide: function () {
|
|
||||||
this.$element.closest(".openerp")
|
|
||||||
.addClass("login-mode")
|
.addClass("login-mode")
|
||||||
.removeClass("database_block")
|
.removeClass("database_block")
|
||||||
|
.end()
|
||||||
|
.empty();
|
||||||
|
this._super();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Converts a .serializeArray() result into a dict. Does not bother folding
|
* Converts a .serializeArray() result into a dict. Does not bother folding
|
||||||
|
@ -373,7 +368,6 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
}
|
}
|
||||||
self.db_list.push(self.to_object(fields)['db_name']);
|
self.db_list.push(self.to_object(fields)['db_name']);
|
||||||
self.db_list.sort();
|
self.db_list.sort();
|
||||||
self.widget_parent.set_db_list(self.db_list);
|
|
||||||
var form_obj = self.to_object(fields);
|
var form_obj = self.to_object(fields);
|
||||||
self.wait_for_newdb(result, {
|
self.wait_for_newdb(result, {
|
||||||
password: form_obj['super_admin_pwd'],
|
password: form_obj['super_admin_pwd'],
|
||||||
|
@ -403,7 +397,6 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
}
|
}
|
||||||
$db_list.find(':selected').remove();
|
$db_list.find(':selected').remove();
|
||||||
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
|
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
|
||||||
self.widget_parent.set_db_list(self.db_list);
|
|
||||||
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
|
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -536,16 +529,16 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||||
var self = this;
|
var self = this;
|
||||||
this.database = new openerp.web.Database(
|
this.database = new openerp.web.Database(
|
||||||
this, "oe_database", "oe_db_options");
|
this, "oe_database", "oe_db_options");
|
||||||
this.database.start();
|
|
||||||
|
|
||||||
this.$element.find('#oe-db-config').click(function() {
|
this.$element.find('#oe-db-config').click(function() {
|
||||||
self.database.show();
|
self.database.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$element.find("form").submit(this.on_submit);
|
this.$element.find("form").submit(this.on_submit);
|
||||||
|
|
||||||
this.rpc("/web/database/get_list", {}, function(result) {
|
this.rpc("/web/database/get_list", {}, function(result) {
|
||||||
self.set_db_list(result.db_list);
|
var tpl = openerp.web.qweb.render('Login_dblist', {db_list: result.db_list, selected_db: self.selected_db});
|
||||||
|
self.$element.find("input[name=db]").replaceWith(tpl)
|
||||||
},
|
},
|
||||||
function(error, event) {
|
function(error, event) {
|
||||||
if (error.data.fault_code === 'AccessDenied') {
|
if (error.data.fault_code === 'AccessDenied') {
|
||||||
|
@ -554,15 +547,6 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
stop: function () {
|
|
||||||
this.database.stop();
|
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
set_db_list: function (list) {
|
|
||||||
this.$element.find("[name=db]").replaceWith(
|
|
||||||
openerp.web.qweb.render('Login_dblist', {
|
|
||||||
db_list: list, selected_db: this.selected_db}))
|
|
||||||
},
|
|
||||||
on_login_invalid: function() {
|
on_login_invalid: function() {
|
||||||
this.$element.closest(".openerp").addClass("login-mode");
|
this.$element.closest(".openerp").addClass("login-mode");
|
||||||
},
|
},
|
||||||
|
|
|
@ -716,7 +716,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
|
||||||
if (parseInt(cookie_val, 10) !== token) { continue; }
|
if (parseInt(cookie_val, 10) !== token) { continue; }
|
||||||
|
|
||||||
// clear cookie
|
// clear cookie
|
||||||
document.cookie = _.sprintf("%s=;expires=%s;path=/",
|
document.cookie = _.str.sprintf("%s=;expires=%s;path=/",
|
||||||
cookie_name, new Date().toGMTString());
|
cookie_name, new Date().toGMTString());
|
||||||
if (options.success) { options.success(); }
|
if (options.success) { options.success(); }
|
||||||
complete();
|
complete();
|
||||||
|
@ -1055,7 +1055,7 @@ openerp.web.qweb.format_text_node = function(s) {
|
||||||
if (translation && translation.value === 'off') {
|
if (translation && translation.value === 'off') {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
var ts = _.trim(s);
|
var ts = _.str.trim(s);
|
||||||
if (ts.length === 0) {
|
if (ts.length === 0) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,18 +86,18 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||||
switch (descriptor.widget || descriptor.type) {
|
switch (descriptor.widget || descriptor.type) {
|
||||||
case 'integer':
|
case 'integer':
|
||||||
return openerp.web.insert_thousand_seps(
|
return openerp.web.insert_thousand_seps(
|
||||||
_.sprintf('%d', value));
|
_.str.sprintf('%d', value));
|
||||||
case 'float':
|
case 'float':
|
||||||
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
||||||
var formatted = _.sprintf('%.' + precision + 'f', value).split('.');
|
var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
|
||||||
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
|
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
|
||||||
return formatted.join(l10n.decimal_point);
|
return formatted.join(l10n.decimal_point);
|
||||||
case 'float_time':
|
case 'float_time':
|
||||||
return _.sprintf("%02d:%02d",
|
return _.str.sprintf("%02d:%02d",
|
||||||
Math.floor(value),
|
Math.floor(value),
|
||||||
Math.round((value % 1) * 60));
|
Math.round((value % 1) * 60));
|
||||||
case 'progressbar':
|
case 'progressbar':
|
||||||
return _.sprintf(
|
return _.str.sprintf(
|
||||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||||
value, value);
|
value, value);
|
||||||
case 'many2one':
|
case 'many2one':
|
||||||
|
|
|
@ -137,7 +137,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
on_loaded: function(data) {
|
on_loaded: function(data) {
|
||||||
if (data.fields_view.type !== 'search' ||
|
if (data.fields_view.type !== 'search' ||
|
||||||
data.fields_view.arch.tag !== 'search') {
|
data.fields_view.arch.tag !== 'search') {
|
||||||
throw new Error(_.sprintf(
|
throw new Error(_.str.sprintf(
|
||||||
"Got non-search view after asking for a search view: type %s, arch root %s",
|
"Got non-search view after asking for a search view: type %s, arch root %s",
|
||||||
data.fields_view.type, data.fields_view.arch.tag));
|
data.fields_view.type, data.fields_view.arch.tag));
|
||||||
}
|
}
|
||||||
|
@ -425,7 +425,7 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
|
||||||
this.message = message;
|
this.message = message;
|
||||||
},
|
},
|
||||||
toString: function () {
|
toString: function () {
|
||||||
return _.sprintf(
|
return _.str.sprintf(
|
||||||
_t("Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s"),
|
_t("Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s"),
|
||||||
{fieldname: this.field, value: this.value, message: this.message}
|
{fieldname: this.field, value: this.value, message: this.message}
|
||||||
);
|
);
|
||||||
|
|
|
@ -240,7 +240,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||||
try {
|
try {
|
||||||
processed = processed || [];
|
processed = processed || [];
|
||||||
if (widget.node.attrs.on_change) {
|
if (widget.node.attrs.on_change) {
|
||||||
var onchange = _.trim(widget.node.attrs.on_change);
|
var onchange = _.str.trim(widget.node.attrs.on_change);
|
||||||
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
||||||
if (call) {
|
if (call) {
|
||||||
var method = call[1], args = [];
|
var method = call[1], args = [];
|
||||||
|
@ -257,7 +257,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||||
};
|
};
|
||||||
var parent_fields = null;
|
var parent_fields = null;
|
||||||
_.each(call[2].split(','), function(a, i) {
|
_.each(call[2].split(','), function(a, i) {
|
||||||
var field = _.trim(a);
|
var field = _.str.trim(a);
|
||||||
if (field in argument_replacement) {
|
if (field in argument_replacement) {
|
||||||
args.push(argument_replacement[field](i));
|
args.push(argument_replacement[field](i));
|
||||||
return;
|
return;
|
||||||
|
@ -267,11 +267,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
var splitted = field.split('.');
|
var splitted = field.split('.');
|
||||||
if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
|
if (splitted.length > 1 && _.str.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
|
||||||
if (parent_fields === null) {
|
if (parent_fields === null) {
|
||||||
parent_fields = self.dataset.parent_view.get_fields_values();
|
parent_fields = self.dataset.parent_view.get_fields_values();
|
||||||
}
|
}
|
||||||
var p_val = parent_fields[_.trim(splitted[1])];
|
var p_val = parent_fields[_.str.trim(splitted[1])];
|
||||||
if (p_val !== undefined) {
|
if (p_val !== undefined) {
|
||||||
args.push(p_val == null ? false : p_val);
|
args.push(p_val == null ? false : p_val);
|
||||||
return;
|
return;
|
||||||
|
@ -638,7 +638,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
|
||||||
},
|
},
|
||||||
on_attachment_delete: function(e) {
|
on_attachment_delete: function(e) {
|
||||||
var self = this, $e = $(e.currentTarget);
|
var self = this, $e = $(e.currentTarget);
|
||||||
var name = _.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
|
var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
|
||||||
if (confirm("Do you really want to delete the attachment " + name + " ?")) {
|
if (confirm("Do you really want to delete the attachment " + name + " ?")) {
|
||||||
this.rpc('/web/dataset/unlink', {
|
this.rpc('/web/dataset/unlink', {
|
||||||
model: 'ir.attachment',
|
model: 'ir.attachment',
|
||||||
|
@ -798,13 +798,8 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
|
||||||
_build_view_fields_values: function() {
|
_build_view_fields_values: function() {
|
||||||
var a_dataset = this.view.dataset;
|
var a_dataset = this.view.dataset;
|
||||||
var fields_values = this.view.get_fields_values();
|
var fields_values = this.view.get_fields_values();
|
||||||
var active_id = a_dataset.ids[a_dataset.index];
|
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
|
||||||
_.extend(fields_values, {
|
fields_values.parent = parent_values;
|
||||||
active_id: active_id || false,
|
|
||||||
active_ids: active_id ? [active_id] : [],
|
|
||||||
active_model: a_dataset.model,
|
|
||||||
parent: a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {}
|
|
||||||
});
|
|
||||||
return fields_values;
|
return fields_values;
|
||||||
},
|
},
|
||||||
_build_eval_context: function() {
|
_build_eval_context: function() {
|
||||||
|
@ -1830,7 +1825,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
||||||
if (search_val.length > 0 &&
|
if (search_val.length > 0 &&
|
||||||
!_.include(raw_result, search_val) &&
|
!_.include(raw_result, search_val) &&
|
||||||
(!self.value || search_val !== self.value[1])) {
|
(!self.value || search_val !== self.value[1])) {
|
||||||
values.push({label: _.sprintf(_t('<em> Create "<strong>%s</strong>"</em>'),
|
values.push({label: _.str.sprintf(_t('<em> Create "<strong>%s</strong>"</em>'),
|
||||||
$('<span />').text(search_val).html()), action: function() {
|
$('<span />').text(search_val).html()), action: function() {
|
||||||
self._quick_create(search_val);
|
self._quick_create(search_val);
|
||||||
}});
|
}});
|
||||||
|
@ -2960,7 +2955,7 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
|
||||||
render_list: function() {
|
render_list: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
|
var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
|
||||||
function(x) { return _.trim(x); });
|
function(x) { return _.str.trim(x); });
|
||||||
shown = _.select(shown, function(x) { return x.length > 0; });
|
shown = _.select(shown, function(x) { return x.length > 0; });
|
||||||
|
|
||||||
if (shown.length == 0) {
|
if (shown.length == 0) {
|
||||||
|
|
|
@ -295,7 +295,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
} else {
|
} else {
|
||||||
last = first + limit;
|
last = first + limit;
|
||||||
}
|
}
|
||||||
this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
|
this.$element.find('span.oe-pager-state').empty().text(_.str.sprintf(
|
||||||
"[%d to %d] of %d", first + 1, last, total));
|
"[%d to %d] of %d", first + 1, last, total));
|
||||||
|
|
||||||
this.$element
|
this.$element
|
||||||
|
@ -647,7 +647,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
|
$footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id))
|
||||||
.html(openerp.web.format_cell(aggregation, column, undefined, false));
|
.html(openerp.web.format_cell(aggregation, column, undefined, false));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1192,7 +1192,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||||
format = "%.2f";
|
format = "%.2f";
|
||||||
}
|
}
|
||||||
$('<td>')
|
$('<td>')
|
||||||
.text(_.sprintf(format, value))
|
.text(_.str.sprintf(format, value))
|
||||||
.appendTo($row);
|
.appendTo($row);
|
||||||
} else {
|
} else {
|
||||||
$row.append('<td>');
|
$row.append('<td>');
|
||||||
|
@ -1251,7 +1251,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||||
var pages = Math.ceil(dataset.ids.length / limit);
|
var pages = Math.ceil(dataset.ids.length / limit);
|
||||||
self.$row
|
self.$row
|
||||||
.find('.oe-pager-state')
|
.find('.oe-pager-state')
|
||||||
.text(_.sprintf('%d/%d', page + 1, pages))
|
.text(_.str.sprintf('%d/%d', page + 1, pages))
|
||||||
.end()
|
.end()
|
||||||
.find('button[data-pager-action=previous]')
|
.find('button[data-pager-action=previous]')
|
||||||
.attr('disabled', page === 0)
|
.attr('disabled', page === 0)
|
||||||
|
|
|
@ -534,7 +534,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
|
||||||
$logs_list = $logs.find('ul').empty();
|
$logs_list = $logs.find('ul').empty();
|
||||||
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
|
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
|
||||||
_(log_records.reverse()).each(function (record) {
|
_(log_records.reverse()).each(function (record) {
|
||||||
$(_.sprintf('<li><a href="#">%s</a></li>', record.name))
|
$(_.str.sprintf('<li><a href="#">%s</a></li>', record.name))
|
||||||
.appendTo($logs_list)
|
.appendTo($logs_list)
|
||||||
.delegate('a', 'click', function (e) {
|
.delegate('a', 'click', function (e) {
|
||||||
self.do_action({
|
self.do_action({
|
||||||
|
@ -628,7 +628,7 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
add_section: function(name, code) {
|
add_section: function(name, code) {
|
||||||
if(!code) code = _.underscored(name);
|
if(!code) code = _.str.underscored(name);
|
||||||
var $section = this.sections[code];
|
var $section = this.sections[code];
|
||||||
|
|
||||||
if(!$section) {
|
if(!$section) {
|
||||||
|
@ -656,7 +656,7 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||||
//
|
//
|
||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
$section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code),
|
$section = this.add_section(_.str.titleize(section_code.replace('_', ' ')), section_code),
|
||||||
section_id = $section.attr('id');
|
section_id = $section.attr('id');
|
||||||
|
|
||||||
if (items) {
|
if (items) {
|
||||||
|
|
|
@ -103,7 +103,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
self.actions_attrs[aid] = {
|
self.actions_attrs[aid] = {
|
||||||
name: aid,
|
name: aid,
|
||||||
string: _.trim(result.result.name)
|
string: _.str.trim(result.result.name)
|
||||||
};
|
};
|
||||||
qdict.action = {
|
qdict.action = {
|
||||||
attrs : self.actions_attrs[aid]
|
attrs : self.actions_attrs[aid]
|
||||||
|
@ -420,7 +420,7 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
||||||
var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
|
var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
|
||||||
Installer.call('default_get', [], function (installed_modules) {
|
Installer.call('default_get', [], function (installed_modules) {
|
||||||
var installed = _(installed_modules).any(function (active, name) {
|
var installed = _(installed_modules).any(function (active, name) {
|
||||||
return _.startsWith(name, 'cat') && active; });
|
return _.str.startsWith(name, 'cat') && active; });
|
||||||
|
|
||||||
if(installed) {
|
if(installed) {
|
||||||
self.do_display_root_menu();
|
self.do_display_root_menu();
|
||||||
|
@ -521,7 +521,7 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
|
||||||
},
|
},
|
||||||
on_widget_loaded: function (widgets) {
|
on_widget_loaded: function (widgets) {
|
||||||
var widget = widgets[0];
|
var widget = widgets[0];
|
||||||
var url = _.sprintf(
|
var url = _.str.sprintf(
|
||||||
'/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
|
'/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
|
||||||
this.session.session_id, widget.id);
|
this.session.session_id, widget.id);
|
||||||
this.$element.html(QWeb.render('HomeWidget.content', {
|
this.$element.html(QWeb.render('HomeWidget.content', {
|
||||||
|
|
|
@ -233,7 +233,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
|
||||||
// second argument is coerced to a str, no good for boolean
|
// second argument is coerced to a str, no good for boolean
|
||||||
r[self.abscissa] = records[0][self.abscissa];
|
r[self.abscissa] = records[0][self.abscissa];
|
||||||
_(records).each(function (record) {
|
_(records).each(function (record) {
|
||||||
var key = _.sprintf('%s_%s',
|
var key = _.str.sprintf('%s_%s',
|
||||||
self.ordinate,
|
self.ordinate,
|
||||||
record[self.group_field].toLowerCase().replace(/\s/g, '_'));
|
record[self.group_field].toLowerCase().replace(/\s/g, '_'));
|
||||||
r[key] = record[self.ordinate];
|
r[key] = record[self.ordinate];
|
||||||
|
@ -278,7 +278,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
|
||||||
border: false,
|
border: false,
|
||||||
width: 1024,
|
width: 1024,
|
||||||
tooltip:{
|
tooltip:{
|
||||||
template: _.sprintf("#%s#, %s=#%s#",
|
template: _.str.sprintf("#%s#, %s=#%s#",
|
||||||
self.abscissa, group_list[0].text, group_list[0].group)
|
self.abscissa, group_list[0].text, group_list[0].group)
|
||||||
},
|
},
|
||||||
radius: 0,
|
radius: 0,
|
||||||
|
@ -306,7 +306,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
|
||||||
bar_chart.addSeries({
|
bar_chart.addSeries({
|
||||||
value: "#"+column.group+"#",
|
value: "#"+column.group+"#",
|
||||||
tooltip:{
|
tooltip:{
|
||||||
template: _.sprintf("#%s#, %s=#%s#",
|
template: _.str.sprintf("#%s#, %s=#%s#",
|
||||||
self.abscissa, column.text, column.group)
|
self.abscissa, column.text, column.group)
|
||||||
},
|
},
|
||||||
color: column.color
|
color: column.color
|
||||||
|
|
|
@ -87,13 +87,13 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
|
||||||
});
|
});
|
||||||
if (node.attrs['data-states']) {
|
if (node.attrs['data-states']) {
|
||||||
var states = _.map(node.attrs['data-states'].split(','), function(state) {
|
var states = _.map(node.attrs['data-states'].split(','), function(state) {
|
||||||
return "record.state.raw_value == '" + _.trim(state) + "'";
|
return "record.state.raw_value == '" + _.str.trim(state) + "'";
|
||||||
});
|
});
|
||||||
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
||||||
}
|
}
|
||||||
if (node.attrs['data-kanban_states']) {
|
if (node.attrs['data-kanban_states']) {
|
||||||
var states = _.map(node.attrs['data-kanban_states'].split(','), function(state) {
|
var states = _.map(node.attrs['data-kanban_states'].split(','), function(state) {
|
||||||
return "record.kanban_state.raw_value == '" + _.trim(state) + "'";
|
return "record.kanban_state.raw_value == '" + _.str.trim(state) + "'";
|
||||||
});
|
});
|
||||||
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
|
||||||
var self = this,
|
var self = this,
|
||||||
new_record = {};
|
new_record = {};
|
||||||
_.each(record, function(value, name) {
|
_.each(record, function(value, name) {
|
||||||
var r = _.clone(self.view.fields_view.fields[name]);
|
var r = _.clone(self.view.fields_view.fields[name] || {});
|
||||||
r.raw_value = value;
|
r.raw_value = value;
|
||||||
r.value = openerp.web.format_value(value, r);
|
r.value = openerp.web.format_value(value, r);
|
||||||
new_record[name] = r;
|
new_record[name] = r;
|
||||||
|
@ -385,7 +385,7 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
|
||||||
widget: this
|
widget: this
|
||||||
}
|
}
|
||||||
for (var p in this) {
|
for (var p in this) {
|
||||||
if (_.startsWith(p, 'kanban_')) {
|
if (_.str.startsWith(p, 'kanban_')) {
|
||||||
ctx[p] = _.bind(this[p], this);
|
ctx[p] = _.bind(this[p], this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue