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 |