Skip to content

Commit

Permalink
Added support for use of HTML entities within template markup.
Browse files Browse the repository at this point in the history
Added HTML encoding of values when using ${someData} in templates.

Simplified afterManip callback, removing parentCtx parameter, which is not needed.
  • Loading branch information
BorisMoore committed Jul 6, 2010
1 parent 8f167dc commit a23f329
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 35 deletions.
10 changes: 5 additions & 5 deletions demos/samplesCore/composition.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@
}

function getTemplate( key ) {
return $("#tmpl" + key).tmpl();
return $( "#tmpl" + key ).tmpl();
}

$(function(){
// Create named template, to be used in composition below
$.templates.citySeparator = $.tmpl( '<tr class="citySeparator"><td colspan="2"></td></tr>' );

$("#tmplPeople")
$( "#tmplPeople" )
.tmpl( people )
.appendTo(".peopleTable");
$("#tmplSeparator")
.appendTo( ".peopleTable" );
$( "#tmplSeparator" )
.tmpl( {} )
.appendTo(".peopleTable");
.appendTo( ".peopleTable" );
});
</script>

Expand Down
10 changes: 5 additions & 5 deletions demos/samplesTmplPlus/composition.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@
}

function getTemplate( key ) {
return $.tmpl("#tmpl" + key);
return $( "#tmpl" + key ).tmpl();
}

$(function(){
$(".peopleTable")
.append("#tmplPeople", people );
$(".peopleTable")
.append("#tmplSeparator", {});
$( ".peopleTable" )
.append( "#tmplPeople", people );
$( ".peopleTable" )
.append( "#tmplSeparator", {} );
});
</script>

Expand Down
53 changes: 33 additions & 20 deletions jquery.tmpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
return jQuery.tmpl( tmpl, data, options, parentCtx || topCtx, true );
});
}
// If no arguments, used to get template context of first wrapped DOM element
// If no arguments, used to get template context of first wrapped DOM element,
// or, if it is a template script block, the compiled template
return jQuery.tmpl( this[0] );
},

Expand All @@ -97,7 +98,7 @@
if ( ctx && cloneIndex ) {
dmArgs[2] = function( fragClone ) {
// Handler called by oldManip when rendered template has been inserted into DOM.
jQuery.tmpl.afterManip( topCtx, this, fragClone, callback );
jQuery.tmpl.afterManip( this, fragClone, callback );
}
}
oldManip.apply( this, dmArgs );
Expand Down Expand Up @@ -132,7 +133,7 @@
// They can stick it in jQuery.templates to cache it.
tmpl = tmplFn( tmpl )
} else if ( fn = jQuery.templates[ tmpl ] ) {
// Use a pre-defined template, if available
// Use a pre-defined template, if available
tmpl = fn;
} else {
// It's a selector
Expand Down Expand Up @@ -202,17 +203,28 @@
// top-level template
ret = ret.join("");

// Support templates which have initial or final text nodes
// Support templates which have initial or final text nodes, or consist only of text
// Also support HTML entities within the HTML markup.
ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) {
frag = jQuery( middle ).get(); // For now use get(), since buildFragment is not current public
// frag = jQuery.buildFragment( [middle] ); // If buildFragment was public, could do these two lines instead
// frag = frag.cacheable ? frag.fragment.cloneNode(true) : frag.fragment;

storeContexts( frag );
if ( !!before ) frag.unshift( document.createTextNode( before ));
if ( !!after ) frag.push( document.createTextNode( after ));
});
return frag ? frag : document.createTextNode( ret );
if ( !!before ) {
frag = unencode( before ).concat(frag);
}
if ( !!after ) {
frag = frag.concat(unencode( after ));
}
});
return frag ? frag : unencode( ret );
function unencode( text ) {
// createTextNode will not render HTML entities correctly
var el = document.createElement( "<span></span>");
el.innerHTML = text;
return jQuery.makeArray(el.childNodes);
}
}

function tmplFn( markup ) {
Expand Down Expand Up @@ -265,14 +277,16 @@
}
},

// You can stick pre-built template functions here
templates: {},
/*
* For example, someone could do:
* jQuery.templates.foo = jQuery.tmpl("some long templating string");
* $("#test").append("foo", data);
*/

// You can cache a named template using $.templates( name, tmpl );
// which is equivalent to $.templates[name] = $.tmpl( tmpl);
// tmpl is a string, a script element or a selector to a script element, etc.
// To get a cached template, use $.templates( name ) where name is a selector or a previously named template.
templates: function( name, tmpl ) {
if (tmpl) {
return jQuery.templates[name] = jQuery.tmpl( tmpl );
}
return jQuery.templates[name] || jQuery( name ).tmpl();
},
tmplTags: {
"tmpl": {
_default: { $2: "{}" },
Expand Down Expand Up @@ -302,16 +316,16 @@
}
},
encode: function( text ) {
// This should probably do HTML encoding replacing < > & and' and " by corresponding entities.
return text != null ? document.createTextNode( text.toString() ).nodeValue : "";
// Do HTML encoding replacing < > & and ' and " by corresponding entities.
return ("" + text).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;");
}
});

jQuery.extend( jQuery.tmpl, {
complete: function( ctxs ) {
newCtxs = {};
},
afterManip: function afterManip( parentCtx, elem, fragClone, callback ) {
afterManip: function afterManip( elem, fragClone, callback ) {
// Provides cloned fragment ready for fixup prior to and after insertion into DOM
var content = fragClone.nodeType === 11 ?
jQuery.makeArray(fragClone.childNodes) :
Expand All @@ -323,7 +337,6 @@
// Fragment has been inserted:- Add inserted nodes to context. Replace inserted element annotations by jQuery.data.
storeContexts( content );
cloneIndex++;
delete parentCtx.content;
}
});

Expand Down
10 changes: 5 additions & 5 deletions jquery.tmplPlus.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@

jQuery.fn.extend({
domManip: function (args, table, callback, options) {
var parentCtx, data = args[1], tmpl = args[0], dmArgs;
var data = args[1], tmpl = args[0], dmArgs;
if ( args.length >= 2 && typeof data === "object" && !data.nodeType && !(data instanceof jQuery)) {
// args[1] is data, for a template.
dmArgs = jQuery.makeArray( arguments );
// args[1] is data, for a template. Eval template to obtain fragment to clone and insert
parentCtx = args[3] || { key: 0 };

dmArgs[0] = [ jQuery.tmpl( tmpl, data, args[2], parentCtx, true ) ];
// Eval template to obtain fragment to clone and insert
dmArgs[0] = [ jQuery.tmpl( tmpl, data, args[2], args[3], true ) ];

dmArgs[2] = function( fragClone ) {
// Handler called by oldManip when rendered template has been inserted into DOM.
jQuery.tmpl.afterManip( parentCtx, this, fragClone, callback );
jQuery.tmpl.afterManip( this, fragClone, callback );
}
return oldManip.apply( this, dmArgs );
}
Expand Down

0 comments on commit a23f329

Please sign in to comment.