mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
simplify todomvc example
This commit is contained in:
parent
7a22f134d4
commit
8242d9498a
@ -3,7 +3,8 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Vue.js • TodoMVC</title>
|
||||
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/todomvc-app-css/index.css">
|
||||
<script src="https:unpkg.com/director/build/director.js"></script>
|
||||
<style>[v-cloak] { display: none; }</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -57,29 +58,12 @@
|
||||
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
|
||||
</footer>
|
||||
|
||||
<!-- testing/benchmark only -->
|
||||
<script>
|
||||
if (window.location.hash === '#test') {
|
||||
localStorage.clear()
|
||||
}
|
||||
var now = window.performance && window.performance.now
|
||||
? function () { return window.performance.now() }
|
||||
: Date.now
|
||||
var metrics = { beforeLoad: now() }
|
||||
</script>
|
||||
<!-- end testing/bench -->
|
||||
|
||||
<script src="../../dist/vue.js"></script>
|
||||
<script>metrics.afterLoad = now()</script>
|
||||
<script src="node_modules/director/build/director.js"></script>
|
||||
<script src="js/store.js"></script>
|
||||
<script>metrics.beforeRender = now()</script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/routes.js"></script>
|
||||
<script>
|
||||
app.$mount('.todoapp')
|
||||
</script>
|
||||
<script>metrics.afterRender = now()</script>
|
||||
<script src="perf.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
725
examples/todomvc/node_modules/director/build/director.js
generated
vendored
725
examples/todomvc/node_modules/director/build/director.js
generated
vendored
@ -1,725 +0,0 @@
|
||||
|
||||
|
||||
//
|
||||
// Generated on Tue Dec 16 2014 12:13:47 GMT+0100 (CET) by Charlie Robbins, Paolo Fragomeni & the Contributors (Using Codesurgeon).
|
||||
// Version 1.2.6
|
||||
//
|
||||
|
||||
(function (exports) {
|
||||
|
||||
/*
|
||||
* browser.js: Browser specific functionality for director.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins, Paolo Fragomeni, & the Contributors.
|
||||
* MIT LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
var dloc = document.location;
|
||||
|
||||
function dlocHashEmpty() {
|
||||
// Non-IE browsers return '' when the address bar shows '#'; Director's logic
|
||||
// assumes both mean empty.
|
||||
return dloc.hash === '' || dloc.hash === '#';
|
||||
}
|
||||
|
||||
var listener = {
|
||||
mode: 'modern',
|
||||
hash: dloc.hash,
|
||||
history: false,
|
||||
|
||||
check: function () {
|
||||
var h = dloc.hash;
|
||||
if (h != this.hash) {
|
||||
this.hash = h;
|
||||
this.onHashChanged();
|
||||
}
|
||||
},
|
||||
|
||||
fire: function () {
|
||||
if (this.mode === 'modern') {
|
||||
this.history === true ? window.onpopstate() : window.onhashchange();
|
||||
}
|
||||
else {
|
||||
this.onHashChanged();
|
||||
}
|
||||
},
|
||||
|
||||
init: function (fn, history) {
|
||||
var self = this;
|
||||
this.history = history;
|
||||
|
||||
if (!Router.listeners) {
|
||||
Router.listeners = [];
|
||||
}
|
||||
|
||||
function onchange(onChangeEvent) {
|
||||
for (var i = 0, l = Router.listeners.length; i < l; i++) {
|
||||
Router.listeners[i](onChangeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//note IE8 is being counted as 'modern' because it has the hashchange event
|
||||
if ('onhashchange' in window && (document.documentMode === undefined
|
||||
|| document.documentMode > 7)) {
|
||||
// At least for now HTML5 history is available for 'modern' browsers only
|
||||
if (this.history === true) {
|
||||
// There is an old bug in Chrome that causes onpopstate to fire even
|
||||
// upon initial page load. Since the handler is run manually in init(),
|
||||
// this would cause Chrome to run it twise. Currently the only
|
||||
// workaround seems to be to set the handler after the initial page load
|
||||
// http://code.google.com/p/chromium/issues/detail?id=63040
|
||||
setTimeout(function() {
|
||||
window.onpopstate = onchange;
|
||||
}, 500);
|
||||
}
|
||||
else {
|
||||
window.onhashchange = onchange;
|
||||
}
|
||||
this.mode = 'modern';
|
||||
}
|
||||
else {
|
||||
//
|
||||
// IE support, based on a concept by Erik Arvidson ...
|
||||
//
|
||||
var frame = document.createElement('iframe');
|
||||
frame.id = 'state-frame';
|
||||
frame.style.display = 'none';
|
||||
document.body.appendChild(frame);
|
||||
this.writeFrame('');
|
||||
|
||||
if ('onpropertychange' in document && 'attachEvent' in document) {
|
||||
document.attachEvent('onpropertychange', function () {
|
||||
if (event.propertyName === 'location') {
|
||||
self.check();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.setInterval(function () { self.check(); }, 50);
|
||||
|
||||
this.onHashChanged = onchange;
|
||||
this.mode = 'legacy';
|
||||
}
|
||||
|
||||
Router.listeners.push(fn);
|
||||
|
||||
return this.mode;
|
||||
},
|
||||
|
||||
destroy: function (fn) {
|
||||
if (!Router || !Router.listeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
var listeners = Router.listeners;
|
||||
|
||||
for (var i = listeners.length - 1; i >= 0; i--) {
|
||||
if (listeners[i] === fn) {
|
||||
listeners.splice(i, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setHash: function (s) {
|
||||
// Mozilla always adds an entry to the history
|
||||
if (this.mode === 'legacy') {
|
||||
this.writeFrame(s);
|
||||
}
|
||||
|
||||
if (this.history === true) {
|
||||
window.history.pushState({}, document.title, s);
|
||||
// Fire an onpopstate event manually since pushing does not obviously
|
||||
// trigger the pop event.
|
||||
this.fire();
|
||||
} else {
|
||||
dloc.hash = (s[0] === '/') ? s : '/' + s;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
writeFrame: function (s) {
|
||||
// IE support...
|
||||
var f = document.getElementById('state-frame');
|
||||
var d = f.contentDocument || f.contentWindow.document;
|
||||
d.open();
|
||||
d.write("<script>_hash = '" + s + "'; onload = parent.listener.syncHash;<script>");
|
||||
d.close();
|
||||
},
|
||||
|
||||
syncHash: function () {
|
||||
// IE support...
|
||||
var s = this._hash;
|
||||
if (s != dloc.hash) {
|
||||
dloc.hash = s;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
onHashChanged: function () {}
|
||||
};
|
||||
|
||||
var Router = exports.Router = function (routes) {
|
||||
if (!(this instanceof Router)) return new Router(routes);
|
||||
|
||||
this.params = {};
|
||||
this.routes = {};
|
||||
this.methods = ['on', 'once', 'after', 'before'];
|
||||
this.scope = [];
|
||||
this._methods = {};
|
||||
|
||||
this._insert = this.insert;
|
||||
this.insert = this.insertEx;
|
||||
|
||||
this.historySupport = (window.history != null ? window.history.pushState : null) != null
|
||||
|
||||
this.configure();
|
||||
this.mount(routes || {});
|
||||
};
|
||||
|
||||
Router.prototype.init = function (r) {
|
||||
var self = this
|
||||
, routeTo;
|
||||
this.handler = function(onChangeEvent) {
|
||||
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
|
||||
var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, '');
|
||||
self.dispatch('on', url.charAt(0) === '/' ? url : '/' + url);
|
||||
};
|
||||
|
||||
listener.init(this.handler, this.history);
|
||||
|
||||
if (this.history === false) {
|
||||
if (dlocHashEmpty() && r) {
|
||||
dloc.hash = r;
|
||||
} else if (!dlocHashEmpty()) {
|
||||
self.dispatch('on', '/' + dloc.hash.replace(/^(#\/|#|\/)/, ''));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.convert_hash_in_init) {
|
||||
// Use hash as route
|
||||
routeTo = dlocHashEmpty() && r ? r : !dlocHashEmpty() ? dloc.hash.replace(/^#/, '') : null;
|
||||
if (routeTo) {
|
||||
window.history.replaceState({}, document.title, routeTo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use canonical url
|
||||
routeTo = this.getPath();
|
||||
}
|
||||
|
||||
// Router has been initialized, but due to the chrome bug it will not
|
||||
// yet actually route HTML5 history state changes. Thus, decide if should route.
|
||||
if (routeTo || this.run_in_init === true) {
|
||||
this.handler();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Router.prototype.explode = function () {
|
||||
var v = this.history === true ? this.getPath() : dloc.hash;
|
||||
if (v.charAt(1) === '/') { v=v.slice(1) }
|
||||
return v.slice(1, v.length).split("/");
|
||||
};
|
||||
|
||||
Router.prototype.setRoute = function (i, v, val) {
|
||||
var url = this.explode();
|
||||
|
||||
if (typeof i === 'number' && typeof v === 'string') {
|
||||
url[i] = v;
|
||||
}
|
||||
else if (typeof val === 'string') {
|
||||
url.splice(i, v, s);
|
||||
}
|
||||
else {
|
||||
url = [i];
|
||||
}
|
||||
|
||||
listener.setHash(url.join('/'));
|
||||
return url;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function insertEx(method, path, route, parent)
|
||||
// #### @method {string} Method to insert the specific `route`.
|
||||
// #### @path {Array} Parsed path to insert the `route` at.
|
||||
// #### @route {Array|function} Route handlers to insert.
|
||||
// #### @parent {Object} **Optional** Parent "routes" to insert into.
|
||||
// insert a callback that will only occur once per the matched route.
|
||||
//
|
||||
Router.prototype.insertEx = function(method, path, route, parent) {
|
||||
if (method === "once") {
|
||||
method = "on";
|
||||
route = function(route) {
|
||||
var once = false;
|
||||
return function() {
|
||||
if (once) return;
|
||||
once = true;
|
||||
return route.apply(this, arguments);
|
||||
};
|
||||
}(route);
|
||||
}
|
||||
return this._insert(method, path, route, parent);
|
||||
};
|
||||
|
||||
Router.prototype.getRoute = function (v) {
|
||||
var ret = v;
|
||||
|
||||
if (typeof v === "number") {
|
||||
ret = this.explode()[v];
|
||||
}
|
||||
else if (typeof v === "string"){
|
||||
var h = this.explode();
|
||||
ret = h.indexOf(v);
|
||||
}
|
||||
else {
|
||||
ret = this.explode();
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
Router.prototype.destroy = function () {
|
||||
listener.destroy(this.handler);
|
||||
return this;
|
||||
};
|
||||
|
||||
Router.prototype.getPath = function () {
|
||||
var path = window.location.pathname;
|
||||
if (path.substr(0, 1) !== '/') {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
};
|
||||
function _every(arr, iterator) {
|
||||
for (var i = 0; i < arr.length; i += 1) {
|
||||
if (iterator(arr[i], i, arr) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _flatten(arr) {
|
||||
var flat = [];
|
||||
for (var i = 0, n = arr.length; i < n; i++) {
|
||||
flat = flat.concat(arr[i]);
|
||||
}
|
||||
return flat;
|
||||
}
|
||||
|
||||
function _asyncEverySeries(arr, iterator, callback) {
|
||||
if (!arr.length) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
(function iterate() {
|
||||
iterator(arr[completed], function(err) {
|
||||
if (err || err === false) {
|
||||
callback(err);
|
||||
callback = function() {};
|
||||
} else {
|
||||
completed += 1;
|
||||
if (completed === arr.length) {
|
||||
callback();
|
||||
} else {
|
||||
iterate();
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
function paramifyString(str, params, mod) {
|
||||
mod = str;
|
||||
for (var param in params) {
|
||||
if (params.hasOwnProperty(param)) {
|
||||
mod = params[param](str);
|
||||
if (mod !== str) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mod === str ? "([._a-zA-Z0-9-%()]+)" : mod;
|
||||
}
|
||||
|
||||
function regifyString(str, params) {
|
||||
var matches, last = 0, out = "";
|
||||
while (matches = str.substr(last).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/)) {
|
||||
last = matches.index + matches[0].length;
|
||||
matches[0] = matches[0].replace(/^\*/, "([_.()!\\ %@&a-zA-Z0-9-]+)");
|
||||
out += str.substr(0, matches.index) + matches[0];
|
||||
}
|
||||
str = out += str.substr(last);
|
||||
var captures = str.match(/:([^\/]+)/ig), capture, length;
|
||||
if (captures) {
|
||||
length = captures.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
capture = captures[i];
|
||||
if (capture.slice(0, 2) === "::") {
|
||||
str = capture.slice(1);
|
||||
} else {
|
||||
str = str.replace(capture, paramifyString(capture, params));
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function terminator(routes, delimiter, start, stop) {
|
||||
var last = 0, left = 0, right = 0, start = (start || "(").toString(), stop = (stop || ")").toString(), i;
|
||||
for (i = 0; i < routes.length; i++) {
|
||||
var chunk = routes[i];
|
||||
if (chunk.indexOf(start, last) > chunk.indexOf(stop, last) || ~chunk.indexOf(start, last) && !~chunk.indexOf(stop, last) || !~chunk.indexOf(start, last) && ~chunk.indexOf(stop, last)) {
|
||||
left = chunk.indexOf(start, last);
|
||||
right = chunk.indexOf(stop, last);
|
||||
if (~left && !~right || !~left && ~right) {
|
||||
var tmp = routes.slice(0, (i || 1) + 1).join(delimiter);
|
||||
routes = [ tmp ].concat(routes.slice((i || 1) + 1));
|
||||
}
|
||||
last = (right > left ? right : left) + 1;
|
||||
i = 0;
|
||||
} else {
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
var QUERY_SEPARATOR = /\?.*/;
|
||||
|
||||
Router.prototype.configure = function(options) {
|
||||
options = options || {};
|
||||
for (var i = 0; i < this.methods.length; i++) {
|
||||
this._methods[this.methods[i]] = true;
|
||||
}
|
||||
this.recurse = options.recurse || this.recurse || false;
|
||||
this.async = options.async || false;
|
||||
this.delimiter = options.delimiter || "/";
|
||||
this.strict = typeof options.strict === "undefined" ? true : options.strict;
|
||||
this.notfound = options.notfound;
|
||||
this.resource = options.resource;
|
||||
this.history = options.html5history && this.historySupport || false;
|
||||
this.run_in_init = this.history === true && options.run_handler_in_init !== false;
|
||||
this.convert_hash_in_init = this.history === true && options.convert_hash_in_init !== false;
|
||||
this.every = {
|
||||
after: options.after || null,
|
||||
before: options.before || null,
|
||||
on: options.on || null
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
Router.prototype.param = function(token, matcher) {
|
||||
if (token[0] !== ":") {
|
||||
token = ":" + token;
|
||||
}
|
||||
var compiled = new RegExp(token, "g");
|
||||
this.params[token] = function(str) {
|
||||
return str.replace(compiled, matcher.source || matcher);
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
Router.prototype.on = Router.prototype.route = function(method, path, route) {
|
||||
var self = this;
|
||||
if (!route && typeof path == "function") {
|
||||
route = path;
|
||||
path = method;
|
||||
method = "on";
|
||||
}
|
||||
if (Array.isArray(path)) {
|
||||
return path.forEach(function(p) {
|
||||
self.on(method, p, route);
|
||||
});
|
||||
}
|
||||
if (path.source) {
|
||||
path = path.source.replace(/\\\//ig, "/");
|
||||
}
|
||||
if (Array.isArray(method)) {
|
||||
return method.forEach(function(m) {
|
||||
self.on(m.toLowerCase(), path, route);
|
||||
});
|
||||
}
|
||||
path = path.split(new RegExp(this.delimiter));
|
||||
path = terminator(path, this.delimiter);
|
||||
this.insert(method, this.scope.concat(path), route);
|
||||
};
|
||||
|
||||
Router.prototype.path = function(path, routesFn) {
|
||||
var self = this, length = this.scope.length;
|
||||
if (path.source) {
|
||||
path = path.source.replace(/\\\//ig, "/");
|
||||
}
|
||||
path = path.split(new RegExp(this.delimiter));
|
||||
path = terminator(path, this.delimiter);
|
||||
this.scope = this.scope.concat(path);
|
||||
routesFn.call(this, this);
|
||||
this.scope.splice(length, path.length);
|
||||
};
|
||||
|
||||
Router.prototype.dispatch = function(method, path, callback) {
|
||||
var self = this, fns = this.traverse(method, path.replace(QUERY_SEPARATOR, ""), this.routes, ""), invoked = this._invoked, after;
|
||||
this._invoked = true;
|
||||
if (!fns || fns.length === 0) {
|
||||
this.last = [];
|
||||
if (typeof this.notfound === "function") {
|
||||
this.invoke([ this.notfound ], {
|
||||
method: method,
|
||||
path: path
|
||||
}, callback);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (this.recurse === "forward") {
|
||||
fns = fns.reverse();
|
||||
}
|
||||
function updateAndInvoke() {
|
||||
self.last = fns.after;
|
||||
self.invoke(self.runlist(fns), self, callback);
|
||||
}
|
||||
after = this.every && this.every.after ? [ this.every.after ].concat(this.last) : [ this.last ];
|
||||
if (after && after.length > 0 && invoked) {
|
||||
if (this.async) {
|
||||
this.invoke(after, this, updateAndInvoke);
|
||||
} else {
|
||||
this.invoke(after, this);
|
||||
updateAndInvoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
updateAndInvoke();
|
||||
return true;
|
||||
};
|
||||
|
||||
Router.prototype.invoke = function(fns, thisArg, callback) {
|
||||
var self = this;
|
||||
var apply;
|
||||
if (this.async) {
|
||||
apply = function(fn, next) {
|
||||
if (Array.isArray(fn)) {
|
||||
return _asyncEverySeries(fn, apply, next);
|
||||
} else if (typeof fn == "function") {
|
||||
fn.apply(thisArg, (fns.captures || []).concat(next));
|
||||
}
|
||||
};
|
||||
_asyncEverySeries(fns, apply, function() {
|
||||
if (callback) {
|
||||
callback.apply(thisArg, arguments);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
apply = function(fn) {
|
||||
if (Array.isArray(fn)) {
|
||||
return _every(fn, apply);
|
||||
} else if (typeof fn === "function") {
|
||||
return fn.apply(thisArg, fns.captures || []);
|
||||
} else if (typeof fn === "string" && self.resource) {
|
||||
self.resource[fn].apply(thisArg, fns.captures || []);
|
||||
}
|
||||
};
|
||||
_every(fns, apply);
|
||||
}
|
||||
};
|
||||
|
||||
Router.prototype.traverse = function(method, path, routes, regexp, filter) {
|
||||
var fns = [], current, exact, match, next, that;
|
||||
function filterRoutes(routes) {
|
||||
if (!filter) {
|
||||
return routes;
|
||||
}
|
||||
function deepCopy(source) {
|
||||
var result = [];
|
||||
for (var i = 0; i < source.length; i++) {
|
||||
result[i] = Array.isArray(source[i]) ? deepCopy(source[i]) : source[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function applyFilter(fns) {
|
||||
for (var i = fns.length - 1; i >= 0; i--) {
|
||||
if (Array.isArray(fns[i])) {
|
||||
applyFilter(fns[i]);
|
||||
if (fns[i].length === 0) {
|
||||
fns.splice(i, 1);
|
||||
}
|
||||
} else {
|
||||
if (!filter(fns[i])) {
|
||||
fns.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var newRoutes = deepCopy(routes);
|
||||
newRoutes.matched = routes.matched;
|
||||
newRoutes.captures = routes.captures;
|
||||
newRoutes.after = routes.after.filter(filter);
|
||||
applyFilter(newRoutes);
|
||||
return newRoutes;
|
||||
}
|
||||
if (path === this.delimiter && routes[method]) {
|
||||
next = [ [ routes.before, routes[method] ].filter(Boolean) ];
|
||||
next.after = [ routes.after ].filter(Boolean);
|
||||
next.matched = true;
|
||||
next.captures = [];
|
||||
return filterRoutes(next);
|
||||
}
|
||||
for (var r in routes) {
|
||||
if (routes.hasOwnProperty(r) && (!this._methods[r] || this._methods[r] && typeof routes[r] === "object" && !Array.isArray(routes[r]))) {
|
||||
current = exact = regexp + this.delimiter + r;
|
||||
if (!this.strict) {
|
||||
exact += "[" + this.delimiter + "]?";
|
||||
}
|
||||
match = path.match(new RegExp("^" + exact));
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
if (match[0] && match[0] == path && routes[r][method]) {
|
||||
next = [ [ routes[r].before, routes[r][method] ].filter(Boolean) ];
|
||||
next.after = [ routes[r].after ].filter(Boolean);
|
||||
next.matched = true;
|
||||
next.captures = match.slice(1);
|
||||
if (this.recurse && routes === this.routes) {
|
||||
next.push([ routes.before, routes.on ].filter(Boolean));
|
||||
next.after = next.after.concat([ routes.after ].filter(Boolean));
|
||||
}
|
||||
return filterRoutes(next);
|
||||
}
|
||||
next = this.traverse(method, path, routes[r], current);
|
||||
if (next.matched) {
|
||||
if (next.length > 0) {
|
||||
fns = fns.concat(next);
|
||||
}
|
||||
if (this.recurse) {
|
||||
fns.push([ routes[r].before, routes[r].on ].filter(Boolean));
|
||||
next.after = next.after.concat([ routes[r].after ].filter(Boolean));
|
||||
if (routes === this.routes) {
|
||||
fns.push([ routes["before"], routes["on"] ].filter(Boolean));
|
||||
next.after = next.after.concat([ routes["after"] ].filter(Boolean));
|
||||
}
|
||||
}
|
||||
fns.matched = true;
|
||||
fns.captures = next.captures;
|
||||
fns.after = next.after;
|
||||
return filterRoutes(fns);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Router.prototype.insert = function(method, path, route, parent) {
|
||||
var methodType, parentType, isArray, nested, part;
|
||||
path = path.filter(function(p) {
|
||||
return p && p.length > 0;
|
||||
});
|
||||
parent = parent || this.routes;
|
||||
part = path.shift();
|
||||
if (/\:|\*/.test(part) && !/\\d|\\w/.test(part)) {
|
||||
part = regifyString(part, this.params);
|
||||
}
|
||||
if (path.length > 0) {
|
||||
parent[part] = parent[part] || {};
|
||||
return this.insert(method, path, route, parent[part]);
|
||||
}
|
||||
if (!part && !path.length && parent === this.routes) {
|
||||
methodType = typeof parent[method];
|
||||
switch (methodType) {
|
||||
case "function":
|
||||
parent[method] = [ parent[method], route ];
|
||||
return;
|
||||
case "object":
|
||||
parent[method].push(route);
|
||||
return;
|
||||
case "undefined":
|
||||
parent[method] = route;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
parentType = typeof parent[part];
|
||||
isArray = Array.isArray(parent[part]);
|
||||
if (parent[part] && !isArray && parentType == "object") {
|
||||
methodType = typeof parent[part][method];
|
||||
switch (methodType) {
|
||||
case "function":
|
||||
parent[part][method] = [ parent[part][method], route ];
|
||||
return;
|
||||
case "object":
|
||||
parent[part][method].push(route);
|
||||
return;
|
||||
case "undefined":
|
||||
parent[part][method] = route;
|
||||
return;
|
||||
}
|
||||
} else if (parentType == "undefined") {
|
||||
nested = {};
|
||||
nested[method] = route;
|
||||
parent[part] = nested;
|
||||
return;
|
||||
}
|
||||
throw new Error("Invalid route context: " + parentType);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Router.prototype.extend = function(methods) {
|
||||
var self = this, len = methods.length, i;
|
||||
function extend(method) {
|
||||
self._methods[method] = true;
|
||||
self[method] = function() {
|
||||
var extra = arguments.length === 1 ? [ method, "" ] : [ method ];
|
||||
self.on.apply(self, extra.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
extend(methods[i]);
|
||||
}
|
||||
};
|
||||
|
||||
Router.prototype.runlist = function(fns) {
|
||||
var runlist = this.every && this.every.before ? [ this.every.before ].concat(_flatten(fns)) : _flatten(fns);
|
||||
if (this.every && this.every.on) {
|
||||
runlist.push(this.every.on);
|
||||
}
|
||||
runlist.captures = fns.captures;
|
||||
runlist.source = fns.source;
|
||||
return runlist;
|
||||
};
|
||||
|
||||
Router.prototype.mount = function(routes, path) {
|
||||
if (!routes || typeof routes !== "object" || Array.isArray(routes)) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
path = path || [];
|
||||
if (!Array.isArray(path)) {
|
||||
path = path.split(self.delimiter);
|
||||
}
|
||||
function insertOrMount(route, local) {
|
||||
var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename;
|
||||
if (isRoute) {
|
||||
rename = rename.slice((rename.match(new RegExp("^" + self.delimiter)) || [ "" ])[0].length);
|
||||
parts.shift();
|
||||
}
|
||||
if (isRoute && routeType === "object" && !Array.isArray(routes[route])) {
|
||||
local = local.concat(parts);
|
||||
self.mount(routes[route], local);
|
||||
return;
|
||||
}
|
||||
if (isRoute) {
|
||||
local = local.concat(rename.split(self.delimiter));
|
||||
local = terminator(local, self.delimiter);
|
||||
}
|
||||
self.insert(event, local, routes[route]);
|
||||
}
|
||||
for (var route in routes) {
|
||||
if (routes.hasOwnProperty(route)) {
|
||||
insertOrMount(route, path.slice(0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}(typeof exports === "object" ? exports : window));
|
378
examples/todomvc/node_modules/todomvc-app-css/index.css
generated
vendored
378
examples/todomvc/node_modules/todomvc-app-css/index.css
generated
vendored
@ -1,378 +0,0 @@
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: none;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
line-height: 1.4em;
|
||||
background: #f5f5f5;
|
||||
color: #4d4d4d;
|
||||
min-width: 230px;
|
||||
max-width: 550px;
|
||||
margin: 0 auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
font-smoothing: antialiased;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
button,
|
||||
input[type="checkbox"] {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.todoapp {
|
||||
background: #fff;
|
||||
margin: 130px 0 40px 0;
|
||||
position: relative;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
|
||||
0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.todoapp input::-webkit-input-placeholder {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.todoapp input::-moz-placeholder {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.todoapp input::input-placeholder {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.todoapp h1 {
|
||||
position: absolute;
|
||||
top: -155px;
|
||||
width: 100%;
|
||||
font-size: 100px;
|
||||
font-weight: 100;
|
||||
text-align: center;
|
||||
color: rgba(175, 47, 47, 0.15);
|
||||
-webkit-text-rendering: optimizeLegibility;
|
||||
-moz-text-rendering: optimizeLegibility;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
.new-todo,
|
||||
.edit {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: 1.4em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
color: inherit;
|
||||
padding: 6px;
|
||||
border: 1px solid #999;
|
||||
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.new-todo {
|
||||
padding: 16px 16px 16px 60px;
|
||||
border: none;
|
||||
background: rgba(0, 0, 0, 0.003);
|
||||
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
|
||||
}
|
||||
|
||||
.main {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
label[for='toggle-all'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggle-all {
|
||||
position: absolute;
|
||||
top: -55px;
|
||||
left: -12px;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
text-align: center;
|
||||
border: none; /* Mobile Safari */
|
||||
}
|
||||
|
||||
.toggle-all:before {
|
||||
content: '❯';
|
||||
font-size: 22px;
|
||||
color: #e6e6e6;
|
||||
padding: 10px 27px 10px 27px;
|
||||
}
|
||||
|
||||
.toggle-all:checked:before {
|
||||
color: #737373;
|
||||
}
|
||||
|
||||
.todo-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.todo-list li {
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
border-bottom: 1px solid #ededed;
|
||||
}
|
||||
|
||||
.todo-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.todo-list li.editing {
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.todo-list li.editing .edit {
|
||||
display: block;
|
||||
width: 506px;
|
||||
padding: 13px 17px 12px 17px;
|
||||
margin: 0 0 0 43px;
|
||||
}
|
||||
|
||||
.todo-list li.editing .view {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.todo-list li .toggle {
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
/* auto, since non-WebKit browsers doesn't support input styling */
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto 0;
|
||||
border: none; /* Mobile Safari */
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.todo-list li .toggle:after {
|
||||
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
|
||||
}
|
||||
|
||||
.todo-list li .toggle:checked:after {
|
||||
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
|
||||
}
|
||||
|
||||
.todo-list li label {
|
||||
white-space: pre;
|
||||
word-break: break-word;
|
||||
padding: 15px 60px 15px 15px;
|
||||
margin-left: 45px;
|
||||
display: block;
|
||||
line-height: 1.2;
|
||||
transition: color 0.4s;
|
||||
}
|
||||
|
||||
.todo-list li.completed label {
|
||||
color: #d9d9d9;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.todo-list li .destroy {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
bottom: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: auto 0;
|
||||
font-size: 30px;
|
||||
color: #cc9a9a;
|
||||
margin-bottom: 11px;
|
||||
transition: color 0.2s ease-out;
|
||||
}
|
||||
|
||||
.todo-list li .destroy:hover {
|
||||
color: #af5b5e;
|
||||
}
|
||||
|
||||
.todo-list li .destroy:after {
|
||||
content: '×';
|
||||
}
|
||||
|
||||
.todo-list li:hover .destroy {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.todo-list li .edit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.todo-list li.editing:last-child {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
color: #777;
|
||||
padding: 10px 15px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.footer:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
|
||||
0 8px 0 -3px #f6f6f6,
|
||||
0 9px 1px -3px rgba(0, 0, 0, 0.2),
|
||||
0 16px 0 -6px #f6f6f6,
|
||||
0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.todo-count {
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.todo-count strong {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.filters {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.filters li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.filters li a {
|
||||
color: inherit;
|
||||
margin: 3px;
|
||||
padding: 3px 7px;
|
||||
text-decoration: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.filters li a.selected,
|
||||
.filters li a:hover {
|
||||
border-color: rgba(175, 47, 47, 0.1);
|
||||
}
|
||||
|
||||
.filters li a.selected {
|
||||
border-color: rgba(175, 47, 47, 0.2);
|
||||
}
|
||||
|
||||
.clear-completed,
|
||||
html .clear-completed:active {
|
||||
float: right;
|
||||
position: relative;
|
||||
line-height: 20px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.clear-completed:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin: 65px auto 0;
|
||||
color: #bfbfbf;
|
||||
font-size: 10px;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info p {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.info a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.info a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*
|
||||
Hack to remove background from Mobile Safari.
|
||||
Can't use it globally since it destroys checkboxes in Firefox
|
||||
*/
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
.toggle-all,
|
||||
.todo-list li .toggle {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.todo-list li .toggle {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.toggle-all {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 430px) {
|
||||
.footer {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
bottom: 10px;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
setTimeout(function () {
|
||||
|
||||
if (window.isPhantom) return
|
||||
|
||||
// Initial load & render metrics
|
||||
|
||||
metrics.afterRenderAsync = now()
|
||||
console.log('Vue load : ' + (metrics.afterLoad - metrics.beforeLoad).toFixed(2) + 'ms')
|
||||
console.log('Render sync : ' + (metrics.afterRender - metrics.beforeRender).toFixed(2) + 'ms')
|
||||
console.log('Render async : ' + (metrics.afterRenderAsync - metrics.beforeRender).toFixed(2) + 'ms')
|
||||
console.log('Total sync : ' + (metrics.afterRender - metrics.beforeLoad).toFixed(2) + 'ms')
|
||||
console.log('Total async : ' + (metrics.afterRenderAsync - metrics.beforeLoad).toFixed(2) + 'ms')
|
||||
|
||||
// Benchmark
|
||||
// add 100 items
|
||||
// toggle them one by one
|
||||
// then delete them one by one
|
||||
|
||||
var benchSetting = window.location.search.match(/\bbenchmark=(\d+)/)
|
||||
if (!benchSetting) return
|
||||
|
||||
var itemsToAdd = +benchSetting[1],
|
||||
render,
|
||||
bench,
|
||||
addTime,
|
||||
toggleTime,
|
||||
removeTime
|
||||
|
||||
var start = now(),
|
||||
last
|
||||
|
||||
add()
|
||||
|
||||
function add() {
|
||||
last = now()
|
||||
var newTodo = '12345',
|
||||
todoInput = document.getElementById('new-todo')
|
||||
for (var i = 0; i < itemsToAdd; i++) {
|
||||
var keyupEvent = document.createEvent('Event');
|
||||
keyupEvent.initEvent('keyup', true, true);
|
||||
keyupEvent.keyCode = 13;
|
||||
app.newTodo = 'Something to do ' + i;
|
||||
todoInput.dispatchEvent(keyupEvent)
|
||||
}
|
||||
setTimeout(toggle, 0)
|
||||
}
|
||||
|
||||
function toggle () {
|
||||
addTime = now() - last
|
||||
var checkboxes = document.querySelectorAll('.toggle')
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].click()
|
||||
}
|
||||
last = now()
|
||||
setTimeout(remove, 0)
|
||||
}
|
||||
|
||||
function remove () {
|
||||
toggleTime = now() - last
|
||||
var deleteButtons = document.querySelectorAll('.destroy');
|
||||
for (var i = 0; i < deleteButtons.length; i++) {
|
||||
deleteButtons[i].click()
|
||||
}
|
||||
last = now()
|
||||
setTimeout(report, 0)
|
||||
}
|
||||
|
||||
function report () {
|
||||
bench = now() - start
|
||||
removeTime = now() - last
|
||||
console.log('\nBenchmark x ' + itemsToAdd)
|
||||
console.log('add : ' + addTime.toFixed(2) + 'ms')
|
||||
console.log('toggle : ' + toggleTime.toFixed(2) + 'ms')
|
||||
console.log('remove : ' + removeTime.toFixed(2) + 'ms')
|
||||
console.log('total : ' + bench.toFixed(2) + 'ms')
|
||||
}
|
||||
|
||||
}, 0)
|
Loading…
Reference in New Issue
Block a user