Skip to content

Instantly share code, notes, and snippets.

@Zirak
Created December 6, 2012 15:20
Show Gist options
  • Save Zirak/4225242 to your computer and use it in GitHub Desktop.
Save Zirak/4225242 to your computer and use it in GitHub Desktop.
util for text search/replace for DOM output
var fragger = {
root : null,
cur_root : null, //ungh, but I can't find a better place...
last_index : null,
new : function () {
return Object.create( this );
},
init : function ( text ) {
this.root = document.createDocumentFragment();
this.root.appendChild( document.createTextNode(text) );
},
replace : function ( re, fun ) {
this.last_index = 0;
var list = this.getTextNodes(),
bound = this.actual_replace.bind( this, fun ),
cur;
while ( cur = list.pop() ) {
this.cur_root = document.createDocumentFragment();
cur.data.replace( re, bound );
this.append_text( cur.data, this.last_index );
this.root.replaceChild( this.cur_root, cur );
}
return this.root;
},
/*
For getting this far through the code, here is some pie:
(
)
__..---..__
,-=' / | \ `=-.
:--..___________..--;
\.,_____________,./
*/
actual_replace : function ( cb, match ) {
var args = [].slice.call( arguments ),
str = args[ args.length - 1 ],
offset = args[ args.length - 2 ];
this.append_text( str, this.last_index, offset );
var node = cb.apply( null, args.slice(1) );
if ( node && node.nodeType ) {
this.cur_root.appendChild( node );
this.last_index = offset + match.length;
}
},
append_text : function ( str, begin, end ) {
if ( begin === end ) {
return;
}
var node = document.createTextNode();
node.data = str.slice( begin, end );
this.cur_root.appendChild( node );
},
getTextNodes : function () {
return [].filter.call( this.root.childNodes, text_node_check );
function text_node_check ( node ) {
return node && node.nodeType === 3;
}
}
};
var frag = fragger.new();
frag.init( 'foobar' );
frag.replace( /foo/, replacer );
document.body.appendChild( frag.root );
//instead of directly accessing frag.root, you can store the result of frag.replace
//input: the capturing groups
function replacer ( $0 ) {
var ret = document.createElement( 'div' );
ret.textContent = 'lulz ' + $0;
//output: node to replace caught text with
// if you want just text, return a text node
return ret;
}
//you can see it in action either here:
// http://zirak.github.com/SO-ChatBot/
//as the mini-md formatter, or in this demo:
// http://tinkerbin.com/E5ZL7RV7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment