diff --git a/demos/doc/deleteme.html b/demos/doc/deleteme.html index 32453d74..8355b563 100644 --- a/demos/doc/deleteme.html +++ b/demos/doc/deleteme.html @@ -1,122 +1,18 @@ - + + + - - - - - - - -
Ox.foo<foo>foo
- - - - -
- Usage
- - - - - - - - - - - - - -
- Ox.foo(foo)returns<foo>foo
- Ox.foo(foo, bar)returns<foobar>foobar
- - - - -
- Arguments
- - - - - - - - - - - - - - - - -
- foo<foo>foo
- - - - -
- Properties
- - - - - - - - - - - - - - - - - - -
- foo<foo>foo
- - - - -
- Properties
- - - - - - - - - - - - - - -
- foo<foo>foo
- foobar<foobar>foobar
-
- foobar<foobar>foobar
-
- foobar<foobar>foobar
- - + \ No newline at end of file diff --git a/source/Ox.UI/js/Core/Ox.DocPage.js b/source/Ox.UI/js/Core/Ox.DocPage.js index 5bbe6012..d5d06a47 100644 --- a/source/Ox.UI/js/Core/Ox.DocPage.js +++ b/source/Ox.UI/js/Core/Ox.DocPage.js @@ -8,10 +8,12 @@ Ox.DocPage = function(options, self) { .options(options || {}) .addClass('OxText') .css({ - width: '640px' + width: '640px', + height: '400px', + overflow: 'auto' }); - $('body').css('overflowY', 'auto') + $('body').css('overflowY', 'scroll') that.append($('

').append('' + self.options.doc.name + '')); @@ -85,12 +87,12 @@ Ox.DocPage = function(options, self) { .addClass(className) .css({marginLeft: ((level * 32 + 32) + 'px')}) .html( - '> ' + + '> ' + Ox.encodeHTML(example.statement) //example.statement .replace(/ /g, ' ') .replace(/\n/g, '
\n  ') + - '
' + '
' ) ); example.result && $elements.push($('
') diff --git a/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js b/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js index 155c9a49..d8afb691 100644 --- a/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js +++ b/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js @@ -35,6 +35,8 @@ Ox.SyntaxHighlighter = function(options, self) { .replace(/\r\n/g, '\n') .replace(/\r/g, '\n'); + //self.options.source = Ox.minify(self.options.source); + self.cursor = 0; self.source = ''; self.tokens = Ox.tokenize(self.options.source); diff --git a/source/Ox.UI/js/Map/Ox.Map.js b/source/Ox.UI/js/Map/Ox.Map.js index 02938071..4ca1a62f 100644 --- a/source/Ox.UI/js/Map/Ox.Map.js +++ b/source/Ox.UI/js/Map/Ox.Map.js @@ -90,7 +90,7 @@ Ox.Map = function(options, self) { var that = new Ox.Element({}, self) .defaults({ // fixme: isClickable? hasZoombar? - clickable: false, + clickable: false, editable: false, findPlaceholder: 'Find', labels: false, diff --git a/source/Ox.js b/source/Ox.js index 36e95922..86996197 100644 --- a/source/Ox.js +++ b/source/Ox.js @@ -10,7 +10,7 @@ Ox The Ox object See Ox.wrap for details. (value) -> wrapped value - value <*> any value + value <*> Any value @*/ Ox = function(val) { @@ -28,6 +28,7 @@ Ox.AMPM = ['AM', 'PM']; //@ Ox.DURATIONS <[str]> ['year', 'month', 'day', 'minute', 'second'] Ox.DURATIONS = ['year', 'month', 'day', 'minute', 'second']; //@ Ox.EARTH_RADIUS Radius of the earth in meters +// see http://en.wikipedia.org/wiki/WGS-84 Ox.EARTH_RADIUS = 6378137; //@ Ox.EARTH_CIRCUMFERENCE Circumference of the earth in meters Ox.EARTH_CIRCUMFERENCE = Ox.EARTH_RADIUS * 2 * Math.PI; @@ -36,8 +37,8 @@ Ox.HTML_ENTITIES = { '"': '"', '&': '&', "'": ''', '<': '<', '>': '>' }; //@ Ox.KEYS Names for key codes -// the dot notation ('0.numpad') allows for namespaced events ('key_0.numpad'), -// so that binding to 'key_0' will catch 'key0.numpad' too +// The dot notation ('0.numpad') allows for namespaced events ('key_0.numpad'), +// so that binding to 'key_0' will catch both 'key_0' and 'key_0.numpad'. Ox.KEYS = { 0: 'section', 8: 'backspace', 9: 'tab', 12: 'clear', 13: 'enter', 16: 'shift', 17: 'control', 18: 'alt', 20: 'capslock', 27: 'escape', @@ -209,7 +210,9 @@ Ox.doc = (function() { lastItem.properties = lastItem.properties || []; lastItem.properties.push(item); // include leading linebreaks and whitespace - lastItem.source = Ox.merge(lastItem.source, parseTokens(tokens[i], true)); + lastItem.source = Ox.merge( + lastItem.source, parseTokens(tokens[i], true) + ); } }); function decodeLinebreaks(match, submatch) { @@ -361,9 +364,9 @@ Ox.doc = (function() { return Ox.startsWith(type, unwrapped); })).length ) { - ret.types.push(wrap(type[0])) + ret.types.push(wrap(type[0])); } else { - ret.default = str; + ret['default'] = str; } }); function unwrap(str) { @@ -371,7 +374,8 @@ Ox.doc = (function() { str = str.substr(1, str.length - 2) : str; } function wrap(str) { - return isArray ? '[' + str + ']' : str; + return isArray ? + 'array[' + str + (str != 'any' ? 's' : '') + ']' : str; } return ret; } @@ -506,9 +510,12 @@ Ox.loadFile = (function() { element.src = file; } else { if (!findFileInHead()) { - element = document.createElement(type == 'css' ? 'link' : 'script'); + element = document.createElement( + type == 'css' ? 'link' : 'script' + ); element[type == 'css' ? 'href' : 'src'] = file; - element.type = type == 'css' ? 'text/css' : 'text/javascript'; + element.type = type == 'css' ? + 'text/css' : 'text/javascript'; if (type == 'css') { element.rel = 'stylesheet'; waitForCSS(); @@ -573,7 +580,8 @@ Ox.print = function() { date = new Date(); args.unshift( Ox.formatDate(date, '%H:%M:%S.') + (+date).toString().substr(-3), - arguments.callee.caller.name || '(anonymous)' + (arguments.callee.caller && arguments.callee.caller.name) || + '(anonymous)' ); window.console && window.console.log.apply(window.console, args); return args.join(' '); @@ -599,7 +607,7 @@ Ox.wrap Wraps a value so that one can directly call any Ox function on it (value) -> wrapped value chain wrap the return value to allow chaining value unwrap the value wrapped by chain() - value <*> any value + value <*> Any value > Ox.wrap("foobar").repeat(2) "foobarfoobar" > Ox.wrap("foobar").chain().reverse().toTitleCase().value() @@ -728,7 +736,7 @@ Ox.every = function(obj, fn) { Ox.extend = function() { /* >>> Ox.extend({a: 1, b: 1, c: 1}, {b: 2, c: 2}, {c: 3}).c - 3 + {"a":1,"b":2,"c":3} */ var obj = arguments[0]; Ox.forEach(Array.prototype.slice.call(arguments, 1), function(arg, i) { @@ -745,9 +753,9 @@ Ox.filter = function(obj, fn) { >>> Ox.filter([2, 1, 0], function(v, i) { return v == i; }) [1] >>> Ox.keys(Ox.filter({a: 'c', b: 'b', c: 'a'}, function(v, k) { return v == k; })) - ['b'] - >>> Ox.filter(' hello world ', function(v) { return v != ' '; }) - 'helloworld' + ["b"] + >>> Ox.filter(' foo bar ', function(v) { return v != ' '; }) + "foobar" ***/ var type = Ox.typeOf(obj), ret = type == 'array' ? [] : type == 'object' ? {} : ''; @@ -816,20 +824,14 @@ Ox.forEach forEach loop callback Callback function value <*> Value key Key + > var string = ""; + > Ox.forEach(["f", "o", "o"], function(v, i) { string += i; }) + > Ox.forEach({a: "f", b: "o", c: "o"}, function(v, k) { string += k; }) + > Ox.forEach("foo", function(v) { string += v; }) + > string + "012abcfoo" @*/ Ox.forEach = function(obj, fn) { - /* - Ox.forEach() works for arrays, objects and strings, - like $.each(), unlike [].forEach() - The arguments of the iterator function are (value, key), - like [].forEach(), unlike $.each() - >>> Ox.forEach('foo', function(v, i) {}) - 'foo' - >>> Ox.forEach([0, 1, 2], function(v, i) {}) - [0, 1, 2] - >>> Ox.forEach({a: 1, b: 2, c: 3}, function(v, k) {}).a - 1 - */ var isObject = Ox.isObject(obj), key; for (key in obj) { key = isObject ? key : parseInt(key); @@ -888,8 +890,12 @@ Ox.isEqual = function(obj0, obj1) { true >>> Ox.isEqual({a: 1, b: [2, 3], c: {d: '4'}}, {a: 1, b: [2, 3], c: {d: '4'}}) true - >>> Ox.isEqual(function(arg) { return arg; }, function(arg) { return arg; }); + >>> Ox.isEqual({a: 1, b: 2, c: 3}, {c: 3, b: 2, a: 1}) + true // FIXME: is false + >>> Ox.isEqual(function(arg) { return arg; }, function(arg) { return arg; }) true + >>> Ox.isEqual(function(foo) { return foo; }, function(bar) { return bar; }) + false */ var ret = false; if (obj0 === obj1) { @@ -967,25 +973,59 @@ Ox.len = function(obj) { return Ox.isObject(obj) ? Ox.values(obj).length : obj.length; }; +/*@ +Ox.loop For-loop, functional-style + Returning false from the iterater function acts like a + break statement. Unlike a for loop, + Ox.loop doesn't leak its counter variable to the outer scope, + but returns it. + (stop, callback) -> Next value + equivalent to for (var i = 0; i < stop; i++) + (start, stop, callback) -> Next value + equivalent to for (var i = start; i < stop; i++) or, + if start is larger than stop, + for (var i = start; i > stop; i--) + (start, stop, step) -> Next value + equivalent to for (var i = start; i < stop; i += step) + start Start value + stop Stop value (exclusive) + step Step value + callback Iterator function + i Counter value + > Ox.loop(0, 3, 2, function() {}) + 4 + > Ox.loop(10, function(i) { return i != 4; }) + 4 +@*/ Ox.loop = function() { var length = arguments.length, - fn = arguments[length - 1], - step = length == 4 ? arguments[2] : 1, - stop = arguments[length > 2 ? 1 : 0], start = length > 2 ? arguments[0] : 0, + stop = arguments[length > 2 ? 1 : 0], + step = length == 4 ? arguments[2] : (start <= stop ? 1 : -1), + callback = arguments[length - 1], i; - for (i = start; i < stop; i += step) { - fn(i); + for (i = start; step > 0 ? i < stop : i > stop; i += step) { + if (callback(i) === false) { + break; + }; } + return i; }; -Ox.makeArray = function(obj) { - /* - >>> (function() { return Ox.makeArray(arguments); }('foo', 'bar')) - ['foo', 'bar'] - */ - return Array.prototype.slice.call(obj); -}; +/*@ +Ox.makeArray Takes an array-like object and returns a true array + Alias for Array.prototype.slice.call + (value) -> True array + value <*> Array-like object + > (function() { return Ox.makeArray(arguments); }("foo", "bar")) + ["foo", "bar"] + > Ox.makeArray("foo") + ["f", "o", "o"] + > Ox.makeArray({0: "f", 1: "o", 2: "0", length: 3}) + ["f", "o", "o"] +@*/ + +Ox.makeArray = Array.prototype.slice.call; Ox.makeObject = function(obj) { /* @@ -1066,22 +1106,38 @@ Ox.merge = function(arr) { return arr; }; -Ox.range = function(start, stop, step) { - /* - >>> Ox.range(3) +/*@ +Ox.range Python-style range + (stop) -> <[n]> range + Returns an array of integers from 0 (inclusive) to + stop (exclusive). + (start, stop) -> <[n]> range + Returns an array of integers from start (inclusive) to + stop (exclusive). + (start, stop, step) -> <[n]> range + Returns an array of numbers from start (inclusive) to + stop (exclusive), incrementing by step. + start Start value + stop Stop value + step Step value + > Ox.range(3) [0, 1, 2] - >>> Ox.range(3, 0) + > Ox.range(1, 4) + [1, 2, 3] + > Ox.range(3, 0) [3, 2, 1] - >>> Ox.range(1, 2, 0.5) + > Ox.range(1, 2, 0.5) [1, 1.5] - */ - stop = arguments.length > 1 ? stop : arguments[0]; - start = arguments.length > 1 ? start : 0; - step = step || (start <= stop ? 1 : -1); - var arr = [], i; - for (i = start; step > 0 ? i < stop : i > stop; i += step) { + > Ox.range(-1, -2, -0.5) + [-1, -1.5] +@*/ +Ox.range = function() { + var args = Ox.makeArray(arguments), + arr = []; + args.push(function(i) { arr.push(i); - } + }); + Ox.loop.apply(null, args); return arr; }; @@ -2084,13 +2140,18 @@ Encoding functions } } + /*@ + Ox.encodeUTF8 Encodes a string as UTF-8 + see http://en.wikipedia.org/wiki/UTF-8 + (string) -> UTF-8 encoded string + string Any string + > Ox.encodeUTF8("foo") + "foo" + > Ox.encodeUTF8("¥€$") + "\u00C2\u00A5\u00E2\u0082\u00AC\u0024" + @*/ Ox.encodeUTF8 = function(str) { /* - see http://en.wikipedia.org/wiki/UTF-8 - >>> Ox.encodeUTF8('foo') - 'foo' - >>> Ox.encodeUTF8('¥€$') - '\u00C2\u00A5\u00E2\u0082\u00AC\u0024' */ return Ox.map(str, function(chr) { var code = chr.charCodeAt(0), @@ -2109,12 +2170,18 @@ Encoding functions }).join(''); } + /*@ + Ox.decodeUTF8 Decodes an UTF-8-encoded string + see http://en.wikipedia.org/wiki/UTF-8 + (utf8) -> string + utf8 Any UTF-8-encoded string + > Ox.decodeUTF8('foo') + 'foo' + > Ox.decodeUTF8('\u00C2\u00A5\u00E2\u0082\u00AC\u0024') + '¥€$' + @*/ Ox.decodeUTF8 = function(str) { /* - >>> Ox.decodeUTF8('foo') - 'foo' - >>> Ox.decodeUTF8('\u00C2\u00A5\u00E2\u0082\u00AC\u0024') - '¥€$' */ var bytes = Ox.map(str, function(v) { return v.charCodeAt(0); @@ -3208,6 +3275,49 @@ Ox.toDashes = function(str) { }); }; +Ox.minify = function(source) { + var tokens = Ox.tokenize(source) + return Ox.map(tokens, function(token, i) { + var ret = source.substr(token.offset, token.type == 'whitespace' ? 1 : token.length); + if (token.type == 'comment') { + ret = null; + } else if ( + token.type == 'linebreak' && ( + i == 0 || i == tokens.length - 1 || + tokens[i - 1].type == 'linebreak' || + tokens[i + 1].type == 'linebreak' + ) + ) { + ret = null; + } else if ( + token.type == 'whitespace' && ( + i == 0 || i == tokens.length - 1 || + tokens[i - 1].type != 'keyword' || ( + tokens[i + 1].type == 'operator' + ) + ) + ) { + ret = null; + } + return ret; + }).join(''); +}; + +/*@ +Ox.tokenize Tokenizes JavaScript + (source) -> <[o]> Array of tokens + length Length of the token + offset Offset of the token + type Type of the token + Type can be "comment", "constant", + "identifier", "keyword", + "linebreak", "method", + "number", "object", + "operator", "property", + "regexp", "string" + or "whitespace" + source JavaScript source code +@*/ Ox.tokenize = (function() { // see https://github.com/mozilla/narcissus/blob/master/lib/jslex.js @@ -3657,113 +3767,161 @@ Type functions ================================================================================ */ -Ox.isArguments = function(val) { - /* - >>> Ox.isArguments((function() { return arguments; }())) +/*@ +Ox.isArguments Tests if a value is an arguments "array" + (value) -> True if the value is an arguments "array" + value <*> Any value + > Ox.isArguments((function() { return arguments; }())) true - */ +@*/ +Ox.isArguments = function(val) { return !!(val && val.toString() == '[object Arguments]'); } -Ox.isArray = function(val) { // is in jQuery - /* - >>> Ox.isArray([]) +/*@ +Ox.isArray Tests if a value is an array + (value) -> True if the value is a date + value <*> Any value + > Ox.isArray([]) true - */ + > Ox.isArray((function() { return arguments; }())) + false + > Ox.isArray({0: 0, length: 1}) + false +@*/ +Ox.isArray = function(val) { return val instanceof Array; } -Ox.isBoolean = function(val) { - /* - >>> Ox.isBoolean(false) +/*@ +Ox.isBoolean Tests if a value is boolean + (value) -> True if the value is boolean + value <*> Any value + > Ox.isBoolean(false) true - */ +@*/ +Ox.isBoolean = function(val) { return typeof val == 'boolean'; }; -Ox.isDate = function(val) { - /* - >>> Ox.isDate(new Date()) +/*@ +Ox.isDate Tests if a value is a date + (value) -> True if the value is a date + value <*> Any value + > Ox.isDate(new Date()) true - */ +@*/ +Ox.isDate = function(val) { return val instanceof Date; }; -Ox.isElement = function(val) { - /* - >>> Ox.isElement(document.createElement()) +/*@ +Ox.isElement Tests if a value is a DOM element + (value) -> True if the value is a DOM element + value <*> Any value + > Ox.isElement(document.createElement()) true - */ +@*/ +Ox.isElement = function(val) { return !!(val && val.nodeType == 1); }; -Ox.isFunction = function(val) { // is in jQuery - /* - >>> Ox.isFunction(function() {}) +/*@ +Ox.isFunction Tests if a value is a function + (value) -> True if the value is a function + value <*> Any value + > Ox.isFunction(function() {}) true - >>> Ox.isFunction(/ /) + > Ox.isFunction(/ /) false - */ +@*/ +Ox.isFunction = function(val) { // is in jQuery return typeof val == 'function' && !Ox.isRegExp(val); }; -Ox.isInfinity = function(val) { - /* - >>> Ox.isInfinity(Infinity) +/*@ +Ox.isInfinity Tests if a value is infinite + (value) -> True if the value is infinite + value <*> Any value + > Ox.isInfinity(Infinity) true - >>> Ox.isInfinity(-Infinity) + > Ox.isInfinity(-Infinity) true - >>> Ox.isInfinity(NaN) + > Ox.isInfinity(NaN) false - */ +@*/ +Ox.isInfinity = function(val) { return typeof val == 'number' && !isFinite(val) && !Ox.isNaN(val); }; -Ox.isNaN = function(val) { - /* - >>> Ox.isNaN(NaN) +/*@ +Ox.isNaN Tests if a value is "Not a Number" + (value) -> True if the value is "Not a Number" + value <*> Any value + > Ox.isNaN(NaN) true - */ +@*/ + +Ox.isNaN = function(val) { return val !== val; } -Ox.isNull = function(val) { - /* - >>> Ox.isNull(null) +/*@ +Ox.isNull Tests if a value is null + (value) -> True if the value is null + value <*> Any value + > Ox.isNull(null) true - */ +@*/ +Ox.isNull = function(val) { return val === null; }; -Ox.isNumber = function(val) { - /* - >>> Ox.isNumber(0) +/*@ +Ox.isNumber Tests if a value is a number + (value) -> True if the value is a number + value <*> Any value + > Ox.isNumber(0) true - >>> Ox.isNumber(Infinity) + > Ox.isNumber(Infinity) false - >>> Ox.isNumber(-Infinity) + > Ox.isNumber(-Infinity) false - >>> Ox.isNumber(NaN) + > Ox.isNumber(NaN) false - */ +@*/ + +Ox.isNumber = function(val) { return typeof val == 'number' && isFinite(val); }; -Ox.isObject = function(val) { - /* - >>> Ox.isObject({}) +/*@ +Ox.isObject Tests if a value is a an object + (value) -> True if the value is an object + value <*> Any value + > Ox.isObject({}) true - >>> Ox.isObject([]) + > Ox.isObject([]) false - >>> Ox.isObject(new Date()) + > Ox.isObject(new Date()) false - >>> Ox.isObject(null) + > Ox.isObject(null) false - */ +@*/ + +Ox.isObject = function(val) { return typeof val == 'object' && !Ox.isArguments(val) && !Ox.isArray(val) && !Ox.isDate(val) && !Ox.isNull(val); }; +/*@ +Ox.isRegExp Tests if a value is a regular expression + (value) -> True if the value is a regular expression + value <*> Any value + > Ox.isRegExp(/ /) + true +@*/ + Ox.isRegExp = function(val) { /* >>> Ox.isRegExp(/ /) @@ -3772,24 +3930,28 @@ Ox.isRegExp = function(val) { return val instanceof RegExp; }; -Ox.isString = function(val) { - /* - >>> Ox.isString('') +/*@ +Ox.isString Tests if a value is a string + (value) -> True if the value is a string + value <*> Any value + > Ox.isString('') true - */ +@*/ + +Ox.isString = function(val) { return typeof val == 'string'; }; /*@ Ox.isUndefined Tests if a value is undefined - (value) -> If true, the value is undefined - value <*> any value + (value) -> True if the value is undefined + value <*> Any value > Ox.isUndefined() true @*/ Ox.isUndefined = function(val) { - // fixme: void 0 is also nice + // fixme: val === void 0 is also nice return typeof val == 'undefined'; };