OLD | NEW |
(Empty) | |
| 1 (function () { |
| 2 'use strict'; |
| 3 |
| 4 // Underscore's Template Module |
| 5 // Courtesy of underscorejs.org |
| 6 var _ = (function (_) { |
| 7 _.defaults = function (object) { |
| 8 if (!object) { |
| 9 return object; |
| 10 } |
| 11 for (var argsIndex = 1, argsLength = arguments.length; a
rgsIndex < argsLength; argsIndex++) { |
| 12 var iterable = arguments[argsIndex]; |
| 13 if (iterable) { |
| 14 for (var key in iterable) { |
| 15 if (object[key] == null) { |
| 16 object[key] = iterable[k
ey]; |
| 17 } |
| 18 } |
| 19 } |
| 20 } |
| 21 return object; |
| 22 } |
| 23 |
| 24 // By default, Underscore uses ERB-style template delimiters, ch
ange the |
| 25 // following template settings to use alternative delimiters. |
| 26 _.templateSettings = { |
| 27 evaluate : /<%([\s\S]+?)%>/g, |
| 28 interpolate : /<%=([\s\S]+?)%>/g, |
| 29 escape : /<%-([\s\S]+?)%>/g |
| 30 }; |
| 31 |
| 32 // When customizing `templateSettings`, if you don't want to def
ine an |
| 33 // interpolation, evaluation or escaping regex, we need one that
is |
| 34 // guaranteed not to match. |
| 35 var noMatch = /(.)^/; |
| 36 |
| 37 // Certain characters need to be escaped so that they can be put
into a |
| 38 // string literal. |
| 39 var escapes = { |
| 40 "'": "'", |
| 41 '\\': '\\', |
| 42 '\r': 'r', |
| 43 '\n': 'n', |
| 44 '\t': 't', |
| 45 '\u2028': 'u2028', |
| 46 '\u2029': 'u2029' |
| 47 }; |
| 48 |
| 49 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; |
| 50 |
| 51 // JavaScript micro-templating, similar to John Resig's implemen
tation. |
| 52 // Underscore templating handles arbitrary delimiters, preserves
whitespace, |
| 53 // and correctly escapes quotes within interpolated code. |
| 54 _.template = function(text, data, settings) { |
| 55 var render; |
| 56 settings = _.defaults({}, settings, _.templateSettings); |
| 57 |
| 58 // Combine delimiters into one regular expression via al
ternation. |
| 59 var matcher = new RegExp([ |
| 60 (settings.escape || noMatch).source, |
| 61 (settings.interpolate || noMatch).source, |
| 62 (settings.evaluate || noMatch).source |
| 63 ].join('|') + '|$', 'g'); |
| 64 |
| 65 // Compile the template source, escaping string literals
appropriately. |
| 66 var index = 0; |
| 67 var source = "__p+='"; |
| 68 text.replace(matcher, function(match, escape, interpolat
e, evaluate, offset) { |
| 69 source += text.slice(index, offset) |
| 70 .replace(escaper, function(match) { retu
rn '\\' + escapes[match]; }); |
| 71 |
| 72 if (escape) { |
| 73 source += "'+\n((__t=(" + escape + "))==
null?'':_.escape(__t))+\n'"; |
| 74 } |
| 75 if (interpolate) { |
| 76 source += "'+\n((__t=(" + interpolate +
"))==null?'':__t)+\n'"; |
| 77 } |
| 78 if (evaluate) { |
| 79 source += "';\n" + evaluate + "\n__p+='"
; |
| 80 } |
| 81 index = offset + match.length; |
| 82 return match; |
| 83 }); |
| 84 source += "';\n"; |
| 85 |
| 86 // If a variable is not specified, place data values in
local scope. |
| 87 if (!settings.variable) source = 'with(obj||{}){\n' + so
urce + '}\n'; |
| 88 |
| 89 source = "var __t,__p='',__j=Array.prototype.join," + |
| 90 "print=function(){__p+=__j.call(arguments,'');};
\n" + |
| 91 source + "return __p;\n"; |
| 92 |
| 93 try { |
| 94 render = new Function(settings.variable || 'obj'
, '_', source); |
| 95 } catch (e) { |
| 96 e.source = source; |
| 97 throw e; |
| 98 } |
| 99 |
| 100 if (data) return render(data, _); |
| 101 var template = function(data) { |
| 102 return render.call(this, data, _); |
| 103 }; |
| 104 |
| 105 // Provide the compiled function source as a convenience
for precompilation. |
| 106 template.source = 'function(' + (settings.variable || 'o
bj') + '){\n' + source + '}'; |
| 107 |
| 108 return template; |
| 109 }; |
| 110 |
| 111 return _; |
| 112 })({}); |
| 113 |
| 114 if (location.hostname === 'todomvc.com') { |
| 115 window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview'
]];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src=
'//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'scr
ipt')); |
| 116 } |
| 117 |
| 118 function redirect() { |
| 119 if (location.hostname === 'tastejs.github.io') { |
| 120 location.href = location.href.replace('tastejs.github.io
/todomvc', 'todomvc.com'); |
| 121 } |
| 122 } |
| 123 |
| 124 function findRoot() { |
| 125 var base; |
| 126 |
| 127 [/labs/, /\w*-examples/].forEach(function (href) { |
| 128 var match = location.href.match(href); |
| 129 |
| 130 if (!base && match) { |
| 131 base = location.href.indexOf(match); |
| 132 } |
| 133 }); |
| 134 |
| 135 return location.href.substr(0, base); |
| 136 } |
| 137 |
| 138 function getFile(file, callback) { |
| 139 if (!location.host) { |
| 140 return console.info('Miss the info bar? Run TodoMVC from
a server to avoid a cross-origin error.'); |
| 141 } |
| 142 |
| 143 var xhr = new XMLHttpRequest(); |
| 144 |
| 145 xhr.open('GET', findRoot() + file, true); |
| 146 xhr.send(); |
| 147 |
| 148 xhr.onload = function () { |
| 149 if (xhr.status === 200 && callback) { |
| 150 callback(xhr.responseText); |
| 151 } |
| 152 }; |
| 153 } |
| 154 |
| 155 function Learn(learnJSON, config) { |
| 156 if (!(this instanceof Learn)) { |
| 157 return new Learn(learnJSON, config); |
| 158 } |
| 159 |
| 160 var template, framework; |
| 161 |
| 162 if (typeof learnJSON !== 'object') { |
| 163 try { |
| 164 learnJSON = JSON.parse(learnJSON); |
| 165 } catch (e) { |
| 166 return; |
| 167 } |
| 168 } |
| 169 |
| 170 if (config) { |
| 171 template = config.template; |
| 172 framework = config.framework; |
| 173 } |
| 174 |
| 175 if (!template && learnJSON.templates) { |
| 176 template = learnJSON.templates.todomvc; |
| 177 } |
| 178 |
| 179 if (!framework && document.querySelector('[data-framework]')) { |
| 180 framework = document.querySelector('[data-framework]').g
etAttribute('data-framework'); |
| 181 } |
| 182 |
| 183 |
| 184 if (template && learnJSON[framework]) { |
| 185 this.frameworkJSON = learnJSON[framework]; |
| 186 this.template = template; |
| 187 |
| 188 this.append(); |
| 189 } |
| 190 } |
| 191 |
| 192 Learn.prototype.append = function () { |
| 193 var aside = document.createElement('aside'); |
| 194 aside.innerHTML = _.template(this.template, this.frameworkJSON); |
| 195 aside.className = 'learn'; |
| 196 |
| 197 // Localize demo links |
| 198 var demoLinks = aside.querySelectorAll('.demo-link'); |
| 199 Array.prototype.forEach.call(demoLinks, function (demoLink) { |
| 200 demoLink.setAttribute('href', findRoot() + demoLink.getA
ttribute('href')); |
| 201 }); |
| 202 |
| 203 document.body.className = (document.body.className + ' learn-bar
').trim(); |
| 204 document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); |
| 205 }; |
| 206 |
| 207 redirect(); |
| 208 getFile('learn.json', Learn); |
| 209 })(); |
OLD | NEW |