Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 15 commits
  • 16 files changed
  • 0 commit comments
  • 2 contributors
4 gateway.html
View
@@ -17,8 +17,8 @@
<a href={{=crumb.path|uri}} class="crumb{{? i == 0; root-crumb}}">{{=crumb.name|html}}</a>}}
</div>
<input id=search type=search class=input placeholder=search… autofocus>
- <a class=btn id=newfolder title=add><img src=/lib/icons/folder_add.png></a>
- <a class=btn id=newfile title=add><img src=/lib/icons/file_add.png></a>
+ <a class=btn id=newfolder title='create folder'><img src=/lib/icons/folder_add.png></a>
+ <a class=btn id=newfile title='create file'><img src=/lib/icons/file_add.png></a>
</nav>
<div id=controls-zone class=btn-group>
<a class=btn id=settings title=settings href={{=file.path|uri}}?plug=meta>
2  lib/css/common.css
View
@@ -273,7 +273,7 @@ input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shad
padding-top: 4px;
}
-#toolbar #preview, #toolbar #run, #toolbar #download {
+#toolbar #preview, #toolbar #run, #toolbar #validate, #toolbar #download {
display: none;
}
167 lib/js/OpenSequenceDiagrams.js
View
@@ -22,18 +22,19 @@ var interPart = 25; //Horizontal interval between 2 participants
//SVG functions ---------------------------------------------------------------
-function drawText(x, y, text) {
- return '<text x="'+x+'" y="'+ y + '" style="text-anchor:middle;">'+text+'</text>';
+function drawText(x, y, text, center) {
+ return '<text x="'+x+'" y="'+ y + '"' + (center ? ' style="text-anchor:middle;"' : '') + '>'+text+'</text>';
}
-function drawRect(x, y, width, height, ry, gradient) {
+function drawRect(x, y, width, height, ry, fill, stroke) {
return '<rect'
+ ' x="' + x
+ '" y="' + y
+ '" width="' + width
+ '" height="' + height
+ '" ry="' + ry
- + '" style="fill:' + (gradient ? 'url(#grad1)' : 'white') + ';stroke:black;stroke-width:2;" ></rect>';
+ + '" style="fill:' + fill + ';'
+ + (stroke ? 'stroke:black;stroke-width:2;' : '') + '" ></rect>';
}
function drawLine(x1, y1, x2, y2, isDotted) {
@@ -74,14 +75,32 @@ function actor(x, y, height, text) {
function rectWithText(x, y, text, gradient) {
var end = text.length * 20 + 10;
var r = '<g transform="translate('+x+','+y+')">';
- r+= drawRect(0, 0, partSize, end, 5, gradient);
+ r+= drawRect(0, 0, partSize, end, 5, (gradient ? 'url(#grad1)' : 'white'), true);
for(var i in text) {
- r+= drawText(partSize/2, i*20+20, text[i]);
+ r+= drawText(partSize/2, i*20+20, text[i], true);
}
r+='</g>';
return r;
}
+function specialRectangle(x, y, w, h, type, comment) {
+ var svg = "";
+ svg += drawRect(x, y, 70, 30, 0, 'white', false);
+
+ svg += drawRect(x, y, w, h, 0, 'none', true);
+
+ svg += drawLine(x, y+30, x+60, y+30, false);
+ svg += drawLine(x+60, y+30, x+70, y+20, false);
+ svg += drawLine(x+70, y+20, x+70, y, false);
+
+ svg += drawText(x+30, y+20, type, true);
+
+ if(comment != "") {
+ svg += drawText(x+90, y+20, '['+comment+']', false);
+ }
+ return svg;
+}
+
function arrow(x, y, width, text, isToTheRight, isDotted, isToSelf) {
var r = '<g transform="translate('+x+','+y+')">';
var lineY = 7+(text.length-1)*20;
@@ -95,7 +114,7 @@ function arrow(x, y, width, text, isToTheRight, isDotted, isToSelf) {
r+= drawTriangle((isToTheRight ? (partSize+interPart)*width : 0), lineY, isToTheRight);
}
for(var i in text) {
- r+= drawText((partSize+interPart)*width/2, i*20, text[i]);
+ r+= drawText((partSize+interPart)*width/2, i*20, text[i], true);
}
r+='</g>';
return r;
@@ -105,17 +124,17 @@ function arrow(x, y, width, text, isToTheRight, isDotted, isToSelf) {
//Model -----------------------------------------------------------------------
function filter(text) {
- return text.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
+ return text.replace(/</g, "&lt;");
}
//Participant
function Participant(name, text) {
- this.name = filter(name);
+ this.name = name;
if(text == undefined) {
- this.text = filter(name).split("\\n");
+ this.text = name.split("\\n");
} else {
- this.text = filter(text).split("\\n");
+ this.text = text.split("\\n");
}
this.height = this.text.length*20+10+30;
this.position = 0;
@@ -130,7 +149,7 @@ function Participant(name, text) {
function Signal(participant1, participant2, text, isDotted) {
this.participant1 = participant1;
this.participant2 = participant2;
- this.text = filter(text).split("\\n");
+ this.text = text.split("\\n");
this.isDotted = isDotted;
this.height = this.text.length*20+10;
if(participant1.name == participant2.name) {
@@ -141,11 +160,11 @@ function Signal(participant1, participant2, text, isDotted) {
return this.height;
}
- this.getSVG = function(position) {
+ this.getSVG = function(position, width) {
var minPosition = Math.min(this.participant1.position,
this.participant2.position);
return arrow(minPosition*(partSize+interPart)+5+partSize/2,
- position,
+ position+10,
Math.abs(this.participant1.position
- this.participant2.position),
this.text,
@@ -159,14 +178,14 @@ function Signal(participant1, participant2, text, isDotted) {
function State(participant, text) {
this.participant = participant;
- this.text = filter(text).split("\\n");
+ this.text = text.split("\\n");
this.height = this.text.length*20+15;
this.getHeight = function() {
return this.height;
}
- this.getSVG = function(position) {
+ this.getSVG = function(position, width) {
return rectWithText(
this.participant.position*(partSize+interPart)+5,
position,
@@ -177,9 +196,22 @@ function State(participant, text) {
//Container
-function Container() {
+function Container(parent) {
this.children = [];
this.height = 0;
+ this.parent = parent;
+ this.depth = 0;
+ if(parent != null) {
+ this.depth = parent.getDepth()+1;
+ }
+}
+
+Container.prototype.getDepth = function() {
+ return this.depth;
+}
+
+Container.prototype.getParent = function() {
+ return this.parent;
}
Container.prototype.addSignal = function(signal) {
@@ -194,10 +226,10 @@ Container.prototype.getHeight = function() {
return height;
}
-Container.prototype.getSVG = function(position) {
+Container.prototype.getSVG = function(position, width) {
var svg = "";
for(var i in this.children) {
- svg += this.children[i].getSVG(position);
+ svg += this.children[i].getSVG(position, width);
position += this.children[i].getHeight();
}
return svg;
@@ -205,27 +237,60 @@ Container.prototype.getSVG = function(position) {
//Parallel container
-function ParallelContainer() {
- Container.call(this);
+function ParallelContainer(parent) {
+ Container.call(this, parent);
}
ParallelContainer.prototype = new Container();
ParallelContainer.prototype.getHeight = function() {
- var height = this.height;
- var maxHeight = 0;
for(var i in this.children) {
- if(this.children[i].getHeight() > maxHeight) {
- maxHeight = this.children[i].getHeight();
+ if(this.children[i].getHeight() > this.height) {
+ this.height = this.children[i].getHeight();
}
}
- return height+maxHeight;
+ return this.height;
+}
+
+ParallelContainer.prototype.getSVG = function(position, width) {
+ var svg = "";
+ for(var i in this.children) {
+ svg += this.children[i].getSVG(position + this.height - this.children[i].getHeight());
+ }
+ return svg;
+}
+
+//Loop container
+
+function SimpleContainer(parent, type, times) {
+ Container.call(this, parent);
+ this.height = 60;
+ this.times = times;
+ this.type = type;
}
-ParallelContainer.prototype.getSVG = function(position) {
+SimpleContainer.prototype = new Container();
+
+SimpleContainer.prototype.getHeight = function() {
+ var height = this.height;
+ for(var i in this.children) {
+ height += this.children[i].getHeight();
+ }
+ return height;
+}
+
+SimpleContainer.prototype.getSVG = function(position, width) {
var svg = "";
+ svg += specialRectangle(10*(this.getDepth()+1),
+ position,
+ width-((this.getDepth()+1)*2*10),
+ this.getHeight()-10,
+ this.type,
+ (this.times == "" ? "" : this.times + " times"));
+ position += 50;
for(var i in this.children) {
- svg += this.children[i].getSVG(position);
+ svg += this.children[i].getSVG(position, width);
+ position += this.children[i].getHeight();
}
return svg;
}
@@ -234,7 +299,7 @@ ParallelContainer.prototype.getSVG = function(position) {
function Schema() {
this.participants = [];
- this.signals = new Container();
+ this.signals = new Container(null);
this.patterns = [
['[ \t]*participant[ ]*"([^"]*)"[ ]*as[ ]*"?([^"]*)"?',
2,
@@ -244,10 +309,22 @@ function Schema() {
'this.addParticipant(new Participant(res[1]));'],
['[ \t]*parallel[ ]*{[ ]*',
0,
- 'var p = new ParallelContainer(); this.addSignal(p); this.parallel = p;'],
+ 'var p = new ParallelContainer(this.signals); this.addSignal(p); this.signals = p;'],
['[ \t]*}[ ]*',
0,
- 'this.parallel = null;'],
+ 'if(!(this.signals instanceof ParallelContainer)) res[0]=null;'
+ + 'else this.signals = this.signals.getParent();'],
+ ['[ \t]*opt[ ]*',
+ 0,
+ 'var p = new SimpleContainer(this.signals, "opt", ""); this.addSignal(p); this.signals = p;'],
+ ['[ \t]*loop[ ]*([0-9]+)[ ]*times[ ]*',
+ 1,
+ 'var p = new SimpleContainer(this.signals, "loop", res[1]); this.addSignal(p); this.signals = p;'],
+ ['[ \t]*end[ ]*',
+ 0,
+ 'if(!(this.signals instanceof SimpleContainer)) res[0]=null;'
+ + 'else this.signals = this.signals.getParent();'],
+
['[ \t]*autonumber[ ]*([0-9]+)[ ]*',
1,
'this.autonumber = res[1];'],
@@ -265,7 +342,6 @@ function Schema() {
+ 'this.addSignal(new Signal(this.getParticipant(res[1]), this.getParticipant(res[3]), res[4], res[2]=="-"))'],
['[ \t]*', 0, '']
];
- this.parallel = null;
this.autonumber = null;
this.addParticipant = function(participant) {
@@ -282,11 +358,11 @@ function Schema() {
}
this.addSignal = function(signal) {
- if(this.autonumber != null) {
- if(signal.text != undefined) {
- signal.text[0] = "["+this.autonumber+"] " + signal.text[0];
- this.autonumber++;
- }
+ if(this.autonumber != null
+ && signal.text != undefined
+ && !(signal instanceof State)) {
+ signal.text[0] = "["+this.autonumber+"] " + signal.text[0];
+ this.autonumber++;
}
if(this.parallel != null) {
this.parallel.addSignal(signal);
@@ -310,18 +386,19 @@ function Schema() {
for(var i in tab) {
var found = this.parseLine(tab[i]);
if(!found) {
- retour += 'E: line ' + (parseInt(i)+1) + ' (' + tab[i] + ')<br/>';
+ retour += 'E: line ' + (parseInt(i)+1) + '<br/>';
}
}
+ if(this.signals.getParent() != null) {
+ retour += 'E: missing closing \'end\' tag before the end of the code<br/>';
+ }
return retour;
}
this.parseLine = function(line) {
- if(line === "") {
- return true;
- }
for(var i in this.patterns) {
var pat = new RegExp(this.patterns[i][0]);
+ line = filter(line);
var res = pat.exec(line);
if(res != null && res.length-1 == this.patterns[i][1]) {
eval(this.patterns[i][2]);
@@ -346,16 +423,18 @@ function Schema() {
var height = heightParticipants;
height += this.signals.getHeight();
+ var width = (this.participants.length * (partSize+interPart)) - interPart + 10;
+
for(var i in this.participants) {
this.participants[i].position = i;
svg += this.participants[i].getSVG(height);
}
height += heightParticipants;
- svg += this.signals.getSVG(heightParticipants);
+ svg += this.signals.getSVG(heightParticipants, width);
var finalSVG =
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="'
- + (this.participants.length * (partSize+interPart))
+ + width
+ '" height="'
+ (height + 10)
+ '">';
@@ -366,4 +445,4 @@ function Schema() {
finalSVG += '</svg>';
return finalSVG;
}
-}
+}
13 lib/js/pencil.js
View
@@ -4,12 +4,6 @@
// The following code is covered by the GPLv2 license.
-function stopEvent (e) {
- if (e.preventDefault) { e.preventDefault(); }
- if (e.stopPropagation) { e.stopPropagation(); }
-};
-
-
// Controls
//
@@ -17,6 +11,11 @@ function stopEvent (e) {
Scout('#undo').onclick = function (e) { cm.undo(); stopEvent(e); };
Scout('#redo').onclick = function (e) { cm.redo(); stopEvent(e); };
+function stopEvent (e) {
+ if (e.preventDefault) { e.preventDefault(); }
+ if (e.stopPropagation) { e.stopPropagation(); }
+};
+
var disabledRegex = /(^|\s+)disabled($|\s+)/;
function enable (el) {
@@ -37,6 +36,7 @@ function maybeEnable(stack, el) {
}
}
+
// Run button
function runJS() {
var result;
@@ -45,6 +45,7 @@ function runJS() {
alert(result);
}
+
// Theme button
function selectTheme(node) {
window.cm.setTheme(node.options[node.selectedIndex].innerHTML);
356 lib/js/webjson.js
View
@@ -1,6 +1,6 @@
-/* json2all.js: display json.
- * Copyright (c) 2010 Thaddee Tyl. All rights reserved.
- */
+// Display JSON data as editable HTML elements.
+// Copyright © 2010-2012 Thaddee Tyl, Jan Keromnes. All rights reserved.
+(function() {
JSON.getweb = {};
JSON.web = function (obj, id, opts) {
@@ -11,11 +11,11 @@ JSON.web = function (obj, id, opts) {
* opts.reviver, which is a function to filter the object.
* Example of use:
* <html>
- * <body id="locat"></body>
+ * <body id="spot"></body>
* <script>
- * var locat = JSON.web({hello:'world'}, 'locat', {template:'rewrite'});
+ * var locat = JSON.web({hello:'world'}, 'spot', {template:'rewrite'});
* if( locat() ) { // if it has changed...
- * alert( JSON.getweb['locat'] );
+ * alert( JSON.getweb['spot'] );
* }
* </script>
* </html> */
@@ -47,6 +47,15 @@ JSON._parseObj = function(obj, path, id, template) {
} else {
deal = JSON._plates[template];
}
+ if (!deal) throw("No template was given to JSON.web().");
+
+ /* Inject corresponding CSS. */
+ if (deal.css) {
+ var styleElt = document.createElement('style');
+ styleElt.textContent = deal.css(id);
+ document.body.appendChild(styleElt);
+ }
+
/* We put it all in html. */
var html = '';
if (typeof obj === 'object') {
@@ -73,9 +82,17 @@ JSON._parseObj = function(obj, path, id, template) {
return html;
};
+/* Helper escape functions go here. */
+function escObjInAttr(o) {
+ return JSON.stringify(o).replace(/"/g,'&quot;');
+};
+
JSON._plates = {};
+JSON._plates.escObjInNestedAttr = function(o) {
+ return JSON.stringify(o).replace(/"/g,'\\\'');
+};
JSON._plates.readonly = {
- 'obj': function(obj, path, id, template) {
+ obj: function(obj, path, id, template) {
var html = '';
html += '<dl>';
var i;
@@ -88,7 +105,7 @@ JSON._plates.readonly = {
html += '</dl>';
return html;
},
- 'list': function(obj, path, id, template) {
+ list: function(obj, path, id, template) {
var html = '';
html += '<ul>';
for (var i=0; i<obj.length; i++) {
@@ -100,119 +117,174 @@ JSON._plates.readonly = {
html += '</ul>';
return html;
},
- 'str': function(obj) {
+ str: function(obj) {
return obj;
},
- 'num': function(obj) {
+ num: function(obj) {
return obj;
},
- 'bool': function(obj) {
+ bool: function(obj) {
return (obj? 'true': 'false');
},
- 'null':function(obj) {
+ 'null': function(obj) {
return 'null';
}
};
JSON._plates.rewrite = {
- 'objdt': function(path, id, key) {
- return '<span style="border:1px solid black">%</span>' +
- /* Remove: 1. Data; 2. Graphics. */
- '<button onclick="delete JSON.getweb[\'' + id + '\']' +
- path + '[\''+key+'\']; ' +
- 'this.parentNode.parentNode.removeChild(' +
- 'this.parentNode.nextSibling);' +
- 'this.parentNode.parentNode.removeChild(this.parentNode);' +
- '">x</button>' +
- /* Modification of a key! 1. Copy key; 2. Remove old key. */
- /* TODO
- '<input value="' + key + '" ' +
- 'oninput="JSON.getweb[\'' + id + '\']' +
- path + '[this.value] = JSON.getweb[\'' + id + '\']' +
- path + '[\''+key+'\']; delete JSON.getweb[\'' + id + '\']' +
- path + '[\''+key+'\']"' +
- '/>:</dt><dd>' +
- */
- key + ':</dt>'
+ css: function(id) {
+ return 'html body {' +
+ 'font-family: monospace;' +
+ '}' +
+ 'div.webjson-element {' +
+ 'margin-left: 1em;' +
+ '}' +
+ '.hidden { visibility: hidden !important; }' +
+ 'div.webjson-element > button.delete {' +
+ 'border: 0;' +
+ 'background: transparent;' +
+ 'cursor: pointer;' +
+ 'color: lightgrey;' +
+ 'width: 1em;' +
+ 'visibility: hidden;' +
+ '}' +
+ 'div.webjson-element:hover > button.delete {' +
+ 'visibility: visible;' +
+ '}' +
+ 'div.webjson-element:hover > button.delete:hover {' +
+ 'color: black;' +
+ '}' +
+ 'input.webjson-edit {' +
+ 'font-family: monospace;' +
+ 'border: 1px solid lightgrey;' +
+ 'box-shadow: 2px 2px 2px lightgrey;' +
+ 'margin: 0px; padding: 0px;' +
+ '}' +
+ 'input[type=text].webjson-edit {' +
+ 'width: 130px;' +
+ '}' +
+ 'input[type=number].webjson-edit {' +
+ 'width: 50px;' +
+ '}';
+ },
+ objkey: function(path, id, key) {
+ /* Remove: 1. Data; 2. Graphics. */
+ return '<button class="delete" onclick="delete JSON.getweb[' +
+ escObjInAttr(id) + ']' + path + '[' + escObjInAttr(key) + ']; ' +
+ 'this.parentNode.parentNode.removeChild(this.parentNode)">x</button>' +
+ key + JSON._plates.rewrite.objkeySeparator;
},
- 'obj': function(obj, path, id, template) {
+ objkeySeparator: ': ',
+ obj: function(obj, path, id, template) {
/* This function uses the path of the current object to alter
* the value of its elements. */
/* path: string, eg, '["hello"][4][2]'. */
/* id: string of container id, eg, 'show'. */
var html = '';
- html += '<dl>';
+ html += '<button class="delete hidden">x</button>{';
var i;
for (i in obj) {
- html += '<dt>' + JSON._plates.rewrite.objdt(path, id, i);
- html += '<dd>' +
- /* The subpath is updated. */
- JSON._parseObj(obj[i], path + '[\''+i+'\']', id, template) + '</dd>';
+ html += '<div class="webjson-element">' +
+ JSON._plates.rewrite.objkey(path, id, i) +
+ JSON._parseObj(obj[i], path + '[\'' + i + '\']', id, template) +
+ ',</div>';
}
- html += '<dt><span style="border:1px solid black">%</span>' +
+ html += '<div class="webjson-element">' +
/* Value. */
- '<input placeholder="New key">' +
+ '<button class="delete hidden">x</button>' +
/* add button. */
- '<button onclick="' +
- 'JSON._plates.rewrite.addObjBut(this,&quot;' + path + '&quot;,\'' + id +
- '\', this.previousSibling.value)' +
- '">+</button></dt>';
- html += '</dl>';
+ '<button onclick="JSON._plates.rewrite.addObjBut(this,&quot;' +
+ path + '&quot;,\'' +
+ id + '\')">+key:value</button></div>';
+ html += '<button class="delete hidden">x</button>}';
return html;
},
- 'listdt': function(path, id, index) {
- return '<span style="border:1px solid black">::</span>' +
- /* Remove: 1. Data; 2. Graphics. */
- '<button onclick="delete JSON.getweb[\'' + id + '\']' +
+ listitem: function(path, id, index) {
+ /* Remove: 1. Data; 2. Graphics. */
+ return '<button class="delete" onclick="delete JSON.getweb[\'' + id + '\']' +
path + '[' + index + ']; ' +
'this.parentNode.parentNode.removeChild(this.parentNode)' +
'">x</button>';
/* The subpath is updated. */
},
- 'list': function(obj, path, id, template) {
+ list: function(obj, path, id, template) {
var html = '';
- html += '<ul>';
+ html += '[';
for (var i=0; i<obj.length; i++) {
- html += '<li>' + JSON._plates.rewrite.listdt(path, id, i);
- html += JSON._parseObj(obj[i], path + '['+i+']', id, template) + '</li>';
+ html += '<div class="webjson-element">' +
+ JSON._plates.rewrite.listitem(path, id, i);
+ html += JSON._parseObj(obj[i], path + '['+i+']', id, template) + ',</div>';
}
- html += '<li><button ' +
- /* add button */
- 'onclick="JSON._plates.rewrite.addListBut(this,&quot;' +
- path + '&quot;, \'' + id + '\', ' +
- 'JSON.getweb[\'' + id + '\']' + path + '.length);"' +
- '>+</button></li>';
- html += '</ul>';
+ html += '<div class="webjson-element">' +
+ /* add button. */
+ '<button class="delete hidden">x</button><button onclick="' +
+ 'JSON._plates.rewrite.addListBut(this,&quot;' + path + '&quot;,' +
+ escObjInAttr(id) + ')">+item</button></div>';
+ html += '<button class="delete hidden">x</button>]';
return html;
},
- 'str': function(obj, path, id) {
- return '<input value="' + obj + '" ' +
- /* Change the string. */
- 'oninput="JSON.getweb[\'' + id + '\']' +
- path + ' = this.value;"/>';
+ atom: function(obj, path, id, type) {
+ /* Calling the next function when double clicking. */
+ return '<span onclick="(function(that){var parent=that.parentNode;' +
+ 'that.outerHTML = JSON._plates.rewrite.' + type + 'Input(' +
+ escObjInAttr(obj) + ',&quot;' + path + '&quot;,' +
+ escObjInAttr(id) + ');' +
+ 'parent.firstChild.nextElementSibling.firstElementChild' +
+ '.focus();}(this))">' +
+ JSON._plates.rewrite[type + 'Output'](obj) + '</span>';
+ },
+ str: function(obj, path, id) {
+ return JSON._plates.rewrite.atom(obj, path, id, 'str');
+ },
+ strOutput: function(obj) {
+ return '"' + obj + '"';
+ },
+ strInput: function(obj, path, id) {
+ return '<span>"<input type="text" class="webjson-edit" value="' + obj + '" ' +
+ 'onblur="this.parentNode.outerHTML=JSON._plates.rewrite.atom(this.value,' +
+ '&quot;' + path + '&quot;,' + escObjInAttr(id) + ',\'str\')" ' +
+ 'oninput="JSON.getweb[' + escObjInAttr(id) + ']' +
+ path + '=this.value">"</span>';
+ },
+ num: function(obj, path, id) {
+ return JSON._plates.rewrite.atom(obj, path, id, 'num');
+ },
+ numOutput: function(obj) {
+ return obj.toString(10);
},
- 'num': function(obj, path, id) {
- return '<input type="number" value="' + obj + '" ' +
+ numInput: function(obj, path, id) {
+ return '<input class="webjson-edit" type="number" value="' + obj + '" ' +
/* Change a number. */
'oninput="JSON.getweb[\'' + id + '\']' +
- path + ' = parseInt(this.value,10);"/>';
+ path + ' = parseInt(this.value,10);"' +
+ 'onblur="this.outerHTML = ' +
+ 'JSON._plates.rewrite.atom(parseInt(this.value,10),' +
+ '&quot;' + path + '&quot;,' + escObjInAttr(id) + ',\'num\')">';
},
- 'bool': function(obj, path, id) {
+ bool: function(obj, path, id) {
+ return JSON._plates.rewrite.atom(obj, path, id, 'bool');
+ },
+ boolOutput: function(obj) {
+ return '' + obj;
+ },
+ boolInput: function(obj, path, id) {
return '<select ' +
+ 'onblur="this.outerHTML=JSON._plates.rewrite.atom(' +
+ 'this.value==\'true\'?true:false,&quot;' + path + '&quot;,' +
+ escObjInAttr(id) + ',\'bool\')" ' +
/* Change the value. */
'onchange="JSON.getweb[\'' + id + '\']' +
- path + ' = this.value==\'true\'?true:false;">' +
+ path + ' = this.value==\'true\'?true:false;">' +
'<option' + (obj?' selected':'') + '>true</option>' +
'<option' + (!obj?' selected':'') +'>false</option></select>';
},
'null':function(obj) {
return 'null';
},
- 'addButAsk': function(path, id, key, updatedb) {
- return '<div><label>' +
- 'Type:<select>' +
- '<option value="0" selected>Object</option>' +
+ addButAsk: function(path, id, update) {
+ return '<span><select>' +
+ '<option value="0">Object</option>' +
'<option value="1">List</option>' +
- '<option value="2">String</option>' +
+ '<option value="2" selected>String</option>' +
'<option value="3">Number</option>' +
'<option value="4">Boolean</option>' +
'<option value="5">Null </option>' +
@@ -220,106 +292,76 @@ JSON._plates.rewrite = {
/* Careful there! JS use in the event attr of an event attr. */
'<button onclick="(function(that){' +
'var o;' +
- 'switch(that.previousSibling.firstChild.nextSibling.value){' +
+ 'switch(that.previousSibling.value){' +
'case \'0\': o = {}; break;' +
'case \'1\': o = []; break;' +
'case \'2\': o = \'\'; break;' +
'case \'3\': o = 0; break;' +
'case \'4\': o = false;break;' +
'case \'5\': o = null; break;' +
- '};' + updatedb(path,id,key) +
- '})(this);">Add</button></div>';
+ '};' + update(path, id) +
+ '})(this);">Add</button></span>';
},
- 'addObjBut': function(button, path, id, key) {
+ addObjBut: function(button, path, id) {
/* add button */
- var dd = document.createElement('dd');
- dd.innerHTML = JSON._plates.rewrite.addButAsk(path,id,key,
- function(path,id,key) {
- return '' +
- /* Graphical update */
- 'var dt = document.createElement(&quot;dt&quot;);' +
- 'dt.innerHTML = JSON._plates.rewrite.objdt(&quot;' + path +
- '&quot;, &quot;' + id +'&quot;, &quot;' + key + '&quot;);' +
- 'that.parentNode.parentNode.parentNode.insertBefore(dt, ' +
- 'that.parentNode.parentNode);' +
- 'that.parentNode.parentNode.innerHTML = ' +
- 'JSON._parseObj(o,&quot;' + path + '[\'' + key + '\']' + '&quot;,' +
- '\'' + id + '\',\'rewrite\');' +
- /* Data update */
- 'JSON.getweb[\'' + id + '\']' + path + '[\'' + key + '\'] = o;';
+ var div = document.createElement('div');
+ div.classList.add('webjson-element');
+ div.innerHTML = JSON._plates.rewrite.objkey(path, id, '')
+ .slice(0, -JSON._plates.rewrite.objkeySeparator.length) +
+ // The following item is the key. It must start as a focused input.
+ '<input class="webjson-edit" />: ' +
+ // Input field to choose the type.
+ JSON._plates.rewrite.addButAsk(path, id, function(path, id) {
+ // In there, `that` is the button DOM node.
+ // All this is JS inside a DOM attribute.
+ return 'var key = that.parentNode.previousElementSibling.value;' +
+ // Graphical update.
+ 'that.parentNode.parentNode.innerHTML = ' +
+ 'JSON._plates.rewrite.objkey(&quot;' + path + '&quot;,' +
+ escObjInAttr(id) + ', key) +' +
+ 'JSON._parseObj(o, &quot;' + path + '&quot; +' +
+ '\'[\' + JSON._plates.escObjInNestedAttr(key) + \']\',' +
+ escObjInAttr(id) + ', \'rewrite\') + \',\';' +
+ // Data update.
+ 'JSON.getweb[' + escObjInAttr(id) + ']' + path + '[key] = o;';
});
+ // FIXME we must wait for it to render.
+ setTimeout(function(){div.firstChild.nextSibling.focus()}, 100);
- /* Add the selector to the dom tree. */
- button.parentNode.parentNode.insertBefore(dd, button.parentNode);
+ /* Add the type selector to the dom tree. */
+ button.parentNode.parentNode.insertBefore(div, button.parentNode);
/* Void the key name input widget. */
button.previousSibling.value = '';
},
- 'addListBut': function(button, path, id, index) {
+ addListBut: function(button, path, id, index) {
/* add button */
- var li = document.createElement('li');
- li.innerHTML = JSON._plates.rewrite.addButAsk(path, id, undefined,
- function(path, id, key) {
- return '' +
- /* Graphical update */
- 'that.parentNode.parentNode.innerHTML = ' +
- 'JSON._plates.rewrite.listdt(&quot;' + path + '&quot;,' +
- '&quot;' + id + '&quot;,' + index + ') +' +
- 'JSON._parseObj(o,&quot;' + path +
- /* The object being parsed is at index length. */
- '[&quot; + (JSON.getweb[\'' + id + '\']' +
- path + '.length) + &quot;]&quot;' +
- ',\'' + id + '\',\'rewrite\');' +
- /* Data update */
- 'JSON.getweb[\'' + id + '\']' + path + '.push(o);';
+ var div = document.createElement('div');
+ div.classList.add('webjson-element');
+ div.innerHTML = JSON._plates.rewrite.listitem(path, id, index) +
+ JSON._plates.rewrite.addButAsk(path, id,
+ function(path, id) {
+ // In there, `that` is the button DOM node.
+ // All this is JS inside a DOM attribute.
+ // The object being parsed is at index length.
+ return 'var index = JSON.getweb[' + escObjInAttr(id) + ']' +
+ path + '.length;' +
+ // Graphical update.
+ 'that.parentNode.parentNode.innerHTML = ' +
+ 'JSON._plates.rewrite.listitem(&quot;' + path + '&quot;,' +
+ escObjInAttr(id) + ', index) +' +
+ 'JSON._parseObj(o, &quot;' + path + '[&quot; + index +' +
+ '&quot;]&quot;, ' + escObjInAttr(id) + ',' +
+ '\'rewrite\') + \',\';' +
+ // Data update.
+ 'JSON.getweb[' + escObjInAttr(id) + ']' + path + '.push(o);';
});
/* Add the selector to the dom tree. */
- button.parentNode.parentNode.insertBefore(li, button.parentNode);
- }
-};
-JSON._plates.editable = {
- 'obj': function(obj, path, id, template) {
- var html = '{';
- var key;
- for (key in obj) {
- html += '<div style="margin-left:20px">';
- html += key + ' : ' + JSON._parseObj(obj[key], '', id, template) + ',';
- html += '</div>';
- }
- html += '<div style="margin-left:20px">';
- html += '<input type="button" value="+ key:value">';
- html += '</div>';
- html += '}';
- return html;
- },
- 'list': function(obj, path, id, template) {
- var html = '[';
- for (var i = 0; i < obj.length; i++) {
- html += '<div style="margin-left:20px">';
- html += JSON._parseObj(obj[i], '', id, template) + ',';
- html += '</div>';
- }
- html += '<div style="margin-left:20px">';
- html += '<input type="button" value="+ item">';
- html += '</div>';
- html += ']';
- return html;
- },
- 'str': function(obj) {
- return '<input type="text" value="' + obj + '">';
- },
- 'num': function(obj) {
- return '<input type="number" value="' + obj + '">';
- },
- 'bool': function(obj) {
- var html = '<select>';
- html += '<option' + (obj?' selected':'') + '>true</option>';
- html += '<option' + (obj?'':' selected') + '>false</option>';
- html += '</select>';
- return html;
- },
- 'null':function(obj) {
- return 'null';
+ button.parentNode.parentNode.insertBefore(div, button.parentNode);
}
};
+
+
+}());
+
18 meta.html
View
@@ -1,17 +1,21 @@
<!doctype html>
<meta charset=utf-8>
-<title> {{=title|html}} </title>
+<title> Metadata of {{=title|html}} </title>
<style>
-p#saved { visibility: hidden; }
+ html body { font-family: monospace; }
+ p#saved { visibility: hidden; }
+ div#show { margin-bottom: 13px; }
</style>
-<div id=show></div>
+<p> Click on an item to edit it. </p>
+
+<div class='webjson-element' id=show></div>
<button id=save> Save </button>
<p id=saved></p>
-<script src='/lib/js/webjson.js?plug=none'></script>
-<script src='/lib/js/scout.js?plug=none'></script>
+<script src='/lib/js/webjson.js'></script>
+<script src='/lib/js/scout.js'></script>
<script>
onload = function() {
@@ -20,6 +24,7 @@
var save = Scout('#save'),
saved = Scout('#saved');
+
save.on('click', function(param) {
save.disabled = true;
saved.textContent = 'Saving…';
@@ -39,3 +44,6 @@
});
};
</script>
+
+<!-- Google Analytics -->
+<script>var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-27876347-1']);_gaq.push(['_trackPageview']);(function(){var ga=document.createElement('script');ga.type='text/javascript';ga.async=true;ga.src=('https:'==document.location.protocol?'https://ssl':'http://www')+'.google-analytics.com/ga.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);})()</script>
2  meta/lib/js/scout.js
View
@@ -1 +1 @@
-{"type":"text/javascript"}
+{"type":"text/javascript","plug":"none"}
2  meta/lib/js/webjson.js
View
@@ -1 +1 @@
-{"type":"text/javascript"}
+{"type":"text/javascript","plug":"none"}
2  meta/profiler.html
View
@@ -1 +1 @@
-{"type":"text/html"}
+{"type":"text/html","plug":"none"}
1  meta/test/test.erl
View
@@ -0,0 +1 @@
+{"type":"text/plain"}
1  meta/test/this/is/starting/.DS-Store
View
@@ -0,0 +1 @@
+{"type":"dir"}
120 pencil.html
View
@@ -19,10 +19,11 @@
{{=crumb.name|html}}</a>}}
</div>
</nav>
- <div id=controls-zone class=btn-group>
+ <form id=controls-zone class=btn-group name=export method=post target=_blank enctype=multipart/form-data>
<a class=btn id=undo title=undo><img src=/lib/icons/undo.png></a>
<a class=btn id=redo title=redo><img src=/lib/icons/redo.png></a>
<a class=btn id=preview title=preview><img src=/lib/icons/eye_open.png></a>
+ <a class=btn id=validate title=validate><img src=/lib/icons/check.png></a>
<a class=btn id=run title=run><img src=/lib/icons/play.png></a>
<a class=btn id=download title=download><img src=/lib/icons/download_alt.png></a>
<a class=btn id=settings title=settings><img src=/lib/icons/cogwheel.png></a>
@@ -31,7 +32,13 @@
'cobalt','eclipse','rubyblue','lesser-dark','xq-dark']|theme|i;
<option{{?theme===lookup('theme'); selected}}>{{=theme|html}}</option>}}
</select>
- </div>
+ <input type=hidden name=code>
+ <input type=hidden name=lang>
+ <input type=hidden name=ucn_text>
+ <input type=hidden name=ucn_text_mime>
+ <input type=hidden name=ucn_task value=conformance>
+ <input type=hidden name=run value=True>
+ </form>
</div>
<base target=_parent>
@@ -47,8 +54,9 @@
// UI elements
var undo = Scout('#undo'),
redo = Scout('#redo'),
- run = Scout('#run'),
+ validate = Scout('#validate'),
preview = Scout('#preview'),
+ run = Scout('#run'),
download = Scout('#download'),
settings = Scout('#settings'),
wrapper = Scout('#wrapper'), delay;
@@ -60,42 +68,10 @@
keymap = {{=lookup('keymap')|json}} || 'default',
lineNumbers = {{=lookup('lineNumbers')|json}} || true,
lineWrapping = {{=lookup('lineWrapping')|json}} || false;
-
- // General button actions
- disable(undo); disable(redo);
- settings.href = '{{=file.path|uri}}?plug=meta';
- download.href = '{{=file.path|uri}}?plug=none';
- download.style.display = 'block';
-
- // Mime type specific button actions
- switch(mime) {
- case 'text/html':
- preview.style.display = 'block';
- preview.href = '{{=file.path|uri}}?plug=html';
- run.style.display = 'block';
- run.href = '{{=file.path|uri}}?plug=none'; // TODO plug=raw
- download.style.display = 'none';
- break;
- case 'text/x-markdown':
- preview.style.display = 'block';
- preview.href = '{{=file.path|uri}}?plug=markdown';
- break;
- case 'text/x-sequence':
- preview.style.display = 'block';
- preview.href = '{{=file.path|uri}}?plug=sequence';
- break;
- case 'text/javascript':
- run.style.display = 'block';
- run.onclick = function(e) { runJS(); stopEvent(e) };
- break;
- }
-
+
// Update UI elements on content changes
function onChange() {
postMessage(cm.getValue(), '*');
- // Use this instead if browser CPU load is too intense:
- //clearTimeout(delay);
- //delay = setTimeout(function(){postMessage(cm.getValue(), '*');}, 150);
if (cmClient) {
maybeEnable(cmClient.undoStack, undo);
maybeEnable(cmClient.redoStack, redo);
@@ -108,6 +84,7 @@
value: {{=file.content|json|script}},
lineNumbers: lineNumbers,
lineWrapping: lineWrapping,
+ autofocus: true,
theme: theme,
keyMap: keymap,
onChange: onChange
@@ -123,6 +100,77 @@
document.body.className =
document.body.className.replace(/cm-s-\w+/, 'cm-s-' + theme);
}; cm.setTheme(theme);
+
+ // General button actions
+ disable(undo); disable(redo);
+ validate.target = run.target = download.target = settings.target = '_blank';
+ download.href = '{{=file.path|uri}}?plug=none';
+ settings.href = '{{=file.path|uri}}?plug=meta';
+ download.style.display = 'block';
+
+ // Mime type specific button actions
+ switch(mime) {
+ case 'text/javascript': case 'javascript':
+ run.style.display = 'block';
+ run.onclick = function(e) { runJS(); stopEvent(e); };
+ break;
+ case 'text/html': case 'html':
+ unicorn('text/html');
+ preview.style.display = 'block';
+ preview.href = '{{=file.path|uri}}?plug=html';
+ run.style.display = 'block';
+ run.href = '{{=file.path|uri}}?plug=none'; // TODO plug=raw
+ download.style.display = 'none';
+ break;
+ case 'text/x-markdown': case 'markdown':
+ preview.style.display = 'block';
+ preview.href = '{{=file.path|uri}}?plug=markdown';
+ break;
+ case 'text/x-sequence': case 'sequence':
+ preview.style.display = 'block';
+ preview.href = '{{=file.path|uri}}?plug=sequence';
+ break;
+ case 'text/css': case 'css': unicorn('text/css'); break;
+ case 'text/xml': case 'xml': case 'application/xml': unicorn('text/xml'); break;
+ case 'text/x-csrc': codepad('C'); break;
+ case 'text/x-c++src': codepad('C++'); break;
+ case 'text/x-dsrc': codepad('D'); break;
+ case 'text/x-haskell': codepad('Haskell'); break;
+ case 'text/x-lua': codepad('Lua'); break;
+ case 'text/x-ocaml': codepad('OCaml'); break;
+ case 'text/x-php': codepad('PHP'); break;
+ case 'text/x-perl': codepad('Perl'); break;
+ case 'text/x-python': codepad('Python'); break;
+ case 'text/x-ruby': codepad('Ruby'); break;
+ case 'text/x-scheme': codepad('Scheme'); break;
+ case 'text/x-tcl': codepad('Tcl'); break;
+ }
+
+ // Export code to Codepad for remote execution
+ function codepad(lang) {
+ document.export.action = run.href = 'http://codepad.org/';
+ document.export.lang.value = lang;
+ run.style.display = 'block';
+ run.onclick = function(e) {
+ document.export.code.value = cm.getValue();
+ document.export.submit();
+ stopEvent(e);
+ }
+ }
+
+ // Export code to Unicorn for HTML/CSS/XML validation
+ function unicorn(mime) {
+ document.export.action = 'http://validator.w3.org/unicorn/check#validate-by-input';
+ document.export.ucn_text_mime.value = mime;
+ validate.style.display = 'block';
+ validate.href = 'http://validator.w3.org/unicorn/';
+ validate.onclick = function(e) {
+ document.export.ucn_text.value = cm.getValue();
+ document.export.submit();
+ stopEvent(e);
+ }
+ }
+
})();
</script>
101 profiler.html
View
@@ -11,7 +11,7 @@
span.unit { color: #aaa; }
</style>
-<form id=param action="javascript:void 0">
+<form id=param action='javascript:void 0'>
<label> Path: <input id=path></label>
<button type=submit> Get data for that path </button>
</form>
@@ -20,40 +20,69 @@
<script src=lib/js/scout.js?plug=none></script>
<script>
-function esc(str) { return str.replace('<', '&lt;'); }
-
-function templateRow(header, data, unit) {
- return "<tr><th>" + esc(header) + "<td>" + esc('' + data) +
- (unit? " <span class=unit>" + unit + "</span>": '');
-}
-
-function templateSection(name, data) {
- return "<h1>" + esc(name) + "</h1><table>" + data.map(function (row) {
- return templateRow(row.doc, row.data, row.unit);
- }).join('') + "</table>";
-}
-
-function templateProf(data) {
- var str = '';
- for (var e in data) {
- str += templateSection(e, data[e]);
- }
- return str;
-}
-
-var dataElt = null;
-
-function ask (params) {
- console.log("Something happens");
- params.action = 'profiler';
- params.data = {'File system': {path:Scout('#path').value}};
- params.resp = function(resp) {
- dataElt = dataElt || document.getElementById('data');
- dataElt.innerHTML = templateProf(resp);
+ function esc(str) { return str.replace('<', '&lt;'); }
+
+ var formatData = {
+ raw: function(data, unit) {
+ return data + (unit ? ' <span class=unit>' + unit + '</span>' : '');
+ },
+ seconds: function(data, unit) {
+ var s = parseInt(data) % 60,
+ m = parseInt(data / 60) % 60,
+ h = parseInt(data / 3600) % 24,
+ d = parseInt(data / 86400);
+ function digits(n) {
+ return (n < 10 ? '0' + n : n);
+ };
+ return d + ' <span class=unit>days</span> ' +
+ digits(h) + '<span class=unit>:</span class=unit>' +
+ digits(m) + '<span class=unit>:</span class=unit>' +
+ digits(s);
+ },
+ bytes: function(data, unit) {
+ console.log(data,unit);
+ var units = ['','k','M','G','T','P','E','Z','Y'];
+ for (var i = 0, max = 1 ; i < units.length ; i++) {
+ if (data < max * 1024)
+ return parseInt(100 * data / max) / 100 + ' <span class=unit>' + units[i] + 'B</span>';
+ max *= 1024;
+ }
+ }
};
-}
-
-addEventListener('load', Scout.send(ask), false);
-Scout('#param').on('submit', ask);
-
+
+ function templateRow(header, data, unit) {
+ var html = '<tr><th>' + esc(header) + '<td>', data = esc('' + data);
+ return html + (formatData[unit] || formatData.raw)(data, unit);
+ }
+
+ function templateSection(name, data) {
+ return '<h1>' + esc(name) + '</h1><table>' + data.map(function (row) {
+ return templateRow(row.doc, row.data, row.unit);
+ }).join('') + '</table>';
+ }
+
+ function templateProf(data) {
+ var str = '';
+ for (var e in data) {
+ str += templateSection(e, data[e]);
+ }
+ return str;
+ }
+
+ var dataElt = null;
+
+ function ask (params) {
+ params.action = 'profiler';
+ params.data = {'File system': {path:Scout('#path').value}};
+ params.resp = function(resp) {
+ dataElt = dataElt || document.getElementById('data');
+ dataElt.innerHTML = templateProf(resp);
+ };
+ }
+
+ addEventListener('load', Scout.send(ask), false);
+ Scout('#param').on('submit', ask);
</script>
+
+<!-- Google Analytics -->
+<script>var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-27876347-1']);_gaq.push(['_trackPageview']);(function(){var ga=document.createElement('script');ga.type='text/javascript';ga.async=true;ga.src=('https:'==document.location.protocol?'https://ssl':'http://www')+'.google-analytics.com/ga.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);})()</script>
7 sequence.html
View
@@ -6,18 +6,23 @@
<link rel=stylesheet href=/lib/css/preview.css?plug=none>
<iframe id=source src="{{=file.path|uri}}?plug=pencil"></iframe>
+<p>Open issues <a href="https://github.com/tpatel/OpenSequenceDiagrams.js/issues">here</a> if you find something going wrong !</p>
+<div id=error></div>
<div id=preview></div>
<script src=/lib/js/OpenSequenceDiagrams.js?plug=none></script>
<script>
var source = document.getElementById('source'),
+ error = document.getElementById('error'),
preview = document.getElementById('preview');
source.contentWindow.addEventListener('message', function(event) {
var schema = new Schema(),
- error = schema.parseLines(event.data);
+ errorText = schema.parseLines(event.data);
+ error.innerHTML = errorText;
preview.innerHTML = schema.getSVG();
+
});
</script>
34 test/test.erl
View
@@ -0,0 +1,34 @@
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
+%%% Created : 7 May 2012 by mats cronqvist <masse@klarna.com>
+
+%% @doc
+%% Demonstrates how to print a record.
+%% @end
+
+-module('ex').
+-author('mats cronqvist').
+-export([demo/0,
+ rec_info/1]).
+
+-record(demo,{a="One",b="Two",c="Three",d="Four"}).
+
+rec_info(demo) -> record_info(fields,demo).
+
+demo() -> expand_recs(?MODULE,#demo{a="A",b="BB"}).
+
+expand_recs(M,List) when is_list(List) ->
+ [expand_recs(M,L)||L<-List];
+expand_recs(M,Tup) when is_tuple(Tup) ->
+ case tuple_size(Tup) of
+ L when L < 1 -> Tup;
+ L ->
+ try Fields = M:rec_info(element(1,Tup)),
+ L = length(Fields)+1,
+ lists:zip(Fields,expand_recs(M,tl(tuple_to_list(Tup))))
+ catch _:_ ->
+ list_to_tuple(expand_recs(M,tuple_to_list(Tup)))
+ end
+ end;
+expand_recs(_,Term) ->
+ Term.
+
52 test/test.sequence
View
@@ -2,7 +2,55 @@ participant Bob
participant Alice
participant "I have a really\nlong name" as L
-Alice->Bob: Authentication Request
+loop 10 times
+ Alice->Bob: Authentication Request
+end
Bob-->Alice: Authentication Response
Bob->L: Log transaction
-Alice->Alice: This is a signal to self.
+Alice->Alice: Entertain "I have a really\nlong name".
+
+opt
+ state over L : this is bug report ^^ \n (handle a dynamic distance between bob & alice probably come first)
+end
+
+loop 9001 times
+ loop 2 times
+ opt
+ L->Bob:spamming you
+ end
+ end
+ opt
+ parallel {
+ Bob->Alice:stop
+ Alice-->L: he said stop!!!1
+ }
+ end
+end
+participant Bob
+participant Alice
+participant "I have a really\nlong name" as L
+
+loop 10 times
+ Alice->Bob: Authentication Request
+end
+Bob-->Alice: Authentication Response
+Bob->L: Log transaction
+Alice->Alice: Entertain "I have a really\nlong name".
+
+opt
+ state over L : this is bug report ^^ \n (handle a dynamic distance between bob & alice probably come first)
+end
+
+loop 9001 times
+ loop 2 times
+ opt
+ L->Bob:spamming you
+ end
+ end
+ opt
+ parallel {
+ Bob->Alice:stop
+ Alice-->L: he said stop!!!1
+ }
+ end
+end

No commit comments for this range

Something went wrong with that request. Please try again.