/* global _ */ (function () { 'use strict'; /* jshint ignore:start */ // Underscore's Template Module // Courtesy of underscorejs.org var _ = (function (_) { _.defaults = function (object) { if (!object) { return object; } for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) { var iterable = arguments[argsIndex]; if (iterable) { for (var key in iterable) { if (object[key] == null) { object[key] = iterable[key]; } } } } return object; }; // By default, Underscore uses ERB-style template delimiters, change the // following template settings to use alternative delimiters. _.templateSettings = { evaluate : /<%([\s\S]+?)%>/g, interpolate : /<%=([\s\S]+?)%>/g, escape : /<%-([\s\S]+?)%>/g }; // When customizing `templateSettings`, if you don't want to define an // interpolation, evaluation or escaping regex, we need one that is // guaranteed not to match. var noMatch = /(.)^/; // Certain characters need to be escaped so that they can be put into a // string literal. var escapes = { "'": "'", '\\': '\\', '\r': 'r', '\n': 'n', '\t': 't', '\u2028': 'u2028', '\u2029': 'u2029' }; var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; // JavaScript micro-templating, similar to John Resig's implementation. // Underscore templating handles arbitrary delimiters, preserves whitespace, // and correctly escapes quotes within interpolated code. _.template = function(text, data, settings) { var render; settings = _.defaults({}, settings, _.templateSettings); // Combine delimiters into one regular expression via alternation. var matcher = new RegExp([ (settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source ].join('|') + '|$', 'g'); // Compile the template source, escaping string literals appropriately. var index = 0; var source = "__p+='"; text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { source += text.slice(index, offset) .replace(escaper, function(match) { return '\\' + escapes[match]; }); if (escape) { source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; } if (interpolate) { source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; } if (evaluate) { source += "';\n" + evaluate + "\n__p+='"; } index = offset + match.length; return match; }); source += "';\n"; // If a variable is not specified, place data values in local scope. if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; source = "var __t,__p='',__j=Array.prototype.join," + "print=function(){__p+=__j.call(arguments,'');};\n" + source + "return __p;\n"; try { render = new Function(settings.variable || 'obj', '_', source); } catch (e) { e.source = source; throw e; } if (data) return render(data, _); var template = function(data) { return render.call(this, data, _); }; // Provide the compiled function source as a convenience for precompilation. template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; return template; }; return _; })({}); if (location.hostname === 'todomvc.com') { (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-31081062-1', 'auto'); ga('send', 'pageview'); } /* jshint ignore:end */ function redirect() { if (location.hostname === 'tastejs.github.io') { location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com'); } } function findRoot() { var base = location.href.indexOf('examples/'); return location.href.substr(0, base); } function getFile(file, callback) { if (!location.host) { return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.'); } var xhr = new XMLHttpRequest(); xhr.open('GET', findRoot() + file, true); xhr.send(); xhr.onload = function () { if (xhr.status === 200 && callback) { callback(xhr.responseText); } }; } function Learn(learnJSON, config) { if (!(this instanceof Learn)) { return new Learn(learnJSON, config); } var template, framework; if (typeof learnJSON !== 'object') { try { learnJSON = JSON.parse(learnJSON); } catch (e) { return; } } if (config) { template = config.template; framework = config.framework; } if (!template && learnJSON.templates) { template = learnJSON.templates.todomvc; } if (!framework && document.querySelector('[data-framework]')) { framework = document.querySelector('[data-framework]').dataset.framework; } this.template = template; if (learnJSON.backend) { this.frameworkJSON = learnJSON.backend; this.frameworkJSON.issueLabel = framework; this.append({ backend: true }); } else if (learnJSON[framework]) { this.frameworkJSON = learnJSON[framework]; this.frameworkJSON.issueLabel = framework; this.append(); } this.fetchIssueCount(); } Learn.prototype.append = function (opts) { var aside = document.createElement('aside'); aside.innerHTML = _.template(this.template, this.frameworkJSON); aside.className = 'learn'; if (opts && opts.backend) { // Remove demo link var sourceLinks = aside.querySelector('.source-links'); var heading = sourceLinks.firstElementChild; var sourceLink = sourceLinks.lastElementChild; // Correct link path var href = sourceLink.getAttribute('href'); sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http'))); sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML; } else { // Localize demo links var demoLinks = aside.querySelectorAll('.demo-link'); Array.prototype.forEach.call(demoLinks, function (demoLink) { if (demoLink.getAttribute('href').substr(0, 4) !== 'http') { demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href')); } }); } document.body.className = (document.body.className + ' learn-bar').trim(); document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); }; Learn.prototype.fetchIssueCount = function () { var issueLink = document.getElementById('issue-count-link'); if (issueLink) { var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos'); var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function (e) { var parsedResponse = JSON.parse(e.target.responseText); if (parsedResponse instanceof Array) { var count = parsedResponse.length; if (count !== 0) { issueLink.innerHTML = 'This app has ' + count + ' open issues'; document.getElementById('issue-count').style.display = 'inline'; } } }; xhr.send(); } }; redirect(); getFile('learn.json', Learn); })();