better layout for documentation pages, use syntax highlighter

This commit is contained in:
rolux 2011-05-07 23:07:53 +02:00
parent f5f19c1c11
commit a1ed6a44c5
7 changed files with 121 additions and 115 deletions

View file

@ -1442,20 +1442,18 @@ SyntaxHightlighter
================================================================================ ================================================================================
*/ */
.OxSyntaxHighlighter {
position: absolute;
overflow: auto;
}
.OxSyntaxHighlighter > div { .OxSyntaxHighlighter > div {
position: absolute;
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console; font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
line-height: 14px; //line-height: 14px;
} }
.OxSyntaxHighlighter > .OxLineNumbers { .OxSyntaxHighlighter > .OxLineNumbers {
padding: 4px;
text-align: right; text-align: right;
-moz-user-select: none;
-webkit-user-select: none;
} }
.OxSyntaxHighlighter > .OxSourceCode { .OxSyntaxHighlighter > .OxSourceCode {
//display: table-cell; padding: 4px;
-moz-user-select: text; -moz-user-select: text;
-webkit-user-select: text; -webkit-user-select: text;
} }

View file

@ -11,12 +11,14 @@ Ox.DocPage = function(options, self) {
overflow: 'auto' overflow: 'auto'
}); });
that.append($('<h1>') that.append(
.css({ $('<h1>')
marginTop: 0, .css({
WebkitMarginBefore: 0 marginTop: 0,
}) WebkitMarginBefore: 0
.append('<code>' + self.options.item.name + '</code>')); })
.html('<code>' + self.options.item.name + '</code>')
);
getItem(self.options.item, 0).forEach(function($element) { getItem(self.options.item, 0).forEach(function($element) {
that.append($element); that.append($element);
@ -24,7 +26,7 @@ Ox.DocPage = function(options, self) {
function getItem(item, level, name) { function getItem(item, level, name) {
var $elements = [$('<div>') var $elements = [$('<div>')
.css({paddingLeft: ((level * 32) + 'px')}) .css({paddingLeft: (level ? level * 32 - 16 : 0) + 'px'})
.html( .html(
'<code><b>' + (name || item.name) + '</b> ' + '<code><b>' + (name || item.name) + '</b> ' +
'&lt;' + item.types.join('&gt;</code> or <code>&lt;') + '&gt; </code>' + '&lt;' + item.types.join('&gt;</code> or <code>&lt;') + '&gt; </code>' +
@ -33,18 +35,24 @@ Ox.DocPage = function(options, self) {
) )
]; ];
[ [
'description', 'usage', 'arguments', 'properties', 'events', 'examples', 'source' 'description', 'usage', 'arguments', 'properties',
'events', 'examples', 'source'
].forEach(function(section) { ].forEach(function(section) {
var className = 'OxLine' + Ox.uid(); var className = 'OxLine' + Ox.uid();
if (item[section]) { if (item[section]) {
if (section == 'description') { if (section == 'description') {
$elements.push($('<div>') $elements.push($('<div>')
.css({paddingLeft: ((level * 32 + 16) + 'px')}) .css({paddingLeft: (level * 32) + 'px'})
.html(item.description) .html(item.description)
); );
} else { } else {
$elements.push($('<div>') $elements.push($('<div>')
.css({paddingLeft: ((level * 32 + 16) + 'px')}) .css({
paddingTop: (level ? 0 : 8) + 'px',
borderTop: level ? '': '1px solid rgb(192, 192, 192)',
marginTop: (level ? 0 : 8) + 'px',
marginLeft: (level * 32) + 'px',
})
.append( .append(
$('<img>') $('<img>')
.attr({src: Ox.UI.getImagePath('symbolDown.svg')}) .attr({src: Ox.UI.getImagePath('symbolDown.svg')})
@ -87,7 +95,7 @@ Ox.DocPage = function(options, self) {
item.examples.forEach(function(example) { item.examples.forEach(function(example) {
$elements.push($('<div>') $elements.push($('<div>')
.addClass(className) .addClass(className)
.css({marginLeft: ((level * 32 + 32) + 'px')}) .css({marginLeft: (level * 32 + 16) + 'px'})
.html( .html(
'<code><b>&gt;&nbsp;' + '<code><b>&gt;&nbsp;' +
Ox.encodeHTML(example.statement) Ox.encodeHTML(example.statement)
@ -98,26 +106,35 @@ Ox.DocPage = function(options, self) {
); );
example.result && $elements.push($('<div>') example.result && $elements.push($('<div>')
.addClass(className) .addClass(className)
.css({marginLeft: ((level * 32 + 32) + 'px')}) .css({marginLeft: (level * 32 + 16) + 'px'})
.html( .html(
'<code>' + Ox.parseHTML(example.result) + '</code>' '<code>' + Ox.parseHTML(example.result) + '</code>'
) )
) )
}); });
} else if (section == 'source') { } else if (section == 'source') {
var html = ''; // fixme: not the right place to fix path
item.source.forEach(function(token) {
html += '<span class="Ox' + Ox.toTitleCase(token.type) + '">' +
Ox.encodeHTML(token.source)
.replace(/ /g, '&nbsp;')
.replace(/\n/g, '<br/>') +
'</span>';
});
$elements.push($('<div>') $elements.push($('<div>')
.addClass('OxSourceCode ' + className) .addClass(className)
.css({background: 'rgb(255, 255, 255)', padding: '4px'}) .css({marginLeft: 16 + 'px'})
.css({marginLeft: ((level * 32 + 32) + 'px')}) .html(
.html('<code>' + html + '</code>') '<code><b>' + self.options.item.file.replace(Ox.PATH, '') +
'</b> line ' + self.options.item.line + '</code>'
)
);
$elements.push(
Ox.SyntaxHighlighter({
// fixme: silly
source: item.source.map(function(token) {
return token.source;
}).join(''),
offset: self.options.item.line
})
.addClass(className)
.css({
border: '1px solid rgb(192, 192, 192)',
marginTop: '8px',
})
); );
} else { } else {
item[section].forEach(function(v) { item[section].forEach(function(v) {

View file

@ -12,21 +12,6 @@ Ox.Element <function:Ox.JQueryElement> Basic UI element object
tooltip <object> tooltip (not implemented) tooltip <object> tooltip (not implemented)
options <string> tagname or CSS selector options <string> tagname or CSS selector
self <object> shared private variable self <object> shared private variable
# Properties ---------------------------------------------------------------
$element <object> jQuery DOM object
bindEvent <function> binds an event to a function, once
# Usage
(event, callback) -> <object> this element
({event: callback, ...}) -> <object> this element
# Arguments
event <string> event name
callback <function> callback function
data <object> event data
bindEventOnce <function> binds an event to a function
defaults <function> sets the default options
options <function> sets the options
triggerEvent <function> triggers an event
unbindEvent <function> unbinds an event
# Events ------------------------------------------------------------------- # Events -------------------------------------------------------------------
anyclick <event> anyclick anyclick <event> anyclick
fires on mouseup, but not on any subsequent mouseup within 250 ms fires on mouseup, but not on any subsequent mouseup within 250 ms
@ -231,11 +216,13 @@ Ox.Element = function() {
/*@ /*@
bindEvent <function> Binds a function to an event bindEvent <function> Binds a function to an event
(event, callback) -> <f> This element (event, callback) -> <o> This element
({event: callback, ...}) -> <f> This element ({event: callback, ...}) -> <o> This element
callback <f> Callback function callback <f> Callback function
data <o> event data (key/value pairs) data <o> event data (key/value pairs)
event <s> Event name (can be namespaced, like "click.foo") event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code>
@*/ @*/
that.bindEvent = function() { that.bindEvent = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) { Ox.forEach(Ox.makeObject(arguments), function(fn, event) {
@ -246,11 +233,12 @@ Ox.Element = function() {
/*@ /*@
bindEventOnce <function> Binds a function to an event, once bindEventOnce <function> Binds a function to an event, once
(event, callback) -> <f> This element (event, callback) -> <obj> This element object
({event: callback, ...}) -> <f> This element ({event: callback, ...}) -> <obj> This element object
callback <f> Callback function callback <f> Callback function
data <o> event data (key/value pairs) data <o> event data (key/value pairs)
event <s> Event name (can be namespaced, like "click.foo") event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code>
@*/ @*/
that.bindEventOnce = function() { that.bindEventOnce = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) { Ox.forEach(Ox.makeObject(arguments), function(fn, event) {
@ -260,11 +248,10 @@ Ox.Element = function() {
}; };
/*@ /*@
Sets the default options for an element object defaults <function> Sets the default options for an element object
({key: value, ...}) -> <f> ({key: value, ...}) -> <obj> This element object
key <str> the name of the default option key <str> The name of the default option
that <obj> the element object value <val> The value of the default option
value <val> the value of the default option
@*/ @*/
that.defaults = function(defaults) { that.defaults = function(defaults) {
// sets the default options // sets the default options
@ -274,9 +261,8 @@ Ox.Element = function() {
}; };
/*@ /*@
Makes an element object gain focus gainFocus <function> Makes an element object gain focus
() -> that () -> <obj> This element object
that <obj> the element object
@*/ @*/
that.gainFocus = function() { that.gainFocus = function() {
Ox.Focus.focus(that.id); Ox.Focus.focus(that.id);
@ -284,18 +270,16 @@ Ox.Element = function() {
}; };
/*@ /*@
Returns true if an element object has focus hasFocus <function> Returns true if an element object has focus
() -> hasFocus () -> <boolean> True if the element has focus
hasFocus <boolean> true if the element has focus
@*/ @*/
that.hasFocus = function() { that.hasFocus = function() {
return Ox.Focus.focused() == that.id; return Ox.Focus.focused() == that.id;
}; };
/*@ /*@
Makes an element object lose focus loseFocus <function> Makes an element object lose focus
() -> that () -> <object> This element object
that <object> the element object
@*/ @*/
that.loseFocus = function() { that.loseFocus = function() {
@ -304,8 +288,7 @@ Ox.Element = function() {
}; };
/*@ /*@
.options() options <function> Gets or sets the options of an element object
Gets or sets the options of an element object
# Usage # Usage
() -> <obj> all options () -> <obj> all options
(key) -> <val> the value of option[key] (key) -> <val> the value of option[key]
@ -324,10 +307,11 @@ Ox.Element = function() {
return Ox.getset(self.options, arguments, self.setOption, that); return Ox.getset(self.options, arguments, self.setOption, that);
}; };
/*@
removeElement <function> Removes an element object and its event handler
() -> <obj> This element
@*/
that.removeElement = function() { that.removeElement = function() {
/***
remove this element, including its event handler
***/
that.loseFocus(); that.loseFocus();
delete self.$eventHandler; delete self.$eventHandler;
that.remove(); that.remove();
@ -335,14 +319,15 @@ Ox.Element = function() {
return that; return that;
}; };
/*@
triggerEvent <function> Triggers an event
(event) -> <object> This element object
(event, data) -> <object> This element object
({event: data, ...}) -> <object> This element object
event <string> Event name
data <object> Event data (key/value pairs)
@*/
that.triggerEvent = function() { that.triggerEvent = function() {
/***
triggers an event
Usage
triggerEvent(event)
triggerEvent(event, data)
triggerEvent({eventA: dataA, eventB: dataB, ...})
***/
Ox.forEach(Ox.makeObject(arguments), function(data, event) { Ox.forEach(Ox.makeObject(arguments), function(data, event) {
if ([ if ([
'mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick',
@ -355,17 +340,22 @@ Ox.Element = function() {
return that; return that;
}; };
/*@
unbindEvent <function> Unbinds all callbacks from an event
To unbind a specific handler, use namespaced events, like
<code>bindEvent('click.foo', callback)</code>, and then
<code>unbindEvent('click.foo')</code>.
() -> <object> This element object
Unbinds all events
(event) -> <object> This element object
Unbinds one event
(event, event, ...) -> <object> This element object
Unbinds multiple events
([event, event, ...]) -> <object> This element object
Unbinds multiple events
event <string> Event name
@*/
that.unbindEvent = function() { that.unbindEvent = function() {
/***
unbinds an event triggered by this element
Usage
unbindEvent() // unbinds all events
unbindEvent(event)
unbindEvent(eventA, eventB, ...)
unbindEvent([eventA, eventB, ...])
to unbind a specific handler, use namespaced events
bind('doubleclick.x', fn) ... unbind('doubleclick.x')
***/
if (arguments.length == 0) { if (arguments.length == 0) {
self.$eventHandler.unbind(); self.$eventHandler.unbind();
} else { } else {

View file

@ -11,6 +11,7 @@ Ox.SyntaxHighlighter = function(options, self) {
.defaults({ .defaults({
height: 40, height: 40,
lineLength: 80, //@ number of characters per line lineLength: 80, //@ number of characters per line
offset: 1, //@ first line number
showLinebreaks: false, //@ show linebreak symbols showLinebreaks: false, //@ show linebreak symbols
showTabs: false, //@ show tab symbols showTabs: false, //@ show tab symbols
showWhitespace: false, //@ show irregular leading or trailing whitespace showWhitespace: false, //@ show irregular leading or trailing whitespace
@ -24,19 +25,10 @@ Ox.SyntaxHighlighter = function(options, self) {
.options(options || {}) .options(options || {})
.addClass('OxSyntaxHighlighter'); .addClass('OxSyntaxHighlighter');
var foo = $('<div>')
//.css({marginTop: '-1000px'})
.html(Ox.repeat('_', 80))
.appendTo(that.$element);
//alert(foo.width());
foo.remove();
self.options.source = self.options.source self.options.source = self.options.source
.replace(/\r\n/g, '\n') .replace(/\r\n/g, '\n')
.replace(/\r/g, '\n'); .replace(/\r/g, '\n');
//self.options.source = Ox.minify(self.options.source);
self.cursor = 0; self.cursor = 0;
self.source = ''; self.source = '';
self.tokens = Ox.tokenize(self.options.source); self.tokens = Ox.tokenize(self.options.source);
@ -73,7 +65,7 @@ Ox.SyntaxHighlighter = function(options, self) {
} }
}); });
self.lines = self.source.split('<br/>'); self.lines = self.source.split('<br/>');
self.lineNumbersWidth = self.lines.length.toString().length * 7 + 7; self.lineNumbersWidth = (self.lines.length + self.options.offset - 1).toString().length * 7;
self.sourceCodeWidth = 80 * 7 + ( self.sourceCodeWidth = 80 * 7 + (
self.lines.length > 40 ? Ox.UI.SCROLLBAR_SIZE : 0 self.lines.length > 40 ? Ox.UI.SCROLLBAR_SIZE : 0
); );
@ -84,28 +76,31 @@ Ox.SyntaxHighlighter = function(options, self) {
); );
that.css({ that.css({
width: self.lineNumbersWidth + self.sourceCodeWidth, //width: self.lineNumbersWidth + self.sourceCodeWidth,
height: self.height //height: self.height
}); });
self.$lineNumbers = new Ox.Element() self.$lineNumbers = new Ox.Element()
.addClass('OxLineNumbers') .addClass('OxLineNumbers')
.css({ .css({
display: 'table-cell',
width: self.lineNumbersWidth + 'px', width: self.lineNumbersWidth + 'px',
height: (self.lines.length * 14) + 'px' //height: (self.lines.length * 14) + 8 + 'px',
padding: '4px',
}) })
.html( .html(
Ox.range(self.lines.length).map(function(line) { Ox.range(self.lines.length).map(function(line) {
return (line + 1) + '&nbsp;'; return (line + self.options.offset);
}).join('<br/>') }).join('<br/>')
) )
.appendTo(that); .appendTo(that);
self.$source = new Ox.Element() self.$source = new Ox.Element()
.addClass('OxSourceCode') .addClass('OxSourceCode')
.css({ .css({
left: self.lineNumbersWidth + 'px', display: 'table-cell',
width: self.sourceCodeWidth + 'px', //width: self.sourceCodeWidth + 'px',
height: (self.lines.length * 14) + 'px' //height: (self.lines.length * 14) + 'px',
padding: '4px'
}) })
.html(self.source) .html(self.source)
.appendTo(that); .appendTo(that);

View file

@ -1,6 +1,8 @@
// vim: et:ts=4:sw=4:sts=4:ft=js // vim: et:ts=4:sw=4:sts=4:ft=js
Ox.TreeList = function(options, self) { Ox.TreeList = function(options, self) {
// fixme: expanding the last item should cause some scroll
var self = self || {}, var self = self || {},
that = new Ox.Element({}, self) that = new Ox.Element({}, self)
.defaults({ .defaults({

View file

@ -368,7 +368,7 @@ SyntaxHighlighter
================================================================================ ================================================================================
*/ */
.OxThemeClassic .OxSyntaxHighlighter .OxSourceCode { .OxThemeClassic .OxSyntaxHighlighter {
background-color: rgb(255, 255, 255); background-color: rgb(255, 255, 255);
} }
.OxThemeClassic .OxSyntaxHighlighter .OxLineNumbers { .OxThemeClassic .OxSyntaxHighlighter .OxLineNumbers {

View file

@ -116,7 +116,7 @@ Ox.wrap = function(val, chained) {
//@ Array ---------------------------------------------------------------------- //@ Array ----------------------------------------------------------------------
/*@ /*@
Ox.compact <f> Returns an array w/o <code>null</code or <code>undefined</code> Ox.compact <f> Returns an array w/o <code>null</code> or <code>undefined</code>
> Ox.compact([null,,1,,2,,3]) > Ox.compact([null,,1,,2,,3])
[1, 2, 3] [1, 2, 3]
@*/ @*/
@ -132,8 +132,8 @@ Ox.compact = function(arr) {
/*@ /*@
Ox.flatten <f> Flattens an array Ox.flatten <f> Flattens an array
> Ox.flatten([1, [2, [3], 4], 5]) > Ox.flatten([1, [2, [3], 2], 1])
[1, 2, 3, 4, 5] [1, 2, 3, 2, 1]
@*/ @*/
Ox.flatten = function(arr) { Ox.flatten = function(arr) {
// fixme: can this work for objects too? // fixme: can this work for objects too?
@ -152,8 +152,8 @@ Ox.flatten = function(arr) {
/*@ /*@
Ox.merge <f> Merges an array with one or more other arrays Ox.merge <f> Merges an array with one or more other arrays
> Ox.merge(['foo'], ['foo', 'bar'], ['bar']) > Ox.merge([1], [2, 3, 2], [1])
['foo', 'foo', 'bar', 'bar'] [1, 2, 3, 2, 1]
@*/ @*/
Ox.merge = function(arr) { Ox.merge = function(arr) {
Ox.forEach(Array.prototype.slice.call(arguments, 1), function(arg) { Ox.forEach(Array.prototype.slice.call(arguments, 1), function(arg) {
@ -1661,7 +1661,7 @@ Ox.element = function(str) {
33819 33819
> Ox.decodeBase32('?').toString() > Ox.decodeBase32('?').toString()
'NaN' 'NaN'
*/ @*/
Ox.decodeBase32 = function(str) { Ox.decodeBase32 = function(str) {
return parseInt(Ox.map(str.toUpperCase(), function(char) { return parseInt(Ox.map(str.toUpperCase(), function(char) {
var index = digits.indexOf(aliases[char] || char); var index = digits.indexOf(aliases[char] || char);
@ -3014,6 +3014,8 @@ Ox.doc = (function() {
if (/^[A-Z]/.test(item.name)) { if (/^[A-Z]/.test(item.name)) {
// main item // main item
item.source = parseTokens(tokens[i]); item.source = parseTokens(tokens[i]);
item.line = source.substr(0, item.source[0].offset)
.split('\n').length;
items.push(item); items.push(item);
} else { } else {
// property of a function item // property of a function item
@ -3428,7 +3430,9 @@ Ox.divideInt = function(num, by) {
} }
/*@ /*@
Ox.limit <f> Returns the logarithm of a given number to a given base Ox.limit <f> Limits a number by a given mininum and maximum
<code>Ox.limit(num, min, max)</code> is a shorthand for
<code>Math.min(Math.max(num, min), max)</code>
(num) -> <n> <code>num</code> (num) -> <n> <code>num</code>
(num, max) -> <n> <code>Math.max(num, max)</code> (num, max) -> <n> <code>Math.max(num, max)</code>
(num, min, max) -> <n> <code>Math.min(Math.max(num, min), max)</code> (num, min, max) -> <n> <code>Math.min(Math.max(num, min), max)</code>