- add loadAsync and use in Ox.loadFile, Ox.getJSON

- add Ox.getJSONP
- fix Ox.parseHTML
- fix Ox.Doc
- add more documentation
This commit is contained in:
j 2012-05-23 01:17:17 +02:00
parent 601a29023a
commit 1b08732fa7
8 changed files with 106 additions and 103 deletions

View file

@ -47,7 +47,7 @@ Ox.TreeList = function(options, self) {
max: self.options.max, max: self.options.max,
min: self.options.min, min: self.options.min,
unique: 'id' unique: 'id'
}, Ox.copy(self)) }, Ox.clone(self))
.addClass('OxTextList OxTreeList') .addClass('OxTextList OxTreeList')
.css({ .css({
width: self.options.width + 'px', width: self.options.width + 'px',
@ -160,8 +160,8 @@ Ox.TreeList = function(options, self) {
if (type == 'array' || type == 'object') { if (type == 'array' || type == 'object') {
ret.title += Ox.toTitleCase(type) ret.title += Ox.toTitleCase(type)
+ ' <span class="OxLight">[' + Ox.len(value) + ']</span>'; + ' <span class="OxLight">[' + Ox.len(value) + ']</span>';
ret.items = Ox.sort(Ox.keys(value).map(function(k) { ret.items = Ox.sort(Ox.map(value, function(v, k) {
return parseData(k, value[k]); return parseData(k, v);
})); }));
} else { } else {
ret.title += ( ret.title += (

View file

@ -344,7 +344,6 @@ Ox.flatten <f> Flattens an array
[1, 2, 3, 2, 1] [1, 2, 3, 2, 1]
@*/ @*/
Ox.flatten = function(arr) { Ox.flatten = function(arr) {
// fixme: can this work for objects too?
var ret = []; var ret = [];
arr.forEach(function(val) { arr.forEach(function(val) {
if (Ox.isArray(val)) { if (Ox.isArray(val)) {

View file

@ -188,8 +188,8 @@ Ox.forEach = function(col, fn, that) {
} }
} else { } else {
for (i = 0; i < col.length; i++) { for (i = 0; i < col.length; i++) {
// fn.call(that, col[i], i, col); // i in col && fn.call(that, col[i], i, col);
if (fn.call(that, col[i], i, col) === false) { if (i in col && fn.call(that, col[i], i, col) === false) {
console.warn('Returning false in Ox.forEach is deprecated.') console.warn('Returning false in Ox.forEach is deprecated.')
break; break;
} }
@ -304,8 +304,12 @@ Ox.indexOf = function(col, fn) {
return index == col.length ? -1 : index; return index == col.length ? -1 : index;
}; };
// FIXME: use this instead of `Ox.filter(Ox.map())` when it's just about getting /*@
// the original indices Ox.indicesOf <f> return indices of array elements that pass a test
> Ox.indicesOf([1, 2, 3, 4], function(val) { return val % 2 == 0; })
[1, 3]
@*/
Ox.indicesOf = function(col, fn) { Ox.indicesOf = function(col, fn) {
return Ox.map(col, function(val, i) { return Ox.map(col, function(val, i) {
return fn(val) ? i : null; return fn(val) ? i : null;
@ -339,31 +343,6 @@ Ox.isEmpty = function(val) {
return Ox.len(val) === 0; return Ox.len(val) === 0;
}; };
/*@
Ox.keys <f> Returns the keys of a collection
Unlike <code>Object.keys()</code>, <code>Ox.keys()</code> works for arrays,
objects and strings.
> Ox.keys([1, 2, 3])
[0, 1, 2]
> Ox.keys([1,,3])
[0, 2]
# fixme?
# > Ox.keys([,])
# [0]
> Ox.keys({a: 1, b: 2, c: 3})
['a', 'b', 'c']
> Ox.keys('abc')
[0, 1, 2]
@*/
// fixme: is this really needed? arrays... ok... but strings??
Ox.keys = function(obj) {
var keys = [];
Ox.forEach(obj, function(v, k) {
keys.push(k);
});
return keys.sort();
};
/*@ /*@
Ox.last <f> Gets or sets the last element of an array Ox.last <f> Gets or sets the last element of an array
Unlike <code>arrayWithALongName[arrayWithALongName.length - 1]</code>, Unlike <code>arrayWithALongName[arrayWithALongName.length - 1]</code>,
@ -395,7 +374,7 @@ Ox.last = function(arr, val) {
Ox.len <f> Returns the length of an array, node list, object or string Ox.len <f> Returns the length of an array, node list, object or string
Not to be confused with <code>Ox.length</code>, which is the Not to be confused with <code>Ox.length</code>, which is the
<code>length</code> property of the <code>Ox</code> function <code>length</code> property of the <code>Ox</code> function
(<code>1</code>). // FIXME: 1 becomes 67 in DocPanel (<code>1</code>).
> Ox.len((function() { return arguments; }(1, 2, 3))) > Ox.len((function() { return arguments; }(1, 2, 3)))
3 3
> Ox.len([1, 2, 3]) > Ox.len([1, 2, 3])
@ -480,9 +459,8 @@ Ox.map <f> Transforms the values of an array, object or string
[true, false, false] [true, false, false]
> Ox.map([0, 1, 2, 4], function(v, i) { return v ? i == v : null; }) > Ox.map([0, 1, 2, 4], function(v, i) { return v ? i == v : null; })
[true, true, false] [true, true, false]
# fixme? > Ox.map([,], function(v, i) { return i; })
# > Ox.map([,], function(v, i) { return i; }) [,]
# [0]
@*/ @*/
Ox.map = function(col, fn, that) { Ox.map = function(col, fn, that) {
var type = Ox.typeOf(col), ret; var type = Ox.typeOf(col), ret;
@ -593,23 +571,25 @@ Ox.shuffle <f> Randomizes the order of values within a collection
> Ox.shuffle('123').split('').sort().join('') > Ox.shuffle('123').split('').sort().join('')
'123' '123'
@*/ @*/
// FIXME: this doesn't actually randomize the order
Ox.shuffle = function(col) { Ox.shuffle = function(col) {
var keys, ret, type = Ox.typeOf(col), values; var keys, ret, type = Ox.typeOf(col), values;
function sort() { if (type == 'object') {
return Math.random() - 0.5;
}
if (type == 'array') {
ret = col.sort(sort);
} else if (type == 'object') {
keys = Object.keys(col); keys = Object.keys(col);
values = Ox.values(col).sort(sort); values = Ox.shuffle(Ox.values(col));
ret = {}; ret = {};
keys.forEach(function(key, i) { keys.forEach(function(key, i) {
ret[key] = values[i] ret[key] = values[i]
}); });
} else if (type == 'string') { } else {
ret = col.split('').sort(sort).join(''); ret = [];
Ox.toArray(col).forEach(function(v, i) {
var random = Math.floor(Math.random() * (i + 1));
ret[i] = ret[random];
ret[random] = v;
});
if (type == 'string') {
ret = ret.join('');
}
} }
return ret; return ret;
}; };

View file

@ -78,13 +78,10 @@ Ox.$ <f> Generic HTML element, mimics jQuery
'red' 'red'
@*/ @*/
Ox.$ = Ox.element = function(val) { Ox.$ = Ox.element = function(val) {
// fixme: remove click and mousedown,
// add native css selector
// take all matches of getElementsBy...
var element = !Ox.isString(val) ? val // window or document var element = !Ox.isString(val) ? val // window or document
: val[0] == '<' ? document.createElement(Ox.sub(val, 1, -1)) : val[0] == '<' ? document.createElement(val.slice(1, -1))
: val[0] == '#' ? document.getElementById(Ox.sub(val, 1)) : val[0] == '#' ? document.getElementById(val.slice(1))
: val[0] == '.' ? document.getElementsByClassName(Ox.sub(val, 1))[0] : val[0] == '.' ? document.getElementsByClassName(val.slice(1))[0]
: document.getElementsByTagName(val)[0]; : document.getElementsByTagName(val)[0];
return element ? { return element ? {
//@ 0 <e> The DOM element itself //@ 0 <e> The DOM element itself

View file

@ -99,7 +99,7 @@ Ox.parseHTML = (function() {
//html = Ox.parseURLs(html); //html = Ox.parseURLs(html);
//html = Ox.parseEmailAddresses(html); //html = Ox.parseEmailAddresses(html);
matches.forEach(function(match, i) { matches.forEach(function(match, i) {
html = html.replace(new RegExp(tab + i + tab, 'gi'), match); html = html.replace(new RegExp(tab + i + tab), match);
}); });
html = html.replace(/\n\n/g, '<br/><br/>'); html = html.replace(/\n\n/g, '<br/><br/>');
// close extra opening (and remove extra closing) tags // close extra opening (and remove extra closing) tags

View file

@ -42,7 +42,7 @@ Ox.doc <f> Generates documentation for annotated JavaScript
Ox.doc = (function() { Ox.doc = (function() {
// fixme: dont require the trailing '@' // fixme: dont require the trailing '@'
var re = { var re = {
item: /^(.+?) <(.+?)>(.*?)$/, item: /^(.+?) <(.+?)> (.+?)$/,
multiline: /^\/\*\@.*?\n([\w\W]+)\n.*?\@\*\/$/, multiline: /^\/\*\@.*?\n([\w\W]+)\n.*?\@\*\/$/,
script: /\n(\s*<script>s*\n[\w\W]+\n\s*<\/script>s*)/g, script: /\n(\s*<script>s*\n[\w\W]+\n\s*<\/script>s*)/g,
singleline: /^\/\/@\s*(.*?)\s*$/, singleline: /^\/\/@\s*(.*?)\s*$/,

View file

@ -3,9 +3,10 @@
/*@ /*@
Ox.asinh <f> Inverse hyperbolic sine Ox.asinh <f> Inverse hyperbolic sine
Missing from <code>Math</code>. Missing from <code>Math</code>.
> Ox.asinh(0)
0
@*/ @*/
Ox.asinh = function(x) { Ox.asinh = function(x) {
// fixme: no test
return Math.log(x + Math.sqrt(x * x + 1)); return Math.log(x + Math.sqrt(x * x + 1));
}; };
@ -137,8 +138,9 @@ Ox.round = function(num, dec) {
/*@ /*@
Ox.sinh <f> Hyperbolic sine Ox.sinh <f> Hyperbolic sine
Missing from <code>Math</code>. Missing from <code>Math</code>.
> Ox.sinh(0)
0
@*/ @*/
Ox.sinh = function(x) { Ox.sinh = function(x) {
// fixme: no test
return (Math.exp(x) - Math.exp(-x)) / 2; return (Math.exp(x) - Math.exp(-x)) / 2;
}; };

View file

@ -27,29 +27,51 @@ Ox.get = function(url, callback) {
/*@ /*@
Ox.getJSON <f> Get and parse one or more remote JSON files Ox.getJSON <f> Get and parse one or more remote JSON files
# fixme: remote? same-origin-policy? jsonp? # fixme: remote? same-origin-policy?
(url, callback) -> <u> undefined (url, callback) -> <u> undefined
url <s|[s]> One or more remote URLs url <s|[s]> One or more remote URLs
callback <f> Callback function callback <f> Callback function
data <o> The parsed contents of the remote resource(s) data <o> The parsed contents of the remote resource(s)
For multiple URLs, keys are file names, values are contents For multiple URLs, keys are file names, values are contents
@*/ @*/
Ox.getJSON = (function() { Ox.getJSON = function(url, callback) {
function getJSON(url, callback) { var urls = Ox.makeArray(url);
Ox.loadAsync(urls, function(url, callback) {
Ox.get(url, function(data) { Ox.get(url, function(data) {
callback(JSON.parse(data)); var result = {};
result[url] = JSON.parse(data);
callback(result);
});
}, function(results) {
callback(urls.length == 1 ? results[url] : results);
}); });
} }
return function(url, callback) {
var urls = Ox.makeArray(url), data = {}, i = 0, n = urls.length; /*@
urls.forEach(function(url) { Ox.getJSONP <f> Get and parse one or more remote JSONP files
getJSON(url, function(data_) { (url, callback) -> <u> undefined
data[url] = data_; url <s|[s]> One or more remote URLs,
++i == n && callback(n == 1 ? data[url] : data); {callback} gets replaced with jsonp callback function name
callback <f> Callback function
data <o> The parsed contents of the remote resource(s)
For multiple URLs, keys are file names, values are contents
@*/
Ox.getJSONP = function(url, callback) {
var urls = Ox.makeArray(url);
Ox.loadAsync(urls, function(url, callback) {
var id = 'callback' + Ox.uid();
Ox.getJSONP[id] = function(data) {
delete Ox.getJSONP[id];
callback(data);
}
Ox.$('body').append(Ox.$('<script>').attr({
'src': url.replace('{callback}', 'Ox.getJSONP.' + id),
'type': 'text/javascript'
}));
}, function(results) {
callback(urls.length == 1 ? results[url] : results);
}); });
}); }
};
}());
/*@ /*@
Ox.getJSONC <f> Get and parse a remote JSONC file Ox.getJSONC <f> Get and parse a remote JSONC file
@ -77,9 +99,16 @@ Ox.loadFile <f> Loads a file (image, script or stylesheet)
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?
// fixme: what about array of files?
var cache = {}; var cache = {};
return function (file, callback) { return function(files, callback) {
Ox.loadAsync(files, function(file, callback) {
loadFile(file, function(images) {
callback(images ? {file: images} : {});
});
}, callback);
}
function loadFile(file, callback) {
var element, var element,
head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
request, request,
@ -152,35 +181,31 @@ Ox.loadFile = (function() {
}()); }());
/*@ /*@
Ox.loadFiles <f> Loads multiple files (images, scripts or stylesheets) Ox.loadAsync <f> run map function on all array items and call callback with results
(files, callback) -> <u> undefined (arr, map, callback) -> <u> undefined
files <[s]|[[s]]> Array of files, or array of arrays of files arr <s|[s]|[[s]]> string, Array of strins, or array of arrays of strings
Multiple files in the same array will be loaded simultaneously, but Multiple strings in the same array will be processed simultaneously, but
multiple arrays of files will be loaded in that order. multiple arrays of strings will be processed in that order.
callback <f> Callback function callback <f> Callback function
images <o> DOM elements (if any file was an image) results <o> result
Keys are the file names, values are the DOM elements
@*/ @*/
Ox.loadFiles = (function() { Ox.loadAsync = function(arr, map, callback) {
function loadFiles(files, callback) { arr = Ox.makeArray(arr);
files = Ox.makeArray(files); var i = 0, n = arr.length, results = {};
var i = 0, n = files.length, images = {}; if(arr.some(Ox.isArray)) {
Ox.makeArray(files).forEach(function(file) { iterate();
Ox.loadFile(file, function(image) { } else {
if (image) { arr.forEach(function(item) {
images[file] = image; map(item, function(result) {
} Ox.extend(results, result);
++i == n && callback(images); ++i == n && callback(results);
}); });
}); });
} }
return function(files, callback) { function iterate() {
var i = 0, n = files.length, images = {}; Ox.loadAsync(arr.shift(), function(result) {
files.forEach(function(file) { Ox.extend(results, result);
loadFiles(file, function(images_) { arr.length ? iterate() : callback(results);
Ox.extend(images, images_)
++i == n && callback(Ox.len(images) ? images : void 0);
});
}); });
}
}; };
}());