| 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 |