From ddc430a6d35fcd4dc07b29b80d4461a70b7c46f6 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Fri, 3 Jun 2016 23:55:31 -0400 Subject: [PATCH] fix most gcc warnings --- README.md | 4 +- index.js | 33 +++--- mithril.js | 240 ++++++++++++++++++++++--------------------- package.json | 2 + promise/promise.js | 175 ++++++++++++++++--------------- querystring/parse.js | 2 +- render/render.js | 30 +++--- request/request.js | 4 +- router/router.js | 2 +- 9 files changed, 248 insertions(+), 244 deletions(-) diff --git a/README.md b/README.md index 8177db24..d1c54163 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,10 @@ Mithril's `config` method is now replaced by several lifecycle methods to improv ## Robustness -There are over 2300 assertions in the test suite, and tests cover even difficult-to-test things like `location.href`, `element.innerHTML` and `XMLHttpRequest` usage. +There are over 2500 assertions in the test suite, and tests cover even difficult-to-test things like `location.href`, `element.innerHTML` and `XMLHttpRequest` usage. ## Modularity -Despite the huge performance improvements, the new codebase is smaller than v0.2.x, currently clocking at 5.6kb min+gzip +Despite the huge performance improvements, the new codebase is smaller than v0.2.x, currently clocking at 6.5kb min+gzip In addition, Mithril is now completely modular: you can import only the modules that you need and easily integrate 3rd party modules if you wish to use a different library for routing, ajax, and even rendering diff --git a/index.js b/index.js index 8467bd99..f433e159 100644 --- a/index.js +++ b/index.js @@ -1,19 +1,20 @@ "use strict" +;(function () { + var Promise = require("./promise/promise") + var m = require("./render/hyperscript") + var renderService = require("./render/render")(window) + var redrawService = require("./api/pubsub")() + var requestService = require("./request/request")(window, Promise) -var Promise = require("./promise/promise") -var m = require("./render/hyperscript") -var renderService = require("./render/render")(window) -var redrawService = require("./api/pubsub")() -var requestService = require("./request/request")(window, Promise) + m.request = requestService.xhr + m.jsonp = requestService.jsonp + m.route = require("./api/router")(window, renderService, redrawService) + m.mount = require("./api/mount")(renderService, redrawService) + m.trust = require("./render/trust") + m.prop = require("./util/prop") + m.withAttr = require("./util/withAttr") + m.render = renderService.render + m.redraw = redrawService.publish -m.request = requestService.xhr -m.jsonp = requestService.jsonp -m.route = require("./api/router")(window, renderService, redrawService) -m.mount = require("./api/mount")(renderService, redrawService) -m.trust = require("./render/trust") -m.prop = require("./util/prop") -m.withAttr = require("./util/withAttr") -m.render = renderService.render -m.redraw = redrawService.publish - -module.exports = m + module.exports = m +})() \ No newline at end of file diff --git a/mithril.js b/mithril.js index 5fb992ba..5813d474 100644 --- a/mithril.js +++ b/mithril.js @@ -1,101 +1,101 @@ "use strict" -if (typeof Promise === "undefined") { - var Promise = function(executor) { - if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") - if (typeof executor !== "function") throw new TypeError("executor must be a function") - - var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) - var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} - var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout - function handler(list, shouldAbsorb) { - return function execute(value) { - var then - try { - if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { - if (value === self) throw new TypeError("Promise can't be resolved w/ itself") - executeOnce(then.bind(value)) - } - else { - callAsync(function() { - if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) - for (var i = 0; i < list.length; i++) list[i](value) - resolvers.length = 0, rejectors.length = 0 - instance.state = shouldAbsorb - instance.retry = function() {execute(value)} - }, 0) - } +;(function () { + /** @constructor */ +var Promise = function(executor) { + if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") + if (typeof executor !== "function") throw new TypeError("executor must be a function") + + var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) + var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} + var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout + function handler(list, shouldAbsorb) { + return function execute(value) { + var then + try { + if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { + if (value === self) throw new TypeError("Promise can't be resolved w/ itself") + executeOnce(then.bind(value)) } - catch (e) { - rejectCurrent(e) + else { + callAsync(function() { + if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) + for (var i = 0; i < list.length; i++) list[i](value) + resolvers.length = 0, rejectors.length = 0 + instance.state = shouldAbsorb + instance.retry = function() {execute(value)} + }) } } - } - function executeOnce(then) { - var runs = 0 - function run(fn) { - return function(value) { - if (runs++ > 0) return - fn(value) - } + catch (e) { + rejectCurrent(e) } - var onerror = run(rejectCurrent) - try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} } - - executeOnce(executor) } - Promise.prototype.then = function(onFulfilled, onRejection) { - var self = this, instance = self._instance - function handle(callback, list, next, state) { - list.push(function(value) { - if (typeof callback !== "function") next(value) - else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} - }) - if (typeof instance.retry === "function" && state === instance.state) instance.retry() + function executeOnce(then) { + var runs = 0 + function run(fn) { + return function(value) { + if (runs++ > 0) return + fn(value) + } } - var resolveNext, rejectNext - var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) - handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) - return promise - } - Promise.prototype.catch = function(onRejection) { - return this.then(null, onRejection) - } - Promise.resolve = function(value) { - if (value instanceof Promise) return value - return new Promise(function(resolve, reject) {resolve(value)}) - } - Promise.reject = function(value) { - return new Promise(function(resolve, reject) {reject(value)}) - } - Promise.all = function(list) { - return new Promise(function(resolve, reject) { - var total = list.length, count = 0, values = [] - if (list.length === 0) resolve([]) - else for (var i = 0; i < list.length; i++) { - new function(i) { - function consume(value) { - count++ - values[i] = value - if (count === total) resolve(values) - } - if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { - list[i].then(consume, reject) - } - else consume(list[i]) - }(i) - } - }) - } - Promise.race = function(list) { - return new Promise(function(resolve, reject) { - for (var i = 0; i < list.length; i++) { - list[i].then(resolve, reject) - } - }) + var onerror = run(rejectCurrent) + try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} } + + executeOnce(executor) } -function Node(tag, key, attrs, children, text, dom) { +Promise.prototype.then = function(onFulfilled, onRejection) { + var self = this, instance = self._instance + function handle(callback, list, next, state) { + list.push(function(value) { + if (typeof callback !== "function") next(value) + else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} + }) + if (typeof instance.retry === "function" && state === instance.state) instance.retry() + } + var resolveNext, rejectNext + var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) + handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) + return promise +} +Promise.prototype.catch = function(onRejection) { + return this.then(null, onRejection) +} +Promise.resolve = function(value) { + if (value instanceof Promise) return value + return new Promise(function(resolve, reject) {resolve(value)}) +} +Promise.reject = function(value) { + return new Promise(function(resolve, reject) {reject(value)}) +} +Promise.all = function(list) { + return new Promise(function(resolve, reject) { + var total = list.length, count = 0, values = [] + if (list.length === 0) resolve([]) + else for (var i = 0; i < list.length; i++) { + (function(i) { + function consume(value) { + count++ + values[i] = value + if (count === total) resolve(values) + } + if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { + list[i].then(consume, reject) + } + else consume(list[i]) + })(i) + } + }) +} +Promise.race = function(list) { + return new Promise(function(resolve, reject) { + for (var i = 0; i < list.length; i++) { + list[i].then(resolve, reject) + } + }) +} + function Node(tag, key, attrs, children, text, dom) { return {tag: tag, key: key, attrs: attrs, children: children, text: text, dom: dom, domSize: undefined, state: {}, events: undefined, instance: undefined} } Node.normalize = function(node) { @@ -170,6 +170,7 @@ function hyperscript(selector) { return Node(selector, attrs && attrs.key, attrs || {}, Node.normalizeChildren(children), undefined, undefined) } var m = hyperscript + var renderService = function($window) { var $doc = $window.document var $emptyFragment = $doc.createDocumentFragment() @@ -242,7 +243,7 @@ var renderService = function($window) { vnode.dom = element if (attrs != null) { - setAttrs(vnode, attrs) + setAttrs(vnode, attrs, ns) } if (vnode.text != null) { @@ -273,7 +274,7 @@ var renderService = function($window) { //update function updateNodes(parent, old, vnodes, hooks, nextSibling) { if (old == null && vnodes == null) return - else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling) + else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined) else if (vnodes == null) removeNodes(parent, old, 0, old.length, vnodes) else { var recycling = isRecyclable(old, vnodes) @@ -320,7 +321,7 @@ var renderService = function($window) { nextSibling = movable.dom } else { - var dom = createNode(v, hooks) + var dom = createNode(v, hooks, undefined) insertNode(parent, dom, nextSibling) nextSibling = dom } @@ -329,7 +330,7 @@ var renderService = function($window) { } if (end < start) break } - createNodes(parent, vnodes, start, end + 1, hooks, nextSibling) + createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, undefined) removeNodes(parent, old, oldStart, oldEnd + 1, vnodes) } } @@ -354,7 +355,7 @@ var renderService = function($window) { } else { removeNode(parent, old, null, false) - insertNode(parent, createNode(vnode, hooks), nextSibling) + insertNode(parent, createNode(vnode, hooks, undefined), nextSibling) } } function updateText(old, vnode) { @@ -511,12 +512,12 @@ var renderService = function($window) { } } //attrs - function setAttrs(vnode, attrs) { + function setAttrs(vnode, attrs, ns) { for (var key in attrs) { - setAttr(vnode, key, null, attrs[key]) + setAttr(vnode, key, null, attrs[key], ns) } } - function setAttr(vnode, key, old, value) { + function setAttr(vnode, key, old, value, ns) { var element = vnode.dom if (key === "key" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return var nsLastIndex = key.indexOf(":") @@ -525,7 +526,7 @@ var renderService = function($window) { } else if (key[0] === "o" && key[1] === "n" && typeof value === "function") updateEvent(vnode, key, value) else if (key === "style") updateStyle(element, old, value) - else if (key in element && !isAttribute(key) && vnode.ns === undefined) { + else if (key in element && !isAttribute(key) && ns === undefined) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return element[key] = value @@ -541,14 +542,14 @@ var renderService = function($window) { function setLateAttrs(vnode) { var attrs = vnode.attrs if (vnode.tag === "select" && attrs != null) { - if ("value" in attrs) setAttr(vnode, "value", null, attrs.value) - if ("selectedIndex" in attrs) setAttr(vnode, "selectedIndex", null, attrs.selectedIndex) + if ("value" in attrs) setAttr(vnode, "value", null, attrs.value, undefined) + if ("selectedIndex" in attrs) setAttr(vnode, "selectedIndex", null, attrs.selectedIndex, undefined) } } function updateAttrs(vnode, old, attrs) { if (attrs != null) { for (var key in attrs) { - setAttr(vnode, key, old && old[key], attrs[key]) + setAttr(vnode, key, old && old[key], attrs[key], undefined) } } if (old != null) { @@ -609,12 +610,12 @@ var renderService = function($window) { } //lifecycle function initLifecycle(source, vnode, hooks) { - if (source.oninit != null) source.oninit.call(vnode.state, vnode) - if (source.oncreate != null) hooks.push(source.oncreate.bind(vnode.state, vnode)) + if (typeof source.oninit === "function") source.oninit.call(vnode.state, vnode) + if (typeof source.oncreate === "function") hooks.push(source.oncreate.bind(vnode.state, vnode)) } function updateLifecycle(source, vnode, hooks, recycling) { if (recycling) initLifecycle(source, vnode, hooks) - else if (source.onupdate != null) hooks.push(source.onupdate.bind(vnode.state, vnode)) + else if (typeof source.onupdate === "function") hooks.push(source.onupdate.bind(vnode.state, vnode)) } function shouldUpdate(vnode, old) { var forceVnodeUpdate, forceComponentUpdate @@ -655,7 +656,7 @@ var renderService = function($window) { } return {render: render, setEventCallback: setEventCallback} }(window) -var redrawService = function() { + var redrawService = function() { var callbacks = [] function unsubscribe(callback) { var index = callbacks.indexOf(callback) @@ -668,7 +669,7 @@ var redrawService = function() { } return {subscribe: callbacks.push.bind(callbacks), unsubscribe: unsubscribe, publish: publish} }() -var buildQueryString = function(object) { + var buildQueryString = function(object) { if (Object.prototype.toString.call(object) !== "[object Object]") return "" var args = [] @@ -695,7 +696,7 @@ var requestService = function($window, Promise1) { var callbackCount = 0 function xhr(args) { return new Promise1(function(resolve, reject) { - var useBody = args.useBody != null ? args.useBody : args.method !== "GET" && args.method !== "TRACE" + var useBody = typeof args.useBody === "boolean" ? args.useBody : args.method !== "GET" && args.method !== "TRACE" if (typeof args.serialize !== "function") args.serialize = JSON.stringify if (typeof args.deserialize !== "function") args.deserialize = deserialize @@ -706,7 +707,7 @@ var requestService = function($window, Promise1) { else args.url = assemble(args.url, args.data) var xhr = new $window.XMLHttpRequest() - xhr.open(args.method, args.url, args.async || true, args.user, args.password) + xhr.open(args.method, args.url, typeof args.async === "boolean" ? args.async : true, typeof args.user === "string" ? args.user : undefined, typeof args.password === "string" ? args.password : undefined) if (args.serialize === JSON.stringify && useBody) { xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8") @@ -795,8 +796,8 @@ var requestService = function($window, Promise1) { return {xhr: xhr, jsonp: jsonp} }(window, Promise) -m.request = requestService.xhr -m.jsonp = requestService.jsonp + m.request = requestService.xhr + m.jsonp = requestService.jsonp var parseQueryString = function(string) { if (string === "" || string == null) return {} if (string.charAt(0) === "?") string = string.slice(1) @@ -822,7 +823,7 @@ var parseQueryString = function(string) { if (key.indexOf("[") > -1) levels.pop() for (var j = 0; j < levels.length; j++) { var level = levels[j], nextLevel = levels[j + 1] - var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel)) + var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10)) var isValue = j === levels.length - 1 if (level === "") { var key = levels.slice(0, j).join() @@ -932,7 +933,7 @@ var coreRouter = function($window) { vnode.dom.setAttribute("href", prefix + vnode.attrs.href) vnode.dom.onclick = function(e) { e.preventDefault() - setPath(vnode.attrs.href) + setPath(vnode.attrs.href, undefined, undefined) } } @@ -973,7 +974,7 @@ var autoredraw = function(root, renderer, pubsub, callback) { return root.redraw = run } -m.route = function($window, renderer, pubsub) { + m.route = function($window, renderer, pubsub) { var router = coreRouter($window) var route = function(root, defaultRoute, routes) { var replay = router.defineRoutes(routes, function(component, args) { @@ -990,7 +991,7 @@ m.route = function($window, renderer, pubsub) { return route }(window, renderService, redrawService) -m.mount = function(renderer, pubsub) { + m.mount = function(renderer, pubsub) { return function(root, component) { var run = autoredraw(root, renderer, pubsub, function() { renderer.render(root, {tag: component}) @@ -999,20 +1000,21 @@ m.mount = function(renderer, pubsub) { run() } }(renderService, redrawService) -m.trust = function(html) { + m.trust = function(html) { return Node("<", undefined, undefined, html, undefined, undefined) } -m.prop = function(store) { + m.prop = function(store) { return function() { if (arguments.length > 0) store = arguments[0] return store } } -m.withAttr = function(attrName, callback, context) { + m.withAttr = function(attrName, callback, context) { return function(e) { return callback.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName)) } } -m.render = renderService.render -m.redraw = redrawService.publish -module.exports = m + m.render = renderService.render + m.redraw = redrawService.publish + module.exports = m +})() \ No newline at end of file diff --git a/package.json b/package.json index 2decdd87..33fae8a4 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "main": "index.js", "scripts": { "build": "node bundler/bundler", + "minify": "uglifyjs mithril.js -m -c -o mithril.min.js", + "size": "uglifyjs mithril.js -m -c | gzipped", "lint": "eslint .", "test": "node ospec/bin/ospec", "cover": "istanbul cover --print both ospec/bin/ospec" diff --git a/promise/promise.js b/promise/promise.js index 68247f69..da382775 100644 --- a/promise/promise.js +++ b/promise/promise.js @@ -1,99 +1,98 @@ "use strict" - -if (typeof Promise === "undefined") { - var Promise = function(executor) { - if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") - if (typeof executor !== "function") throw new TypeError("executor must be a function") - - var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) - var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} - var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout - function handler(list, shouldAbsorb) { - return function execute(value) { - var then - try { - if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { - if (value === self) throw new TypeError("Promise can't be resolved w/ itself") - executeOnce(then.bind(value)) - } - else { - callAsync(function() { - if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) - for (var i = 0; i < list.length; i++) list[i](value) - resolvers.length = 0, rejectors.length = 0 - instance.state = shouldAbsorb - instance.retry = function() {execute(value)} - }, 0) - } +/** @constructor */ +var Promise = function(executor) { + if (!(this instanceof Promise)) throw new Error("Promise must be called with `new`") + if (typeof executor !== "function") throw new TypeError("executor must be a function") + + var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false) + var instance = self._instance = {resolvers: resolvers, rejectors: rejectors} + var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout + function handler(list, shouldAbsorb) { + return function execute(value) { + var then + try { + if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") { + if (value === self) throw new TypeError("Promise can't be resolved w/ itself") + executeOnce(then.bind(value)) } - catch (e) { - rejectCurrent(e) + else { + callAsync(function() { + if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value) + for (var i = 0; i < list.length; i++) list[i](value) + resolvers.length = 0, rejectors.length = 0 + instance.state = shouldAbsorb + instance.retry = function() {execute(value)} + }) } } - } - function executeOnce(then) { - var runs = 0 - function run(fn) { - return function(value) { - if (runs++ > 0) return - fn(value) - } + catch (e) { + rejectCurrent(e) } - var onerror = run(rejectCurrent) - try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} } - - executeOnce(executor) } - Promise.prototype.then = function(onFulfilled, onRejection) { - var self = this, instance = self._instance - function handle(callback, list, next, state) { - list.push(function(value) { - if (typeof callback !== "function") next(value) - else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} - }) - if (typeof instance.retry === "function" && state === instance.state) instance.retry() + function executeOnce(then) { + var runs = 0 + function run(fn) { + return function(value) { + if (runs++ > 0) return + fn(value) + } } - var resolveNext, rejectNext - var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) - handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) - return promise - } - Promise.prototype.catch = function(onRejection) { - return this.then(null, onRejection) - } - Promise.resolve = function(value) { - if (value instanceof Promise) return value - return new Promise(function(resolve, reject) {resolve(value)}) - } - Promise.reject = function(value) { - return new Promise(function(resolve, reject) {reject(value)}) - } - Promise.all = function(list) { - return new Promise(function(resolve, reject) { - var total = list.length, count = 0, values = [] - if (list.length === 0) resolve([]) - else for (var i = 0; i < list.length; i++) { - new function(i) { - function consume(value) { - count++ - values[i] = value - if (count === total) resolve(values) - } - if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { - list[i].then(consume, reject) - } - else consume(list[i]) - }(i) - } - }) - } - Promise.race = function(list) { - return new Promise(function(resolve, reject) { - for (var i = 0; i < list.length; i++) { - list[i].then(resolve, reject) - } - }) + var onerror = run(rejectCurrent) + try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)} } + + executeOnce(executor) } +Promise.prototype.then = function(onFulfilled, onRejection) { + var self = this, instance = self._instance + function handle(callback, list, next, state) { + list.push(function(value) { + if (typeof callback !== "function") next(value) + else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)} + }) + if (typeof instance.retry === "function" && state === instance.state) instance.retry() + } + var resolveNext, rejectNext + var promise = new Promise(function(resolve, reject) {resolveNext = resolve, rejectNext = reject}) + handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false) + return promise +} +Promise.prototype.catch = function(onRejection) { + return this.then(null, onRejection) +} +Promise.resolve = function(value) { + if (value instanceof Promise) return value + return new Promise(function(resolve, reject) {resolve(value)}) +} +Promise.reject = function(value) { + return new Promise(function(resolve, reject) {reject(value)}) +} +Promise.all = function(list) { + return new Promise(function(resolve, reject) { + var total = list.length, count = 0, values = [] + if (list.length === 0) resolve([]) + else for (var i = 0; i < list.length; i++) { + (function(i) { + function consume(value) { + count++ + values[i] = value + if (count === total) resolve(values) + } + if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") { + list[i].then(consume, reject) + } + else consume(list[i]) + })(i) + } + }) +} +Promise.race = function(list) { + return new Promise(function(resolve, reject) { + for (var i = 0; i < list.length; i++) { + list[i].then(resolve, reject) + } + }) +} + module.exports = Promise diff --git a/querystring/parse.js b/querystring/parse.js index 2783cf27..5e0441f0 100644 --- a/querystring/parse.js +++ b/querystring/parse.js @@ -25,7 +25,7 @@ module.exports = function(string) { if (key.indexOf("[") > -1) levels.pop() for (var j = 0; j < levels.length; j++) { var level = levels[j], nextLevel = levels[j + 1] - var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel)) + var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10)) var isValue = j === levels.length - 1 if (level === "") { var key = levels.slice(0, j).join() diff --git a/render/render.js b/render/render.js index 9d2a5ac5..669bf2d4 100644 --- a/render/render.js +++ b/render/render.js @@ -75,7 +75,7 @@ module.exports = function($window) { vnode.dom = element if (attrs != null) { - setAttrs(vnode, attrs) + setAttrs(vnode, attrs, ns) } if (vnode.text != null) { @@ -107,7 +107,7 @@ module.exports = function($window) { //update function updateNodes(parent, old, vnodes, hooks, nextSibling) { if (old == null && vnodes == null) return - else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling) + else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined) else if (vnodes == null) removeNodes(parent, old, 0, old.length, vnodes) else { var recycling = isRecyclable(old, vnodes) @@ -154,7 +154,7 @@ module.exports = function($window) { nextSibling = movable.dom } else { - var dom = createNode(v, hooks) + var dom = createNode(v, hooks, undefined) insertNode(parent, dom, nextSibling) nextSibling = dom } @@ -163,7 +163,7 @@ module.exports = function($window) { } if (end < start) break } - createNodes(parent, vnodes, start, end + 1, hooks, nextSibling) + createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, undefined) removeNodes(parent, old, oldStart, oldEnd + 1, vnodes) } } @@ -188,7 +188,7 @@ module.exports = function($window) { } else { removeNode(parent, old, null, false) - insertNode(parent, createNode(vnode, hooks), nextSibling) + insertNode(parent, createNode(vnode, hooks, undefined), nextSibling) } } function updateText(old, vnode) { @@ -348,12 +348,12 @@ module.exports = function($window) { } //attrs - function setAttrs(vnode, attrs) { + function setAttrs(vnode, attrs, ns) { for (var key in attrs) { - setAttr(vnode, key, null, attrs[key]) + setAttr(vnode, key, null, attrs[key], ns) } } - function setAttr(vnode, key, old, value) { + function setAttr(vnode, key, old, value, ns) { var element = vnode.dom if (key === "key" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return var nsLastIndex = key.indexOf(":") @@ -362,7 +362,7 @@ module.exports = function($window) { } else if (key[0] === "o" && key[1] === "n" && typeof value === "function") updateEvent(vnode, key, value) else if (key === "style") updateStyle(element, old, value) - else if (key in element && !isAttribute(key) && vnode.ns === undefined) { + else if (key in element && !isAttribute(key) && ns === undefined) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return element[key] = value @@ -378,14 +378,14 @@ module.exports = function($window) { function setLateAttrs(vnode) { var attrs = vnode.attrs if (vnode.tag === "select" && attrs != null) { - if ("value" in attrs) setAttr(vnode, "value", null, attrs.value) - if ("selectedIndex" in attrs) setAttr(vnode, "selectedIndex", null, attrs.selectedIndex) + if ("value" in attrs) setAttr(vnode, "value", null, attrs.value, undefined) + if ("selectedIndex" in attrs) setAttr(vnode, "selectedIndex", null, attrs.selectedIndex, undefined) } } function updateAttrs(vnode, old, attrs) { if (attrs != null) { for (var key in attrs) { - setAttr(vnode, key, old && old[key], attrs[key]) + setAttr(vnode, key, old && old[key], attrs[key], undefined) } } if (old != null) { @@ -447,12 +447,12 @@ module.exports = function($window) { //lifecycle function initLifecycle(source, vnode, hooks) { - if (source.oninit != null) source.oninit.call(vnode.state, vnode) - if (source.oncreate != null) hooks.push(source.oncreate.bind(vnode.state, vnode)) + if (typeof source.oninit === "function") source.oninit.call(vnode.state, vnode) + if (typeof source.oncreate === "function") hooks.push(source.oncreate.bind(vnode.state, vnode)) } function updateLifecycle(source, vnode, hooks, recycling) { if (recycling) initLifecycle(source, vnode, hooks) - else if (source.onupdate != null) hooks.push(source.onupdate.bind(vnode.state, vnode)) + else if (typeof source.onupdate === "function") hooks.push(source.onupdate.bind(vnode.state, vnode)) } function shouldUpdate(vnode, old) { var forceVnodeUpdate, forceComponentUpdate diff --git a/request/request.js b/request/request.js index 75160272..071600d6 100644 --- a/request/request.js +++ b/request/request.js @@ -7,7 +7,7 @@ module.exports = function($window, Promise) { function xhr(args) { return new Promise(function(resolve, reject) { - var useBody = args.useBody != null ? args.useBody : args.method !== "GET" && args.method !== "TRACE" + var useBody = typeof args.useBody === "boolean" ? args.useBody : args.method !== "GET" && args.method !== "TRACE" if (typeof args.serialize !== "function") args.serialize = JSON.stringify if (typeof args.deserialize !== "function") args.deserialize = deserialize @@ -18,7 +18,7 @@ module.exports = function($window, Promise) { else args.url = assemble(args.url, args.data) var xhr = new $window.XMLHttpRequest() - xhr.open(args.method, args.url, args.async || true, args.user, args.password) + xhr.open(args.method, args.url, typeof args.async === "boolean" ? args.async : true, typeof args.user === "string" ? args.user : undefined, typeof args.password === "string" ? args.password : undefined) if (args.serialize === JSON.stringify && useBody) { xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8") diff --git a/router/router.js b/router/router.js index f6911de0..5b66671d 100644 --- a/router/router.js +++ b/router/router.js @@ -100,7 +100,7 @@ module.exports = function($window) { vnode.dom.setAttribute("href", prefix + vnode.attrs.href) vnode.dom.onclick = function(e) { e.preventDefault() - setPath(vnode.attrs.href) + setPath(vnode.attrs.href, undefined, undefined) } }