this.My = {}; //@ My.REQUEST_TIMEOUT Request timeout, in seconds My.REQUEST_TIMEOUT = 60; /*@ My.MAGIC_CONSTANT Magic constant needed for HTTP requests Please note that the value for `MAGIC_CONSTANT` is browser-dependent. */ My.MAGIC_CONSTANT = navigator.userAgent.length % 2 == 0 ? 23 : 42; /*@ My.favorites ... array My favorite array boolean My favorite boolean value date My favorite date element My favorite HTML element number My favorite number object My favorite object regexp My favorite regular expression string My favorite string */ My.favorites = { array: [], boolean: false, date: new Date(0); element: document.createElement('a'), number: 0, object: {}, regexp: new RegExp(''), string: '' }; /*@ (url[, method], callback) -> undefined url URL method Request method ('GET', 'POST', 'PUT' or 'DELETE') callback Callback function */ My.readURL = function(url, method, callback) { var request = new XMLHttpRequest(); if (arguments.length == 2) { callback = method; method = 'GET'; } request.open(method, url, true); req.onreadystatechange = function() { if (request.readyState == 4) { if (request.status == 200) { callback(request.responseText); } else { throw new Error( 'Cannot get URL "' + url + '" (Status: ' + request.status + ')' ); } } }; request.send(); }; /*@ My.isOdd Synchronously or asynchronously computes if a given number is odd (number) -> True if the number is odd (number, callback) -> undefined number Any number callback Callback function isOdd True if the number is odd ms Time it took to compute the result, in milliseconds */ My.isOdd = function(number, callback) { var time = +new Date, isOdd = !!(number % 2); if (callback) { callback(isOdd, +new Date - time); } else { return isOdd; } } /* Occasionally, you may write a function whose signature cannot be represented in `(required[, optional])` notation. For a range function — `(stop)` or `(start, stop)` or `(start, stop, step)` — the notation `([start, ]stop[, step])` would be ambigious, since you cannot call it with `(stop, step)`. */ /*@ My.range Returns a python-style range (b) -> <[n]> Integers from 0 (inclusive) to b (exclusive) (a, b) -> <[n]> Integers from a (inclusice) to b (exclusive) (a, b, x) -> <[n]> Numbers from a (inclusive) to b (exclusive), growing by x */ My.range = function() { var a = []; Ox.loop.apply(null, Ox.toArray(arguments).concat(function(i) { a.push(i); })); return a; }; /*@ My.localStorage Returns a localStorage handler for a given namespace (ns) -> storage localStorage handler () -> Returns all key:value pairs (key) -> <*> Returns one value (key, value) -> Sets one value, returns the handler ({key: value, ...}) -> Sets one or more values, returns the handler key Any string value <*> Any value that can be JSON-serialized .delete Delete method () -> Deletes all key:value pairs, returns the handler (key[, ...]) -> Deletes one or more pairs, returns the handler key Any string ns Namespace */ My.localStorage = (function() { if (!window.localStorage) { window.localStorage = {}; } return function(ns) { function storage(key, value) { var args, ret; if (arguments.length == 0) { ret = {}; Ox.forEach(localStorage, function(value, key) { if (Ox.startsWith(key, ns + '.')) { ret[key.slice(ns.length + 1)] = JSON.parse(value); } }); } else if (arguments.length == 1 && typeof key == 'string') { value = localStorage[ns + '.' + key]; ret = Ox.isUndefined(value) ? void 0 : JSON.parse(value); } else { Ox.forEach(Ox.makeObject(arguments), function(value, key) { localStorage[ns + '.' + key] = JSON.stringify(value); }); ret = this; } return ret; }; storage.delete = function() { var keys = arguments.length == 0 ? Object.keys(storage()) : Ox.toArray(arguments) keys.forEach(function(key) { delete localStorage[ns + '.' + key]; }); return storage; }; return storage; }; }();