From b1d171282ccbb344848970fc7eb52fcb4b68a087 Mon Sep 17 00:00:00 2001 From: rolux Date: Fri, 6 May 2011 19:40:26 +0200 Subject: [PATCH] prototype of a documentation page --- demos/doc/deleteme.html | 122 +++++++++++++ demos/doc/index.html | 10 ++ demos/doc/js/doc.js | 18 ++ source/Ox.UI/css/Ox.UI.css | 42 +++++ source/Ox.UI/js/Core/Ox.DocPage.js | 146 +++++++++++++++ source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js | 14 +- source/Ox.UI/themes/classic/css/classic.css | 30 ++-- source/Ox.js | 179 ++++++++++++------- 8 files changed, 476 insertions(+), 85 deletions(-) create mode 100644 demos/doc/deleteme.html create mode 100644 demos/doc/index.html create mode 100644 demos/doc/js/doc.js create mode 100644 source/Ox.UI/js/Core/Ox.DocPage.js diff --git a/demos/doc/deleteme.html b/demos/doc/deleteme.html new file mode 100644 index 00000000..32453d74 --- /dev/null +++ b/demos/doc/deleteme.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + +
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/demos/doc/index.html b/demos/doc/index.html new file mode 100644 index 00000000..7e3b8b03 --- /dev/null +++ b/demos/doc/index.html @@ -0,0 +1,10 @@ + + + + OxJS Doc Demo + + + + + + \ No newline at end of file diff --git a/demos/doc/js/doc.js b/demos/doc/js/doc.js new file mode 100644 index 00000000..b86dac02 --- /dev/null +++ b/demos/doc/js/doc.js @@ -0,0 +1,18 @@ +Ox.load('UI', { + debug: true, + theme: 'classic' +}, function() { + Ox.Theme('classic'); + Ox.get('../../build/Ox.js', function(source) { + var doc = Ox.doc(source); + doc.forEach(function(item) { + Ox.DocPage({doc: item}).appendTo(Ox.UI.$body); + }); + Ox.get('../../build/Ox.UI/js/Map/Ox.Map.js', function(source) { + var doc = Ox.doc(source); + doc.forEach(function(item) { + Ox.DocPage({doc: item}).appendTo(Ox.UI.$body); + }); + }); + }); +}); \ No newline at end of file diff --git a/source/Ox.UI/css/Ox.UI.css b/source/Ox.UI/css/Ox.UI.css index 7519b65f..228f3469 100644 --- a/source/Ox.UI/css/Ox.UI.css +++ b/source/Ox.UI/css/Ox.UI.css @@ -1464,6 +1464,48 @@ SyntaxHightlighter -webkit-user-select: none; } +/* +================================================================================ +Text +================================================================================ +*/ + +.OxText { + padding: 8px; + -moz-user-select: text; + -webkit-user-select: text; +} +.OxText div { + font-size: 12px; + line-height: 16px; + -moz-user-select: text; + -webkit-user-select: text; +} +.OxText code { + font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console; + color: rgb(0, 0, 128); +} +.OxText h1 { + font-weight: bold; + font-size: 16px; + line-height: 20px; +} +.OxText table { + border-spacing: 0; + //border: 1px solid red; +} +.OxText td { + padding: 0 4px 0 4px; + //border: 1px solid rgb(128, 128, 128); + vertical-align: top; +} +.OxText td:first-child { + padding-left: 0; +} +.OxText td:last-child { + padding-right: 0; +} + /* ================================================================================ Video diff --git a/source/Ox.UI/js/Core/Ox.DocPage.js b/source/Ox.UI/js/Core/Ox.DocPage.js new file mode 100644 index 00000000..a16183ff --- /dev/null +++ b/source/Ox.UI/js/Core/Ox.DocPage.js @@ -0,0 +1,146 @@ +Ox.DocPage = function(options, self) { + + self = self || {}; + var that = Ox.Element({}, self) + .defaults({ + doc: '' + }) + .options(options || {}) + .addClass('OxText') + .css({ + width: '640px' + }); + + $('body').css('overflowY', 'auto') + + that.append($('

').append('' + self.options.doc.name + '')); + + getItem(self.options.doc, 0, '').forEach(function($element) { + that.append($element); + }) + + function getItem(item, level) { + var $elements = [$('
') + .css({paddingLeft: ((level * 32) + 'px')}) + .html( + '' + item.name + ' ' + + '<' + item.types.join('> or <') + '> ' + + Ox.parseHTML(item.summary) + ) + ]; + [ + 'description', 'usage', 'arguments', 'properties', 'events', 'examples', 'source' + ].forEach(function(section) { + var className = 'OxLine' + Ox.uid(); + if (item[section]) { + if (section == 'description') { + $elements.push($('
') + .css({paddingLeft: ((level * 32 + 16) + 'px')}) + .html(item.description) + ); + } else { + $elements.push($('
') + .css({paddingLeft: ((level * 32 + 16) + 'px')}) + .append( + $('') + .attr({src: Ox.UI.getImagePath('symbolDown.svg')}) + .css({ + width: '12px', + height: '12px', + margin: '0 4px -1px 0' + }) + .click(function() { + var $this = $(this), + isExpanded = $this.attr('src') == Ox.UI.getImagePath('symbolDown.svg'); + $this.attr({ + src: isExpanded ? + Ox.UI.getImagePath('symbolRight.svg') : + Ox.UI.getImagePath('symbolDown.svg') + }); + $('.' + className).each(function() { + var $this = $(this); + $this[isExpanded ? 'addClass' : 'removeClass'](className + 'Hidden'); + if (isExpanded) { + $this.hide(); + } else { + var hidden = false; + Ox.forEach(this.className.split(' '), function(v) { + if (/Hidden$/.test(v)) { + hidden = true; + return false; + } + }); + if (!hidden) { + $this.show() + } + } + }); + }) + ) + .append('' + Ox.toTitleCase(section) + '') + ); + if (section == 'examples') { + item.examples.forEach(function(example) { + $elements.push($('
') + .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($('
') + .addClass(className) + .css({marginLeft: ((level * 32 + 32) + 'px')}) + .html( + '' + Ox.parseHTML(example.result) + '' + ) + ) + }); + } else if (section == 'source') { + var html = ''; + var flag = false; + item.source.forEach(function(token) { + if (token.type != 'linebreak' && token.type != 'whitespace') { + flag = true; + } + if (flag) { + html += '' + + Ox.encodeHTML(token.source) + .replace(/ /g, ' ') + .replace(/\n/g, '
') + + '
'; + } + }); + $elements.push($('
') + .addClass('OxSourceCode ' + className) + .css({background: 'rgb(255, 255, 255)', padding: '4px'}) + .css({marginLeft: ((level * 32 + 32) + 'px')}) + .html('' + html + '') + ); + } else { + item[section].forEach(function(v) { + if (section == 'usage') { + v.name = item.name + v.name + ' returns '; + } + $elements = Ox.merge( + $elements, + Ox.map(getItem(v, level + 1), function($element) { + return $element.addClass(className); + }) + ); + }); + } + } + } + }) + return $elements; + } + + return that; + +}; \ No newline at end of file diff --git a/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js b/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js index f8739060..155c9a49 100644 --- a/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js +++ b/source/Ox.UI/js/Core/Ox.SyntaxHighlighter.js @@ -39,7 +39,8 @@ Ox.SyntaxHighlighter = function(options, self) { self.source = ''; self.tokens = Ox.tokenize(self.options.source); self.tokens.forEach(function(token, i) { - var classNames; + var classNames, + source = self.options.source.substr(token.offset, token.length); if ( !(self.options.stripComments && token.type == 'comment') ) { @@ -52,7 +53,7 @@ Ox.SyntaxHighlighter = function(options, self) { } } self.source += '' + - encodeToken(token.source, token.type) + ''; + encodeToken(source, token.type) + ''; } self.cursor += token.length; function isAfterLinebreak() { @@ -64,7 +65,7 @@ Ox.SyntaxHighlighter = function(options, self) { self.tokens[i + 1].type == 'linebreak'; } function hasIrregularSpaces() { - return token.source.split('').reduce(function(prev, curr) { + return source.split('').reduce(function(prev, curr) { return prev + (curr == ' ' ? 1 : 0); }, 0) % self.options.tabLength; } @@ -107,11 +108,11 @@ Ox.SyntaxHighlighter = function(options, self) { .html(self.source) .appendTo(that); - function encodeToken(source, type) { + function encodeToken(source, token) { var linebreak = '
', tab = Ox.repeat(' ', self.options.tabLength); if (self.options.showLinebreaks) { - if (type == 'linebreak') { + if (token.type == 'linebreak') { linebreak = '\u21A9' + linebreak; } else { linebreak = '\u21A9' + linebreak; @@ -120,11 +121,10 @@ Ox.SyntaxHighlighter = function(options, self) { if (self.options.showTabs) { tab = '\u2192' + tab.substr(6) + ''; } - source = Ox.encodeHTML(source) + return Ox.encodeHTML(source) .replace(/ /g, ' ') .replace(/\t/g, tab) .replace(/\n/g, linebreak); - return source; } self.setOption = function() { diff --git a/source/Ox.UI/themes/classic/css/classic.css b/source/Ox.UI/themes/classic/css/classic.css index 0e21b544..a73fb217 100644 --- a/source/Ox.UI/themes/classic/css/classic.css +++ b/source/Ox.UI/themes/classic/css/classic.css @@ -375,54 +375,54 @@ SyntaxHighlighter background-color: rgb(224, 224, 224); color: rgb(128, 128, 128); } -.OxThemeClassic .OxSyntaxHighlighter .OxComment { +.OxThemeClassic .OxSourceCode .OxComment { color: rgb(128, 128, 128); font-style: italic; } -.OxThemeClassic .OxSyntaxHighlighter .OxConstant { +.OxThemeClassic .OxSourceCode .OxConstant { color: rgb(128, 0, 0); font-weight: bold; } -.OxThemeClassic .OxSyntaxHighlighter .OxIdentifier { +.OxThemeClassic .OxSourceCode .OxIdentifier { color: rgb(0, 0, 0); } -.OxThemeClassic .OxSyntaxHighlighter .OxKeyword { +.OxThemeClassic .OxSourceCode .OxKeyword { color: rgb(0, 0, 128); font-weight: bold; } -.OxThemeClassic .OxSyntaxHighlighter .OxLinebreak { +.OxThemeClassic .OxSourceCode .OxLinebreak { color: rgb(192, 192, 192); font-weight: normal; font-style: normal; } -.OxThemeClassic .OxSyntaxHighlighter .OxMethod { +.OxThemeClassic .OxSourceCode .OxMethod { color: rgb(0, 128, 128); } -.OxThemeClassic .OxSyntaxHighlighter .OxNumber { +.OxThemeClassic .OxSourceCode .OxNumber { color: rgb(128, 0, 0); } -.OxThemeClassic .OxSyntaxHighlighter .OxObject { +.OxThemeClassic .OxSourceCode .OxObject { color: rgb(0, 128, 128); font-weight: bold; } -.OxThemeClassic .OxSyntaxHighlighter .OxOperator { +.OxThemeClassic .OxSourceCode .OxOperator { color: rgb(0, 0, 128); } -.OxThemeClassic .OxSyntaxHighlighter .OxProperty { +.OxThemeClassic .OxSourceCode .OxProperty { color: rgb(0, 128, 0); font-weight: bold; } -.OxThemeClassic .OxSyntaxHighlighter .OxRegexp { +.OxThemeClassic .OxSourceCode .OxRegexp { color: rgb(128, 128, 0); } -.OxThemeClassic .OxSyntaxHighlighter .OxString { +.OxThemeClassic .OxSourceCode .OxString { color: rgb(0, 128, 0); } -.OxThemeClassic .OxSyntaxHighlighter .OxTab { +.OxThemeClassic .OxSourceCode .OxTab { color: rgb(192, 192, 192); } -.OxThemeClassic .OxSyntaxHighlighter .OxWhitespace.OxLeading, -.OxThemeClassic .OxSyntaxHighlighter .OxWhitespace.OxTrailing { +.OxThemeClassic .OxSourceCode .OxWhitespace.OxLeading, +.OxThemeClassic .OxSourceCode .OxWhitespace.OxTrailing { background: rgb(255, 128, 128); } diff --git a/source/Ox.js b/source/Ox.js index e36c0819..6d90db1c 100644 --- a/source/Ox.js +++ b/source/Ox.js @@ -1,12 +1,14 @@ // vim: et:ts=4:sw=4:sts=4:ft=js -// todo: check http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ +// OxJS (c) 2007-2011 Ox2620, dual-licensed (GPL/MIT), see oxjs.org for details + +// todo: check http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ // also see https://github.com/tlrobinson/narwhal/blob/master/lib/util.js /*@ -Ox The Ox object - See Ox.wrap for details. +Ox The Ox object + See Ox.wrap for details. (value) -> wrapped value value <*> any value @*/ @@ -51,10 +53,11 @@ Ox.KEYS = { 85: 'u', 86: 'v', 87: 'w', 88: 'x', 89: 'y', 90: 'z', // fixme: this is usually 91: window.left, 92: window.right, 93: select 91: 'meta.left', 92: 'meta.right', 93: 'meta.right', - 96: '0.numpad', 97: '1.numpad', 98: '2.numpad', 99: '3.numpad', - 100: '4.numpad', 101: '5.numpad', 102: '6.numpad', 103: '7.numpad', - 104: '8.numpad', 105: '9.numpad', 106: 'asterisk.numpad', 107: 'plus.numpad', - 109: 'minus.numpad', 108: 'enter.numpad', 110: 'dot.numpad', 111: 'slash.numpad', + 96: '0.numpad', 97: '1.numpad', 98: '2.numpad', + 99: '3.numpad', 100: '4.numpad', 101: '5.numpad', + 102: '6.numpad', 103: '7.numpad', 104: '8.numpad', 105: '9.numpad', + 106: 'asterisk.numpad', 107: 'plus.numpad', 109: 'minus.numpad', + 108: 'enter.numpad', 110: 'dot.numpad', 111: 'slash.numpad', 112: 'f1', 113: 'f2', 114: 'f3', 115: 'f4', 116: 'f5', 117: 'f6', 118: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11', 123: 'f12', 124: 'f13', 125: 'f14', 126: 'f15', 127: 'f16', @@ -89,7 +92,7 @@ Ox.PATH = Array.prototype.slice.apply( ).filter(function(element) { return /Ox\.js$/.test(element.src); })[0].src.replace('Ox.js', ''); -//@ Ox.PREFIXES ['K', 'M', 'G', 'T', 'P'] +//@ Ox.PREFIXES <[str]> ['K', 'M', 'G', 'T', 'P'] Ox.PREFIXES = ['K', 'M', 'G', 'T', 'P']; //@ Ox.SYMBOLS Unicode characters for symbols Ox.SYMBOLS = { @@ -117,7 +120,7 @@ Ox.SYMBOLS = { CLOSE: '\u2715', BALLOT: '\u2717', WINDOWS: '\u2756', EDIT: '\uF802', CLICK: '\uF803', APPLE: '\uF8FF' }; -//@ Ox.TYPES <[str]> list of types, as returned by Ox.type() +//@ Ox.TYPES <[str]> list of types, as returned by Ox.type() Ox.TYPES = [ 'Arguments', 'Array', 'Boolean', 'Date', 'Element', 'Function', 'Infinity', 'NaN', 'Null', 'Number', 'Object', 'RegExp', 'String', 'Undefined' @@ -143,13 +146,13 @@ Core functions Ox.doc Generates documentation for annotated JavaScript (source) Array of documentation objects source JavaScript source code - > Ox.doc("//@ Ox.foo bar") - [{"name": "Ox.foo", "summary": "bar", "type": "string"}] + > Ox.doc("//@ Ox.foo just some string") + [{"name": "Ox.foo", "summary": "just some string", "type": "string"}] @*/ Ox.doc = (function() { var re = { - item: /^(.+) <(.+)> (.+)$/, + item: /^(.+?) <(.+?)> (.+)$/, multiline: /^\/\*\@.*?\n([\w\W]+)\n.*?\@\*\/$/, script: /\n(\s*