misc updates to ox.js

This commit is contained in:
rolux 2012-01-04 13:12:48 +05:30
parent d64e39c5b2
commit 2ef642fdeb
11 changed files with 136 additions and 93 deletions

View file

@ -8,7 +8,7 @@ Ox.ArrayEditable = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element(options.editable === false ? {} : { var that = Ox.Element(options.editable === false ? {} : {
tooltip: 'Doubleclick to add ' + (options.itemName : 'item') tooltip: 'Doubleclick to add ' + (options.itemName || 'item')
}) })
.defaults({ .defaults({
editable: true, editable: true,

View file

@ -188,16 +188,19 @@ Ox.forEach = function(col, fn, includePrototype) {
}; };
/*@ /*@
Ox.getObjectById <f> Returns an array element with a given id Ox.getIndex <f> Returns the first array index of an object where obj[key] is val
> Ox.getObjectById([{id: "foo", title: "Foo"}, {id: "bar", title: "Bar"}], "foo") > Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 2)
{id: "foo", title: "Foo"} 1
> Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 1)
0
> Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 0)
-1
@*/ @*/
// fixme: should this be getElementById() ? Ox.getIndex = function(arr, key, val) {
Ox.getObjectById = function(arr, id) { var ret = -1;
var ret = null; Ox.forEach(arr, function(obj, ind) {
Ox.forEach(arr, function(v) { if (obj[key] === val) {
if (v.id == id) { ret = ind;
ret = v;
return false; return false;
} }
}); });
@ -205,23 +208,43 @@ Ox.getObjectById = function(arr, id) {
}; };
/*@ /*@
Ox.getPositionById <f> Returns the index of an array element with a given id Ox.getIndexById <f> Returns the first array index of an object with a given id
> Ox.getPositionById([{id: "foo", title: "Foo"}, {id: "bar", title: "Bar"}], "foo") > Ox.getIndexById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'foo')
0 0
@*/ @*/
// fixme: this should be getIndexById() // FIXME: this should be getIndexById() only
Ox.getPositionById = function(arr, id) { Ox.getIndexById = Ox.getPositionById = function(arr, id) {
var ret = -1; return Ox.getIndex(arr, 'id', id);
Ox.forEach(arr, function(v, i) { };
if (v.id == id) {
ret = i; /*@
Ox.getObject <f> Returns the first object in an array where obj[key] is val
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 2)
{a: 2, i: 1}
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 1)
{a: 1, i: 0}
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 0)
null
@*/
Ox.getObject = function(arr, key, val) {
var ret = null;
Ox.forEach(arr, function(obj) {
if (obj[key] === val) {
ret = obj;
return false; return false;
} }
}); });
return ret; return ret;
}; };
// fixme: and what about getElementBy() and getIndexBy() ? /*@
Ox.getObjectById <f> Returns the first object in an array with a given id
> Ox.getObjectById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'foo')
{id: "foo", str: "Foo"}
@*/
Ox.getObjectById = function(arr, id) {
return Ox.getObject(arr, 'id', id);
};
/*@ /*@
Ox.getset <f> Generic getter and setter function Ox.getset <f> Generic getter and setter function

View file

@ -2,6 +2,7 @@
/*@ /*@
Ox.canvas <function> Generic canvas object Ox.canvas <function> Generic canvas object
# Description --------------------------------------------------------------
Returns an object with the properties: <code>canvas</code>, Returns an object with the properties: <code>canvas</code>,
<code>context</code>, <code>data</code> and <code>imageData</code>. <code>context</code>, <code>data</code> and <code>imageData</code>.
# Usage -------------------------------------------------------------------- # Usage --------------------------------------------------------------------
@ -14,7 +15,6 @@ Ox.canvas <function> Generic canvas object
@*/ @*/
Ox.canvas = function() { Ox.canvas = function() {
// Ox.print("CANVAS", arguments)
var c = {}, isImage = arguments.length == 1, var c = {}, isImage = arguments.length == 1,
image = isImage ? arguments[0] : { image = isImage ? arguments[0] : {
width: arguments[0], height: arguments[1] width: arguments[0], height: arguments[1]

View file

@ -433,12 +433,12 @@
if (code < 128) { if (code < 128) {
str = chr; str = chr;
} else if (code < 2048) { } else if (code < 2048) {
str = String.fromCharCode(code >> 6 | 192) + str = String.fromCharCode(code >> 6 | 192)
String.fromCharCode(code & 63 | 128); + String.fromCharCode(code & 63 | 128);
} else { } else {
str = String.fromCharCode(code >> 12 | 224) + str = String.fromCharCode(code >> 12 | 224)
String.fromCharCode(code >> 6 & 63 | 128) + + String.fromCharCode(code >> 6 & 63 | 128)
String.fromCharCode(code & 63 | 128); + String.fromCharCode(code & 63 | 128);
} }
return str; return str;
}).join(''); }).join('');
@ -455,40 +455,44 @@
'¥€$' '¥€$'
@*/ @*/
Ox.decodeUTF8 = function(str) { Ox.decodeUTF8 = function(str) {
var bytes = Ox.map(str, function(v) { var code,
return v.charCodeAt(0);
}),
i = 0, i = 0,
len = str.length, len = str.length,
str = ''; ret = '';
while (i < len) { while (i < len) {
if (bytes[i] <= 128) { code = Ox.range(3).map(function(o) {
str += String.fromCharCode(bytes[i]); return str.charCodeAt(i + o);
});
if (code[0] <= 128) {
ret += str[i];
i++; i++;
} else if ( } else if (
bytes[i] >= 192 && bytes[i] < 240 && code[0] >= 192 && code[0] < 240
i < len - (bytes[i] < 224 ? 1 : 2) && i < len - (code[0] < 224 ? 1 : 2)
) { ) {
if (bytes[i + 1] >= 128 && bytes[i + 1] < 192) { if (code[1] >= 128 && code[1] < 192) {
if (bytes[i] < 224) { if (code[0] < 224) {
str += String.fromCharCode((bytes[i] & 31) << 6 | ret += String.fromCharCode(
bytes[i + 1] & 63); (code[0] & 31) << 6 | code[1] & 63
);
i += 2; i += 2;
} else if (bytes[i + 2] >= 128 && bytes[i + 2] < 192) { } else if (code[2] >= 128 && code[2] < 192) {
str += String.fromCharCode((bytes[i] & 15) << 12 | ret += String.fromCharCode(
(bytes[i + 1] & 63) << 6 | bytes[i + 2] & 63); (code[0] & 15) << 12 | (code[1] & 63) << 6
| code[2] & 63
);
i += 3; i += 3;
} else { } else {
throwUTF8Error(bytes[i + 2], i + 2); throwUTF8Error(code[2], i + 2);
} }
} else { } else {
throwUTF8Error(bytes[i + 1], i + 1); throwUTF8Error(code[1], i + 1);
} }
} else { } else {
throwUTF8Error(bytes[i], i); throwUTF8Error(code[0], i);
} }
} }
return str; return ret;
}; };
})(); })();

View file

@ -350,10 +350,8 @@ Ox.formatDateRangeDuration = function(start, end, utc) {
} else { } else {
// outside the range, rewind the date by one unit // outside the range, rewind the date by one unit
Ox['set' + parts[i]](date, Ox['get' + parts[i]](date, utc) - 1, utc); Ox['set' + parts[i]](date, Ox['get' + parts[i]](date, utc) - 1, utc);
if (key == 'month') {
// and revert to original day // and revert to original day
Ox.setDate(date, day, utc); key == 'month' && Ox.setDate(date, day, utc);
}
break; break;
} }
} }

View file

@ -30,15 +30,14 @@
Ox.getArea = function(pointA, pointB) { Ox.getArea = function(pointA, pointB) {
/* /*
area of a ring between two latitudes: area of a ring between two latitudes:
2 * PI * r^2 * abs(sin(lat0) - sin(lat1)) 2 * PI * r^2 * abs(sin(latA) - sin(latB))
see http://mathforum.org/library/drmath/view/63767.html see http://mathforum.org/library/drmath/view/63767.html
*/ =>
/* 2 * Math.PI
2 * Math.PI * * Math.pow(Ox.EARTH_RADIUS, 2)
Math.pow(Ox.EARTH_RADIUS, 2) * * Math.abs(Math.sin(Ox.rad(latA)) - Math.sin(Ox.rad(latB)))
Math.abs(Math.sin(Ox.rad(0)) - Math.sin(Ox.rad(1))) * * Math.abs(Ox.rad(lngA) - Ox.rad(lngB))
Math.abs(Ox.rad(0) - Ox.rad(1)) / / (2 * Math.PI)
(2 * Math.PI)
*/ */
if (Ox.crossesDateline(pointA, pointB)) { if (Ox.crossesDateline(pointA, pointB)) {
pointB.lng += 360; pointB.lng += 360;

View file

@ -722,8 +722,9 @@ Ox.tokenize = (function() {
// scan back to the previous significant token, // scan back to the previous significant token,
// or the beginning of the source // or the beginning of the source
while ( while (
typeof tokens[--index] != 'undefined' tokens[--index] !== void 0 && [
&& ['comment', 'linebreak', 'whitespace'].indexOf(tokens[index].type) > -1 'comment', 'linebreak', 'whitespace'
].indexOf(tokens[index].type) > -1
) { ) {
offset += tokens[index].length; offset += tokens[index].length;
} }
@ -732,7 +733,9 @@ Ox.tokenize = (function() {
isRegExp = true; isRegExp = true;
} else { } else {
prevToken = tokens[index]; prevToken = tokens[index];
prevString = source.substr(cursor - prevToken.length - offset, prevToken.length); prevString = source.substr(
cursor - prevToken.length - offset, prevToken.length
);
isRegExp = ( isRegExp = (
prevToken.type == 'keyword' prevToken.type == 'keyword'
&& ['false', 'null', 'true'].indexOf(prevString) == -1 && ['false', 'null', 'true'].indexOf(prevString) == -1

View file

@ -2,7 +2,7 @@
/*@ /*@
Ox.asinh <f> Inverse hyperbolic sine Ox.asinh <f> Inverse hyperbolic sine
Strangely missing from <code>Math</code>. Missing from <code>Math</code>.
@*/ @*/
Ox.asinh = function(x) { Ox.asinh = function(x) {
// fixme: no test // fixme: no test
@ -11,7 +11,7 @@ Ox.asinh = function(x) {
/*@ /*@
Ox.deg <f> Takes radians, returns degrees Ox.deg <f> Takes radians, returns degrees
Strangely missing from <code>Math</code>. Missing from <code>Math</code>.
> Ox.deg(2 * Math.PI) > Ox.deg(2 * Math.PI)
360 360
@*/ @*/
@ -55,18 +55,20 @@ Ox.limit <f> Limits a number by a given mininum and maximum
3 3
> Ox.limit(2, 1) > Ox.limit(2, 1)
1 1
> Ox.limit(-1, -2)
-2
@*/ @*/
Ox.limit = function(/*num[[, min], max]*/) { Ox.limit = function(/*num[[, min], max]*/) {
var len = arguments.length, var len = arguments.length,
num = arguments[0], num = arguments[0],
min = len == 3 ? arguments[1] : 0, // fixme: should be -Infinity min = len == 3 ? arguments[1] : -Infinity,
max = arguments[len - 1]; max = arguments[len - 1];
return Math.min(Math.max(num, min), max); return Math.min(Math.max(num, min), max);
}; };
/*@ /*@
Ox.log <f> Returns the logarithm of a given number to a given base Ox.log <f> Returns the logarithm of a given number to a given base
Strangely missing from <code>Math</code>. Missing from <code>Math</code>.
> Ox.log(100, 10) > Ox.log(100, 10)
2 2
> Ox.log(Math.E) > Ox.log(Math.E)
@ -86,13 +88,12 @@ Ox.mod <f> Modulo function
9 9
@*/ @*/
Ox.mod = function(num, by) { Ox.mod = function(num, by) {
var mod = num % by; return (num % by + by) % by;
return mod >= 0 ? mod : mod + by;
}; };
/*@ /*@
Ox.rad <f> Takes degrees, returns radians Ox.rad <f> Takes degrees, returns radians
Strangely missing from <code>Math</code>. Missing from <code>Math</code>.
> Ox.rad(360) > Ox.rad(360)
2 * Math.PI 2 * Math.PI
@*/ @*/
@ -101,7 +102,12 @@ Ox.rad = function(deg) {
}; };
/*@ /*@
Ox.random <f> Returns a random integer Ox.random <f> Returns a random integer within a given range
() -> 0 or 1
(max) -> Integer between 0 (inclusive) and max (exclusive)
(min, max) -> Integer between min (inclusive) and max (exclusive)
> [0, 1].indexOf(Ox.random()) > -1
true
> [0, 1, 2].indexOf(Ox.random(3)) > -1 > [0, 1, 2].indexOf(Ox.random(3)) > -1
true true
> Ox.random(1, 2) == 1 > Ox.random(1, 2) == 1
@ -109,9 +115,9 @@ Ox.random <f> Returns a random integer
@*/ @*/
Ox.random = function() { Ox.random = function() {
var len = arguments.length, var len = arguments.length,
min = len == 1 ? 0 : arguments[0], min = len == 2 ? arguments[0] : 0,
max = arguments[len - 1]; max = len ? arguments[len - 1] : 2;
return min + parseInt(Math.random() * (max - min)); return min + Math.floor(Math.random() * (max - min));
}; };
/*@ /*@
@ -130,7 +136,7 @@ Ox.round = function(num, dec) {
/*@ /*@
Ox.sinh <f> Hyperbolic sine Ox.sinh <f> Hyperbolic sine
Strangely missing from <code>Math</code>. Missing from <code>Math</code>.
@*/ @*/
Ox.sinh = function(x) { Ox.sinh = function(x) {
// fixme: no test // fixme: no test

View file

@ -5,7 +5,6 @@ Ox.extend <function> Extends an object with one or more other objects
> Ox.extend({a: 1, b: 1, c: 1}, {b: 2, c: 2}, {c: 3}) > Ox.extend({a: 1, b: 1, c: 1}, {b: 2, c: 2}, {c: 3})
{a: 1, b: 2, c: 3} {a: 1, b: 2, c: 3}
@*/ @*/
Ox.extend = function() { Ox.extend = function() {
var obj = arguments[0]; var obj = arguments[0];
Ox.forEach(Array.prototype.slice.call(arguments, 1), function(arg, i) { Ox.forEach(Array.prototype.slice.call(arguments, 1), function(arg, i) {
@ -17,9 +16,10 @@ Ox.extend = function() {
}; };
/*@ /*@
Ox.keyOf <f> undocumented Ox.keyOf <f> Equivalent of [].indexOf for objects
> Ox.keyOf({a: 1, b: 2, c: 3}, 1)
'a'
@*/ @*/
Ox.keyOf = function(obj, val) { Ox.keyOf = function(obj, val) {
var key; var key;
Ox.forEach(obj, function(v, k) { Ox.forEach(obj, function(v, k) {
@ -40,7 +40,6 @@ Ox.serialize <f> Parses an object into query parameters
> Ox.serialize({string: 'foo', empty: {}, null: null, undefined: void 0}) > Ox.serialize({string: 'foo', empty: {}, null: null, undefined: void 0})
'string=foo' 'string=foo'
@*/ @*/
Ox.serialize = function(obj) { Ox.serialize = function(obj) {
var arr = []; var arr = [];
Ox.forEach(obj, function(val, key) { Ox.forEach(obj, function(val, key) {
@ -57,19 +56,22 @@ Ox.unserialize <f> Parses query parameters into an object
{a: '1', b: '2', c: '3'} {a: '1', b: '2', c: '3'}
> Ox.unserialize('a=-1&b=2.3&c=4,5', true) > Ox.unserialize('a=-1&b=2.3&c=4,5', true)
{a: -1, b: 2.3, c: [4, 5]} {a: -1, b: 2.3, c: [4, 5]}
> Ox.unserialize('a=1&b=&c&a=0', true)
{a: 0}
@*/ @*/
Ox.unserialize = function(str, toNumber) { Ox.unserialize = function(str, toNumber) {
var obj = {}; var obj = {};
Ox.forEach(str.split('&'), function(val) { Ox.forEach(str.split('&'), function(val) {
if (val) { if (val) {
var arr = val.split('='); var arr = val.split('=');
if (arr[1]) {
obj[arr[0]] = !toNumber ? arr[1] obj[arr[0]] = !toNumber ? arr[1]
: arr[1].indexOf(',') == -1 ? +arr[1] : arr[1].indexOf(',') == -1 ? +arr[1]
: arr[1].split(',').map(function(val) { : arr[1].split(',').map(function(val) {
return +val; return +val;
}); });
} }
}
}); });
return obj; return obj;
}; };

View file

@ -31,7 +31,7 @@ Ox.getJSON <f> Get and parse a remote JSON file
(url, callback) -> <u> undefined (url, callback) -> <u> undefined
url <s> Remote URL url <s> Remote URL
callback <f> Callback function callback <f> Callback function
data <s> The contents of the remote resource data <s> The parsed contents of the remote resource
@*/ @*/
Ox.getJSON = function(url, callback) { Ox.getJSON = function(url, callback) {
Ox.get(url, function(data) { Ox.get(url, function(data) {
@ -39,6 +39,14 @@ Ox.getJSON = function(url, callback) {
}); });
}; };
/*@
Ox.getJSONC <f> Get and parse a remote JSONC file
JSONC is JSON with JavaScript line or block comments
(url, callback) -> <u> undefined
url <s> Remote URL
callback <f> Callback function
data <s> The parsed contents of the remote resource
@*/
Ox.getJSONC = function(url, callback) { Ox.getJSONC = function(url, callback) {
Ox.get(url, function(data) { Ox.get(url, function(data) {
callback(JSON.parse(Ox.minify(data))); callback(JSON.parse(Ox.minify(data)));
@ -53,7 +61,6 @@ Ox.loadFile <f> Loads a file (image, script or stylesheet)
file <s> Local path or remote URL file <s> Local path or remote URL
callback <f> Callback function callback <f> Callback function
@*/ @*/
Ox.loadFile = (function() { Ox.loadFile = (function() {
// fixme: this doesn't handle errors yet // fixme: this doesn't handle errors yet
// fixme: rename to getFile? // fixme: rename to getFile?

View file

@ -37,12 +37,12 @@ Ox.clean = function(str) {
/*@ /*@
Ox.endsWith <f> Checks if a string ends with a given substring Ox.endsWith <f> Checks if a string ends with a given substring
If the substring is a string literal (and not a variable), If the substring is a string literal (and not a variable),
<code>/sub$/.test(str)</code> or <code>!!/sub$/(str)</code> <code>/sub$/.test(str)</code> or <code>!!/sub$/.exec(str)</code>
is shorter than <code>Ox.ends(str, sub)</code>. is shorter than <code>Ox.ends(str, sub)</code>.
> Ox.endsWith('foobar', 'bar') > Ox.endsWith('foobar', 'bar')
true true
@*/ @*/
Ox.endsWith = function(str, sub) { Ox.ends = Ox.endsWith = function(str, sub) {
// fixme: rename to ends // fixme: rename to ends
return str.substr(str.length - sub.length) == sub; return str.substr(str.length - sub.length) == sub;
}; };
@ -248,23 +248,24 @@ Ox.repeat = function(val, num) {
return ret; return ret;
}; };
/*@
Ox.reverse <f> Reverses a string
> Ox.reverse('foobar')
'raboof'
@*/
Ox.reverse = function(str) { Ox.reverse = function(str) {
/*
Ox.reverse("foo")
oof
*/
return str.toString().split('').reverse().join(''); return str.toString().split('').reverse().join('');
}; };
/*@ /*@
Ox.startsWith <f> Checks if a string starts with a given substring Ox.startsWith <f> Checks if a string starts with a given substring
If the substring is a string literal (and not a variable), If the substring is a string literal (and not a variable),
<code>/^sub/.test(str)</code> or <code>!!/^sub/(str)</code> <code>/^sub/.test(str)</code> or <code>!!/^sub/.exec(str)</code>
is shorter than <code>Ox.starts(str, sub)</code>. is shorter than <code>Ox.starts(str, sub)</code>.
> Ox.startsWith('foobar', 'foo') > Ox.startsWith('foobar', 'foo')
true true
@*/ @*/
Ox.startsWith = function(str, sub) { Ox.starts = Ox.startsWith = function(str, sub) {
// fixme: rename to starts // fixme: rename to starts
return str.substr(0, sub.length) == sub; return str.substr(0, sub.length) == sub;
}; };