/* An Ox.doc comment looks like this `//@ foo` or ``` /*@ foo bar baz *\/ ``` The syntax is simple: almost every line has the form `name summary`. If it doesn't, its meaning depends on its context. */ this.My = {}; /* If the first line of the comment doesn't match `name summary`, it is a section definition. Here, we mark a section named 'Primitives'. */ //@ Primitives //@ My.REQUEST_TIMEOUT Request timeout, in milliseconds My.REQUEST_TIMEOUT = 60000; /*@ 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; Ox.load(function() { //@ Objects /* */ /*@ My.favorites ... # Properties -------------------------------------------------------------- array My favorite array boolean My favorite boolean value date My favorite date error My favorite error function My favorite function arguments My favorite arguments htmlelement My favorite HTML element nodelist My favorite nodelist number My favorite number object My favorite object regexp My favorite regular expression string My favorite string undefined Undefined is an all-time favorite window ... other <+> ... any <*> Favorite of the day # Events ------------------------------------------------------------------- event Fires when My.favorite['function'] is called */ My.favorites = (function() { var favorites = { array: [], boolean: false, date: new Date(), error: new Error(), 'function': function() { My.triggerEvent(this, 'event'); }, arguments: (function() { return arguments; }()), htmlelement: document.createElement('a'), nodelist: document.getElementsByTagName('a'), number: 0, object: {}, regexp: new RegExp(), string: '', 'undefined': void 0, 'window': window, other: document }, keys = Object.keys(favorites); return Ox.extend(favorites, {any: favorites[keys[Ox.random(keys.length)]]}); }()); /*@ My.HTMLUtils ... replace ... 0 ... 1 replace */ My.HTMLUtils = (function() { var entities = { '"': '"', '&': '&', "'": ''', '<': '<', '>': '>' }; return { entities: entities, replace: { namedEntity: [ new RegExp('(' + Ox.values(entities).join('|') + ')', 'g'), function(match) { return Ox.keyOf(entities, match); } ], numericEntity: [ /&#([0-9A-FX]+);/gi, function(match, code) { return Ox.char( /^X/i.test(code) ? parseInt(code.slice(1), 16) : parseInt(code, 10) ); } ], } }; }()); /*@ My.defaultPlace Default place object geometry bounds .. northEast lat lng southWest lat lng types <[s]> name Localized place names short Short place name de Short German name en Short English name fr Short French name long Long place name de Long German name en Long English name fr Long French name points <[o]> Points of interest lat Latitude lng Longitude @*/ My.place = { bounds: { northEast: {lat: 0, lng: 0}, southWest: {lat: 0, lng: 0} }, name: { short: { de: 'Brüssel', en: 'Brussels', fr: 'Bruxelles' }, long: { de: 'Brüssel, Belgien', en: 'Brussels, Belgium', fr: 'Bruxelles, Belgique' } }, points: [ {lat: 0, lng: 0}, {lat: 45, lng: 90} ] }; //@ Functions /*@ (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, c) -> <[n]> Numbers from a (inclusive) to b (exclusive), growing by c */ 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 && !Ox.isObject(key)) { 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; }; }()); }); //@ Ox.load('UI', function() { var path = Ox.PATH + '../examples/documentation/js/'; Ox.print(path, '??') Ox.DocPanel({ files: 'example.js', path: path }).appendTo(Ox.$body); });