Skip to content

Instantly share code, notes, and snippets.

@magmoro
Created March 9, 2009 16:39
Show Gist options
  • Save magmoro/76366 to your computer and use it in GitHub Desktop.
Save magmoro/76366 to your computer and use it in GitHub Desktop.
xml builder
h2, h3, h4{
font-weight:normal;
font-family:Georgia, serif;
padding-left:.5em;
}
h2{
background:#c3c3c3;
border-bottom:solid 1px #959595;
color:#6a6a6a;
font-size:28px;
}
h3{
background:#d7d7d7;
border-bottom:solid 1px #adadad;
color:#6a6a6a;
font-size:23px;
}
h4{
background:#e6e6e6;
border-bottom:solid 1px #bcbcbc;
color:#6a6a6a;
font-size:19px;
}
.builder{
background:#f0f0f0;
}
.builder label{
display:block;
line-height:1.5em;
color:#58657a;
border-bottom:solid 1px #e2e2e2;
padding-left:0.2em;
}
.builder input{
margin-right:1em;
}
.name{
color:#000;
}
.child{
margin-left:1.5em;
}
.download{
text-align:center;
padding:20px;
background:#dfdfdf;
}
#download{
font-weight:bold;
color:#6a6a6a;
}
var Builder=new Class({
Implements: [Events, Options],
options:{
url: 'deps.xml'
},
initialize: function(options){
this.setOptions(options);
this.element=new Element('div', {'class': 'builder'});
this.load();
},
load: function(){
new Request({
url: this.options.url,
method: 'get',
onComplete: function(xmlString){
var xmlDoc=XML.rootFromString(xmlString);
this.xmlDoc=xmlDoc;
this.makeHtml(xmlDoc);
this.initEvents();
}.bind(this)
}).send();
},
inject: function(element, how){
this.element.inject(element, how);
},
makeHtml: function(xmlDoc){
var documentElement=xmlDoc.documentElement;
var children=documentElement.childNodes;
var mainHtml=[];
var externHtml=[];
for(var i=0,l=children.length;i<l;i++){
var child=children[i];
if(child.nodeType==3) continue;
var extern=child.getAttribute('extern')=='true' ? true : false;
var how = extern ? 'bottom' : 'top';
if(extern){
externHtml.push('<h3>'+child.tagName+'</h3>');
externHtml.push(this.makeNodeHtml(child));
}else{
mainHtml.push('<h2>'+child.tagName+'</h2>');
mainHtml.push(this.makeNodeHtml(child));
};
}
this.element.set('html','<div class="main" id="main">'+mainHtml.join('')+'</div>'+
'<div class="extern" id="extern"><h2>External scripts</h2>'+externHtml.join('')+'</div>'+
'<div class="compress"><h2>Compressor</h2>'+
'<div class="child">'+
'<label for="packer"><input type="radio" name="compression" value="packer" id="packer" />Dean Edwards packer</label>'+
'<label class="description" for="jsmin"><input type="radio" name="compression" value="none" id="jsmin" />jsmin</label>'+
'<label class="description" for="uncompressed"><input type="radio" name="compression" value="none" id="uncompressed" />uncompressed</label>'+
'</div>'+
'</div>'+
'<div class="download"><input type="button" value="DOWNLOAD" id="download"></input></div>');
},
makeNodeHtml: function(root){
var html=[];
var children=root.childNodes;
for(var i=0, l=children.length;i<l;i++){
var child=children[i];
if(child.nodeType==3) continue;
if(child.childNodes.length>0 && !child.getAttribute('group')){
var hN='h'+(this.getLevel(child));
html.push('<'+hN+'>'+child.tagName+'</'+hN+'>');
html.push('<div class="child">'+this.makeNodeHtml(child)+'</div>');
}else{
html.push('<div class="child"><label><input type="checkbox" xpath="'+this.getXpath(child)+'"/><span class="name">'+child.tagName+'</span><span class="desc"> &mdash; '+child.getAttribute('desc')+'</span></label></div>');
}
}
return html.join('');
},
getLevel: function(node){
var level=-1;
while(node){
node=node.parentNode;
level++;
}
return level;
},
getXpath: function(node){
var xpath=[];
xpath.push(node.tagName);
while(node.parentNode){
node=node.parentNode;
xpath.push(node.tagName);
}
return xpath.reverse().join('/');
},
initEvents: function(){
this.element.getElements('input[type="checkbox"]').each(function(checkbox){
checkbox.addEvent('click', function(){
checkbox.checked ? this.check(checkbox) : this.uncheck(checkbox);
}.bind(this));
}, this);
},
getXmlNode: function(checkbox){
return XML.getNode(this.xmlDoc, checkbox.getAttribute('xpath'));
},
getCheckbox: function(node){
return this.element.getElement('input[xpath="'+this.getXpath(node)+'"]');
},
getDeps: function(xmlNode){
var deps=xmlNode.getAttribute('deps');
if(deps){
deps=deps.split(' ');
deps=deps.map(function(dep){
if(dep.substring(0,1)=='/') dep='/deps'+dep;
try{
var node=XML.getNode(xmlNode, dep);
}catch(e){}
if(!node) throw new Error('xpath:"'+dep+'" from node:"'+this.getXpath(xmlNode)+'" return empty result');
return node;
}, this);
return deps;
}
return [];
},
check: function(checkbox){
checkbox.checked=true;
this.checkDependants(checkbox);
},
checkDependants: function(checkbox){
var xmlNode=this.getXmlNode(checkbox);
var parent=xmlNode;
while(1){
parent=parent.parentNode;
if(!parent||parent.tagName=='deps') break;
this.checkNodes(this.getDeps(parent));
}
this.checkNodes(this.getDeps(xmlNode));
},
checkNodes: function(nodes){
nodes.each(this.checkNode, this);
},
checkNode: function(node){
if(node.childNodes.length && !node.getAttribute('group')){
this.checkChildren(node);
}
var checkbox=this.getCheckbox(node);
if(!checkbox) return;
if(!checkbox.checked){
this.check(checkbox);
}
},
checkChildren: function(node){
var children=node.childNodes;
for(var i=0, l=children.length; i<l; i++){
var child=children[i];
if(child.nodeType==3) continue;
this.checkNode(child);
}
},
uncheck: function(checkbox){
checkbox.checked=false;
this.uncheckDepending(checkbox);
},
uncheckDepending: function(checkbox){
this.element.getElements('input[type="checkbox"]:checked').each(function(input){
var testNode=this.getXmlNode(input);
var node=this.getXmlNode(checkbox);
var deps=this.getDeps(testNode);
while(1){
testNode=testNode.parentNode;
if(!testNode||testNode.tagName=='deps') break;
deps.combine(this.getDeps(testNode));
}
if(!deps.length) return;
while(1){
if(deps.contains(node)){
this.uncheck(input);
return;
}
node=node.parentNode;
if(!node||node.tagName=='deps') break;
}
}, this);
}
});
var XML = {
rootFromString: function(string){
var root;
if (Browser.Engine.trident){
root = new ActiveXObject('Microsoft.XMLDOM');
root.async = false;
root.loadXML(string);
}else{
root = new DOMParser().parseFromString(string, 'text/xml');
}
return root;
},
getNodes: function(node, xpath){
var found=[], foundNodes;
var root=node.ownerDocument||node;
if(Browser.Engine.trident){
root.setProperty("SelectionLanguage","XPath");
foundNodes=node.selectNodes(xpath)
for(var i=0, l=foundNodes.length; i<l; i++) found.push(foundNodes[i]);
}else{
foundNodes=root.evaluate(xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i=0, l=foundNodes.snapshotLength; i<l; i++) found.push(foundNodes.snapshotItem(i));
}
return found;
},
getNode: function(node, xpath){
return XML.getNodes(node, xpath)[0];
}
}
window.addEvent('domready', function(){
var builder=new Builder();
builder.inject('container');
});
<?xml version="1.0" encoding="utf-8"?>
<deps>
<mootools extern="true">
<mootools desc="mootools core" />
</mootools>
<moocanvas extern="true">
<moocanvas deps="/mootools" desc="vml based canvas for mootools"/>
</moocanvas>
<Mif deps="Core">
<Core>
<Mif deps="/mootools" desc="Mif core" />
</Core>
<Tree>
<Core group="true" desc="Tree control">
<Tree desc="Mif.Tree control class" css="Tree/Tree.css" />
<Node desc="Mif.Tree node class" />
<Draw desc="drawing Mif.Tree(create html code)" />
<Selection desc="implements selection" />
<Hover desc="implements hover effect" ></Hover>
<Load desc="load nodes from json, load json" />
<mootools-patch desc="fix mootools bugs patch" />
</Core>
<More deps="../Core">
<KeyNav desc="implement Mif.Tree keyboard navigation" />
<Sort desc="make Mif.Tree sortable" />
<Transform desc="implements move, copy, romove functionality" />
<Drag deps="../Transform" desc="implements Drag'n'Drop" />
<Drag.Element deps="../Drag" desc="dom elements can be used as drop containers" />
<Rename desc="implements inline rename node functionality" />
<Checkbox desc="checkbox implementation" />
<CookieStorage desc="cookie collapse/expand state storage" />
<Search desc="implement search/filter functionality" />
</More>
</Tree>
<Menu>
<Core group="true" desc="Menu control">
<Menu desc="Mif.Menu control base class" />
<List desc="menu list Class" />
<Item desc="menu item Class" />
<Utils desc="util functionality for menu" />
<Container desc="container with shadow" />
<CanvasContainer desc="container canvas graphic" />
</Core>
<More deps="../Core">
<KeyNav desc="KeyNav implementation" />
</More>
</Menu>
</Mif>
</deps>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment