jsdoc template: Support inline paperscript tags for examples.

This commit is contained in:
Jonathan Puckey 2011-06-02 20:52:02 +02:00
parent 415728f7cf
commit 6ddb29bd21
5 changed files with 214 additions and 91 deletions

View file

@ -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');

View file

@ -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;
}

View file

@ -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();
});
}

View file

@ -1,2 +1,13 @@
<b>Example</b> <if test="data.description.length">{+ '&mdash; ' + data.description +}</if>
<pre class="code">{+data.code+}</pre>
<if test="data.paperScript">
<div class="paperscript <if test="data.paperScript.mode">{+ data.paperScript.mode +}</if>">
<if test="data.paperScript.source != 'false'"><div class="button">{+ data.paperScript.mode == 'source' ? 'Source' : 'Run' +}</div></if>
<script type="text/paperscript" canvas="canvas{+ data.paperScript.id +}">
{+ data.code +}
</script>
<div class="canvas"><canvas width="{+ Number(data.paperScript.width) - 4 +}" height="{+ data.paperScript.height +}" id="canvas{+ data.paperScript.id +}"></canvas></div>
</div>
</if>
<if test="!data.paperScript">
<pre class="code">{+ data.code +}</pre>
</if>

View file

@ -7,6 +7,7 @@
<link rel="stylesheet" href="../resources/css/style.css" type="text/css">
<link rel="stylesheet" href="../resources/css/codemirror.css" type="text/css">
<script src="../resources/js/bootstrap.js" type="text/javascript"></script>
<script src="../resources/js/paper.js" type="text/javascript"></script>
<script src="../resources/js/codemirror.js" type="text/javascript"></script>
<script src="../resources/js/reference.js" type="text/javascript"></script>
</head>