var Module = Class.create( {
initialize: function() {
var options = Object.extend( {}, arguments[0] || {} );
if ( !Module.sources ) {
Module.sources = {};
Module.workarea = new Element( 'div', { 'style': 'display:none', id: 'workarea' } );
document.body.appendChild( Module.workarea );
}
if ( options.source )
this._set_doms( options.source );
else if ( this.source )
this._set_doms( this.source );
if ( this.source_doms && this.source_doms.length ) {
if ( this.doms ) {
for ( var d = 0 ; d < this.doms.length ; d ++ )
Module.workarea.appendChild( this.doms[d] );
}
else {
this.doms = [];
for ( var d = 0 ; d < this.source_doms.length ; d ++ ) {
var dom = this.source_doms[d].cloneNode( true );
this.doms.push( dom );
Module.workarea.appendChild( dom );
}
}
if ( this.unique_ids && this.unique_ids.length ) {
this.unique_index = this._generate_module_index();
for ( var i = 0 ; i < this.unique_ids.length ; i ++ ) {
this.make_unique( this.unique_ids[i] );
}
}
}
if ( options.attach_to )
this.attach( options.attach_to );
},
attach: function( id ) {
this.doms.each( function ( dom ) {
dom.parentNode.removeChild( dom );
$(id).appendChild( dom );
} );
},
insert: function( element, position ) {
var doms = this.doms;
if ( position == "top" || position == "before" )
doms = this.doms.reverse();
var content = {};
doms.each( function ( dom ) {
dom.parentNode.removeChild( dom );
content[position] = dom;
Element.insert( $(element), content );
} );
},
attach_before: function( id ) {
this.doms.each( function ( dom ) {
dom.parentNode.removeChild( dom );
$(id).parentNode.insertBefore( dom, $(id) );
} );
},
detach: function() {
this.doms.each( function ( dom ) {
dom.parentNode.removeChild( dom );
Module.workarea.appendChild( dom );
} );
},
$: function( id ) {
return $( this.id( id ) );
},
id: function( id ) {
return this.source_name + "_" + id + "_" + this.unique_index;
},
make_unique: function( id ) {
var element = $(id);
if ( !element )
for ( var i = 0 ; !element && i < this.doms.length ; i ++ )
element = Module.find_element_with_id( this.doms[i], id );
element.id = this.id( id );
},
_set_doms: function( source ) {
var html_source_id = source[0];
var source_id = Module.make_non_unique( html_source_id );
this.source_name = source_id;
var options = Object.extend( {}, source[1] || {} );
if ( source_id != html_source_id || options.unique ) {
$(html_source_id).id = source_id;
source[0] = source_id;
}
if ( options.unique || source_id != html_source_id || !Module.sources[source_id] ) {
this.source_doms = Module.make_doms( source );
if ( !Module.sources[source_id] ) {
Module.sources[source_id] = {
indexer: Module.create_indexer()
};
}
if ( source_id != html_source_id || options.unique )
this.doms = this.source_doms;
else
Module.sources[source_id].doms = this.source_doms;
}
else
this.source_doms = Module.sources[source_id].doms;
this._generate_module_index = Module.sources[source_id].indexer;
}
} );
Module.make_non_unique = function ( id ) {
var id_index = id.match( "_[0-9]+$" );
if ( id_index )
return id.substr ( 0, id.length - id_index[0].length );
else
return id;
};
Module.find_element_with_id = function( root, id ) {
if ( root.id == id )
return root;
else {
if ( root.hasChildNodes() ) {
for ( var i = 0 ; i < root.childNodes.length ; i ++ ) {
var element = Module.find_element_with_id( root.childNodes[i], id );
if ( element )
return element;
}
}
}
return false;
};
Module.create_indexer = function() {
var index = 0;
return function() {
index += 1;
return index;
};
};
Module.make_doms = function ( source ) {
var source_id = source[0];
var options = source[1];
var parent;
var doms = [];
if ( options && options.inside ) {
parent = $(source_id);
var children = parent.childNodes;
for ( var i = 0 ; i < parent.childNodes.length ; i ++ )
doms.push( parent.childNodes[i] );
if ( !source.keep )
while( parent.childNodes.length )
parent.removeChild( parent.firstChild );
}
else {
parent = $(source_id).parentNode;
doms.push( $(source_id).remove() );
}
if ( options && options.removeParent ) {
parent.parentNode.removeChild( parent );
}
return doms;
};

