Created
July 17, 2009 13:43
-
-
Save FND/149056 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[submodule "wireit"] | |
path = wireit | |
url = git://github.com/neyric/wireit.git | |
[submodule "scripts/chrjs"] | |
path = scripts/chrjs | |
url = git://github.com/tiddlyweb/chrjs.git |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TiddlyWebConfigurator | |
visual configuration of bags and recipes | |
N.B.: | |
This repository includes chrjs and WireIt as submodules: | |
http://github.com/tiddlyweb/chrjs | |
http://github.com/neyric/wireit | |
After cloning, run the following commands: | |
$ git submodules init | |
$ git submodules update |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var layer = null; | |
/* LOAD FROM TIDDLYWEB */ | |
function lookupModule(matchObj,layer) { | |
var container; | |
var match; | |
var matchObjects = function(obj1,obj2) { | |
for(var n in obj1) { | |
if(obj1.hasOwnProperty(n)) { | |
// ignore functions | |
if(typeof obj1[n]!=='function' && obj2[n]) { | |
if(typeof obj1[n]==='object') { // catches arrays and objects | |
if(!arguments.callee(obj1[n],obj2[n])) { | |
return false; | |
} | |
} else { | |
if(obj2[n]!==obj1[n]) { | |
return false; | |
} | |
} | |
} | |
} | |
} | |
return true; | |
}; | |
for(var i=0;i<layer.containers.length;i++) { | |
container = layer.containers[i]; | |
match = null; | |
if(matchObjects(matchObj,container)) { | |
match = i; | |
break; | |
} | |
} | |
return match; | |
} | |
function loadFromTiddlyWeb() { | |
var addRecipes = function(recipes) { | |
var recipe; | |
var pos; | |
for(var i=0;i<recipes.length;i++) { | |
recipe = recipes[i]; | |
pos = calculateVerticalLayout(i,{x:700,y:400},150); | |
addRecipe({ name: recipe, pos_x: pos.x, pos_y: pos.y }, layer); | |
tiddlyweb.loadRecipe(recipe,function() { | |
var recipeName = recipe; | |
return function(recipeObj) { | |
var recipeBags = recipeObj.recipe; | |
var bag; | |
var wireConfig; | |
var moduleId = 0; | |
var recipeId = lookupModule({ | |
type:'recipe', | |
options: { | |
title:recipeName | |
} | |
},layer); | |
for(var i=0;i<recipeBags.length;i++) { | |
bag = recipeBags[i][0]; | |
bagId = lookupModule({ | |
type:'bag', | |
options: { | |
title:bag | |
} | |
},layer); | |
wireConfig = { | |
src: { moduleId: bagId, terminal: "tiddlers"}, | |
tgt: { moduleId: recipeId, terminal: "tiddlers" } | |
}; | |
layer.addWire(wireConfig,layer); | |
} | |
} | |
}()); | |
} | |
}; | |
var addBags = function(bags) { | |
var bag; | |
var pos; | |
for(var i=0;i<bags.length;i++) { | |
bag = bags[i]; | |
pos = calculateVerticalLayout(i,{x:400,y:0},250); | |
addBag({ name: bag, pos_x: pos.x, pos_y: pos.y}, layer); | |
} | |
tiddlyweb.loadRecipes(addRecipes); | |
}; | |
tiddlyweb.loadBags(addBags); | |
} | |
/* end of LOAD FROM TIDDLYWEB */ | |
/* ADDING MODULES */ | |
// n runs from 0 to N-1, where N is the number of items to be laid out | |
function calculateVerticalLayout(n,offset,height) { | |
if(!offset) { | |
offset = {x:0,y:0}; | |
} | |
var pos = { | |
x:offset.x, | |
y:offset.y | |
}; | |
if(!height) { | |
height = 100; | |
} | |
pos.y += n*height; | |
return pos; | |
} | |
function addBag(bag, layer) { | |
bag = YAHOO.lang.merge(bag, { type: "bag" }); | |
return addContainer(bag, layer); | |
} | |
function addRecipe(recipe, layer) { | |
recipe = YAHOO.lang.merge(recipe, { type: "recipe" }); | |
return addContainer(recipe, layer); | |
} | |
function addContainer(obj, layer) { | |
var x = obj.pos_x || 0; | |
var y = obj.pos_y || 0; | |
var permissions = ["write", "create", "delete", "manage", "accept"]; | |
var container = { | |
xtype: "WireIt.InOutContainer", | |
inputs: obj.type == "bag" ? permissions : ["tiddlers"], | |
outputs: [obj.type == "bag" ? "tiddlers" : "document"], | |
title: obj.name, | |
position: [x, y], | |
close: false | |
}; | |
container = layer.addContainer(container); | |
container.type = obj.type; | |
var el = container.el; | |
el.title = obj.desc || ""; // XXX: don't use title? -- XXX: use setAttribute? | |
YAHOO.util.Dom.addClass(el, obj.type); | |
return container; | |
} | |
/* ADDING MODULES */ | |
/* AUTO-RESIZE OF InOut MODULES */ | |
function addExtraInput(container,name) { | |
addExtraTerminal(container,name,"input"); | |
} | |
function addExtraOutput(container,name) { | |
addExtraTerminal(container,name,"output"); | |
} | |
// defaults to adding an input | |
function addExtraTerminal(container,name,type) { | |
if(type!=="input" && type!=="output") { | |
return false; | |
} | |
if(!name) { | |
return false; | |
} | |
var i = container.terminals.length; | |
var notType = type === "output" ? "input" : "output"; | |
var alwaysSrc = type === "output" ? true : false; | |
var direction = type === "output" ? [-1,0] : [1,0]; | |
var align = type === "output" ? "right" : "left"; | |
var offsetPosition = {}; | |
offsetPosition[align] = -14; | |
offsetPosition.top = 3+30*(i+1); | |
container.options.terminals.push({ | |
"name": name, | |
"direction": direction, | |
"offsetPosition": offsetPosition, | |
"ddConfig": { | |
"type": type, | |
"allowedTypes": [notType] | |
}, | |
"alwaysSrc": alwaysSrc | |
}); | |
container.bodyEl.appendChild(WireIt.cn('div', null, {lineHeight: "30px", textAlign: align}, name)); | |
container.addTerminal(container.options.terminals[container.options.terminals.length-1]); | |
} | |
/* end of AUTO-RESIZE OF InOut MODULES */ | |
/* SAVING TO TIDDLYWEB */ | |
function configure() { | |
var v = getValue(layer); | |
var tw = convertFromWorkingToTiddlyWeb(v.working); | |
saveEntities(tw.bags, tw.recipes); | |
} | |
function saveEntities(bags, recipes) { | |
for(var bag in bags) { | |
this.saveBag(bag, tw.bags[bag]); | |
} | |
for(var recipe in recipes) { | |
// add filters | |
recipe = recipe.map(function(item, i) { | |
return [item, ""]; | |
}); | |
this.saveRecipe(recipe, tw.recipes[recipe]); | |
} | |
} | |
// mainly nicked from WiringEditor.js | |
function getValue(layer) { | |
var i; | |
var obj = {modules: [], wires: []}; | |
for (i=0; i<layer.containers.length; i++) { | |
obj.modules.push( {name: layer.containers[i].options.title, type: layer.containers[i].type, value: layer.containers[i].getValue(), config: layer.containers[i].getConfig()}); | |
} | |
for(i=0; i<layer.wires.length; i++) { | |
var wire = layer.wires[i]; | |
var wireObj = { | |
src: {moduleId: WireIt.indexOf(wire.terminal1.container, layer.containers), terminal: wire.terminal1.options.name}, | |
tgt: {moduleId: WireIt.indexOf(wire.terminal2.container, layer.containers), terminal: wire.terminal2.options.name} | |
}; | |
obj.wires.push(wireObj); | |
} | |
return { | |
working: obj | |
}; | |
} | |
/* | |
A bag is: | |
bagName: { | |
write: ["GUEST",...], | |
create: ["GUEST",...], | |
delete: ["GUEST",...], | |
manage: ["GUEST",...], | |
accept: ["GUEST",...] | |
} | |
A recipe is: | |
recipeName: ["bag A","bag B",...] | |
*/ | |
function convertFromWorkingToTiddlyWeb(working) { | |
// modules -> nodes | |
var module = {}; | |
var nodes = {}; | |
for(var i=0;i<working.modules.length;i++) { | |
module = working.modules[i]; | |
name = module.name; | |
nodes[name] = { | |
type:module.type, | |
inputs:{}, | |
outputs:{} | |
}; | |
} | |
// wires -> edges | |
var wire = {}; | |
var to_node, to_channel, from_node, from_channel; | |
for(i=0;i<working.wires.length;i++) { | |
wire = working.wires[i]; | |
to_node = working.modules[wire.tgt.moduleId].name; | |
to_channel = wire.tgt.terminal; | |
from_node = working.modules[wire.src.moduleId].name; | |
from_channel = wire.src.terminal; | |
if(!nodes[to_node].inputs[to_channel]) { | |
nodes[to_node].inputs[to_channel] = []; | |
} | |
nodes[to_node].inputs[to_channel].push(from_node); | |
if(!nodes[from_node].outputs[from_channel]) { | |
nodes[from_node].outputs[from_channel] = []; | |
} | |
nodes[from_node].outputs[from_channel].push(to_node); | |
} | |
console.log('nodes with wires',nodes); | |
// nodes -> bags, recipes | |
var tiddlyweb = { | |
bags: {}, | |
recipes: {} | |
}; | |
var node; | |
var bag, recipe; | |
for(i in nodes) { | |
node = nodes[i]; | |
var j; | |
switch(node.type) { | |
case "bag": | |
bag = {}; | |
// for each role attached to my various terminals, push the name into the appropriate property's array | |
/* | |
"write": ["GUEST",...], | |
"create": ["GUEST",...], | |
"delete": ["GUEST",...], | |
"manage": ["GUEST",...], | |
"accept": ["GUEST",...] | |
*/ | |
for(j in node.inputs) { | |
bag[j] = node.inputs[j]; | |
} | |
tiddlyweb.bags[i] = bag; | |
break; | |
case "recipe": | |
recipe = []; | |
// for each bag connected to me, push the name into recipe | |
for(j in node.inputs) { | |
for(var k=0; k<node.inputs[j].length; k++) { | |
recipe.push(node.inputs[j][k]); | |
} | |
} | |
tiddlyweb.recipes[i] = recipe; | |
break; | |
} | |
} | |
return tiddlyweb; | |
} | |
/* end of SAVING TO TIDDLYWEB */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>TiddlyWeb Configurator proof of concept</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<!-- YUI --> | |
<link rel="stylesheet" type="text/css" href="wireit/lib/yui/fonts/fonts-min.css" /> | |
<link rel="stylesheet" type="text/css" href="wireit/lib/yui/reset/reset-min.css" /> | |
<!-- WireIt --> | |
<link rel="stylesheet" type="text/css" href="wireit/css/WireIt.css" /> | |
<!-- TiddlyWebConfigurator --> | |
<link rel="stylesheet" type="text/css" href="styles/main.css" /> | |
<!-- YUI --> | |
<script type="text/javascript" src="wireit/lib/yui/utilities/utilities.js"></script> | |
<script type="text/javascript" src="wireit/lib/yui/json/json-min.js"></script> | |
<!-- jQuery - required for TiddlyWeb adaptor --> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> | |
<script type="text/javascript" src="scripts/jquery-json.js"></script> | |
<script type="text/javascript"> | |
jQuery.noConflict(); | |
</script> | |
<!-- Excanvas --> | |
<!--[if IE]><script type="text/javascript" src="wireit/lib/excanvas.js"></script><![endif]--> | |
<!-- WireIt --> | |
<script type="text/javascript" src="wireit/js/WireIt.js"></script> | |
<script type="text/javascript" src="wireit/js/CanvasElement.js"></script> | |
<script type="text/javascript" src="wireit/js/Wire.js"></script> | |
<script type="text/javascript" src="wireit/js/Terminal.js"></script> | |
<script type="text/javascript" src="wireit/js/util/Anim.js"></script> | |
<script type="text/javascript" src="wireit/js/util/DD.js"></script> | |
<script type="text/javascript" src="wireit/js/util/DDResize.js"></script> | |
<script type="text/javascript" src="wireit/js/Container.js"></script> | |
<script type="text/javascript" src="wireit/js/Layer.js"></script> | |
<script type="text/javascript" src="wireit/js/Layout.js"></script> | |
<script type="text/javascript" src="wireit/js/InOutContainer.js"></script> | |
<!-- TiddlyWebConfigurator --> | |
<script type="text/javascript" language="JavaScript" src="scripts/main.js"></script> | |
<script type="text/javascript" language="JavaScript" src="scripts/configurator.js"></script> | |
<script type="text/javascript" language="JavaScript" src="scripts/chrjs/main.js"></script> | |
</head> | |
<body> | |
<div id="wrapper"> | |
<div id="canvas"></div> | |
<button onclick="configure();">Go configure!</button> | |
</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($){function toIntegersAtLease(n) | |
{return n<10?'0'+n:n;} | |
Date.prototype.toJSON=function(date) | |
{return this.getUTCFullYear()+'-'+ | |
toIntegersAtLease(this.getUTCMonth())+'-'+ | |
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string) | |
{if(escapeable.test(string)) | |
{return'"'+string.replace(escapeable,function(a) | |
{var c=meta[a];if(typeof c==='string'){return c;} | |
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';} | |
return'"'+string+'"';};$.toJSON=function(o,compact) | |
{var type=typeof(o);if(type=="undefined") | |
return"undefined";else if(type=="number"||type=="boolean") | |
return o+"";else if(o===null) | |
return"null";if(type=="string") | |
{return $.quoteString(o);} | |
if(type=="object"&&typeof o.toJSON=="function") | |
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number") | |
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));} | |
if(compact) | |
return"["+ret.join(",")+"]";else | |
return"["+ret.join(", ")+"]";} | |
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");} | |
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number") | |
name='"'+k+'"';else if(type=="string") | |
name=$.quoteString(k);else | |
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;} | |
if(compact) | |
ret.push(name+":"+val);else | |
ret.push(name+": "+val);} | |
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o) | |
{return $.toJSON(o,true);};$.evalJSON=function(src) | |
{return eval("("+src+")");};$.secureEvalJSON=function(src) | |
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered)) | |
return eval("("+src+")");else | |
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#wrapper { | |
padding: 10px; | |
} | |
div.WireIt-Layer { | |
overflow: auto; | |
} | |
div.bag div.body { | |
background-color: #F8F8F8; | |
} | |
div.recipe div.body { | |
background-color: #FFE; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function init() { | |
try { // XXX: DEBUG | |
tiddlyweb.host = "http://tiddlyweb.peermore.com/wiki"; | |
var canvas = document.getElementById("canvas"); // TODO: use YUI selector? | |
layer = new WireIt.Layer({ parentEl: canvas }); | |
loadFromTiddlyWeb(); | |
} catch(e) { | |
console.log(e); | |
} | |
} | |
YAHOO.util.Event.onDOMReady(init); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment