From 6ddb29bd21ed5a2aaeceeb26ffb6f99ae1af43fd Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Thu, 2 Jun 2011 20:52:02 +0200 Subject: [PATCH] jsdoc template: Support inline paperscript tags for examples. --- .../templates/jsdoc/src/Render.js | 33 ++- .../jsdoc/static/resources/css/reference.css | 61 +++++- .../jsdoc/static/resources/js/reference.js | 197 ++++++++++-------- .../templates/jsdoc/templates/example.tmpl | 13 +- .../templates/jsdoc/templates/html.tmpl | 1 + 5 files changed, 214 insertions(+), 91 deletions(-) diff --git a/build/jsdoc-toolkit/templates/jsdoc/src/Render.js b/build/jsdoc-toolkit/templates/jsdoc/src/Render.js index dbe2cc24..99ce0c3f 100644 --- a/build/jsdoc-toolkit/templates/jsdoc/src/Render.js +++ b/build/jsdoc-toolkit/templates/jsdoc/src/Render.js @@ -123,7 +123,7 @@ var Render = new function() { } return '(' + signature + postSignature + ')'; }; - + var paperScriptId = 0; return { _class: function(symbol) { var param = { @@ -280,16 +280,41 @@ var Render = new function() { var out = [], examples = symbol.example; for (var i = 0, l = examples.length; i < l; i++) { - var example = examples[i], - lines = example.toString().split('\n'), + var example = examples[i].toString(); + + // Parse {@paperscript} inline tags + var paperScript; + example = example.replace(/\{@paperscript[\s]*([^}]+)*\}/, + function(tag, content) { + paperScript = { + width: 520, + height: 320, + id: paperScriptId++ + }; + var pairs = tag.match(/[\S]+=[^\s}]+/g); + if (pairs) { + for (var i = 0, l = pairs.length; i < l; i++) { + var pair = pairs[i].split('='); + paperScript[pair[0]] = pair[1]; + } + } + paperScript.mode = paperScript.split == 'true' ? 'split' + : paperScript.source == 'true' ? 'source' : null; + return ''; + } + ); + + var lines = example.split('\n'), description = []; // The description is the first commented lines: while (/^[\/]{2}/.test(lines[0])) { description.push(lines.shift().replace('// ', '')); } + out.push(Render.example({ description: description.join(' ').trim(), - code: lines.join('\n').trim() + code: lines.join('\n').trim(), + paperScript: paperScript })); } return out.join('\n'); diff --git a/build/jsdoc-toolkit/templates/jsdoc/static/resources/css/reference.css b/build/jsdoc-toolkit/templates/jsdoc/static/resources/css/reference.css index 8904a487..ba11fcc4 100644 --- a/build/jsdoc-toolkit/templates/jsdoc/static/resources/css/reference.css +++ b/build/jsdoc-toolkit/templates/jsdoc/static/resources/css/reference.css @@ -124,7 +124,62 @@ ul.package-classes { font-weight: bold; } -.CodeMirror { - margin-bottom: 16px; - margin-top: 8px; +/* PaperScript */ + +.paperscript { + margin-bottom: 20px; +} + +.paperscript .button { + display: none; + position: relative; /* position (top / right) relative to paperscriptcontainer */ + float: right; /* align right as block */ + font-size: 11px; + line-height: 16px; + padding: 2px 6px; + margin-bottom: -20px; /* move canvas up by 16px (height) + 2 * 2px (padding) */ + top: 8px; /* margin to top */ + right: 8px; /* margin to right */ + background: #eee; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + z-index: 1; +} + +.paperscript .source { + overflow: auto; + border: 1px solid #999; +} + +.paperscript:hover .button { + display: block; +} + +.paperscript .button:hover { + background: #ddd; + cursor: pointer; +} + +.paperscript .CodeMirror-gutter-text, +.paperscript .CodeMirror-lines { + padding-top: 10px; + padding-bottom: 10px; +} + +.paperscript .canvas { + line-height: 0; /* prevent weird 5px padding under canvas elements */ +} + +.paperscript.split .canvas { + border: 1px solid #999; + border-top: 0; +} + +.content .text .line, +.content .text .paperscript, +.content .text > .CodeMirror { + /* Compensate line margin for -10px above */ + margin-right: 10px; + margin-bottom: 20px; } \ No newline at end of file diff --git a/build/jsdoc-toolkit/templates/jsdoc/static/resources/js/reference.js b/build/jsdoc-toolkit/templates/jsdoc/static/resources/js/reference.js index 941bfd82..d6c4f410 100644 --- a/build/jsdoc-toolkit/templates/jsdoc/static/resources/js/reference.js +++ b/build/jsdoc-toolkit/templates/jsdoc/static/resources/js/reference.js @@ -52,93 +52,124 @@ Code = HtmlElement.extend({ } }); - PaperScript = HtmlElement.extend({ _class: 'paperscript', initialize: function() { - var script = $('script', this); - if (script) { - var canvas = $('canvas', this); - var button = $('.button', this); - if (!button) - return; - var source = this.injectBottom('div', { - className: 'source hidden', - }); - var width, height; - var editor = null; - var hasBorders = true; - function resize() { - if (canvas.hasClass('hidden')) { - // Can't get correct dimensions from hidden canvas, - // so calculate again. - var size = $window.getScrollSize(); - var offset = source.getOffset(); - width = size.width - offset.x; - height = size.height - offset.y; - } else { - width = canvas.getWidth(); - height = canvas.getHeight(); - } - source.set({ - width: width - (hasBorders ? 2 : 1), - height: height - (hasBorders ? 2 : 0) - }); - } - if (canvas.getProperty('resize')) { - $window.addEvents({ - resize: resize - }); - hasBorders = false; - source.setStyles({ - borderWidth: '0 0 0 1px' - }); - } else { - this.addClass('small'); - } - button.addEvents({ - click: function(event) { - var show = source.hasClass('hidden'); - resize(); - canvas.modifyClass('hidden', show); - source.modifyClass('hidden', !show); - this.setText(show ? 'Run' : 'Source'); - if (show && !editor) { - editor = createCodeMirror(source.$, { - /* - onKeyEvent: function(editor, event) { - event = new DomEvent(event); - if (event.type == 'keydown') { - var pos = editor.getCursor(); - pos.ch += 4; - editor.setCursor(pos); - event.stop(); - } - }, - */ - }, script); - } else if (!show) { - var scope = paper.PaperScope.get(script.$); - if (scope) { - // Update script to edited version - script.setText(editor.getValue()); - // Clear scope first, then evaluate a new script. - scope.clear(); - scope.evaluate(script.$); - } - } - this.setStyle('right', - $('.CodeMirror', source).getScrollSize().height > height // Remove padding - ? 24 : 8); - event.stop(); - }, - - mousedown: function(event) { - event.stop(); - } - }) + // Only format this element if it is visible, otherwise wait until + // it is made visible and then call format() manually. + if (this.getBounds().height != 0) { + this.format(); } + }, + + format: function() { + var script = $('script', this), + button = $('.button', this); + if (!script || !button) + return; + var source = button.injectAfter('div', { + className: 'source hidden' + }); + var canvas = $('canvas', this), + showSplit = this.hasClass('split'), + sourceFirst = this.hasClass('source'), + width, height, + editor = null, + hasBorders = true; + + function showSource(show) { + source.modifyClass('hidden', !show); + button.setText(show ? 'Run' : 'Source'); + if (show && !editor) { + editor = createCodeMirror(source.$, { + /* + onKeyEvent: function(editor, event) { + event = new DomEvent(event); + if (event.type == 'keydown') { + var pos = editor.getCursor(); + pos.ch += 4; + editor.setCursor(pos); + event.stop(); + } + }, + */ + }, script); + } + } + + function runScript() { + var scope = paper.PaperScope.get(script.$); + if (scope) { + // Update script to edited version + script.setText(editor.getValue()); + // Clear scope first, then evaluate a new script. + scope.clear(); + scope.evaluate(script.$); + } + } + + function resize() { + if (canvas.hasClass('hidden')) { + // Can't get correct dimensions from hidden canvas, + // so calculate again. + var size = $window.getScrollSize(); + var offset = source.getOffset(); + width = size.width - offset.x; + height = size.height - offset.y; + } else { + width = canvas.getWidth(); + height = canvas.getHeight(); + } + source.set({ + width: width - (hasBorders ? 2 : 1), + height: height - (hasBorders ? 2 : 0) + }); + } + + function toggleView() { + var show = source.hasClass('hidden'); + resize(); + canvas.modifyClass('hidden', show); + showSource(show); + if (!show) + runScript(); + // Remove padding + button.setStyle('right', + $('.CodeMirror', source).getScrollSize().height > height + ? 24 : 8); + } + + if (canvas.getProperty('resize')) { + $window.addEvents({ + resize: resize + }); + hasBorders = false; + source.setStyles({ + borderWidth: '0 0 0 1px' + }); + } + + if (showSplit) { + showSource(true); + } else if (sourceFirst) { + toggleView(); + } + + button.addEvents({ + click: function(event) { + if (showSplit) { + runScript(); + } else { + toggleView(); + } + event.stop(); + }, + + mousedown: function(event) { + event.stop(); + } + }); } }); @@ -162,7 +193,7 @@ function toggleMember(id, scrollTo) { link.modifyClass('hidden', v); desc.modifyClass('hidden', !v); if (!desc.editor && v) { - desc.editor = $$('pre.code', desc).each(function(code) { + desc.editor = $$('pre.code, .paperscript', desc).each(function(code) { code.format(); }); } diff --git a/build/jsdoc-toolkit/templates/jsdoc/templates/example.tmpl b/build/jsdoc-toolkit/templates/jsdoc/templates/example.tmpl index 2964d755..97d04fff 100644 --- a/build/jsdoc-toolkit/templates/jsdoc/templates/example.tmpl +++ b/build/jsdoc-toolkit/templates/jsdoc/templates/example.tmpl @@ -1,2 +1,13 @@ Example {+ '— ' + data.description +} -
{+data.code+}
\ No newline at end of file + +
{+ data.paperScript.mode +}"> +
{+ data.paperScript.mode == 'source' ? 'Source' : 'Run' +}
+ +
+
+
+ +
{+ data.code +}
+
\ No newline at end of file diff --git a/build/jsdoc-toolkit/templates/jsdoc/templates/html.tmpl b/build/jsdoc-toolkit/templates/jsdoc/templates/html.tmpl index bd239870..ff4f7b55 100644 --- a/build/jsdoc-toolkit/templates/jsdoc/templates/html.tmpl +++ b/build/jsdoc-toolkit/templates/jsdoc/templates/html.tmpl @@ -7,6 +7,7 @@ +