From 9ae592ee4d186567925c866b663f5d995d374ee6 Mon Sep 17 00:00:00 2001 From: impinball Date: Thu, 9 Jul 2015 16:14:08 -0400 Subject: [PATCH 1/2] Do some local style modifications and profile. 1. Do some temporary style modifications to help make the code more readable for profiling (with help from ESLint). 2. Profile the code, and optimize accordingly. --- .eslintignore | 5 + .eslintrc | 27 + Gruntfile.js | 302 +- README.md | 2 + docs/layout/tools/template-converter.js | 164 +- mithril.js | 2626 +++++++++++------ package.json | 97 +- tests/e2e/.eslintrc | 23 + tests/e2e/tests.js | 403 +-- tests/mithril-tests.js | 3411 +++++++++++++---------- tests/mock.js | 50 +- tests/test.js | 11 +- 12 files changed, 4426 insertions(+), 2695 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 tests/e2e/.eslintrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..29de9e28 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules +**/*.min.js +docs/layout/lib/**/*.js +tests/e2e/libs/** +mithril.closure-compiler-externs.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..a3c03520 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + "env": { + "browser": true + }, + "rules": { + "no-cond-assign": [2, "except-parens"], + "no-shadow": 0, + "semi-spacing": 0, + "quotes": [2, "double", "avoid-escape"], + "curly": [2, "multi-line"], + "semi": [2, "never"], + "eqeqeq": [2, "allow-null"], + "no-throw-literal": 2, + "wrap-iife": 2, + "strict": [2, "function"], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "linebreak-style": [1, "windows"], + "one-var": [2, { + "initialized": "never" + }], + "new-cap": 0, + "no-use-before-define": [2, "nofunc"], + "max-len": [2, 80, 4], + "dot-notation": 2, + "indent": [2, "tab"] + } +} diff --git a/Gruntfile.js b/Gruntfile.js index ae789912..69afbcb0 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,14 +1,15 @@ +/* eslint-env node */ module.exports = function(grunt) { - _ = require('lodash'); + "use strict" - var version = "0.2.0"; + var _ = require("lodash") + var version = "0.4.0" - var inputFolder = "./docs"; - var tempFolder = "./temp"; - var archiveFolder = "./archive"; - var outputFolder = "../mithril"; + var inputFolder = "./docs" + var tempFolder = "./temp" + var archiveFolder = "./archive" + var outputFolder = "../mithril" - var guideLayout = "guide"; var guide = [ "auto-redrawing", "benchmarks", @@ -24,8 +25,7 @@ module.exports = function(grunt) { "routing", "tools", "web-services" - ]; - var apiLayout = "api"; + ] var api = [ "change-log", "roadmap", @@ -45,55 +45,68 @@ module.exports = function(grunt) { "mithril.trust", "mithril.withAttr", "mithril.xhr" - ]; + ] - - - var md2htmlTasks = {}; + var md2htmlTasks = {} var makeTasks = function(layout, pages) { pages.map(function(name) { - var src = inputFolder + "/" + name + ".md"; - var title = (grunt.file.exists(src)) ? grunt.file.read(src).split(/\n/)[0].substring(3) + ' - ' : ''; + var src = inputFolder + "/" + name + ".md" + var title + if (grunt.file.exist(src)) { + title = grunt.file.read(src) + .split(/\n/)[0] + .substring(3) + " - " + } else { + title = "" + } md2htmlTasks[name] = { - options: {layout: inputFolder + "/layout/" + layout + ".html", templateData: { "topic": title }}, + options: { + layout: inputFolder + "/layout/" + layout + ".html", + templateData: { "topic": title } + }, files: [{src: [src], dest: tempFolder + "/" + name + ".html"}] } }) - }; - makeTasks("guide", guide); - makeTasks("api", api); + } + makeTasks("guide", guide) + makeTasks("api", api) - var sauceBrowsers =[ - { browserName: 'firefox', version: '19', platform: 'XP' }, + var sauceBrowsers = [ + { browserName: "firefox", version: "19", platform: "XP" }, { browserName: "internet explorer", platform: "XP", version: "6"}, { browserName: "safari", platform: "OS X 10.9", version: "7"}, { browserName: "iPad", platform: "OS X 10.9", version: "7.1"}, { browserName: "opera", platform: "Linux", version: "12"}, { browserName: "chrome", platform: "XP", version: "26"}, { browserName: "chrome", platform: "Windows 8", version: "26"} - ]; + ] var sauceOnTestComplete = function(result, callback) { - var request = require('request'); + var request = require("request") - var user = process.env.SAUCE_USERNAME; - var pass = process.env.SAUCE_ACCESS_KEY; + var user = process.env.SAUCE_USERNAME + var pass = process.env.SAUCE_ACCESS_KEY request.put({ - url: ['https://saucelabs.com/rest/v1', user, 'jobs', result.job_id].join('/'), + url: [ + "https://saucelabs.com/rest/v1", + user, + "jobs", + result.job_id + ].join("/"), auth: { user: user, pass: pass }, json: { passed: result.passed } - }, function (error, response, body) { + }, function (error, response) { if (error) { - callback(error); + callback(error) } else if (response.statusCode !== 200) { - callback(new Error('Unexpected response status: ' - + response.statusCode + "\n ")); + callback(new Error("Unexpected response status: " + + response.statusCode + "\n ")) } else { - callback(null, result.passed); + callback(null, result.passed) } - }); - }; + }) + } var sauceBaseOptions = { username: process.env.SAUCE_USERNAME, @@ -102,74 +115,164 @@ module.exports = function(grunt) { browsers: sauceBrowsers, sauceConfig: { "record-video": false, - "record-screenshots": false, + "record-screenshots": false }, build: process.env.TRAVIS_JOB_ID, onTestComplete: sauceOnTestComplete, - tunnelTimeout: 5, - }; + tunnelTimeout: 5 + } var sauceCustomOptions = { - testname: "Mithril Custom Tests "+ new Date().toJSON(), - urls: ["http://127.0.0.1:8000/tests/index.html"], - }; - _.assign(sauceCustomOptions, sauceBaseOptions); + testname: "Mithril Custom Tests " + new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/index.html"] + } + _.assign(sauceCustomOptions, sauceBaseOptions) var sauceQunitOptions = { - testname: "qUnit Tests "+ new Date().toJSON(), - urls: ["http://127.0.0.1:8000/tests/e2e/test.html"], - }; - _.assign(sauceQunitOptions, sauceBaseOptions); + testname: "qUnit Tests " + new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/e2e/test.html"] + } + _.assign(sauceQunitOptions, sauceBaseOptions) - var currentVersionArchiveFolder = archiveFolder + "/v" + version; + var currentVersionArchiveFolder = archiveFolder + "/v" + version grunt.initConfig({ md2html: md2htmlTasks, uglify: { - options: {banner: "/*\nMithril v" + version + "\nhttp://github.com/lhorie/mithril.js\n(c) Leo Horie\nLicense: MIT\n*/", sourceMap: true}, + options: { + banner: [[ + "/*", + "Mithril v" + version, + "http://github.com/lhorie/mithril.js", + "(c) Leo Horie", + "License: MIT", + "*/" + ].join("\n")], + sourceMap: true + }, mithril: {src: "mithril.js", dest: "mithril.min.js"} }, concat: { - test: {src: ["mithril.js", "./tests/test.js", "./tests/mock.js", "./tests/mithril-tests.js"], dest: currentVersionArchiveFolder + "/mithril-tests.js"} + test: { + src: [ + "mithril.js", + "./tests/test.js", + "./tests/mock.js", + "./tests/mithril-tests.js" + ], + dest: currentVersionArchiveFolder + "/mithril-tests.js" + } }, zip: { distribution: { cwd: currentVersionArchiveFolder + "/", - src: [currentVersionArchiveFolder + "/mithril.min.js", currentVersionArchiveFolder + "/mithril.min.js.map", currentVersionArchiveFolder + "/mithril.js"], + src: [ + currentVersionArchiveFolder + "/mithril.min.js", + currentVersionArchiveFolder + "/mithril.min.js.map", + currentVersionArchiveFolder + "/mithril.js" + ], dest: currentVersionArchiveFolder + "/mithril.min.zip" } }, replace: { - options: {force: true, patterns: [{match: /\.md/g, replacement: ".html"}, {match: /\$version/g, replacement: version}]}, - links: {expand: true, flatten: true, src: [tempFolder + "/**/*.html"], dest: currentVersionArchiveFolder + "/"}, - index: {src: inputFolder + "/layout/index.html", dest: currentVersionArchiveFolder + "/index.html"}, - commonjs: {expand: true, flatten: true, src: [inputFolder + "/layout/*.json"], dest: currentVersionArchiveFolder}, - cdnjs: {src: "deploy/cdnjs-package.json", dest: "../cdnjs/ajax/libs/mithril/package.json"} + options: { + force: true, + patterns: [ + {match: /\.md/g, replacement: ".html"}, + {match: /\$version/g, replacement: version} + ] + }, + links: { + expand: true, + flatten: true, + src: [tempFolder + "/**/*.html"], + dest: currentVersionArchiveFolder + "/" + }, + index: { + src: inputFolder + "/layout/index.html", + dest: currentVersionArchiveFolder + "/index.html" + }, + commonjs: { + expand: true, + flatten: true, + src: [inputFolder + "/layout/*.json"], + dest: currentVersionArchiveFolder + }, + cdnjs: { + src: "deploy/cdnjs-package.json", + dest: "../cdnjs/ajax/libs/mithril/package.json" + } }, copy: { - style: {src: inputFolder + "/layout/style.css", dest: currentVersionArchiveFolder + "/style.css"}, - pages: {src: inputFolder + "/layout/pages.json", dest: currentVersionArchiveFolder + "/pages.json"}, - lib: {expand: true, cwd: inputFolder + "/layout/lib/", src: "./**", dest: currentVersionArchiveFolder + "/lib/"}, - tools: {expand: true, cwd: inputFolder + "/layout/tools/", src: "./**", dest: currentVersionArchiveFolder + "/tools/"}, - comparisons: {expand: true, cwd: inputFolder + "/layout/comparisons/", src: "./**", dest: currentVersionArchiveFolder + "/comparisons/"}, - unminified: {src: "mithril.js", dest: currentVersionArchiveFolder + "/mithril.js"}, - minified: {src: "mithril.min.js", dest: currentVersionArchiveFolder + "/mithril.min.js"}, - readme: {src: "README.md", dest: currentVersionArchiveFolder + "/README.md"}, - map: {src: "mithril.min.js.map", dest: currentVersionArchiveFolder + "/mithril.min.js.map"}, - typescript: {src: "mithril.d.ts", dest: currentVersionArchiveFolder + "/mithril.d.ts"}, - publish: {expand: true, cwd: currentVersionArchiveFolder, src: "./**", dest: outputFolder}, - archive: {expand: true, cwd: currentVersionArchiveFolder, src: "./**", dest: outputFolder + "/archive/v" + version}, + style: { + src: inputFolder + "/layout/style.css", + dest: currentVersionArchiveFolder + "/style.css" + }, + pages: { + src: inputFolder + "/layout/pages.json", + dest: currentVersionArchiveFolder + "/pages.json" + }, + lib: { + expand: true, + cwd: inputFolder + "/layout/lib/", + src: "./**", + dest: currentVersionArchiveFolder + "/lib/" + }, + tools: { + expand: true, + cwd: inputFolder + "/layout/tools/", + src: "./**", + dest: currentVersionArchiveFolder + "/tools/" + }, + comparisons: { + expand: true, + cwd: inputFolder + "/layout/comparisons/", + src: "./**", + dest: currentVersionArchiveFolder + "/comparisons/" + }, + unminified: { + src: "mithril.js", + dest: currentVersionArchiveFolder + "/mithril.js" + }, + minified: { + src: "mithril.min.js", + dest: currentVersionArchiveFolder + "/mithril.min.js" + }, + readme: { + src: "README.md", + dest: currentVersionArchiveFolder + "/README.md" + }, + map: { + src: "mithril.min.js.map", + dest: currentVersionArchiveFolder + "/mithril.min.js.map" + }, + typescript: { + src: "mithril.d.ts", + dest: currentVersionArchiveFolder + "/mithril.d.ts" + }, + publish: { + expand: true, + cwd: currentVersionArchiveFolder, + src: "./**", + dest: outputFolder + }, + archive: { + expand: true, + cwd: currentVersionArchiveFolder, + src: "./**", + dest: outputFolder + "/archive/v" + version + } }, execute: { tests: {src: [currentVersionArchiveFolder + "/mithril-tests.js"]} }, qunit: { - all: ['tests/e2e/**/*.html'] + all: ["tests/e2e/**/*.html"] }, "saucelabs-custom": { - all:{ + all: { options: sauceCustomOptions } }, "saucelabs-qunit": { - all:{ + all: { options: sauceQunitOptions } }, @@ -179,7 +282,7 @@ module.exports = function(grunt) { server: { options: { port: 8888, - base: '.' + base: "." } } }, @@ -191,34 +294,45 @@ module.exports = function(grunt) { default: { files: [{ expand: true, - src: ['mithril.js'], - cwd: '.', - dest: '.' + src: ["mithril.js"], + cwd: ".", + dest: "." }] } + }, + eslint: { + target: [ + "**/*.js", + "!node_modules/**", + "!**/*.min.js", + "!docs/layout/lib/**/*.js" + ] } - }); + }) - grunt.loadNpmTasks("grunt-contrib-clean"); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks("grunt-contrib-copy"); - grunt.loadNpmTasks("grunt-contrib-uglify"); - grunt.loadNpmTasks('grunt-execute'); - grunt.loadNpmTasks("grunt-md2html"); - grunt.loadNpmTasks("grunt-replace"); - grunt.loadNpmTasks('grunt-zip'); - grunt.loadNpmTasks('grunt-contrib-qunit'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-saucelabs'); - grunt.loadNpmTasks('grunt-jsfmt'); + grunt.loadNpmTasks("grunt-contrib-clean") + grunt.loadNpmTasks("grunt-contrib-concat") + grunt.loadNpmTasks("grunt-contrib-copy") + grunt.loadNpmTasks("grunt-contrib-uglify") + grunt.loadNpmTasks("grunt-execute") + grunt.loadNpmTasks("grunt-md2html") + grunt.loadNpmTasks("grunt-replace") + grunt.loadNpmTasks("grunt-zip") + grunt.loadNpmTasks("grunt-contrib-qunit") + grunt.loadNpmTasks("grunt-contrib-connect") + grunt.loadNpmTasks("grunt-saucelabs") + grunt.loadNpmTasks("grunt-jsfmt") + grunt.loadNpmTasks("grunt-eslint") - grunt.registerTask("build", ["test", "uglify", "zip", "md2html", "replace", "copy", "clean"]); - grunt.registerTask("testall", ["test", "teste2e"]); - grunt.registerTask("test", ["concat", "execute"]); - grunt.registerTask('teste2e', ['connect', 'qunit']); - grunt.registerTask("default", ["build"]); + grunt.registerTask("build", [ + "test", "uglify", "zip", "md2html", "replace", "copy", "clean"]) + grunt.registerTask("testall", ["test", "teste2e"]) + grunt.registerTask("test", ["eslint", "concat", "execute"]) + grunt.registerTask("teste2e", ["connect", "qunit"]) + grunt.registerTask("default", ["build"]) - grunt.registerTask("sauce-qunit", ["connect", "saucelabs-qunit"]); - grunt.registerTask("sauce-custom", ["connect", "saucelabs-custom"]); - grunt.registerTask("sauce-all", ["connect", "saucelabs-qunit", "saucelabs-custom"]); -}; + grunt.registerTask("sauce-qunit", ["connect", "saucelabs-qunit"]) + grunt.registerTask("sauce-custom", ["connect", "saucelabs-custom"]) + grunt.registerTask("sauce-all", [ + "connect", "saucelabs-qunit", "saucelabs-custom"]) +} diff --git a/README.md b/README.md index 8f8cc956..ca56901a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +**Note: This is a WIP partial rewrite of Mithril.** + [![JS.ORG](https://img.shields.io/badge/js.org-mithril-ffb400.svg?style=flat-square)](http://js.org) [![Join the chat at https://gitter.im/lhorie/mithril.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lhorie/mithril.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/lhorie/mithril.js.svg?branch=master)](https://travis-ci.org/lhorie/mithril.js) diff --git a/docs/layout/tools/template-converter.js b/docs/layout/tools/template-converter.js index b8cd01cf..79046db2 100644 --- a/docs/layout/tools/template-converter.js +++ b/docs/layout/tools/template-converter.js @@ -1,90 +1,128 @@ -var templateConverter = {}; +/* globals m */ + +var templateConverter = {} templateConverter.DOMFragment = function(markup) { - if (markup.indexOf(" -1) return [new DOMParser().parseFromString(markup, "text/html").childNodes[1]] - var container = document.createElement("div"); - container.insertAdjacentHTML("beforeend", markup); - return container.childNodes; + "use strict" + if (markup.indexOf(" -1) { + return [ + new DOMParser().parseFromString(markup, "text/html").childNodes[1] + ] + } + var container = document.createElement("div") + container.insertAdjacentHTML("beforeend", markup) + return container.childNodes } templateConverter.VirtualFragment = function recurse(domFragment) { - var virtualFragment = []; - for (var i = 0, el; el = domFragment[i]; i++) { - if (el.nodeType == 3) { - virtualFragment.push(el.nodeValue); - } - else if (el.nodeType == 1) { - var attrs = {}; - for (var j = 0, attr; attr = el.attributes[j]; j++) { - attrs[attr.name] = attr.value; + "use strict" + var virtualFragment = [] + for (var i = 0; i < domFragment.length; i++) { + var el = domFragment[i] + if (el.nodeType === 3) { + virtualFragment.push(el.nodeValue) + } else if (el.nodeType === 1) { + var attrs = {} + for (var j = 0; el.attributes.length; j++) { + var attr = el.attributes[j] + attrs[attr.name] = attr.value } - - virtualFragment.push({tag: el.nodeName.toLowerCase(), attrs: attrs, children: recurse(el.childNodes)}); + + virtualFragment.push({ + tag: el.nodeName.toLowerCase(), + attrs: attrs, + children: recurse(el.childNodes) + }) } } - return virtualFragment; + return virtualFragment } templateConverter.Template = function recurse() { - if (Object.prototype.toString.call(arguments[0]) == "[object String]") { - return new recurse(new templateConverter.VirtualFragment(new templateConverter.DOMFragment(arguments[0]))); + "use strict" + if (Object.prototype.toString.call(arguments[0]) === "[object String]") { + return new recurse(new templateConverter.VirtualFragment( + new templateConverter.DOMFragment(arguments[0]))) } - - var virtualFragment = arguments[0], level = arguments[1] - if (!level) level = 1; - - var tab = "\n" + new Array(level + 1).join("\t"); - var virtuals = []; - for (var i = 0, el; el = virtualFragment[i]; i++) { - if (typeof el == "string") { - if (el.match(/\t| {2,}/g) && el.trim().length == 0) virtuals.indented = true; - else virtuals.push('"' + el.replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n") + '"'); - } - else { - var virtual = ""; - if (el.tag != "div") virtual += el.tag; - if (el.attrs["class"]) { - virtual += "." + el.attrs["class"].replace(/\t+/g, " ").split(" ").join("."); - delete el.attrs["class"]; + + var virtualFragment = arguments[0] + var level = arguments[1] + if (!level) level = 1 + + var tab = "\n" + new Array(level + 1).join("\t") + var virtuals = [] + for (var i = 0; i < virtualFragment.length; i++) { + var el = virtualFragment[i] + if (typeof el === "string") { + if (el.match(/\t| {2,}/g) && el.trim().length === 0) { + virtuals.indented = true + } else { + virtuals.push('"' + el + .replace(/"/g, '\\"') + .replace(/\r/g, "\\r") + .replace(/\n/g, "\\n") + '"') + } + } else { + var virtual = "" + if (el.tag !== "div") virtual += el.tag + if (el.attrs.class) { + virtual += "." + el.attrs.class + .replace(/\t+/g, " ") + .split(" ") + .join(".") + delete el.attrs.class } var attrNames = Object.keys(el.attrs).sort() - for (var j = 0, attrName; attrName = attrNames[j]; j++) { - if (attrName != "style") virtual += "[" + attrName + "='" + el.attrs[attrName].replace(/'/g, "\\'") + "']"; + for (var j = 0; j < attrNames.length; j++) { + var attrName = attrNames[j] + if (attrName !== "style") { + virtual += "[" + attrName + "='" + + el.attrs[attrName].replace(/'/g, "\\'") + "']" + } } - if (virtual == "") virtual = "div" - virtual = '"' + virtual + '"'; - - var style = "" + if (virtual === "") virtual = "div" + virtual = '"' + virtual + '"' + if (el.attrs.style) { - virtual += ", {style: " + ("{\"" + el.attrs.style.replace(/:/g, "\": \"").replace(/;/g, "\", \"") + "}").replace(/, "}|"}/, "}") + "}" + virtual += ", {style: " + ("{\"" + el.attrs.style + .replace(/:/g, "\": \"") + .replace(/;/g, "\", \"") + "}") + .replace(/, "}|"}/, "}") + "}" } - + if (el.children.length > 0) { - virtual += ", " + recurse(el.children, level + 1); + virtual += ", " + recurse(el.children, level + 1) } - virtual = "m(" + virtual + ")"; - virtuals.push(virtual); + virtual = "m(" + virtual + ")" + virtuals.push(virtual) } } - if (!virtuals.indented) tab = ""; - - var isInline = virtuals.length == 1 && virtuals[0].charAt(0) == '"'; - var template = isInline ? virtuals.join(", ") : "[" + tab + virtuals.join("," + tab) + tab.slice(0, -1) + "]"; - return new String(template); + if (!virtuals.indented) tab = "" + + var isInline = virtuals.length === 1 && virtuals[0].charAt(0) === '"' + var template = isInline ? + virtuals.join(", ") : + "[" + tab + virtuals.join("," + tab) + tab.slice(0, -1) + "]" + return new String(template) // eslint-disable-line no-new-wrappers } templateConverter.controller = function() { - this.source = m.prop(""); - this.output = m.prop(""); - + "use strict" + this.source = m.prop("") + this.output = m.prop("") + this.convert = function() { - return this.output(new templateConverter.Template(this.source())); - }; - -}; + return this.output(new templateConverter.Template(this.source())) + } +} templateConverter.view = function(ctrl) { + "use strict" return m("div", [ - m("textarea", {autofocus: true, style: {width:"100%", height: "40%"}, onchange: m.withAttr("value", ctrl.source)}, ctrl.source()), + m("textarea", { + autofocus: true, + style: {width: "100%", height: "40%"}, + onchange: m.withAttr("value", ctrl.source) + }, ctrl.source()), m("button", {onclick: ctrl.convert.bind(ctrl)}, "Convert"), - m("textarea", {style: {width:"100%", height: "40%"}}, ctrl.output()) - ]); -}; \ No newline at end of file + m("textarea", {style: {width: "100%", height: "40%"}}, ctrl.output()) + ]) +} diff --git a/mithril.js b/mithril.js index c4ed06fc..06e10307 100644 --- a/mithril.js +++ b/mithril.js @@ -1,33 +1,63 @@ +/* eslint-disable wrap-iife, no-shadow-restricted-names */ var m = (function app(window, undefined) { +/* eslint-enable wrap-iife, no-shadow-restricted-names */ + "use strict" + + function noop() {} + + var type = {}.toString + function isFunction(object) { - return typeof object === "function"; + return typeof object === "function" } + function isObject(object) { - return type.call(object) === "[object Object]"; + return type.call(object) === "[object Object]" } + function isString(object) { - return type.call(object) === "[object String]"; + return type.call(object) === "[object String]" } + var isArray = Array.isArray || function (object) { - return type.call(object) === "[object Array]"; - }; - var type = {}.toString; - var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/; - var voidElements = /^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/; - var noop = function () {}; + return type.call(object) === "[object Array]" + } + + var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g + var attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/ + /* eslint-disable max-len */ + var voidElements = /^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/ + /* eslint-enable max-len */ // caching commonly used variables - var $document, $location, $requestAnimationFrame, $cancelAnimationFrame; + var $document, $location, $requestAnimationFrame, $cancelAnimationFrame + + var roots = [] + var components = [] + var controllers = [] + var lastRedrawId = null + var lastRedrawCallTime = 0 + var computePreRedrawHook = null + var computePostRedrawHook = null + var unloaders = [] + var FRAME_BUDGET = 16 // 60 frames per second = 1 call per 16 ms + var topComponent + + var redrawing = false + var forcing = false + var pendingRequests = 0 // self invoking function needed because of the way mocks work - function initialize(window){ - $document = window.document; - $location = window.location; - $cancelAnimationFrame = window.cancelAnimationFrame || window.clearTimeout; - $requestAnimationFrame = window.requestAnimationFrame || window.setTimeout; + function initialize(window) { + $document = window.document + $location = window.location + $cancelAnimationFrame = window.cancelAnimationFrame || + window.clearTimeout + $requestAnimationFrame = window.requestAnimationFrame || + window.setTimeout } - initialize(window); + initialize(window) /** @@ -40,1163 +70,1977 @@ var m = (function app(window, undefined) { * * @param {Tag} The DOM node tag * @param {Object=[]} optional key-value pairs to be mapped to DOM attrs - * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, or splat (optional) + * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, + * or splat (optional) * */ function m(tag, pairs) { for (var args = [], i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - if (isObject(tag)) return parameterize(tag, args); - var hasAttrs = pairs != null && isObject(pairs) && !("tag" in pairs || "view" in pairs || "subtree" in pairs); - var attrs = hasAttrs ? pairs : {}; - var classAttrName = "class" in attrs ? "class" : "className"; - var cell = {tag: "div", attrs: {}}; - var match, classes = []; - if (!isString(tag)) throw new Error("selector in m(selector, attrs, children) should be a string"); - while (match = parser.exec(tag)) { - if (match[1] === "" && match[2]) cell.tag = match[2]; - else if (match[1] === "#") cell.attrs.id = match[2]; - else if (match[1] === ".") classes.push(match[2]); - else if (match[3][0] === "[") { - var pair = attrParser.exec(match[3]); - cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true); - } + args[i - 1] = arguments[i] } - var children = hasAttrs ? args.slice(1) : args; - if (children.length === 1 && isArray(children[0])) { - cell.children = children[0]; + if (isObject(tag)) return parameterize(tag, args) + + var hasAttrs = pairs != null && + isObject(pairs) && + !("tag" in pairs || "view" in pairs || "subtree" in pairs) + + var attrs = hasAttrs ? pairs : {} + var classAttrName = "class" in attrs ? "class" : "className" + var cell = {tag: "div", attrs: {}} + var classes = [] + + if (!isString(tag)) { + throw new Error( + "selector in m(selector, attrs, children) should be a string") } - else { - cell.children = children; + + var match = parser.exec(tag) + + while (match != null) { + if (match[1] === "" && match[2]) { + cell.tag = match[2] + } else if (match[1] === "#") { + cell.attrs.id = match[2] + } else if (match[1] === ".") { + classes.push(match[2]) + } else if (match[3][0] === "[") { + var pair = attrParser.exec(match[3]) + cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" : true) + } + + match = parser.exec(tag) + } + + var children = hasAttrs ? args.slice(1) : args + + if (children.length === 1 && isArray(children[0])) { + cell.children = children[0] + } else { + cell.children = children } for (var attrName in attrs) { if (attrs.hasOwnProperty(attrName)) { - if (attrName === classAttrName && attrs[attrName] != null && attrs[attrName] !== "") { - classes.push(attrs[attrName]); - cell.attrs[attrName] = ""; //create key in correct iteration order + if (attrName === classAttrName && + attrs[attrName] != null && + attrs[attrName] !== "") { + classes.push(attrs[attrName]) + // create key in correct iteration order + cell.attrs[attrName] = "" + } else { + cell.attrs[attrName] = attrs[attrName] } - else cell.attrs[attrName] = attrs[attrName]; } } - if (classes.length) cell.attrs[classAttrName] = classes.join(" "); + if (classes.length) cell.attrs[classAttrName] = classes.join(" ") - return cell; + return cell } + function forEach(list, f) { - for (var i = 0; i < list.length && !f(list[i], i++);) {} + for (var i = 0; i < list.length && !f(list[i], i++);) { + // do nothing + } } + function forKeys(list, f) { forEach(list, function (attrs, i) { - return (attrs = attrs && attrs.attrs) && attrs.key != null && f(attrs, i); - }); + attrs = attrs && attrs.attrs + return attrs && attrs.key != null && f(attrs, i) + }) } + // This function was causing deopts in Chrome. function dataToString(data) { - //data.toString() might throw or return null if data is the return value of Console.log in Firefox (behavior depends on version) + // data.toString() might throw or return null if data is the return + // value of Console.log in Firefox (behavior depends on version) try { - if (data == null || data.toString() == null) data = ""; + if (data == null || data.toString() == null) return "" } catch (e) { - data = ""; + return "" } - return data; + return data } + // This function was causing deopts in Chrome. function injectTextNode(parentElement, first, index, data) { try { - parentElement.insertBefore(first, parentElement.childNodes[index] || null); - first.nodeValue = data; + parentElement.insertBefore( + first, + parentElement.childNodes[index] || null) + first.nodeValue = data + } catch (e) { + // IE erroneously throws error when appending an empty text node + // after a null } - catch (e) {} //IE erroneously throws error when appending an empty text node after a null } - function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace, configs) { - //`build` is a recursive function that manages creation/diffing/removal of DOM elements based on comparison between `data` and `cached` - //the diff algorithm can be summarized as this: - //1 - compare `data` and `cached` - //2 - if they are different, copy `data` to `cached` and update the DOM based on what the difference is - //3 - recursively apply this algorithm for every array and for the children of every virtual element - //the `cached` data structure is essentially the same as the previous redraw's `data` data structure, with a few additions: - //- `cached` always has a property called `nodes`, which is a list of DOM elements that correspond to the data represented by the respective virtual element - //- in order to support attaching `nodes` as a property of `cached`, `cached` is *always* a non-primitive object, i.e. if the data was a string, then cached is a String instance. If data was `null` or `undefined`, cached is `new String("")` - //- `cached also has a `configContext` property, which is the state storage object exposed by config(element, isInitialized, context) - //- when `cached` is an Object, it represents a virtual element; when it's an Array, it represents a list of elements; when it's a String, Number or Boolean, it represents a text node - - //`parentElement` is a DOM element used for W3C DOM API calls - //`parentTag` is only used for handling a corner case for textarea values - //`parentCache` is used to remove nodes in some multi-node cases - //`parentIndex` and `index` are used to figure out the offset of nodes. They're artifacts from before arrays started being flattened and are likely refactorable - //`data` and `cached` are, respectively, the new and old nodes being diffed - //`shouldReattach` is a flag indicating whether a parent node was recreated (if so, and if this node is reused, then this node must reattach itself to the new parent) - //`editable` is a flag that indicates whether an ancestor is contenteditable - //`namespace` indicates the closest HTML namespace as it cascades down from an ancestor - //`configs` is a list of config functions to run after the topmost `build` call finishes running - - //there's logic that relies on the assumption that null and undefined data are equivalent to empty strings - //- this prevents lifecycle surprises from procedural helpers that mix implicit and explicit return statements (e.g. function foo() {if (cond) return m("div")} - //- it simplifies diffing code - data = dataToString(data); - if (data.subtree === "retain") return cached; - var cachedType = type.call(cached), dataType = type.call(data); - if (cached == null || cachedType !== dataType) { - if (cached != null) { - if (parentCache && parentCache.nodes) { - var offset = index - parentIndex; - var end = offset + (isArray(data) ? data : cached.nodes).length; - clear(parentCache.nodes.slice(offset, end), parentCache.slice(offset, end)); - } - else if (cached.nodes) clear(cached.nodes, cached); + function flatten(list) { + // recursively flatten array + for (var i = 0; i < list.length; i++) { + if (isArray(list[i])) { + list = list.concat.apply([], list) + // check current index again and flatten until there are no + // more nested arrays at that index + i-- } - cached = new data.constructor; - if (cached.tag) cached = {}; //if constructor creates a virtual dom element, use a blank object as the base cached node instead of copying the virtual el (#277) - cached.nodes = []; } + return list + } + + function insertNode(parentElement, node, index) { + parentElement.insertBefore( + node, + parentElement.childNodes[index] || null) + } + + var DELETION = 1 + var INSERTION = 2 + var MOVE = 3 + + function handleKeysDiffer(data, existing, cached, parentElement) { + forKeys(data, function (attrs, i) { + var key = attrs.key + if (existing[key]) { + existing[key] = { + action: MOVE, + index: i, + from: existing[key].index, + element: cached.nodes[existing[key].index] || + $document.createElement("div") + } + } else { + existing[key] = {action: INSERTION, index: i} + } + }) + var actions = [] + for (var prop in existing) actions.push(existing[prop]) + var changes = actions.sort(sortChanges) + var newCached = new Array(cached.length) + newCached.nodes = cached.nodes.slice() + + forEach(changes, function (change) { + var index = change.index + if (change.action === DELETION) { + clear(cached[index].nodes, cached[index]) + newCached.splice(index, 1) + } + if (change.action === INSERTION) { + var dummy = $document.createElement("div") + dummy.key = data[index].attrs.key + insertNode(parentElement, dummy, index) + newCached.splice(index, 0, { + attrs: {key: data[index].attrs.key}, + nodes: [dummy] + }) + newCached.nodes[index] = dummy + } + + if (change.action === MOVE) { + var changeElement = change.element + var maybeChanged = parentElement.childNodes[index] + if (maybeChanged !== changeElement && changeElement !== null) { + parentElement.insertBefore(changeElement, + maybeChanged || null) + } + newCached[index] = cached[change.from] + newCached.nodes[index] = changeElement + } + }) + + return newCached + } + + function diffKeys(data, cached, existing, parentElement) { + var keysDiffer = data.length !== cached.length + if (!keysDiffer) { + forKeys(data, function (attrs, i) { + var cachedCell = cached[i] + keysDiffer = cachedCell && + cachedCell.attrs && + cachedCell.attrs.key !== attrs.key + return keysDiffer + }) + } + + if (keysDiffer) { + return handleKeysDiffer(data, existing, cached, parentElement) + } else { + return cached + } + } + + function diffArray(data, cached, nodes) { + // diff the array itself + + // update the list of DOM nodes by collecting the nodes from + // each item + forEach(data, function (_, i) { + if (cached[i] != null) { + nodes.push.apply(nodes, cached[i].nodes) + } + }) + // remove items from the end of the array if the new array is + // shorter than the old one. if errors ever happen here, the + // issue is most likely a bug in the construction of the + // `cached` data structure somewhere earlier in the program + forEach(cached.nodes, function (node, i) { + if (node.parentNode != null && nodes.indexOf(node) < 0) { + clear([node], [cached[i]]) + } + }) + if (data.length < cached.length) cached.length = data.length + cached.nodes = nodes + } + + function buildArrayKeys(data) { + var guid = 0 + forKeys(data, function () { + forEach(data, function (attrs) { + if ((attrs = attrs && attrs.attrs) && attrs.key == null) { + attrs.key = "__mithril__" + guid++ + } + }) + return 1 + }) + } + + function maybeRecreateObject(data, cached, dataAttrKeys) { + // if an element is different enough from the one in cache, recreate it + if (data.tag !== cached.tag || + dataAttrKeys.sort().join() !== + Object.keys(cached.attrs).sort().join() || + data.attrs.id !== cached.attrs.id || + data.attrs.key !== cached.attrs.key || + (m.redraw.strategy() === "all" && (!cached.configContext || + cached.configContext.retain !== true)) || + (m.redraw.strategy() === "diff" && cached.configContext && + cached.configContext.retain === false)) { + if (cached.nodes.length) clear(cached.nodes) + if (cached.configContext && + isFunction(cached.configContext.onunload)) { + cached.configContext.onunload() + } + if (cached.controllers) { + forEach(cached.controllers, function (controller) { + if (controller.unload) { + controller.onunload({preventDefault: noop}) + } + }) + } + } + } + + function getObjectNamespace(data, namespace) { + if (data.attrs.xmlns) { + return data.attrs.xmlns + } else if (data.tag === "svg") { + return "http://www.w3.org/2000/svg" + } else if (data.tag === "math") { + return "http://www.w3.org/1998/Math/MathML" + } else { + return namespace + } + } + + function unloadCachedControllers(cached, views, controllers) { + if (controllers.length) { + cached.views = views + cached.controllers = controllers + forEach(controllers, function (controller) { + if (controller.onunload && controller.onunload.$old) { + controller.onunload = controller.onunload.$old + } + if (pendingRequests && controller.onunload) { + var onunload = controller.onunload + controller.onunload = noop + controller.onunload.$old = onunload + } + }) + } + } + + function scheduleConfigsToBeCalled(configs, data, node, isNew, cached) { + // schedule configs to be called. They are called after `build` + // finishes running + if (isFunction(data.attrs.config)) { + var context = cached.configContext = cached.configContext || {} + + // bind + configs.push(function() { + return data.attrs.config.call(data, node, !isNew, context, + cached) + }) + } + } + + function buildUpdatedNode( + cached, + data, + editable, + hasKeys, + namespace, + views, + configs, + controllers) { + var node = cached.nodes[0] + if (hasKeys) { + setAttributes( + node, + data.tag, + data.attrs, + cached.attrs, + namespace) + } + + cached.children = build( + node, + data.tag, + undefined, + undefined, + data.children, + cached.children, + false, + 0, + data.attrs.contenteditable ? node : editable, + namespace, + configs) + + cached.nodes.intact = true + if (controllers.length) { + cached.views = views + cached.controllers = controllers + } + + return node + } + + function handleNonexistentNodes(data, parentElement, index) { + var nodes + if (data.$trusted) { + nodes = injectHTML(parentElement, index, data) + } else { + nodes = [$document.createTextNode(data)] + if (!parentElement.nodeName.match(voidElements)) { + insertNode(parentElement, nodes[0], index) + } + } + + var cached + if (typeof data === "string" || + typeof data === "number" || + typeof data === "boolean") { + cached = new data.constructor(data) + } else { + cached = data + } + cached.nodes = nodes + return cached + } + + function reattachNodes( + data, + cached, + parentElement, + editable, + index, + parentTag) { + var nodes = cached.nodes + if (!editable || editable !== $document.activeElement) { + if (data.$trusted) { + clear(nodes, cached) + nodes = injectHTML(parentElement, index, data) + } else { + // corner case: replacing the nodeValue of a text node + // that is a child of a textarea/contenteditable doesn't + // work. we need to update the value property of the + // parent textarea or the innerHTML of the + // contenteditable element instead + if (parentTag === "textarea") { + parentElement.value = data + } else if (editable) { + editable.innerHTML = data + } else { + // was a trusted string + if (nodes[0].nodeType === 1 || nodes.length > 1) { + clear(cached.nodes, cached) + nodes = [$document.createTextNode(data)] + } + injectTextNode(parentElement, nodes[0], index, data) + } + } + } + cached = new data.constructor(data) + cached.nodes = nodes + return cached + } + + function handleText( + cached, + data, + index, + parentElement, + shouldReattach, + editable, + parentTag) { + // handle text nodes + if (cached.nodes.length === 0) { + return handleNonexistentNodes(data, parentElement, index) + } else if (cached.valueOf() !== data.valueOf() || + shouldReattach === true) { + return reattachNodes( + data, + cached, + parentElement, + editable, + index, + parentTag) + } else { + cached.nodes.intact = true + return cached + } + } + + function getSubArrayCount(item) { + if (item.$trusted) { + // fix offset of next element if item was a trusted + // string w/ more than one html element + // the first clause in the regexp matches elements + // the second clause (after the pipe) matches text nodes + var match = item.match(/<[^\/]|\>\s*[^<]/g) + if (match != null) { + return match.length + } + } else if (isArray(item)) { + return item.length + } + return 1 + } + + function buildArray( + data, + cached, + parentElement, + index, + parentTag, + shouldReattach, + editable, + namespace, + configs) { + data = flatten(data) + var nodes = [] + var intact = cached.length === data.length + var subArrayCount = 0 + + // keys algorithm: sort elements without recreating them if keys are + // present + // 1) create a map of all existing keys, and mark all for deletion + // 2) add new keys to map and mark them for addition + // 3) if key exists in new list, change action from deletion to a + // move + // 4) for each key, handle its corresponding action as marked in + // previous steps + var existing = {} + var shouldMaintainIdentities = false + forKeys(cached, function (attrs, i) { + shouldMaintainIdentities = true + existing[cached[i].attrs.key] = {action: DELETION, index: i} + }) + + buildArrayKeys(data) + + if (shouldMaintainIdentities) { + cached = diffKeys(data, cached, existing, parentElement) + } + // end key algorithm + + var cacheCount = 0 + for (var i = 0, len = data.length; i < len; i++) { + // diff each item in the array + var item = build( + parentElement, + parentTag, + cached, + index, + data[i], + cached[cacheCount], + shouldReattach, + index + subArrayCount || subArrayCount, + editable, + namespace, + configs) + + if (item !== undefined) { + intact = intact && item.nodes.intact + subArrayCount += getSubArrayCount(item) + cached[cacheCount++] = item + } + } + + if (!intact) diffArray(data, cached, nodes) + + return cached + } + + function makeCache(data, cached, index, parentIndex, parentCache) { + if (cached != null) { + if (type.call(cached) === type.call(data)) return cached + + if (parentCache && parentCache.nodes) { + var offset = index - parentIndex + var end = offset + + (isArray(data) ? data : cached.nodes).length + clear( + parentCache.nodes.slice(offset, end), + parentCache.slice(offset, end)) + } else if (cached.nodes) { + clear(cached.nodes, cached) + } + } + + cached = new data.constructor() + // if constructor creates a virtual dom element, use a blank object + // as the base cached node instead of copying the virtual el (#277) + if (cached.tag) cached = {} + + cached.nodes = [] + + return cached + } + + function constructNode(data, namespace) { + if (data.attrs.is) { + if (namespace === undefined) { + return $document.createElement(data.tag, data.attrs.is) + } else { + return $document.createElementNS(namespace, data.tag, + data.attrs.is) + } + } else { + if (namespace === undefined) { + return $document.createElement(data.tag) + } else { + return $document.createElementNS(namespace, data.tag) + } + } + } + + function constructAttrs(data, node, namespace, hasKeys) { + if (hasKeys) { + return setAttributes( + node, + data.tag, + data.attrs, + {}, + namespace) + } else { + return data.attrs + } + } + + function constructChildren( + data, + node, + cached, + editable, + namespace, + configs) { + if (data.children != null && data.children.length > 0) { + return build( + node, + data.tag, + undefined, + undefined, + data.children, + cached.children, + true, + 0, + data.attrs.contenteditable ? node : editable, + namespace, + configs) + } else { + return data.children + } + } + + function reconstructCached( + data, + cached, + attrs, + children, + node, + namespace, + views, + controllers) { + cached = { + tag: data.tag, + attrs: attrs, + children: children, + nodes: [node] + } + + unloadCachedControllers(cached, views, controllers) + + if (cached.children && !cached.children.nodes) { + cached.children.nodes = [] + } + // edge case: setting value on doesn't work before children exist, so set it again after children have been created - if (data.tag === "select" && "value" in data.attrs) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace); - parentElement.insertBefore(node, parentElement.childNodes[index] || null); - } - else { - node = cached.nodes[0]; - if (hasKeys) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace); - cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs); - cached.nodes.intact = true; - if (controllers.length) { - cached.views = views; - cached.controllers = controllers; - } - if (shouldReattach === true && node != null) parentElement.insertBefore(node, parentElement.childNodes[index] || null); - } - //schedule configs to be called. They are called after `build` finishes running - if (isFunction(data.attrs["config"])) { - var context = cached.configContext = cached.configContext || {}; - - // bind - var callback = function(data, args) { - return function() { - return data.attrs["config"].apply(data, args); - }; - }; - configs.push(callback(data, [node, !isNew, context, cached])); - } - } - else if (!isFunction(data)) { - //handle text nodes - var nodes; - if (cached.nodes.length === 0) { - if (data.$trusted) { - nodes = injectHTML(parentElement, index, data); - } - else { - nodes = [$document.createTextNode(data)]; - if (!parentElement.nodeName.match(voidElements)) parentElement.insertBefore(nodes[0], parentElement.childNodes[index] || null); - } - cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data; - cached.nodes = nodes; - } - else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { - nodes = cached.nodes; - if (!editable || editable !== $document.activeElement) { - if (data.$trusted) { - clear(nodes, cached); - nodes = injectHTML(parentElement, index, data); - } - else { - //corner case: replacing the nodeValue of a text node that is a child of a textarea/contenteditable doesn't work - //we need to update the value property of the parent textarea or the innerHTML of the contenteditable element instead - if (parentTag === "textarea") parentElement.value = data; - else if (editable) editable.innerHTML = data; - else { - if (nodes[0].nodeType === 1 || nodes.length > 1) { //was a trusted string - clear(cached.nodes, cached); - nodes = [$document.createTextNode(data)]; - } - injectTextNode(parentElement, nodes[0], index, data) - } - } - } - cached = new data.constructor(data); - cached.nodes = nodes; - } - else cached.nodes.intact = true; + return buildArray( + data, + cached, + parentElement, + index, + parentTag, + shouldReattach, + editable, + namespace, + configs) + } else if (data != null && isObject(data)) { + return buildObject( + data, + cached, + editable, + parentElement, + index, + shouldReattach, + namespace, + configs) + } else if (!isFunction(data)) { + return handleText( + cached, + data, + index, + parentElement, + shouldReattach, + editable, + parentTag) + } else { + return cached } - return cached; } - function sortChanges(a, b) { return a.action - b.action || a.index - b.index; } + function sortChanges(a, b) { + return a.action - b.action || a.index - b.index + } function setAttributes(node, tag, dataAttrs, cachedAttrs, namespace) { for (var attrName in dataAttrs) { - var dataAttr = dataAttrs[attrName]; - var cachedAttr = cachedAttrs[attrName]; + var dataAttr = dataAttrs[attrName] + var cachedAttr = cachedAttrs[attrName] + var rule if (!(attrName in cachedAttrs) || (cachedAttr !== dataAttr)) { - cachedAttrs[attrName] = dataAttr; + cachedAttrs[attrName] = dataAttr try { - //`config` isn't a real attributes, so ignore it - if (attrName === "config" || attrName == "key") continue; - //hook event handlers to the auto-redrawing system - else if (isFunction(dataAttr) && attrName.indexOf("on") === 0) { - node[attrName] = autoredraw(dataAttr, node); - } - //handle `style: {...}` - else if (attrName === "style" && dataAttr != null && isObject(dataAttr)) { - for (var rule in dataAttr) { - if (cachedAttr == null || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]; + if (attrName === "config" || attrName === "key") { + // `config` isn't a real attributes, so ignore it + } else if (isFunction(dataAttr) && + attrName.slice(0, 2) === "on") { + // hook event handlers to the auto-redrawing system + node[attrName] = autoredraw(dataAttr, node) + } else if (attrName === "style" && + dataAttr != null && + isObject(dataAttr)) { + // handle `style: {...}` + for (rule in dataAttr) { + if (cachedAttr == null || + cachedAttr[rule] !== dataAttr[rule]) { + node.style[rule] = dataAttr[rule] + } } - for (var rule in cachedAttr) { - if (!(rule in dataAttr)) node.style[rule] = ""; + for (rule in cachedAttr) { + if (!(rule in dataAttr)) node.style[rule] = "" } + } else if (namespace != null) { + // handle SVG + if (attrName === "href") { + node.setAttributeNS( + "http://www.w3.org/1999/xlink", + "href", + dataAttr) + } else if (attrName === "className") { + node.setAttribute("class", dataAttr) + } else { + node.setAttribute(attrName, dataAttr) + } + } else if (attrName in node && + !(attrName === "list" || + attrName === "style" || + attrName === "form" || + attrName === "type" || + attrName === "width" || + attrName === "height")) { + // handle cases that are properties (but ignore cases + // where we should use setAttribute instead) + // - list and form are typically used as strings, but + // are DOM element references in js + // - when using CSS selectors (e.g. `m("[style='']")`), + // style is used as a string, but it's an object in js + + // #348 don't set the value if not needed otherwise + // cursor placement breaks in Chrome + if (tag !== "input" || node[attrName] !== dataAttr) { + node[attrName] = dataAttr + } + } else { + node.setAttribute(attrName, dataAttr) } - //handle SVG - else if (namespace != null) { - if (attrName === "href") node.setAttributeNS("http://www.w3.org/1999/xlink", "href", dataAttr); - else if (attrName === "className") node.setAttribute("class", dataAttr); - else node.setAttribute(attrName, dataAttr); - } - //handle cases that are properties (but ignore cases where we should use setAttribute instead) - //- list and form are typically used as strings, but are DOM element references in js - //- when using CSS selectors (e.g. `m("[style='']")`), style is used as a string, but it's an object in js - else if (attrName in node && !(attrName === "list" || attrName === "style" || attrName === "form" || attrName === "type" || attrName === "width" || attrName === "height")) { - //#348 don't set the value if not needed otherwise cursor placement breaks in Chrome - if (tag !== "input" || node[attrName] !== dataAttr) node[attrName] = dataAttr; - } - else node.setAttribute(attrName, dataAttr); + } catch (e) { + // swallow IE's invalid argument errors to mimic HTML's + // fallback-to-doing-nothing-on-invalid-attributes behavior + if (e.message.indexOf("Invalid argument") < 0) throw e } - catch (e) { - //swallow IE's invalid argument errors to mimic HTML's fallback-to-doing-nothing-on-invalid-attributes behavior - if (e.message.indexOf("Invalid argument") < 0) throw e; - } - } - //#348 dataAttr may not be a string, so use loose comparison (double equal) instead of strict (triple equal) - else if (attrName === "value" && tag === "input" && node.value != dataAttr) { - node.value = dataAttr; + } else if (attrName === "value" && + tag === "input" && + node.value !== dataAttr) { + // #348 dataAttr may not be a string, so use loose comparison + // (double equal) instead of strict (triple equal) + node.value = dataAttr } } - return cachedAttrs; + + return cachedAttrs } + function clear(nodes, cached) { for (var i = nodes.length - 1; i > -1; i--) { if (nodes[i] && nodes[i].parentNode) { - try { nodes[i].parentNode.removeChild(nodes[i]); } - catch (e) {} //ignore if this fails due to order of events (see http://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node) - cached = [].concat(cached); - if (cached[i]) unload(cached[i]); + try { + nodes[i].parentNode.removeChild(nodes[i]) + } catch (e) { + /* eslint-disable max-len */ + // ignore if this fails due to order of events (see + // http://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node) + /* eslint-enable max-len */ + } + cached = [].concat(cached) + if (cached[i]) unload(cached[i]) } } - if (nodes.length != 0) nodes.length = 0; + nodes.length = 0 } + function unload(cached) { if (cached.configContext && isFunction(cached.configContext.onunload)) { - cached.configContext.onunload(); - cached.configContext.onunload = null; + cached.configContext.onunload() + cached.configContext.onunload = null } if (cached.controllers) { - for (var i = 0, controller; controller = cached.controllers[i]; i++) { - if (isFunction(controller.onunload)) controller.onunload({preventDefault: noop}); - } + forEach(cached.controllers, function (controller) { + if (isFunction(controller.onunload)) { + controller.onunload({preventDefault: noop}) + } + }) } if (cached.children) { if (isArray(cached.children)) { - for (var i = 0, child; child = cached.children[i]; i++) unload(child); + forEach(cached.children, unload) + } else if (cached.children.tag) { + unload(cached.children) } - else if (cached.children.tag) unload(cached.children); } } - function injectHTML(parentElement, index, data) { - var nextSibling = parentElement.childNodes[index]; - if (nextSibling) { - var isElement = nextSibling.nodeType != 1; - var placeholder = $document.createElement("span"); - if (isElement) { - parentElement.insertBefore(placeholder, nextSibling || null); - placeholder.insertAdjacentHTML("beforebegin", data); - parentElement.removeChild(placeholder); - } - else nextSibling.insertAdjacentHTML("beforebegin", data); - } - else parentElement.insertAdjacentHTML("beforeend", data); - var nodes = []; - while (parentElement.childNodes[index] !== nextSibling) { - nodes.push(parentElement.childNodes[index]); - index++; - } - return nodes; - } - function autoredraw(callback, object) { - return function(e) { - e = e || event; - m.redraw.strategy("diff"); - m.startComputation(); - try { return callback.call(object, e); } - finally { - endFirstComputation(); - } - }; - } - var html; + function injectHTML(parentElement, index, data) { + var nextSibling = parentElement.childNodes[index] + if (nextSibling) { + var isElement = nextSibling.nodeType !== 1 + var placeholder = $document.createElement("span") + if (isElement) { + parentElement.insertBefore(placeholder, nextSibling || null) + placeholder.insertAdjacentHTML("beforebegin", data) + parentElement.removeChild(placeholder) + } else { + nextSibling.insertAdjacentHTML("beforebegin", data) + } + } else { + parentElement.insertAdjacentHTML("beforeend", data) + } + var nodes = [] + while (parentElement.childNodes[index] !== nextSibling) { + nodes.push(parentElement.childNodes[index]) + index++ + } + return nodes + } + + function autoredraw(callback, object) { + return function(e) { + e = e || event + m.redraw.strategy("diff") + m.startComputation() + try { + return callback.call(object, e) + } finally { + endFirstComputation() + } + } + } + + var html var documentNode = { appendChild: function(node) { - if (html === undefined) html = $document.createElement("html"); - if ($document.documentElement && $document.documentElement !== node) { - $document.replaceChild(node, $document.documentElement); + if (html === undefined) html = $document.createElement("html") + if ($document.documentElement && + $document.documentElement !== node) { + $document.replaceChild(node, $document.documentElement) + } else { + $document.appendChild(node) } - else $document.appendChild(node); - this.childNodes = $document.childNodes; + this.childNodes = $document.childNodes }, insertBefore: function(node) { - this.appendChild(node); + this.appendChild(node) }, childNodes: [] - }; - var nodeCache = [], cellCache = {}; + } + + var nodeCache = [] + var cellCache = {} + m.render = function(root, cell, forceRecreation) { - var configs = []; - if (!root) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined."); - var id = getCellCacheKey(root); - var isDocumentRoot = root === $document; - var node = isDocumentRoot || root === $document.documentElement ? documentNode : root; - if (isDocumentRoot && cell.tag != "html") cell = {tag: "html", attrs: {}, children: cell}; - if (cellCache[id] === undefined) clear(node.childNodes); - if (forceRecreation === true) reset(root); - cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined, configs); - for (var i = 0, len = configs.length; i < len; i++) configs[i](); - }; + var configs = [] + if (!root) { + throw new Error("Ensure the DOM element being passed to " + + "m.route/m.mount/m.render is not undefined.") + } + var id = getCellCacheKey(root) + var isDocumentRoot = root === $document + var node + if (isDocumentRoot || root === $document.documentElement) { + node = documentNode + } else { + node = root + } + if (isDocumentRoot && cell.tag !== "html") { + cell = {tag: "html", attrs: {}, children: cell} + } + if (cellCache[id] === undefined) clear(node.childNodes) + if (forceRecreation === true) reset(root) + + cellCache[id] = build( + node, + null, + undefined, + undefined, + cell, + cellCache[id], + false, + 0, + null, + undefined, + configs) + + forEach(configs, function (config) { + config() + }) + } + function getCellCacheKey(element) { - var index = nodeCache.indexOf(element); - return index < 0 ? nodeCache.push(element) - 1 : index; + var index = nodeCache.indexOf(element) + return index < 0 ? nodeCache.push(element) - 1 : index } m.trust = function(value) { - value = new String(value); - value.$trusted = true; - return value; - }; + /* eslint-disable no-new-wrappers */ + value = new String(value) + /* eslint-enable no-new-wrappers */ + value.$trusted = true + return value + } function gettersetter(store) { var prop = function() { - if (arguments.length) store = arguments[0]; - return store; - }; + if (arguments.length) store = arguments[0] + return store + } prop.toJSON = function() { - return store; - }; + return store + } - return prop; + return prop } m.prop = function (store) { - //note: using non-strict equality check here because we're checking if store is null OR undefined - if ((store != null && isObject(store) || isFunction(store)) && isFunction(store.then)) { - return propify(store); + // note: using non-strict equality check here because we're checking if + // store is null OR undefined + if ((store != null && isObject(store) || isFunction(store)) && + isFunction(store.then)) { + return propify(store) } - return gettersetter(store); - }; + return gettersetter(store) + } - var roots = [], components = [], controllers = [], lastRedrawId = null, lastRedrawCallTime = 0, computePreRedrawHook = null, computePostRedrawHook = null, topComponent, unloaders = []; - var FRAME_BUDGET = 16; //60 frames per second = 1 call per 16 ms function parameterize(component, args) { var controller = function() { - return (component.controller || noop).apply(this, args) || this; - }; + return (component.controller || noop).apply(this, args) || this + } var view = function(ctrl) { - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - return component.view.apply(component, args ? [ctrl].concat(args) : [ctrl]); - }; - view.$original = component.view; - var output = {controller: controller, view: view}; - if (args[0] && args[0].key != null) output.attrs = {key: args[0].key}; - return output; + for (var i = 1; i < arguments.length; i++) { + args.push(arguments[i]) + } + return component.view.apply(component, [ctrl].concat(args)) + } + view.$original = component.view + var output = {controller: controller, view: view} + if (args[0] && args[0].key != null) output.attrs = {key: args[0].key} + return output } m.component = function(component) { - for (var args = [], i = 1; i < arguments.length; i++) args[i - 1] = arguments[i]; - return parameterize(component, args); - }; + for (var args = [], i = 1; i < arguments.length; i++) { + args.push(arguments[i]) + } + return parameterize(component, args) + } m.mount = m.module = function(root, component) { - if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it."); - var index = roots.indexOf(root); - if (index < 0) index = roots.length; + if (!root) { + throw new Error("Please ensure the DOM element exists before " + + "rendering a template into it.") + } + var index = roots.indexOf(root) + if (index < 0) index = roots.length - var isPrevented = false; - var event = {preventDefault: function() { - isPrevented = true; - computePreRedrawHook = computePostRedrawHook = null; - }}; - for (var i = 0, unloader; unloader = unloaders[i]; i++) { - unloader.handler.call(unloader.controller, event); - unloader.controller.onunload = null; + var isPrevented = false + var event = { + preventDefault: function() { + isPrevented = true + computePreRedrawHook = computePostRedrawHook = null + } } + + forEach(unloaders, function (unloader) { + unloader.handler.call(unloader.controller, event) + unloader.controller.onunload = null + }) + if (isPrevented) { - for (var i = 0, unloader; unloader = unloaders[i]; i++) unloader.controller.onunload = unloader.handler; + forEach(unloaders, function (unloader) { + unloader.controller.onunload = unloader.handler + }) + } else { + unloaders = [] } - else unloaders = []; if (controllers[index] && isFunction(controllers[index].onunload)) { - controllers[index].onunload(event); + controllers[index].onunload(event) } if (!isPrevented) { - m.redraw.strategy("all"); - m.startComputation(); - roots[index] = root; - if (arguments.length > 2) component = subcomponent(component, [].slice.call(arguments, 2)); - var currentComponent = topComponent = component = component || {controller: noop}; - var constructor = component.controller || noop; - var controller = new constructor; - //controllers may call m.mount recursively (via m.route redirects, for example) - //this conditional ensures only the last recursive m.mount call is applied + m.redraw.strategy("all") + m.startComputation() + roots[index] = root + var currentComponent + if (component) { + currentComponent = topComponent = component + } else { + currentComponent = topComponent = component = {controller: noop} + } + var constructor = component.controller || noop + var controller = new constructor() + // controllers may call m.mount recursively (via m.route redirects, + // for example). this conditional ensures only the last recursive + // m.mount call is applied if (currentComponent === topComponent) { - controllers[index] = controller; - components[index] = component; + controllers[index] = controller + components[index] = component } - endFirstComputation(); - return controllers[index]; + endFirstComputation() + return controllers[index] } - }; - var redrawing = false, forcing = false; + } m.redraw = function(force) { - if (redrawing) return; - redrawing = true; - if (force) forcing = true; + if (redrawing) return + redrawing = true + if (force) forcing = true try { - //lastRedrawId is a positive number if a second redraw is requested before the next animation frame - //lastRedrawID is null if it's the first redraw and not an event handler + // lastRedrawId is a positive number if a second redraw is requested + // before the next animation frame + // lastRedrawID is null if it's the first redraw and not an event + // handler if (lastRedrawId && !force) { - //when setTimeout: only reschedule redraw if time between now and previous redraw is bigger than a frame, otherwise keep currently scheduled timeout - //when rAF: always reschedule redraw - if ($requestAnimationFrame === window.requestAnimationFrame || new Date - lastRedrawCallTime > FRAME_BUDGET) { - if (lastRedrawId > 0) $cancelAnimationFrame(lastRedrawId); - lastRedrawId = $requestAnimationFrame(redraw, FRAME_BUDGET); + // when setTimeout: only reschedule redraw if time between now + // and previous redraw is bigger than a frame, otherwise keep + // currently scheduled timeout + // when rAF: always reschedule redraw + if ($requestAnimationFrame === window.requestAnimationFrame || + new Date() - lastRedrawCallTime > FRAME_BUDGET) { + if (lastRedrawId > 0) $cancelAnimationFrame(lastRedrawId) + lastRedrawId = $requestAnimationFrame(redraw, FRAME_BUDGET) } + } else { + redraw() + lastRedrawId = $requestAnimationFrame(function() { + lastRedrawId = null + }, FRAME_BUDGET) } - else { - redraw(); - lastRedrawId = $requestAnimationFrame(function() { lastRedrawId = null; }, FRAME_BUDGET); - } + } finally { + redrawing = forcing = false } - finally { - redrawing = forcing = false; - } - }; - m.redraw.strategy = m.prop(); + } + m.redraw.strategy = m.prop() function redraw() { if (computePreRedrawHook) { - computePreRedrawHook(); - computePreRedrawHook = null; + computePreRedrawHook() + computePreRedrawHook = null } - for (var i = 0, root; root = roots[i]; i++) { + forEach(roots, function (root, i) { + var component = components[i] if (controllers[i]) { - var args = components[i].controller && components[i].controller.$$args ? [controllers[i]].concat(components[i].controller.$$args) : [controllers[i]]; - m.render(root, components[i].view ? components[i].view(controllers[i], args) : ""); + var args + if (component.controller && component.controller.$$args) { + args = [controllers[i]].concat(component.controller.$$args) + } else { + args = [controllers[i]] + } + var view + if (component.view) { + view = component.view(controllers[i], args) + } else { + view = "" + } + m.render(root, view) } - } - //after rendering within a routed context, we need to scroll back to the top, and fetch the document title for history.pushState + }) + // after rendering within a routed context, we need to scroll back to + // the top, and fetch the document title for history.pushState if (computePostRedrawHook) { - computePostRedrawHook(); - computePostRedrawHook = null; + computePostRedrawHook() + computePostRedrawHook = null } - lastRedrawId = null; - lastRedrawCallTime = new Date; - m.redraw.strategy("diff"); + lastRedrawId = null + lastRedrawCallTime = new Date() + m.redraw.strategy("diff") } - var pendingRequests = 0; - m.startComputation = function() { pendingRequests++; }; + m.startComputation = function() { pendingRequests++ } m.endComputation = function() { - pendingRequests = Math.max(pendingRequests - 1, 0); - if (pendingRequests === 0) m.redraw(); - }; - var endFirstComputation = function() { - if (m.redraw.strategy() == "none") { - pendingRequests--; - m.redraw.strategy("diff"); + if (pendingRequests > 1) { + pendingRequests-- + } else { + pendingRequests = 0 + m.redraw() } - else m.endComputation(); - }; + } + + function endFirstComputation() { + if (m.redraw.strategy() === "none") { + pendingRequests-- + m.redraw.strategy("diff") + } else { + m.endComputation() + } + } m.withAttr = function(prop, withAttrCallback) { return function(e) { - e = e || event; - var currentTarget = e.currentTarget || this; - withAttrCallback(prop in currentTarget ? currentTarget[prop] : currentTarget.getAttribute(prop)); - }; - }; + e = e || event + var currentTarget = e.currentTarget || this + var arg + if (prop in currentTarget) { + arg = currentTarget[prop] + } else { + arg = currentTarget.getAttribute(prop) + } + withAttrCallback(arg) + } + } - //routing - var modes = {pathname: "", hash: "#", search: "?"}; - var redirect = noop, routeParams, currentRoute, isDefaultRoute = false; + // routing + var modes = {pathname: "", hash: "#", search: "?"} + var redirect = noop + var isDefaultRoute = false + var routeParams, currentRoute m.route = function(root, arg1, arg2, vdom) { - //m.route() - if (arguments.length === 0) return currentRoute; - //m.route(el, defaultRoute, routes) - else if (arguments.length === 3 && isString(arg1)) { + // m.route() + if (arguments.length === 0) { + return currentRoute + } else if (arguments.length === 3 && isString(arg1)) { + // m.route(el, defaultRoute, routes) redirect = function(source) { - var path = currentRoute = normalizeRoute(source); + var path = currentRoute = normalizeRoute(source) if (!routeByValue(root, arg2, path)) { - if (isDefaultRoute) throw new Error("Ensure the default route matches one of the routes defined in m.route"); - isDefaultRoute = true; - m.route(arg1, true); - isDefaultRoute = false; + if (isDefaultRoute) { + throw new Error("Ensure the default route matches " + + "one of the routes defined in m.route") + } + isDefaultRoute = true + m.route(arg1, true) + isDefaultRoute = false } - }; - var listener = m.route.mode === "hash" ? "onhashchange" : "onpopstate"; - window[listener] = function() { - var path = $location[m.route.mode]; - if (m.route.mode === "pathname") path += $location.search; - if (currentRoute != normalizeRoute(path)) { - redirect(path); - } - }; - computePreRedrawHook = setScroll; - window[listener](); - } - //config: m.route - else if (root.addEventListener || root.attachEvent) { - root.href = (m.route.mode !== 'pathname' ? $location.pathname : '') + modes[m.route.mode] + vdom.attrs.href; - if (root.addEventListener) { - root.removeEventListener("click", routeUnobtrusive); - root.addEventListener("click", routeUnobtrusive); } - else { - root.detachEvent("onclick", routeUnobtrusive); - root.attachEvent("onclick", routeUnobtrusive); + var listener + if (m.route.mode === "hash") { + listener = "onhashchange" + } else { + listener = "onpopstate" } - } - //m.route(route, params, shouldReplaceHistoryEntry) - else if (isString(root)) { - var oldRoute = currentRoute; - currentRoute = root; - arg1 || {}; - var queryIndex = currentRoute.indexOf("?"); - var params = queryIndex > -1 ? parseQueryString(currentRoute.slice(queryIndex + 1)) : {}; - for (var i in arg1) params[i] = arg1[i]; - var querystring = buildQueryString(params); - var currentPath = queryIndex > -1 ? currentRoute.slice(0, queryIndex) : currentRoute; - if (querystring) currentRoute = currentPath + (currentPath.indexOf("?") === -1 ? "?" : "&") + querystring; - var shouldReplaceHistoryEntry = (arguments.length === 3 ? arg2 : arg1) === true || oldRoute === root; + window[listener] = function() { + var path = $location[m.route.mode] + if (m.route.mode === "pathname") path += $location.search + if (currentRoute !== normalizeRoute(path)) { + redirect(path) + } + } + + computePreRedrawHook = setScroll + window[listener]() + } else if (root.addEventListener || root.attachEvent) { + // config: m.route + var pathname = m.route.mode !== "pathname" ? $location.pathname : "" + root.href = pathname + modes[m.route.mode] + vdom.attrs.href + if (root.addEventListener) { + root.removeEventListener("click", routeUnobtrusive) + root.addEventListener("click", routeUnobtrusive) + } else { + root.detachEvent("onclick", routeUnobtrusive) + root.attachEvent("onclick", routeUnobtrusive) + } + } else if (isString(root)) { + // m.route(route, params, shouldReplaceHistoryEntry) + var oldRoute = currentRoute + currentRoute = root + arg1 = arg1 || {} + var queryIndex = currentRoute.indexOf("?") + var params + if (queryIndex > -1) { + params = parseQueryString(currentRoute.slice(queryIndex + 1)) + } else { + params = {} + } + for (var i in arg1) params[i] = arg1[i] + var querystring = buildQueryString(params) + var currentPath + + if (queryIndex > -1) { + currentPath = currentRoute.slice(0, queryIndex) + } else { + currentPath = currentRoute + } + + var separator = currentPath.indexOf("?") === -1 ? "?" : "&" + + if (querystring) { + currentRoute = currentPath + separator + querystring + } + + var shouldReplaceHistoryEntry + if (arguments.length === 3) { + shouldReplaceHistoryEntry = arg2 + } else { + shouldReplaceHistoryEntry = arg1 + } + + shouldReplaceHistoryEntry = shouldReplaceHistoryEntry === true || + oldRoute === root if (window.history.pushState) { - computePreRedrawHook = setScroll; + computePreRedrawHook = setScroll computePostRedrawHook = function() { - window.history[shouldReplaceHistoryEntry ? "replaceState" : "pushState"](null, $document.title, modes[m.route.mode] + currentRoute); - }; - redirect(modes[m.route.mode] + currentRoute); - } - else { - $location[m.route.mode] = currentRoute; - redirect(modes[m.route.mode] + currentRoute); + var listener + if (shouldReplaceHistoryEntry) { + listener = "replaceState" + } else { + listener = "pushState" + } + window.history[listener]( + null, + $document.title, + modes[m.route.mode] + currentRoute) + } + redirect(modes[m.route.mode] + currentRoute) + } else { + $location[m.route.mode] = currentRoute + redirect(modes[m.route.mode] + currentRoute) } } - }; + } m.route.param = function(key) { - if (!routeParams) throw new Error("You must call m.route(element, defaultRoute, routes) before calling m.route.param()"); - return routeParams[key]; - }; - m.route.mode = "search"; + if (!routeParams) { + throw new Error("You must call m.route(element, defaultRoute, " + + "routes) before calling m.route.param()") + } + return routeParams[key] + } + m.route.mode = "search" function normalizeRoute(route) { - return route.slice(modes[m.route.mode].length); + return route.slice(modes[m.route.mode].length) } function routeByValue(root, router, path) { - routeParams = {}; + routeParams = {} - var queryStart = path.indexOf("?"); + var queryStart = path.indexOf("?") if (queryStart !== -1) { - routeParams = parseQueryString(path.substr(queryStart + 1, path.length)); - path = path.substr(0, queryStart); + routeParams = parseQueryString( + path.substr(queryStart + 1, path.length)) + path = path.substr(0, queryStart) } // Get all routes and check if there's // an exact match for the current path - var keys = Object.keys(router); - var index = keys.indexOf(path); + var keys = Object.keys(router) + var index = keys.indexOf(path) if(index !== -1){ - m.mount(root, router[keys [index]]); - return true; + m.mount(root, router[keys [index]]) + return true } for (var route in router) { if (route === path) { - m.mount(root, router[route]); - return true; + m.mount(root, router[route]) + return true } - var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$"); + var matcher = new RegExp("^" + route + .replace(/:[^\/]+?\.{3}/g, "(.*?)") + .replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$") if (matcher.test(path)) { + /* eslint-disable no-loop-func */ path.replace(matcher, function() { - var keys = route.match(/:[^\/]+/g) || []; - var values = [].slice.call(arguments, 1, -2); - for (var i = 0, len = keys.length; i < len; i++) routeParams[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i]); - m.mount(root, router[route]); - }); - return true; + var keys = route.match(/:[^\/]+/g) || [] + var values = [].slice.call(arguments, 1, -2) + forEach(keys, function (key, i) { + routeParams[key.replace(/:|\./g, "")] = + decodeURIComponent(values[i]) + }) + m.mount(root, router[route]) + }) + /* eslint-enable no-loop-func */ + return true } } } function routeUnobtrusive(e) { - e = e || event; - if (e.ctrlKey || e.metaKey || e.which === 2) return; - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - var currentTarget = e.currentTarget || e.srcElement; - var args = m.route.mode === "pathname" && currentTarget.search ? parseQueryString(currentTarget.search.slice(1)) : {}; - while (currentTarget && currentTarget.nodeName.toUpperCase() != "A") currentTarget = currentTarget.parentNode; - m.route(currentTarget[m.route.mode].slice(modes[m.route.mode].length), args); + e = e || event + + if (e.ctrlKey || e.metaKey || e.which === 2) return + + if (e.preventDefault) e.preventDefault() + else e.returnValue = false + + var currentTarget = e.currentTarget || e.srcElement + var hasQuery = m.route.mode === "pathname" && currentTarget.search + var args + + if (hasQuery) { + args = parseQueryString(currentTarget.search.slice(1)) + } else { + args = {} + } + + while (currentTarget && currentTarget.nodeName.toUpperCase() !== "A") { + currentTarget = currentTarget.parentNode + } + + var target = currentTarget[m.route.mode] + .slice(modes[m.route.mode].length) + + m.route(target, args) } function setScroll() { - if (m.route.mode != "hash" && $location.hash) $location.hash = $location.hash; - else window.scrollTo(0, 0); + if (m.route.mode !== "hash" && $location.hash) { + $location.hash = $location.hash + } else { + window.scrollTo(0, 0) + } } function buildQueryString(object, prefix) { - var duplicates = {}; - var str = []; + var duplicates = {} + var str = [] for (var prop in object) { - var key = prefix ? prefix + "[" + prop + "]" : prop; - var value = object[prop]; - var valueType = type.call(value); - var pair = (value === null) ? encodeURIComponent(key) : - isObject(value) ? buildQueryString(value, key) : - isArray(value) ? value.reduce(function(memo, item) { - if (!duplicates[key]) duplicates[key] = {}; + var key = prefix ? prefix + "[" + prop + "]" : prop + var value = object[prop] + + if (value === null) { + str.push(encodeURIComponent(key)) + } else if (isObject(value)) { + str.push(buildQueryString(value, key)) + } else if (isArray(value)) { + var keys = [] + /* eslint-disable no-loop-func */ + forEach(value, function (item) { + if (!duplicates[key]) duplicates[key] = {} if (!duplicates[key][item]) { - duplicates[key][item] = true; - return memo.concat(encodeURIComponent(key) + "=" + encodeURIComponent(item)); + duplicates[key][item] = true + keys.push(encodeURIComponent(key) + "=" + + encodeURIComponent(item)) } - return memo; - }, []).join("&") : - encodeURIComponent(key) + "=" + encodeURIComponent(value); - if (value !== undefined) str.push(pair); + }) + /* eslint-enable no-loop-func */ + str.push(keys.join("&")) + } else if (value !== undefined) { + str.push(encodeURIComponent(key) + "=" + + encodeURIComponent(value)) + } } - return str.join("&"); + return str.join("&") } function parseQueryString(str) { - if (str.charAt(0) === "?") str = str.substring(1); + if (str.charAt(0) === "?") str = str.substring(1) - var pairs = str.split("&"), params = {}; - for (var i = 0, len = pairs.length; i < len; i++) { - var pair = pairs[i].split("="); - var key = decodeURIComponent(pair[0]); - var value = pair.length == 2 ? decodeURIComponent(pair[1]) : null; + var pairs = str.split("&") + var params = {} + + forEach(pairs, function (string) { + var pair = string.split("=") + var key = decodeURIComponent(pair[0]) + var value = pair.length === 2 ? decodeURIComponent(pair[1]) : null if (params[key] != null) { - if (!isArray(params[key])) params[key] = [params[key]]; - params[key].push(value); + if (!isArray(params[key])) params[key] = [params[key]] + params[key].push(value) + } else { + params[key] = value } - else params[key] = value; - } - return params; + }) + + return params } - m.route.buildQueryString = buildQueryString; - m.route.parseQueryString = parseQueryString; + m.route.buildQueryString = buildQueryString + m.route.parseQueryString = parseQueryString function reset(root) { - var cacheKey = getCellCacheKey(root); - clear(root.childNodes, cellCache[cacheKey]); - cellCache[cacheKey] = undefined; + var cacheKey = getCellCacheKey(root) + clear(root.childNodes, cellCache[cacheKey]) + cellCache[cacheKey] = undefined } m.deferred = function () { - var deferred = new Deferred(); - deferred.promise = propify(deferred.promise); - return deferred; - }; - function propify(promise, initialValue) { - var prop = m.prop(initialValue); - promise.then(prop); - prop.then = function(resolve, reject) { - return propify(promise.then(resolve, reject), initialValue); - }; - prop["catch"] = prop.then.bind(null, null); - return prop; + var deferred = new Deferred() + deferred.promise = propify(deferred.promise) + return deferred } - //Promiz.mithril.js | Zolmeister | MIT - //a modified version of Promiz.js, which does not conform to Promises/A+ for two reasons: - //1) `then` callbacks are called synchronously (because setTimeout is too slow, and the setImmediate polyfill is too big - //2) throwing subclasses of Error cause the error to be bubbled up instead of triggering rejection (because the spec does not account for the important use case of default browser error handling, i.e. message w/ line number) - function Deferred(successCallback, failureCallback) { - var RESOLVING = 1, REJECTING = 2, RESOLVED = 3, REJECTED = 4; - var self = this, state = 0, promiseValue = 0, next = []; + function propify(promise, initialValue) { + var prop = m.prop(initialValue) - self["promise"] = {}; + promise.then(prop) - self["resolve"] = function(value) { - if (!state) { - promiseValue = value; - state = RESOLVING; - - fire(); - } - return this; - }; - - self["reject"] = function(value) { - if (!state) { - promiseValue = value; - state = REJECTING; - - fire(); - } - return this; - }; - - self.promise["then"] = function(successCallback, failureCallback) { - var deferred = new Deferred(successCallback, failureCallback); - if (state === RESOLVED) { - deferred.resolve(promiseValue); - } - else if (state === REJECTED) { - deferred.reject(promiseValue); - } - else { - next.push(deferred); - } - return deferred.promise; - }; - - function finish(type) { - state = type || REJECTED; - next.map(function(deferred) { - state === RESOLVED && deferred.resolve(promiseValue) || deferred.reject(promiseValue); - }); + prop.then = function(resolve, reject) { + return propify(promise.then(resolve, reject), initialValue) } - function thennable(then, successCallback, failureCallback, notThennableCallback) { - if (((promiseValue != null && isObject(promiseValue)) || isFunction(promiseValue)) && isFunction(then)) { + prop.catch = prop.then.bind(null, null) + + return prop + } + // Promiz.mithril.js | Zolmeister | MIT + // a modified version of Promiz.js, which does not conform to Promises/A+ + // for two reasons: + // 1) `then` callbacks are called synchronously (because setTimeout is too + // slow, and the setImmediate polyfill is too big + // 2) throwing subclasses of Error cause the error to be bubbled up instead + // of triggering rejection (because the spec does not account for the + // important use case of default browser error handling, i.e. message w/ + // line number) + function Deferred(successCallback, failureCallback) { + var RESOLVING = 1 + var REJECTING = 2 + var RESOLVED = 3 + var REJECTED = 4 + var self = this + var state = 0 + var promiseValue = 0 + var next = [] + + self.promise = {} + + self.resolve = function(value) { + if (!state) { + promiseValue = value + state = RESOLVING + + fire() + } + return this + } + + self.reject = function(value) { + if (!state) { + promiseValue = value + state = REJECTING + + fire() + } + return this + } + + self.promise.then = function(successCallback, failureCallback) { + var deferred = new Deferred(successCallback, failureCallback) + if (state === RESOLVED) { + deferred.resolve(promiseValue) + } else if (state === REJECTED) { + deferred.reject(promiseValue) + } else { + next.push(deferred) + } + return deferred.promise + } + + function finish(type) { + state = type || REJECTED + next.map(function(deferred) { + if (state === RESOLVED) { + deferred.resolve(promiseValue) + } else { + deferred.reject(promiseValue) + } + }) + } + + function thennable( + then, + successCallback, + failureCallback, + notThennableCallback) { + if (((promiseValue != null && isObject(promiseValue)) || + isFunction(promiseValue)) && isFunction(then)) { try { // count protects against abuse calls from spec checker - var count = 0; + var count = 0 then.call(promiseValue, function(value) { - if (count++) return; - promiseValue = value; - successCallback(); + if (count++) return + promiseValue = value + successCallback() }, function (value) { - if (count++) return; - promiseValue = value; - failureCallback(); - }); - } - catch (e) { - m.deferred.onerror(e); - promiseValue = e; - failureCallback(); + if (count++) return + promiseValue = value + failureCallback() + }) + } catch (e) { + m.deferred.onerror(e) + promiseValue = e + failureCallback() } } else { - notThennableCallback(); + notThennableCallback() } } function fire() { // check if it's a thenable - var then; + var then try { - then = promiseValue && promiseValue.then; - } - catch (e) { - m.deferred.onerror(e); - promiseValue = e; - state = REJECTING; - return fire(); + then = promiseValue && promiseValue.then + } catch (e) { + m.deferred.onerror(e) + promiseValue = e + state = REJECTING + return fire() } + thennable(then, function() { - state = RESOLVING; - fire(); + state = RESOLVING + fire() }, function() { - state = REJECTING; - fire(); + state = REJECTING + fire() }, function() { try { if (state === RESOLVING && isFunction(successCallback)) { - promiseValue = successCallback(promiseValue); + promiseValue = successCallback(promiseValue) + } else if (state === REJECTING && + isFunction(failureCallback)) { + promiseValue = failureCallback(promiseValue) + state = RESOLVING } - else if (state === REJECTING && isFunction(failureCallback)) { - promiseValue = failureCallback(promiseValue); - state = RESOLVING; - } - } - catch (e) { - m.deferred.onerror(e); - promiseValue = e; - return finish(); + } catch (e) { + m.deferred.onerror(e) + promiseValue = e + return finish() } if (promiseValue === self) { - promiseValue = TypeError(); - finish(); - } - else { + promiseValue = TypeError() + finish() + } else { thennable(then, function () { - finish(RESOLVED); + finish(RESOLVED) }, finish, function () { - finish(state === RESOLVING && RESOLVED); - }); + finish(state === RESOLVING && RESOLVED) + }) } - }); + }) } } m.deferred.onerror = function(e) { - if (type.call(e) === "[object Error]" && !e.constructor.toString().match(/ Error/)) { - pendingRequests = 0; - throw e; + if (type.call(e) === "[object Error]" && + !e.constructor.toString().match(/ Error/)) { + pendingRequests = 0 + throw e } - }; + } m.sync = function(args) { - var method = "resolve"; + var method = "resolve" + var deferred = m.deferred() + var outstanding = args.length + var results = new Array(outstanding) + function synchronizer(pos, resolved) { return function(value) { - results[pos] = value; - if (!resolved) method = "reject"; + results[pos] = value + if (!resolved) method = "reject" if (--outstanding === 0) { - deferred.promise(results); - deferred[method](results); + deferred.promise(results) + deferred[method](results) } - return value; - }; - } - - var deferred = m.deferred(); - var outstanding = args.length; - var results = new Array(outstanding); - if (args.length > 0) { - for (var i = 0; i < args.length; i++) { - args[i].then(synchronizer(i, true), synchronizer(i, false)); + return value } } - else deferred.resolve([]); - return deferred.promise; - }; - function identity(value) { return value; } + if (args.length > 0) { + forEach(args, function (arg, i) { + arg.then(synchronizer(i, true), synchronizer(i, false)) + }) + } else { + deferred.resolve([]) + } + + return deferred.promise + } + function identity(value) { return value } function ajax(options) { if (options.dataType && options.dataType.toLowerCase() === "jsonp") { - var callbackKey = "mithril_callback_" + new Date().getTime() + "_" + (Math.round(Math.random() * 1e16)).toString(36); - var script = $document.createElement("script"); + var callbackKey = "mithril_callback_" + new Date().getTime() + "_" + + (Math.round(Math.random() * 1e16)).toString(36) + var script = $document.createElement("script") window[callbackKey] = function(resp) { - script.parentNode.removeChild(script); + script.parentNode.removeChild(script) options.onload({ type: "load", target: { responseText: resp } - }); - window[callbackKey] = undefined; - }; + }) + window[callbackKey] = undefined + } - script.onerror = function(e) { - script.parentNode.removeChild(script); + script.onerror = function() { + script.parentNode.removeChild(script) options.onerror({ type: "error", target: { status: 500, - responseText: JSON.stringify({error: "Error making jsonp request"}) + responseText: JSON.stringify({ + error: "Error making jsonp request" + }) } - }); - window[callbackKey] = undefined; + }) + window[callbackKey] = undefined - return false; - }; + return false + } - script.onload = function(e) { - return false; - }; + script.onload = function() { + return false + } script.src = options.url + (options.url.indexOf("?") > 0 ? "&" : "?") + (options.callbackKey ? options.callbackKey : "callback") + "=" + callbackKey - + "&" + buildQueryString(options.data || {}); - $document.body.appendChild(script); - } - else { - var xhr = new window.XMLHttpRequest; - xhr.open(options.method, options.url, true, options.user, options.password); + + "&" + buildQueryString(options.data || {}) + $document.body.appendChild(script) + } else { + var xhr = new window.XMLHttpRequest() + xhr.open( + options.method, + options.url, + true, + options.user, + options.password) + xhr.onreadystatechange = function() { if (xhr.readyState === 4) { - if (xhr.status >= 200 && xhr.status < 300) options.onload({type: "load", target: xhr}); - else options.onerror({type: "error", target: xhr}); + if (xhr.status >= 200 && xhr.status < 300) { + options.onload({type: "load", target: xhr}) + } else { + options.onerror({type: "error", target: xhr}) + } } - }; - if (options.serialize === JSON.stringify && options.data && options.method !== "GET") { - xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); + } + if (options.serialize === JSON.stringify && + options.data && options.method !== "GET") { + xhr.setRequestHeader( + "Content-Type", + "application/json; charset=utf-8") } if (options.deserialize === JSON.parse) { - xhr.setRequestHeader("Accept", "application/json, text/*"); + xhr.setRequestHeader("Accept", "application/json, text/*") } if (isFunction(options.config)) { - var maybeXhr = options.config(xhr, options); - if (maybeXhr != null) xhr = maybeXhr; + var maybeXhr = options.config(xhr, options) + if (maybeXhr != null) xhr = maybeXhr } - var data = options.method === "GET" || !options.data ? "" : options.data; - if (data && (!isString(data) && data.constructor != window.FormData)) { - throw "Request data should be either be a string or FormData. Check the `serialize` option in `m.request`"; + var data + + if (options.method === "GET" || !options.data) { + data = "" + } else { + data = options.data } - xhr.send(data); - return xhr; + + if (data && (!isString(data) && + data.constructor !== window.FormData)) { + throw new Error("Request data should be either be a string " + + "or FormData. Check the `serialize` option in `m.request`") + } + xhr.send(data) + return xhr } } + function bindData(xhrOptions, data, serialize) { - if (xhrOptions.method === "GET" && xhrOptions.dataType != "jsonp") { - var prefix = xhrOptions.url.indexOf("?") < 0 ? "?" : "&"; - var querystring = buildQueryString(data); - xhrOptions.url = xhrOptions.url + (querystring ? prefix + querystring : ""); + if (xhrOptions.method === "GET" && xhrOptions.dataType !== "jsonp") { + var prefix = xhrOptions.url.indexOf("?") < 0 ? "?" : "&" + var querystring = buildQueryString(data) + var suffix = querystring ? prefix + querystring : "" + xhrOptions.url = xhrOptions.url + suffix + } else { + xhrOptions.data = serialize(data) } - else xhrOptions.data = serialize(data); - return xhrOptions; + return xhrOptions } + function parameterizeUrl(url, data) { - var tokens = url.match(/:[a-z]\w+/gi); + var tokens = url.match(/:[a-z]\w+/gi) if (tokens && data) { - for (var i = 0; i < tokens.length; i++) { - var key = tokens[i].slice(1); - url = url.replace(tokens[i], data[key]); - delete data[key]; - } + forEach(tokens, function (token) { + var key = token.slice(1) + url = url.replace(token, data[key]) + delete data[key] + }) } - return url; + return url } m.request = function(xhrOptions) { - if (xhrOptions.background !== true) m.startComputation(); - var deferred = new Deferred(); - var isJSONP = xhrOptions.dataType && xhrOptions.dataType.toLowerCase() === "jsonp"; - var serialize = xhrOptions.serialize = isJSONP ? identity : xhrOptions.serialize || JSON.stringify; - var deserialize = xhrOptions.deserialize = isJSONP ? identity : xhrOptions.deserialize || JSON.parse; - var extract = isJSONP ? function(jsonp) { return jsonp.responseText; } : xhrOptions.extract || function(xhr) { - return xhr.responseText.length === 0 && deserialize === JSON.parse ? null : xhr.responseText; - }; - xhrOptions.method = (xhrOptions.method || 'GET').toUpperCase(); - xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data); - xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize); + if (xhrOptions.background !== true) { + m.startComputation() + } + + var deferred = new Deferred() + var isJSONP = xhrOptions.dataType && + xhrOptions.dataType.toLowerCase() === "jsonp" + + var serialize + + if (isJSONP) { + serialize = xhrOptions.serialize = identity + } else { + serialize = xhrOptions.serialize = xhrOptions.serialize || + JSON.stringify + } + + var deserialize + + if (isJSONP) { + deserialize = xhrOptions.deserialize = identity + } else { + deserialize = xhrOptions.deserialize = xhrOptions.deserialize || + JSON.parse + } + + var extract + + if (isJSONP) { + extract = function(jsonp) { return jsonp.responseText } + } else if (xhrOptions.extract) { + extract = xhrOptions.extract + } else { + extract = function(xhr) { + if (xhr.responseText.length === 0 && + deserialize === JSON.parse) { + return null + } else { + return xhr.responseText + } + } + } + + xhrOptions.method = (xhrOptions.method || "GET").toUpperCase() + xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data) + xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize) xhrOptions.onload = xhrOptions.onerror = function(e) { try { - e = e || event; - var unwrap = (e.type === "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity; - var response = unwrap(deserialize(extract(e.target, xhrOptions)), e.target); + e = e || event + var unwrap + + if (e.type === "load") { + unwrap = xhrOptions.unwrapSuccess + } else { + unwrap = xhrOptions.unwrapError + } + + var response = (unwrap || identity)( + deserialize(extract(e.target, xhrOptions)), e.target) + if (e.type === "load") { if (isArray(response) && xhrOptions.type) { forEach(response, function (res, i) { - response[i] = new xhrOptions.type(res); - }); + response[i] = new xhrOptions.type(res) + }) + } else if (xhrOptions.type) { + response = new xhrOptions.type(response) } - else if (xhrOptions.type) response = new xhrOptions.type(response); } - deferred[e.type === "load" ? "resolve" : "reject"](response); - } - catch (e) { - m.deferred.onerror(e); - deferred.reject(e); - } - if (xhrOptions.background !== true) m.endComputation(); - }; - ajax(xhrOptions); - deferred.promise = propify(deferred.promise, xhrOptions.initialValue); - return deferred.promise; - }; - //testing API + deferred[e.type === "load" ? "resolve" : "reject"](response) + } catch (e) { // eslint-disable-line + m.deferred.onerror(e) + deferred.reject(e) + } + + if (xhrOptions.background !== true) m.endComputation() + } + + ajax(xhrOptions) + deferred.promise = propify(deferred.promise, xhrOptions.initialValue) + return deferred.promise + } + + // testing API m.deps = function(mock) { - initialize(window = mock || window); - return window; - }; - //for internal testing only, do not use `m.deps.factory` - m.deps.factory = app; + initialize(window = mock || window) + return window + } - return m; -})(typeof window != "undefined" ? window : {}); + // for internal testing only, do not use `m.deps.factory` + m.deps.factory = app -if (typeof module != "undefined" && module !== null && module.exports) module.exports = m; -else if (typeof define === "function" && define.amd) define(function() { return m; }); + return m +})(typeof window !== "undefined" ? window : {}) + +/* eslint-disable no-undef, strict */ +if (typeof module === "object" && module !== null && module.exports) { + module.exports = m +} else if (typeof define === "function" && define.amd) { + define(function() { return m }) +} +/* eslint-enable no-undef, strict */ diff --git a/package.json b/package.json index 819228f7..f2955287 100644 --- a/package.json +++ b/package.json @@ -1,46 +1,55 @@ { - "name": "mithril", - "description": "Mithril.js beta build - use this to help us test the releases before they are released", - "version": "0.1.34-beta.0", - "repository": { - "type": "git", - "url": "git@github.com:lhorie/mithril.js.git" - }, - "scripts": { - "test": "grunt test" - }, - "main": "mithril.js", - "devDependencies": { - "grunt": "*", - "grunt-cli": "*", - "grunt-contrib-copy": "*", - "grunt-contrib-uglify": "*", - "grunt-contrib-clean": "*", - "grunt-contrib-concat": "*", - "grunt-execute": "*", - "grunt-md2html": "*", - "grunt-replace": "*", - "grunt-contrib-qunit": "*", - "grunt-zip": "*", - "grunt-jsfmt": "git://github.com/ysimonson/grunt-jsfmt", - - "grunt-contrib-connect": "~0.7.1", - "grunt-contrib-jshint": "~0.10.0", - "grunt-contrib-watch": "~0.6.1", - "grunt-jscs": "^1.1.0", - "grunt-sauce-tunnel": "^0.2.1", - "load-grunt-config": "^0.9.2", - "merge": "^1.1.3", - "publish": "~0.3.2", - "grunt-saucelabs": "*", - "request": "~2.35.0", - "q": "~1.0.0", - "saucelabs": "~0.1.1", - "sauce-tunnel": "~2.0.6", - "colors": "~0.6.2", - "lodash": "~2.4.1" - }, - "main": "mithril.js", - "licenses": [{"type": "MIT", "url": "http://opensource.org/licenses/MIT"}], - "files": ["mithril.min.js", "mithril.min.js.map", "mithril.js", "README.*"] + "name": "mithril", + "description": "Mithril.js beta build - use this to help us test the releases before they are released", + "version": "0.1.34-beta.0", + "repository": { + "type": "git", + "url": "git@github.com:lhorie/mithril.js.git" + }, + "scripts": { + "test": "grunt test" + }, + "main": "mithril.js", + "devDependencies": { + "colors": "~0.6.2", + "grunt": "*", + "grunt-cli": "*", + "grunt-contrib-clean": "*", + "grunt-contrib-concat": "*", + "grunt-contrib-connect": "~0.7.1", + "grunt-contrib-copy": "*", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-qunit": "*", + "grunt-contrib-uglify": "*", + "grunt-contrib-watch": "~0.6.1", + "grunt-eslint": "^16.0.0", + "grunt-execute": "*", + "grunt-jscs": "^1.1.0", + "grunt-jsfmt": "git://github.com/ysimonson/grunt-jsfmt", + "grunt-md2html": "*", + "grunt-replace": "*", + "grunt-sauce-tunnel": "^0.2.1", + "grunt-saucelabs": "*", + "grunt-zip": "*", + "load-grunt-config": "^0.9.2", + "lodash": "~2.4.1", + "merge": "^1.1.3", + "publish": "~0.3.2", + "q": "~1.0.0", + "request": "~2.35.0", + "sauce-tunnel": "~2.0.6", + "saucelabs": "~0.1.1" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + ], + "files": [ + "mithril.min.js", + "mithril.min.js.map", + "mithril.js", + "README.*" + ] } diff --git a/tests/e2e/.eslintrc b/tests/e2e/.eslintrc new file mode 100644 index 00000000..a351ac0b --- /dev/null +++ b/tests/e2e/.eslintrc @@ -0,0 +1,23 @@ +{ + "extend": "../../.eslintrc", + "globals": { + "asyncTest": false, + "deepEqual": false, + "equal": false, + "expect": false, + "module": false, + "notDeepEqual": false, + "notEqual": false, + "notPropEqual": false, + "notStrictEqual": false, + "ok": false, + "propEqual": false, + "QUnit": false, + "raises": false, + "start": false, + "stop": false, + "strictEqual": false, + "test": false, + "throws": false + } +} diff --git a/tests/e2e/tests.js b/tests/e2e/tests.js index 1dd8de03..ea1b389a 100644 --- a/tests/e2e/tests.js +++ b/tests/e2e/tests.js @@ -1,8 +1,13 @@ -//saucelabs reporting; see https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit +/* eslint-disable camelcase */ +/* global m, Syn */ + +// saucelabs reporting; see +// https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit + var log = [] -var testName QUnit.done(function (test_results) { + "use strict" var tests = [] for (var i = 0, len = log.length; i < len; i++) { var details = log[i] @@ -19,6 +24,7 @@ QUnit.done(function (test_results) { window.global_test_results = test_results }) QUnit.testStart(function (testDetails) { + "use strict" QUnit.log(function (details) { if (!details.result) { details.name = testDetails.name @@ -27,9 +33,11 @@ QUnit.testStart(function (testDetails) { }) }) -//qunit doesn't support Function.prototype.bind... +// qunit doesn't support Function.prototype.bind... if (!Function.prototype.bind) { + /* eslint-disable */ Function.prototype.bind = function (oThis) { + "use strict" if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 // internal IsCallable function @@ -51,165 +59,181 @@ if (!Function.prototype.bind) { return fBound } + /* eslint-enable */ } //tests -var dummyEl = document.getElementById('dummy') +var dummyEl = document.getElementById("dummy") -test('Mithril accessible as window.m', function() { +test("Mithril accessible as window.m", function() { + "use strict" expect(1) ok(window.m) }) -test('m.trust w/ html entities', function() { +test("m.trust w/ html entities", function() { + "use strict" expect(1) - var view1 = m('div', "a", m.trust("&"), "b") + var view1 = m("div", "a", m.trust("&"), "b") m.render(dummyEl, view1) - equal(dummyEl.innerHTML, '
a&b
', 'view1 rendered correctly') + equal(dummyEl.innerHTML, "
a&b
", "view1 rendered correctly") }) -test('m.trust w/ html entities 2', function() { +test("m.trust w/ html entities 2", function() { + "use strict" expect(1) - var view1 = m('div', "a", m.trust("&"), "b", m.trust("&"), "c") + var view1 = m("div", "a", m.trust("&"), "b", m.trust("&"), "c") m.render(dummyEl, view1) - equal(dummyEl.innerHTML, '
a&b&c
', 'view1 rendered correctly') + equal(dummyEl.innerHTML, "
a&b&c
", + "view1 rendered correctly") }) -test('array item removal', function() { +test("array item removal", function() { + "use strict" expect(2) - var view1 = m('div', {}, [ - m('div', {}, '0'), - m('div', {}, '1'), - m('div', {}, '2') + var view1 = m("div", {}, [ + m("div", {}, "0"), + m("div", {}, "1"), + m("div", {}, "2") ]) - var view2= m('div', {}, [ - m('div', {}, '0') + var view2 = m("div", {}, [ + m("div", {}, "0") ]) m.render(dummyEl, view1) - equal(dummyEl.innerHTML, '
0
1
2
', 'view1 rendered correctly') + equal(dummyEl.innerHTML, "
0
1
2
", + "view1 rendered correctly") m.render(dummyEl, view2) - equal(dummyEl.innerHTML, '
0
', 'view2 should be rendered correctly') + equal(dummyEl.innerHTML, "
0
", + "view2 should be rendered correctly") }) -test('issue99 regression', function() { +test("issue99 regression", function() { + "use strict" // see https://github.com/lhorie/mithril.js/issues/99 expect(2) - var view1 = m('div', {}, [ - m('div', {}, '0'), - m('div', {}, '1'), - m('div', {}, '2') + var view1 = m("div", {}, [ + m("div", {}, "0"), + m("div", {}, "1"), + m("div", {}, "2") ]) - var view2= m('div', {}, [ - m('span', {}, '0') + var view2 = m("div", {}, [ + m("span", {}, "0") ]) m.render(dummyEl, view1) - equal(dummyEl.innerHTML, '
0
1
2
', 'view1 rendered correctly') + equal(dummyEl.innerHTML, "
0
1
2
", + "view1 rendered correctly") m.render(dummyEl, view2) - equal(dummyEl.innerHTML, '
0
', 'view2 should be rendered correctly') + equal(dummyEl.innerHTML, "
0
", + "view2 should be rendered correctly") }) -test('config handler context', function() { +test("config handler context", function() { + "use strict" expect(3) - var view = m('div', {config: function(evt, isInitialized, context) { + var view = m("div", {config: function(evt, isInitialized, context) { equal(context instanceof Object, true) context.data = 1 }}) m.render(dummyEl, view) - var view = m('div', {config: function(evt, isInitialized, context) { + view = m("div", {config: function(evt, isInitialized, context) { equal(context instanceof Object, true) equal(context.data, 1) }}) m.render(dummyEl, view) }) -test('node identity remove firstChild', function() { +test("node identity remove firstChild", function() { + "use strict" expect(2) - var view1 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2') + var view1 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2") ]) m.render(dummyEl, view1) var node2 = dummyEl.firstChild.lastChild - equal(node2.innerHTML, 'E2') + equal(node2.innerHTML, "E2") - var view2 = m('div', {}, [ - m('div', {key:2}, 'E2') + var view2 = m("div", {}, [ + m("div", {key: 2}, "E2") ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild, node2) }) -test('node identity change order', function() { +test("node identity change order", function() { + "use strict" expect(2) - var view1 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2'), - m('div', {key:3}, 'E3') + var view1 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2"), + m("div", {key: 3}, "E3") ]) m.render(dummyEl, view1) var e2 = dummyEl.firstChild.firstChild.nextSibling - equal(e2.innerHTML, 'E2') + equal(e2.innerHTML, "E2") - var view2 = m('div', {}, [ - m('div', {key:2}, 'E2'), - m('div', {key:1}, 'E1'), - m('div', {key:3}, 'E3') + var view2 = m("div", {}, [ + m("div", {key: 2}, "E2"), + m("div", {key: 1}, "E1"), + m("div", {key: 3}, "E3") ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild, e2) }) -test('node identity remove in the middle', function() { +test("node identity remove in the middle", function() { + "use strict" expect(2) - var view1 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2'), - m('div', {key:3}, 'E3') + var view1 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2"), + m("div", {key: 3}, "E3") ]) m.render(dummyEl, view1) var e3 = dummyEl.firstChild.lastChild - equal(e3.innerHTML, 'E3') + equal(e3.innerHTML, "E3") - var view2 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:3}, 'E3') + var view2 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 3}, "E3") ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild.nextSibling, e3) }) -test('node identity remove last', function() { +test("node identity remove last", function() { + "use strict" expect(4) - var view1 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2'), - m('div', {key:3}, 'E3') + var view1 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2"), + m("div", {key: 3}, "E3") ]) m.render(dummyEl, view1) var e1 = dummyEl.firstChild.firstChild - equal(e1.innerHTML, 'E1') + equal(e1.innerHTML, "E1") var e2 = dummyEl.firstChild.firstChild.nextSibling - equal(e2.innerHTML, 'E2') + equal(e2.innerHTML, "E2") - var view2 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2') + var view2 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2") ]) m.render(dummyEl, view2) @@ -217,168 +241,176 @@ test('node identity remove last', function() { equal(dummyEl.firstChild.firstChild.nextSibling, e2) }) -test('node identity shuffle and remove', function() { +test("node identity shuffle and remove", function() { + "use strict" expect(8) - var view1 = m('div', {}, [ - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2'), - m('div', {key:3}, 'E3'), - m('div', {key:4}, 'E4'), - m('div', {key:5}, 'E5') + var view1 = m("div", {}, [ + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2"), + m("div", {key: 3}, "E3"), + m("div", {key: 4}, "E4"), + m("div", {key: 5}, "E5") ]) m.render(dummyEl, view1) var e1 = dummyEl.firstChild.firstChild - equal(e1.innerHTML, 'E1') + equal(e1.innerHTML, "E1") var e2 = e1.nextSibling - equal(e2.innerHTML, 'E2') + equal(e2.innerHTML, "E2") var e3 = e2.nextSibling - equal(e3.innerHTML, 'E3') + equal(e3.innerHTML, "E3") var e4 = e3.nextSibling - equal(e4.innerHTML, 'E4') + equal(e4.innerHTML, "E4") var e5 = e4.nextSibling - equal(e5.innerHTML, 'E5') + equal(e5.innerHTML, "E5") - var view2 = m('div', {}, [ - m('div', {key:4}, 'E4'), - m('div', {key:10}, 'E10'), - m('div', {key:1}, 'E1'), - m('div', {key:2}, 'E2') + var view2 = m("div", {}, [ + m("div", {key: 4}, "E4"), + m("div", {key: 10}, "E10"), + m("div", {key: 1}, "E1"), + m("div", {key: 2}, "E2") ]) m.render(dummyEl, view2) - equal(dummyEl.firstChild.firstChild, e4, 'e4 is first element') - equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling, e1, 'e1 is third element') - equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling.nextSibling, e2, 'e2 is fourth element') + equal(dummyEl.firstChild.firstChild, e4, "e4 is first element") + equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling, e1, + "e1 is third element") + equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling.nextSibling, e2, + "e2 is fourth element") }) -asyncTest('issue214 regression', function() { +asyncTest("issue214 regression", function() { + "use strict" // see https://github.com/lhorie/mithril.js/issues/214 expect(2) function controller() { - this.inputValue = m.prop('') + this.inputValue = m.prop("") } function view(ctrl) { - return m('input#testinput', { + return m("input#testinput", { value: ctrl.inputValue(), - onkeyup: m.withAttr('value', ctrl.inputValue) + onkeyup: m.withAttr("value", ctrl.inputValue) }) } var ctrl = m.module(dummyEl, { controller: controller, view: view }) - Syn.click({}, 'testinput') - .type('0').delay(10) - .type('1').delay(10) - .type('2').delay(10) - .type('3').delay(10) - .type('4').delay(10) - .type('5').delay(10) - .type('6').delay(10) - .type('7').delay(10) - .type('8').delay(10) - .type('9').delay(10) - .type('a').delay(10) - .type('b').delay(10) - .type('c').delay(10) - .type('d').delay(10) - .type('e').delay(10) - .type('f').delay(10) - .type('0').delay(10) - .type('1').delay(10) - .type('2').delay(10) - .type('3').delay(10) - .type('4').delay(10) - .type('5').delay(10) - .type('6').delay(10) - .type('7').delay(10) - .type('8').delay(10) - .type('9').delay(10) - .type('a').delay(10) - .type('b').delay(10) - .type('c').delay(10) - .type('d').delay(10) - .type('e').delay(10) - .type('f').delay(10) - .type('0').delay(10) - .type('1').delay(10) - .type('2').delay(10) - .type('3').delay(10) - .type('4').delay(10) - .type('5').delay(10) - .type('6').delay(10) - .type('7').delay(10) - .type('8').delay(10) - .type('9').delay(10) - .type('a').delay(10) - .type('b').delay(10) - .type('c').delay(10) - .type('d').delay(10) - .type('e').delay(10) - .type('f').delay(10) - .type('0').delay(10) - .type('1').delay(10) - .type('2').delay(10) - .type('3').delay(10) - .type('4').delay(10) - .type('5').delay(10) - .type('6').delay(10) - .type('7').delay(10) - .type('8').delay(10) - .type('9').delay(10) - .type('a').delay(10) - .type('b').delay(10) - .type('c').delay(10) - .type('d').delay(10) - .type('e').delay(10) - .type('f', function() { - equal(ctrl.inputValue(), '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef') - equal(document.getElementById('testinput').value, '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef') + Syn.click({}, "testinput") + .type("0").delay(10) + .type("1").delay(10) + .type("2").delay(10) + .type("3").delay(10) + .type("4").delay(10) + .type("5").delay(10) + .type("6").delay(10) + .type("7").delay(10) + .type("8").delay(10) + .type("9").delay(10) + .type("a").delay(10) + .type("b").delay(10) + .type("c").delay(10) + .type("d").delay(10) + .type("e").delay(10) + .type("f").delay(10) + .type("0").delay(10) + .type("1").delay(10) + .type("2").delay(10) + .type("3").delay(10) + .type("4").delay(10) + .type("5").delay(10) + .type("6").delay(10) + .type("7").delay(10) + .type("8").delay(10) + .type("9").delay(10) + .type("a").delay(10) + .type("b").delay(10) + .type("c").delay(10) + .type("d").delay(10) + .type("e").delay(10) + .type("f").delay(10) + .type("0").delay(10) + .type("1").delay(10) + .type("2").delay(10) + .type("3").delay(10) + .type("4").delay(10) + .type("5").delay(10) + .type("6").delay(10) + .type("7").delay(10) + .type("8").delay(10) + .type("9").delay(10) + .type("a").delay(10) + .type("b").delay(10) + .type("c").delay(10) + .type("d").delay(10) + .type("e").delay(10) + .type("f").delay(10) + .type("0").delay(10) + .type("1").delay(10) + .type("2").delay(10) + .type("3").delay(10) + .type("4").delay(10) + .type("5").delay(10) + .type("6").delay(10) + .type("7").delay(10) + .type("8").delay(10) + .type("9").delay(10) + .type("a").delay(10) + .type("b").delay(10) + .type("c").delay(10) + .type("d").delay(10) + .type("e").delay(10) + .type("f", function() { + equal(ctrl.inputValue(), + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") + equal(document.getElementById("testinput").value, + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") start() }) }) -asyncTest('issue288 regression', function() { +asyncTest("issue288 regression", function() { + "use strict" // see https://github.com/lhorie/mithril.js/issues/288 expect(2) function controller() { - this.inputValue = m.prop('') + this.inputValue = m.prop("") this.submit = function() { if (this.inputValue()) { - this.inputValue('') + this.inputValue("") } - }.bind(this); + }.bind(this) } function view(ctrl) { - return m('form', { onsubmit: ctrl.submit }, [ - m('input#testinput', { - onkeyup: m.withAttr('value', ctrl.inputValue), + return m("form", { onsubmit: ctrl.submit }, [ + m("input#testinput", { + onkeyup: m.withAttr("value", ctrl.inputValue), value: ctrl.inputValue() }), - m('button[type=submit]') + m("button[type=submit]") ]) } var ctrl = m.module(dummyEl, { controller: controller, view: view }) - Syn.click({}, 'testinput') - .type('a').delay(10) - .type('b').delay(10) - .type('c').delay(10) - .type('d').delay(10) - .type('[enter]', function() { - equal(ctrl.inputValue(), '') - equal(document.getElementById('testinput').value, '') + Syn.click({}, "testinput") + .type("a").delay(10) + .type("b").delay(10) + .type("c").delay(10) + .type("d").delay(10) + .type("[enter]", function() { + equal(ctrl.inputValue(), "") + equal(document.getElementById("testinput").value, "") start() }) }) -test('issue278 regression', function() { +test("issue278 regression", function() { + "use strict" // see https://github.com/lhorie/mithril.js/issues/278 expect(1) @@ -389,22 +421,24 @@ test('issue278 regression', function() { }, view: function(ctrl) { - return m('select#testselect', { + return m("select#testselect", { size: ctrl.values.length, - multiple: 'multiple' + multiple: "multiple" }, [ ctrl.values.map(function(v){ var opts = {value: v} - if (ctrl.value().indexOf(v) !== -1) opts.selected = 'selected' - return m('option', opts, v) + if (ctrl.value().indexOf(v) !== -1) { + opts.selected = "selected" + } + return m("option", opts, v) }) ]) } } - m.render(dummyEl, test.view(new test.controller)) + m.render(dummyEl, test.view(new test.controller())) - var select = document.getElementById('testselect') + var select = document.getElementById("testselect") for (var i = 0, selected = 0; i < select.options.length; i++) { if (select.options[i].selected) selected++ @@ -413,25 +447,30 @@ test('issue278 regression', function() { equal(selected, 2) }) test("mixing trusted content", function() { + "use strict" m.render(dummyEl, [m.trust("

1

2

"), m("i", "foo")]) equal(dummyEl.childNodes[2].nodeName, "I") }) test("mixing trusted content w/ text nodes", function() { + "use strict" m.render(dummyEl, [m.trust("

1

123

2

"), m("i", "foo")]) equal(dummyEl.childNodes[3].nodeName, "I") }) test("mixing trusted content w/ td", function() { + "use strict" m.render(dummyEl, [m.trust("12"), m("i", "foo")]) equal(dummyEl.childNodes[1].nodeName, "I") }) test("0 should not be treated as empty string", function() { + "use strict" m.render(dummyEl, m("input", {value: ""})) m.render(dummyEl, m("input", {value: 0})) equal(dummyEl.childNodes[0].value, "0") }) test("empty value in ') }) diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 7194f61a..4b7a2a1a 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1,7 +1,12 @@ +/* global m, test, mock */ +/* eslint-disable no-console */ + function testMithril(mock) { + "use strict" + m.deps(mock) - - //m + + // m test(function() {return m("div").tag === "div"}) test(function() {return m(".foo").tag === "div"}) test(function() {return m(".foo").attrs.className === "foo"}) @@ -12,48 +17,90 @@ function testMithril(mock) { test(function() {return m("div", "test").children[0] === "test"}) test(function() {return m("div", "test", "test2").children[1] === "test2"}) test(function() {return m("div", ["test"]).children[0] === "test"}) - test(function() {return m("div", {title: "bar"}, "test").attrs.title === "bar"}) - test(function() {return m("div", {title: "bar"}, "test").children[0] === "test"}) - test(function() {return m("div", {title: "bar"}, ["test"]).children[0] === "test"}) - test(function() {return m("div", {title: "bar"}, m("div")).children[0].tag === "div"}) - test(function() {return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div"}) - test(function() {return m("div", {title: "bar"}, "test0", "test1", "test2", "test3").children[3] === "test3"}) // splat - test(function() {return m("div", {title: "bar"}, m("div"), m("i"), m("span")).children[2].tag === "span"}) + test(function() { + return m("div", {title: "bar"}, "test").attrs.title === "bar" + }) + test(function() { + return m("div", {title: "bar"}, "test").children[0] === "test" + }) + test(function() { + return m("div", {title: "bar"}, ["test"]).children[0] === "test" + }) + test(function() { + return m("div", {title: "bar"}, m("div")).children[0].tag === "div" + }) + test(function() { + return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div" + }) + test(function() { + // splat + return m("div", {title: "bar"}, + "test0", "test1", "test2", "test3").children[3] === "test3" + }) + test(function() { + return m("div", {title: "bar"}, + m("div"), m("i"), m("span")).children[2].tag === "span" + }) test(function() {return m("div", ["a", "b"]).children.length === 2}) test(function() {return m("div", [m("div")]).children[0].tag === "div"}) - test(function() {return m("div", m("div")).children[0].tag === "div"}) //yes, this is expected behavior: see method signature + test(function() { + // yes, this is expected behavior: see method signature + return m("div", m("div")).children[0].tag === "div" + }) test(function() {return m("div", [undefined]).tag === "div"}) - test(function() {return m("div", [{foo: "bar"}])}) //as long as it doesn't throw errors, it's fine + test(function() { + // as long as it doesn't throw errors, it's fine + return m("div", [{foo: "bar"}]) + }) test(function() {return m("svg", [m("g")])}) test(function() {return m("svg", [m("a[href='http://google.com']")])}) - test(function() {return m(".foo", {"class": "bar"}).attrs["class"] == "foo bar"}) - test(function() {return m(".foo", {className: "bar"}).attrs.className == "foo bar"}) - test(function() {return m(".foo", {className: ""}).attrs.className == "foo"}) - test(function() {return m("div", {className: ""}).attrs.className === ""}) //https://github.com/lhorie/mithril.js/issues/382 and 512 - test(function() {return m("div", {class: ""}).attrs.className === undefined}) - test(function() {return m("div", {className: ""}).attrs.class === undefined}) + test(function() { + return m(".foo", {class: "bar"}).attrs.class === "foo bar" + }) + test(function() { + return m(".foo", {className: "bar"}).attrs.className === "foo bar" + }) + test(function() { + return m(".foo", {className: ""}).attrs.className === "foo" + }) + test(function() { + // https://github.com/lhorie/mithril.js/issues/382 and 512 + return m("div", {className: ""}).attrs.className === "" + }) + test(function() { + return m("div", {class: ""}).attrs.className === undefined + }) + test(function() { + return m("div", {className: ""}).attrs.class === undefined + }) test(function() {return m("div", {class: ""}).attrs.class === ""}) test(function() {return m("div", [1, 2, 3], 4).children.length === 2}) test(function() {return m("div", [1, 2, 3], 4).children[0].length === 3}) test(function() {return m("div", [1, 2, 3], 4).children[1] === 4}) test(function() {return m("div", [1, 2, 3]).children.length === 3}) - test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children.length === 2}) - test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children[0].length === 3}) - test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children[1].length === 4}) + test(function() { + return m("div", [1, 2, 3], [4, 5, 6, 7]).children.length === 2 + }) + test(function() { + return m("div", [1, 2, 3], [4, 5, 6, 7]).children[0].length === 3 + }) + test(function() { + return m("div", [1, 2, 3], [4, 5, 6, 7]).children[1].length === 4 + }) test(function() {return m("div", [1], [2], [3]).children.length === 3}) test(function() { - //class changes shouldn't trigger dom recreation + // class changes shouldn't trigger dom recreation var v1 = m(".foo", {class: "", onclick: function() {}}) var v2 = m(".foo", {class: "bar", onclick: function() {}}) return Object.keys(v1.attrs).join() === Object.keys(v2.attrs).join() }) test(function() { - //m should proxy object first arg to m.component + // m should proxy object first arg to m.component var component = { controller: function(args) { this.args = args }, - view: function(ctrl) { + view: function () { return m("div", "testing") } } @@ -61,33 +108,33 @@ function testMithril(mock) { var c1 = m(component, args).controller() var c2 = m.component(component, args).controller() - return c1.args === args && c1.args == c2.args + return c1.args === args && c1.args === c2.args }) - //m.mount + // m.mount test(function() { var root = mock.document.createElement("div") var whatever = 1 var app = { view: function() { return [ - whatever % 2 ? m('span', '% 2') : undefined, - m('div', 'bugs'), - m('a'), + whatever % 2 ? m("span", "% 2") : undefined, + m("div", "bugs"), + m("a") ] } } m.mount(root, app) mock.requestAnimationFrame.$resolve() - + whatever++ m.redraw() mock.requestAnimationFrame.$resolve() - + whatever++ m.redraw() mock.requestAnimationFrame.$resolve() - + return root.childNodes.length }) test(function() { @@ -107,15 +154,17 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return (root1.childNodes[0].nodeValue === "test1" && root2.childNodes[0].nodeValue === "test2") - && (mod1.value && mod1.value === "test1") && (mod2.value && mod2.value === "test2") + return root1.childNodes[0].nodeValue === "test1" && + root2.childNodes[0].nodeValue === "test2" && + mod1.value && mod1.value === "test1" && + mod2.value && mod2.value === "test2" }) test(function() { mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var unloaded = false - var mod = m.mount(root, { + m.mount(root, { controller: function() { this.value = "test1" this.onunload = function() { @@ -128,13 +177,13 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.mount(root, null) - + mock.requestAnimationFrame.$resolve() - + return unloaded }) test(function() { - //component should pass args to both controller and view + // component should pass args to both controller and view mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") @@ -147,14 +196,14 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return slot1 == 1 && slot2 == 1 + return slot1 === 1 && slot2 === 1 }) test(function() { - //component should work without controller + // component should work without controller mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") - var slot1, slot2 + var slot2 var component = { view: function(ctrl, options) {slot2 = options.a} } @@ -162,124 +211,126 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return slot2 == 1 + return slot2 === 1 }) test(function() { - //component controller should only run once + // component controller should only run once mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") - var count1 = 0, count2 = 0 - var component = { - view: function(ctrl) { - return sub - } - } + var count1 = 0 + var count2 = 0 var sub = { controller: function() { count1++ }, - view: function(ctrl) { + view: function() { count2++ return m("div", "test") } } + var component = { + view: function() { + return sub + } + } m.mount(root, component) mock.requestAnimationFrame.$resolve() - + m.redraw(true) mock.requestAnimationFrame.$resolve() - - return count1 == 1 && count2 == 2 + + return count1 === 1 && count2 === 2 }) test(function() { - //sub component controller should only run once + // sub component controller should only run once mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") - var count1 = 0, count2 = 0, count3 = 0, count4 = 0 - var component = { - view: function(ctrl) { - return sub - } - } - var sub = { - controller: function() { - count1++ - }, - view: function(ctrl) { - count2++ - return subsub - } - } + var count1 = 0 + var count2 = 0 + var count3 = 0 + var count4 = 0 var subsub = { controller: function() { count3++ }, - view: function(ctrl) { + view: function() { count4++ return m("div", "test") } } + var sub = { + controller: function() { + count1++ + }, + view: function() { + count2++ + return subsub + } + } + var component = { + view: function() { + return sub + } + } m.mount(root, component) mock.requestAnimationFrame.$resolve() - + m.redraw(true) mock.requestAnimationFrame.$resolve() - - return count1 == 1 && count2 == 2 && count3 == 1 && count4 == 2 + + return count1 === 1 && count2 === 2 && count3 === 1 && count4 === 2 }) test(function() { - //keys in components should work + // keys in components should work mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var component = { - controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) - } - } var sub = { controller: function() {}, view: function() { return m("div") } } + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } m.mount(root, component) - + var firstBefore = root.childNodes[0] - + mock.requestAnimationFrame.$resolve() - + list.reverse() m.redraw(true) mock.requestAnimationFrame.$resolve() - + var firstAfter = root.childNodes[2] - + return firstBefore === firstAfter }) test(function() { - //keys in subcomponents should work + // keys in subcomponents should work mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var component = { + var subsub = { controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) + view: function() { + return m("div") } } var sub = { @@ -287,150 +338,154 @@ function testMithril(mock) { return subsub } } - var subsub = { - controller: function() {}, - view: function() { - return m("div") - } - } - m.mount(root, component) - - var firstBefore = root.childNodes[0] - - mock.requestAnimationFrame.$resolve() - - list.reverse() - m.redraw(true) - - mock.requestAnimationFrame.$resolve() - - var firstAfter = root.childNodes[2] - - return firstBefore === firstAfter - }) - test(function() { - //keys in components should work even if component internally messes them up - mock.requestAnimationFrame.$resolve() - - var root = mock.document.createElement("div") - var list = [1, 2, 3] var component = { controller: function() {}, - view: function(ctrl) { + view: function() { return list.map(function(i) { return m.component(sub, {key: i}) }) } } + m.mount(root, component) + + var firstBefore = root.childNodes[0] + + mock.requestAnimationFrame.$resolve() + + list.reverse() + m.redraw(true) + + mock.requestAnimationFrame.$resolve() + + var firstAfter = root.childNodes[2] + + return firstBefore === firstAfter + }) + test(function() { + // keys in components should work even if component internally messes + // them up + mock.requestAnimationFrame.$resolve() + + var root = mock.document.createElement("div") + var list = [1, 2, 3] var sub = { controller: function() {}, view: function() { return m("div", {key: 1}) } } - m.mount(root, component) - - var firstBefore = root.childNodes[0] - - mock.requestAnimationFrame.$resolve() - - list.reverse() - m.redraw(true) - - mock.requestAnimationFrame.$resolve() - - var firstAfter = root.childNodes[2] - - return firstBefore === firstAfter - }) - test(function() { - //keys in subcomponents should work even if component internally messes them up - mock.requestAnimationFrame.$resolve() - - var root = mock.document.createElement("div") - var list = [1, 2, 3] var component = { controller: function() {}, - view: function(ctrl) { + view: function() { return list.map(function(i) { return m.component(sub, {key: i}) }) } } - var sub = { - controller: function() {}, - view: function() { - return subsub - } - } + m.mount(root, component) + + var firstBefore = root.childNodes[0] + + mock.requestAnimationFrame.$resolve() + + list.reverse() + m.redraw(true) + + mock.requestAnimationFrame.$resolve() + + var firstAfter = root.childNodes[2] + + return firstBefore === firstAfter + }) + test(function() { + // keys in subcomponents should work even if component internally messes + // them up + mock.requestAnimationFrame.$resolve() + + var root = mock.document.createElement("div") + var list = [1, 2, 3] var subsub = { controller: function() {}, view: function() { return m("div", {key: 1}) } } + var sub = { + controller: function() {}, + view: function() { + return subsub + } + } + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } m.mount(root, component) - + var firstBefore = root.childNodes[0] - + mock.requestAnimationFrame.$resolve() - + list.reverse() m.redraw(true) mock.requestAnimationFrame.$resolve() - + var firstAfter = root.childNodes[2] - + return firstBefore === firstAfter }) test(function() { - //component identity should stay intact if components are descendants of keyed elements + // component identity should stay intact if components are descendants + // of keyed elements mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var component = { - controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m("div", {key: i}, sub) - }) - } - } var sub = { controller: function() {}, view: function() { return m("div") } } + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m("div", {key: i}, sub) + }) + } + } m.mount(root, component) - + var firstBefore = root.childNodes[0].childNodes[0] - + mock.requestAnimationFrame.$resolve() - + list.reverse() m.redraw(true) mock.requestAnimationFrame.$resolve() - + var firstAfter = root.childNodes[2].childNodes[0] - + return firstBefore === firstAfter }) test(function() { - //subcomponent identity should stay intact if components are descendants of keyed elements + // subcomponent identity should stay intact if components are + // descendants of keyed elements mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var component = { + var subsub = { controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m("div", {key: i}, sub) - }) + view: function() { + return m("div") } } var sub = { @@ -439,42 +494,36 @@ function testMithril(mock) { return subsub } } - var subsub = { + var component = { controller: function() {}, view: function() { - return m("div") + return list.map(function(i) { + return m("div", {key: i}, sub) + }) } } m.mount(root, component) - + var firstBefore = root.childNodes[0].childNodes[0] - + mock.requestAnimationFrame.$resolve() - + list.reverse() m.redraw(true) mock.requestAnimationFrame.$resolve() - + var firstAfter = root.childNodes[2].childNodes[0] - + return firstBefore === firstAfter }) test(function() { - //component should call onunload when removed from template + // component should call onunload when removed from template mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] var unloaded - var component = { - controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) - } - } var sub = { controller: function(opts) { this.onunload = function() { @@ -485,32 +534,40 @@ function testMithril(mock) { return m("div") } } + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } m.mount(root, component) - - var firstBefore = root.childNodes[0] - + mock.requestAnimationFrame.$resolve() - + list.pop() m.redraw(true) mock.requestAnimationFrame.$resolve() - + return unloaded === 3 }) test(function() { - //subcomponent should call onunload when removed from template + // subcomponent should call onunload when removed from template mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] var unloaded1, unloaded2 - var component = { - controller: function() {}, - view: function(ctrl) { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) + var subsub = { + controller: function(opts) { + this.onunload = function() { + unloaded2 = opts.key + } + }, + view: function() { + return m("div") } } var sub = { @@ -523,248 +580,253 @@ function testMithril(mock) { return m.component(subsub, {key: opts.key}) } } + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } + m.mount(root, component) + + mock.requestAnimationFrame.$resolve() + + list.pop() + m.redraw(true) + + mock.requestAnimationFrame.$resolve() + + return unloaded1 === 3 && unloaded2 === 3 + }) + test(function() { + // calling m.redraw synchronously from controller constructor should not + // trigger extra redraws + mock.requestAnimationFrame.$resolve() + + var root = mock.document.createElement("div") + var count = 0 + var sub = { + controller: function() { + m.redraw() + }, + view: function() { + count++ + return m("div") + } + } + var component = { + controller: function() {}, + view: function() { + return sub + } + } + m.mount(root, component) + + mock.requestAnimationFrame.$resolve() + + return count === 1 + }) + test(function() { + // calling m.redraw synchronously from controller constructor should not + // trigger extra redraws + mock.requestAnimationFrame.$resolve() + + var root = mock.document.createElement("div") + var count = 0 var subsub = { - controller: function(opts) { - this.onunload = function() { - unloaded2 = opts.key + controller: function() { + m.redraw() + }, + view: function() { + count++ + return m("div") + } + } + var sub = { + controller: function() {}, + view: function() { + return subsub + } + } + var component = { + controller: function() {}, + view: function() { + return sub + } + } + m.mount(root, component) + + mock.requestAnimationFrame.$resolve() + + return count === 1 + }) + test(function() { + // calling preventDefault from component's onunload should prevent route + // change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var sub = { + controller: function() { + this.onunload = function(e) { + if (testEnabled) e.preventDefault() } }, view: function() { return m("div") } } - m.mount(root, component) - - var firstBefore = root.childNodes[0] - - mock.requestAnimationFrame.$resolve() - - list.pop() - m.redraw(true) - - mock.requestAnimationFrame.$resolve() - - return unloaded1 === 3 && unloaded2 === 3 - }) - test(function() { - //calling m.redraw synchronously from controller constructor should not trigger extra redraws - mock.requestAnimationFrame.$resolve() - - var root = mock.document.createElement("div") - var count = 0 var component = { controller: function() {}, - view: function(ctrl) { + view: function() { return sub } } - var sub = { - controller: function(opts) { - m.redraw() + m.route(root, "/a", { + "/a": component, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) + test(function() { + // calling preventDefault from subcomponent's onunload should prevent + // route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var subsub = { + controller: function() { + this.onunload = function(e) { + if (testEnabled) e.preventDefault() + } }, view: function() { - count++ return m("div") } } - m.mount(root, component) - - mock.requestAnimationFrame.$resolve() - - return count === 1 - }) - test(function() { - //calling m.redraw synchronously from controller constructor should not trigger extra redraws - mock.requestAnimationFrame.$resolve() - - var root = mock.document.createElement("div") - var count = 0 - var component = { - controller: function() {}, - view: function(ctrl) { - return sub - } - } var sub = { - controller: function(opts) {}, + controller: function() {}, view: function() { return subsub } } - var subsub = { - controller: function(opts) { - m.redraw() - }, - view: function() { - count++ - return m("div") - } - } - m.mount(root, component) - - mock.requestAnimationFrame.$resolve() - - return count === 1 - }) - test(function() { - //calling preventDefault from component's onunload should prevent route change - mock.requestAnimationFrame.$resolve() - mock.location.search = "?" - - var root = mock.document.createElement("div") - var loaded = false - var testEnabled = true var component = { controller: function() {}, view: function() { return sub } } - var sub = { - controller: function(opts) { - controller = this - this.onunload = function(e) {if (testEnabled) e.preventDefault()} - }, - view: function() { - return m("div") - } - } m.route(root, "/a", { "/a": component, "/b": {controller: function() {loaded = true}, view: function() {}} }) - + mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() testEnabled = false - + return loaded === false }) test(function() { - //calling preventDefault from subcomponent's onunload should prevent route change + // calling preventDefault from non-curried component's onunload should + // prevent route change mock.requestAnimationFrame.$resolve() mock.location.search = "?" var root = mock.document.createElement("div") var loaded = false var testEnabled = true + var sub = { + controller: function() { + this.onunload = function(e) { + if (testEnabled) e.preventDefault() + } + }, + view: function() { + return m("div") + } + } var component = { controller: function() {}, view: function() { return sub } } - var sub = { - controller: function(opts) { + m.route(root, "/a", { + "/a": component, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) + test(function() { + // calling preventDefault from non-curried subcomponent's onunload + // should prevent route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var subsub = { + controller: function() { + this.onunload = function(e) { + if (testEnabled) e.preventDefault() + } }, + view: function() { + return m("div") + } + } + var sub = { + controller: function() {}, view: function() { return subsub } } - var subsub = { - controller: function(opts) { - controller = this - this.onunload = function(e) {if (testEnabled) e.preventDefault()} - }, - view: function() { - return m("div") - } - } - m.route(root, "/a", { - "/a": component, - "/b": {controller: function() {loaded = true}, view: function() {}} - }) - - mock.requestAnimationFrame.$resolve() - - m.route("/b") - - mock.requestAnimationFrame.$resolve() - testEnabled = false - - return loaded === false - }) - test(function() { - //calling preventDefault from non-curried component's onunload should prevent route change - mock.requestAnimationFrame.$resolve() - mock.location.search = "?" - - var root = mock.document.createElement("div") - var loaded = false - var testEnabled = true var component = { controller: function() {}, view: function() { return sub } } - var sub = { - controller: function(opts) { - controller = this - this.onunload = function(e) {if (testEnabled) e.preventDefault()} - }, - view: function() { - return m("div") - } - } m.route(root, "/a", { "/a": component, "/b": {controller: function() {loaded = true}, view: function() {}} }) - - mock.requestAnimationFrame.$resolve() - - m.route("/b") - - mock.requestAnimationFrame.$resolve() - testEnabled = false - - return loaded === false - }) - test(function() { - //calling preventDefault from non-curried subcomponent's onunload should prevent route change - mock.requestAnimationFrame.$resolve() - mock.location.search = "?" - var root = mock.document.createElement("div") - var loaded = false - var testEnabled = true - var component = { - controller: function() {}, - view: function() { - return sub - } - } - var sub = { - controller: function(opts) {}, - view: function() { - return subsub - } - } - var subsub = { - controller: function(opts) { - controller = this - this.onunload = function(e) {if (testEnabled) e.preventDefault()} - }, - view: function() { - return m("div") - } - } - m.route(root, "/a", { - "/a": component, - "/b": {controller: function() {loaded = true}, view: function() {}} - }) - mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() testEnabled = false - + return loaded === false }) test(function() { @@ -773,24 +835,6 @@ function testMithril(mock) { var root = mock.document.createElement("div") var count = 0 - var App = { - controller: function() {}, - view: function(ctrl) { - return m('.outer', [ - m('.inner', m.component(CommentList, { list: [1, 2, 3] })) - ]) - } - } - var CommentList = { - controller: function() {}, - view: function(ctrl, props) { - return m('.list', props.list.map(function(i) { - return m('.comment', [ - m.component(Reply, {key: i}) - ]) - })) - } - } var Reply = { controller: function() {}, view: function() { @@ -798,6 +842,24 @@ function testMithril(mock) { return m(".reply") } } + var CommentList = { + controller: function() {}, + view: function(ctrl, props) { + return m(".list", props.list.map(function(i) { + return m(".comment", [ + m.component(Reply, {key: i}) + ]) + })) + } + } + var App = { + controller: function() {}, + view: function() { + return m(".outer", [ + m(".inner", m.component(CommentList, { list: [1, 2, 3] })) + ]) + } + } m.mount(root, App) mock.requestAnimationFrame.$resolve() @@ -823,15 +885,15 @@ function testMithril(mock) { m.route(root, "/a", { "/a": { view: function () { - return m('.page-a', [ - m('h1'), m.component(subA, { x: 11 }) + return m(".page-a", [ + m("h1"), m.component(subA, { x: 11 }) ]) } }, "/b": { view: function() { - return m('.page-b', [ - m('h2'), m.component(subB, { y: 22 }) + return m(".page-b", [ + m("h2"), m.component(subB, { y: 22 }) ]) } } @@ -851,19 +913,20 @@ function testMithril(mock) { }) test(function() { var root = mock.document.createElement("div") - var component = {}, unloaded = false + var component = {} + var unloaded = false component.controller = function() { this.onunload = function() {unloaded = true} } component.view = function() {} m.mount(root, component) m.mount(root, {controller: function() {}, view: function() {}}) - + return unloaded === true }) test(function() { mock.requestAnimationFrame.$resolve() - + var root = mock.document.createElement("div") var initCount = 0 var component = {} @@ -873,26 +936,30 @@ function testMithril(mock) { }}) } m.mount(root, component) - + mock.requestAnimationFrame.$resolve() - + m.redraw() - + mock.requestAnimationFrame.$resolve() - - return initCount == 1 + + return initCount === 1 }) test(function() { var root = mock.document.createElement("div") - + var dom = mock.document.createElement("div") - + var show = true var component = { view: function() { return [ - m(".foo", {key: 1, config: test, onclick: function() {show = !show}}), + m(".foo", { + key: 1, + config: test, + onclick: function() {show = !show} + }), show ? m(".bar", {key: 2}) : null ] } @@ -905,20 +972,20 @@ function testMithril(mock) { } m.mount(root, component) - + mock.requestAnimationFrame.$resolve() - + show = false m.redraw() - + mock.requestAnimationFrame.$resolve() - + show = true m.redraw() - + mock.requestAnimationFrame.$resolve() - - return root.childNodes.length == 3 + + return root.childNodes.length === 3 }) test(function() { var root = mock.document.createElement("div") @@ -926,36 +993,36 @@ function testMithril(mock) { var testcomponent = { controller: function() {}, view: function() { - return m('div', 'component'); + return m("div", "component") } - }; + } var app = { - view: function(scope) { + view: function() { return show ? [ - m('h1', '1'), + m("h1", "1"), testcomponent ] : [ - m('h1', '2'), - ]; + m("h1", "2") + ] } - }; + } + + m.mount(root, app) - m.mount(root, app); - mock.requestAnimationFrame.$resolve() - + show = false m.redraw() - + mock.requestAnimationFrame.$resolve() - + show = true m.redraw() - + mock.requestAnimationFrame.$resolve() - - return root.childNodes.length == 2 + + return root.childNodes.length === 2 }) test(function() { // Components should not require a view @@ -964,7 +1031,7 @@ function testMithril(mock) { var Component = { view: function () { - return m('.comp') + return m(".comp") } } @@ -980,17 +1047,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return root.childNodes[0].nodeName == "DIV" + return root.childNodes[0].nodeName === "DIV" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/551 + // https://github.com/lhorie/mithril.js/issues/551 var root = mock.document.createElement("div") - var a = false, found = false, unloaded = false, redraws = 0 - var Root = { - view: function() { - return Comp - } - } + var a = false + var found = false + var unloaded = false + var redraws = 0 var Comp = { view: function() { redraws++ @@ -1005,29 +1070,34 @@ function testMithril(mock) { ]) }, config: function(el, init, ctx) { - if (!init) ctx.onunload = function() { - unloaded = true + if (!init) { + ctx.onunload = function() { + unloaded = true + } } } } - m.mount(root, Root) - - var target = root.childNodes[0].childNodes[0] - target.onclick({currentTarget: target}) - - mock.requestAnimationFrame.$resolve() - - return !unloaded && found.id === "a" && redraws == 3 - }) - test(function() { - //https://github.com/lhorie/mithril.js/issues/551 - var root = mock.document.createElement("div") - var a = false, found = false, unloaded = false, redraws = 0 var Root = { view: function() { return Comp } } + m.mount(root, Root) + + var target = root.childNodes[0].childNodes[0] + target.onclick({currentTarget: target}) + + mock.requestAnimationFrame.$resolve() + + return !unloaded && found.id === "a" && redraws === 3 + }) + test(function() { + // https://github.com/lhorie/mithril.js/issues/551 + var root = mock.document.createElement("div") + var a = false + var found = false + var unloaded = false + var redraws = 0 var Comp = { view: function() { redraws++ @@ -1043,19 +1113,26 @@ function testMithril(mock) { ]) }, config: function(el, init, ctx) { - if (!init) ctx.onunload = function() { - unloaded = true + if (!init) { + ctx.onunload = function() { + unloaded = true + } } } } + var Root = { + view: function() { + return Comp + } + } m.mount(root, Root) - + var target = root.childNodes[0].childNodes[0] target.onclick({currentTarget: target}) - + mock.requestAnimationFrame.$resolve() - return !unloaded && found.id === "a" && redraws == 2 + return !unloaded && found.id === "a" && redraws === 2 }) test(function() { var root = mock.document.createElement("div") @@ -1066,67 +1143,63 @@ function testMithril(mock) { return m("div", {onclick: function() {m.redraw(true)}}) } } - + m.mount(root, Root) - + var target = root.childNodes[0] target.onclick({currentTarget: target}) - + mock.requestAnimationFrame.$resolve() - - return redraws == 3 + + return redraws === 3 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/555 + // https://github.com/lhorie/mithril.js/issues/555 var root = mock.document.createElement("div") var MyComponent = { controller: function(args) { - this.name = args.name; + this.name = args.name }, view: function(ctrl) { - return m('div', ctrl.name); + return m("div", ctrl.name) } } var FooPage = { view: function() { - return m('div', [ - m('a[href=/]', {config: m.route}, 'foo'), - m('a[href=/bar]', {config: m.route}, 'bar'), - m.component(MyComponent, {name: 'Jane'}) - ]); + return m("div", [ + m("a[href=/]", {config: m.route}, "foo"), + m("a[href=/bar]", {config: m.route}, "bar"), + m.component(MyComponent, {name: "Jane"}) + ]) } - }; + } var BarPage = { view: function() { - return m('div', [ - m('a[href=/]', {config: m.route}, 'foo'), - m('a[href=/bar]', {config: m.route}, 'bar'), - m.component(MyComponent, {name: 'Bob'}) - ]); + return m("div", [ + m("a[href=/]", {config: m.route}, "foo"), + m("a[href=/bar]", {config: m.route}, "bar"), + m.component(MyComponent, {name: "Bob"}) + ]) } - }; - m.route(root, '/', { - '/': FooPage, - '/bar': BarPage + } + m.route(root, "/", { + "/": FooPage, + "/bar": BarPage }) - + mock.requestAnimationFrame.$resolve() - + m.route("/bar") - + mock.requestAnimationFrame.$resolve() - - return root.childNodes[0].childNodes[2].childNodes[0].nodeValue == "Bob" + + return root.childNodes[0].childNodes[2] + .childNodes[0].nodeValue === "Bob" }) test(function() { var root = mock.document.createElement("div") - var redraws = 0, data - var Root = { - view: function() { - return Comp - } - } - + var redraws = 0 + var data var Comp = { controller: function() { this.foo = m.request({method: "GET", url: "/foo"}) @@ -1137,24 +1210,48 @@ function testMithril(mock) { return m("div") } } - + var Root = { + view: function() { + return Comp + } + } + m.mount(root, Root) - + mock.requestAnimationFrame.$resolve() mock.XMLHttpRequest.$instances.pop().onreadystatechange() - + mock.requestAnimationFrame.$resolve() m.mount(root, null) mock.requestAnimationFrame.$resolve() - - return redraws == 1 && data.url == "/foo" + + return redraws === 1 && data.url === "/foo" }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" var root = mock.document.createElement("div") - var redraws1 = 0, redraws2 = 0 + var redraws1 = 0 + var redraws2 = 0 + var Comp2 = { + controller: function() { + this.bar = m.request({method: "GET", url: "/bar"}) + }, + view: function() { + redraws2++ + return m("div") + } + } + var Comp1 = { + controller: function() { + this.foo = m.request({method: "GET", url: "/foo"}) + }, + view: function() { + redraws1++ + return m("div") + } + } var Root = { view: function() { return m("div", [ @@ -1163,12 +1260,30 @@ function testMithril(mock) { ]) } } - + + m.mount(root, Root) + + mock.requestAnimationFrame.$resolve() + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + + mock.requestAnimationFrame.$resolve() + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + + mock.requestAnimationFrame.$resolve() + m.mount(root, null) + mock.requestAnimationFrame.$resolve() + + return redraws1 === 1 && redraws2 === 1 + }) + test(function() { + var root = mock.document.createElement("div") + var redraws1 = 0 + var redraws2 = 0 var Comp1 = { controller: function() { this.foo = m.request({method: "GET", url: "/foo"}) }, - view: function(ctrl) { + view: function() { redraws1++ return m("div") } @@ -1177,29 +1292,11 @@ function testMithril(mock) { controller: function() { this.bar = m.request({method: "GET", url: "/bar"}) }, - view: function(ctrl) { + view: function() { redraws2++ return m("div") } } - - m.mount(root, Root) - - mock.requestAnimationFrame.$resolve() - mock.XMLHttpRequest.$instances.pop().onreadystatechange() - - mock.requestAnimationFrame.$resolve() - mock.XMLHttpRequest.$instances.pop().onreadystatechange() - - mock.requestAnimationFrame.$resolve() - m.mount(root, null) - mock.requestAnimationFrame.$resolve() - - return redraws1 == 1 && redraws2 == 1 - }) - test(function() { - var root = mock.document.createElement("div") - var redraws1 = 0, redraws2 = 0 var Root1 = { view: function() { return Comp1 @@ -1210,57 +1307,34 @@ function testMithril(mock) { return Comp2 } } - - var Comp1 = { - controller: function() { - this.foo = m.request({method: "GET", url: "/foo"}) - }, - view: function(ctrl) { - redraws1++ - return m("div") - } - } - var Comp2 = { - controller: function() { - this.bar = m.request({method: "GET", url: "/bar"}) - }, - view: function(ctrl) { - redraws2++ - return m("div") - } - } - + + m.route(root, "/", { "/": Root1, "/root2": Root2 }) - + mock.requestAnimationFrame.$resolve() mock.XMLHttpRequest.$instances.pop().onreadystatechange() - + m.route("/root2") - - + + mock.requestAnimationFrame.$resolve() mock.XMLHttpRequest.$instances.pop().onreadystatechange() - + mock.requestAnimationFrame.$resolve() m.mount(root, null) mock.requestAnimationFrame.$resolve() - - return redraws1 == 1 && redraws2 == 1 + + return redraws1 === 1 && redraws2 === 1 }) test(function() { var root = mock.document.createElement("div") - + var cond = true - var controller1 = null, controller2 = null - var Root = { - view: function() { - return cond ? Comp1 : Comp2 - } - } - + var controller1 = null + var controller2 = null var Comp1 = { view: function(ctrl) { controller1 = ctrl @@ -1273,116 +1347,119 @@ function testMithril(mock) { return m("div") } } - - m.mount(root, Root) - - mock.requestAnimationFrame.$resolve() - - cond = false - m.redraw(true) - - mock.requestAnimationFrame.$resolve() - - return controller1 !== controller2 - }) - test(function() { - var root = mock.document.createElement("div") - - var cond = true - var unloaded = false var Root = { view: function() { return cond ? Comp1 : Comp2 } } - + + m.mount(root, Root) + + mock.requestAnimationFrame.$resolve() + + cond = false + m.redraw(true) + + mock.requestAnimationFrame.$resolve() + + return controller1 !== controller2 + }) + test(function() { + var root = mock.document.createElement("div") + + var cond = true + var unloaded = false var Comp1 = { - view: function(ctrl) { + view: function() { return m("div", {config: function(el, init, ctx) { ctx.onunload = function() {unloaded = true} }}) } } var Comp2 = { - view: function(ctrl) { + view: function() { return m("div") } } - - m.mount(root, Root) - - mock.requestAnimationFrame.$resolve() - - cond = false - m.redraw(true) - - mock.requestAnimationFrame.$resolve() - - return unloaded - }) - test(function() { - var root = mock.document.createElement("div") - - var cond = true - var initialized = null var Root = { view: function() { return cond ? Comp1 : Comp2 } } - + + m.mount(root, Root) + + mock.requestAnimationFrame.$resolve() + + cond = false + m.redraw(true) + + mock.requestAnimationFrame.$resolve() + + return unloaded + }) + test(function() { + var root = mock.document.createElement("div") + + var cond = true + var initialized = null var Comp1 = { - view: function(ctrl) { + view: function() { return m("div") } } var Comp2 = { - view: function(ctrl) { + view: function() { return m("div", {config: function(el, init) { initialized = init }}) } } - + var Root = { + view: function() { + return cond ? Comp1 : Comp2 + } + } + m.mount(root, Root) - + mock.requestAnimationFrame.$resolve() - + cond = false m.redraw(true) - + mock.requestAnimationFrame.$resolve() - + return initialized === false }) test(function() { var root = mock.document.createElement("div") var el - var FooPage = { - view: function(ctrl) { - return m('div', [ - m('button', {onclick: function() { - ctrl.bar = true; - m.redraw(true); - el = root.childNodes[0].childNodes[1] - }}, 'click me'), - ctrl.bar ? m.component(BarComponent) : '' - ]); - } - }; var BarComponent = { view: function() { - return m('#bar', 'test'); + return m("#bar", "test") } - }; - m.mount(root, FooPage); - + } + var FooPage = { + view: function(ctrl) { + return m("div", [ + m("button", {onclick: function() { + ctrl.bar = true + m.redraw(true) + el = root.childNodes[0].childNodes[1] + }}, "click me"), + ctrl.bar ? m.component(BarComponent) : "" + ]) + } + } + m.mount(root, FooPage) + root.childNodes[0].childNodes[0].onclick({}) - - return el.id == "bar" + + return el.id === "bar" }) - - //m.withAttr + + // m.withAttr test(function() { var value var handler = m.withAttr("test", function(data) {value = data}) @@ -1390,10 +1467,10 @@ function testMithril(mock) { return value === "foo" }) - //m.trust + // m.trust test(function() {return m.trust("test").valueOf() === "test"}) - //m.render + // m.render test(function() { var root = mock.document.createElement("div") m.render(root, "test") @@ -1401,9 +1478,9 @@ function testMithril(mock) { }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", {"class": "a"})) + m.render(root, m("div", {class: "a"})) var elementBefore = root.childNodes[0] - m.render(root, m("div", {"class": "b"})) + m.render(root, m("div", {class: "b"})) var elementAfter = root.childNodes[0] return elementBefore === elementAfter }) @@ -1442,13 +1519,14 @@ function testMithril(mock) { test(function() { var root = mock.document.createElement("div") m.render(root, m("div", [undefined])) - return root.childNodes[0].childNodes[0].nodeValue == "" + return root.childNodes[0].childNodes[0].nodeValue === "" }) test(function() { var root = mock.document.createElement("div") m.render(root, m("svg", [m("g")])) var g = root.childNodes[0].childNodes[0] - return g.nodeName === "G" && g.namespaceURI == "http://www.w3.org/2000/svg" + return g.nodeName === "G" && + g.namespaceURI === "http://www.w3.org/2000/svg" }) test(function() { var root = mock.document.createElement("div") @@ -1459,25 +1537,25 @@ function testMithril(mock) { var root = mock.document.createElement("div") m.render(root, m("div.classname", [m("a", {href: "/first"})])) m.render(root, m("div", [m("a", {href: "/second"})])) - return root.childNodes[0].childNodes.length == 1 + return root.childNodes[0].childNodes.length === 1 }) test(function() { var root = mock.document.createElement("div") m.render(root, m("ul", [m("li")])) m.render(root, m("ul", [m("li"), undefined])) - return root.childNodes[0].childNodes[1].nodeValue == "" + return root.childNodes[0].childNodes[1].nodeValue === "" }) test(function() { var root = mock.document.createElement("div") m.render(root, m("ul", [m("li"), m("li")])) m.render(root, m("ul", [m("li"), undefined])) - return root.childNodes[0].childNodes[1].nodeValue == "" + return root.childNodes[0].childNodes[1].nodeValue === "" }) test(function() { var root = mock.document.createElement("div") m.render(root, m("ul", [m("li")])) m.render(root, m("ul", [undefined])) - return root.childNodes[0].childNodes[0].nodeValue == "" + return root.childNodes[0].childNodes[0].nodeValue === "" }) test(function() { var root = mock.document.createElement("div") @@ -1489,13 +1567,15 @@ function testMithril(mock) { var root = mock.document.createElement("div") m.render(root, m("ul", [m("li")])) m.render(root, m("ul", [{tag: "b", attrs: {}}])) - return root.childNodes[0].childNodes[0].nodeName == "B" + return root.childNodes[0].childNodes[0].nodeName === "B" }) test(function() { + /* eslint-disable no-new-wrappers */ var root = mock.document.createElement("div") m.render(root, m("ul", [m("li")])) m.render(root, m("ul", [{tag: new String("b"), attrs: {}}])) - return root.childNodes[0].childNodes[0].nodeName == "B" + return root.childNodes[0].childNodes[0].nodeName === "B" + /* eslint-enable no-new-wrappers */ }) test(function() { var root = mock.document.createElement("div") @@ -1504,49 +1584,49 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].childNodes[0].nodeName === "A" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/43 + // https://github.com/lhorie/mithril.js/issues/43 var root = mock.document.createElement("div") m.render(root, m("a", {config: m.route}, "test")) m.render(root, m("a", {config: m.route}, "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/44 (1) + // https://github.com/lhorie/mithril.js/issues/44 (1) var root = mock.document.createElement("div") m.render(root, m("#foo", [null, m("#bar")])) m.render(root, m("#foo", ["test", m("#bar")])) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/44 (2) + // https://github.com/lhorie/mithril.js/issues/44 (2) var root = mock.document.createElement("div") m.render(root, m("#foo", [null, m("#bar")])) m.render(root, m("#foo", [m("div"), m("#bar")])) return root.childNodes[0].childNodes[0].nodeName === "DIV" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/44 (3) + // https://github.com/lhorie/mithril.js/issues/44 (3) var root = mock.document.createElement("div") m.render(root, m("#foo", ["test", m("#bar")])) m.render(root, m("#foo", [m("div"), m("#bar")])) return root.childNodes[0].childNodes[0].nodeName === "DIV" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/44 (4) + // https://github.com/lhorie/mithril.js/issues/44 (4) var root = mock.document.createElement("div") m.render(root, m("#foo", [m("div"), m("#bar")])) m.render(root, m("#foo", ["test", m("#bar")])) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/44 (5) + // https://github.com/lhorie/mithril.js/issues/44 (5) var root = mock.document.createElement("div") m.render(root, m("#foo", [m("#bar")])) m.render(root, m("#foo", [m("#bar"), [m("#baz")]])) return root.childNodes[0].childNodes[1].id === "baz" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/48 + // https://github.com/lhorie/mithril.js/issues/48 var root = mock.document m.render(root, m("html", [m("#foo")])) var result = root.childNodes[0].childNodes[0].id === "foo" @@ -1554,87 +1634,120 @@ function testMithril(mock) { return result }) test(function() { - //https://github.com/lhorie/mithril.js/issues/49 + // https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a", "test")) m.render(root, m("a.foo", "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/49 + // https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a.foo", "test")) m.render(root, m("a", "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/49 + // https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a.foo", "test")) m.render(root, m("a", "test1")) return root.childNodes[0].childNodes[0].nodeValue === "test1" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/49 + // https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a", "test")) m.render(root, m("a", "test1")) return root.childNodes[0].childNodes[0].nodeValue === "test1" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/50 + // https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], m("#bar")])) return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "b" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/50 + // https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], m("#bar")])) - m.render(root, m("#foo", [[m("div", "a"), m("div", "b"), m("div", "c")], m("#bar")])) + m.render(root, m("#foo", [ + [m("div", "a"), m("div", "b"), m("div", "c")], + m("#bar") + ])) return root.childNodes[0].childNodes[2].childNodes[0].nodeValue === "c" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/50 + // https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") - m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], [m("div", "c"), m("div", "d")], m("#bar")])) - return root.childNodes[0].childNodes[3].childNodes[0].nodeValue === "d" && root.childNodes[0].childNodes[4].id === "bar" + m.render(root, m("#foo", [ + [m("div", "a"), m("div", "b")], + [m("div", "c"), m("div", "d")], + m("#bar") + ])) + var children = root.childNodes[0] + return children.childNodes[3].childNodes[0].nodeValue === "d" && + children.childNodes[4].id === "bar" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/50 + // https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], "test"])) - return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "b" && root.childNodes[0].childNodes[2].nodeValue === "test" + var children = root.childNodes[0] + return children.childNodes[1].childNodes[0].nodeValue === "b" && + children.childNodes[2].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/50 + // https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [["a", "b"], "test"])) - return root.childNodes[0].childNodes[1].nodeValue === "b" && root.childNodes[0].childNodes[2].nodeValue === "test" + return root.childNodes[0].childNodes[1].nodeValue === "b" && + root.childNodes[0].childNodes[2].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/51 + // https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) - m.render(root, m("main", [m("button"), m("article", [m("span"), m("nav")])])) - return root.childNodes[0].childNodes[1].childNodes[0].nodeName === "SPAN" + m.render(root, m("main", [ + m("button"), + m("article", [m("section"), m("nav")]) + ])) + m.render(root, m("main", [ + m("button"), + m("article", [m("span"), m("nav")]) + ])) + return root.childNodes[0].childNodes[1] + .childNodes[0].nodeName === "SPAN" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/51 + // https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) - m.render(root, m("main", [m("button"), m("article", ["test", m("nav")])])) - return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "test" + m.render(root, m("main", [ + m("button"), + m("article", [m("section"), m("nav")]) + ])) + m.render(root, m("main", [ + m("button"), + m("article", ["test", m("nav")]) + ])) + return root.childNodes[0].childNodes[1] + .childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/51 + // https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) - m.render(root, m("main", [m("button"), m("article", [m.trust("test"), m("nav")])])) - return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "test" + m.render(root, m("main", [ + m("button"), + m("article", [m("section"), m("nav")]) + ])) + m.render(root, m("main", [ + m("button"), + m("article", [m.trust("test"), m("nav")]) + ])) + return root.childNodes[0].childNodes[1] + .childNodes[0].nodeValue === "test" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/55 + // https://github.com/lhorie/mithril.js/issues/55 var root = mock.document.createElement("div") m.render(root, m("#a")) var elementBefore = root.childNodes[0] @@ -1643,17 +1756,17 @@ function testMithril(mock) { return elementBefore !== elementAfter }) test(function() { - //https://github.com/lhorie/mithril.js/issues/56 + // https://github.com/lhorie/mithril.js/issues/56 var root = mock.document.createElement("div") m.render(root, [null, "foo"]) m.render(root, ["bar"]) - return root.childNodes.length == 1 + return root.childNodes.length === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/56 + // https://github.com/lhorie/mithril.js/issues/56 var root = mock.document.createElement("div") m.render(root, m("div", "foo")) - return root.childNodes.length == 1 + return root.childNodes.length === 1 }) test(function() { var root = mock.document.createElement("div") @@ -1671,10 +1784,13 @@ function testMithril(mock) { m.render(root, m("div", [undefined, m("ul")])) var valueAfter1 = root.childNodes[0].childNodes[0].nodeValue var valueAfter2 = root.childNodes[0].childNodes[1].nodeName - return valueBefore1 === "UL" && valueAfter1 === "" && valueBefore2 === "" && valueAfter2 === "UL" + return valueBefore1 === "UL" && + valueAfter1 === "" && + valueBefore2 === "" && + valueAfter2 === "UL" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/79 + // https://github.com/lhorie/mithril.js/issues/79 var root = mock.document.createElement("div") m.render(root, m("div", {style: {background: "red"}})) var valueBefore = root.childNodes[0].style.background @@ -1696,218 +1812,328 @@ function testMithril(mock) { return valueBefore === "red" && valueAfter === undefined }) test(function() { - //https://github.com/lhorie/mithril.js/issues/87 + // https://github.com/lhorie/mithril.js/issues/87 var root = mock.document.createElement("div") m.render(root, m("div", [[m("a"), m("a")], m("button")])) m.render(root, m("div", [[m("a")], m("button")])) - return root.childNodes[0].childNodes.length == 2 && root.childNodes[0].childNodes[1].nodeName == "BUTTON" + return root.childNodes[0].childNodes.length === 2 && + root.childNodes[0].childNodes[1].nodeName === "BUTTON" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/87 + // https://github.com/lhorie/mithril.js/issues/87 var root = mock.document.createElement("div") m.render(root, m("div", [m("a"), m("b"), m("button")])) m.render(root, m("div", [m("a"), m("button")])) - return root.childNodes[0].childNodes.length == 2 && root.childNodes[0].childNodes[1].nodeName == "BUTTON" + return root.childNodes[0].childNodes.length === 2 && + root.childNodes[0].childNodes[1].nodeName === "BUTTON" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/99 + // https://github.com/lhorie/mithril.js/issues/99 var root = mock.document.createElement("div") m.render(root, m("div", [m("img"), m("h1")])) m.render(root, m("div", [m("a")])) - return root.childNodes[0].childNodes.length == 1 && root.childNodes[0].childNodes[0].nodeName == "A" + return root.childNodes[0].childNodes.length === 1 && + root.childNodes[0].childNodes[0].nodeName === "A" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", "b", "c", "d"])) m.render(root, m("div", [["d", "e"]])) var children = root.childNodes[0].childNodes - return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 2 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", [["a", "b", "c", "d"]])) m.render(root, m("div", ["d", "e"])) var children = root.childNodes[0].childNodes - return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 2 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["x", [["a"], "b", "c", "d"]])) m.render(root, m("div", ["d", ["e"]])) var children = root.childNodes[0].childNodes - return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 2 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["b"])) m.render(root, m("div", [["e"]])) var children = root.childNodes[0].childNodes - return children.length == 1 && children[0].nodeValue == "e" + return children.length === 1 && children[0].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", ["b"]])) m.render(root, m("div", ["d", [["e"]]])) var children = root.childNodes[0].childNodes - return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 2 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", [["b"]]])) m.render(root, m("div", ["d", ["e"]])) var children = root.childNodes[0].childNodes - return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 2 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/120 + // https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", [["b"], "c"]])) m.render(root, m("div", ["d", [[["e"]], "x"]])) var children = root.childNodes[0].childNodes - return children.length == 3 && children[0].nodeValue == "d" && children[1].nodeValue == "e" + return children.length === 3 && + children[0].nodeValue === "d" && + children[1].nodeValue === "e" }) test(function() { var root = mock.document.createElement("div") - + var success = false - m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data = 1}})) - m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data === 1}})) + m.render(root, m("div", { + config: function(elem, isInitialized, ctx) { ctx.data = 1 } + })) + m.render(root, m("div", { + config: function(elem, isInitialized, ctx) { + success = ctx.data === 1 + } + })) return success }) test(function() { var root = mock.document.createElement("div") - var index = 0; - var success = true; - var statefulConfig = function(elem, isInitialized, ctx) {ctx.data = index++} - var node = m("div", {config: statefulConfig}); - m.render(root, [node, node]); + var index = 0 + var success = true + var statefulConfig = function(elem, isInitialized, ctx) { + ctx.data = index++ + } + var node = m("div", {config: statefulConfig}) + m.render(root, [node, node]) - index = 0; + index = 0 var checkConfig = function(elem, isInitialized, ctx) { success = success && (ctx.data === index++) } - node = m("div", {config: checkConfig}); - m.render(root, [node, node]); - return success; + node = m("div", {config: checkConfig}) + m.render(root, [node, node]) + return success }) test(function() { var root = mock.document.createElement("div") var parent m.render(root, m("div", m("a", { - config: function(el) {parent = el.parentNode.parentNode} - }))); + config: function(el) { parent = el.parentNode.parentNode } + }))) return parent === root }) test(function() { var root = mock.document.createElement("div") var count = 0 m.render(root, m("div", m("a", { - config: function(el) { + config: function() { var island = mock.document.createElement("div") count++ - if (count > 2) throw "too much recursion..." + if (count > 2) throw new Error("too much recursion...") m.render(island, m("div")) } - }))); - return count == 1 + }))) + return count === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/129 + // https://github.com/lhorie/mithril.js/issues/129 var root = mock.document.createElement("div") - m.render(root, m("div", [["foo", "bar"], ["foo", "bar"], ["foo", "bar"]])); - m.render(root, m("div", ["asdf", "asdf2", "asdf3"])); + m.render(root, m("div", [ + ["foo", "bar"], + ["foo", "bar"], + ["foo", "bar"] + ])) + m.render(root, m("div", ["asdf", "asdf2", "asdf3"])) return true }) test(function() { - //https://github.com/lhorie/mithril.js/issues/98 - //insert at beginning + // https://github.com/lhorie/mithril.js/issues/98 + // insert at beginning var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) + m.render(root, [ + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3) + ]) var firstBefore = root.childNodes[0] - m.render(root, [m("a", {key: 4}, 4), m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) + m.render(root, [ + m("a", {key: 4}, 4), + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3) + ]) var firstAfter = root.childNodes[1] - return firstBefore == firstAfter && root.childNodes[0].childNodes[0].nodeValue == "4" && root.childNodes.length == 4 + return firstBefore === firstAfter && + root.childNodes[0].childNodes[0].nodeValue === "4" && + root.childNodes.length === 4 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/98 + // https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) + m.render(root, [ + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3) + ]) var firstBefore = root.childNodes[0] - m.render(root, [m("a", {key: 4}, 4), m("a", {key: 1}, 1), m("a", {key: 2}, 2)]) + m.render(root, [ + m("a", {key: 4}, 4), + m("a", {key: 1}, 1), + m("a", {key: 2}, 2) + ]) var firstAfter = root.childNodes[1] - return firstBefore == firstAfter && root.childNodes[0].childNodes[0].nodeValue == 4 && root.childNodes.length == 3 + return firstBefore === firstAfter && + root.childNodes[0].childNodes[0].nodeValue === "4" && + root.childNodes.length === 3 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/98 + // https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) + m.render(root, [ + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3) + ]) var firstBefore = root.childNodes[1] - m.render(root, [m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4)]) + m.render(root, [ + m("a", {key: 2}, 2), + m("a", {key: 3}, 3), + m("a", {key: 4}, 4) + ]) var firstAfter = root.childNodes[0] - return firstBefore == firstAfter && root.childNodes[0].childNodes[0].nodeValue === "2" && root.childNodes.length === 3 + return firstBefore === firstAfter && + root.childNodes[0].childNodes[0].nodeValue === "2" && + root.childNodes.length === 3 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/98 + // https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4), m("a", {key: 5}, 5)]) + m.render(root, [ + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3), + m("a", {key: 4}, 4), + m("a", {key: 5}, 5) + ]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var fourthBefore = root.childNodes[3] - m.render(root, [m("a", {key: 4}, 4), m("a", {key: 10}, 10), m("a", {key: 1}, 1), m("a", {key: 2}, 2)]) + m.render(root, [ + m("a", {key: 4}, 4), + m("a", {key: 10}, 10), + m("a", {key: 1}, 1), + m("a", {key: 2}, 2) + ]) var firstAfter = root.childNodes[2] var secondAfter = root.childNodes[3] var fourthAfter = root.childNodes[0] - return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].childNodes[0].nodeValue == "10" && root.childNodes.length === 4 + return firstBefore === firstAfter && + secondBefore === secondAfter && + fourthBefore === fourthAfter && + root.childNodes[1].childNodes[0].nodeValue === "10" && + root.childNodes.length === 4 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/98 + // https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4), m("a", {key: 5}, 5)]) + m.render(root, [ + m("a", {key: 1}, 1), + m("a", {key: 2}, 2), + m("a", {key: 3}, 3), + m("a", {key: 4}, 4), + m("a", {key: 5}, 5) + ]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var fourthBefore = root.childNodes[3] - m.render(root, [m("a", {key: 4}, 4), m("a", {key: 10}, 10), m("a", {key: 2}, 2), m("a", {key: 1}, 1), m("a", {key: 6}, 6), m("a", {key: 7}, 7)]) + m.render(root, [ + m("a", {key: 4}, 4), + m("a", {key: 10}, 10), + m("a", {key: 2}, 2), + m("a", {key: 1}, 1), + m("a", {key: 6}, 6), + m("a", {key: 7}, 7) + ]) var firstAfter = root.childNodes[3] var secondAfter = root.childNodes[2] var fourthAfter = root.childNodes[0] - return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].childNodes[0].nodeValue == "10" && root.childNodes[4].childNodes[0].nodeValue == "6" && root.childNodes[5].childNodes[0].nodeValue == "7" && root.childNodes.length === 6 + return firstBefore === firstAfter && + secondBefore === secondAfter && + fourthBefore === fourthAfter && + root.childNodes[1].childNodes[0].nodeValue === "10" && + root.childNodes[4].childNodes[0].nodeValue === "6" && + root.childNodes[5].childNodes[0].nodeValue === "7" && + root.childNodes.length === 6 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/149 + // https://github.com/lhorie/mithril.js/issues/149 var root = mock.document.createElement("div") - m.render(root, [m("a", {key: 1}), m("a", {key: 2}), m("a"), m("a", {key: 4}), m("a", {key: 5})]) + m.render(root, [ + m("a", {key: 1}), + m("a", {key: 2}), + m("a"), + m("a", {key: 4}), + m("a", {key: 5}) + ]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var thirdBefore = root.childNodes[2] var fourthBefore = root.childNodes[3] var fifthBefore = root.childNodes[4] - m.render(root, [m("a", {key: 4}), m("a", {key: 5}), m("a"), m("a", {key: 1}), m("a", {key: 2})]) + m.render(root, [ + m("a", {key: 4}), + m("a", {key: 5}), + m("a"), + m("a", {key: 1}), + m("a", {key: 2}) + ]) var firstAfter = root.childNodes[3] var secondAfter = root.childNodes[4] var thirdAfter = root.childNodes[2] var fourthAfter = root.childNodes[0] var fifthAfter = root.childNodes[1] - return firstBefore === firstAfter && secondBefore === secondAfter && thirdBefore === thirdAfter && fourthBefore === fourthAfter && fifthBefore === fifthAfter + return firstBefore === firstAfter && + secondBefore === secondAfter && + thirdBefore === thirdAfter && + fourthBefore === fourthAfter && + fifthBefore === fifthAfter }) test(function() { - //https://github.com/lhorie/mithril.js/issues/246 - //insert at beginning with non-keyed in the middle + // https://github.com/lhorie/mithril.js/issues/246 + // insert at beginning with non-keyed in the middle var root = mock.document.createElement("div") m.render(root, [m("a", {key: 1}, 1)]) var firstBefore = root.childNodes[0] m.render(root, [m("a", {key: 2}, 2), m("br"), m("a", {key: 1}, 1)]) var firstAfter = root.childNodes[2] - return firstBefore == firstAfter && root.childNodes[0].childNodes[0].nodeValue == 2 && root.childNodes.length == 3 + return firstBefore === firstAfter && + root.childNodes[0].childNodes[0].nodeValue === "2" && + root.childNodes.length === 3 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/134 + // https://github.com/lhorie/mithril.js/issues/134 var root = mock.document.createElement("div") m.render(root, m("div", {contenteditable: true}, "test")) mock.document.activeElement = root.childNodes[0] @@ -1916,7 +2142,7 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].nodeValue === "test2" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/136 + // https://github.com/lhorie/mithril.js/issues/136 var root = mock.document.createElement("div") m.render(root, m("textarea", ["test"])) m.render(root, m("textarea", ["test1"])) @@ -1946,7 +2172,7 @@ function testMithril(mock) { } }) ]) - return unloaded == 0 + return unloaded === 0 }) test(function() { var root = mock.document.createElement("div") @@ -1962,9 +2188,12 @@ function testMithril(mock) { unloadedChild++ } } - var unloaded = 0 - m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) - m.render(root, m("main", {config: configParent}, m("a", {config: configChild}))) + m.render(root, m("div", { + config: configParent + }, m("a", {config: configChild}))) + m.render(root, m("main", { + config: configParent + }, m("a", {config: configChild}))) return unloadedParent === 1 && unloadedChild === 0 }) test(function() { @@ -1981,20 +2210,24 @@ function testMithril(mock) { unloadedChild++ } } - var unloaded = 0 - m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) - m.render(root, m("main", {config: configParent}, m("b", {config: configChild}))) + m.render(root, m("div", { + config: configParent + }, m("a", {config: configChild}))) + m.render(root, m("main", { + config: configParent + }, m("b", {config: configChild}))) return unloadedParent === 1 && unloadedChild === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/150 + // https://github.com/lhorie/mithril.js/issues/150 var root = mock.document.createElement("div") m.render(root, [m("a"), m("div")]) m.render(root, [[], m("div")]) - return root.childNodes.length == 1 && root.childNodes[0].nodeName == "DIV" + return root.childNodes.length === 1 && + root.childNodes[0].nodeName === "DIV" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/156 + // https://github.com/lhorie/mithril.js/issues/156 var root = mock.document.createElement("div") m.render(root, m("div", [ ["a", "b", "c", "d"].map(function() { @@ -2002,60 +2235,111 @@ function testMithril(mock) { }), m("span") ])) - return root.childNodes[0].childNodes[8].nodeName == "SPAN" + return root.childNodes[0].childNodes[8].nodeName === "SPAN" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/157 + // https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") - m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 2}, 2), m("li", {key: 4}, 4)])) - m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) - return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join("") == "012345" + m.render(root, m("ul", [ + m("li", {key: 0}, 0), + m("li", {key: 2}, 2), + m("li", {key: 4}, 4) + ])) + m.render(root, m("ul", [ + m("li", {key: 0}, 0), + m("li", {key: 1}, 1), + m("li", {key: 2}, 2), + m("li", {key: 3}, 3), + m("li", {key: 4}, 4), + m("li", {key: 5}, 5) + ])) + return root.childNodes[0].childNodes + .map(function(n) {return n.childNodes[0].nodeValue}) + .join("") === "012345" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/157 + // https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") m.render(root, m("input", {value: "a"})) m.render(root, m("input", {value: "aa"})) - return root.childNodes[0].childNodes.length == 0 + return root.childNodes[0].childNodes.length === 0 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/157 + // https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") - m.render(root, m("br", {"class": "a"})) - m.render(root, m("br", {"class": "aa"})) - return root.childNodes[0].childNodes.length == 0 + m.render(root, m("br", {class: "a"})) + m.render(root, m("br", {class: "aa"})) + return root.childNodes[0].childNodes.length === 0 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/194 + // https://github.com/lhorie/mithril.js/issues/194 var root = mock.document.createElement("div") - m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) - m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) - return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join("") == "01245" + m.render(root, m("ul", [ + m("li", {key: 0}, 0), + m("li", {key: 1}, 1), + m("li", {key: 2}, 2), + m("li", {key: 3}, 3), + m("li", {key: 4}, 4), + m("li", {key: 5}, 5) + ])) + m.render(root, m("ul", [ + m("li", {key: 0}, 0), + m("li", {key: 1}, 1), + m("li", {key: 2}, 2), + m("li", {key: 4}, 4), + m("li", {key: 5}, 5) + ])) + return root.childNodes[0].childNodes + .map(function(n) {return n.childNodes[0].nodeValue}) + .join("") === "01245" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/194 + // https://github.com/lhorie/mithril.js/issues/194 var root = mock.document.createElement("div") - m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) - m.render(root, m("ul", [m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5), m("li", {key: 6}, 6)])) - m.render(root, m("ul", [m("li", {key: 12}, 12), m("li", {key: 13}, 13), m("li", {key: 14}, 14), m("li", {key: 15}, 15), m("li", {key: 16}, 16), m("li", {key: 17}, 17)])) - return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join(",") == "12,13,14,15,16,17" + m.render(root, m("ul", [ + m("li", {key: 0}, 0), + m("li", {key: 1}, 1), + m("li", {key: 2}, 2), + m("li", {key: 3}, 3), + m("li", {key: 4}, 4), + m("li", {key: 5}, 5) + ])) + m.render(root, m("ul", [ + m("li", {key: 1}, 1), + m("li", {key: 2}, 2), + m("li", {key: 3}, 3), + m("li", {key: 4}, 4), + m("li", {key: 5}, 5), + m("li", {key: 6}, 6) + ])) + m.render(root, m("ul", [ + m("li", {key: 12}, 12), + m("li", {key: 13}, 13), + m("li", {key: 14}, 14), + m("li", {key: 15}, 15), + m("li", {key: 16}, 16), + m("li", {key: 17}, 17) + ])) + return root.childNodes[0].childNodes + .map(function(n) {return n.childNodes[0].nodeValue}) + .join(",") === "12,13,14,15,16,17" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/206 + // https://github.com/lhorie/mithril.js/issues/206 var root = mock.document.createElement("div") m.render(root, m("div", undefined)) m.render(root, m("div", [m("div")])) - return root.childNodes[0].childNodes.length == 1 + return root.childNodes[0].childNodes.length === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/206 + // https://github.com/lhorie/mithril.js/issues/206 var root = mock.document.createElement("div") m.render(root, m("div", null)) m.render(root, m("div", [m("div")])) - return root.childNodes[0].childNodes.length == 1 + return root.childNodes[0].childNodes.length === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/200 + // https://github.com/lhorie/mithril.js/issues/200 var root = mock.document.createElement("div") var unloaded1 = false @@ -2082,42 +2366,94 @@ function testMithril(mock) { var root = mock.document.createElement("div") m.render(root, [m("div.blue")]) m.render(root, [m("div.green", [m("div")]), m("div.blue")]) - return root.childNodes.length == 2 + return root.childNodes.length === 2 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/277 + // https://github.com/lhorie/mithril.js/issues/277 var root = mock.document.createElement("div") function Field() { - this.tag = "div"; - this.attrs = {}; - this.children = "hello"; + this.tag = "div" + this.attrs = {} + this.children = "hello" } m.render(root, new Field()) - return root.childNodes.length == 1 + return root.childNodes.length === 1 }) test(function() { var root = mock.document.createElement("div") m.render(root, {foo: 123}) - return root.childNodes.length == 0 + return root.childNodes.length === 0 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/299 + // https://github.com/lhorie/mithril.js/issues/299 var root = mock.document.createElement("div") - m.render(root, m("div", [m("div", {key: 1}, 1), m("div", {key: 2}, 2), m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key: 5}, 5), null, null, null, null, null, null, null, null, null, null])) - m.render(root, m("div", [null, null, m("div", {key: 3}, 3), null, null, m("div", {key: 6}, 6), null, null, m("div", {key: 9}, 9), null, null, m("div", {key: 12}, 12), null, null, m("div", {key: 15}, 15)])) - m.render(root, m("div", [m("div", {key: 1}, 1), m("div", {key: 2}, 2), m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key: 5}, 5), null, null, null, null, null, null, null, null, null, null])) - return root.childNodes[0].childNodes.map(function(c) {return c.childNodes ? c.childNodes[0].nodeValue: c.nodeValue}).slice(0, 5).join("") == "12345" + m.render(root, m("div", [ + m("div", {key: 1}, 1), + m("div", {key: 2}, 2), + m("div", {key: 3}, 3), + m("div", {key: 4}, 4), + m("div", {key: 5}, 5), + null, null, null, null, null, null, null, null, null, null + ])) + m.render(root, m("div", [ + null, null, + m("div", {key: 3}, 3), + null, null, + m("div", {key: 6}, 6), + null, null, + m("div", {key: 9}, 9), + null, null, + m("div", {key: 12}, 12), + null, null, + m("div", {key: 15}, 15) + ])) + m.render(root, m("div", [ + m("div", {key: 1}, 1), + m("div", {key: 2}, 2), + m("div", {key: 3}, 3), + m("div", {key: 4}, 4), + m("div", {key: 5}, 5), + null, null, null, null, null, null, null, null, null, null + ])) + return root.childNodes[0].childNodes + .map(function(c) { + return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue + }) + .slice(0, 5) + .join("") === "12345" }) test(function() { - //https://github.com/lhorie/mithril.js/issues/377 + // https://github.com/lhorie/mithril.js/issues/377 var root = mock.document.createElement("div") - m.render(root, m("div", [m("div", 1), m("div", 2), [m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key:5}, 5)], [m("div", {key: 6}, 6)]])) - m.render(root, m("div", [m("div", 1), null, [m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key:5}, 5)], [m("div", {key: 6}, 6)]])) - return root.childNodes[0].childNodes.map(function(c) {return c.childNodes ? c.childNodes[0].nodeValue: c.nodeValue}).join("") == "13456" + m.render(root, m("div", [ + m("div", 1), + m("div", 2), + [ + m("div", {key: 3}, 3), + m("div", {key: 4}, 4), + m("div", {key: 5}, 5) + ], + [m("div", {key: 6}, 6)] + ])) + m.render(root, m("div", [ + m("div", 1), + null, + [ + m("div", {key: 3}, 3), + m("div", {key: 4}, 4), + m("div", {key: 5}, 5) + ], + [m("div", {key: 6}, 6)] + ])) + return root.childNodes[0].childNodes + .map(function(c) { + return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue + }) + .join("") === "13456" }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [console.log()])) //don't throw in Firefox + m.render(root, m("div", [console.log()])) // don't throw in Firefox return true }) test(function() { @@ -2133,21 +2469,24 @@ function testMithril(mock) { m("#div-3", {key: 3}), m("#div-2", {key: 2}) ]) - return root.childNodes.map(function(node) {return node.id}).join() == "div-1,div-3,div-2" + return root.childNodes + .map(function(node) {return node.id}) + .join() === "div-1,div-3,div-2" }) test(function() { var root = mock.document.createElement("div") m.render(root, m("div", function() {})) - return root.childNodes[0].childNodes.length == 0 + return root.childNodes[0].childNodes.length === 0 }) test(function() { var root = mock.document.createElement("div") m.render(root, m("div", "foo", m("a"))) m.render(root, m("div", "test")) - return root.childNodes[0].childNodes.length == 1 + return root.childNodes[0].childNodes.length === 1 }) test(function() { - //if an element is preceded by a conditional, it should not lose its identity + // if an element is preceded by a conditional, it should not lose its + // identity var root = mock.document.createElement("div") m.render(root, m("div", [m("a"), m("input[autofocus]")])) var before = root.childNodes[0].childNodes[1] @@ -2156,44 +2495,104 @@ function testMithril(mock) { return before === after }) test(function() { - //unkeyed element should maintain identity if mixed w/ keyed elements and identity can be inferred + // unkeyed element should maintain identity if mixed w/ keyed elements + // and identity can be inferred var root = mock.document.createElement("div") - m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), m("a", {key: 3}), m("i")])) + m.render(root, m("div", [ + m("a", {key: 1}), + m("a", {key: 2}), + m("a", {key: 3}), + m("i") + ])) var before = root.childNodes[0].childNodes[3] - m.render(root, m("div", [m("b", {key: 3}), m("b", {key: 4}), m("i"), m("b", {key: 1})])) + m.render(root, m("div", [ + m("b", {key: 3}), + m("b", {key: 4}), + m("i"), + m("b", {key: 1}) + ])) var after = root.childNodes[0].childNodes[2] return before === after }) test(function() { - //unkeyed element should maintain identity if mixed w/ keyed elements and text nodes and identity can be inferred + // unkeyed element should maintain identity if mixed w/ keyed elements + // and text nodes and identity can be inferred var root = mock.document.createElement("div") - m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), "foo", m("a", {key: 3}), m("i")])) + m.render(root, m("div", [ + m("a", {key: 1}), + m("a", {key: 2}), + "foo", + m("a", {key: 3}), + m("i") + ])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), "bar", m("i"), m("a", {key: 1})])) + m.render(root, m("div", [ + m("a", {key: 3}), + m("a", {key: 4}), + "bar", + m("i"), + m("a", {key: 1}) + ])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), null, m("a", {key: 3}), m("i")])) + m.render(root, m("div", [ + m("a", {key: 1}), + m("a", {key: 2}), + null, + m("a", {key: 3}), + m("i") + ])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), null, m("i"), m("a", {key: 1})])) + m.render(root, m("div", [ + m("a", {key: 3}), + m("a", {key: 4}), + null, + m("i"), + m("a", {key: 1}) + ])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), undefined, m("a", {key: 3}), m("i")])) + m.render(root, m("div", [ + m("a", {key: 1}), + m("a", {key: 2}), + undefined, + m("a", {key: 3}), + m("i") + ])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), undefined, m("i"), m("a", {key: 1})])) + m.render(root, m("div", [ + m("a", {key: 3}), + m("a", {key: 4}), + undefined, + m("i"), + m("a", {key: 1}) + ])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), m.trust("a"), m("a", {key: 3}), m("i")])) + m.render(root, m("div", [ + m("a", {key: 1}), + m("a", {key: 2}), + m.trust("a"), + m("a", {key: 3}), + m("i") + ])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), m.trust("a"), m("i"), m("a", {key: 1})])) + m.render(root, m("div", [ + m("a", {key: 3}), + m("a", {key: 4}), + m.trust("a"), + m("i"), + m("a", {key: 1}) + ])) var after = root.childNodes[0].childNodes[3] return before === after }) @@ -2201,19 +2600,19 @@ function testMithril(mock) { var root = mock.document.createElement("div") var vdom = m("div.a", {class: undefined}) m.render(root, vdom) - return root.childNodes[0].class == "a" + return root.childNodes[0].class === "a" }) test(function() { var root = mock.document.createElement("div") m.render(root, m(".a", [1])) m.render(root, m(".a", [])) - return root.childNodes[0].childNodes.length == 0 + return root.childNodes[0].childNodes.length === 0 }) - //end m.render + // end m.render - //m.redraw + // m.redraw test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup var controller var root = mock.document.createElement("div") m.mount(root, { @@ -2228,65 +2627,69 @@ function testMithril(mock) { return valueBefore === "" && root.childNodes[0].nodeValue === "foo" }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup var count = 0 var root = mock.document.createElement("div") m.mount(root, { controller: function() {}, - view: function(ctrl) { + view: function() { count++ } }) - mock.requestAnimationFrame.$resolve() //teardown - m.redraw() //should run synchronously + mock.requestAnimationFrame.$resolve() // teardown + m.redraw() // should run synchronously - m.redraw() //rest should run asynchronously since they're spamming + m.redraw() // rest should run asynchronously since they're spamming m.redraw() m.redraw() - mock.requestAnimationFrame.$resolve() //teardown - + mock.requestAnimationFrame.$resolve() // teardown + return count === 3 }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup var count = 0 var root = mock.document.createElement("div") m.mount(root, { controller: function() {}, - view: function(ctrl) { + view: function() { count++ } }) - mock.requestAnimationFrame.$resolve() //teardown - m.redraw(true) //should run synchronously + mock.requestAnimationFrame.$resolve() // teardown + m.redraw(true) // should run synchronously - m.redraw(true) //forced to run synchronously + m.redraw(true) // forced to run synchronously m.redraw(true) m.redraw(true) - mock.requestAnimationFrame.$resolve() //teardown + mock.requestAnimationFrame.$resolve() // teardown return count === 5 }) - //m.route + // m.route test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/test1", { - "/test1": {controller: function() {}, view: function() {return "foo"}} + "/test1": { + controller: function() {}, + view: function() {return "foo"} + } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test1" && root.childNodes[0].nodeValue === "foo" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test1" && + root.childNodes[0].nodeValue === "foo" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.pathname = "/" var root = mock.document.createElement("div") @@ -2303,52 +2706,65 @@ function testMithril(mock) { } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.pathname == "/test2" && root.childNodes[0].nodeValue === "foo" && root.childNodes[1].href == "/test2" - - m.mount(root, null) //teardown - + + var result = mock.location.pathname === "/test2" && + root.childNodes[0].nodeValue === "foo" && + root.childNodes[1].href === "/test2" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.hash = "#" var root = mock.document.createElement("div") m.route.mode = "hash" m.route(root, "/test3", { - "/test3": {controller: function() {}, view: function() {return "foo"}} + "/test3": { + controller: function() {}, + view: function() {return "foo"} + } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.hash == "#/test3" && root.childNodes[0].nodeValue === "foo" - - m.mount(root, null) //teardown - + + var result = mock.location.hash === "#/test3" && + root.childNodes[0].nodeValue === "foo" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/test4/foo", { - "/test4/:test": {controller: function() {}, view: function() {return m.route.param("test")}} + "/test4/:test": { + controller: function() {}, + view: function() {return m.route.param("test")} + } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test4/foo" && root.childNodes[0].nodeValue === "foo" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test4/foo" && + root.childNodes[0].nodeValue === "foo" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" - var component = {controller: function() {}, view: function() {return m.route.param("test")}} + var component = { + controller: function() {}, + view: function() {return m.route.param("test")} + } var root = mock.document.createElement("div") m.route.mode = "search" @@ -2361,18 +2777,23 @@ function testMithril(mock) { m.route("/") var paramValueAfter = m.route.param("test") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/" && + paramValueBefore === "foo" && + paramValueAfter === undefined + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" - var component = {controller: function() {}, view: function() {return m.route.param("a1")}} + var component = { + controller: function() {}, + view: function() {return m.route.param("a1")} + } var root = mock.document.createElement("div") m.route.mode = "search" @@ -2385,19 +2806,24 @@ function testMithril(mock) { m.route("/") var paramValueAfter = m.route.param("a1") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/" && paramValueBefore === "foo" && paramValueAfter === undefined - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/" && + paramValueBefore === "foo" && + paramValueAfter === undefined + + m.mount(root, null) // teardown + return result }) test(function() { - //https://github.com/lhorie/mithril.js/issues/61 - mock.requestAnimationFrame.$resolve() //setup + // https://github.com/lhorie/mithril.js/issues/61 + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" - var component = {controller: function() {}, view: function() {return m.route.param("a1")}} + var component = { + controller: function() {}, + view: function() {return m.route.param("a1")} + } var root = mock.document.createElement("div") m.route.mode = "search" @@ -2410,15 +2836,16 @@ function testMithril(mock) { m.route("/") var routeValueAfter = m.route() mock.requestAnimationFrame.$resolve() - - var result = routeValueBefore === "/test7/foo" && routeValueAfter === "/" - - m.mount(root, null) //teardown - + + var result = routeValueBefore === "/test7/foo" && + routeValueAfter === "/" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2432,15 +2859,16 @@ function testMithril(mock) { } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test8/foo/SEP/bar/baz" && root.childNodes[0].nodeValue === "foo_bar/baz" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test8/foo/SEP/bar/baz" && + root.childNodes[0].nodeValue === "foo_bar/baz" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2454,15 +2882,16 @@ function testMithril(mock) { } }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test9/foo/bar/SEP/baz" && root.childNodes[0].nodeValue === "foo/bar_baz" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test9/foo/bar/SEP/baz" && + root.childNodes[0].nodeValue === "foo/bar_baz" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2476,136 +2905,180 @@ function testMithril(mock) { } }) mock.requestAnimationFrame.$resolve() - + var result = root.childNodes[0].nodeValue === "foo bar" - - m.mount(root, null) //teardown - + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {return "foo"}}, - "/test11": {controller: function() {}, view: function() {return "bar"}} + "/": { + controller: function() {}, + view: function() {return "foo"} + }, + "/test11": { + controller: function() {}, + view: function() {return "bar"} + } }) mock.requestAnimationFrame.$resolve() m.route("/test11/") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test11/" && root.childNodes[0].nodeValue === "bar" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test11/" && + root.childNodes[0].nodeValue === "bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {}}, - "/test12": {controller: function() {}, view: function() {}} + "/": { + controller: function() {}, + view: function() {} + }, + "/test12": { + controller: function() {}, + view: function() {} + } }) mock.requestAnimationFrame.$resolve() m.route("/test12?a=foo&b=bar") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test12?a=foo&b=bar" && m.route.param("a") == "foo" && m.route.param("b") == "bar" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test12?a=foo&b=bar" && + m.route.param("a") === "foo" && + m.route.param("b") === "bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {return "bar"}}, - "/test13/:test": {controller: function() {}, view: function() {return m.route.param("test")}} + "/": { + controller: function() {}, + view: function() {return "bar"} + }, + "/test13/:test": { + controller: function() {}, + view: function() {return m.route.param("test")} + } }) mock.requestAnimationFrame.$resolve() m.route("/test13/foo?test=bar") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test13/foo?test=bar" && root.childNodes[0].nodeValue === "foo" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test13/foo?test=bar" && + root.childNodes[0].nodeValue === "foo" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {return "bar"}}, - "/test14": {controller: function() {}, view: function() {return "foo"}} + "/": { + controller: function() {}, + view: function() {return "bar"} + }, + "/test14": { + controller: function() {}, + view: function() {return "foo"} + } }) mock.requestAnimationFrame.$resolve() m.route("/test14?test&test2=") mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test14?test&test2=" && m.route.param("test") === null && m.route.param("test2") === "" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test14?test&test2=" && + m.route.param("test") == null && + m.route.param("test2") === "" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {}}, - "/test12": {controller: function() {}, view: function() {}} + "/": { + controller: function() {}, + view: function() {} + }, + "/test12": { + controller: function() {}, + view: function() {} + } }) mock.requestAnimationFrame.$resolve() m.route("/test12", {a: "foo", b: "bar"}) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test12?a=foo&b=bar" && m.route.param("a") == "foo" && m.route.param("b") == "bar" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test12?a=foo&b=bar" && + m.route.param("a") === "foo" && + m.route.param("b") === "bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") var route1, route2 m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {route1 = m.route()}, view: function() {}}, - "/test13": {controller: function() {route2 = m.route()}, view: function() {}} + "/": { + controller: function() {route1 = m.route()}, + view: function() {} + }, + "/test13": { + controller: function() {route2 = m.route()}, + view: function() {} + } }) mock.requestAnimationFrame.$resolve() m.route("/test13") mock.requestAnimationFrame.$resolve() - - var result = route1 == "/" && route2 == "/test13" - - m.mount(root, null) //teardown - + + var result = route1 === "/" && route2 === "/test13" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2629,15 +3102,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test14") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2669,15 +3142,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test15") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2706,15 +3179,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test16") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2745,15 +3218,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test17") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2782,15 +3255,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test18") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2831,17 +3304,17 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test20") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" - + var root = mock.document.createElement("div") var unloaded = 0 m.route.mode = "search" @@ -2879,15 +3352,15 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test21") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2896,30 +3369,30 @@ function testMithril(mock) { "/foo": { controller: function() {}, view: function() { - return m("div", "foo"); + return m("div", "foo") } }, "/bar": { controller: function() {}, view: function() { - return m("div", "bar"); + return m("div", "bar") } - }, + } }) mock.requestAnimationFrame.$resolve() - var foo = root.childNodes[0].childNodes[0].nodeValue; + var foo = root.childNodes[0].childNodes[0].nodeValue m.route("/bar") mock.requestAnimationFrame.$resolve() - var bar = root.childNodes[0].childNodes[0].nodeValue; - + var bar = root.childNodes[0].childNodes[0].nodeValue + var result = (foo === "foo" && bar === "bar") - - m.mount(root, null) //teardown - + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2934,28 +3407,28 @@ function testMithril(mock) { "/foo1": { controller: function() {}, view: function() { - return m("div", m("a", {config: config}, "foo")); + return m("div", m("a", {config: config}, "foo")) } }, "/bar1": { controller: function() {}, view: function() { - return m("main", m("a", {config: config}, "foo")); + return m("main", m("a", {config: config}, "foo")) } - }, + } }) mock.requestAnimationFrame.$resolve() m.route("/bar1") mock.requestAnimationFrame.$resolve() - - var result = unloaded == 1 - - m.mount(root, null) //teardown - + + var result = unloaded === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2968,31 +3441,32 @@ function testMithril(mock) { m.redraw.strategy("none") }, view: function() { - return m("div"); + return m("div") } } }) mock.requestAnimationFrame.$resolve() - - var result = strategy == "all" && root.childNodes.length == 0 - - m.mount(root, null) //teardown - + + var result = strategy === "all" && root.childNodes.length === 0 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") - var strategy, count = 0 + var count = 0 + var strategy var config = function(el, init) {if (!init) count++} m.route.mode = "search" m.route(root, "/foo1", { "/foo1": { controller: function() {}, view: function() { - return m("div", {config: config}); + return m("div", {config: config}) } }, "/bar1": { @@ -3001,22 +3475,22 @@ function testMithril(mock) { m.redraw.strategy("redraw") }, view: function() { - return m("div", {config: config}); + return m("div", {config: config}) } - }, + } }) mock.requestAnimationFrame.$resolve() m.route("/bar1") mock.requestAnimationFrame.$resolve() - - var result = strategy == "all" && count == 1 - - m.mount(root, null) //teardown - + + var result = strategy === "all" && count === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3030,21 +3504,22 @@ function testMithril(mock) { strategy = m.redraw.strategy() ctrl.number++ m.redraw.strategy("none") - }}, ctrl.number); + }}, ctrl.number) } } }) root.childNodes[0].onclick({}) mock.requestAnimationFrame.$resolve() - - var result = strategy == "diff" && root.childNodes[0].childNodes[0].nodeValue == "1" - - m.mount(root, null) //teardown - + + var result = strategy === "diff" && + root.childNodes[0].childNodes[0].nodeValue === "1" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3054,24 +3529,24 @@ function testMithril(mock) { m.route(root, "/foo1", { "/foo1": { controller: function() {}, - view: function(ctrl) { + view: function() { return m("div", {config: config, onclick: function() { m.redraw.strategy("all") - }}); + }}) } } }) root.childNodes[0].onclick({}) mock.requestAnimationFrame.$resolve() - - var result = count == 2 - - m.mount(root, null) //teardown - + + var result = count === 2 + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3079,59 +3554,73 @@ function testMithril(mock) { m.route(root, "/foo+bar", { "/:arg": { controller: function() {value = m.route.param("arg")}, - view: function(ctrl) { + view: function() { return "" } } }) - var result = value == "foo+bar" - - m.mount(root, null) //teardown - + var result = value === "foo+bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {return "foo"}}, - "/test22": {controller: function() {}, view: function() {return "bar"}} + "/": { + controller: function() {}, + view: function() {return "foo"} + }, + "/test22": { + controller: function() {}, + view: function() {return "bar"} + } }) mock.requestAnimationFrame.$resolve() m.route(String("/test22/")) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test22/" && root.childNodes[0].nodeValue === "bar" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test22/" && + root.childNodes[0].nodeValue === "bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": {controller: function() {}, view: function() {return "foo"}}, - "/test23": {controller: function() {}, view: function() {return "bar"}} + "/": { + controller: function() {}, + view: function() {return "foo"} + }, + "/test23": { + controller: function() {}, + view: function() {return "bar"} + } }) mock.requestAnimationFrame.$resolve() - m.route(new String("/test23/")) + m.route(new String("/test23/")) // eslint-disable-line no-new-wrappers mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/test23/" && root.childNodes[0].nodeValue === "bar" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/test23/" && + root.childNodes[0].nodeValue === "bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3139,89 +3628,91 @@ function testMithril(mock) { m.route(root, String("/foo+bar"), { "/:arg": { controller: function() {value = m.route.param("arg")}, - view: function(ctrl) { + view: function() { return "" } } }) - var result = value == "foo+bar" - - m.mount(root, null) //teardown - + var result = value === "foo+bar" + + m.mount(root, null) // teardown + return result }) test(function() { - mock.requestAnimationFrame.$resolve() //setup + mock.requestAnimationFrame.$resolve() // setup mock.location.search = "?" var root = mock.document.createElement("div") var value + /* eslint-disable no-new-wrappers */ m.route(root, new String("/foo+bar"), { + /* eslint-enable no-new-wrappers */ "/:arg": { controller: function() {value = m.route.param("arg")}, - view: function(ctrl) { + view: function() { return "" } } }) - var result = value == "foo+bar" - - m.mount(root, null) //teardown - + var result = value === "foo+bar" + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") - + var a = {} a.controller = function() {m.route("/b")} a.view = function() {return "a"} var b = {} b.controller = function() {} - b.view = function(ctrl) {return "b"} + b.view = function() {return "b"} m.route(root, "/a", { "/a": a, "/b": b }) mock.requestAnimationFrame.$resolve() - - var result = root.childNodes[0].nodeValue == "b" - - m.mount(root, null) //teardown - + + var result = root.childNodes[0].nodeValue === "b" + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") - + var a = {} a.controller = function() { m.route("/b?foo=1", {foo: 2}) } a.view = function() {return "a"} - + var b = {} b.controller = function() {} b.view = function() {return "b"} m.route(root, "/", { "/": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - - var result = mock.location.search == "?/b?foo=2" - - m.mount(root, null) //teardown - + + var result = mock.location.search === "?/b?foo=2" + + m.mount(root, null) // teardown + return result }) @@ -3229,31 +3720,31 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() mock.location.search = "?" mock.history.$$length = 0 - + var root = mock.document.createElement("div") - + var a = {} a.controller = function() {} a.view = function() {return "a"} - + var b = {} b.controller = function() {} b.view = function() {return "b"} m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = mock.history.$$length == 1 - - m.mount(root, null) //teardown - + + var result = mock.history.$$length === 1 + + m.mount(root, null) // teardown + return result }) @@ -3261,75 +3752,75 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() mock.location.search = "?" mock.history.$$length = 0 - + var root = mock.document.createElement("div") - + var a = {} a.controller = function() {} a.view = function() {return "a"} - + var b = {} b.controller = function() {} b.view = function() {return "b"} m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/a") - + mock.requestAnimationFrame.$resolve() - - var result = mock.history.$$length == 0 - - m.mount(root, null) //teardown - + + var result = mock.history.$$length === 0 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { - return m("a", {config: function(el, init, ctx) { + return m("a", {config: function(el, init) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { @@ -3338,34 +3829,34 @@ function testMithril(mock) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { @@ -3374,69 +3865,69 @@ function testMithril(mock) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { - return m("a", {config: function(el, init, ctx) { + return m("a", {config: function(el, init) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { @@ -3445,34 +3936,34 @@ function testMithril(mock) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { @@ -3481,34 +3972,34 @@ function testMithril(mock) { if (!init) initCount++ }}) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = a.view m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { @@ -3517,7 +4008,7 @@ function testMithril(mock) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {} b.view = function() { @@ -3529,27 +4020,27 @@ function testMithril(mock) { m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { @@ -3558,7 +4049,7 @@ function testMithril(mock) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {} b.view = function() { @@ -3570,66 +4061,66 @@ function testMithril(mock) { m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { - return m("div", m("a", {config: function(el, init, ctx) { + return m("div", m("a", {config: function(el, init) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {} b.view = function() { - return m("section", m("a", {config: function(el, init, ctx) { + return m("section", m("a", {config: function(el, init) { if (!init) initCount++ }})) } m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { @@ -3638,7 +4129,7 @@ function testMithril(mock) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = function() { @@ -3650,27 +4141,27 @@ function testMithril(mock) { m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { @@ -3679,7 +4170,7 @@ function testMithril(mock) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = function() { @@ -3691,67 +4182,67 @@ function testMithril(mock) { m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 2 - - m.mount(root, null) //teardown - + + var result = initCount === 2 + + m.mount(root, null) // teardown + return result }) test(function() { mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {m.redraw.strategy("diff")} a.view = function() { - return m("div", m("a", {config: function(el, init, ctx) { + return m("div", m("a", {config: function(el, init) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = function() { - return m("section", m("a", {config: function(el, init, ctx) { + return m("section", m("a", {config: function(el, init) { if (!init) initCount++ }})) } m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - - var result = initCount == 1 - - m.mount(root, null) //teardown - + + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { - //retain flag should work inside component + // retain flag should work inside component mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") var initCount = 0 - + var a = {} a.controller = function() {} a.view = function() { @@ -3760,7 +4251,7 @@ function testMithril(mock) { if (!init) initCount++ }})) } - + var b = {} b.controller = function() {m.redraw.strategy("diff")} b.view = function() { @@ -3772,34 +4263,34 @@ function testMithril(mock) { m.route(root, "/a", { "/a": {view: function() {return m("div", a)}}, - "/b": {view: function() {return m("div", b)}}, + "/b": {view: function() {return m("div", b)}} }) mock.requestAnimationFrame.$resolve() - - m.route("/b") - - mock.requestAnimationFrame.$resolve() - var result = initCount == 1 - m.mount(root, null) //teardown - + m.route("/b") + + mock.requestAnimationFrame.$resolve() + var result = initCount === 1 + + m.mount(root, null) // teardown + return result }) test(function() { // https://github.com/lhorie/mithril.js/pull/571 mock.requestAnimationFrame.$resolve() mock.location.search = "?" - + var root = mock.document.createElement("div") - + var a = {} a.controller = function() {} a.view = function() { - return m("div", {config: function(elm, init, ctx) { + return m("div", {config: function(elm) { elm.childNodes[0].modified = true }}, m("div")) } - + var b = {} b.controller = function() {} b.view = function() { @@ -3808,47 +4299,57 @@ function testMithril(mock) { m.route(root, "/a", { "/a": a, - "/b": b, + "/b": b }) mock.requestAnimationFrame.$resolve() - + m.route("/b") - + mock.requestAnimationFrame.$resolve() - var result = !root.childNodes[0].childNodes[0].modified; + var result = !root.childNodes[0].childNodes[0].modified + + m.mount(root, null) // teardown - m.mount(root, null) //teardown - return result - }); - //end m.route + }) + // end m.route - //m.route.parseQueryString + // m.route.parseQueryString test(function() { - var args = m.route.parseQueryString("foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto") - return args["hello[]"] instanceof Array && args["hello[]"].indexOf("world") > -1 && args["hello[]"].indexOf("mars") > -1 && args["hello[]"].indexOf("pluto") > -1 + var args = m.route.parseQueryString( + "foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto") + return args["hello[]"] instanceof Array && + args["hello[]"].indexOf("world") > -1 && + args["hello[]"].indexOf("mars") > -1 && + args["hello[]"].indexOf("pluto") > -1 }) test(function() { - var args = m.route.parseQueryString("foo=bar&hello=world&hello=mars&bam=&yup") - return args.foo === "bar" && args.hello[0] === "world" && args.hello[1] === "mars" && args.bam === "" && args.yup === null + var args = m.route.parseQueryString( + "foo=bar&hello=world&hello=mars&bam=&yup") + return args.foo === "bar" && + args.hello[0] === "world" && + args.hello[1] === "mars" && + args.bam === "" && + args.yup == null }) - - //m.route.buildQueryString + + // m.route.buildQueryString test(function() { var string = m.route.buildQueryString({ foo: "bar", hello: ["world", "mars", "mars"], world: { - test:3 + test: 3 }, bam: "", yup: null, removed: undefined }) - return string === "foo=bar&hello=world&hello=mars&world%5Btest%5D=3&bam=&yup" + return string === + "foo=bar&hello=world&hello=mars&world%5Btest%5D=3&bam=&yup" }) - - //m.prop + + // m.prop test(function() { var prop = m.prop("test") return prop() === "test" @@ -3884,79 +4385,115 @@ function testMithril(mock) { }) test(function() { var prop = m.prop(null) - return prop() === null + return prop() == null }) - //m.request + // m.request test(function() { var prop = m.request({method: "GET", url: "test"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().method === "GET" && prop().url === "test" }) test(function() { - var prop = m.request({method: "GET", url: "test"}).then(function(value) {return "foo"}) + var prop = m.request({method: "GET", url: "test"}) + .then(function() {return "foo"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop() === "foo" }) test(function() { - var prop = m.request({method: "POST", url: "http://domain.com:80", data: {}}).then(function(value) {return value}) + var prop = m.request({ + method: "POST", + url: "http://domain.com:80", + data: {} + }).then(function(value) {return value}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().url === "http://domain.com:80" }) test(function() { - var prop = m.request({method: "POST", url: "http://domain.com:80/:test1", data: {test1: "foo"}}).then(function(value) {return value}) + var prop = m.request({ + method: "POST", + url: "http://domain.com:80/:test1", + data: {test1: "foo"} + }).then(function(value) {return value}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().url === "http://domain.com:80/foo" }) test(function() { var error = m.prop("no error") - var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new Error("error occurred")}}).then(null, error) + var prop = m.request({ + method: "GET", + url: "test", + deserialize: function() {throw new Error("error occurred")} + }).then(null, error) mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return prop().message === "error occurred" && error().message === "error occurred" + return prop().message === "error occurred" && + error().message === "error occurred" }) test(function() { var error = m.prop("no error") - var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new Error("error occurred")}}).catch(error) + var prop = m.request({ + method: "GET", + url: "test", + deserialize: function() {throw new Error("error occurred")} + }).catch(error) mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return prop().message === "error occurred" && error().message === "error occurred" - }) - test(function() { - var error = m.prop("no error"), exception - var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new TypeError("error occurred")}}).then(null, error) - try {mock.XMLHttpRequest.$instances.pop().onreadystatechange()} - catch (e) {exception = e} - return prop() === undefined && error() === "no error" && exception.message == "error occurred" + return prop().message === "error occurred" && + error().message === "error occurred" }) test(function() { var error = m.prop("no error") - var prop = m.request({method: "POST", url: "test", data: {foo: 1}}).then(null, error) + var exception + var prop = m.request({ + method: "GET", + url: "test", + deserialize: function() {throw new TypeError("error occurred")} + }).then(null, error) + try { + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + } catch (e) { + exception = e + } + return prop() === undefined && + error() === "no error" && + exception.message === "error occurred" + }) + test(function() { + var error = m.prop("no error") + m.request({ + method: "POST", + url: "test", + data: {foo: 1} + }).then(null, error) var xhr = mock.XMLHttpRequest.$instances.pop() xhr.onreadystatechange() - return xhr.$headers["Content-Type"] == "application/json; charset=utf-8" + return xhr.$headers["Content-Type"] === + "application/json; charset=utf-8" }) test(function() { var error = m.prop("no error") - var prop = m.request({method: "POST", url: "test"}).then(null, error) + m.request({method: "POST", url: "test"}).then(null, error) var xhr = mock.XMLHttpRequest.$instances.pop() xhr.onreadystatechange() return xhr.$headers["Content-Type"] === undefined }) test(function() { - var prop = m.request({method: "POST", url: "test", initialValue: "foo"}).then(function(data) { return data; }) - var initialValue = prop(); + var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) + .then(function(data) { return data }) + var initialValue = prop() mock.XMLHttpRequest.$instances.pop().onreadystatechange() return initialValue === "foo" }) test(function() { var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) - var initialValue = prop(); + var initialValue = prop() mock.XMLHttpRequest.$instances.pop().onreadystatechange() return initialValue === "foo" }) test(function() { - var prop = m.request({method: "POST", url: "test", initialValue: "foo"}).then(function(value) {return "bar"}) + var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) + .then(function() {return "bar"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop() === "bar" }) @@ -3984,7 +4521,11 @@ function testMithril(mock) { var prop3 = prop1.then(function(v) {value = v}) var val3 = prop3() mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return val1 === 123 && val2 === 123 && val3 === 123 && value.method === "GET" && value.url === "test" + return val1 === 123 && + val2 === 123 && + val3 === 123 && + value.method === "GET" && + value.url === "test" }) // m.request over jsonp @@ -3996,16 +4537,20 @@ function testMithril(mock) { var error = m.prop("no error") var data - var req = m.request({url: "/test", dataType: "jsonp"}).then(function(received) {data = received}, error) + m.request({url: "/test", dataType: "jsonp"}) + .then(function(received) {data = received}, error) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call( + mock.document.getElementsByTagName("script")) + .filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar"}) mock.document.removeChild(body) - return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && data.foo == "bar" + return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && + data.foo === "bar" }) test(function(){ // script tags cannot be appended directly on the document @@ -4015,16 +4560,24 @@ function testMithril(mock) { var error = m.prop("no error") var data - var req = m.request({url: "/test", dataType: "jsonp", callbackKey: "jsonpCallback"}).then(function(received) {data = received}, error); + m.request({ + url: "/test", + dataType: "jsonp", + callbackKey: "jsonpCallback" + }).then(function(received) {data = received}, error) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call( + mock.document.getElementsByTagName("script")) + .filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar1"}) mock.document.removeChild(body) - return scriptTag.src.indexOf("/test?jsonpCallback=mithril_callback") > -1 && data.foo == "bar1" + return scriptTag.src.indexOf( + "/test?jsonpCallback=mithril_callback") > -1 && + data.foo === "bar1" }) test(function(){ var body = mock.document.createElement("body") @@ -4035,9 +4588,11 @@ function testMithril(mock) { var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop(); + ;[].slice.call( + mock.document.getElementsByTagName("script")) + .filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar1"}) var out = {foo: "bar1"} mock.document.removeChild(body) @@ -4048,36 +4603,47 @@ function testMithril(mock) { mock.document.body = body mock.document.appendChild(body) - var req = m.request({url: "/test", dataType: "jsonp", data: {foo: "bar"}}) + m.request({ + url: "/test", + dataType: "jsonp", + data: {foo: "bar"} + }) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop(); + var scriptTag = [].slice.call( + mock.document.getElementsByTagName("script")) + .filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar"}) return scriptTag.src.indexOf("foo=bar") > -1 }) test(function(){ - var body = mock.document.createElement("body"); - mock.document.body = body; - mock.document.appendChild(body); + var body = mock.document.createElement("body") + mock.document.body = body + mock.document.appendChild(body) - var _window = mock; - var error = m.prop(false); - var req = m.request({url: "/test", dataType: "jsonp", method: "GET", data: {foo: "bar"}}); + m.request({ + url: "/test", + dataType: "jsonp", + method: "GET", + data: {foo: "bar"} + }) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop(); + var scriptTag = [].slice.call( + mock.document.getElementsByTagName("script")) + .filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar"}) - mock.document.removeChild(body); - return scriptTag.src.match(/foo=bar/g).length == 1; + mock.document.removeChild(body) + return scriptTag.src.match(/foo=bar/g).length === 1 }) - //m.deferred + // m.deferred test(function() { var value var deferred = m.deferred() @@ -4088,7 +4654,8 @@ function testMithril(mock) { test(function() { var value var deferred = m.deferred() - deferred.promise.then(function(data) {return "foo"}).then(function(data) {value = data}) + deferred.promise.then(function() {return "foo"}) + .then(function(data) {value = data}) deferred.resolve("test") return value === "foo" }) @@ -4109,41 +4676,70 @@ function testMithril(mock) { test(function() { var value var deferred = m.deferred() - deferred.promise.then(null, function(data) {return "foo"}).then(function(data) {value = data}) + deferred.promise.then(null, function() {return "foo"}) + .then(function(data) {value = data}) deferred.reject("test") return value === "foo" }) test(function() { var value var deferred = m.deferred() - deferred.promise.catch(function(data) {return "foo"}).then(function(data) {value = data}) + deferred.promise.catch(function() {return "foo"}) + .then(function(data) {value = data}) deferred.reject("test") return value === "foo" }) test(function() { var value1, value2 var deferred = m.deferred() - deferred.promise.then(function(data) {throw new Error}).then(function(data) {value1 = 1}, function(data) {value2 = data}) + deferred.promise.then(function() {throw new Error()}) + .then(function() {value1 = 1}, function(data) {value2 = data}) deferred.resolve("test") return value1 === undefined && value2 instanceof Error }) test(function() { - //Let unchecked exceptions bubble up in order to allow meaningful error messages in common cases like null reference exceptions due to typos - //An unchecked exception is defined as an object that is a subclass of Error (but not a direct instance of Error itself) - basically anything that can be thrown without an explicit `throw` keyword and that we'd never want to programmatically manipulate. In other words, an unchecked error is one where we only care about its line number and where the only reasonable way to deal with it is to change the buggy source code that caused the error to be thrown in the first place. - //By contrast, a checked exception is defined as anything that is explicitly thrown via the `throw` keyword and that can be programmatically handled, for example to display a validation error message on the UI. If an exception is a subclass of Error for whatever reason, but it is meant to be handled as a checked exception (i.e. follow the rejection rules for A+), it can be rethrown as an instance of Error - //This test tests two implementation details that differ from the Promises/A+ spec: - //1) A+ requires the `then` callback to be called in a different event loop from the resolve call, i.e. it must be asynchronous (this requires a setImmediate polyfill, which cannot be implemented in a reasonable way for Mithril's purpose - the possible polyfills are either too big or too slow) - //2) A+ swallows exceptions in a unrethrowable way, i.e. it's not possible to see default error messages on the console for runtime errors thrown from within a promise chain + // Let unchecked exceptions bubble up in order to allow meaningful error + // messages in common cases like null reference exceptions due to typos + // An unchecked exception is defined as an object that is a subclass of + // Error (but not a direct instance of Error itself) - basically + // anything that can be thrown without an explicit `throw` keyword and + // that we'd never want to programmatically manipulate. In other words, + // an unchecked error is one where we only care about its line number + // and where the only reasonable way to deal with it is to change the + // buggy source code that caused the error to be thrown in the first + // place. By contrast, a checked exception is defined as anything that + // is explicitly thrown via the `throw` keyword and that can be + // programmatically handled, for example to display a validation error + // message on the UI. If an exception is a subclass of Error for + // whatever reason, but it is meant to be handled as a checked exception + // (i.e. follow the rejection rules for A+), it can be rethrown as an + // instance of Error + // + // This test tests two implementation details that differ from the + // Promises/A+ spec: + // 1) A+ requires the `then` callback to be called in a different event + // loop from the resolve call, i.e. it must be asynchronous (this + // requires a setImmediate polyfill, which cannot be implemented in a + // reasonable way for Mithril's purpose - the possible polyfills are + // either too big or too slow) + // 2) A+ swallows exceptions in a unrethrowable way, i.e. it's not + // possible to see default error messages on the console for runtime + // errors thrown from within a promise chain var value1, value2, value3 var deferred = m.deferred() try { deferred.promise - .then(function(data) {foo.bar.baz}) //throws ReferenceError - .then(function(data) {value1 = 1}, function(data) {value2 = data}) + /* eslint-disable no-undef, no-unused-expressions */ + .then(function() {foo.bar.baz}) // throws ReferenceError + /* eslint-enable no-undef, no-unused-expressions */ + .then(function() {value1 = 1}, function(data) {value2 = data}) deferred.resolve("test") + } catch (e) { + value3 = e } - catch (e) {value3 = e} - return value1 === undefined && value2 === undefined && (value3 instanceof ReferenceError || value3 instanceof TypeError) + return value1 === undefined && + value2 === undefined && + (value3 instanceof ReferenceError || value3 instanceof TypeError) }) test(function() { var deferred1 = m.deferred() @@ -4160,8 +4756,9 @@ function testMithril(mock) { return value1 === 1 && value2 === 2 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value deferred.resolve(1) deferred.promise.then(function(data) { value = data @@ -4169,8 +4766,9 @@ function testMithril(mock) { return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value deferred.reject(1) deferred.promise.then(null, function(data) { value = data @@ -4178,8 +4776,9 @@ function testMithril(mock) { return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value deferred.resolve(1) deferred.resolve(2) deferred.promise.then(function(data) { @@ -4188,8 +4787,9 @@ function testMithril(mock) { return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value deferred.promise.then(function(data) { value = data }) @@ -4198,8 +4798,9 @@ function testMithril(mock) { return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value1, value2 + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value1, value2 deferred.promise.then(function(data) { value1 = data }, function(data) { @@ -4210,9 +4811,10 @@ function testMithril(mock) { return value1 === 1 && value2 === undefined }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value1, value2 - deferred.promise.then(function() { + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value1, value2 + deferred.promise.then(function(data) { value1 = data }, function(data) { value2 = data @@ -4222,8 +4824,9 @@ function testMithril(mock) { return value1 === undefined && value2 === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred() + var value deferred.promise.then(null, function(data) { value = data }) @@ -4232,46 +4835,49 @@ function testMithril(mock) { return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/85 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/85 + var deferred = m.deferred() + var value deferred.resolve() - deferred.promise.then(function(data) { + deferred.promise.then(function() { value = 1 }) return value === 1 }) test(function() { - //https://github.com/lhorie/mithril.js/issues/85 - var deferred = m.deferred(), value + // https://github.com/lhorie/mithril.js/issues/85 + var deferred = m.deferred() + var value deferred.reject() - deferred.promise.then(null, function(data) { + deferred.promise.then(null, function() { value = 1 }) return value === 1 }) test(function() { - var deferred = m.deferred(), value + var deferred = m.deferred() deferred.resolve(1) return deferred.promise() === 1 }) test(function() { - var deferred = m.deferred(), value + var deferred = m.deferred() var promise = deferred.promise.then(function(data) {return data + 1}) deferred.resolve(1) return promise() === 2 }) test(function() { - var deferred = m.deferred(), value + var deferred = m.deferred() deferred.reject(1) return deferred.promise() === undefined }) - //m.sync + // m.sync test(function() { var value var deferred1 = m.deferred() var deferred2 = m.deferred() - m.sync([deferred1.promise, deferred2.promise]).then(function(data) {value = data}) + m.sync([deferred1.promise, deferred2.promise]) + .then(function(data) {value = data}) deferred1.resolve("test") deferred2.resolve("foo") return value[0] === "test" && value[1] === "foo" @@ -4280,7 +4886,8 @@ function testMithril(mock) { var value var deferred1 = m.deferred() var deferred2 = m.deferred() - m.sync([deferred1.promise, deferred2.promise]).then(function(data) {value = data}) + m.sync([deferred1.promise, deferred2.promise]) + .then(function(data) {value = data}) deferred2.resolve("foo") deferred1.resolve("test") return value[0] === "test" && value[1] === "foo" @@ -4295,7 +4902,7 @@ function testMithril(mock) { test(function() { var value = 1 m.sync([]).then(function() {value = 2}) - return value == 2 + return value === 2 }) test(function() { var success @@ -4303,7 +4910,7 @@ function testMithril(mock) { return success }) - //m.startComputation/m.endComputation + // m.startComputation/m.endComputation test(function() { mock.requestAnimationFrame.$resolve() @@ -4326,32 +4933,40 @@ function testMithril(mock) { test(function() { var root = mock.document.createElement("div") - var success = false; - m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data=1}})); - m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data===1}})); - return success; + var success = false + m.render(root, m("div", { + config: function(elem, isInitialized, ctx) {ctx.data = 1} + })) + m.render(root, m("div", { + config: function(elem, isInitialized, ctx) { + success = ctx.data === 1 + } + })) + return success }) // more complex config context test(function() { var root = mock.document.createElement("div") - var idx = 0; - var success = true; - var statefulConfig = function(elem, isInitialized, ctx) {ctx.data=idx++} - var node = m("div", {config: statefulConfig}); - m.render(root, [node, node]); + var idx = 0 + var success = true + var statefulConfig = function(elem, isInitialized, ctx) { + ctx.data = idx++ + } + var node = m("div", {config: statefulConfig}) + m.render(root, [node, node]) - idx = 0; + idx = 0 var checkConfig = function(elem, isInitialized, ctx) { success = success && (ctx.data === idx++) } - node = m("div", {config: checkConfig}); - m.render(root, [node, node]); - return success; + node = m("div", {config: checkConfig}) + m.render(root, [node, node]) + return success }) - //console.log presence + // console.log presence test(function() { return m.deps.factory.toString().indexOf("console") < 0 }) @@ -4360,7 +4975,9 @@ function testMithril(mock) { }) } -//mock -testMithril(mock.window); - -test.print(function(value) {console.log(value)}) +// mock +testMithril(mock.window) +test.print(function(value) { + "use strict" + console.log(value) +}) diff --git a/tests/mock.js b/tests/mock.js index 30c8712c..f4080b3e 100644 --- a/tests/mock.js +++ b/tests/mock.js @@ -1,3 +1,4 @@ +/* eslint-disable no-extend-native, strict */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(item) { for (var i = 0; i < this.length; i++) { @@ -31,9 +32,11 @@ if (!Object.keys) { return keys } } +/* eslint-enable no-extend-native, strict */ var mock = {} mock.window = (function() { + "use strict" var window = {} window.document = {} window.document.childNodes = [] @@ -55,11 +58,12 @@ mock.window = (function() { else this.childNodes.splice(referenceIndex, 0, node) }, insertAdjacentHTML: function(position, html) { - //todo: accept markup - if (position == "beforebegin") { - this.parentNode.insertBefore(window.document.createTextNode(html), this) - } - else if (position == "beforeend") { + // todo: accept markup + if (position === "beforebegin") { + this.parentNode.insertBefore( + window.document.createTextNode(html), + this) + } else if (position === "beforeend") { this.appendChild(window.document.createTextNode(html)) } }, @@ -70,7 +74,7 @@ mock.window = (function() { this.namespaceURI = namespace this[name] = value.toString() }, - getAttribute: function(name, value) { + getAttribute: function(name) { return this[name] }, addEventListener: function () {}, @@ -104,23 +108,25 @@ mock.window = (function() { this.childNodes.splice(index, 1) child.parentNode = null } - //getElementsByTagName is only used by JSONP tests, it's not required by Mithril + // getElementsByTagName is only used by JSONP tests, it's not required by + // Mithril window.document.getElementsByTagName = function(name){ - name = name.toLowerCase(); - var out = []; + name = name.toLowerCase() + var out = [] var traverse = function(node){ if(node.childNodes && node.childNodes.length > 0){ node.childNodes.map(function(curr){ - if(curr.nodeName.toLowerCase() === name) - out.push(curr); - traverse(curr); - }); + if (curr.nodeName.toLowerCase() === name) { + out.push(curr) + } + traverse(curr) + }) } - }; + } - traverse(window.document); - return out; + traverse(window.document) + return out } window.scrollTo = function() {} window.cancelAnimationFrame = function() {} @@ -156,15 +162,17 @@ mock.window = (function() { request.$instances = [] return request }()) - window.location = {search: "", pathname: "", hash: ""}, + window.location = {search: "", pathname: "", hash: ""} window.history = {} window.history.$$length = 0 window.history.pushState = function(data, title, url) { window.history.$$length++ - window.location.pathname = window.location.search = window.location.hash = url - }, + window.location.pathname = window.location.search = + window.location.hash = url + } window.history.replaceState = function(data, title, url) { - window.location.pathname = window.location.search = window.location.hash = url + window.location.pathname = window.location.search = + window.location.hash = url } return window -}()) \ No newline at end of file +}()) diff --git a/tests/test.js b/tests/test.js index 844cf8aa..984e15ee 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,15 +1,19 @@ +/* eslint-disable no-console */ if (!this.console) { - var log = function(value) {document.write("
" + value + "
")} + var log = function(value) { + "use strict" + document.write("
" + value + "
") + } this.console = {log: log, error: log} } function test(condition) { + "use strict" test.total++ try { if (!condition()) throw new Error("failed") - } - catch (e) { + } catch (e) { console.error(e) test.failures.push(condition) } @@ -17,6 +21,7 @@ function test(condition) { test.total = 0 test.failures = [] test.print = function(print) { + "use strict" for (var i = 0; i < test.failures.length; i++) { print(test.failures[i].toString()) } From 3de01a1554b449b050621fd19feacb6a7809fd65 Mon Sep 17 00:00:00 2001 From: impinball Date: Thu, 23 Jul 2015 05:24:48 -0400 Subject: [PATCH 2/2] Clean up tests, resolve style differences, reduce upstream diff This is in preparation for a PR, to reduce potential for merge conflicts with either my PR or others', since mine will modify a large amount of the main file. --- .eslintignore | 5 - .eslintrc | 27 - Gruntfile.js | 297 +-- README.md | 2 - docs/layout/tools/template-converter.js | 164 +- mithril.js | 2319 ++++++++--------------- mithril.min.js | 4 +- mithril.min.js.map | 2 +- package.json | 97 +- tests/e2e/.eslintrc | 23 - tests/e2e/tests.js | 401 ++-- tests/mithril-tests.js | 2181 ++++++++------------- tests/mock.js | 32 +- tests/test.js | 11 +- 14 files changed, 1987 insertions(+), 3578 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc delete mode 100644 tests/e2e/.eslintrc diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 29de9e28..00000000 --- a/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -**/*.min.js -docs/layout/lib/**/*.js -tests/e2e/libs/** -mithril.closure-compiler-externs.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index a3c03520..00000000 --- a/.eslintrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - "env": { - "browser": true - }, - "rules": { - "no-cond-assign": [2, "except-parens"], - "no-shadow": 0, - "semi-spacing": 0, - "quotes": [2, "double", "avoid-escape"], - "curly": [2, "multi-line"], - "semi": [2, "never"], - "eqeqeq": [2, "allow-null"], - "no-throw-literal": 2, - "wrap-iife": 2, - "strict": [2, "function"], - "brace-style": [2, "1tbs", { "allowSingleLine": true }], - "linebreak-style": [1, "windows"], - "one-var": [2, { - "initialized": "never" - }], - "new-cap": 0, - "no-use-before-define": [2, "nofunc"], - "max-len": [2, 80, 4], - "dot-notation": 2, - "indent": [2, "tab"] - } -} diff --git a/Gruntfile.js b/Gruntfile.js index 69afbcb0..deeae059 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,14 +1,11 @@ -/* eslint-env node */ module.exports = function(grunt) { - "use strict" + var _ = require("lodash"); + var version = "0.4.0"; - var _ = require("lodash") - var version = "0.4.0" - - var inputFolder = "./docs" - var tempFolder = "./temp" - var archiveFolder = "./archive" - var outputFolder = "../mithril" + var inputFolder = "./docs"; + var tempFolder = "./temp"; + var archiveFolder = "./archive"; + var outputFolder = "../mithril"; var guide = [ "auto-redrawing", @@ -25,7 +22,7 @@ module.exports = function(grunt) { "routing", "tools", "web-services" - ] + ]; var api = [ "change-log", "roadmap", @@ -45,68 +42,53 @@ module.exports = function(grunt) { "mithril.trust", "mithril.withAttr", "mithril.xhr" - ] + ]; - var md2htmlTasks = {} + var md2htmlTasks = {}; var makeTasks = function(layout, pages) { pages.map(function(name) { - var src = inputFolder + "/" + name + ".md" - var title - if (grunt.file.exist(src)) { - title = grunt.file.read(src) - .split(/\n/)[0] - .substring(3) + " - " - } else { - title = "" - } + var src = inputFolder + "/" + name + ".md"; + var title = (grunt.file.exists(src)) ? grunt.file.read(src).split(/\n/)[0].substring(3) + ' - ' : ''; md2htmlTasks[name] = { - options: { - layout: inputFolder + "/layout/" + layout + ".html", - templateData: { "topic": title } - }, + options: {layout: inputFolder + "/layout/" + layout + ".html", templateData: { "topic": title }}, files: [{src: [src], dest: tempFolder + "/" + name + ".html"}] } }) - } - makeTasks("guide", guide) - makeTasks("api", api) + }; + makeTasks("guide", guide); + makeTasks("api", api); - var sauceBrowsers = [ - { browserName: "firefox", version: "19", platform: "XP" }, + var sauceBrowsers =[ + { browserName: 'firefox', version: '19', platform: 'XP' }, { browserName: "internet explorer", platform: "XP", version: "6"}, { browserName: "safari", platform: "OS X 10.9", version: "7"}, { browserName: "iPad", platform: "OS X 10.9", version: "7.1"}, { browserName: "opera", platform: "Linux", version: "12"}, { browserName: "chrome", platform: "XP", version: "26"}, { browserName: "chrome", platform: "Windows 8", version: "26"} - ] + ]; var sauceOnTestComplete = function(result, callback) { - var request = require("request") + var request = require('request'); - var user = process.env.SAUCE_USERNAME - var pass = process.env.SAUCE_ACCESS_KEY + var user = process.env.SAUCE_USERNAME; + var pass = process.env.SAUCE_ACCESS_KEY; request.put({ - url: [ - "https://saucelabs.com/rest/v1", - user, - "jobs", - result.job_id - ].join("/"), + url: ['https://saucelabs.com/rest/v1', user, 'jobs', result.job_id].join('/'), auth: { user: user, pass: pass }, json: { passed: result.passed } }, function (error, response) { if (error) { - callback(error) + callback(error); } else if (response.statusCode !== 200) { - callback(new Error("Unexpected response status: " - + response.statusCode + "\n ")) + callback(new Error('Unexpected response status: ' + + response.statusCode + "\n ")); } else { - callback(null, result.passed) + callback(null, result.passed); } - }) - } + }); + }; var sauceBaseOptions = { username: process.env.SAUCE_USERNAME, @@ -115,164 +97,74 @@ module.exports = function(grunt) { browsers: sauceBrowsers, sauceConfig: { "record-video": false, - "record-screenshots": false + "record-screenshots": false, }, build: process.env.TRAVIS_JOB_ID, onTestComplete: sauceOnTestComplete, - tunnelTimeout: 5 - } + tunnelTimeout: 5, + }; var sauceCustomOptions = { - testname: "Mithril Custom Tests " + new Date().toJSON(), - urls: ["http://127.0.0.1:8000/tests/index.html"] - } - _.assign(sauceCustomOptions, sauceBaseOptions) + testname: "Mithril Custom Tests "+ new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/index.html"], + }; + _.assign(sauceCustomOptions, sauceBaseOptions); var sauceQunitOptions = { - testname: "qUnit Tests " + new Date().toJSON(), - urls: ["http://127.0.0.1:8000/tests/e2e/test.html"] - } - _.assign(sauceQunitOptions, sauceBaseOptions) + testname: "qUnit Tests "+ new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/e2e/test.html"], + }; + _.assign(sauceQunitOptions, sauceBaseOptions); - var currentVersionArchiveFolder = archiveFolder + "/v" + version + var currentVersionArchiveFolder = archiveFolder + "/v" + version; grunt.initConfig({ md2html: md2htmlTasks, uglify: { - options: { - banner: [[ - "/*", - "Mithril v" + version, - "http://github.com/lhorie/mithril.js", - "(c) Leo Horie", - "License: MIT", - "*/" - ].join("\n")], - sourceMap: true - }, + options: {banner: "/*\nMithril v" + version + "\nhttp://github.com/lhorie/mithril.js\n(c) Leo Horie\nLicense: MIT\n*/", sourceMap: true}, mithril: {src: "mithril.js", dest: "mithril.min.js"} }, concat: { - test: { - src: [ - "mithril.js", - "./tests/test.js", - "./tests/mock.js", - "./tests/mithril-tests.js" - ], - dest: currentVersionArchiveFolder + "/mithril-tests.js" - } + test: {src: ["mithril.js", "./tests/test.js", "./tests/mock.js", "./tests/mithril-tests.js"], dest: currentVersionArchiveFolder + "/mithril-tests.js"} }, zip: { distribution: { cwd: currentVersionArchiveFolder + "/", - src: [ - currentVersionArchiveFolder + "/mithril.min.js", - currentVersionArchiveFolder + "/mithril.min.js.map", - currentVersionArchiveFolder + "/mithril.js" - ], + src: [currentVersionArchiveFolder + "/mithril.min.js", currentVersionArchiveFolder + "/mithril.min.js.map", currentVersionArchiveFolder + "/mithril.js"], dest: currentVersionArchiveFolder + "/mithril.min.zip" } }, replace: { - options: { - force: true, - patterns: [ - {match: /\.md/g, replacement: ".html"}, - {match: /\$version/g, replacement: version} - ] - }, - links: { - expand: true, - flatten: true, - src: [tempFolder + "/**/*.html"], - dest: currentVersionArchiveFolder + "/" - }, - index: { - src: inputFolder + "/layout/index.html", - dest: currentVersionArchiveFolder + "/index.html" - }, - commonjs: { - expand: true, - flatten: true, - src: [inputFolder + "/layout/*.json"], - dest: currentVersionArchiveFolder - }, - cdnjs: { - src: "deploy/cdnjs-package.json", - dest: "../cdnjs/ajax/libs/mithril/package.json" - } + options: {force: true, patterns: [{match: /\.md/g, replacement: ".html"}, {match: /\$version/g, replacement: version}]}, + links: {expand: true, flatten: true, src: [tempFolder + "/**/*.html"], dest: currentVersionArchiveFolder + "/"}, + index: {src: inputFolder + "/layout/index.html", dest: currentVersionArchiveFolder + "/index.html"}, + commonjs: {expand: true, flatten: true, src: [inputFolder + "/layout/*.json"], dest: currentVersionArchiveFolder}, + cdnjs: {src: "deploy/cdnjs-package.json", dest: "../cdnjs/ajax/libs/mithril/package.json"} }, copy: { - style: { - src: inputFolder + "/layout/style.css", - dest: currentVersionArchiveFolder + "/style.css" - }, - pages: { - src: inputFolder + "/layout/pages.json", - dest: currentVersionArchiveFolder + "/pages.json" - }, - lib: { - expand: true, - cwd: inputFolder + "/layout/lib/", - src: "./**", - dest: currentVersionArchiveFolder + "/lib/" - }, - tools: { - expand: true, - cwd: inputFolder + "/layout/tools/", - src: "./**", - dest: currentVersionArchiveFolder + "/tools/" - }, - comparisons: { - expand: true, - cwd: inputFolder + "/layout/comparisons/", - src: "./**", - dest: currentVersionArchiveFolder + "/comparisons/" - }, - unminified: { - src: "mithril.js", - dest: currentVersionArchiveFolder + "/mithril.js" - }, - minified: { - src: "mithril.min.js", - dest: currentVersionArchiveFolder + "/mithril.min.js" - }, - readme: { - src: "README.md", - dest: currentVersionArchiveFolder + "/README.md" - }, - map: { - src: "mithril.min.js.map", - dest: currentVersionArchiveFolder + "/mithril.min.js.map" - }, - typescript: { - src: "mithril.d.ts", - dest: currentVersionArchiveFolder + "/mithril.d.ts" - }, - publish: { - expand: true, - cwd: currentVersionArchiveFolder, - src: "./**", - dest: outputFolder - }, - archive: { - expand: true, - cwd: currentVersionArchiveFolder, - src: "./**", - dest: outputFolder + "/archive/v" + version - } + style: {src: inputFolder + "/layout/style.css", dest: currentVersionArchiveFolder + "/style.css"}, + pages: {src: inputFolder + "/layout/pages.json", dest: currentVersionArchiveFolder + "/pages.json"}, + lib: {expand: true, cwd: inputFolder + "/layout/lib/", src: "./**", dest: currentVersionArchiveFolder + "/lib/"}, + tools: {expand: true, cwd: inputFolder + "/layout/tools/", src: "./**", dest: currentVersionArchiveFolder + "/tools/"}, + comparisons: {expand: true, cwd: inputFolder + "/layout/comparisons/", src: "./**", dest: currentVersionArchiveFolder + "/comparisons/"}, + unminified: {src: "mithril.js", dest: currentVersionArchiveFolder + "/mithril.js"}, + minified: {src: "mithril.min.js", dest: currentVersionArchiveFolder + "/mithril.min.js"}, + readme: {src: "README.md", dest: currentVersionArchiveFolder + "/README.md"}, + map: {src: "mithril.min.js.map", dest: currentVersionArchiveFolder + "/mithril.min.js.map"}, + typescript: {src: "mithril.d.ts", dest: currentVersionArchiveFolder + "/mithril.d.ts"}, + publish: {expand: true, cwd: currentVersionArchiveFolder, src: "./**", dest: outputFolder}, + archive: {expand: true, cwd: currentVersionArchiveFolder, src: "./**", dest: outputFolder + "/archive/v" + version}, }, execute: { tests: {src: [currentVersionArchiveFolder + "/mithril-tests.js"]} }, qunit: { - all: ["tests/e2e/**/*.html"] + all: ['tests/e2e/**/*.html'] }, "saucelabs-custom": { - all: { + all:{ options: sauceCustomOptions } }, "saucelabs-qunit": { - all: { + all:{ options: sauceQunitOptions } }, @@ -282,7 +174,7 @@ module.exports = function(grunt) { server: { options: { port: 8888, - base: "." + base: '.' } } }, @@ -294,45 +186,34 @@ module.exports = function(grunt) { default: { files: [{ expand: true, - src: ["mithril.js"], - cwd: ".", - dest: "." + src: ['mithril.js'], + cwd: '.', + dest: '.' }] } - }, - eslint: { - target: [ - "**/*.js", - "!node_modules/**", - "!**/*.min.js", - "!docs/layout/lib/**/*.js" - ] } - }) + }); - grunt.loadNpmTasks("grunt-contrib-clean") - grunt.loadNpmTasks("grunt-contrib-concat") - grunt.loadNpmTasks("grunt-contrib-copy") - grunt.loadNpmTasks("grunt-contrib-uglify") - grunt.loadNpmTasks("grunt-execute") - grunt.loadNpmTasks("grunt-md2html") - grunt.loadNpmTasks("grunt-replace") - grunt.loadNpmTasks("grunt-zip") - grunt.loadNpmTasks("grunt-contrib-qunit") - grunt.loadNpmTasks("grunt-contrib-connect") - grunt.loadNpmTasks("grunt-saucelabs") - grunt.loadNpmTasks("grunt-jsfmt") - grunt.loadNpmTasks("grunt-eslint") + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-contrib-uglify"); + grunt.loadNpmTasks('grunt-execute'); + grunt.loadNpmTasks("grunt-md2html"); + grunt.loadNpmTasks("grunt-replace"); + grunt.loadNpmTasks('grunt-zip'); + grunt.loadNpmTasks('grunt-contrib-qunit'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-saucelabs'); + grunt.loadNpmTasks('grunt-jsfmt'); - grunt.registerTask("build", [ - "test", "uglify", "zip", "md2html", "replace", "copy", "clean"]) - grunt.registerTask("testall", ["test", "teste2e"]) - grunt.registerTask("test", ["eslint", "concat", "execute"]) - grunt.registerTask("teste2e", ["connect", "qunit"]) - grunt.registerTask("default", ["build"]) + grunt.registerTask("build", ["test", "uglify", "zip", "md2html", "replace", "copy", "clean"]); + grunt.registerTask("testall", ["test", "teste2e"]); + grunt.registerTask("test", ["concat", "execute"]); + grunt.registerTask('teste2e', ['connect', 'qunit']); + grunt.registerTask("default", ["build"]); - grunt.registerTask("sauce-qunit", ["connect", "saucelabs-qunit"]) - grunt.registerTask("sauce-custom", ["connect", "saucelabs-custom"]) - grunt.registerTask("sauce-all", [ - "connect", "saucelabs-qunit", "saucelabs-custom"]) -} + grunt.registerTask("sauce-qunit", ["connect", "saucelabs-qunit"]); + grunt.registerTask("sauce-custom", ["connect", "saucelabs-custom"]); + grunt.registerTask("sauce-all", ["connect", "saucelabs-qunit", "saucelabs-custom"]); +}; diff --git a/README.md b/README.md index ca56901a..8f8cc956 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -**Note: This is a WIP partial rewrite of Mithril.** - [![JS.ORG](https://img.shields.io/badge/js.org-mithril-ffb400.svg?style=flat-square)](http://js.org) [![Join the chat at https://gitter.im/lhorie/mithril.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lhorie/mithril.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/lhorie/mithril.js.svg?branch=master)](https://travis-ci.org/lhorie/mithril.js) diff --git a/docs/layout/tools/template-converter.js b/docs/layout/tools/template-converter.js index 79046db2..b8cd01cf 100644 --- a/docs/layout/tools/template-converter.js +++ b/docs/layout/tools/template-converter.js @@ -1,128 +1,90 @@ -/* globals m */ - -var templateConverter = {} +var templateConverter = {}; templateConverter.DOMFragment = function(markup) { - "use strict" - if (markup.indexOf(" -1) { - return [ - new DOMParser().parseFromString(markup, "text/html").childNodes[1] - ] - } - var container = document.createElement("div") - container.insertAdjacentHTML("beforeend", markup) - return container.childNodes + if (markup.indexOf(" -1) return [new DOMParser().parseFromString(markup, "text/html").childNodes[1]] + var container = document.createElement("div"); + container.insertAdjacentHTML("beforeend", markup); + return container.childNodes; } templateConverter.VirtualFragment = function recurse(domFragment) { - "use strict" - var virtualFragment = [] - for (var i = 0; i < domFragment.length; i++) { - var el = domFragment[i] - if (el.nodeType === 3) { - virtualFragment.push(el.nodeValue) - } else if (el.nodeType === 1) { - var attrs = {} - for (var j = 0; el.attributes.length; j++) { - var attr = el.attributes[j] - attrs[attr.name] = attr.value + var virtualFragment = []; + for (var i = 0, el; el = domFragment[i]; i++) { + if (el.nodeType == 3) { + virtualFragment.push(el.nodeValue); + } + else if (el.nodeType == 1) { + var attrs = {}; + for (var j = 0, attr; attr = el.attributes[j]; j++) { + attrs[attr.name] = attr.value; } - - virtualFragment.push({ - tag: el.nodeName.toLowerCase(), - attrs: attrs, - children: recurse(el.childNodes) - }) + + virtualFragment.push({tag: el.nodeName.toLowerCase(), attrs: attrs, children: recurse(el.childNodes)}); } } - return virtualFragment + return virtualFragment; } templateConverter.Template = function recurse() { - "use strict" - if (Object.prototype.toString.call(arguments[0]) === "[object String]") { - return new recurse(new templateConverter.VirtualFragment( - new templateConverter.DOMFragment(arguments[0]))) + if (Object.prototype.toString.call(arguments[0]) == "[object String]") { + return new recurse(new templateConverter.VirtualFragment(new templateConverter.DOMFragment(arguments[0]))); } - - var virtualFragment = arguments[0] - var level = arguments[1] - if (!level) level = 1 - - var tab = "\n" + new Array(level + 1).join("\t") - var virtuals = [] - for (var i = 0; i < virtualFragment.length; i++) { - var el = virtualFragment[i] - if (typeof el === "string") { - if (el.match(/\t| {2,}/g) && el.trim().length === 0) { - virtuals.indented = true - } else { - virtuals.push('"' + el - .replace(/"/g, '\\"') - .replace(/\r/g, "\\r") - .replace(/\n/g, "\\n") + '"') - } - } else { - var virtual = "" - if (el.tag !== "div") virtual += el.tag - if (el.attrs.class) { - virtual += "." + el.attrs.class - .replace(/\t+/g, " ") - .split(" ") - .join(".") - delete el.attrs.class + + var virtualFragment = arguments[0], level = arguments[1] + if (!level) level = 1; + + var tab = "\n" + new Array(level + 1).join("\t"); + var virtuals = []; + for (var i = 0, el; el = virtualFragment[i]; i++) { + if (typeof el == "string") { + if (el.match(/\t| {2,}/g) && el.trim().length == 0) virtuals.indented = true; + else virtuals.push('"' + el.replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n") + '"'); + } + else { + var virtual = ""; + if (el.tag != "div") virtual += el.tag; + if (el.attrs["class"]) { + virtual += "." + el.attrs["class"].replace(/\t+/g, " ").split(" ").join("."); + delete el.attrs["class"]; } var attrNames = Object.keys(el.attrs).sort() - for (var j = 0; j < attrNames.length; j++) { - var attrName = attrNames[j] - if (attrName !== "style") { - virtual += "[" + attrName + "='" + - el.attrs[attrName].replace(/'/g, "\\'") + "']" - } + for (var j = 0, attrName; attrName = attrNames[j]; j++) { + if (attrName != "style") virtual += "[" + attrName + "='" + el.attrs[attrName].replace(/'/g, "\\'") + "']"; } - if (virtual === "") virtual = "div" - virtual = '"' + virtual + '"' - + if (virtual == "") virtual = "div" + virtual = '"' + virtual + '"'; + + var style = "" if (el.attrs.style) { - virtual += ", {style: " + ("{\"" + el.attrs.style - .replace(/:/g, "\": \"") - .replace(/;/g, "\", \"") + "}") - .replace(/, "}|"}/, "}") + "}" + virtual += ", {style: " + ("{\"" + el.attrs.style.replace(/:/g, "\": \"").replace(/;/g, "\", \"") + "}").replace(/, "}|"}/, "}") + "}" } - + if (el.children.length > 0) { - virtual += ", " + recurse(el.children, level + 1) + virtual += ", " + recurse(el.children, level + 1); } - virtual = "m(" + virtual + ")" - virtuals.push(virtual) + virtual = "m(" + virtual + ")"; + virtuals.push(virtual); } } - if (!virtuals.indented) tab = "" - - var isInline = virtuals.length === 1 && virtuals[0].charAt(0) === '"' - var template = isInline ? - virtuals.join(", ") : - "[" + tab + virtuals.join("," + tab) + tab.slice(0, -1) + "]" - return new String(template) // eslint-disable-line no-new-wrappers + if (!virtuals.indented) tab = ""; + + var isInline = virtuals.length == 1 && virtuals[0].charAt(0) == '"'; + var template = isInline ? virtuals.join(", ") : "[" + tab + virtuals.join("," + tab) + tab.slice(0, -1) + "]"; + return new String(template); } templateConverter.controller = function() { - "use strict" - this.source = m.prop("") - this.output = m.prop("") - + this.source = m.prop(""); + this.output = m.prop(""); + this.convert = function() { - return this.output(new templateConverter.Template(this.source())) - } -} + return this.output(new templateConverter.Template(this.source())); + }; + +}; templateConverter.view = function(ctrl) { - "use strict" return m("div", [ - m("textarea", { - autofocus: true, - style: {width: "100%", height: "40%"}, - onchange: m.withAttr("value", ctrl.source) - }, ctrl.source()), + m("textarea", {autofocus: true, style: {width:"100%", height: "40%"}, onchange: m.withAttr("value", ctrl.source)}, ctrl.source()), m("button", {onclick: ctrl.convert.bind(ctrl)}, "Convert"), - m("textarea", {style: {width: "100%", height: "40%"}}, ctrl.output()) - ]) -} + m("textarea", {style: {width:"100%", height: "40%"}}, ctrl.output()) + ]); +}; \ No newline at end of file diff --git a/mithril.js b/mithril.js index e0b1c0a6..4f6c8ddd 100644 --- a/mithril.js +++ b/mithril.js @@ -1,63 +1,34 @@ -/* eslint-disable wrap-iife, no-shadow-restricted-names */ var m = (function app(window, undefined) { -/* eslint-enable wrap-iife, no-shadow-restricted-names */ - "use strict" - - function noop() {} - - var type = {}.toString - + "use strict"; function isFunction(object) { - return typeof object === "function" + return typeof object === "function"; } - function isObject(object) { - return type.call(object) === "[object Object]" + return type.call(object) === "[object Object]"; } - function isString(object) { - return type.call(object) === "[object String]" + return type.call(object) === "[object String]"; } - var isArray = Array.isArray || function (object) { - return type.call(object) === "[object Array]" - } - - var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g - var attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/ - /* eslint-disable max-len */ - var voidElements = /^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/ - /* eslint-enable max-len */ + return type.call(object) === "[object Array]"; + }; + var type = {}.toString; + var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/; + var voidElements = /^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/; + var noop = function () {}; // caching commonly used variables - var $document, $location, $requestAnimationFrame, $cancelAnimationFrame - - var roots = [] - var components = [] - var controllers = [] - var lastRedrawId = null - var lastRedrawCallTime = 0 - var computePreRedrawHook = null - var computePostRedrawHook = null - var unloaders = [] - var FRAME_BUDGET = 16 // 60 frames per second = 1 call per 16 ms - var topComponent - - var redrawing = false - var forcing = false - var pendingRequests = 0 + var $document, $location, $requestAnimationFrame, $cancelAnimationFrame; // self invoking function needed because of the way mocks work - function initialize(window) { - $document = window.document - $location = window.location - $cancelAnimationFrame = window.cancelAnimationFrame || - window.clearTimeout - $requestAnimationFrame = window.requestAnimationFrame || - window.setTimeout + function initialize(window){ + $document = window.document; + $location = window.location; + $cancelAnimationFrame = window.cancelAnimationFrame || window.clearTimeout; + $requestAnimationFrame = window.requestAnimationFrame || window.setTimeout; } - initialize(window) + initialize(window); /** @@ -70,1780 +41,1190 @@ var m = (function app(window, undefined) { * * @param {Tag} The DOM node tag * @param {Object=[]} optional key-value pairs to be mapped to DOM attrs - * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, - * or splat (optional) + * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, or splat (optional) * */ function m(tag, pairs) { for (var args = [], i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i] + args[i - 1] = arguments[i]; } - - if (isObject(tag)) return parameterize(tag, args) - - var hasAttrs = pairs != null && - isObject(pairs) && - !("tag" in pairs || "view" in pairs || "subtree" in pairs) - - var attrs = hasAttrs ? pairs : {} - var classAttrName = "class" in attrs ? "class" : "className" - var cell = {tag: "div", attrs: {}} - var classes = [] - - if (!isString(tag)) { - throw new Error( - "selector in m(selector, attrs, children) should be a string") - } - - var match = parser.exec(tag) - - while (match != null) { - if (match[1] === "" && match[2]) { - cell.tag = match[2] - } else if (match[1] === "#") { - cell.attrs.id = match[2] - } else if (match[1] === ".") { - classes.push(match[2]) - } else if (match[3][0] === "[") { - var pair = attrParser.exec(match[3]) - cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" : true) + if (isObject(tag)) return parameterize(tag, args); + var hasAttrs = pairs != null && isObject(pairs) && !("tag" in pairs || "view" in pairs || "subtree" in pairs); + var attrs = hasAttrs ? pairs : {}; + var classAttrName = "class" in attrs ? "class" : "className"; + var cell = {tag: "div", attrs: {}}; + var match, classes = []; + if (!isString(tag)) throw new Error("selector in m(selector, attrs, children) should be a string"); + while ((match = parser.exec(tag)) != null) { + if (match[1] === "" && match[2]) cell.tag = match[2]; + else if (match[1] === "#") cell.attrs.id = match[2]; + else if (match[1] === ".") classes.push(match[2]); + else if (match[3][0] === "[") { + var pair = attrParser.exec(match[3]); + cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true); } - - match = parser.exec(tag) } - var children = hasAttrs ? args.slice(1) : args - + var children = hasAttrs ? args.slice(1) : args; if (children.length === 1 && isArray(children[0])) { - cell.children = children[0] - } else { - cell.children = children + cell.children = children[0]; + } + else { + cell.children = children; } for (var attrName in attrs) { if (attrs.hasOwnProperty(attrName)) { - if (attrName === classAttrName && - attrs[attrName] != null && - attrs[attrName] !== "") { - classes.push(attrs[attrName]) - // create key in correct iteration order - cell.attrs[attrName] = "" - } else { - cell.attrs[attrName] = attrs[attrName] + if (attrName === classAttrName && attrs[attrName] != null && attrs[attrName] !== "") { + classes.push(attrs[attrName]); + cell.attrs[attrName] = ""; //create key in correct iteration order } + else cell.attrs[attrName] = attrs[attrName]; } } - if (classes.length) cell.attrs[classAttrName] = classes.join(" ") + if (classes.length) cell.attrs[classAttrName] = classes.join(" "); - return cell + return cell; } - function forEach(list, f) { - for (var i = 0; i < list.length && !f(list[i], i++);) { - // do nothing - } + for (var i = 0; i < list.length && !f(list[i], i++);) {} } - function forKeys(list, f) { forEach(list, function (attrs, i) { - attrs = attrs && attrs.attrs - return attrs && attrs.key != null && f(attrs, i) - }) + return (attrs = attrs && attrs.attrs) && attrs.key != null && f(attrs, i); + }); } - // This function was causing deopts in Chrome. function dataToString(data) { - // data.toString() might throw or return null if data is the return - // value of Console.log in Firefox (behavior depends on version) + //data.toString() might throw or return null if data is the return value of Console.log in Firefox (behavior depends on version) try { - if (data == null || data.toString() == null) return "" + if (data == null || data.toString() == null) return ""; } catch (e) { - return "" + return ""; } - return data + return data; } - // This function was causing deopts in Chrome. function injectTextNode(parentElement, first, index, data) { try { - parentElement.insertBefore( - first, - parentElement.childNodes[index] || null) - first.nodeValue = data - } catch (e) { - // IE erroneously throws error when appending an empty text node - // after a null - } + insertNode(parentElement, first, index); + first.nodeValue = data; + } catch (e) {} //IE erroneously throws error when appending an empty text node after a null } function flatten(list) { - // recursively flatten array + //recursively flatten array for (var i = 0; i < list.length; i++) { if (isArray(list[i])) { - list = list.concat.apply([], list) - // check current index again and flatten until there are no - // more nested arrays at that index - i-- + list = list.concat.apply([], list); + //check current index again and flatten until there are no more nested arrays at that index + i--; } } - return list + return list; } function insertNode(parentElement, node, index) { - parentElement.insertBefore( - node, - parentElement.childNodes[index] || null) + parentElement.insertBefore(node, parentElement.childNodes[index] || null); } - var DELETION = 1 - var INSERTION = 2 - var MOVE = 3 + var DELETION = 1, INSERTION = 2, MOVE = 3; function handleKeysDiffer(data, existing, cached, parentElement) { - forKeys(data, function (attrs, i) { - var key = attrs.key - if (existing[key]) { - existing[key] = { - action: MOVE, - index: i, - from: existing[key].index, - element: cached.nodes[existing[key].index] || - $document.createElement("div") - } - } else { - existing[key] = {action: INSERTION, index: i} - } - }) - var actions = [] - for (var prop in existing) actions.push(existing[prop]) - var changes = actions.sort(sortChanges) - var newCached = new Array(cached.length) - newCached.nodes = cached.nodes.slice() + forKeys(data, function (key, i) { + existing[key = key.key] = existing[key] ? { + action: MOVE, + index: i, + from: existing[key].index, + element: cached.nodes[existing[key].index] || $document.createElement("div") + } : {action: INSERTION, index: i}; + }); + var actions = []; + for (var prop in existing) actions.push(existing[prop]); + var changes = actions.sort(sortChanges), newCached = new Array(cached.length); + newCached.nodes = cached.nodes.slice(); forEach(changes, function (change) { - var index = change.index + var index = change.index; if (change.action === DELETION) { - clear(cached[index].nodes, cached[index]) - newCached.splice(index, 1) + clear(cached[index].nodes, cached[index]); + newCached.splice(index, 1); } if (change.action === INSERTION) { - var dummy = $document.createElement("div") - dummy.key = data[index].attrs.key - insertNode(parentElement, dummy, index) + var dummy = $document.createElement("div"); + dummy.key = data[index].attrs.key; + insertNode(parentElement, dummy, index); newCached.splice(index, 0, { attrs: {key: data[index].attrs.key}, nodes: [dummy] - }) - newCached.nodes[index] = dummy + }); + newCached.nodes[index] = dummy; } if (change.action === MOVE) { - var changeElement = change.element - var maybeChanged = parentElement.childNodes[index] + var changeElement = change.element; + var maybeChanged = parentElement.childNodes[index]; if (maybeChanged !== changeElement && changeElement !== null) { - parentElement.insertBefore(changeElement, - maybeChanged || null) + parentElement.insertBefore(changeElement, maybeChanged || null); } - newCached[index] = cached[change.from] - newCached.nodes[index] = changeElement + newCached[index] = cached[change.from]; + newCached.nodes[index] = changeElement; } - }) + }); - return newCached + return newCached; } function diffKeys(data, cached, existing, parentElement) { - var keysDiffer = data.length !== cached.length + var keysDiffer = data.length !== cached.length; if (!keysDiffer) { forKeys(data, function (attrs, i) { - var cachedCell = cached[i] - keysDiffer = cachedCell && - cachedCell.attrs && - cachedCell.attrs.key !== attrs.key - return keysDiffer - }) + var cachedCell = cached[i]; + return keysDiffer = cachedCell && cachedCell.attrs && cachedCell.attrs.key !== attrs.key; + }); } - if (keysDiffer) { - return handleKeysDiffer(data, existing, cached, parentElement) - } else { - return cached - } + return keysDiffer ? handleKeysDiffer(data, existing, cached, parentElement) : cached; } function diffArray(data, cached, nodes) { - // diff the array itself + //diff the array itself - // update the list of DOM nodes by collecting the nodes from - // each item + //update the list of DOM nodes by collecting the nodes from each item forEach(data, function (_, i) { - if (cached[i] != null) { - nodes.push.apply(nodes, cached[i].nodes) - } + if (cached[i] != null) nodes.push.apply(nodes, cached[i].nodes); }) - // remove items from the end of the array if the new array is - // shorter than the old one. if errors ever happen here, the - // issue is most likely a bug in the construction of the - // `cached` data structure somewhere earlier in the program + //remove items from the end of the array if the new array is shorter than the old one. if errors ever happen here, the issue is most likely + //a bug in the construction of the `cached` data structure somewhere earlier in the program forEach(cached.nodes, function (node, i) { - if (node.parentNode != null && nodes.indexOf(node) < 0) { - clear([node], [cached[i]]) - } + if (node.parentNode != null && nodes.indexOf(node) < 0) clear([node], [cached[i]]); }) - if (data.length < cached.length) cached.length = data.length - cached.nodes = nodes + if (data.length < cached.length) cached.length = data.length; + cached.nodes = nodes; } function buildArrayKeys(data) { - var guid = 0 + var guid = 0; forKeys(data, function () { forEach(data, function (attrs) { - if ((attrs = attrs && attrs.attrs) && attrs.key == null) { - attrs.key = "__mithril__" + guid++ - } + if ((attrs = attrs && attrs.attrs) && attrs.key == null) attrs.key = "__mithril__" + guid++; }) - return 1 - }) + return 1; + }); } function maybeRecreateObject(data, cached, dataAttrKeys) { - // if an element is different enough from the one in cache, recreate it + //if an element is different enough from the one in cache, recreate it if (data.tag !== cached.tag || - dataAttrKeys.sort().join() !== - Object.keys(cached.attrs).sort().join() || + dataAttrKeys.sort().join() !== Object.keys(cached.attrs).sort().join() || data.attrs.id !== cached.attrs.id || data.attrs.key !== cached.attrs.key || - (m.redraw.strategy() === "all" && (!cached.configContext || - cached.configContext.retain !== true)) || - (m.redraw.strategy() === "diff" && cached.configContext && - cached.configContext.retain === false)) { - if (cached.nodes.length) clear(cached.nodes) - if (cached.configContext && - isFunction(cached.configContext.onunload)) { - cached.configContext.onunload() - } + (m.redraw.strategy() === "all" && (!cached.configContext || cached.configContext.retain !== true)) || + (m.redraw.strategy() === "diff" && cached.configContext && cached.configContext.retain === false)) { + if (cached.nodes.length) clear(cached.nodes); + if (cached.configContext && isFunction(cached.configContext.onunload)) cached.configContext.onunload(); if (cached.controllers) { forEach(cached.controllers, function (controller) { - if (controller.unload) { - controller.onunload({preventDefault: noop}) - } - }) + if (controller.unload) controller.onunload({preventDefault: noop}); + }); } } } function getObjectNamespace(data, namespace) { - if (data.attrs.xmlns) { - return data.attrs.xmlns - } else if (data.tag === "svg") { - return "http://www.w3.org/2000/svg" - } else if (data.tag === "math") { - return "http://www.w3.org/1998/Math/MathML" - } else { - return namespace - } + return data.attrs.xmlns ? data.attrs.xmlns : + data.tag === "svg" ? "http://www.w3.org/2000/svg" : + data.tag === "math" ? "http://www.w3.org/1998/Math/MathML" : + namespace; } function unloadCachedControllers(cached, views, controllers) { if (controllers.length) { - cached.views = views - cached.controllers = controllers + cached.views = views; + cached.controllers = controllers; forEach(controllers, function (controller) { - if (controller.onunload && controller.onunload.$old) { - controller.onunload = controller.onunload.$old - } + if (controller.onunload && controller.onunload.$old) controller.onunload = controller.onunload.$old; if (pendingRequests && controller.onunload) { - var onunload = controller.onunload - controller.onunload = noop - controller.onunload.$old = onunload + var onunload = controller.onunload; + controller.onunload = noop; + controller.onunload.$old = onunload; } - }) + }); } } function scheduleConfigsToBeCalled(configs, data, node, isNew, cached) { - // schedule configs to be called. They are called after `build` - // finishes running + //schedule configs to be called. They are called after `build` + //finishes running if (isFunction(data.attrs.config)) { - var context = cached.configContext = cached.configContext || {} + var context = cached.configContext = cached.configContext || {}; - // bind + //bind configs.push(function() { - return data.attrs.config.call(data, node, !isNew, context, - cached) - }) + return data.attrs.config.call(data, node, !isNew, context, cached); + }); } } - function buildUpdatedNode( - cached, - data, - editable, - hasKeys, - namespace, - views, - configs, - controllers) { - var node = cached.nodes[0] - if (hasKeys) { - setAttributes( - node, - data.tag, - data.attrs, - cached.attrs, - namespace) - } + function buildUpdatedNode(cached, data, editable, hasKeys, namespace, views, configs, controllers) { + var node = cached.nodes[0]; + if (hasKeys) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace); + cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs); + cached.nodes.intact = true; - cached.children = build( - node, - data.tag, - undefined, - undefined, - data.children, - cached.children, - false, - 0, - data.attrs.contenteditable ? node : editable, - namespace, - configs) - - cached.nodes.intact = true if (controllers.length) { - cached.views = views - cached.controllers = controllers + cached.views = views; + cached.controllers = controllers; } - return node + return node; } function handleNonexistentNodes(data, parentElement, index) { - var nodes + var nodes; if (data.$trusted) { - nodes = injectHTML(parentElement, index, data) - } else { - nodes = [$document.createTextNode(data)] - if (!parentElement.nodeName.match(voidElements)) { - insertNode(parentElement, nodes[0], index) - } + nodes = injectHTML(parentElement, index, data); + } + else { + nodes = [$document.createTextNode(data)]; + if (!parentElement.nodeName.match(voidElements)) insertNode(parentElement, nodes[0], index); } - var cached - if (typeof data === "string" || - typeof data === "number" || - typeof data === "boolean") { - cached = new data.constructor(data) - } else { - cached = data - } - cached.nodes = nodes - return cached + var cached = typeof data === "string" || typeof data === "number" || typeof data === "boolean" ? new data.constructor(data) : data; + cached.nodes = nodes; + return cached; } - function reattachNodes( - data, - cached, - parentElement, - editable, - index, - parentTag) { - var nodes = cached.nodes + function reattachNodes(data, cached, parentElement, editable, index, parentTag) { + var nodes = cached.nodes; if (!editable || editable !== $document.activeElement) { if (data.$trusted) { - clear(nodes, cached) - nodes = injectHTML(parentElement, index, data) - } else { - // corner case: replacing the nodeValue of a text node - // that is a child of a textarea/contenteditable doesn't - // work. we need to update the value property of the - // parent textarea or the innerHTML of the - // contenteditable element instead - if (parentTag === "textarea") { - parentElement.value = data - } else if (editable) { - editable.innerHTML = data - } else { - // was a trusted string - if (nodes[0].nodeType === 1 || nodes.length > 1) { - clear(cached.nodes, cached) - nodes = [$document.createTextNode(data)] - } - injectTextNode(parentElement, nodes[0], index, data) + clear(nodes, cached); + nodes = injectHTML(parentElement, index, data); + } + //corner case: replacing the nodeValue of a text node that is a child of a textarea/contenteditable doesn't work + //we need to update the value property of the parent textarea or the innerHTML of the contenteditable element instead + else if (parentTag === "textarea") { + parentElement.value = data; + } + else if (editable) { + editable.innerHTML = data; + } + else { + //was a trusted string + if (nodes[0].nodeType === 1 || nodes.length > 1) { + clear(cached.nodes, cached); + nodes = [$document.createTextNode(data)]; } + injectTextNode(parentElement, nodes[0], index, data); } } - cached = new data.constructor(data) - cached.nodes = nodes - return cached + cached = new data.constructor(data); + cached.nodes = nodes; + return cached; } - function handleText( - cached, - data, - index, - parentElement, - shouldReattach, - editable, - parentTag) { - // handle text nodes - if (cached.nodes.length === 0) { - return handleNonexistentNodes(data, parentElement, index) - } else if (cached.valueOf() !== data.valueOf() || - shouldReattach === true) { - return reattachNodes( - data, - cached, - parentElement, - editable, - index, - parentTag) - } else { - cached.nodes.intact = true - return cached - } + function handleText(cached, data, index, parentElement, shouldReattach, editable, parentTag) { + //handle text nodes + return cached.nodes.length === 0 ? handleNonexistentNodes(data, parentElement, index) : + cached.valueOf() !== data.valueOf() || shouldReattach === true ? + reattachNodes(data, cached, parentElement, editable, index, parentTag) : + (cached.nodes.intact = true, cached); } function getSubArrayCount(item) { if (item.$trusted) { - // fix offset of next element if item was a trusted - // string w/ more than one html element - // the first clause in the regexp matches elements - // the second clause (after the pipe) matches text nodes - var match = item.match(/<[^\/]|\>\s*[^<]/g) - if (match != null) { - return match.length - } - } else if (isArray(item)) { - return item.length + //fix offset of next element if item was a trusted string w/ more than one html element + //the first clause in the regexp matches elements + //the second clause (after the pipe) matches text nodes + var match = item.match(/<[^\/]|\>\s*[^<]/g); + if (match != null) return match.length; } - return 1 + else if (isArray(item)) { + return item.length; + } + return 1; } - function buildArray( - data, - cached, - parentElement, - index, - parentTag, - shouldReattach, - editable, - namespace, - configs) { - data = flatten(data) - var nodes = [] - var intact = cached.length === data.length - var subArrayCount = 0 + function buildArray(data, cached, parentElement, index, parentTag, shouldReattach, editable, namespace, configs) { + data = flatten(data); + var nodes = [], intact = cached.length === data.length, subArrayCount = 0; - // keys algorithm: sort elements without recreating them if keys are - // present - // 1) create a map of all existing keys, and mark all for deletion - // 2) add new keys to map and mark them for addition - // 3) if key exists in new list, change action from deletion to a - // move - // 4) for each key, handle its corresponding action as marked in - // previous steps - var existing = {} - var shouldMaintainIdentities = false + //keys algorithm: sort elements without recreating them if keys are present + //1) create a map of all existing keys, and mark all for deletion + //2) add new keys to map and mark them for addition + //3) if key exists in new list, change action from deletion to a move + //4) for each key, handle its corresponding action as marked in previous steps + var existing = {}, shouldMaintainIdentities = false; forKeys(cached, function (attrs, i) { - shouldMaintainIdentities = true - existing[cached[i].attrs.key] = {action: DELETION, index: i} - }) + shouldMaintainIdentities = true; + existing[cached[i].attrs.key] = {action: DELETION, index: i}; + }); - buildArrayKeys(data) + buildArrayKeys(data); + if (shouldMaintainIdentities) cached = diffKeys(data, cached, existing, parentElement); + //end key algorithm - if (shouldMaintainIdentities) { - cached = diffKeys(data, cached, existing, parentElement) - } - // end key algorithm - - var cacheCount = 0 + var cacheCount = 0; + //faster explicitly written for (var i = 0, len = data.length; i < len; i++) { - // diff each item in the array - var item = build( - parentElement, - parentTag, - cached, - index, - data[i], - cached[cacheCount], - shouldReattach, - index + subArrayCount || subArrayCount, - editable, - namespace, - configs) + //diff each item in the array + var item = build(parentElement, parentTag, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace, configs); if (item !== undefined) { - intact = intact && item.nodes.intact - subArrayCount += getSubArrayCount(item) - cached[cacheCount++] = item + intact = intact && item.nodes.intact; + subArrayCount += getSubArrayCount(item); + cached[cacheCount++] = item; } } - if (!intact) diffArray(data, cached, nodes) - + if (!intact) diffArray(data, cached, nodes); return cached } function makeCache(data, cached, index, parentIndex, parentCache) { if (cached != null) { - if (type.call(cached) === type.call(data)) return cached + if (type.call(cached) === type.call(data)) return cached; if (parentCache && parentCache.nodes) { - var offset = index - parentIndex - var end = offset + - (isArray(data) ? data : cached.nodes).length - clear( - parentCache.nodes.slice(offset, end), - parentCache.slice(offset, end)) + var offset = index - parentIndex, end = offset + (isArray(data) ? data : cached.nodes).length; + clear(parentCache.nodes.slice(offset, end), parentCache.slice(offset, end)); } else if (cached.nodes) { - clear(cached.nodes, cached) + clear(cached.nodes, cached); } } - cached = new data.constructor() - // if constructor creates a virtual dom element, use a blank object - // as the base cached node instead of copying the virtual el (#277) - if (cached.tag) cached = {} - - cached.nodes = [] - - return cached + cached = new data.constructor(); + //if constructor creates a virtual dom element, use a blank object + //as the base cached node instead of copying the virtual el (#277) + if (cached.tag) cached = {}; + cached.nodes = []; + return cached; } function constructNode(data, namespace) { - if (data.attrs.is) { - if (namespace === undefined) { - return $document.createElement(data.tag, data.attrs.is) - } else { - return $document.createElementNS(namespace, data.tag, - data.attrs.is) - } - } else { - if (namespace === undefined) { - return $document.createElement(data.tag) - } else { - return $document.createElementNS(namespace, data.tag) - } - } + return namespace === undefined ? + data.attrs.is ? $document.createElement(data.tag, data.attrs.is) : $document.createElement(data.tag) : + data.attrs.is ? $document.createElementNS(namespace, data.tag, data.attrs.is) : $document.createElementNS(namespace, data.tag); } function constructAttrs(data, node, namespace, hasKeys) { - if (hasKeys) { - return setAttributes( - node, - data.tag, - data.attrs, - {}, - namespace) - } else { - return data.attrs - } + return hasKeys ? setAttributes(node, data.tag, data.attrs, {}, namespace) : data.attrs; } - function constructChildren( - data, - node, - cached, - editable, - namespace, - configs) { - if (data.children != null && data.children.length > 0) { - return build( - node, - data.tag, - undefined, - undefined, - data.children, - cached.children, - true, - 0, - data.attrs.contenteditable ? node : editable, - namespace, - configs) - } else { - return data.children - } + function constructChildren(data, node, cached, editable, namespace, configs) { + return data.children != null && data.children.length > 0 ? + build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs) : + data.children; } - function reconstructCached( - data, - cached, - attrs, - children, - node, - namespace, - views, - controllers) { - cached = { - tag: data.tag, - attrs: attrs, - children: children, - nodes: [node] - } - - unloadCachedControllers(cached, views, controllers) - - if (cached.children && !cached.children.nodes) { - cached.children.nodes = [] - } - // edge case: setting value on doesn't work before children exist, so set it again after children have been created + if (data.tag === "select" && "value" in data.attrs) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace); return cached } function getController(views, view, cachedControllers, controller) { - var controllerIndex = -1 - if (m.redraw.strategy() === "diff" && views) { - controllerIndex = views.indexOf(view) - } - if (controllerIndex > -1) { - return cachedControllers[controllerIndex] - } else if (typeof controller === "function") { - return new controller() - } else { - return {} - } + var controllerIndex = m.redraw.strategy() === "diff" && views ? views.indexOf(view) : -1; + return controllerIndex > -1 ? cachedControllers[controllerIndex] : + typeof controller === "function" ? new controller() : {}; } function updateLists(views, controllers, view, controller) { - if (controller.onunload != null) { - unloaders.push({ - controller: controller, - handler: controller.onunload - }) - } - views.push(view) - controllers.push(controller) + if (controller.onunload != null) unloaders.push({controller: controller, handler: controller.onunload}); + views.push(view); + controllers.push(controller); } - function checkView( - data, - view, - cached, - cachedControllers, - controllers, - views) { - var controller = getController(cached.views, view, cachedControllers, - data.controller) - var key = +(data && data.attrs && data.attrs.key) - if (pendingRequests === 0 || forcing || - cachedControllers && - cachedControllers.indexOf(controller) > -1) { - data = data.view(controller) - } else { - data = {tag: "placeholder"} - } - if (data.subtree === "retain") return cached - if (key === key) { - if (!data.attrs) data.attrs = {} - data.attrs.key = key - } - updateLists(views, controllers, view, controller) - return data + function checkView(data, view, cached, cachedControllers, controllers, views) { + var controller = getController(cached.views, view, cachedControllers, data.controller); + //Faster to coerce to number and check for NaN + var key = +(data && data.attrs && data.attrs.key); + data = pendingRequests === 0 || forcing || cachedControllers && cachedControllers.indexOf(controller) > -1 ? data.view(controller) : {tag: "placeholder"}; + if (data.subtree === "retain") return cached; + if (key === key) (data.attrs = data.attrs || {}).key = key; + updateLists(views, controllers, view, controller); + return data; } function markViews(data, cached, views, controllers) { - var cachedControllers - if (cached) { - cachedControllers = cached.controllers - } - while (data.view != null) { - data = checkView( - data, - data.view.$original || data.view, - cached, - cachedControllers, - controllers, - views) - } - return data + var cachedControllers = cached && cached.controllers; + while (data.view != null) data = checkView(data, data.view.$original || data.view, cached, cachedControllers, controllers, views); + return data; } - function buildObject( - data, - cached, - editable, - parentElement, - index, - shouldReattach, - namespace, - configs) { - var views = [] - var controllers = [] - data = markViews(data, cached, views, controllers) - if (!data.tag && controllers.length) { - throw new Error("Component template must return a virtual " + - "element, not an array, string, etc.") - } - if (!data.attrs) data.attrs = {} - if (!cached.attrs) cached.attrs = {} - - var dataAttrKeys = Object.keys(data.attrs) - var hasKeys = dataAttrKeys.length > ("key" in data.attrs ? 1 : 0) - maybeRecreateObject(data, cached, dataAttrKeys) - if (!isString(data.tag)) return undefined - - var isNew = cached.nodes.length === 0 - namespace = getObjectNamespace(data, namespace) - - var node - + function buildObject(data, cached, editable, parentElement, index, shouldReattach, namespace, configs) { + var views = [], controllers = []; + data = markViews(data, cached, views, controllers); + if (!data.tag && controllers.length) throw new Error("Component template must return a virtual element, not an array, string, etc."); + data.attrs = data.attrs || {}; + cached.attrs = cached.attrs || {}; + var dataAttrKeys = Object.keys(data.attrs); + var hasKeys = dataAttrKeys.length > ("key" in data.attrs ? 1 : 0); + maybeRecreateObject(data, cached, dataAttrKeys); + if (!isString(data.tag)) return; + var isNew = cached.nodes.length === 0; + namespace = getObjectNamespace(data, namespace); + var node; if (isNew) { - node = constructNode(data, namespace) - - // set attributes first, then create children + node = constructNode(data, namespace); + //set attributes first, then create children var attrs = constructAttrs(data, node, namespace, hasKeys) - var children = constructChildren(data, node, cached, editable, - namespace, configs) - - cached = reconstructCached( - data, - cached, - attrs, - children, - node, - namespace, - views, - controllers) - } else { - node = buildUpdatedNode( - cached, - data, - editable, - hasKeys, - namespace, - views, - configs, - controllers) + var children = constructChildren(data, node, cached, editable, namespace, configs); + cached = reconstructCached(data, attrs, children, node, namespace, views, controllers); } - if (isNew || shouldReattach === true && node != null) { - insertNode(parentElement, node, index) + else { + node = buildUpdatedNode(cached, data, editable, hasKeys, namespace, views, configs, controllers); } - // schedule configs to be called. They are called after `build` - // finishes running - scheduleConfigsToBeCalled(configs, data, node, isNew, cached) - + if (isNew || shouldReattach === true && node != null) insertNode(parentElement, node, index); + //schedule configs to be called. They are called after `build` + //finishes running + scheduleConfigsToBeCalled(configs, data, node, isNew, cached); return cached } - function build( - parentElement, - parentTag, - parentCache, - parentIndex, - data, - cached, - shouldReattach, - index, - editable, - namespace, - configs) { - // `build` is a recursive function that manages creation/diffing/removal - // of DOM elements based on comparison between `data` and `cached` - // the diff algorithm can be summarized as this: - // 1 - compare `data` and `cached` - // 2 - if they are different, copy `data` to `cached` and update the DOM - // based on what the difference is - // 3 - recursively apply this algorithm for every array and for the - // children of every virtual element + function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace, configs) { + //`build` is a recursive function that manages creation/diffing/removal + //of DOM elements based on comparison between `data` and `cached` + //the diff algorithm can be summarized as this: + //1 - compare `data` and `cached` + //2 - if they are different, copy `data` to `cached` and update the DOM + // based on what the difference is + //3 - recursively apply this algorithm for every array and for the + // children of every virtual element - // the `cached` data structure is essentially the same as the previous - // redraw's `data` data structure, with a few additions: - // - `cached` always has a property called `nodes`, which is a list of - // DOM elements that correspond to the data represented by the - // respective virtual element - // - in order to support attaching `nodes` as a property of `cached`, - // `cached` is *always* a non-primitive object, i.e. if the data was - // a string, then cached is a String instance. If data was `null` or - // `undefined`, cached is `new String("")` - // - `cached also has a `configContext` property, which is the state - // storage object exposed by config(element, isInitialized, context) - // - when `cached` is an Object, it represents a virtual element; when - // it's an Array, it represents a list of elements; when it's a - // String, Number or Boolean, it represents a text node + //the `cached` data structure is essentially the same as the previous + //redraw's `data` data structure, with a few additions: + //- `cached` always has a property called `nodes`, which is a list of + // DOM elements that correspond to the data represented by the + // respective virtual element + //- in order to support attaching `nodes` as a property of `cached`, + // `cached` is *always* a non-primitive object, i.e. if the data was + // a string, then cached is a String instance. If data was `null` or + // `undefined`, cached is `new String("")` + //- `cached also has a `configContext` property, which is the state + // storage object exposed by config(element, isInitialized, context) + //- when `cached` is an Object, it represents a virtual element; when + // it's an Array, it represents a list of elements; when it's a + // String, Number or Boolean, it represents a text node - // `parentElement` is a DOM element used for W3C DOM API calls - // `parentTag` is only used for handling a corner case for textarea - // values - // `parentCache` is used to remove nodes in some multi-node cases - // `parentIndex` and `index` are used to figure out the offset of nodes. - // They're artifacts from before arrays started being flattened and are - // likely refactorable - // `data` and `cached` are, respectively, the new and old nodes being - // diffed - // `shouldReattach` is a flag indicating whether a parent node was - // recreated (if so, and if this node is reused, then this node must - // reattach itself to the new parent) - // `editable` is a flag that indicates whether an ancestor is - // contenteditable - // `namespace` indicates the closest HTML namespace as it cascades down - // from an ancestor - // `configs` is a list of config functions to run after the topmost - // `build` call finishes running - - // there's logic that relies on the assumption that null and undefined - // data are equivalent to empty strings - // - this prevents lifecycle surprises from procedural helpers that mix - // implicit and explicit return statements (e.g. - // function foo() {if (cond) return m("div")} - // - it simplifies diffing code - data = dataToString(data) - if (data.subtree === "retain") return cached - - cached = makeCache( - data, - cached, - index, - parentIndex, - parentCache) - - if (isArray(data)) { - return buildArray( - data, - cached, - parentElement, - index, - parentTag, - shouldReattach, - editable, - namespace, - configs) - } else if (data != null && isObject(data)) { - return buildObject( - data, - cached, - editable, - parentElement, - index, - shouldReattach, - namespace, - configs) - } else if (!isFunction(data)) { - return handleText( - cached, - data, - index, - parentElement, - shouldReattach, - editable, - parentTag) - } else { - return cached - } + //`parentElement` is a DOM element used for W3C DOM API calls + //`parentTag` is only used for handling a corner case for textarea + //values + //`parentCache` is used to remove nodes in some multi-node cases + //`parentIndex` and `index` are used to figure out the offset of nodes. + //They're artifacts from before arrays started being flattened and are + //likely refactorable + //`data` and `cached` are, respectively, the new and old nodes being + //diffed + //`shouldReattach` is a flag indicating whether a parent node was + //recreated (if so, and if this node is reused, then this node must + //reattach itself to the new parent) + //`editable` is a flag that indicates whether an ancestor is + //contenteditable + //`namespace` indicates the closest HTML namespace as it cascades down + //from an ancestor + //`configs` is a list of config functions to run after the topmost + //`build` call finishes running + //there's logic that relies on the assumption that null and undefined + //data are equivalent to empty strings + //- this prevents lifecycle surprises from procedural helpers that mix + // implicit and explicit return statements (e.g. + // function foo() {if (cond) return m("div")} + //- it simplifies diffing code + data = dataToString(data); + if (data.subtree === "retain") return cached; + cached = makeCache(data, cached, index, parentIndex, parentCache); + return isArray(data) ? buildArray(data, cached, parentElement, index, parentTag, shouldReattach, editable, namespace, configs) : + data != null && isObject(data) ? buildObject(data, cached, editable, parentElement, index, shouldReattach, namespace, configs) : + !isFunction(data) ? handleText(cached, data, index, parentElement, shouldReattach, editable, parentTag) : + cached; } - function sortChanges(a, b) { - return a.action - b.action || a.index - b.index - } + function sortChanges(a, b) { return a.action - b.action || a.index - b.index; } function setAttributes(node, tag, dataAttrs, cachedAttrs, namespace) { for (var attrName in dataAttrs) { - var dataAttr = dataAttrs[attrName] - var cachedAttr = cachedAttrs[attrName] - var rule + var dataAttr = dataAttrs[attrName]; + var cachedAttr = cachedAttrs[attrName]; if (!(attrName in cachedAttrs) || (cachedAttr !== dataAttr)) { - cachedAttrs[attrName] = dataAttr + cachedAttrs[attrName] = dataAttr; try { - if (attrName === "config" || attrName === "key") { - // `config` isn't a real attributes, so ignore it - } else if (isFunction(dataAttr) && - attrName.slice(0, 2) === "on") { - // hook event handlers to the auto-redrawing system - node[attrName] = autoredraw(dataAttr, node) - } else if (attrName === "style" && - dataAttr != null && - isObject(dataAttr)) { - // handle `style: {...}` - for (rule in dataAttr) { - if (cachedAttr == null || - cachedAttr[rule] !== dataAttr[rule]) { - node.style[rule] = dataAttr[rule] - } - } - for (rule in cachedAttr) { - if (!(rule in dataAttr)) node.style[rule] = "" - } - } else if (namespace != null) { - // handle SVG - if (attrName === "href") { - node.setAttributeNS( - "http://www.w3.org/1999/xlink", - "href", - dataAttr) - } else if (attrName === "className") { - node.setAttribute("class", dataAttr) - } else { - node.setAttribute(attrName, dataAttr) - } - } else if (attrName in node && - !(attrName === "list" || - attrName === "style" || - attrName === "form" || - attrName === "type" || - attrName === "width" || - attrName === "height")) { - // handle cases that are properties (but ignore cases - // where we should use setAttribute instead) - // - list and form are typically used as strings, but - // are DOM element references in js - // - when using CSS selectors (e.g. `m("[style='']")`), - // style is used as a string, but it's an object in js - - // #348 don't set the value if not needed otherwise - // cursor placement breaks in Chrome - if (tag !== "input" || node[attrName] !== dataAttr) { - node[attrName] = dataAttr - } - } else { - node.setAttribute(attrName, dataAttr) + //`config` isn't a real attributes, so ignore it + if (attrName === "config" || attrName === "key") continue; + //hook event handlers to the auto-redrawing system + else if (isFunction(dataAttr) && attrName.slice(0, 2) === "on") { + node[attrName] = autoredraw(dataAttr, node); } - } catch (e) { - // swallow IE's invalid argument errors to mimic HTML's - // fallback-to-doing-nothing-on-invalid-attributes behavior - if (e.message.indexOf("Invalid argument") < 0) throw e + //handle `style: {...}` + else if (attrName === "style" && dataAttr != null && isObject(dataAttr)) { + for (var rule in dataAttr) { + if (cachedAttr == null || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]; + } + for (var rule in cachedAttr) { + if (!(rule in dataAttr)) node.style[rule] = ""; + } + } + //handle SVG + else if (namespace != null) { + if (attrName === "href") node.setAttributeNS("http://www.w3.org/1999/xlink", "href", dataAttr); + else node.setAttribute(attrName === "className" ? "class" : attrName, dataAttr); + } + //handle cases that are properties (but ignore cases where we should use setAttribute instead) + //- list and form are typically used as strings, but are DOM element references in js + //- when using CSS selectors (e.g. `m("[style='']")`), style is used as a string, but it's an object in js + else if (attrName in node && attrName !== "list" && attrName !== "style" && attrName !== "form" && attrName !== "type" && attrName !== "width" && attrName !== "height") { + //#348 don't set the value if not needed otherwise cursor placement breaks in Chrome + if (tag !== "input" || node[attrName] !== dataAttr) node[attrName] = dataAttr; + } + else node.setAttribute(attrName, dataAttr); } - } else if (attrName === "value" && - tag === "input" && - node.value !== dataAttr) { - // #348 dataAttr may not be a string, so use loose comparison - // (double equal) instead of strict (triple equal) - node.value = dataAttr + catch (e) { + //swallow IE's invalid argument errors to mimic HTML's fallback-to-doing-nothing-on-invalid-attributes behavior + if (e.message.indexOf("Invalid argument") < 0) throw e; + } + } + //#348 dataAttr may not be a string, so use loose comparison (double equal) instead of strict (triple equal) + else if (attrName === "value" && tag === "input" && node.value != dataAttr) { + node.value = dataAttr; } } - - return cachedAttrs + return cachedAttrs; } - function clear(nodes, cached) { for (var i = nodes.length - 1; i > -1; i--) { if (nodes[i] && nodes[i].parentNode) { - try { - nodes[i].parentNode.removeChild(nodes[i]) - } catch (e) { - /* eslint-disable max-len */ - // ignore if this fails due to order of events (see - // http://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node) - /* eslint-enable max-len */ - } - cached = [].concat(cached) - if (cached[i]) unload(cached[i]) + try { nodes[i].parentNode.removeChild(nodes[i]); } + catch (e) {} //ignore if this fails due to order of events (see http://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node) + cached = [].concat(cached); + if (cached[i]) unload(cached[i]); } } - nodes.length = 0 + nodes.length = 0; } - function unload(cached) { if (cached.configContext && isFunction(cached.configContext.onunload)) { - cached.configContext.onunload() - cached.configContext.onunload = null + cached.configContext.onunload(); + cached.configContext.onunload = null; } if (cached.controllers) { forEach(cached.controllers, function (controller) { - if (isFunction(controller.onunload)) { - controller.onunload({preventDefault: noop}) - } - }) + if (isFunction(controller.onunload)) controller.onunload({preventDefault: noop}); + }); } if (cached.children) { - if (isArray(cached.children)) { - forEach(cached.children, unload) - } else if (cached.children.tag) { - unload(cached.children) - } + if (isArray(cached.children)) forEach(cached.children, unload); + else if (cached.children.tag) unload(cached.children); } } - function injectHTML(parentElement, index, data) { - var nextSibling = parentElement.childNodes[index] + var nextSibling = parentElement.childNodes[index]; if (nextSibling) { - var isElement = nextSibling.nodeType !== 1 - var placeholder = $document.createElement("span") + var isElement = nextSibling.nodeType !== 1; + var placeholder = $document.createElement("span"); if (isElement) { - parentElement.insertBefore(placeholder, nextSibling || null) - placeholder.insertAdjacentHTML("beforebegin", data) - parentElement.removeChild(placeholder) - } else { - nextSibling.insertAdjacentHTML("beforebegin", data) + parentElement.insertBefore(placeholder, nextSibling || null); + placeholder.insertAdjacentHTML("beforebegin", data); + parentElement.removeChild(placeholder); } - } else { - parentElement.insertAdjacentHTML("beforeend", data) + else nextSibling.insertAdjacentHTML("beforebegin", data); } - var nodes = [] + else parentElement.insertAdjacentHTML("beforeend", data); + var nodes = []; while (parentElement.childNodes[index] !== nextSibling) { - nodes.push(parentElement.childNodes[index]) - index++ + nodes.push(parentElement.childNodes[index]); + index++; } - return nodes + return nodes; } - function autoredraw(callback, object) { return function(e) { - e = e || event - m.redraw.strategy("diff") - m.startComputation() - try { - return callback.call(object, e) - } finally { - endFirstComputation() + e = e || event; + m.redraw.strategy("diff"); + m.startComputation(); + try { return callback.call(object, e); } + finally { + endFirstComputation(); } - } + }; } - var html + var html; var documentNode = { appendChild: function(node) { - if (html === undefined) html = $document.createElement("html") - if ($document.documentElement && - $document.documentElement !== node) { - $document.replaceChild(node, $document.documentElement) - } else { - $document.appendChild(node) + if (html === undefined) html = $document.createElement("html"); + if ($document.documentElement && $document.documentElement !== node) { + $document.replaceChild(node, $document.documentElement); } - this.childNodes = $document.childNodes + else $document.appendChild(node); + this.childNodes = $document.childNodes; }, insertBefore: function(node) { - this.appendChild(node) + this.appendChild(node); }, childNodes: [] - } - - var nodeCache = [] - var cellCache = {} - + }; + var nodeCache = [], cellCache = {}; m.render = function(root, cell, forceRecreation) { - var configs = [] - if (!root) { - throw new Error("Ensure the DOM element being passed to " + - "m.route/m.mount/m.render is not undefined.") - } - var id = getCellCacheKey(root) - var isDocumentRoot = root === $document - var node - if (isDocumentRoot || root === $document.documentElement) { - node = documentNode - } else { - node = root - } - if (isDocumentRoot && cell.tag !== "html") { - cell = {tag: "html", attrs: {}, children: cell} - } - if (cellCache[id] === undefined) clear(node.childNodes) - if (forceRecreation === true) reset(root) - - cellCache[id] = build( - node, - null, - undefined, - undefined, - cell, - cellCache[id], - false, - 0, - null, - undefined, - configs) - - forEach(configs, function (config) { - config() - }) - } - + var configs = []; + if (!root) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined."); + var id = getCellCacheKey(root); + var isDocumentRoot = root === $document; + var node = isDocumentRoot || root === $document.documentElement ? documentNode : root; + if (isDocumentRoot && cell.tag !== "html") cell = {tag: "html", attrs: {}, children: cell}; + if (cellCache[id] === undefined) clear(node.childNodes); + if (forceRecreation === true) reset(root); + cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined, configs); + forEach(configs, function (config) { config(); }); + }; function getCellCacheKey(element) { - var index = nodeCache.indexOf(element) - return index < 0 ? nodeCache.push(element) - 1 : index + var index = nodeCache.indexOf(element); + return index < 0 ? nodeCache.push(element) - 1 : index; } m.trust = function(value) { - /* eslint-disable no-new-wrappers */ - value = new String(value) - /* eslint-enable no-new-wrappers */ - value.$trusted = true - return value - } + value = new String(value); + value.$trusted = true; + return value; + }; function gettersetter(store) { var prop = function() { - if (arguments.length) store = arguments[0] - return store - } + if (arguments.length) store = arguments[0]; + return store; + }; prop.toJSON = function() { - return store - } + return store; + }; - return prop + return prop; } m.prop = function (store) { - // note: using non-strict equality check here because we're checking if - // store is null OR undefined - if ((store != null && isObject(store) || isFunction(store)) && - isFunction(store.then)) { - return propify(store) + //note: using non-strict equality check here because we're checking if store is null OR undefined + if ((store != null && isObject(store) || isFunction(store)) && isFunction(store.then)) { + return propify(store); } - return gettersetter(store) - } + return gettersetter(store); + }; + var roots = [], components = [], controllers = [], lastRedrawId = null, lastRedrawCallTime = 0, computePreRedrawHook = null, computePostRedrawHook = null, topComponent, unloaders = []; + var FRAME_BUDGET = 16; //60 frames per second = 1 call per 16 ms function parameterize(component, args) { var controller = function() { - return (component.controller || noop).apply(this, args) || this - } - if (component.controller) { - controller.prototype = component.controller.prototype - } + return (component.controller || noop).apply(this, args) || this; + }; + if (component.controller) controller.prototype = component.controller.prototype; var view = function(ctrl) { - for (var i = 1; i < arguments.length; i++) { - args.push(arguments[i]) - } - return component.view.apply(component, [ctrl].concat(args)) - } - view.$original = component.view - var output = {controller: controller, view: view} - if (args[0] && args[0].key != null) output.attrs = {key: args[0].key} - return output + for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); + return component.view.apply(component, [ctrl].concat(args)); + }; + view.$original = component.view; + var output = {controller: controller, view: view}; + if (args[0] && args[0].key != null) output.attrs = {key: args[0].key}; + return output; } m.component = function(component) { - for (var args = [], i = 1; i < arguments.length; i++) { - args.push(arguments[i]) - } - return parameterize(component, args) - } + for (var args = [], i = 1; i < arguments.length; i++) args.push(arguments[i]); + return parameterize(component, args); + }; m.mount = m.module = function(root, component) { - if (!root) { - throw new Error("Please ensure the DOM element exists before " + - "rendering a template into it.") - } - var index = roots.indexOf(root) - if (index < 0) index = roots.length + if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it."); + var index = roots.indexOf(root); + if (index < 0) index = roots.length; - var isPrevented = false - var event = { - preventDefault: function() { - isPrevented = true - computePreRedrawHook = computePostRedrawHook = null - } - } + var isPrevented = false; + var event = {preventDefault: function() { + isPrevented = true; + computePreRedrawHook = computePostRedrawHook = null; + }}; forEach(unloaders, function (unloader) { - unloader.handler.call(unloader.controller, event) - unloader.controller.onunload = null - }) + unloader.handler.call(unloader.controller, event); + unloader.controller.onunload = null; + }); if (isPrevented) { forEach(unloaders, function (unloader) { - unloader.controller.onunload = unloader.handler - }) - } else { - unloaders = [] + unloader.controller.onunload = unloader.handler; + }); } + else unloaders = []; if (controllers[index] && isFunction(controllers[index].onunload)) { - controllers[index].onunload(event) + controllers[index].onunload(event); } if (!isPrevented) { - m.redraw.strategy("all") - m.startComputation() - roots[index] = root - var currentComponent - if (component) { - currentComponent = topComponent = component - } else { - currentComponent = topComponent = component = {controller: noop} - } - var constructor = component.controller || noop - var controller = new constructor() - // controllers may call m.mount recursively (via m.route redirects, - // for example). this conditional ensures only the last recursive - // m.mount call is applied + m.redraw.strategy("all"); + m.startComputation(); + roots[index] = root; + var currentComponent = component ? (topComponent = component) : (topComponent = component = {controller: noop}); + var controller = new (component.controller || noop)(); + //controllers may call m.mount recursively (via m.route redirects, for example) + //this conditional ensures only the last recursive m.mount call is applied if (currentComponent === topComponent) { - controllers[index] = controller - components[index] = component + controllers[index] = controller; + components[index] = component; } - endFirstComputation() - return controllers[index] + endFirstComputation(); + return controllers[index]; } - } + }; + var redrawing = false, forcing = false; m.redraw = function(force) { - if (redrawing) return - redrawing = true - if (force) forcing = true + if (redrawing) return; + redrawing = true; + if (force) forcing = true; try { - // lastRedrawId is a positive number if a second redraw is requested - // before the next animation frame - // lastRedrawID is null if it's the first redraw and not an event - // handler + //lastRedrawId is a positive number if a second redraw is requested before the next animation frame + //lastRedrawID is null if it's the first redraw and not an event handler if (lastRedrawId && !force) { - // when setTimeout: only reschedule redraw if time between now - // and previous redraw is bigger than a frame, otherwise keep - // currently scheduled timeout - // when rAF: always reschedule redraw - if ($requestAnimationFrame === window.requestAnimationFrame || - new Date() - lastRedrawCallTime > FRAME_BUDGET) { - if (lastRedrawId > 0) $cancelAnimationFrame(lastRedrawId) - lastRedrawId = $requestAnimationFrame(redraw, FRAME_BUDGET) + //when setTimeout: only reschedule redraw if time between now and previous redraw is bigger than a frame, otherwise keep currently scheduled timeout + //when rAF: always reschedule redraw + if ($requestAnimationFrame === window.requestAnimationFrame || new Date - lastRedrawCallTime > FRAME_BUDGET) { + if (lastRedrawId > 0) $cancelAnimationFrame(lastRedrawId); + lastRedrawId = $requestAnimationFrame(redraw, FRAME_BUDGET); } - } else { - redraw() - lastRedrawId = $requestAnimationFrame(function() { - lastRedrawId = null - }, FRAME_BUDGET) } - } finally { - redrawing = forcing = false + else { + redraw(); + lastRedrawId = $requestAnimationFrame(function() { lastRedrawId = null; }, FRAME_BUDGET); + } } - } - m.redraw.strategy = m.prop() + finally { + redrawing = forcing = false; + } + }; + m.redraw.strategy = m.prop(); function redraw() { if (computePreRedrawHook) { - computePreRedrawHook() - computePreRedrawHook = null + computePreRedrawHook(); + computePreRedrawHook = null; } forEach(roots, function (root, i) { - var component = components[i] + var component = components[i]; if (controllers[i]) { - var args - if (component.controller && component.controller.$$args) { - args = [controllers[i]].concat(component.controller.$$args) - } else { - args = [controllers[i]] - } - var view - if (component.view) { - view = component.view(controllers[i], args) - } else { - view = "" - } - m.render(root, view) + var args = [controllers[i]]; + if (component.controller && component.controller.$$args) args = args.concat(component.controller.$$args); + m.render(root, component.view ? component.view(controllers[i], args) : ""); } - }) - // after rendering within a routed context, we need to scroll back to - // the top, and fetch the document title for history.pushState + }); + //after rendering within a routed context, we need to scroll back to the top, and fetch the document title for history.pushState if (computePostRedrawHook) { - computePostRedrawHook() - computePostRedrawHook = null + computePostRedrawHook(); + computePostRedrawHook = null; } - lastRedrawId = null - lastRedrawCallTime = new Date() - m.redraw.strategy("diff") + lastRedrawId = null; + lastRedrawCallTime = new Date; + m.redraw.strategy("diff"); } - m.startComputation = function() { pendingRequests++ } + var pendingRequests = 0; + m.startComputation = function() { pendingRequests++; }; m.endComputation = function() { - if (pendingRequests > 1) { - pendingRequests-- - } else { - pendingRequests = 0 - m.redraw() + if (pendingRequests > 1) pendingRequests--; + else { + pendingRequests = 0; + m.redraw(); } } function endFirstComputation() { if (m.redraw.strategy() === "none") { - pendingRequests-- - m.redraw.strategy("diff") - } else { - m.endComputation() + pendingRequests--; + m.redraw.strategy("diff"); } + else m.endComputation(); } m.withAttr = function(prop, withAttrCallback) { return function(e) { - e = e || event - var currentTarget = e.currentTarget || this - var arg - if (prop in currentTarget) { - arg = currentTarget[prop] - } else { - arg = currentTarget.getAttribute(prop) - } - withAttrCallback(arg) - } - } + e = e || event; + var currentTarget = e.currentTarget || this; + withAttrCallback(prop in currentTarget ? currentTarget[prop] : currentTarget.getAttribute(prop)); + }; + }; - // routing - var modes = {pathname: "", hash: "#", search: "?"} - var redirect = noop - var isDefaultRoute = false - var routeParams, currentRoute + //routing + var modes = {pathname: "", hash: "#", search: "?"}; + var redirect = noop, routeParams, currentRoute, isDefaultRoute = false; m.route = function(root, arg1, arg2, vdom) { - // m.route() - if (arguments.length === 0) { - return currentRoute - } else if (arguments.length === 3 && isString(arg1)) { - // m.route(el, defaultRoute, routes) + //m.route() + if (arguments.length === 0) return currentRoute; + //m.route(el, defaultRoute, routes) + else if (arguments.length === 3 && isString(arg1)) { redirect = function(source) { - var path = currentRoute = normalizeRoute(source) + var path = currentRoute = normalizeRoute(source); if (!routeByValue(root, arg2, path)) { - if (isDefaultRoute) { - throw new Error("Ensure the default route matches " + - "one of the routes defined in m.route") - } - isDefaultRoute = true - m.route(arg1, true) - isDefaultRoute = false + if (isDefaultRoute) throw new Error("Ensure the default route matches one of the routes defined in m.route"); + isDefaultRoute = true; + m.route(arg1, true); + isDefaultRoute = false; } - } - var listener - if (m.route.mode === "hash") { - listener = "onhashchange" - } else { - listener = "onpopstate" - } - + }; + var listener = m.route.mode === "hash" ? "onhashchange" : "onpopstate"; window[listener] = function() { - var path = $location[m.route.mode] - if (m.route.mode === "pathname") path += $location.search - if (currentRoute !== normalizeRoute(path)) { - redirect(path) - } - } + var path = $location[m.route.mode]; + if (m.route.mode === "pathname") path += $location.search; + if (currentRoute !== normalizeRoute(path)) redirect(path); + }; - computePreRedrawHook = setScroll - window[listener]() - } else if (root.addEventListener || root.attachEvent) { - // config: m.route - var pathname = m.route.mode !== "pathname" ? $location.pathname : "" - root.href = pathname + modes[m.route.mode] + vdom.attrs.href + computePreRedrawHook = setScroll; + window[listener](); + } + //config: m.route + else if (root.addEventListener || root.attachEvent) { + root.href = (m.route.mode !== 'pathname' ? $location.pathname : '') + modes[m.route.mode] + vdom.attrs.href; if (root.addEventListener) { - root.removeEventListener("click", routeUnobtrusive) - root.addEventListener("click", routeUnobtrusive) - } else { - root.detachEvent("onclick", routeUnobtrusive) - root.attachEvent("onclick", routeUnobtrusive) + root.removeEventListener("click", routeUnobtrusive); + root.addEventListener("click", routeUnobtrusive); } - } else if (isString(root)) { - // m.route(route, params, shouldReplaceHistoryEntry) - var oldRoute = currentRoute - currentRoute = root - arg1 = arg1 || {} - var queryIndex = currentRoute.indexOf("?") - var params - if (queryIndex > -1) { - params = parseQueryString(currentRoute.slice(queryIndex + 1)) - } else { - params = {} + else { + root.detachEvent("onclick", routeUnobtrusive); + root.attachEvent("onclick", routeUnobtrusive); } - for (var i in arg1) params[i] = arg1[i] - var querystring = buildQueryString(params) - var currentPath + } + //m.route(route, params, shouldReplaceHistoryEntry) + else if (isString(root)) { + var oldRoute = currentRoute; + currentRoute = root; + var args = arg1 || {}; + var queryIndex = currentRoute.indexOf("?"); + var params = queryIndex > -1 ? parseQueryString(currentRoute.slice(queryIndex + 1)) : {}; + for (var i in args) params[i] = args[i]; + var querystring = buildQueryString(params); + var currentPath = queryIndex > -1 ? currentRoute.slice(0, queryIndex) : currentRoute; + if (querystring) currentRoute = currentPath + (currentPath.indexOf("?") === -1 ? "?" : "&") + querystring; - if (queryIndex > -1) { - currentPath = currentRoute.slice(0, queryIndex) - } else { - currentPath = currentRoute - } - - var separator = currentPath.indexOf("?") === -1 ? "?" : "&" - - if (querystring) { - currentRoute = currentPath + separator + querystring - } - - var shouldReplaceHistoryEntry - if (arguments.length === 3) { - shouldReplaceHistoryEntry = arg2 - } else { - shouldReplaceHistoryEntry = arg1 - } - - shouldReplaceHistoryEntry = shouldReplaceHistoryEntry === true || - oldRoute === root + var shouldReplaceHistoryEntry = (arguments.length === 3 ? arg2 : arg1) === true || oldRoute === root; if (window.history.pushState) { - computePreRedrawHook = setScroll + computePreRedrawHook = setScroll; computePostRedrawHook = function() { - var listener - if (shouldReplaceHistoryEntry) { - listener = "replaceState" - } else { - listener = "pushState" - } - window.history[listener]( - null, - $document.title, - modes[m.route.mode] + currentRoute) - } - redirect(modes[m.route.mode] + currentRoute) - } else { - $location[m.route.mode] = currentRoute - redirect(modes[m.route.mode] + currentRoute) + window.history[shouldReplaceHistoryEntry ? "replaceState" : "pushState"](null, $document.title, modes[m.route.mode] + currentRoute); + }; + redirect(modes[m.route.mode] + currentRoute); + } + else { + $location[m.route.mode] = currentRoute; + redirect(modes[m.route.mode] + currentRoute); } } - } + }; m.route.param = function(key) { - if (!routeParams) { - throw new Error("You must call m.route(element, defaultRoute, " + - "routes) before calling m.route.param()") - } - return routeParams[key] - } - m.route.mode = "search" + if (!routeParams) throw new Error("You must call m.route(element, defaultRoute, routes) before calling m.route.param()"); + return routeParams[key]; + }; + m.route.mode = "search"; function normalizeRoute(route) { - return route.slice(modes[m.route.mode].length) + return route.slice(modes[m.route.mode].length); } function routeByValue(root, router, path) { - routeParams = {} + routeParams = {}; - var queryStart = path.indexOf("?") + var queryStart = path.indexOf("?"); if (queryStart !== -1) { - routeParams = parseQueryString( - path.substr(queryStart + 1, path.length)) - path = path.substr(0, queryStart) + routeParams = parseQueryString(path.substr(queryStart + 1, path.length)); + path = path.substr(0, queryStart); } // Get all routes and check if there's // an exact match for the current path - var keys = Object.keys(router) - var index = keys.indexOf(path) + var keys = Object.keys(router); + var index = keys.indexOf(path); if(index !== -1){ - m.mount(root, router[keys [index]]) - return true + m.mount(root, router[keys [index]]); + return true; } for (var route in router) { if (route === path) { - m.mount(root, router[route]) - return true + m.mount(root, router[route]); + return true; } - var matcher = new RegExp("^" + route - .replace(/:[^\/]+?\.{3}/g, "(.*?)") - .replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$") + var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$"); if (matcher.test(path)) { - /* eslint-disable no-loop-func */ path.replace(matcher, function() { - var keys = route.match(/:[^\/]+/g) || [] - var values = [].slice.call(arguments, 1, -2) + var keys = route.match(/:[^\/]+/g) || []; + var values = [].slice.call(arguments, 1, -2); forEach(keys, function (key, i) { - routeParams[key.replace(/:|\./g, "")] = - decodeURIComponent(values[i]) + routeParams[key.replace(/:|\./g, "")] = decodeURIComponent(values[i]); }) - m.mount(root, router[route]) - }) - /* eslint-enable no-loop-func */ - return true + m.mount(root, router[route]); + }); + return true; } } } function routeUnobtrusive(e) { - e = e || event + e = e || event; - if (e.ctrlKey || e.metaKey || e.which === 2) return + if (e.ctrlKey || e.metaKey || e.which === 2) return; - if (e.preventDefault) e.preventDefault() - else e.returnValue = false + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; - var currentTarget = e.currentTarget || e.srcElement - var hasQuery = m.route.mode === "pathname" && currentTarget.search - var args - - if (hasQuery) { - args = parseQueryString(currentTarget.search.slice(1)) - } else { - args = {} - } - - while (currentTarget && currentTarget.nodeName.toUpperCase() !== "A") { - currentTarget = currentTarget.parentNode - } - - var target = currentTarget[m.route.mode] - .slice(modes[m.route.mode].length) - - m.route(target, args) + var currentTarget = e.currentTarget || e.srcElement; + var args = m.route.mode === "pathname" && currentTarget.search ? parseQueryString(currentTarget.search.slice(1)) : {}; + while (currentTarget && currentTarget.nodeName.toUpperCase() !== "A") currentTarget = currentTarget.parentNode; + m.route(currentTarget[m.route.mode].slice(modes[m.route.mode].length), args); } function setScroll() { - if (m.route.mode !== "hash" && $location.hash) { - $location.hash = $location.hash - } else { - window.scrollTo(0, 0) - } + if (m.route.mode !== "hash" && $location.hash) $location.hash = $location.hash; + else window.scrollTo(0, 0); } function buildQueryString(object, prefix) { - var duplicates = {} - var str = [] + var duplicates = {}; + var str = []; for (var prop in object) { - var key = prefix ? prefix + "[" + prop + "]" : prop - var value = object[prop] + var key = prefix ? prefix + "[" + prop + "]" : prop; + var value = object[prop]; if (value === null) { - str.push(encodeURIComponent(key)) + str.push(encodeURIComponent(key)); } else if (isObject(value)) { - str.push(buildQueryString(value, key)) + str.push(buildQueryString(value, key)); } else if (isArray(value)) { - var keys = [] - /* eslint-disable no-loop-func */ + var keys = []; + duplicates[key] = duplicates[key] || {}; forEach(value, function (item) { - if (!duplicates[key]) duplicates[key] = {} if (!duplicates[key][item]) { - duplicates[key][item] = true - keys.push(encodeURIComponent(key) + "=" + - encodeURIComponent(item)) + duplicates[key][item] = true; + keys.push(encodeURIComponent(key) + "=" + encodeURIComponent(item)); } - }) - /* eslint-enable no-loop-func */ - str.push(keys.join("&")) + }); + str.push(keys.join("&")); } else if (value !== undefined) { - str.push(encodeURIComponent(key) + "=" + - encodeURIComponent(value)) + str.push(encodeURIComponent(key) + "=" + encodeURIComponent(value)); } } - return str.join("&") + return str.join("&"); } function parseQueryString(str) { - if (str.charAt(0) === "?") str = str.substring(1) - - var pairs = str.split("&") - var params = {} + if (str.charAt(0) === "?") str = str.slice(1); + var pairs = str.split("&"), params = {}; forEach(pairs, function (string) { - var pair = string.split("=") - var key = decodeURIComponent(pair[0]) - var value = pair.length === 2 ? decodeURIComponent(pair[1]) : null + var pair = string.split("="); + var key = decodeURIComponent(pair[0]); + var value = pair.length === 2 ? decodeURIComponent(pair[1]) : null; if (params[key] != null) { - if (!isArray(params[key])) params[key] = [params[key]] - params[key].push(value) - } else { - params[key] = value + if (!isArray(params[key])) params[key] = [params[key]]; + params[key].push(value); } - }) + else params[key] = value; + }); - return params + return params; } - m.route.buildQueryString = buildQueryString - m.route.parseQueryString = parseQueryString + m.route.buildQueryString = buildQueryString; + m.route.parseQueryString = parseQueryString; function reset(root) { - var cacheKey = getCellCacheKey(root) - clear(root.childNodes, cellCache[cacheKey]) - cellCache[cacheKey] = undefined + var cacheKey = getCellCacheKey(root); + clear(root.childNodes, cellCache[cacheKey]); + cellCache[cacheKey] = undefined; } m.deferred = function () { - var deferred = new Deferred() - deferred.promise = propify(deferred.promise) - return deferred - } + var deferred = new Deferred(); + deferred.promise = propify(deferred.promise); + return deferred; + }; function propify(promise, initialValue) { - var prop = m.prop(initialValue) - - promise.then(prop) - + var prop = m.prop(initialValue); + promise.then(prop); prop.then = function(resolve, reject) { - return propify(promise.then(resolve, reject), initialValue) - } - - prop.catch = prop.then.bind(null, null) - - return prop + return propify(promise.then(resolve, reject), initialValue); + }; + prop["catch"] = prop.then.bind(null, null); + return prop; } - // Promiz.mithril.js | Zolmeister | MIT - // a modified version of Promiz.js, which does not conform to Promises/A+ - // for two reasons: - // 1) `then` callbacks are called synchronously (because setTimeout is too - // slow, and the setImmediate polyfill is too big - // 2) throwing subclasses of Error cause the error to be bubbled up instead - // of triggering rejection (because the spec does not account for the - // important use case of default browser error handling, i.e. message w/ - // line number) + //Promiz.mithril.js | Zolmeister | MIT + //a modified version of Promiz.js, which does not conform to Promises/A+ for two reasons: + //1) `then` callbacks are called synchronously (because setTimeout is too slow, and the setImmediate polyfill is too big + //2) throwing subclasses of Error cause the error to be bubbled up instead of triggering rejection (because the spec does not account for the important use case of default browser error handling, i.e. message w/ line number) function Deferred(successCallback, failureCallback) { - var RESOLVING = 1 - var REJECTING = 2 - var RESOLVED = 3 - var REJECTED = 4 - var self = this - var state = 0 - var promiseValue = 0 - var next = [] + var RESOLVING = 1, REJECTING = 2, RESOLVED = 3, REJECTED = 4; + var self = this, state = 0, promiseValue = 0, next = []; - self.promise = {} + self.promise = {}; self.resolve = function(value) { if (!state) { - promiseValue = value - state = RESOLVING + promiseValue = value; + state = RESOLVING; - fire() + fire(); } - return this - } + return this; + }; self.reject = function(value) { if (!state) { - promiseValue = value - state = REJECTING + promiseValue = value; + state = REJECTING; - fire() + fire(); } - return this - } + return this; + }; self.promise.then = function(successCallback, failureCallback) { var deferred = new Deferred(successCallback, failureCallback) if (state === RESOLVED) { - deferred.resolve(promiseValue) - } else if (state === REJECTED) { - deferred.reject(promiseValue) - } else { - next.push(deferred) + deferred.resolve(promiseValue); + } + else if (state === REJECTED) { + deferred.reject(promiseValue); + } + else { + next.push(deferred); } return deferred.promise - } + }; function finish(type) { - state = type || REJECTED + state = type || REJECTED; next.map(function(deferred) { - if (state === RESOLVED) { - deferred.resolve(promiseValue) - } else { - deferred.reject(promiseValue) - } - }) + state === RESOLVED ? deferred.resolve(promiseValue) : deferred.reject(promiseValue); + }); } - function thennable( - then, - successCallback, - failureCallback, - notThennableCallback) { - if (((promiseValue != null && isObject(promiseValue)) || - isFunction(promiseValue)) && isFunction(then)) { + function thennable(then, successCallback, failureCallback, notThennableCallback) { + if (((promiseValue != null && isObject(promiseValue)) || isFunction(promiseValue)) && isFunction(then)) { try { // count protects against abuse calls from spec checker - var count = 0 + var count = 0; then.call(promiseValue, function(value) { - if (count++) return - promiseValue = value - successCallback() + if (count++) return; + promiseValue = value; + successCallback(); }, function (value) { - if (count++) return - promiseValue = value - failureCallback() - }) - } catch (e) { - m.deferred.onerror(e) - promiseValue = e - failureCallback() + if (count++) return; + promiseValue = value; + failureCallback(); + }); + } + catch (e) { + m.deferred.onerror(e); + promiseValue = e; + failureCallback(); } } else { - notThennableCallback() + notThennableCallback(); } } function fire() { // check if it's a thenable - var then + var then; try { - then = promiseValue && promiseValue.then - } catch (e) { - m.deferred.onerror(e) - promiseValue = e - state = REJECTING - return fire() + then = promiseValue && promiseValue.then; + } + catch (e) { + m.deferred.onerror(e); + promiseValue = e; + state = REJECTING; + return fire(); } thennable(then, function() { - state = RESOLVING - fire() + state = RESOLVING; + fire(); }, function() { - state = REJECTING - fire() + state = REJECTING; + fire(); }, function() { try { if (state === RESOLVING && isFunction(successCallback)) { - promiseValue = successCallback(promiseValue) - } else if (state === REJECTING && - isFunction(failureCallback)) { - promiseValue = failureCallback(promiseValue) - state = RESOLVING + promiseValue = successCallback(promiseValue); } - } catch (e) { - m.deferred.onerror(e) - promiseValue = e - return finish() + else if (state === REJECTING && isFunction(failureCallback)) { + promiseValue = failureCallback(promiseValue); + state = RESOLVING; + } + } + catch (e) { + m.deferred.onerror(e); + promiseValue = e; + return finish(); } if (promiseValue === self) { - promiseValue = TypeError() - finish() + promiseValue = TypeError(); + finish(); } else { thennable(then, function () { - finish(RESOLVED) + finish(RESOLVED); }, finish, function () { - finish(state === RESOLVING && RESOLVED) - }) + finish(state === RESOLVING && RESOLVED); + }); } - }) + }); } } m.deferred.onerror = function(e) { - if (type.call(e) === "[object Error]" && - !e.constructor.toString().match(/ Error/)) { - pendingRequests = 0 - throw e + if (type.call(e) === "[object Error]" && !e.constructor.toString().match(/ Error/)) { + pendingRequests = 0; + throw e; } - } + }; m.sync = function(args) { - var method = "resolve" - var deferred = m.deferred() - var outstanding = args.length - var results = new Array(outstanding) + var method = "resolve"; function synchronizer(pos, resolved) { return function(value) { - results[pos] = value - if (!resolved) method = "reject" + results[pos] = value; + if (!resolved) method = "reject"; if (--outstanding === 0) { - deferred.promise(results) - deferred[method](results) + deferred.promise(results); + deferred[method](results); } - return value - } + return value; + }; } + var deferred = m.deferred(); + var outstanding = args.length; + var results = new Array(outstanding); if (args.length > 0) { forEach(args, function (arg, i) { - arg.then(synchronizer(i, true), synchronizer(i, false)) - }) - } else { - deferred.resolve([]) + arg.then(synchronizer(i, true), synchronizer(i, false)); + }); } + else deferred.resolve([]); - return deferred.promise - } - function identity(value) { return value } + return deferred.promise; + }; + function identity(value) { return value; } function ajax(options) { if (options.dataType && options.dataType.toLowerCase() === "jsonp") { - var callbackKey = "mithril_callback_" + new Date().getTime() + "_" + - (Math.round(Math.random() * 1e16)).toString(36) - var script = $document.createElement("script") + var callbackKey = "mithril_callback_" + new Date().getTime() + "_" + (Math.round(Math.random() * 1e16)).toString(36) + var script = $document.createElement("script"); window[callbackKey] = function(resp) { - script.parentNode.removeChild(script) + script.parentNode.removeChild(script); options.onload({ type: "load", target: { responseText: resp } - }) - window[callbackKey] = undefined - } + }); + window[callbackKey] = undefined; + }; script.onerror = function() { - script.parentNode.removeChild(script) + script.parentNode.removeChild(script); options.onerror({ type: "error", @@ -1853,197 +1234,129 @@ var m = (function app(window, undefined) { error: "Error making jsonp request" }) } - }) - window[callbackKey] = undefined + }); + window[callbackKey] = undefined; - return false + return false; } script.onload = function() { - return false - } + return false; + }; script.src = options.url + (options.url.indexOf("?") > 0 ? "&" : "?") + (options.callbackKey ? options.callbackKey : "callback") + "=" + callbackKey - + "&" + buildQueryString(options.data || {}) - $document.body.appendChild(script) - } else { - var xhr = new window.XMLHttpRequest() - xhr.open( - options.method, - options.url, - true, - options.user, - options.password) - + + "&" + buildQueryString(options.data || {}); + $document.body.appendChild(script); + } + else { + var xhr = new window.XMLHttpRequest(); + xhr.open(options.method, options.url, true, options.user, options.password); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { - if (xhr.status >= 200 && xhr.status < 300) { - options.onload({type: "load", target: xhr}) - } else { - options.onerror({type: "error", target: xhr}) - } + if (xhr.status >= 200 && xhr.status < 300) options.onload({type: "load", target: xhr}); + else options.onerror({type: "error", target: xhr}); } - } - if (options.serialize === JSON.stringify && - options.data && options.method !== "GET") { - xhr.setRequestHeader( - "Content-Type", - "application/json; charset=utf-8") + }; + if (options.serialize === JSON.stringify && options.data && options.method !== "GET") { + xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); } if (options.deserialize === JSON.parse) { - xhr.setRequestHeader("Accept", "application/json, text/*") + xhr.setRequestHeader("Accept", "application/json, text/*"); } if (isFunction(options.config)) { - var maybeXhr = options.config(xhr, options) - if (maybeXhr != null) xhr = maybeXhr + var maybeXhr = options.config(xhr, options); + if (maybeXhr != null) xhr = maybeXhr; } - var data - - if (options.method === "GET" || !options.data) { - data = "" - } else { - data = options.data + var data = options.method === "GET" || !options.data ? "" : options.data; + if (data && (!isString(data) && data.constructor !== window.FormData)) { + throw new Error("Request data should be either be a string or FormData. Check the `serialize` option in `m.request`"); } - - if (data && (!isString(data) && - data.constructor !== window.FormData)) { - throw new Error("Request data should be either be a string " + - "or FormData. Check the `serialize` option in `m.request`") - } - xhr.send(data) - return xhr + xhr.send(data); + return xhr; } } function bindData(xhrOptions, data, serialize) { if (xhrOptions.method === "GET" && xhrOptions.dataType !== "jsonp") { - var prefix = xhrOptions.url.indexOf("?") < 0 ? "?" : "&" - var querystring = buildQueryString(data) - var suffix = querystring ? prefix + querystring : "" - xhrOptions.url = xhrOptions.url + suffix - } else { - xhrOptions.data = serialize(data) + var prefix = xhrOptions.url.indexOf("?") < 0 ? "?" : "&"; + var querystring = buildQueryString(data); + xhrOptions.url = xhrOptions.url + (querystring ? prefix + querystring : ""); } - return xhrOptions + else xhrOptions.data = serialize(data); + return xhrOptions; } function parameterizeUrl(url, data) { - var tokens = url.match(/:[a-z]\w+/gi) + var tokens = url.match(/:[a-z]\w+/gi); if (tokens && data) { forEach(tokens, function (token) { - var key = token.slice(1) - url = url.replace(token, data[key]) - delete data[key] - }) + var key = token.slice(1); + url = url.replace(token, data[key]); + delete data[key]; + }); } - return url + return url; } m.request = function(xhrOptions) { - if (xhrOptions.background !== true) { - m.startComputation() - } - - var deferred = new Deferred() - var isJSONP = xhrOptions.dataType && - xhrOptions.dataType.toLowerCase() === "jsonp" - - var serialize - - if (isJSONP) { - serialize = xhrOptions.serialize = identity - } else { - serialize = xhrOptions.serialize = xhrOptions.serialize || - JSON.stringify - } - - var deserialize - - if (isJSONP) { - deserialize = xhrOptions.deserialize = identity - } else { - deserialize = xhrOptions.deserialize = xhrOptions.deserialize || - JSON.parse - } - - var extract - - if (isJSONP) { - extract = function(jsonp) { return jsonp.responseText } - } else if (xhrOptions.extract) { - extract = xhrOptions.extract - } else { - extract = function(xhr) { - if (xhr.responseText.length === 0 && - deserialize === JSON.parse) { - return null - } else { - return xhr.responseText - } + if (xhrOptions.background !== true) m.startComputation(); + var deferred = new Deferred(); + var isJSONP = xhrOptions.dataType && xhrOptions.dataType.toLowerCase() === "jsonp" + var serialize = xhrOptions.serialize = isJSONP ? identity : xhrOptions.serialize || JSON.stringify; + var deserialize = xhrOptions.deserialize = isJSONP ? identity : xhrOptions.deserialize || JSON.parse; + var extract = isJSONP ? function(jsonp) { return jsonp.responseText } : xhrOptions.extract || function(xhr) { + if (xhr.responseText.length === 0 && deserialize === JSON.parse) { + return null + } else { + return xhr.responseText } - } - - xhrOptions.method = (xhrOptions.method || "GET").toUpperCase() - xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data) - xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize) + }; + xhrOptions.method = (xhrOptions.method || "GET").toUpperCase(); + xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data); + xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize); xhrOptions.onload = xhrOptions.onerror = function(e) { try { - e = e || event - var unwrap - - if (e.type === "load") { - unwrap = xhrOptions.unwrapSuccess - } else { - unwrap = xhrOptions.unwrapError - } - - var response = (unwrap || identity)( - deserialize(extract(e.target, xhrOptions)), e.target) - + e = e || event; + var unwrap = (e.type === "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity; + var response = unwrap(deserialize(extract(e.target, xhrOptions)), e.target); if (e.type === "load") { if (isArray(response) && xhrOptions.type) { forEach(response, function (res, i) { - response[i] = new xhrOptions.type(res) - }) + response[i] = new xhrOptions.type(res); + }); } else if (xhrOptions.type) { - response = new xhrOptions.type(response) + response = new xhrOptions.type(response); } } - deferred[e.type === "load" ? "resolve" : "reject"](response) - } catch (e) { // eslint-disable-line - m.deferred.onerror(e) - deferred.reject(e) + deferred[e.type === "load" ? "resolve" : "reject"](response); + } catch (e) { + m.deferred.onerror(e); + deferred.reject(e); } if (xhrOptions.background !== true) m.endComputation() } - ajax(xhrOptions) - deferred.promise = propify(deferred.promise, xhrOptions.initialValue) - return deferred.promise - } + ajax(xhrOptions); + deferred.promise = propify(deferred.promise, xhrOptions.initialValue); + return deferred.promise; + }; - // testing API + //testing API m.deps = function(mock) { - initialize(window = mock || window) - return window - } + initialize(window = mock || window); + return window; + }; + //for internal testing only, do not use `m.deps.factory` + m.deps.factory = app; - // for internal testing only, do not use `m.deps.factory` - m.deps.factory = app + return m; +})(typeof window !== "undefined" ? window : {}); - return m -})(typeof window !== "undefined" ? window : {}) - -/* eslint-disable no-undef, strict */ -if (typeof module === "object" && module !== null && module.exports) { - module.exports = m -} else if (typeof define === "function" && define.amd) { - define(function() { return m }) -} -/* eslint-enable no-undef, strict */ +if (typeof module === "object" && module != null && module.exports) module.exports = m; +else if (typeof define === "function" && define.amd) define(function() { return m }); diff --git a/mithril.min.js b/mithril.min.js index d60ff391..4bba9b21 100644 --- a/mithril.min.js +++ b/mithril.min.js @@ -1,8 +1,8 @@ /* -Mithril v0.2.0 +Mithril v0.4.0 http://github.com/lhorie/mithril.js (c) Leo Horie License: MIT */ -var m=function a(b,c){function d(a){return"function"==typeof a}function e(a){return"[object Object]"===P.call(a)}function f(a){return"[object String]"===P.call(a)}function g(a){K=a.document,L=a.location,N=a.cancelAnimationFrame||a.clearTimeout,M=a.requestAnimationFrame||a.setTimeout}function h(a,b){for(var c=[],d=1;d\s*[^<]/g)||[0]).length:O(e)?e.length:1,t[V++]=e)}),D||(i(s,function(a,b){null!=t[b]&&C.push.apply(C,t[b].nodes)}),i(t.nodes,function(a,b){null!=a.parentNode&&C.indexOf(a)<0&&p([a],[t[b]])}),s.length-1?t.controllers[Z]:new(s.controller||T),_=s&&s.attrs&&s.attrs.key;if(s=0==ia||ha||t&&t.controllers&&t.controllers.indexOf($)>-1?s.view($):{tag:"placeholder"},"retain"===s.subtree)return t;null!=_&&(s.attrs||(s.attrs={}),s.attrs.key=_),$.onunload&&ea.push({controller:$,handler:$.onunload}),W.push(Y),X.push($)}if(!s.tag&&X.length)throw new Error("Component template must return a virtual element, not an array, string, etc.");s.attrs||(s.attrs={}),t.attrs||(t.attrs={});var aa=Object.keys(s.attrs),ba=aa.length>("key"in s.attrs?1:0);if((s.tag!=t.tag||aa.sort().join()!=Object.keys(t.attrs).sort().join()||s.attrs.id!=t.attrs.id||s.attrs.key!=t.attrs.key||"all"==h.redraw.strategy()&&(!t.configContext||t.configContext.retain!==!0)||"diff"==h.redraw.strategy()&&t.configContext&&t.configContext.retain===!1)&&(t.nodes.length&&p(t.nodes),t.configContext&&d(t.configContext.onunload)&&t.configContext.onunload(),t.controllers))for(var $,B=0;$=t.controllers[B];B++)d($.onunload)&&$.onunload({preventDefault:T});if(!f(s.tag))return;var ca,da=0===t.nodes.length;if(s.attrs.xmlns?x=s.attrs.xmlns:"svg"===s.tag?x="http://www.w3.org/2000/svg":"math"===s.tag&&(x="http://www.w3.org/1998/Math/MathML"),da){if(ca=s.attrs.is?x===c?K.createElement(s.tag,s.attrs.is):K.createElementNS(x,s.tag,s.attrs.is):x===c?K.createElement(s.tag):K.createElementNS(x,s.tag),t={tag:s.tag,attrs:ba?o(ca,s.tag,s.attrs,{},x):s.attrs,children:null!=s.children&&s.children.length>0?m(ca,s.tag,c,c,s.children,t.children,!0,0,s.attrs.contenteditable?ca:w,x,y):s.children,nodes:[ca]},X.length){t.views=W,t.controllers=X;for(var $,B=0;$=X[B];B++)if($.onunload&&$.onunload.$old&&($.onunload=$.onunload.$old),ia&&$.onunload){var fa=$.onunload;$.onunload=T,$.onunload.$old=fa}}t.children&&!t.children.nodes&&(t.children.nodes=[]),"select"===s.tag&&"value"in s.attrs&&o(ca,s.tag,{value:s.attrs.value},{},x),a.insertBefore(ca,a.childNodes[v]||null)}else ca=t.nodes[0],ba&&o(ca,s.tag,s.attrs,t.attrs,x),t.children=m(ca,s.tag,c,c,s.children,t.children,!1,0,s.attrs.contenteditable?ca:w,x,y),t.nodes.intact=!0,X.length&&(t.views=W,t.controllers=X),u===!0&&null!=ca&&a.insertBefore(ca,a.childNodes[v]||null);if(d(s.attrs.config)){var ga=t.configContext=t.configContext||{},ja=function(a,b){return function(){return a.attrs.config.apply(a,b)}};y.push(ja(s,[ca,!da,ga,t]))}}else if(!d(s)){var C;0===t.nodes.length?(s.$trusted?C=r(a,v,s):(C=[K.createTextNode(s)],a.nodeName.match(S)||a.insertBefore(C[0],a.childNodes[v]||null)),t="string number boolean".indexOf(typeof s)>-1?new s.constructor(s):s,t.nodes=C):t.valueOf()!==s.valueOf()||u===!0?(C=t.nodes,w&&w===K.activeElement||(s.$trusted?(p(C,t),C=r(a,v,s)):"textarea"===b?a.value=s:w?w.innerHTML=s:((1===C[0].nodeType||C.length>1)&&(p(t.nodes,t),C=[K.createTextNode(s)]),l(a,C[0],v,s))),t=new s.constructor(s),t.nodes=C):t.nodes.intact=!0}return t}function n(a,b){return a.action-b.action||a.index-b.index}function o(a,b,c,f,g){for(var h in c){var i=c[h],j=f[h];if(h in f&&j===i)"value"===h&&"input"===b&&a.value!=i&&(a.value=i);else{f[h]=i;try{if("config"===h||"key"==h)continue;if(d(i)&&0===h.indexOf("on"))a[h]=s(i,a);else if("style"===h&&null!=i&&e(i)){for(var k in i)(null==j||j[k]!==i[k])&&(a.style[k]=i[k]);for(var k in j)k in i||(a.style[k]="")}else null!=g?"href"===h?a.setAttributeNS("http://www.w3.org/1999/xlink","href",i):"className"===h?a.setAttribute("class",i):a.setAttribute(h,i):h in a&&"list"!==h&&"style"!==h&&"form"!==h&&"type"!==h&&"width"!==h&&"height"!==h?("input"!==b||a[h]!==i)&&(a[h]=i):a.setAttribute(h,i)}catch(l){if(l.message.indexOf("Invalid argument")<0)throw l}}}return f}function p(a,b){for(var c=a.length-1;c>-1;c--)if(a[c]&&a[c].parentNode){try{a[c].parentNode.removeChild(a[c])}catch(d){}b=[].concat(b),b[c]&&q(b[c])}0!=a.length&&(a.length=0)}function q(a){if(a.configContext&&d(a.configContext.onunload)&&(a.configContext.onunload(),a.configContext.onunload=null),a.controllers)for(var b,c=0;b=a.controllers[c];c++)d(b.onunload)&&b.onunload({preventDefault:T});if(a.children)if(O(a.children))for(var e,c=0;e=a.children[c];c++)q(e);else a.children.tag&&q(a.children)}function r(a,b,c){var d=a.childNodes[b];if(d){var e=1!=d.nodeType,f=K.createElement("span");e?(a.insertBefore(f,d||null),f.insertAdjacentHTML("beforebegin",c),a.removeChild(f)):d.insertAdjacentHTML("beforebegin",c)}else a.insertAdjacentHTML("beforeend",c);for(var g=[];a.childNodes[b]!==d;)g.push(a.childNodes[b]),b++;return g}function s(a,b){return function(c){c=c||event,h.redraw.strategy("diff"),h.startComputation();try{return a.call(b,c)}finally{ja()}}}function t(a){var b=W.indexOf(a);return 0>b?W.push(a)-1:b}function u(a){var b=function(){return arguments.length&&(a=arguments[0]),a};return b.toJSON=function(){return a},b}function v(a,b){var c=function(){return(a.controller||T).apply(this,b)||this},d=function(c){for(var d=1;de;e++)ka[c[e].replace(/:|\./g,"")]=decodeURIComponent(d[e]);h.mount(a,b[g])}),!0}}function z(a){if(a=a||event,!a.ctrlKey&&!a.metaKey&&2!==a.which){a.preventDefault?a.preventDefault():a.returnValue=!1;for(var b=a.currentTarget||a.srcElement,c="pathname"===h.route.mode&&b.search?C(b.search.slice(1)):{};b&&"A"!=b.nodeName.toUpperCase();)b=b.parentNode;h.route(b[h.route.mode].slice(ma[h.route.mode].length),c)}}function A(){"hash"!=h.route.mode&&L.hash?L.hash=L.hash:b.scrollTo(0,0)}function B(a,b){var d={},f=[];for(var g in a){var h=b?b+"["+g+"]":g,i=a[g],j=(P.call(i),null===i?encodeURIComponent(h):e(i)?B(i,h):O(i)?i.reduce(function(a,b){return d[h]||(d[h]={}),d[h][b]?a:(d[h][b]=!0,a.concat(encodeURIComponent(h)+"="+encodeURIComponent(b)))},[]).join("&"):encodeURIComponent(h)+"="+encodeURIComponent(i));i!==c&&f.push(j)}return f.join("&")}function C(a){"?"===a.charAt(0)&&(a=a.substring(1));for(var b=a.split("&"),c={},d=0,e=b.length;e>d;d++){var f=b[d].split("="),g=decodeURIComponent(f[0]),h=2==f.length?decodeURIComponent(f[1]):null;null!=c[g]?(O(c[g])||(c[g]=[c[g]]),c[g].push(h)):c[g]=h}return c}function D(a){var b=t(a);p(a.childNodes,X[b]),X[b]=c}function E(a,b){var c=h.prop(b);return a.then(c),c.then=function(c,d){return E(a.then(c,d),b)},c["catch"]=c.then.bind(null,null),c}function F(a,b){function c(a){n=a||l,p.map(function(a){n===k&&a.resolve(o)||a.reject(o)})}function f(a,b,c,f){if((null!=o&&e(o)||d(o))&&d(a))try{var g=0;a.call(o,function(a){g++||(o=a,b())},function(a){g++||(o=a,c())})}catch(i){h.deferred.onerror(i),o=i,c()}else f()}function g(){var e;try{e=o&&o.then}catch(l){return h.deferred.onerror(l),o=l,n=j,g()}f(e,function(){n=i,g()},function(){n=j,g()},function(){try{n===i&&d(a)?o=a(o):n===j&&d(b)&&(o=b(o),n=i)}catch(g){return h.deferred.onerror(g),o=g,c()}o===m?(o=TypeError(),c()):f(e,function(){c(k)},c,function(){c(n===i&&k)})})}var i=1,j=2,k=3,l=4,m=this,n=0,o=0,p=[];m.promise={},m.resolve=function(a){return n||(o=a,n=i,g()),this},m.reject=function(a){return n||(o=a,n=j,g()),this},m.promise.then=function(a,b){var c=new F(a,b);return n===k?c.resolve(o):n===l?c.reject(o):p.push(c),c.promise}}function G(a){return a}function H(a){if(!a.dataType||"jsonp"!==a.dataType.toLowerCase()){var e=new b.XMLHttpRequest;if(e.open(a.method,a.url,!0,a.user,a.password),e.onreadystatechange=function(){4===e.readyState&&(e.status>=200&&e.status<300?a.onload({type:"load",target:e}):a.onerror({type:"error",target:e}))},a.serialize===JSON.stringify&&a.data&&"GET"!==a.method&&e.setRequestHeader("Content-Type","application/json; charset=utf-8"),a.deserialize===JSON.parse&&e.setRequestHeader("Accept","application/json, text/*"),d(a.config)){var g=a.config(e,a);null!=g&&(e=g)}var h="GET"!==a.method&&a.data?a.data:"";if(h&&!f(h)&&h.constructor!=b.FormData)throw"Request data should be either be a string or FormData. Check the `serialize` option in `m.request`";return e.send(h),e}var i="mithril_callback_"+(new Date).getTime()+"_"+Math.round(1e16*Math.random()).toString(36),j=K.createElement("script");b[i]=function(d){j.parentNode.removeChild(j),a.onload({type:"load",target:{responseText:d}}),b[i]=c},j.onerror=function(d){return j.parentNode.removeChild(j),a.onerror({type:"error",target:{status:500,responseText:JSON.stringify({error:"Error making jsonp request"})}}),b[i]=c,!1},j.onload=function(a){return!1},j.src=a.url+(a.url.indexOf("?")>0?"&":"?")+(a.callbackKey?a.callbackKey:"callback")+"="+i+"&"+B(a.data||{}),K.body.appendChild(j)}function I(a,b,c){if("GET"===a.method&&"jsonp"!=a.dataType){var d=a.url.indexOf("?")<0?"?":"&",e=B(b);a.url=a.url+(e?d+e:"")}else a.data=c(b);return a}function J(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;di;i++)e[i]()},h.trust=function(a){return a=new String(a),a.$trusted=!0,a},h.prop=function(a){return(null!=a&&e(a)||d(a))&&d(a.then)?E(a):u(a)};var Y,Z=[],$=[],_=[],aa=null,ba=0,ca=null,da=null,ea=[],fa=16;h.component=function(a){for(var b=[],c=1;cc&&(c=Z.length);for(var e,f=!1,g={preventDefault:function(){f=!0,ca=da=null}},i=0;e=ea[i];i++)e.handler.call(e.controller,g),e.controller.onunload=null;if(f)for(var e,i=0;e=ea[i];i++)e.controller.onunload=e.handler;else ea=[];if(_[c]&&d(_[c].onunload)&&_[c].onunload(g),!f){h.redraw.strategy("all"),h.startComputation(),Z[c]=a,arguments.length>2&&(b=subcomponent(b,[].slice.call(arguments,2)));var j=Y=b=b||{controller:T},k=b.controller||T,l=new k;return j===Y&&(_[c]=l,$[c]=b),ja(),_[c]}};var ga=!1,ha=!1;h.redraw=function(a){if(!ga){ga=!0,a&&(ha=!0);try{aa&&!a?(M===b.requestAnimationFrame||new Date-ba>fa)&&(aa>0&&N(aa),aa=M(w,fa)):(w(),aa=M(function(){aa=null},fa))}finally{ga=ha=!1}}},h.redraw.strategy=h.prop();var ia=0;h.startComputation=function(){ia++},h.endComputation=function(){ia=Math.max(ia-1,0),0===ia&&h.redraw()};var ja=function(){"none"==h.redraw.strategy()?(ia--,h.redraw.strategy("diff")):h.endComputation()};h.withAttr=function(a,b){return function(c){c=c||event;var d=c.currentTarget||this;b(a in d?d[a]:d.getAttribute(a))}};var ka,la,ma={pathname:"",hash:"#",search:"?"},na=T,oa=!1;return h.route=function(a,c,d,e){if(0===arguments.length)return la;if(3===arguments.length&&f(c)){na=function(b){var e=la=x(b);if(!y(a,d,e)){if(oa)throw new Error("Ensure the default route matches one of the routes defined in m.route");oa=!0,h.route(c,!0),oa=!1}};var g="hash"===h.route.mode?"onhashchange":"onpopstate";b[g]=function(){var a=L[h.route.mode];"pathname"===h.route.mode&&(a+=L.search),la!=x(a)&&na(a)},ca=A,b[g]()}else if(a.addEventListener||a.attachEvent)a.href=("pathname"!==h.route.mode?L.pathname:"")+ma[h.route.mode]+e.attrs.href,a.addEventListener?(a.removeEventListener("click",z),a.addEventListener("click",z)):(a.detachEvent("onclick",z),a.attachEvent("onclick",z));else if(f(a)){var i=la;la=a;var j=la.indexOf("?"),k=j>-1?C(la.slice(j+1)):{};for(var l in c)k[l]=c[l];var m=B(k),n=j>-1?la.slice(0,j):la;m&&(la=n+(-1===n.indexOf("?")?"?":"&")+m);var o=(3===arguments.length?d:c)===!0||i===a;b.history.pushState?(ca=A,da=function(){b.history[o?"replaceState":"pushState"](null,K.title,ma[h.route.mode]+la)},na(ma[h.route.mode]+la)):(L[h.route.mode]=la,na(ma[h.route.mode]+la))}},h.route.param=function(a){if(!ka)throw new Error("You must call m.route(element, defaultRoute, routes) before calling m.route.param()");return ka[a]},h.route.mode="search",h.route.buildQueryString=B,h.route.parseQueryString=C,h.deferred=function(){var a=new F;return a.promise=E(a.promise),a},h.deferred.onerror=function(a){if("[object Error]"===P.call(a)&&!a.constructor.toString().match(/ Error/))throw ia=0,a},h.sync=function(a){function b(a,b){return function(g){return f[a]=g,b||(c="reject"),0===--e&&(d.promise(f),d[c](f)),g}}var c="resolve",d=h.deferred(),e=a.length,f=new Array(e);if(a.length>0)for(var g=0;g1)&&(P(b.nodes,b),g=[ja.createTextNode(a)]),l(c,g[0],e,a))),b=new a.constructor(a),b.nodes=g,b}function z(a,b,c,d,e,f,g){return 0===a.nodes.length?x(b,d,c):a.valueOf()!==b.valueOf()||e===!0?y(b,a,d,f,c,g):(a.nodes.intact=!0,a)}function A(a){if(a.$trusted){var b=a.match(/<[^\/]|\>\s*[^<]/g);if(null!=b)return b.length}else if(na(a))return a.length;return 1}function B(a,b,d,e,f,g,h,i,k){a=m(a);var l=[],n=b.length===a.length,o=0,s={},t=!1;j(b,function(a,c){t=!0,s[b[c].attrs.key]={action:ua,index:c}}),r(a),t&&(b=p(a,b,s,d));for(var u=0,v=0,w=a.length;w>v;v++){var x=M(d,f,b,e,a[v],b[u],g,e+o||o,h,i,k);x!==c&&(n=n&&x.nodes.intact,o+=A(x),b[u++]=x)}return n||q(a,b,l),b}function C(a,b,c,d,e){if(null!=b){if(oa.call(b)===oa.call(a))return b;if(e&&e.nodes){var f=c-d,g=f+(na(a)?a:b.nodes).length;P(e.nodes.slice(f,g),e.slice(f,g))}else b.nodes&&P(b.nodes,b)}return b=new a.constructor,b.tag&&(b={}),b.nodes=[],b}function D(a,b){return b===c?a.attrs.is?ja.createElement(a.tag,a.attrs.is):ja.createElement(a.tag):a.attrs.is?ja.createElementNS(b,a.tag,a.attrs.is):ja.createElementNS(b,a.tag)}function E(a,b,c,d){return d?O(b,a.tag,a.attrs,{},c):a.attrs}function F(a,b,d,e,f,g){return null!=a.children&&a.children.length>0?M(b,a.tag,c,c,a.children,d.children,!0,0,a.attrs.contenteditable?b:e,f,g):a.children}function G(a,b,c,d,e,f,g){var h={tag:a.tag,attrs:b,children:c,nodes:[d]};return u(h,f,g),h.children&&!h.children.nodes&&(h.children.nodes=[]),"select"===a.tag&&"value"in a.attrs&&O(d,a.tag,{value:a.attrs.value},{},e),h}function H(a,b,c,d){var e="diff"===h.redraw.strategy()&&a?a.indexOf(b):-1;return e>-1?c[e]:"function"==typeof d?new d:{}}function I(a,b,c,d){null!=d.onunload&&Ia.push({controller:d,handler:d.onunload}),a.push(c),b.push(d)}function J(a,b,c,d,e,f){var g=H(c.views,b,d,a.controller),h=+(a&&a.attrs&&a.attrs.key);return a=0===Ma||La||d&&d.indexOf(g)>-1?a.view(g):{tag:"placeholder"},"retain"===a.subtree?c:(h===h&&((a.attrs=a.attrs||{}).key=h),I(f,e,b,g),a)}function K(a,b,c,d){for(var e=b&&b.controllers;null!=a.view;)a=J(a,a.view.$original||a.view,b,e,d,c);return a}function L(a,b,c,d,e,g,h,i){var j=[],k=[];if(a=K(a,b,j,k),!a.tag&&k.length)throw new Error("Component template must return a virtual element, not an array, string, etc.");a.attrs=a.attrs||{},b.attrs=b.attrs||{};var l=Object.keys(a.attrs),m=l.length>("key"in a.attrs?1:0);if(s(a,b,l),f(a.tag)){var o=0===b.nodes.length;h=t(a,h);var p;if(o){p=D(a,h);var q=E(a,p,h,m),r=F(a,p,b,c,h,i);b=G(a,q,r,p,h,j,k)}else p=w(b,a,c,m,h,j,i,k);return(o||g===!0&&null!=p)&&n(d,p,e),v(i,a,p,o,b),b}}function M(a,b,c,f,g,h,i,j,l,m,n){return g=k(g),"retain"===g.subtree?h:(h=C(g,h,j,f,c),na(g)?B(g,h,a,j,b,i,l,m,n):null!=g&&e(g)?L(g,h,l,a,j,i,m,n):d(g)?h:z(h,g,j,a,i,l,b))}function N(a,b){return a.action-b.action||a.index-b.index}function O(a,b,c,f,g){for(var h in c){var i=c[h],j=f[h];if(h in f&&j===i)"value"===h&&"input"===b&&a.value!=i&&(a.value=i);else{f[h]=i;try{if("config"===h||"key"===h)continue;if(d(i)&&"on"===h.slice(0,2))a[h]=S(i,a);else if("style"===h&&null!=i&&e(i)){for(var k in i)(null==j||j[k]!==i[k])&&(a.style[k]=i[k]);for(var k in j)k in i||(a.style[k]="")}else null!=g?"href"===h?a.setAttributeNS("http://www.w3.org/1999/xlink","href",i):a.setAttribute("className"===h?"class":h,i):h in a&&"list"!==h&&"style"!==h&&"form"!==h&&"type"!==h&&"width"!==h&&"height"!==h?("input"!==b||a[h]!==i)&&(a[h]=i):a.setAttribute(h,i)}catch(l){if(l.message.indexOf("Invalid argument")<0)throw l}}}return f}function P(a,b){for(var c=a.length-1;c>-1;c--)if(a[c]&&a[c].parentNode){try{a[c].parentNode.removeChild(a[c])}catch(d){}b=[].concat(b),b[c]&&Q(b[c])}a.length=0}function Q(a){a.configContext&&d(a.configContext.onunload)&&(a.configContext.onunload(),a.configContext.onunload=null),a.controllers&&i(a.controllers,function(a){d(a.onunload)&&a.onunload({preventDefault:sa})}),a.children&&(na(a.children)?i(a.children,Q):a.children.tag&&Q(a.children))}function R(a,b,c){var d=a.childNodes[b];if(d){var e=1!==d.nodeType,f=ja.createElement("span");e?(a.insertBefore(f,d||null),f.insertAdjacentHTML("beforebegin",c),a.removeChild(f)):d.insertAdjacentHTML("beforebegin",c)}else a.insertAdjacentHTML("beforeend",c);for(var g=[];a.childNodes[b]!==d;)g.push(a.childNodes[b]),b++;return g}function S(a,b){return function(c){c=c||event,h.redraw.strategy("diff"),h.startComputation();try{return a.call(b,c)}finally{X()}}}function T(a){var b=ya.indexOf(a);return 0>b?ya.push(a)-1:b}function U(a){var b=function(){return arguments.length&&(a=arguments[0]),a};return b.toJSON=function(){return a},b}function V(a,b){var c=function(){return(a.controller||sa).apply(this,b)||this};a.controller&&(c.prototype=a.controller.prototype);var d=function(c){for(var d=1;d=200&&e.status<300?a.onload({type:"load",target:e}):a.onerror({type:"error",target:e}))},a.serialize===JSON.stringify&&a.data&&"GET"!==a.method&&e.setRequestHeader("Content-Type","application/json; charset=utf-8"),a.deserialize===JSON.parse&&e.setRequestHeader("Accept","application/json, text/*"),d(a.config)){var g=a.config(e,a);null!=g&&(e=g)}var h="GET"!==a.method&&a.data?a.data:"";if(h&&!f(h)&&h.constructor!==b.FormData)throw new Error("Request data should be either be a string or FormData. Check the `serialize` option in `m.request`");return e.send(h),e}var i="mithril_callback_"+(new Date).getTime()+"_"+Math.round(1e16*Math.random()).toString(36),j=ja.createElement("script");b[i]=function(d){j.parentNode.removeChild(j),a.onload({type:"load",target:{responseText:d}}),b[i]=c},j.onerror=function(){return j.parentNode.removeChild(j),a.onerror({type:"error",target:{status:500,responseText:JSON.stringify({error:"Error making jsonp request"})}}),b[i]=c,!1},j.onload=function(){return!1},j.src=a.url+(a.url.indexOf("?")>0?"&":"?")+(a.callbackKey?a.callbackKey:"callback")+"="+i+"&"+aa(a.data||{}),ja.body.appendChild(j)}function ha(a,b,c){if("GET"===a.method&&"jsonp"!==a.dataType){var d=a.url.indexOf("?")<0?"?":"&",e=aa(b);a.url=a.url+(e?d+e:"")}else a.data=c(b);return a}function ia(a,b){var c=a.match(/:[a-z]\w+/gi);return c&&b&&i(c,function(c){var d=c.slice(1);a=a.replace(c,b[d]),delete b[d]}),a}var ja,ka,la,ma,na=Array.isArray||function(a){return"[object Array]"===oa.call(a)},oa={}.toString,pa=/(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g,qa=/\[(.+?)(?:=("|'|)(.*?)\2)?\]/,ra=/^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/,sa=function(){};g(b);var ta,ua=1,va=2,wa=3,xa={appendChild:function(a){ta===c&&(ta=ja.createElement("html")),ja.documentElement&&ja.documentElement!==a?ja.replaceChild(a,ja.documentElement):ja.appendChild(a),this.childNodes=ja.childNodes},insertBefore:function(a){this.appendChild(a)},childNodes:[]},ya=[],za={};h.render=function(a,b,d){var e=[];if(!a)throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var f=T(a),g=a===ja,h=g||a===ja.documentElement?xa:a;g&&"html"!==b.tag&&(b={tag:"html",attrs:{},children:b}),za[f]===c&&P(h.childNodes),d===!0&&ca(a),za[f]=M(h,null,c,c,b,za[f],!1,0,null,c,e),i(e,function(a){a()})},h.trust=function(a){return a=new String(a),a.$trusted=!0,a},h.prop=function(a){return(null!=a&&e(a)||d(a))&&d(a.then)?da(a):U(a)};var Aa,Ba=[],Ca=[],Da=[],Ea=null,Fa=0,Ga=null,Ha=null,Ia=[],Ja=16;h.component=function(a){for(var b=[],c=1;cc&&(c=Ba.length);var e=!1,f={preventDefault:function(){e=!0,Ga=Ha=null}};if(i(Ia,function(a){a.handler.call(a.controller,f),a.controller.onunload=null}),e?i(Ia,function(a){a.controller.onunload=a.handler}):Ia=[],Da[c]&&d(Da[c].onunload)&&Da[c].onunload(f),!e){h.redraw.strategy("all"),h.startComputation(),Ba[c]=a;var g=Aa=b?b:b={controller:sa},j=new(b.controller||sa);return g===Aa&&(Da[c]=j,Ca[c]=b),X(),Da[c]}};var Ka=!1,La=!1;h.redraw=function(a){if(!Ka){Ka=!0,a&&(La=!0);try{Ea&&!a?(la===b.requestAnimationFrame||new Date-Fa>Ja)&&(Ea>0&&ma(Ea),Ea=la(W,Ja)):(W(),Ea=la(function(){Ea=null},Ja))}finally{Ka=La=!1}}},h.redraw.strategy=h.prop();var Ma=0;h.startComputation=function(){Ma++},h.endComputation=function(){Ma>1?Ma--:(Ma=0,h.redraw())},h.withAttr=function(a,b){return function(c){c=c||event;var d=c.currentTarget||this;b(a in d?d[a]:d.getAttribute(a))}};var Na,Oa,Pa={pathname:"",hash:"#",search:"?"},Qa=sa,Ra=!1;return h.route=function(a,c,d,e){if(0===arguments.length)return Oa;if(3===arguments.length&&f(c)){Qa=function(b){var e=Oa=Y(b);if(!Z(a,d,e)){if(Ra)throw new Error("Ensure the default route matches one of the routes defined in m.route");Ra=!0,h.route(c,!0),Ra=!1}};var g="hash"===h.route.mode?"onhashchange":"onpopstate";b[g]=function(){var a=ka[h.route.mode];"pathname"===h.route.mode&&(a+=ka.search),Oa!==Y(a)&&Qa(a)},Ga=_,b[g]()}else if(a.addEventListener||a.attachEvent)a.href=("pathname"!==h.route.mode?ka.pathname:"")+Pa[h.route.mode]+e.attrs.href,a.addEventListener?(a.removeEventListener("click",$),a.addEventListener("click",$)):(a.detachEvent("onclick",$),a.attachEvent("onclick",$));else if(f(a)){var i=Oa;Oa=a;var j=c||{},k=Oa.indexOf("?"),l=k>-1?ba(Oa.slice(k+1)):{};for(var m in j)l[m]=j[m];var n=aa(l),o=k>-1?Oa.slice(0,k):Oa;n&&(Oa=o+(-1===o.indexOf("?")?"?":"&")+n);var p=(3===arguments.length?d:c)===!0||i===a;b.history.pushState?(Ga=_,Ha=function(){b.history[p?"replaceState":"pushState"](null,ja.title,Pa[h.route.mode]+Oa)},Qa(Pa[h.route.mode]+Oa)):(ka[h.route.mode]=Oa,Qa(Pa[h.route.mode]+Oa))}},h.route.param=function(a){if(!Na)throw new Error("You must call m.route(element, defaultRoute, routes) before calling m.route.param()");return Na[a]},h.route.mode="search",h.route.buildQueryString=aa,h.route.parseQueryString=ba,h.deferred=function(){var a=new ea;return a.promise=da(a.promise),a},h.deferred.onerror=function(a){if("[object Error]"===oa.call(a)&&!a.constructor.toString().match(/ Error/))throw Ma=0,a},h.sync=function(a){function b(a,b){return function(g){return f[a]=g,b||(c="reject"),0===--e&&(d.promise(f),d[c](f)),g}}var c="resolve",d=h.deferred(),e=a.length,f=new Array(e);return a.length>0?i(a,function(a,c){a.then(b(c,!0),b(c,!1))}):d.resolve([]),d.promise},h.request=function(a){a.background!==!0&&h.startComputation();var b=new ea,c=a.dataType&&"jsonp"===a.dataType.toLowerCase(),d=a.serialize=c?fa:a.serialize||JSON.stringify,e=a.deserialize=c?fa:a.deserialize||JSON.parse,f=c?function(a){return a.responseText}:a.extract||function(a){return 0===a.responseText.length&&e===JSON.parse?null:a.responseText};return a.method=(a.method||"GET").toUpperCase(),a.url=ia(a.url,a.data),a=ha(a,a.data,d),a.onload=a.onerror=function(c){try{c=c||event;var d=("load"===c.type?a.unwrapSuccess:a.unwrapError)||fa,g=d(e(f(c.target,a)),c.target);"load"===c.type&&(na(g)&&a.type?i(g,function(b,c){g[c]=new a.type(b)}):a.type&&(g=new a.type(g))),b["load"===c.type?"resolve":"reject"](g)}catch(c){h.deferred.onerror(c),b.reject(c)}a.background!==!0&&h.endComputation()},ga(a),b.promise=da(b.promise,a.initialValue),b.promise},h.deps=function(a){return g(b=a||b),b},h.deps.factory=a,h}("undefined"!=typeof window?window:{});"object"==typeof module&&null!=module&&module.exports?module.exports=m:"function"==typeof define&&define.amd&&define(function(){return m}); //# sourceMappingURL=mithril.min.js.map \ No newline at end of file diff --git a/mithril.min.js.map b/mithril.min.js.map index 3fb3ad8e..c98909e1 100644 --- a/mithril.min.js.map +++ b/mithril.min.js.map @@ -1 +1 @@ -{"version":3,"file":"mithril.min.js","sources":["mithril.js"],"names":["m","app","window","undefined","isFunction","object","isObject","type","call","isString","initialize","$document","document","$location","location","$cancelAnimationFrame","cancelAnimationFrame","clearTimeout","$requestAnimationFrame","requestAnimationFrame","setTimeout","tag","pairs","args","i","arguments","length","parameterize","match","hasAttrs","attrs","classAttrName","cell","classes","Error","parser","exec","id","push","pair","attrParser","children","slice","isArray","attrName","hasOwnProperty","join","forEach","list","f","forKeys","key","dataToString","data","toString","e","injectTextNode","parentElement","first","index","insertBefore","childNodes","nodeValue","build","parentTag","parentCache","parentIndex","cached","shouldReattach","editable","namespace","configs","subtree","nodes","offset","end","clear","constructor","concat","apply","intact","subArrayCount","DELETION","INSERTION","MOVE","existing","shouldMaintainIdentities","action","guid","keysDiffer","cachedCell","from","element","createElement","actions","prop","changes","sort","sortChanges","newCached","Array","change","splice","dummy","cacheCount","entry","item","$trusted","_","node","parentNode","indexOf","views","controllers","view","$original","controllerIndex","redraw","strategy","controller","noop","pendingRequests","forcing","onunload","unloaders","handler","dataAttrKeys","Object","keys","hasKeys","configContext","retain","preventDefault","isNew","xmlns","is","createElementNS","setAttributes","contenteditable","$old","value","context","callback","injectHTML","createTextNode","nodeName","voidElements","valueOf","activeElement","innerHTML","nodeType","a","b","dataAttrs","cachedAttrs","dataAttr","cachedAttr","autoredraw","rule","style","setAttributeNS","setAttribute","message","removeChild","unload","child","nextSibling","isElement","placeholder","insertAdjacentHTML","event","startComputation","endFirstComputation","getCellCacheKey","nodeCache","gettersetter","store","toJSON","component","this","ctrl","output","computePreRedrawHook","root","roots","components","$$args","render","computePostRedrawHook","lastRedrawId","lastRedrawCallTime","Date","normalizeRoute","route","modes","mode","routeByValue","router","path","routeParams","queryStart","parseQueryString","substr","mount","matcher","RegExp","replace","test","values","len","decodeURIComponent","routeUnobtrusive","ctrlKey","metaKey","which","returnValue","currentTarget","srcElement","search","toUpperCase","setScroll","hash","scrollTo","buildQueryString","prefix","duplicates","str","encodeURIComponent","reduce","memo","charAt","substring","split","params","reset","cacheKey","cellCache","propify","promise","initialValue","then","resolve","reject","bind","Deferred","successCallback","failureCallback","finish","state","REJECTED","next","map","deferred","RESOLVED","promiseValue","thennable","notThennableCallback","count","onerror","fire","REJECTING","RESOLVING","self","TypeError","identity","ajax","options","dataType","toLowerCase","xhr","XMLHttpRequest","open","method","url","user","password","onreadystatechange","readyState","status","onload","target","serialize","JSON","stringify","setRequestHeader","deserialize","parse","config","maybeXhr","FormData","send","callbackKey","getTime","Math","round","random","script","resp","responseText","error","src","body","appendChild","bindData","xhrOptions","querystring","parameterizeUrl","tokens","html","documentNode","documentElement","replaceChild","forceRecreation","isDocumentRoot","trust","String","topComponent","FRAME_BUDGET","module","unloader","isPrevented","subcomponent","currentComponent","redrawing","force","endComputation","max","withAttr","withAttrCallback","getAttribute","currentRoute","pathname","redirect","isDefaultRoute","arg1","arg2","vdom","source","listener","addEventListener","attachEvent","href","removeEventListener","detachEvent","oldRoute","queryIndex","currentPath","shouldReplaceHistoryEntry","history","pushState","title","param","sync","synchronizer","pos","resolved","results","outstanding","request","background","isJSONP","extract","jsonp","unwrap","unwrapSuccess","unwrapError","response","res","deps","mock","factory","exports","define","amd"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"mithril.min.js","sources":["mithril.js"],"names":["m","app","window","undefined","isFunction","object","isObject","type","call","isString","initialize","$document","document","$location","location","$cancelAnimationFrame","cancelAnimationFrame","clearTimeout","$requestAnimationFrame","requestAnimationFrame","setTimeout","tag","pairs","args","i","arguments","length","parameterize","match","hasAttrs","attrs","classAttrName","cell","classes","Error","parser","exec","id","push","pair","attrParser","children","slice","isArray","attrName","hasOwnProperty","join","forEach","list","f","forKeys","key","dataToString","data","toString","e","injectTextNode","parentElement","first","index","insertNode","nodeValue","flatten","concat","apply","node","insertBefore","childNodes","handleKeysDiffer","existing","cached","action","MOVE","from","element","nodes","createElement","INSERTION","actions","prop","changes","sort","sortChanges","newCached","Array","change","DELETION","clear","splice","dummy","changeElement","maybeChanged","diffKeys","keysDiffer","cachedCell","diffArray","_","parentNode","indexOf","buildArrayKeys","guid","maybeRecreateObject","dataAttrKeys","Object","keys","redraw","strategy","configContext","retain","onunload","controllers","controller","unload","preventDefault","noop","getObjectNamespace","namespace","xmlns","unloadCachedControllers","views","$old","pendingRequests","scheduleConfigsToBeCalled","configs","isNew","config","context","buildUpdatedNode","editable","hasKeys","setAttributes","build","contenteditable","intact","handleNonexistentNodes","$trusted","injectHTML","createTextNode","nodeName","voidElements","constructor","reattachNodes","parentTag","activeElement","value","innerHTML","nodeType","handleText","shouldReattach","valueOf","getSubArrayCount","item","buildArray","subArrayCount","shouldMaintainIdentities","cacheCount","len","makeCache","parentIndex","parentCache","offset","end","constructNode","is","createElementNS","constructAttrs","constructChildren","reconstructCached","getController","view","cachedControllers","controllerIndex","updateLists","unloaders","handler","checkView","forcing","subtree","markViews","$original","buildObject","a","b","dataAttrs","cachedAttrs","dataAttr","cachedAttr","autoredraw","rule","style","setAttributeNS","setAttribute","message","removeChild","nextSibling","isElement","placeholder","insertAdjacentHTML","callback","event","startComputation","endFirstComputation","getCellCacheKey","nodeCache","gettersetter","store","toJSON","component","this","prototype","ctrl","output","computePreRedrawHook","roots","root","components","$$args","render","computePostRedrawHook","lastRedrawId","lastRedrawCallTime","Date","endComputation","normalizeRoute","route","modes","mode","routeByValue","router","path","routeParams","queryStart","parseQueryString","substr","mount","matcher","RegExp","replace","test","values","decodeURIComponent","routeUnobtrusive","ctrlKey","metaKey","which","returnValue","currentTarget","srcElement","search","toUpperCase","setScroll","hash","scrollTo","buildQueryString","prefix","duplicates","str","encodeURIComponent","charAt","split","params","string","reset","cacheKey","cellCache","propify","promise","initialValue","then","resolve","reject","bind","Deferred","successCallback","failureCallback","finish","state","REJECTED","next","map","deferred","RESOLVED","promiseValue","thennable","notThennableCallback","count","onerror","fire","REJECTING","RESOLVING","self","TypeError","identity","ajax","options","dataType","toLowerCase","xhr","XMLHttpRequest","open","method","url","user","password","onreadystatechange","readyState","status","onload","target","serialize","JSON","stringify","setRequestHeader","deserialize","parse","maybeXhr","FormData","send","callbackKey","getTime","Math","round","random","script","resp","responseText","error","src","body","appendChild","bindData","xhrOptions","querystring","parameterizeUrl","tokens","token","html","documentNode","documentElement","replaceChild","forceRecreation","isDocumentRoot","trust","String","topComponent","FRAME_BUDGET","module","isPrevented","unloader","currentComponent","redrawing","force","withAttr","withAttrCallback","getAttribute","currentRoute","pathname","redirect","isDefaultRoute","arg1","arg2","vdom","source","listener","addEventListener","attachEvent","href","removeEventListener","detachEvent","oldRoute","queryIndex","currentPath","shouldReplaceHistoryEntry","history","pushState","title","param","sync","synchronizer","pos","resolved","results","outstanding","arg","request","background","isJSONP","extract","jsonp","unwrap","unwrapSuccess","unwrapError","response","res","deps","mock","factory","exports","define","amd"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index f2955287..819228f7 100644 --- a/package.json +++ b/package.json @@ -1,55 +1,46 @@ { - "name": "mithril", - "description": "Mithril.js beta build - use this to help us test the releases before they are released", - "version": "0.1.34-beta.0", - "repository": { - "type": "git", - "url": "git@github.com:lhorie/mithril.js.git" - }, - "scripts": { - "test": "grunt test" - }, - "main": "mithril.js", - "devDependencies": { - "colors": "~0.6.2", - "grunt": "*", - "grunt-cli": "*", - "grunt-contrib-clean": "*", - "grunt-contrib-concat": "*", - "grunt-contrib-connect": "~0.7.1", - "grunt-contrib-copy": "*", - "grunt-contrib-jshint": "~0.10.0", - "grunt-contrib-qunit": "*", - "grunt-contrib-uglify": "*", - "grunt-contrib-watch": "~0.6.1", - "grunt-eslint": "^16.0.0", - "grunt-execute": "*", - "grunt-jscs": "^1.1.0", - "grunt-jsfmt": "git://github.com/ysimonson/grunt-jsfmt", - "grunt-md2html": "*", - "grunt-replace": "*", - "grunt-sauce-tunnel": "^0.2.1", - "grunt-saucelabs": "*", - "grunt-zip": "*", - "load-grunt-config": "^0.9.2", - "lodash": "~2.4.1", - "merge": "^1.1.3", - "publish": "~0.3.2", - "q": "~1.0.0", - "request": "~2.35.0", - "sauce-tunnel": "~2.0.6", - "saucelabs": "~0.1.1" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://opensource.org/licenses/MIT" - } - ], - "files": [ - "mithril.min.js", - "mithril.min.js.map", - "mithril.js", - "README.*" - ] + "name": "mithril", + "description": "Mithril.js beta build - use this to help us test the releases before they are released", + "version": "0.1.34-beta.0", + "repository": { + "type": "git", + "url": "git@github.com:lhorie/mithril.js.git" + }, + "scripts": { + "test": "grunt test" + }, + "main": "mithril.js", + "devDependencies": { + "grunt": "*", + "grunt-cli": "*", + "grunt-contrib-copy": "*", + "grunt-contrib-uglify": "*", + "grunt-contrib-clean": "*", + "grunt-contrib-concat": "*", + "grunt-execute": "*", + "grunt-md2html": "*", + "grunt-replace": "*", + "grunt-contrib-qunit": "*", + "grunt-zip": "*", + "grunt-jsfmt": "git://github.com/ysimonson/grunt-jsfmt", + + "grunt-contrib-connect": "~0.7.1", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-watch": "~0.6.1", + "grunt-jscs": "^1.1.0", + "grunt-sauce-tunnel": "^0.2.1", + "load-grunt-config": "^0.9.2", + "merge": "^1.1.3", + "publish": "~0.3.2", + "grunt-saucelabs": "*", + "request": "~2.35.0", + "q": "~1.0.0", + "saucelabs": "~0.1.1", + "sauce-tunnel": "~2.0.6", + "colors": "~0.6.2", + "lodash": "~2.4.1" + }, + "main": "mithril.js", + "licenses": [{"type": "MIT", "url": "http://opensource.org/licenses/MIT"}], + "files": ["mithril.min.js", "mithril.min.js.map", "mithril.js", "README.*"] } diff --git a/tests/e2e/.eslintrc b/tests/e2e/.eslintrc deleted file mode 100644 index a351ac0b..00000000 --- a/tests/e2e/.eslintrc +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extend": "../../.eslintrc", - "globals": { - "asyncTest": false, - "deepEqual": false, - "equal": false, - "expect": false, - "module": false, - "notDeepEqual": false, - "notEqual": false, - "notPropEqual": false, - "notStrictEqual": false, - "ok": false, - "propEqual": false, - "QUnit": false, - "raises": false, - "start": false, - "stop": false, - "strictEqual": false, - "test": false, - "throws": false - } -} diff --git a/tests/e2e/tests.js b/tests/e2e/tests.js index ea1b389a..078ba122 100644 --- a/tests/e2e/tests.js +++ b/tests/e2e/tests.js @@ -1,13 +1,8 @@ -/* eslint-disable camelcase */ -/* global m, Syn */ - -// saucelabs reporting; see -// https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit +//saucelabs reporting; see https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit var log = [] QUnit.done(function (test_results) { - "use strict" var tests = [] for (var i = 0, len = log.length; i < len; i++) { var details = log[i] @@ -24,7 +19,6 @@ QUnit.done(function (test_results) { window.global_test_results = test_results }) QUnit.testStart(function (testDetails) { - "use strict" QUnit.log(function (details) { if (!details.result) { details.name = testDetails.name @@ -33,11 +27,9 @@ QUnit.testStart(function (testDetails) { }) }) -// qunit doesn't support Function.prototype.bind... +//qunit doesn't support Function.prototype.bind... if (!Function.prototype.bind) { - /* eslint-disable */ Function.prototype.bind = function (oThis) { - "use strict" if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 // internal IsCallable function @@ -59,181 +51,165 @@ if (!Function.prototype.bind) { return fBound } - /* eslint-enable */ } //tests -var dummyEl = document.getElementById("dummy") +var dummyEl = document.getElementById('dummy') -test("Mithril accessible as window.m", function() { - "use strict" +test('Mithril accessible as window.m', function() { expect(1) ok(window.m) }) -test("m.trust w/ html entities", function() { - "use strict" +test('m.trust w/ html entities', function() { expect(1) - var view1 = m("div", "a", m.trust("&"), "b") + var view1 = m('div', "a", m.trust("&"), "b") m.render(dummyEl, view1) - equal(dummyEl.innerHTML, "
a&b
", "view1 rendered correctly") + equal(dummyEl.innerHTML, '
a&b
', 'view1 rendered correctly') }) -test("m.trust w/ html entities 2", function() { - "use strict" +test('m.trust w/ html entities 2', function() { expect(1) - var view1 = m("div", "a", m.trust("&"), "b", m.trust("&"), "c") + var view1 = m('div', "a", m.trust("&"), "b", m.trust("&"), "c") m.render(dummyEl, view1) - equal(dummyEl.innerHTML, "
a&b&c
", - "view1 rendered correctly") + equal(dummyEl.innerHTML, '
a&b&c
', 'view1 rendered correctly') }) -test("array item removal", function() { - "use strict" +test('array item removal', function() { expect(2) - var view1 = m("div", {}, [ - m("div", {}, "0"), - m("div", {}, "1"), - m("div", {}, "2") + var view1 = m('div', {}, [ + m('div', {}, '0'), + m('div', {}, '1'), + m('div', {}, '2') ]) - var view2 = m("div", {}, [ - m("div", {}, "0") + var view2 = m('div', {}, [ + m('div', {}, '0') ]) m.render(dummyEl, view1) - equal(dummyEl.innerHTML, "
0
1
2
", - "view1 rendered correctly") + equal(dummyEl.innerHTML, '
0
1
2
', 'view1 rendered correctly') m.render(dummyEl, view2) - equal(dummyEl.innerHTML, "
0
", - "view2 should be rendered correctly") + equal(dummyEl.innerHTML, '
0
', 'view2 should be rendered correctly') }) -test("issue99 regression", function() { - "use strict" +test('issue99 regression', function() { // see https://github.com/lhorie/mithril.js/issues/99 expect(2) - var view1 = m("div", {}, [ - m("div", {}, "0"), - m("div", {}, "1"), - m("div", {}, "2") + var view1 = m('div', {}, [ + m('div', {}, '0'), + m('div', {}, '1'), + m('div', {}, '2') ]) - var view2 = m("div", {}, [ - m("span", {}, "0") + var view2 = m('div', {}, [ + m('span', {}, '0') ]) m.render(dummyEl, view1) - equal(dummyEl.innerHTML, "
0
1
2
", - "view1 rendered correctly") + equal(dummyEl.innerHTML, '
0
1
2
', 'view1 rendered correctly') m.render(dummyEl, view2) - equal(dummyEl.innerHTML, "
0
", - "view2 should be rendered correctly") + equal(dummyEl.innerHTML, '
0
', 'view2 should be rendered correctly') }) -test("config handler context", function() { - "use strict" +test('config handler context', function() { expect(3) - var view = m("div", {config: function(evt, isInitialized, context) { + var view = m('div', {config: function(evt, isInitialized, context) { equal(context instanceof Object, true) context.data = 1 }}) m.render(dummyEl, view) - view = m("div", {config: function(evt, isInitialized, context) { + view = m('div', {config: function(evt, isInitialized, context) { equal(context instanceof Object, true) equal(context.data, 1) }}) m.render(dummyEl, view) }) -test("node identity remove firstChild", function() { - "use strict" +test('node identity remove firstChild', function() { expect(2) - var view1 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2") + var view1 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2') ]) m.render(dummyEl, view1) var node2 = dummyEl.firstChild.lastChild - equal(node2.innerHTML, "E2") + equal(node2.innerHTML, 'E2') - var view2 = m("div", {}, [ - m("div", {key: 2}, "E2") + var view2 = m('div', {}, [ + m('div', {key:2}, 'E2') ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild, node2) }) -test("node identity change order", function() { - "use strict" +test('node identity change order', function() { expect(2) - var view1 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2"), - m("div", {key: 3}, "E3") + var view1 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2'), + m('div', {key:3}, 'E3') ]) m.render(dummyEl, view1) var e2 = dummyEl.firstChild.firstChild.nextSibling - equal(e2.innerHTML, "E2") + equal(e2.innerHTML, 'E2') - var view2 = m("div", {}, [ - m("div", {key: 2}, "E2"), - m("div", {key: 1}, "E1"), - m("div", {key: 3}, "E3") + var view2 = m('div', {}, [ + m('div', {key:2}, 'E2'), + m('div', {key:1}, 'E1'), + m('div', {key:3}, 'E3') ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild, e2) }) -test("node identity remove in the middle", function() { - "use strict" +test('node identity remove in the middle', function() { expect(2) - var view1 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2"), - m("div", {key: 3}, "E3") + var view1 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2'), + m('div', {key:3}, 'E3') ]) m.render(dummyEl, view1) var e3 = dummyEl.firstChild.lastChild - equal(e3.innerHTML, "E3") + equal(e3.innerHTML, 'E3') - var view2 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 3}, "E3") + var view2 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:3}, 'E3') ]) m.render(dummyEl, view2) equal(dummyEl.firstChild.firstChild.nextSibling, e3) }) -test("node identity remove last", function() { - "use strict" +test('node identity remove last', function() { expect(4) - var view1 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2"), - m("div", {key: 3}, "E3") + var view1 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2'), + m('div', {key:3}, 'E3') ]) m.render(dummyEl, view1) var e1 = dummyEl.firstChild.firstChild - equal(e1.innerHTML, "E1") + equal(e1.innerHTML, 'E1') var e2 = dummyEl.firstChild.firstChild.nextSibling - equal(e2.innerHTML, "E2") + equal(e2.innerHTML, 'E2') - var view2 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2") + var view2 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2') ]) m.render(dummyEl, view2) @@ -241,176 +217,168 @@ test("node identity remove last", function() { equal(dummyEl.firstChild.firstChild.nextSibling, e2) }) -test("node identity shuffle and remove", function() { - "use strict" +test('node identity shuffle and remove', function() { expect(8) - var view1 = m("div", {}, [ - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2"), - m("div", {key: 3}, "E3"), - m("div", {key: 4}, "E4"), - m("div", {key: 5}, "E5") + var view1 = m('div', {}, [ + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2'), + m('div', {key:3}, 'E3'), + m('div', {key:4}, 'E4'), + m('div', {key:5}, 'E5') ]) m.render(dummyEl, view1) var e1 = dummyEl.firstChild.firstChild - equal(e1.innerHTML, "E1") + equal(e1.innerHTML, 'E1') var e2 = e1.nextSibling - equal(e2.innerHTML, "E2") + equal(e2.innerHTML, 'E2') var e3 = e2.nextSibling - equal(e3.innerHTML, "E3") + equal(e3.innerHTML, 'E3') var e4 = e3.nextSibling - equal(e4.innerHTML, "E4") + equal(e4.innerHTML, 'E4') var e5 = e4.nextSibling - equal(e5.innerHTML, "E5") + equal(e5.innerHTML, 'E5') - var view2 = m("div", {}, [ - m("div", {key: 4}, "E4"), - m("div", {key: 10}, "E10"), - m("div", {key: 1}, "E1"), - m("div", {key: 2}, "E2") + var view2 = m('div', {}, [ + m('div', {key:4}, 'E4'), + m('div', {key:10}, 'E10'), + m('div', {key:1}, 'E1'), + m('div', {key:2}, 'E2') ]) m.render(dummyEl, view2) - equal(dummyEl.firstChild.firstChild, e4, "e4 is first element") - equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling, e1, - "e1 is third element") - equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling.nextSibling, e2, - "e2 is fourth element") + equal(dummyEl.firstChild.firstChild, e4, 'e4 is first element') + equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling, e1, 'e1 is third element') + equal(dummyEl.firstChild.firstChild.nextSibling.nextSibling.nextSibling, e2, 'e2 is fourth element') }) -asyncTest("issue214 regression", function() { - "use strict" +asyncTest('issue214 regression', function() { // see https://github.com/lhorie/mithril.js/issues/214 expect(2) function controller() { - this.inputValue = m.prop("") + this.inputValue = m.prop('') } function view(ctrl) { - return m("input#testinput", { + return m('input#testinput', { value: ctrl.inputValue(), - onkeyup: m.withAttr("value", ctrl.inputValue) + onkeyup: m.withAttr('value', ctrl.inputValue) }) } var ctrl = m.module(dummyEl, { controller: controller, view: view }) - Syn.click({}, "testinput") - .type("0").delay(10) - .type("1").delay(10) - .type("2").delay(10) - .type("3").delay(10) - .type("4").delay(10) - .type("5").delay(10) - .type("6").delay(10) - .type("7").delay(10) - .type("8").delay(10) - .type("9").delay(10) - .type("a").delay(10) - .type("b").delay(10) - .type("c").delay(10) - .type("d").delay(10) - .type("e").delay(10) - .type("f").delay(10) - .type("0").delay(10) - .type("1").delay(10) - .type("2").delay(10) - .type("3").delay(10) - .type("4").delay(10) - .type("5").delay(10) - .type("6").delay(10) - .type("7").delay(10) - .type("8").delay(10) - .type("9").delay(10) - .type("a").delay(10) - .type("b").delay(10) - .type("c").delay(10) - .type("d").delay(10) - .type("e").delay(10) - .type("f").delay(10) - .type("0").delay(10) - .type("1").delay(10) - .type("2").delay(10) - .type("3").delay(10) - .type("4").delay(10) - .type("5").delay(10) - .type("6").delay(10) - .type("7").delay(10) - .type("8").delay(10) - .type("9").delay(10) - .type("a").delay(10) - .type("b").delay(10) - .type("c").delay(10) - .type("d").delay(10) - .type("e").delay(10) - .type("f").delay(10) - .type("0").delay(10) - .type("1").delay(10) - .type("2").delay(10) - .type("3").delay(10) - .type("4").delay(10) - .type("5").delay(10) - .type("6").delay(10) - .type("7").delay(10) - .type("8").delay(10) - .type("9").delay(10) - .type("a").delay(10) - .type("b").delay(10) - .type("c").delay(10) - .type("d").delay(10) - .type("e").delay(10) - .type("f", function() { - equal(ctrl.inputValue(), - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") - equal(document.getElementById("testinput").value, - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") + Syn.click({}, 'testinput') + .type('0').delay(10) + .type('1').delay(10) + .type('2').delay(10) + .type('3').delay(10) + .type('4').delay(10) + .type('5').delay(10) + .type('6').delay(10) + .type('7').delay(10) + .type('8').delay(10) + .type('9').delay(10) + .type('a').delay(10) + .type('b').delay(10) + .type('c').delay(10) + .type('d').delay(10) + .type('e').delay(10) + .type('f').delay(10) + .type('0').delay(10) + .type('1').delay(10) + .type('2').delay(10) + .type('3').delay(10) + .type('4').delay(10) + .type('5').delay(10) + .type('6').delay(10) + .type('7').delay(10) + .type('8').delay(10) + .type('9').delay(10) + .type('a').delay(10) + .type('b').delay(10) + .type('c').delay(10) + .type('d').delay(10) + .type('e').delay(10) + .type('f').delay(10) + .type('0').delay(10) + .type('1').delay(10) + .type('2').delay(10) + .type('3').delay(10) + .type('4').delay(10) + .type('5').delay(10) + .type('6').delay(10) + .type('7').delay(10) + .type('8').delay(10) + .type('9').delay(10) + .type('a').delay(10) + .type('b').delay(10) + .type('c').delay(10) + .type('d').delay(10) + .type('e').delay(10) + .type('f').delay(10) + .type('0').delay(10) + .type('1').delay(10) + .type('2').delay(10) + .type('3').delay(10) + .type('4').delay(10) + .type('5').delay(10) + .type('6').delay(10) + .type('7').delay(10) + .type('8').delay(10) + .type('9').delay(10) + .type('a').delay(10) + .type('b').delay(10) + .type('c').delay(10) + .type('d').delay(10) + .type('e').delay(10) + .type('f', function() { + equal(ctrl.inputValue(), '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef') + equal(document.getElementById('testinput').value, '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef') start() }) }) -asyncTest("issue288 regression", function() { - "use strict" +asyncTest('issue288 regression', function() { // see https://github.com/lhorie/mithril.js/issues/288 expect(2) function controller() { - this.inputValue = m.prop("") + this.inputValue = m.prop('') this.submit = function() { if (this.inputValue()) { - this.inputValue("") + this.inputValue('') } - }.bind(this) + }.bind(this); } function view(ctrl) { - return m("form", { onsubmit: ctrl.submit }, [ - m("input#testinput", { - onkeyup: m.withAttr("value", ctrl.inputValue), + return m('form', { onsubmit: ctrl.submit }, [ + m('input#testinput', { + onkeyup: m.withAttr('value', ctrl.inputValue), value: ctrl.inputValue() }), - m("button[type=submit]") + m('button[type=submit]') ]) } var ctrl = m.module(dummyEl, { controller: controller, view: view }) - Syn.click({}, "testinput") - .type("a").delay(10) - .type("b").delay(10) - .type("c").delay(10) - .type("d").delay(10) - .type("[enter]", function() { - equal(ctrl.inputValue(), "") - equal(document.getElementById("testinput").value, "") + Syn.click({}, 'testinput') + .type('a').delay(10) + .type('b').delay(10) + .type('c').delay(10) + .type('d').delay(10) + .type('[enter]', function() { + equal(ctrl.inputValue(), '') + equal(document.getElementById('testinput').value, '') start() }) }) -test("issue278 regression", function() { - "use strict" +test('issue278 regression', function() { // see https://github.com/lhorie/mithril.js/issues/278 expect(1) @@ -421,24 +389,22 @@ test("issue278 regression", function() { }, view: function(ctrl) { - return m("select#testselect", { + return m('select#testselect', { size: ctrl.values.length, - multiple: "multiple" + multiple: 'multiple' }, [ ctrl.values.map(function(v){ var opts = {value: v} - if (ctrl.value().indexOf(v) !== -1) { - opts.selected = "selected" - } - return m("option", opts, v) + if (ctrl.value().indexOf(v) !== -1) opts.selected = 'selected' + return m('option', opts, v) }) ]) } } - m.render(dummyEl, test.view(new test.controller())) + m.render(dummyEl, test.view(new test.controller)) - var select = document.getElementById("testselect") + var select = document.getElementById('testselect') for (var i = 0, selected = 0; i < select.options.length; i++) { if (select.options[i].selected) selected++ @@ -447,30 +413,25 @@ test("issue278 regression", function() { equal(selected, 2) }) test("mixing trusted content", function() { - "use strict" m.render(dummyEl, [m.trust("

1

2

"), m("i", "foo")]) equal(dummyEl.childNodes[2].nodeName, "I") }) test("mixing trusted content w/ text nodes", function() { - "use strict" m.render(dummyEl, [m.trust("

1

123

2

"), m("i", "foo")]) equal(dummyEl.childNodes[3].nodeName, "I") }) test("mixing trusted content w/ td", function() { - "use strict" m.render(dummyEl, [m.trust("12"), m("i", "foo")]) equal(dummyEl.childNodes[1].nodeName, "I") }) test("0 should not be treated as empty string", function() { - "use strict" m.render(dummyEl, m("input", {value: ""})) m.render(dummyEl, m("input", {value: 0})) equal(dummyEl.childNodes[0].value, "0") }) test("empty value in ') }) diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 4b7a2a1a..ac350c14 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1,12 +1,7 @@ -/* global m, test, mock */ -/* eslint-disable no-console */ - function testMithril(mock) { - "use strict" - m.deps(mock) - // m + //m test(function() {return m("div").tag === "div"}) test(function() {return m(".foo").tag === "div"}) test(function() {return m(".foo").attrs.className === "foo"}) @@ -17,85 +12,43 @@ function testMithril(mock) { test(function() {return m("div", "test").children[0] === "test"}) test(function() {return m("div", "test", "test2").children[1] === "test2"}) test(function() {return m("div", ["test"]).children[0] === "test"}) - test(function() { - return m("div", {title: "bar"}, "test").attrs.title === "bar" - }) - test(function() { - return m("div", {title: "bar"}, "test").children[0] === "test" - }) - test(function() { - return m("div", {title: "bar"}, ["test"]).children[0] === "test" - }) - test(function() { - return m("div", {title: "bar"}, m("div")).children[0].tag === "div" - }) - test(function() { - return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div" - }) - test(function() { - // splat - return m("div", {title: "bar"}, - "test0", "test1", "test2", "test3").children[3] === "test3" - }) - test(function() { - return m("div", {title: "bar"}, - m("div"), m("i"), m("span")).children[2].tag === "span" - }) + test(function() {return m("div", {title: "bar"}, "test").attrs.title === "bar"}) + test(function() {return m("div", {title: "bar"}, "test").children[0] === "test"}) + test(function() {return m("div", {title: "bar"}, ["test"]).children[0] === "test"}) + test(function() {return m("div", {title: "bar"}, m("div")).children[0].tag === "div"}) + test(function() {return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div"}) + test(function() {return m("div", {title: "bar"}, "test0", "test1", "test2", "test3").children[3] === "test3"}) // splat + test(function() {return m("div", {title: "bar"}, m("div"), m("i"), m("span")).children[2].tag === "span"}) test(function() {return m("div", ["a", "b"]).children.length === 2}) test(function() {return m("div", [m("div")]).children[0].tag === "div"}) - test(function() { - // yes, this is expected behavior: see method signature - return m("div", m("div")).children[0].tag === "div" - }) + test(function() {return m("div", m("div")).children[0].tag === "div"}) //yes, this is expected behavior: see method signature test(function() {return m("div", [undefined]).tag === "div"}) - test(function() { - // as long as it doesn't throw errors, it's fine - return m("div", [{foo: "bar"}]) - }) + test(function() {return m("div", [{foo: "bar"}])}) //as long as it doesn't throw errors, it's fine test(function() {return m("svg", [m("g")])}) test(function() {return m("svg", [m("a[href='http://google.com']")])}) - test(function() { - return m(".foo", {class: "bar"}).attrs.class === "foo bar" - }) - test(function() { - return m(".foo", {className: "bar"}).attrs.className === "foo bar" - }) - test(function() { - return m(".foo", {className: ""}).attrs.className === "foo" - }) - test(function() { - // https://github.com/lhorie/mithril.js/issues/382 and 512 - return m("div", {className: ""}).attrs.className === "" - }) - test(function() { - return m("div", {class: ""}).attrs.className === undefined - }) - test(function() { - return m("div", {className: ""}).attrs.class === undefined - }) - test(function() {return m("div", {class: ""}).attrs.class === ""}) + test(function() {return m(".foo", {"class": "bar"}).attrs["class"] === "foo bar"}) + test(function() {return m(".foo", {className: "bar"}).attrs.className === "foo bar"}) + test(function() {return m(".foo", {className: ""}).attrs.className === "foo"}) + test(function() {return m("div", {className: ""}).attrs.className === ""}) //https://github.com/lhorie/mithril.js/issues/382 and 512 + test(function() {return m("div", {"class": ""}).attrs.className === undefined}) + test(function() {return m("div", {className: ""}).attrs["class"] === undefined}) + test(function() {return m("div", {"class": ""}).attrs["class"] === ""}) test(function() {return m("div", [1, 2, 3], 4).children.length === 2}) test(function() {return m("div", [1, 2, 3], 4).children[0].length === 3}) test(function() {return m("div", [1, 2, 3], 4).children[1] === 4}) test(function() {return m("div", [1, 2, 3]).children.length === 3}) - test(function() { - return m("div", [1, 2, 3], [4, 5, 6, 7]).children.length === 2 - }) - test(function() { - return m("div", [1, 2, 3], [4, 5, 6, 7]).children[0].length === 3 - }) - test(function() { - return m("div", [1, 2, 3], [4, 5, 6, 7]).children[1].length === 4 - }) + test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children.length === 2}) + test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children[0].length === 3}) + test(function() {return m("div", [1, 2, 3], [4, 5, 6, 7]).children[1].length === 4}) test(function() {return m("div", [1], [2], [3]).children.length === 3}) test(function() { - // class changes shouldn't trigger dom recreation - var v1 = m(".foo", {class: "", onclick: function() {}}) - var v2 = m(".foo", {class: "bar", onclick: function() {}}) + //class changes shouldn't trigger dom recreation + var v1 = m(".foo", {"class": "", onclick: function() {}}) + var v2 = m(".foo", {"class": "bar", onclick: function() {}}) return Object.keys(v1.attrs).join() === Object.keys(v2.attrs).join() }) test(function() { - // m should proxy object first arg to m.component + //m should proxy object first arg to m.component var component = { controller: function(args) { this.args = args @@ -111,16 +64,16 @@ function testMithril(mock) { return c1.args === args && c1.args === c2.args }) - // m.mount + //m.mount test(function() { var root = mock.document.createElement("div") var whatever = 1 var app = { view: function() { return [ - whatever % 2 ? m("span", "% 2") : undefined, - m("div", "bugs"), - m("a") + whatever % 2 ? m('span', '% 2') : undefined, + m('div', 'bugs'), + m('a') ] } } @@ -154,10 +107,8 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return root1.childNodes[0].nodeValue === "test1" && - root2.childNodes[0].nodeValue === "test2" && - mod1.value && mod1.value === "test1" && - mod2.value && mod2.value === "test2" + return (root1.childNodes[0].nodeValue === "test1" && root2.childNodes[0].nodeValue === "test2") + && (mod1.value && mod1.value === "test1") && (mod2.value && mod2.value === "test2") }) test(function() { mock.requestAnimationFrame.$resolve() @@ -183,7 +134,7 @@ function testMithril(mock) { return unloaded }) test(function() { - // component should pass args to both controller and view + //component should pass args to both controller and view mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") @@ -199,7 +150,7 @@ function testMithril(mock) { return slot1 === 1 && slot2 === 1 }) test(function() { - // component should work without controller + //component should work without controller mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") @@ -214,12 +165,16 @@ function testMithril(mock) { return slot2 === 1 }) test(function() { - // component controller should only run once + //component controller should only run once mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") - var count1 = 0 - var count2 = 0 + var count1 = 0, count2 = 0 + var component = { + view: function() { + return sub + } + } var sub = { controller: function() { count1++ @@ -229,11 +184,6 @@ function testMithril(mock) { return m("div", "test") } } - var component = { - view: function() { - return sub - } - } m.mount(root, component) mock.requestAnimationFrame.$resolve() @@ -245,21 +195,14 @@ function testMithril(mock) { return count1 === 1 && count2 === 2 }) test(function() { - // sub component controller should only run once + //sub component controller should only run once mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") - var count1 = 0 - var count2 = 0 - var count3 = 0 - var count4 = 0 - var subsub = { - controller: function() { - count3++ - }, + var count1 = 0, count2 = 0, count3 = 0, count4 = 0 + var component = { view: function() { - count4++ - return m("div", "test") + return sub } } var sub = { @@ -271,9 +214,13 @@ function testMithril(mock) { return subsub } } - var component = { + var subsub = { + controller: function() { + count3++ + }, view: function() { - return sub + count4++ + return m("div", "test") } } m.mount(root, component) @@ -287,17 +234,11 @@ function testMithril(mock) { return count1 === 1 && count2 === 2 && count3 === 1 && count4 === 2 }) test(function() { - // keys in components should work + //keys in components should work mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var sub = { - controller: function() {}, - view: function() { - return m("div") - } - } var component = { controller: function() {}, view: function() { @@ -306,6 +247,12 @@ function testMithril(mock) { }) } } + var sub = { + controller: function() {}, + view: function() { + return m("div") + } + } m.mount(root, component) var firstBefore = root.childNodes[0] @@ -322,15 +269,17 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // keys in subcomponents should work + //keys in subcomponents should work mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var subsub = { + var component = { controller: function() {}, view: function() { - return m("div") + return list.map(function(i) { + return m.component(sub, {key: i}) + }) } } var sub = { @@ -338,12 +287,10 @@ function testMithril(mock) { return subsub } } - var component = { + var subsub = { controller: function() {}, view: function() { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) + return m("div") } } m.mount(root, component) @@ -362,26 +309,25 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // keys in components should work even if component internally messes - // them up + //keys in components should work even if component internally messes them up mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } var sub = { controller: function() {}, view: function() { return m("div", {key: 1}) } } - var component = { - controller: function() {}, - view: function() { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) - } - } m.mount(root, component) var firstBefore = root.childNodes[0] @@ -398,16 +344,17 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // keys in subcomponents should work even if component internally messes - // them up + //keys in subcomponents should work even if component internally messes them up mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var subsub = { + var component = { controller: function() {}, view: function() { - return m("div", {key: 1}) + return list.map(function(i) { + return m.component(sub, {key: i}) + }) } } var sub = { @@ -416,12 +363,10 @@ function testMithril(mock) { return subsub } } - var component = { + var subsub = { controller: function() {}, view: function() { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) + return m("div", {key: 1}) } } m.mount(root, component) @@ -440,18 +385,11 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // component identity should stay intact if components are descendants - // of keyed elements + //component identity should stay intact if components are descendants of keyed elements mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var sub = { - controller: function() {}, - view: function() { - return m("div") - } - } var component = { controller: function() {}, view: function() { @@ -460,6 +398,12 @@ function testMithril(mock) { }) } } + var sub = { + controller: function() {}, + view: function() { + return m("div") + } + } m.mount(root, component) var firstBefore = root.childNodes[0].childNodes[0] @@ -476,16 +420,17 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // subcomponent identity should stay intact if components are - // descendants of keyed elements + //subcomponent identity should stay intact if components are descendants of keyed elements mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] - var subsub = { + var component = { controller: function() {}, view: function() { - return m("div") + return list.map(function(i) { + return m("div", {key: i}, sub) + }) } } var sub = { @@ -494,12 +439,10 @@ function testMithril(mock) { return subsub } } - var component = { + var subsub = { controller: function() {}, view: function() { - return list.map(function(i) { - return m("div", {key: i}, sub) - }) + return m("div") } } m.mount(root, component) @@ -518,12 +461,20 @@ function testMithril(mock) { return firstBefore === firstAfter }) test(function() { - // component should call onunload when removed from template + //component should call onunload when removed from template mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] var unloaded + var component = { + controller: function() {}, + view: function() { + return list.map(function(i) { + return m.component(sub, {key: i}) + }) + } + } var sub = { controller: function(opts) { this.onunload = function() { @@ -534,14 +485,6 @@ function testMithril(mock) { return m("div") } } - var component = { - controller: function() {}, - view: function() { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) - } - } m.mount(root, component) mock.requestAnimationFrame.$resolve() @@ -554,20 +497,18 @@ function testMithril(mock) { return unloaded === 3 }) test(function() { - // subcomponent should call onunload when removed from template + //subcomponent should call onunload when removed from template mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var list = [1, 2, 3] var unloaded1, unloaded2 - var subsub = { - controller: function(opts) { - this.onunload = function() { - unloaded2 = opts.key - } - }, + var component = { + controller: function() {}, view: function() { - return m("div") + return list.map(function(i) { + return m.component(sub, {key: i}) + }) } } var sub = { @@ -580,12 +521,14 @@ function testMithril(mock) { return m.component(subsub, {key: opts.key}) } } - var component = { - controller: function() {}, + var subsub = { + controller: function(opts) { + this.onunload = function() { + unloaded2 = opts.key + } + }, view: function() { - return list.map(function(i) { - return m.component(sub, {key: i}) - }) + return m("div") } } m.mount(root, component) @@ -600,12 +543,17 @@ function testMithril(mock) { return unloaded1 === 3 && unloaded2 === 3 }) test(function() { - // calling m.redraw synchronously from controller constructor should not - // trigger extra redraws + //calling m.redraw synchronously from controller constructor should not trigger extra redraws mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var count = 0 + var component = { + controller: function() {}, + view: function() { + return sub + } + } var sub = { controller: function() { m.redraw() @@ -615,12 +563,6 @@ function testMithril(mock) { return m("div") } } - var component = { - controller: function() {}, - view: function() { - return sub - } - } m.mount(root, component) mock.requestAnimationFrame.$resolve() @@ -628,12 +570,23 @@ function testMithril(mock) { return count === 1 }) test(function() { - // calling m.redraw synchronously from controller constructor should not - // trigger extra redraws + //calling m.redraw synchronously from controller constructor should not trigger extra redraws mock.requestAnimationFrame.$resolve() var root = mock.document.createElement("div") var count = 0 + var component = { + controller: function() {}, + view: function() { + return sub + } + } + var sub = { + controller: function() {}, + view: function() { + return subsub + } + } var subsub = { controller: function() { m.redraw() @@ -643,18 +596,6 @@ function testMithril(mock) { return m("div") } } - var sub = { - controller: function() {}, - view: function() { - return subsub - } - } - var component = { - controller: function() {}, - view: function() { - return sub - } - } m.mount(root, component) mock.requestAnimationFrame.$resolve() @@ -662,30 +603,27 @@ function testMithril(mock) { return count === 1 }) test(function() { - // calling preventDefault from component's onunload should prevent route - // change + //calling preventDefault from component's onunload should prevent route change mock.requestAnimationFrame.$resolve() mock.location.search = "?" var root = mock.document.createElement("div") var loaded = false var testEnabled = true - var sub = { - controller: function() { - this.onunload = function(e) { - if (testEnabled) e.preventDefault() - } - }, - view: function() { - return m("div") - } - } var component = { controller: function() {}, view: function() { return sub } } + var sub = { + controller: function() { + this.onunload = function(e) {if (testEnabled) e.preventDefault()} + }, + view: function() { + return m("div") + } + } m.route(root, "/a", { "/a": component, "/b": {controller: function() {loaded = true}, view: function() {}} @@ -701,22 +639,17 @@ function testMithril(mock) { return loaded === false }) test(function() { - // calling preventDefault from subcomponent's onunload should prevent - // route change + //calling preventDefault from subcomponent's onunload should prevent route change mock.requestAnimationFrame.$resolve() mock.location.search = "?" var root = mock.document.createElement("div") var loaded = false var testEnabled = true - var subsub = { - controller: function() { - this.onunload = function(e) { - if (testEnabled) e.preventDefault() - } - }, + var component = { + controller: function() {}, view: function() { - return m("div") + return sub } } var sub = { @@ -725,94 +658,90 @@ function testMithril(mock) { return subsub } } - var component = { - controller: function() {}, - view: function() { - return sub - } - } - m.route(root, "/a", { - "/a": component, - "/b": {controller: function() {loaded = true}, view: function() {}} - }) - - mock.requestAnimationFrame.$resolve() - - m.route("/b") - - mock.requestAnimationFrame.$resolve() - testEnabled = false - - return loaded === false - }) - test(function() { - // calling preventDefault from non-curried component's onunload should - // prevent route change - mock.requestAnimationFrame.$resolve() - mock.location.search = "?" - - var root = mock.document.createElement("div") - var loaded = false - var testEnabled = true - var sub = { - controller: function() { - this.onunload = function(e) { - if (testEnabled) e.preventDefault() - } - }, - view: function() { - return m("div") - } - } - var component = { - controller: function() {}, - view: function() { - return sub - } - } - m.route(root, "/a", { - "/a": component, - "/b": {controller: function() {loaded = true}, view: function() {}} - }) - - mock.requestAnimationFrame.$resolve() - - m.route("/b") - - mock.requestAnimationFrame.$resolve() - testEnabled = false - - return loaded === false - }) - test(function() { - // calling preventDefault from non-curried subcomponent's onunload - // should prevent route change - mock.requestAnimationFrame.$resolve() - mock.location.search = "?" - - var root = mock.document.createElement("div") - var loaded = false - var testEnabled = true var subsub = { controller: function() { - this.onunload = function(e) { - if (testEnabled) e.preventDefault() - } + this.onunload = function(e) {if (testEnabled) e.preventDefault()} }, view: function() { return m("div") } } + m.route(root, "/a", { + "/a": component, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) + test(function() { + //calling preventDefault from non-curried component's onunload should prevent route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var component = { + controller: function() {}, + view: function() { + return sub + } + } + var sub = { + controller: function() { + this.onunload = function(e) {if (testEnabled) e.preventDefault()} + }, + view: function() { + return m("div") + } + } + m.route(root, "/a", { + "/a": component, + "/b": {controller: function() {loaded = true}, view: function() {}} + }) + + mock.requestAnimationFrame.$resolve() + + m.route("/b") + + mock.requestAnimationFrame.$resolve() + testEnabled = false + + return loaded === false + }) + test(function() { + //calling preventDefault from non-curried subcomponent's onunload should prevent route change + mock.requestAnimationFrame.$resolve() + mock.location.search = "?" + + var root = mock.document.createElement("div") + var loaded = false + var testEnabled = true + var component = { + controller: function() {}, + view: function() { + return sub + } + } var sub = { controller: function() {}, view: function() { return subsub } } - var component = { - controller: function() {}, + var subsub = { + controller: function() { + this.onunload = function(e) {if (testEnabled) e.preventDefault()} + }, view: function() { - return sub + return m("div") } } m.route(root, "/a", { @@ -835,29 +764,29 @@ function testMithril(mock) { var root = mock.document.createElement("div") var count = 0 - var Reply = { + var App = { controller: function() {}, view: function() { - count++ - return m(".reply") + return m('.outer', [ + m('.inner', m.component(CommentList, { list: [1, 2, 3] })) + ]) } } var CommentList = { controller: function() {}, view: function(ctrl, props) { - return m(".list", props.list.map(function(i) { - return m(".comment", [ + return m('.list', props.list.map(function(i) { + return m('.comment', [ m.component(Reply, {key: i}) ]) })) } } - var App = { + var Reply = { controller: function() {}, view: function() { - return m(".outer", [ - m(".inner", m.component(CommentList, { list: [1, 2, 3] })) - ]) + count++ + return m(".reply") } } m.mount(root, App) @@ -885,15 +814,15 @@ function testMithril(mock) { m.route(root, "/a", { "/a": { view: function () { - return m(".page-a", [ - m("h1"), m.component(subA, { x: 11 }) + return m('.page-a', [ + m('h1'), m.component(subA, { x: 11 }) ]) } }, "/b": { view: function() { - return m(".page-b", [ - m("h2"), m.component(subB, { y: 22 }) + return m('.page-b', [ + m('h2'), m.component(subB, { y: 22 }) ]) } } @@ -913,8 +842,7 @@ function testMithril(mock) { }) test(function() { var root = mock.document.createElement("div") - var component = {} - var unloaded = false + var component = {}, unloaded = false component.controller = function() { this.onunload = function() {unloaded = true} } @@ -955,11 +883,7 @@ function testMithril(mock) { var component = { view: function() { return [ - m(".foo", { - key: 1, - config: test, - onclick: function() {show = !show} - }), + m(".foo", {key: 1, config: test, onclick: function() {show = !show}}), show ? m(".bar", {key: 2}) : null ] } @@ -993,22 +917,22 @@ function testMithril(mock) { var testcomponent = { controller: function() {}, view: function() { - return m("div", "component") + return m('div', 'component'); } } var app = { view: function() { return show ? [ - m("h1", "1"), + m('h1', '1'), testcomponent ] : [ - m("h1", "2") - ] + m('h1', '2') + ]; } - } + }; - m.mount(root, app) + m.mount(root, app); mock.requestAnimationFrame.$resolve() @@ -1031,7 +955,7 @@ function testMithril(mock) { var Component = { view: function () { - return m(".comp") + return m('.comp') } } @@ -1050,12 +974,14 @@ function testMithril(mock) { return root.childNodes[0].nodeName === "DIV" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/551 + //https://github.com/lhorie/mithril.js/issues/551 var root = mock.document.createElement("div") - var a = false - var found = false - var unloaded = false - var redraws = 0 + var a = false, found = false, unloaded = false, redraws = 0 + var Root = { + view: function() { + return Comp + } + } var Comp = { view: function() { redraws++ @@ -1070,18 +996,11 @@ function testMithril(mock) { ]) }, config: function(el, init, ctx) { - if (!init) { - ctx.onunload = function() { - unloaded = true - } + if (!init) ctx.onunload = function() { + unloaded = true } } } - var Root = { - view: function() { - return Comp - } - } m.mount(root, Root) var target = root.childNodes[0].childNodes[0] @@ -1092,12 +1011,14 @@ function testMithril(mock) { return !unloaded && found.id === "a" && redraws === 3 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/551 + //https://github.com/lhorie/mithril.js/issues/551 var root = mock.document.createElement("div") - var a = false - var found = false - var unloaded = false - var redraws = 0 + var a = false, found = false, unloaded = false, redraws = 0 + var Root = { + view: function() { + return Comp + } + } var Comp = { view: function() { redraws++ @@ -1113,18 +1034,11 @@ function testMithril(mock) { ]) }, config: function(el, init, ctx) { - if (!init) { - ctx.onunload = function() { - unloaded = true - } + if (!init) ctx.onunload = function() { + unloaded = true } } } - var Root = { - view: function() { - return Comp - } - } m.mount(root, Root) var target = root.childNodes[0].childNodes[0] @@ -1154,37 +1068,37 @@ function testMithril(mock) { return redraws === 3 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/555 + //https://github.com/lhorie/mithril.js/issues/555 var root = mock.document.createElement("div") var MyComponent = { controller: function(args) { - this.name = args.name + this.name = args.name; }, view: function(ctrl) { - return m("div", ctrl.name) + return m('div', ctrl.name); } } var FooPage = { view: function() { - return m("div", [ - m("a[href=/]", {config: m.route}, "foo"), - m("a[href=/bar]", {config: m.route}, "bar"), - m.component(MyComponent, {name: "Jane"}) - ]) + return m('div', [ + m('a[href=/]', {config: m.route}, 'foo'), + m('a[href=/bar]', {config: m.route}, 'bar'), + m.component(MyComponent, {name: 'Jane'}) + ]); } - } + }; var BarPage = { view: function() { - return m("div", [ - m("a[href=/]", {config: m.route}, "foo"), - m("a[href=/bar]", {config: m.route}, "bar"), - m.component(MyComponent, {name: "Bob"}) - ]) + return m('div', [ + m('a[href=/]', {config: m.route}, 'foo'), + m('a[href=/bar]', {config: m.route}, 'bar'), + m.component(MyComponent, {name: 'Bob'}) + ]); } - } - m.route(root, "/", { - "/": FooPage, - "/bar": BarPage + }; + m.route(root, '/', { + '/': FooPage, + '/bar': BarPage }) mock.requestAnimationFrame.$resolve() @@ -1193,13 +1107,17 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() - return root.childNodes[0].childNodes[2] - .childNodes[0].nodeValue === "Bob" + return root.childNodes[0].childNodes[2].childNodes[0].nodeValue === "Bob" }) test(function() { var root = mock.document.createElement("div") - var redraws = 0 - var data + var redraws = 0, data + var Root = { + view: function() { + return Comp + } + } + var Comp = { controller: function() { this.foo = m.request({method: "GET", url: "/foo"}) @@ -1210,11 +1128,6 @@ function testMithril(mock) { return m("div") } } - var Root = { - view: function() { - return Comp - } - } m.mount(root, Root) @@ -1232,15 +1145,13 @@ function testMithril(mock) { mock.location.search = "?" var root = mock.document.createElement("div") - var redraws1 = 0 - var redraws2 = 0 - var Comp2 = { - controller: function() { - this.bar = m.request({method: "GET", url: "/bar"}) - }, + var redraws1 = 0, redraws2 = 0 + var Root = { view: function() { - redraws2++ - return m("div") + return m("div", [ + Comp1, + Comp2 + ]) } } var Comp1 = { @@ -1252,12 +1163,13 @@ function testMithril(mock) { return m("div") } } - var Root = { + var Comp2 = { + controller: function() { + this.bar = m.request({method: "GET", url: "/bar"}) + }, view: function() { - return m("div", [ - Comp1, - Comp2 - ]) + redraws2++ + return m("div") } } @@ -1277,8 +1189,17 @@ function testMithril(mock) { }) test(function() { var root = mock.document.createElement("div") - var redraws1 = 0 - var redraws2 = 0 + var redraws1 = 0, redraws2 = 0 + var Root1 = { + view: function() { + return Comp1 + } + } + var Root2 = { + view: function() { + return Comp2 + } + } var Comp1 = { controller: function() { this.foo = m.request({method: "GET", url: "/foo"}) @@ -1297,16 +1218,6 @@ function testMithril(mock) { return m("div") } } - var Root1 = { - view: function() { - return Comp1 - } - } - var Root2 = { - view: function() { - return Comp2 - } - } m.route(root, "/", { @@ -1333,8 +1244,13 @@ function testMithril(mock) { var root = mock.document.createElement("div") var cond = true - var controller1 = null - var controller2 = null + var controller1 = null, controller2 = null + var Root = { + view: function() { + return cond ? Comp1 : Comp2 + } + } + var Comp1 = { view: function(ctrl) { controller1 = ctrl @@ -1347,11 +1263,6 @@ function testMithril(mock) { return m("div") } } - var Root = { - view: function() { - return cond ? Comp1 : Comp2 - } - } m.mount(root, Root) @@ -1369,6 +1280,12 @@ function testMithril(mock) { var cond = true var unloaded = false + var Root = { + view: function() { + return cond ? Comp1 : Comp2 + } + } + var Comp1 = { view: function() { return m("div", {config: function(el, init, ctx) { @@ -1381,11 +1298,6 @@ function testMithril(mock) { return m("div") } } - var Root = { - view: function() { - return cond ? Comp1 : Comp2 - } - } m.mount(root, Root) @@ -1403,6 +1315,12 @@ function testMithril(mock) { var cond = true var initialized = null + var Root = { + view: function() { + return cond ? Comp1 : Comp2 + } + } + var Comp1 = { view: function() { return m("div") @@ -1415,11 +1333,6 @@ function testMithril(mock) { }}) } } - var Root = { - view: function() { - return cond ? Comp1 : Comp2 - } - } m.mount(root, Root) @@ -1435,31 +1348,31 @@ function testMithril(mock) { test(function() { var root = mock.document.createElement("div") var el - var BarComponent = { - view: function() { - return m("#bar", "test") - } - } var FooPage = { view: function(ctrl) { - return m("div", [ - m("button", {onclick: function() { - ctrl.bar = true - m.redraw(true) + return m('div', [ + m('button', {onclick: function() { + ctrl.bar = true; + m.redraw(true); el = root.childNodes[0].childNodes[1] - }}, "click me"), - ctrl.bar ? m.component(BarComponent) : "" - ]) + }}, 'click me'), + ctrl.bar ? m.component(BarComponent) : '' + ]); } - } - m.mount(root, FooPage) + }; + var BarComponent = { + view: function() { + return m('#bar', 'test'); + } + }; + m.mount(root, FooPage); root.childNodes[0].childNodes[0].onclick({}) return el.id === "bar" }) - // m.withAttr + //m.withAttr test(function() { var value var handler = m.withAttr("test", function(data) {value = data}) @@ -1467,10 +1380,10 @@ function testMithril(mock) { return value === "foo" }) - // m.trust + //m.trust test(function() {return m.trust("test").valueOf() === "test"}) - // m.render + //m.render test(function() { var root = mock.document.createElement("div") m.render(root, "test") @@ -1478,9 +1391,9 @@ function testMithril(mock) { }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", {class: "a"})) + m.render(root, m("div", {"class": "a"})) var elementBefore = root.childNodes[0] - m.render(root, m("div", {class: "b"})) + m.render(root, m("div", {"class": "b"})) var elementAfter = root.childNodes[0] return elementBefore === elementAfter }) @@ -1525,8 +1438,7 @@ function testMithril(mock) { var root = mock.document.createElement("div") m.render(root, m("svg", [m("g")])) var g = root.childNodes[0].childNodes[0] - return g.nodeName === "G" && - g.namespaceURI === "http://www.w3.org/2000/svg" + return g.nodeName === "G" && g.namespaceURI === "http://www.w3.org/2000/svg" }) test(function() { var root = mock.document.createElement("div") @@ -1570,12 +1482,10 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].nodeName === "B" }) test(function() { - /* eslint-disable no-new-wrappers */ var root = mock.document.createElement("div") m.render(root, m("ul", [m("li")])) m.render(root, m("ul", [{tag: new String("b"), attrs: {}}])) return root.childNodes[0].childNodes[0].nodeName === "B" - /* eslint-enable no-new-wrappers */ }) test(function() { var root = mock.document.createElement("div") @@ -1584,49 +1494,49 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].childNodes[0].nodeName === "A" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/43 + //https://github.com/lhorie/mithril.js/issues/43 var root = mock.document.createElement("div") m.render(root, m("a", {config: m.route}, "test")) m.render(root, m("a", {config: m.route}, "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/44 (1) + //https://github.com/lhorie/mithril.js/issues/44 (1) var root = mock.document.createElement("div") m.render(root, m("#foo", [null, m("#bar")])) m.render(root, m("#foo", ["test", m("#bar")])) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/44 (2) + //https://github.com/lhorie/mithril.js/issues/44 (2) var root = mock.document.createElement("div") m.render(root, m("#foo", [null, m("#bar")])) m.render(root, m("#foo", [m("div"), m("#bar")])) return root.childNodes[0].childNodes[0].nodeName === "DIV" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/44 (3) + //https://github.com/lhorie/mithril.js/issues/44 (3) var root = mock.document.createElement("div") m.render(root, m("#foo", ["test", m("#bar")])) m.render(root, m("#foo", [m("div"), m("#bar")])) return root.childNodes[0].childNodes[0].nodeName === "DIV" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/44 (4) + //https://github.com/lhorie/mithril.js/issues/44 (4) var root = mock.document.createElement("div") m.render(root, m("#foo", [m("div"), m("#bar")])) m.render(root, m("#foo", ["test", m("#bar")])) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/44 (5) + //https://github.com/lhorie/mithril.js/issues/44 (5) var root = mock.document.createElement("div") m.render(root, m("#foo", [m("#bar")])) m.render(root, m("#foo", [m("#bar"), [m("#baz")]])) return root.childNodes[0].childNodes[1].id === "baz" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/48 + //https://github.com/lhorie/mithril.js/issues/48 var root = mock.document m.render(root, m("html", [m("#foo")])) var result = root.childNodes[0].childNodes[0].id === "foo" @@ -1634,120 +1544,87 @@ function testMithril(mock) { return result }) test(function() { - // https://github.com/lhorie/mithril.js/issues/49 + //https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a", "test")) m.render(root, m("a.foo", "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/49 + //https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a.foo", "test")) m.render(root, m("a", "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/49 + //https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a.foo", "test")) m.render(root, m("a", "test1")) return root.childNodes[0].childNodes[0].nodeValue === "test1" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/49 + //https://github.com/lhorie/mithril.js/issues/49 var root = mock.document.createElement("div") m.render(root, m("a", "test")) m.render(root, m("a", "test1")) return root.childNodes[0].childNodes[0].nodeValue === "test1" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/50 + //https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], m("#bar")])) return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "b" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/50 + //https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], m("#bar")])) - m.render(root, m("#foo", [ - [m("div", "a"), m("div", "b"), m("div", "c")], - m("#bar") - ])) + m.render(root, m("#foo", [[m("div", "a"), m("div", "b"), m("div", "c")], m("#bar")])) return root.childNodes[0].childNodes[2].childNodes[0].nodeValue === "c" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/50 + //https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") - m.render(root, m("#foo", [ - [m("div", "a"), m("div", "b")], - [m("div", "c"), m("div", "d")], - m("#bar") - ])) - var children = root.childNodes[0] - return children.childNodes[3].childNodes[0].nodeValue === "d" && - children.childNodes[4].id === "bar" + m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], [m("div", "c"), m("div", "d")], m("#bar")])) + return root.childNodes[0].childNodes[3].childNodes[0].nodeValue === "d" && root.childNodes[0].childNodes[4].id === "bar" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/50 + //https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], "test"])) - var children = root.childNodes[0] - return children.childNodes[1].childNodes[0].nodeValue === "b" && - children.childNodes[2].nodeValue === "test" + return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "b" && root.childNodes[0].childNodes[2].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/50 + //https://github.com/lhorie/mithril.js/issues/50 var root = mock.document.createElement("div") m.render(root, m("#foo", [["a", "b"], "test"])) - return root.childNodes[0].childNodes[1].nodeValue === "b" && - root.childNodes[0].childNodes[2].nodeValue === "test" + return root.childNodes[0].childNodes[1].nodeValue === "b" && root.childNodes[0].childNodes[2].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/51 + //https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [ - m("button"), - m("article", [m("section"), m("nav")]) - ])) - m.render(root, m("main", [ - m("button"), - m("article", [m("span"), m("nav")]) - ])) - return root.childNodes[0].childNodes[1] - .childNodes[0].nodeName === "SPAN" + m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) + m.render(root, m("main", [m("button"), m("article", [m("span"), m("nav")])])) + return root.childNodes[0].childNodes[1].childNodes[0].nodeName === "SPAN" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/51 + //https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [ - m("button"), - m("article", [m("section"), m("nav")]) - ])) - m.render(root, m("main", [ - m("button"), - m("article", ["test", m("nav")]) - ])) - return root.childNodes[0].childNodes[1] - .childNodes[0].nodeValue === "test" + m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) + m.render(root, m("main", [m("button"), m("article", ["test", m("nav")])])) + return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/51 + //https://github.com/lhorie/mithril.js/issues/51 var root = mock.document.createElement("div") - m.render(root, m("main", [ - m("button"), - m("article", [m("section"), m("nav")]) - ])) - m.render(root, m("main", [ - m("button"), - m("article", [m.trust("test"), m("nav")]) - ])) - return root.childNodes[0].childNodes[1] - .childNodes[0].nodeValue === "test" + m.render(root, m("main", [m("button"), m("article", [m("section"), m("nav")])])) + m.render(root, m("main", [m("button"), m("article", [m.trust("test"), m("nav")])])) + return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "test" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/55 + //https://github.com/lhorie/mithril.js/issues/55 var root = mock.document.createElement("div") m.render(root, m("#a")) var elementBefore = root.childNodes[0] @@ -1756,14 +1633,14 @@ function testMithril(mock) { return elementBefore !== elementAfter }) test(function() { - // https://github.com/lhorie/mithril.js/issues/56 + //https://github.com/lhorie/mithril.js/issues/56 var root = mock.document.createElement("div") m.render(root, [null, "foo"]) m.render(root, ["bar"]) return root.childNodes.length === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/56 + //https://github.com/lhorie/mithril.js/issues/56 var root = mock.document.createElement("div") m.render(root, m("div", "foo")) return root.childNodes.length === 1 @@ -1784,13 +1661,10 @@ function testMithril(mock) { m.render(root, m("div", [undefined, m("ul")])) var valueAfter1 = root.childNodes[0].childNodes[0].nodeValue var valueAfter2 = root.childNodes[0].childNodes[1].nodeName - return valueBefore1 === "UL" && - valueAfter1 === "" && - valueBefore2 === "" && - valueAfter2 === "UL" + return valueBefore1 === "UL" && valueAfter1 === "" && valueBefore2 === "" && valueAfter2 === "UL" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/79 + //https://github.com/lhorie/mithril.js/issues/79 var root = mock.document.createElement("div") m.render(root, m("div", {style: {background: "red"}})) var valueBefore = root.childNodes[0].style.background @@ -1812,61 +1686,52 @@ function testMithril(mock) { return valueBefore === "red" && valueAfter === undefined }) test(function() { - // https://github.com/lhorie/mithril.js/issues/87 + //https://github.com/lhorie/mithril.js/issues/87 var root = mock.document.createElement("div") m.render(root, m("div", [[m("a"), m("a")], m("button")])) m.render(root, m("div", [[m("a")], m("button")])) - return root.childNodes[0].childNodes.length === 2 && - root.childNodes[0].childNodes[1].nodeName === "BUTTON" + return root.childNodes[0].childNodes.length === 2 && root.childNodes[0].childNodes[1].nodeName === "BUTTON" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/87 + //https://github.com/lhorie/mithril.js/issues/87 var root = mock.document.createElement("div") m.render(root, m("div", [m("a"), m("b"), m("button")])) m.render(root, m("div", [m("a"), m("button")])) - return root.childNodes[0].childNodes.length === 2 && - root.childNodes[0].childNodes[1].nodeName === "BUTTON" + return root.childNodes[0].childNodes.length === 2 && root.childNodes[0].childNodes[1].nodeName === "BUTTON" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/99 + //https://github.com/lhorie/mithril.js/issues/99 var root = mock.document.createElement("div") m.render(root, m("div", [m("img"), m("h1")])) m.render(root, m("div", [m("a")])) - return root.childNodes[0].childNodes.length === 1 && - root.childNodes[0].childNodes[0].nodeName === "A" + return root.childNodes[0].childNodes.length === 1 && root.childNodes[0].childNodes[0].nodeName === "A" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", "b", "c", "d"])) m.render(root, m("div", [["d", "e"]])) var children = root.childNodes[0].childNodes - return children.length === 2 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 2 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", [["a", "b", "c", "d"]])) m.render(root, m("div", ["d", "e"])) var children = root.childNodes[0].childNodes - return children.length === 2 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 2 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["x", [["a"], "b", "c", "d"]])) m.render(root, m("div", ["d", ["e"]])) var children = root.childNodes[0].childNodes - return children.length === 2 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 2 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["b"])) m.render(root, m("div", [["e"]])) @@ -1874,74 +1739,60 @@ function testMithril(mock) { return children.length === 1 && children[0].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", ["b"]])) m.render(root, m("div", ["d", [["e"]]])) var children = root.childNodes[0].childNodes - return children.length === 2 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 2 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", [["b"]]])) m.render(root, m("div", ["d", ["e"]])) var children = root.childNodes[0].childNodes - return children.length === 2 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 2 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/120 + //https://github.com/lhorie/mithril.js/issues/120 var root = mock.document.createElement("div") m.render(root, m("div", ["a", [["b"], "c"]])) m.render(root, m("div", ["d", [[["e"]], "x"]])) var children = root.childNodes[0].childNodes - return children.length === 3 && - children[0].nodeValue === "d" && - children[1].nodeValue === "e" + return children.length === 3 && children[0].nodeValue === "d" && children[1].nodeValue === "e" }) test(function() { var root = mock.document.createElement("div") var success = false - m.render(root, m("div", { - config: function(elem, isInitialized, ctx) { ctx.data = 1 } - })) - m.render(root, m("div", { - config: function(elem, isInitialized, ctx) { - success = ctx.data === 1 - } - })) + m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data = 1}})) + m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data === 1}})) return success }) test(function() { var root = mock.document.createElement("div") - var index = 0 - var success = true - var statefulConfig = function(elem, isInitialized, ctx) { - ctx.data = index++ - } - var node = m("div", {config: statefulConfig}) - m.render(root, [node, node]) + var index = 0; + var success = true; + var statefulConfig = function(elem, isInitialized, ctx) {ctx.data = index++} + var node = m("div", {config: statefulConfig}); + m.render(root, [node, node]); - index = 0 + index = 0; var checkConfig = function(elem, isInitialized, ctx) { success = success && (ctx.data === index++) } - node = m("div", {config: checkConfig}) - m.render(root, [node, node]) - return success + node = m("div", {config: checkConfig}); + m.render(root, [node, node]); + return success; }) test(function() { var root = mock.document.createElement("div") var parent m.render(root, m("div", m("a", { - config: function(el) { parent = el.parentNode.parentNode } - }))) + config: function(el) {parent = el.parentNode.parentNode} + }))); return parent === root }) test(function() { @@ -1954,186 +1805,99 @@ function testMithril(mock) { if (count > 2) throw new Error("too much recursion...") m.render(island, m("div")) } - }))) + }))); return count === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/129 + //https://github.com/lhorie/mithril.js/issues/129 var root = mock.document.createElement("div") - m.render(root, m("div", [ - ["foo", "bar"], - ["foo", "bar"], - ["foo", "bar"] - ])) - m.render(root, m("div", ["asdf", "asdf2", "asdf3"])) + m.render(root, m("div", [["foo", "bar"], ["foo", "bar"], ["foo", "bar"]])); + m.render(root, m("div", ["asdf", "asdf2", "asdf3"])); return true }) test(function() { - // https://github.com/lhorie/mithril.js/issues/98 - // insert at beginning + //https://github.com/lhorie/mithril.js/issues/98 + //insert at beginning var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3) - ]) + m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) var firstBefore = root.childNodes[0] - m.render(root, [ - m("a", {key: 4}, 4), - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3) - ]) + m.render(root, [m("a", {key: 4}, 4), m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) var firstAfter = root.childNodes[1] - return firstBefore === firstAfter && - root.childNodes[0].childNodes[0].nodeValue === "4" && - root.childNodes.length === 4 + return firstBefore === firstAfter && root.childNodes[0].childNodes[0].nodeValue === "4" && root.childNodes.length === 4 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/98 + //https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3) - ]) + m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) var firstBefore = root.childNodes[0] - m.render(root, [ - m("a", {key: 4}, 4), - m("a", {key: 1}, 1), - m("a", {key: 2}, 2) - ]) + m.render(root, [m("a", {key: 4}, 4), m("a", {key: 1}, 1), m("a", {key: 2}, 2)]) var firstAfter = root.childNodes[1] - return firstBefore === firstAfter && - root.childNodes[0].childNodes[0].nodeValue === "4" && - root.childNodes.length === 3 + return firstBefore === firstAfter && root.childNodes[0].childNodes[0].nodeValue === "4" && root.childNodes.length === 3 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/98 + //https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3) - ]) + m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3)]) var firstBefore = root.childNodes[1] - m.render(root, [ - m("a", {key: 2}, 2), - m("a", {key: 3}, 3), - m("a", {key: 4}, 4) - ]) + m.render(root, [m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4)]) var firstAfter = root.childNodes[0] - return firstBefore === firstAfter && - root.childNodes[0].childNodes[0].nodeValue === "2" && - root.childNodes.length === 3 + return firstBefore === firstAfter && root.childNodes[0].childNodes[0].nodeValue === "2" && root.childNodes.length === 3 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/98 + //https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3), - m("a", {key: 4}, 4), - m("a", {key: 5}, 5) - ]) + m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4), m("a", {key: 5}, 5)]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var fourthBefore = root.childNodes[3] - m.render(root, [ - m("a", {key: 4}, 4), - m("a", {key: 10}, 10), - m("a", {key: 1}, 1), - m("a", {key: 2}, 2) - ]) + m.render(root, [m("a", {key: 4}, 4), m("a", {key: 10}, 10), m("a", {key: 1}, 1), m("a", {key: 2}, 2)]) var firstAfter = root.childNodes[2] var secondAfter = root.childNodes[3] var fourthAfter = root.childNodes[0] - return firstBefore === firstAfter && - secondBefore === secondAfter && - fourthBefore === fourthAfter && - root.childNodes[1].childNodes[0].nodeValue === "10" && - root.childNodes.length === 4 + return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].childNodes[0].nodeValue === "10" && root.childNodes.length === 4 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/98 + //https://github.com/lhorie/mithril.js/issues/98 var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}, 1), - m("a", {key: 2}, 2), - m("a", {key: 3}, 3), - m("a", {key: 4}, 4), - m("a", {key: 5}, 5) - ]) + m.render(root, [m("a", {key: 1}, 1), m("a", {key: 2}, 2), m("a", {key: 3}, 3), m("a", {key: 4}, 4), m("a", {key: 5}, 5)]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var fourthBefore = root.childNodes[3] - m.render(root, [ - m("a", {key: 4}, 4), - m("a", {key: 10}, 10), - m("a", {key: 2}, 2), - m("a", {key: 1}, 1), - m("a", {key: 6}, 6), - m("a", {key: 7}, 7) - ]) + m.render(root, [m("a", {key: 4}, 4), m("a", {key: 10}, 10), m("a", {key: 2}, 2), m("a", {key: 1}, 1), m("a", {key: 6}, 6), m("a", {key: 7}, 7)]) var firstAfter = root.childNodes[3] var secondAfter = root.childNodes[2] var fourthAfter = root.childNodes[0] - return firstBefore === firstAfter && - secondBefore === secondAfter && - fourthBefore === fourthAfter && - root.childNodes[1].childNodes[0].nodeValue === "10" && - root.childNodes[4].childNodes[0].nodeValue === "6" && - root.childNodes[5].childNodes[0].nodeValue === "7" && - root.childNodes.length === 6 + return firstBefore === firstAfter && secondBefore === secondAfter && fourthBefore === fourthAfter && root.childNodes[1].childNodes[0].nodeValue === "10" && root.childNodes[4].childNodes[0].nodeValue === "6" && root.childNodes[5].childNodes[0].nodeValue === "7" && root.childNodes.length === 6 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/149 + //https://github.com/lhorie/mithril.js/issues/149 var root = mock.document.createElement("div") - m.render(root, [ - m("a", {key: 1}), - m("a", {key: 2}), - m("a"), - m("a", {key: 4}), - m("a", {key: 5}) - ]) + m.render(root, [m("a", {key: 1}), m("a", {key: 2}), m("a"), m("a", {key: 4}), m("a", {key: 5})]) var firstBefore = root.childNodes[0] var secondBefore = root.childNodes[1] var thirdBefore = root.childNodes[2] var fourthBefore = root.childNodes[3] var fifthBefore = root.childNodes[4] - m.render(root, [ - m("a", {key: 4}), - m("a", {key: 5}), - m("a"), - m("a", {key: 1}), - m("a", {key: 2}) - ]) + m.render(root, [m("a", {key: 4}), m("a", {key: 5}), m("a"), m("a", {key: 1}), m("a", {key: 2})]) var firstAfter = root.childNodes[3] var secondAfter = root.childNodes[4] var thirdAfter = root.childNodes[2] var fourthAfter = root.childNodes[0] var fifthAfter = root.childNodes[1] - return firstBefore === firstAfter && - secondBefore === secondAfter && - thirdBefore === thirdAfter && - fourthBefore === fourthAfter && - fifthBefore === fifthAfter + return firstBefore === firstAfter && secondBefore === secondAfter && thirdBefore === thirdAfter && fourthBefore === fourthAfter && fifthBefore === fifthAfter }) test(function() { - // https://github.com/lhorie/mithril.js/issues/246 - // insert at beginning with non-keyed in the middle + //https://github.com/lhorie/mithril.js/issues/246 + //insert at beginning with non-keyed in the middle var root = mock.document.createElement("div") m.render(root, [m("a", {key: 1}, 1)]) var firstBefore = root.childNodes[0] m.render(root, [m("a", {key: 2}, 2), m("br"), m("a", {key: 1}, 1)]) var firstAfter = root.childNodes[2] - return firstBefore === firstAfter && - root.childNodes[0].childNodes[0].nodeValue === "2" && - root.childNodes.length === 3 + return firstBefore === firstAfter && root.childNodes[0].childNodes[0].nodeValue === "2" && root.childNodes.length === 3 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/134 + //https://github.com/lhorie/mithril.js/issues/134 var root = mock.document.createElement("div") m.render(root, m("div", {contenteditable: true}, "test")) mock.document.activeElement = root.childNodes[0] @@ -2142,7 +1906,7 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].nodeValue === "test2" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/136 + //https://github.com/lhorie/mithril.js/issues/136 var root = mock.document.createElement("div") m.render(root, m("textarea", ["test"])) m.render(root, m("textarea", ["test1"])) @@ -2188,12 +1952,8 @@ function testMithril(mock) { unloadedChild++ } } - m.render(root, m("div", { - config: configParent - }, m("a", {config: configChild}))) - m.render(root, m("main", { - config: configParent - }, m("a", {config: configChild}))) + m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) + m.render(root, m("main", {config: configParent}, m("a", {config: configChild}))) return unloadedParent === 1 && unloadedChild === 0 }) test(function() { @@ -2210,24 +1970,19 @@ function testMithril(mock) { unloadedChild++ } } - m.render(root, m("div", { - config: configParent - }, m("a", {config: configChild}))) - m.render(root, m("main", { - config: configParent - }, m("b", {config: configChild}))) + m.render(root, m("div", {config: configParent}, m("a", {config: configChild}))) + m.render(root, m("main", {config: configParent}, m("b", {config: configChild}))) return unloadedParent === 1 && unloadedChild === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/150 + //https://github.com/lhorie/mithril.js/issues/150 var root = mock.document.createElement("div") m.render(root, [m("a"), m("div")]) m.render(root, [[], m("div")]) - return root.childNodes.length === 1 && - root.childNodes[0].nodeName === "DIV" + return root.childNodes.length === 1 && root.childNodes[0].nodeName === "DIV" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/156 + //https://github.com/lhorie/mithril.js/issues/156 var root = mock.document.createElement("div") m.render(root, m("div", [ ["a", "b", "c", "d"].map(function() { @@ -2238,94 +1993,43 @@ function testMithril(mock) { return root.childNodes[0].childNodes[8].nodeName === "SPAN" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/157 + //https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") - m.render(root, m("ul", [ - m("li", {key: 0}, 0), - m("li", {key: 2}, 2), - m("li", {key: 4}, 4) - ])) - m.render(root, m("ul", [ - m("li", {key: 0}, 0), - m("li", {key: 1}, 1), - m("li", {key: 2}, 2), - m("li", {key: 3}, 3), - m("li", {key: 4}, 4), - m("li", {key: 5}, 5) - ])) - return root.childNodes[0].childNodes - .map(function(n) {return n.childNodes[0].nodeValue}) - .join("") === "012345" + m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 2}, 2), m("li", {key: 4}, 4)])) + m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) + return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join("") === "012345" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/157 + //https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") m.render(root, m("input", {value: "a"})) m.render(root, m("input", {value: "aa"})) return root.childNodes[0].childNodes.length === 0 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/157 + //https://github.com/lhorie/mithril.js/issues/157 var root = mock.document.createElement("div") - m.render(root, m("br", {class: "a"})) - m.render(root, m("br", {class: "aa"})) + m.render(root, m("br", {"class": "a"})) + m.render(root, m("br", {"class": "aa"})) return root.childNodes[0].childNodes.length === 0 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/194 + //https://github.com/lhorie/mithril.js/issues/194 var root = mock.document.createElement("div") - m.render(root, m("ul", [ - m("li", {key: 0}, 0), - m("li", {key: 1}, 1), - m("li", {key: 2}, 2), - m("li", {key: 3}, 3), - m("li", {key: 4}, 4), - m("li", {key: 5}, 5) - ])) - m.render(root, m("ul", [ - m("li", {key: 0}, 0), - m("li", {key: 1}, 1), - m("li", {key: 2}, 2), - m("li", {key: 4}, 4), - m("li", {key: 5}, 5) - ])) - return root.childNodes[0].childNodes - .map(function(n) {return n.childNodes[0].nodeValue}) - .join("") === "01245" + m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) + m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) + return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join("") === "01245" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/194 + //https://github.com/lhorie/mithril.js/issues/194 var root = mock.document.createElement("div") - m.render(root, m("ul", [ - m("li", {key: 0}, 0), - m("li", {key: 1}, 1), - m("li", {key: 2}, 2), - m("li", {key: 3}, 3), - m("li", {key: 4}, 4), - m("li", {key: 5}, 5) - ])) - m.render(root, m("ul", [ - m("li", {key: 1}, 1), - m("li", {key: 2}, 2), - m("li", {key: 3}, 3), - m("li", {key: 4}, 4), - m("li", {key: 5}, 5), - m("li", {key: 6}, 6) - ])) - m.render(root, m("ul", [ - m("li", {key: 12}, 12), - m("li", {key: 13}, 13), - m("li", {key: 14}, 14), - m("li", {key: 15}, 15), - m("li", {key: 16}, 16), - m("li", {key: 17}, 17) - ])) - return root.childNodes[0].childNodes - .map(function(n) {return n.childNodes[0].nodeValue}) - .join(",") === "12,13,14,15,16,17" + m.render(root, m("ul", [m("li", {key: 0}, 0), m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5)])) + m.render(root, m("ul", [m("li", {key: 1}, 1), m("li", {key: 2}, 2), m("li", {key: 3}, 3), m("li", {key: 4}, 4), m("li", {key: 5}, 5), m("li", {key: 6}, 6)])) + m.render(root, m("ul", [m("li", {key: 12}, 12), m("li", {key: 13}, 13), m("li", {key: 14}, 14), m("li", {key: 15}, 15), m("li", {key: 16}, 16), m("li", {key: 17}, 17)])) + return root.childNodes[0].childNodes.map(function(n) {return n.childNodes[0].nodeValue}).join(",") === "12,13,14,15,16,17" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/206 + //https://github.com/lhorie/mithril.js/issues/206 var root = mock.document.createElement("div") m.render(root, m("div", undefined)) m.render(root, m("div", [m("div")])) @@ -2339,7 +2043,7 @@ function testMithril(mock) { return root.childNodes[0].childNodes.length === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/200 + //https://github.com/lhorie/mithril.js/issues/200 var root = mock.document.createElement("div") var unloaded1 = false @@ -2369,12 +2073,12 @@ function testMithril(mock) { return root.childNodes.length === 2 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/277 + //https://github.com/lhorie/mithril.js/issues/277 var root = mock.document.createElement("div") function Field() { - this.tag = "div" - this.attrs = {} - this.children = "hello" + this.tag = "div"; + this.attrs = {}; + this.children = "hello"; } m.render(root, new Field()) return root.childNodes.length === 1 @@ -2385,71 +2089,19 @@ function testMithril(mock) { return root.childNodes.length === 0 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/299 + //https://github.com/lhorie/mithril.js/issues/299 var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("div", {key: 1}, 1), - m("div", {key: 2}, 2), - m("div", {key: 3}, 3), - m("div", {key: 4}, 4), - m("div", {key: 5}, 5), - null, null, null, null, null, null, null, null, null, null - ])) - m.render(root, m("div", [ - null, null, - m("div", {key: 3}, 3), - null, null, - m("div", {key: 6}, 6), - null, null, - m("div", {key: 9}, 9), - null, null, - m("div", {key: 12}, 12), - null, null, - m("div", {key: 15}, 15) - ])) - m.render(root, m("div", [ - m("div", {key: 1}, 1), - m("div", {key: 2}, 2), - m("div", {key: 3}, 3), - m("div", {key: 4}, 4), - m("div", {key: 5}, 5), - null, null, null, null, null, null, null, null, null, null - ])) - return root.childNodes[0].childNodes - .map(function(c) { - return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue - }) - .slice(0, 5) - .join("") === "12345" + m.render(root, m("div", [m("div", {key: 1}, 1), m("div", {key: 2}, 2), m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key: 5}, 5), null, null, null, null, null, null, null, null, null, null])) + m.render(root, m("div", [null, null, m("div", {key: 3}, 3), null, null, m("div", {key: 6}, 6), null, null, m("div", {key: 9}, 9), null, null, m("div", {key: 12}, 12), null, null, m("div", {key: 15}, 15)])) + m.render(root, m("div", [m("div", {key: 1}, 1), m("div", {key: 2}, 2), m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key: 5}, 5), null, null, null, null, null, null, null, null, null, null])) + return root.childNodes[0].childNodes.map(function(c) {return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue}).slice(0, 5).join("") === "12345" }) test(function() { - // https://github.com/lhorie/mithril.js/issues/377 + //https://github.com/lhorie/mithril.js/issues/377 var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("div", 1), - m("div", 2), - [ - m("div", {key: 3}, 3), - m("div", {key: 4}, 4), - m("div", {key: 5}, 5) - ], - [m("div", {key: 6}, 6)] - ])) - m.render(root, m("div", [ - m("div", 1), - null, - [ - m("div", {key: 3}, 3), - m("div", {key: 4}, 4), - m("div", {key: 5}, 5) - ], - [m("div", {key: 6}, 6)] - ])) - return root.childNodes[0].childNodes - .map(function(c) { - return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue - }) - .join("") === "13456" + m.render(root, m("div", [m("div", 1), m("div", 2), [m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key:5}, 5)], [m("div", {key: 6}, 6)]])) + m.render(root, m("div", [m("div", 1), null, [m("div", {key: 3}, 3), m("div", {key: 4}, 4), m("div", {key:5}, 5)], [m("div", {key: 6}, 6)]])) + return root.childNodes[0].childNodes.map(function(c) {return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue}).join("") === "13456" }) test(function() { var root = mock.document.createElement("div") @@ -2469,9 +2121,7 @@ function testMithril(mock) { m("#div-3", {key: 3}), m("#div-2", {key: 2}) ]) - return root.childNodes - .map(function(node) {return node.id}) - .join() === "div-1,div-3,div-2" + return root.childNodes.map(function(node) {return node.id}).join() === "div-1,div-3,div-2" }) test(function() { var root = mock.document.createElement("div") @@ -2485,8 +2135,7 @@ function testMithril(mock) { return root.childNodes[0].childNodes.length === 1 }) test(function() { - // if an element is preceded by a conditional, it should not lose its - // identity + //if an element is preceded by a conditional, it should not lose its identity var root = mock.document.createElement("div") m.render(root, m("div", [m("a"), m("input[autofocus]")])) var before = root.childNodes[0].childNodes[1] @@ -2495,112 +2144,52 @@ function testMithril(mock) { return before === after }) test(function() { - // unkeyed element should maintain identity if mixed w/ keyed elements - // and identity can be inferred + //unkeyed element should maintain identity if mixed w/ keyed elements and identity can be inferred var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("a", {key: 1}), - m("a", {key: 2}), - m("a", {key: 3}), - m("i") - ])) + m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), m("a", {key: 3}), m("i")])) var before = root.childNodes[0].childNodes[3] - m.render(root, m("div", [ - m("b", {key: 3}), - m("b", {key: 4}), - m("i"), - m("b", {key: 1}) - ])) + m.render(root, m("div", [m("b", {key: 3}), m("b", {key: 4}), m("i"), m("b", {key: 1})])) var after = root.childNodes[0].childNodes[2] return before === after }) test(function() { - // unkeyed element should maintain identity if mixed w/ keyed elements - // and text nodes and identity can be inferred + //unkeyed element should maintain identity if mixed w/ keyed elements and text nodes and identity can be inferred var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("a", {key: 1}), - m("a", {key: 2}), - "foo", - m("a", {key: 3}), - m("i") - ])) + m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), "foo", m("a", {key: 3}), m("i")])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [ - m("a", {key: 3}), - m("a", {key: 4}), - "bar", - m("i"), - m("a", {key: 1}) - ])) + m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), "bar", m("i"), m("a", {key: 1})])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("a", {key: 1}), - m("a", {key: 2}), - null, - m("a", {key: 3}), - m("i") - ])) + m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), null, m("a", {key: 3}), m("i")])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [ - m("a", {key: 3}), - m("a", {key: 4}), - null, - m("i"), - m("a", {key: 1}) - ])) + m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), null, m("i"), m("a", {key: 1})])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("a", {key: 1}), - m("a", {key: 2}), - undefined, - m("a", {key: 3}), - m("i") - ])) + m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), undefined, m("a", {key: 3}), m("i")])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [ - m("a", {key: 3}), - m("a", {key: 4}), - undefined, - m("i"), - m("a", {key: 1}) - ])) + m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), undefined, m("i"), m("a", {key: 1})])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - m.render(root, m("div", [ - m("a", {key: 1}), - m("a", {key: 2}), - m.trust("a"), - m("a", {key: 3}), - m("i") - ])) + m.render(root, m("div", [m("a", {key: 1}), m("a", {key: 2}), m.trust("a"), m("a", {key: 3}), m("i")])) var before = root.childNodes[0].childNodes[4] - m.render(root, m("div", [ - m("a", {key: 3}), - m("a", {key: 4}), - m.trust("a"), - m("i"), - m("a", {key: 1}) - ])) + m.render(root, m("div", [m("a", {key: 3}), m("a", {key: 4}), m.trust("a"), m("i"), m("a", {key: 1})])) var after = root.childNodes[0].childNodes[3] return before === after }) test(function() { var root = mock.document.createElement("div") - var vdom = m("div.a", {class: undefined}) + var vdom = m("div.a", {"class": undefined}) m.render(root, vdom) - return root.childNodes[0].class === "a" + return root.childNodes[0]["class"] === "a" }) test(function() { var root = mock.document.createElement("div") @@ -2608,11 +2197,11 @@ function testMithril(mock) { m.render(root, m(".a", [])) return root.childNodes[0].childNodes.length === 0 }) - // end m.render + //end m.render - // m.redraw + //m.redraw test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup var controller var root = mock.document.createElement("div") m.mount(root, { @@ -2627,7 +2216,7 @@ function testMithril(mock) { return valueBefore === "" && root.childNodes[0].nodeValue === "foo" }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup var count = 0 var root = mock.document.createElement("div") m.mount(root, { @@ -2636,18 +2225,18 @@ function testMithril(mock) { count++ } }) - mock.requestAnimationFrame.$resolve() // teardown - m.redraw() // should run synchronously + mock.requestAnimationFrame.$resolve() //teardown + m.redraw() //should run synchronously - m.redraw() // rest should run asynchronously since they're spamming + m.redraw() //rest should run asynchronously since they're spamming m.redraw() m.redraw() - mock.requestAnimationFrame.$resolve() // teardown + mock.requestAnimationFrame.$resolve() //teardown return count === 3 }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup var count = 0 var root = mock.document.createElement("div") m.mount(root, { @@ -2656,40 +2245,36 @@ function testMithril(mock) { count++ } }) - mock.requestAnimationFrame.$resolve() // teardown - m.redraw(true) // should run synchronously + mock.requestAnimationFrame.$resolve() //teardown + m.redraw(true) //should run synchronously - m.redraw(true) // forced to run synchronously + m.redraw(true) //forced to run synchronously m.redraw(true) m.redraw(true) - mock.requestAnimationFrame.$resolve() // teardown + mock.requestAnimationFrame.$resolve() //teardown return count === 5 }) - // m.route + //m.route test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/test1", { - "/test1": { - controller: function() {}, - view: function() {return "foo"} - } + "/test1": {controller: function() {}, view: function() {return "foo"}} }) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test1" && - root.childNodes[0].nodeValue === "foo" + var result = mock.location.search === "?/test1" && root.childNodes[0].nodeValue === "foo" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.pathname = "/" var root = mock.document.createElement("div") @@ -2707,64 +2292,51 @@ function testMithril(mock) { }) mock.requestAnimationFrame.$resolve() - var result = mock.location.pathname === "/test2" && - root.childNodes[0].nodeValue === "foo" && - root.childNodes[1].href === "/test2" + var result = mock.location.pathname === "/test2" && root.childNodes[0].nodeValue === "foo" && root.childNodes[1].href === "/test2" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.hash = "#" var root = mock.document.createElement("div") m.route.mode = "hash" m.route(root, "/test3", { - "/test3": { - controller: function() {}, - view: function() {return "foo"} - } + "/test3": {controller: function() {}, view: function() {return "foo"}} }) mock.requestAnimationFrame.$resolve() - var result = mock.location.hash === "#/test3" && - root.childNodes[0].nodeValue === "foo" + var result = mock.location.hash === "#/test3" && root.childNodes[0].nodeValue === "foo" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/test4/foo", { - "/test4/:test": { - controller: function() {}, - view: function() {return m.route.param("test")} - } + "/test4/:test": {controller: function() {}, view: function() {return m.route.param("test")}} }) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test4/foo" && - root.childNodes[0].nodeValue === "foo" + var result = mock.location.search === "?/test4/foo" && root.childNodes[0].nodeValue === "foo" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" - var component = { - controller: function() {}, - view: function() {return m.route.param("test")} - } + var component = {controller: function() {}, view: function() {return m.route.param("test")}} var root = mock.document.createElement("div") m.route.mode = "search" @@ -2778,22 +2350,17 @@ function testMithril(mock) { var paramValueAfter = m.route.param("test") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/" && - paramValueBefore === "foo" && - paramValueAfter === undefined + var result = mock.location.search === "?/" && paramValueBefore === "foo" && paramValueAfter === undefined - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" - var component = { - controller: function() {}, - view: function() {return m.route.param("a1")} - } + var component = {controller: function() {}, view: function() {return m.route.param("a1")}} var root = mock.document.createElement("div") m.route.mode = "search" @@ -2807,23 +2374,18 @@ function testMithril(mock) { var paramValueAfter = m.route.param("a1") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/" && - paramValueBefore === "foo" && - paramValueAfter === undefined + var result = mock.location.search === "?/" && paramValueBefore === "foo" && paramValueAfter === undefined - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - // https://github.com/lhorie/mithril.js/issues/61 - mock.requestAnimationFrame.$resolve() // setup + //https://github.com/lhorie/mithril.js/issues/61 + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" - var component = { - controller: function() {}, - view: function() {return m.route.param("a1")} - } + var component = {controller: function() {}, view: function() {return m.route.param("a1")}} var root = mock.document.createElement("div") m.route.mode = "search" @@ -2837,15 +2399,14 @@ function testMithril(mock) { var routeValueAfter = m.route() mock.requestAnimationFrame.$resolve() - var result = routeValueBefore === "/test7/foo" && - routeValueAfter === "/" + var result = routeValueBefore === "/test7/foo" && routeValueAfter === "/" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2860,15 +2421,14 @@ function testMithril(mock) { }) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test8/foo/SEP/bar/baz" && - root.childNodes[0].nodeValue === "foo_bar/baz" + var result = mock.location.search === "?/test8/foo/SEP/bar/baz" && root.childNodes[0].nodeValue === "foo_bar/baz" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2883,15 +2443,14 @@ function testMithril(mock) { }) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test9/foo/bar/SEP/baz" && - root.childNodes[0].nodeValue === "foo/bar_baz" + var result = mock.location.search === "?/test9/foo/bar/SEP/baz" && root.childNodes[0].nodeValue === "foo/bar_baz" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -2908,164 +2467,120 @@ function testMithril(mock) { var result = root.childNodes[0].nodeValue === "foo bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {return "foo"} - }, - "/test11": { - controller: function() {}, - view: function() {return "bar"} - } + "/": {controller: function() {}, view: function() {return "foo"}}, + "/test11": {controller: function() {}, view: function() {return "bar"}} }) mock.requestAnimationFrame.$resolve() m.route("/test11/") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test11/" && - root.childNodes[0].nodeValue === "bar" + var result = mock.location.search === "?/test11/" && root.childNodes[0].nodeValue === "bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {} - }, - "/test12": { - controller: function() {}, - view: function() {} - } + "/": {controller: function() {}, view: function() {}}, + "/test12": {controller: function() {}, view: function() {}} }) mock.requestAnimationFrame.$resolve() m.route("/test12?a=foo&b=bar") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test12?a=foo&b=bar" && - m.route.param("a") === "foo" && - m.route.param("b") === "bar" + var result = mock.location.search === "?/test12?a=foo&b=bar" && m.route.param("a") === "foo" && m.route.param("b") === "bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {return "bar"} - }, - "/test13/:test": { - controller: function() {}, - view: function() {return m.route.param("test")} - } + "/": {controller: function() {}, view: function() {return "bar"}}, + "/test13/:test": {controller: function() {}, view: function() {return m.route.param("test")}} }) mock.requestAnimationFrame.$resolve() m.route("/test13/foo?test=bar") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test13/foo?test=bar" && - root.childNodes[0].nodeValue === "foo" + var result = mock.location.search === "?/test13/foo?test=bar" && root.childNodes[0].nodeValue === "foo" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {return "bar"} - }, - "/test14": { - controller: function() {}, - view: function() {return "foo"} - } + "/": {controller: function() {}, view: function() {return "bar"}}, + "/test14": {controller: function() {}, view: function() {return "foo"}} }) mock.requestAnimationFrame.$resolve() m.route("/test14?test&test2=") mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test14?test&test2=" && - m.route.param("test") == null && - m.route.param("test2") === "" + var result = mock.location.search === "?/test14?test&test2=" && m.route.param("test") == null && m.route.param("test2") === "" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {} - }, - "/test12": { - controller: function() {}, - view: function() {} - } + "/": {controller: function() {}, view: function() {}}, + "/test12": {controller: function() {}, view: function() {}} }) mock.requestAnimationFrame.$resolve() m.route("/test12", {a: "foo", b: "bar"}) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test12?a=foo&b=bar" && - m.route.param("a") === "foo" && - m.route.param("b") === "bar" + var result = mock.location.search === "?/test12?a=foo&b=bar" && m.route.param("a") === "foo" && m.route.param("b") === "bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") var route1, route2 m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {route1 = m.route()}, - view: function() {} - }, - "/test13": { - controller: function() {route2 = m.route()}, - view: function() {} - } + "/": {controller: function() {route1 = m.route()}, view: function() {}}, + "/test13": {controller: function() {route2 = m.route()}, view: function() {}} }) mock.requestAnimationFrame.$resolve() m.route("/test13") @@ -3073,12 +2588,12 @@ function testMithril(mock) { var result = route1 === "/" && route2 === "/test13" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3105,12 +2620,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3145,12 +2660,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3182,12 +2697,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3221,12 +2736,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3258,12 +2773,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3307,12 +2822,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3355,12 +2870,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3369,30 +2884,30 @@ function testMithril(mock) { "/foo": { controller: function() {}, view: function() { - return m("div", "foo") + return m("div", "foo"); } }, "/bar": { controller: function() {}, view: function() { - return m("div", "bar") + return m("div", "bar"); } } }) mock.requestAnimationFrame.$resolve() - var foo = root.childNodes[0].childNodes[0].nodeValue + var foo = root.childNodes[0].childNodes[0].nodeValue; m.route("/bar") mock.requestAnimationFrame.$resolve() - var bar = root.childNodes[0].childNodes[0].nodeValue + var bar = root.childNodes[0].childNodes[0].nodeValue; var result = (foo === "foo" && bar === "bar") - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3407,13 +2922,13 @@ function testMithril(mock) { "/foo1": { controller: function() {}, view: function() { - return m("div", m("a", {config: config}, "foo")) + return m("div", m("a", {config: config}, "foo")); } }, "/bar1": { controller: function() {}, view: function() { - return m("main", m("a", {config: config}, "foo")) + return m("main", m("a", {config: config}, "foo")); } } }) @@ -3423,12 +2938,12 @@ function testMithril(mock) { var result = unloaded === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3441,7 +2956,7 @@ function testMithril(mock) { m.redraw.strategy("none") }, view: function() { - return m("div") + return m("div"); } } }) @@ -3449,24 +2964,23 @@ function testMithril(mock) { var result = strategy === "all" && root.childNodes.length === 0 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") - var count = 0 - var strategy + var strategy, count = 0 var config = function(el, init) {if (!init) count++} m.route.mode = "search" m.route(root, "/foo1", { "/foo1": { controller: function() {}, view: function() { - return m("div", {config: config}) + return m("div", {config: config}); } }, "/bar1": { @@ -3475,7 +2989,7 @@ function testMithril(mock) { m.redraw.strategy("redraw") }, view: function() { - return m("div", {config: config}) + return m("div", {config: config}); } } }) @@ -3485,12 +2999,12 @@ function testMithril(mock) { var result = strategy === "all" && count === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3504,22 +3018,21 @@ function testMithril(mock) { strategy = m.redraw.strategy() ctrl.number++ m.redraw.strategy("none") - }}, ctrl.number) + }}, ctrl.number); } } }) root.childNodes[0].onclick({}) mock.requestAnimationFrame.$resolve() - var result = strategy === "diff" && - root.childNodes[0].childNodes[0].nodeValue === "1" + var result = strategy === "diff" && root.childNodes[0].childNodes[0].nodeValue === "1" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3532,7 +3045,7 @@ function testMithril(mock) { view: function() { return m("div", {config: config, onclick: function() { m.redraw.strategy("all") - }}) + }}); } } }) @@ -3541,12 +3054,12 @@ function testMithril(mock) { var result = count === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3561,66 +3074,52 @@ function testMithril(mock) { }) var result = value === "foo+bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {return "foo"} - }, - "/test22": { - controller: function() {}, - view: function() {return "bar"} - } + "/": {controller: function() {}, view: function() {return "foo"}}, + "/test22": {controller: function() {}, view: function() {return "bar"}} }) mock.requestAnimationFrame.$resolve() m.route(String("/test22/")) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test22/" && - root.childNodes[0].nodeValue === "bar" + var result = mock.location.search === "?/test22/" && root.childNodes[0].nodeValue === "bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") m.route.mode = "search" m.route(root, "/", { - "/": { - controller: function() {}, - view: function() {return "foo"} - }, - "/test23": { - controller: function() {}, - view: function() {return "bar"} - } + "/": {controller: function() {}, view: function() {return "foo"}}, + "/test23": {controller: function() {}, view: function() {return "bar"}} }) mock.requestAnimationFrame.$resolve() - m.route(new String("/test23/")) // eslint-disable-line no-new-wrappers + m.route(new String("/test23/")) mock.requestAnimationFrame.$resolve() - var result = mock.location.search === "?/test23/" && - root.childNodes[0].nodeValue === "bar" + var result = mock.location.search === "?/test23/" && root.childNodes[0].nodeValue === "bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") @@ -3635,19 +3134,17 @@ function testMithril(mock) { }) var result = value === "foo+bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - mock.requestAnimationFrame.$resolve() // setup + mock.requestAnimationFrame.$resolve() //setup mock.location.search = "?" var root = mock.document.createElement("div") var value - /* eslint-disable no-new-wrappers */ m.route(root, new String("/foo+bar"), { - /* eslint-enable no-new-wrappers */ "/:arg": { controller: function() {value = m.route.param("arg")}, view: function() { @@ -3657,7 +3154,7 @@ function testMithril(mock) { }) var result = value === "foo+bar" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3683,7 +3180,7 @@ function testMithril(mock) { var result = root.childNodes[0].nodeValue === "b" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3711,7 +3208,7 @@ function testMithril(mock) { var result = mock.location.search === "?/b?foo=2" - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result @@ -3743,7 +3240,7 @@ function testMithril(mock) { var result = mock.history.$$length === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result @@ -3775,7 +3272,7 @@ function testMithril(mock) { var result = mock.history.$$length === 0 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3810,7 +3307,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3846,7 +3343,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3882,7 +3379,7 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3917,7 +3414,7 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3953,7 +3450,7 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -3989,7 +3486,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4030,7 +3527,7 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4071,7 +3568,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4110,7 +3607,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4151,7 +3648,7 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4192,7 +3689,7 @@ function testMithril(mock) { var result = initCount === 2 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4231,12 +3728,12 @@ function testMithril(mock) { var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) test(function() { - // retain flag should work inside component + //retain flag should work inside component mock.requestAnimationFrame.$resolve() mock.location.search = "?" @@ -4272,7 +3769,7 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() var result = initCount === 1 - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result }) @@ -4306,34 +3803,25 @@ function testMithril(mock) { m.route("/b") mock.requestAnimationFrame.$resolve() - var result = !root.childNodes[0].childNodes[0].modified + var result = !root.childNodes[0].childNodes[0].modified; - m.mount(root, null) // teardown + m.mount(root, null) //teardown return result - }) - // end m.route + }); + //end m.route - // m.route.parseQueryString + //m.route.parseQueryString test(function() { - var args = m.route.parseQueryString( - "foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto") - return args["hello[]"] instanceof Array && - args["hello[]"].indexOf("world") > -1 && - args["hello[]"].indexOf("mars") > -1 && - args["hello[]"].indexOf("pluto") > -1 + var args = m.route.parseQueryString("foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto") + return args["hello[]"] instanceof Array && args["hello[]"].indexOf("world") > -1 && args["hello[]"].indexOf("mars") > -1 && args["hello[]"].indexOf("pluto") > -1 }) test(function() { - var args = m.route.parseQueryString( - "foo=bar&hello=world&hello=mars&bam=&yup") - return args.foo === "bar" && - args.hello[0] === "world" && - args.hello[1] === "mars" && - args.bam === "" && - args.yup == null + var args = m.route.parseQueryString("foo=bar&hello=world&hello=mars&bam=&yup") + return args.foo === "bar" && args.hello[0] === "world" && args.hello[1] === "mars" && args.bam === "" && args.yup == null }) - // m.route.buildQueryString + //m.route.buildQueryString test(function() { var string = m.route.buildQueryString({ foo: "bar", @@ -4345,11 +3833,10 @@ function testMithril(mock) { yup: null, removed: undefined }) - return string === - "foo=bar&hello=world&hello=mars&world%5Btest%5D=3&bam=&yup" + return string === "foo=bar&hello=world&hello=mars&world%5Btest%5D=3&bam=&yup" }) - // m.prop + //m.prop test(function() { var prop = m.prop("test") return prop() === "test" @@ -4385,89 +3872,55 @@ function testMithril(mock) { }) test(function() { var prop = m.prop(null) - return prop() == null + return prop() === null }) - // m.request + //m.request test(function() { var prop = m.request({method: "GET", url: "test"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().method === "GET" && prop().url === "test" }) test(function() { - var prop = m.request({method: "GET", url: "test"}) - .then(function() {return "foo"}) + var prop = m.request({method: "GET", url: "test"}).then(function() {return "foo"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop() === "foo" }) test(function() { - var prop = m.request({ - method: "POST", - url: "http://domain.com:80", - data: {} - }).then(function(value) {return value}) + var prop = m.request({method: "POST", url: "http://domain.com:80", data: {}}).then(function(value) {return value}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().url === "http://domain.com:80" }) test(function() { - var prop = m.request({ - method: "POST", - url: "http://domain.com:80/:test1", - data: {test1: "foo"} - }).then(function(value) {return value}) + var prop = m.request({method: "POST", url: "http://domain.com:80/:test1", data: {test1: "foo"}}).then(function(value) {return value}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().url === "http://domain.com:80/foo" }) test(function() { var error = m.prop("no error") - var prop = m.request({ - method: "GET", - url: "test", - deserialize: function() {throw new Error("error occurred")} - }).then(null, error) + var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new Error("error occurred")}}).then(null, error) mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return prop().message === "error occurred" && - error().message === "error occurred" + return prop().message === "error occurred" && error().message === "error occurred" }) test(function() { var error = m.prop("no error") - var prop = m.request({ - method: "GET", - url: "test", - deserialize: function() {throw new Error("error occurred")} - }).catch(error) + var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new Error("error occurred")}})["catch"](error) mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return prop().message === "error occurred" && - error().message === "error occurred" + return prop().message === "error occurred" && error().message === "error occurred" + }) + test(function() { + var error = m.prop("no error"), exception + var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new TypeError("error occurred")}}).then(null, error) + try {mock.XMLHttpRequest.$instances.pop().onreadystatechange()} + catch (e) {exception = e} + return prop() === undefined && error() === "no error" && exception.message === "error occurred" }) test(function() { var error = m.prop("no error") - var exception - var prop = m.request({ - method: "GET", - url: "test", - deserialize: function() {throw new TypeError("error occurred")} - }).then(null, error) - try { - mock.XMLHttpRequest.$instances.pop().onreadystatechange() - } catch (e) { - exception = e - } - return prop() === undefined && - error() === "no error" && - exception.message === "error occurred" - }) - test(function() { - var error = m.prop("no error") - m.request({ - method: "POST", - url: "test", - data: {foo: 1} - }).then(null, error) + m.request({method: "POST", url: "test", data: {foo: 1}}).then(null, error) var xhr = mock.XMLHttpRequest.$instances.pop() xhr.onreadystatechange() - return xhr.$headers["Content-Type"] === - "application/json; charset=utf-8" + return xhr.$headers["Content-Type"] === "application/json; charset=utf-8" }) test(function() { var error = m.prop("no error") @@ -4477,23 +3930,21 @@ function testMithril(mock) { return xhr.$headers["Content-Type"] === undefined }) test(function() { - var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) - .then(function(data) { return data }) - var initialValue = prop() + var prop = m.request({method: "POST", url: "test", initialValue: "foo"}).then(function(data) { return data; }) + var initialValue = prop(); mock.XMLHttpRequest.$instances.pop().onreadystatechange() return initialValue === "foo" }) test(function() { var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) - var initialValue = prop() + var initialValue = prop(); mock.XMLHttpRequest.$instances.pop().onreadystatechange() return initialValue === "foo" }) test(function() { - var prop = m.request({method: "POST", url: "test", initialValue: "foo"}) - .then(function() {return "bar"}) + var prop = m.request({method: "POST", url: "test", initialValue: "foo"}).then(function() {return "bar"}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop() === "bar" }) @@ -4521,11 +3972,7 @@ function testMithril(mock) { var prop3 = prop1.then(function(v) {value = v}) var val3 = prop3() mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return val1 === 123 && - val2 === 123 && - val3 === 123 && - value.method === "GET" && - value.url === "test" + return val1 === 123 && val2 === 123 && val3 === 123 && value.method === "GET" && value.url === "test" }) // m.request over jsonp @@ -4537,20 +3984,16 @@ function testMithril(mock) { var error = m.prop("no error") var data - m.request({url: "/test", dataType: "jsonp"}) - .then(function(received) {data = received}, error) + m.request({url: "/test", dataType: "jsonp"}).then(function(received) {data = received}, error) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call( - mock.document.getElementsByTagName("script")) - .filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() mock[callbackKey]({foo: "bar"}) mock.document.removeChild(body) - return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && - data.foo === "bar" + return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && data.foo === "bar" }) test(function(){ // script tags cannot be appended directly on the document @@ -4560,24 +4003,16 @@ function testMithril(mock) { var error = m.prop("no error") var data - m.request({ - url: "/test", - dataType: "jsonp", - callbackKey: "jsonpCallback" - }).then(function(received) {data = received}, error) + m.request({url: "/test", dataType: "jsonp", callbackKey: "jsonpCallback"}).then(function(received) {data = received}, error) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call( - mock.document.getElementsByTagName("script")) - .filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); mock[callbackKey]({foo: "bar1"}) mock.document.removeChild(body) - return scriptTag.src.indexOf( - "/test?jsonpCallback=mithril_callback") > -1 && - data.foo === "bar1" + return scriptTag.src.indexOf("/test?jsonpCallback=mithril_callback") > -1 && data.foo === "bar1" }) test(function(){ var body = mock.document.createElement("body") @@ -4588,11 +4023,9 @@ function testMithril(mock) { var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - ;[].slice.call( - mock.document.getElementsByTagName("script")) - .filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + ;[].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); mock[callbackKey]({foo: "bar1"}) var out = {foo: "bar1"} mock.document.removeChild(body) @@ -4603,47 +4036,34 @@ function testMithril(mock) { mock.document.body = body mock.document.appendChild(body) - m.request({ - url: "/test", - dataType: "jsonp", - data: {foo: "bar"} - }) + m.request({url: "/test", dataType: "jsonp", data: {foo: "bar"}}) var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call( - mock.document.getElementsByTagName("script")) - .filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); mock[callbackKey]({foo: "bar"}) return scriptTag.src.indexOf("foo=bar") > -1 }) test(function(){ - var body = mock.document.createElement("body") - mock.document.body = body - mock.document.appendChild(body) + var body = mock.document.createElement("body"); + mock.document.body = body; + mock.document.appendChild(body); - m.request({ - url: "/test", - dataType: "jsonp", - method: "GET", - data: {foo: "bar"} - }) + m.request({url: "/test", dataType: "jsonp", method: "GET", data: {foo: "bar"}}); var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 }).pop() - var scriptTag = [].slice.call( - mock.document.getElementsByTagName("script")) - .filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); mock[callbackKey]({foo: "bar"}) - mock.document.removeChild(body) - return scriptTag.src.match(/foo=bar/g).length === 1 + mock.document.removeChild(body); + return scriptTag.src.match(/foo=bar/g).length === 1; }) - // m.deferred + //m.deferred test(function() { var value var deferred = m.deferred() @@ -4654,8 +4074,7 @@ function testMithril(mock) { test(function() { var value var deferred = m.deferred() - deferred.promise.then(function() {return "foo"}) - .then(function(data) {value = data}) + deferred.promise.then(function() {return "foo"}).then(function(data) {value = data}) deferred.resolve("test") return value === "foo" }) @@ -4669,77 +4088,48 @@ function testMithril(mock) { test(function() { var value var deferred = m.deferred() - deferred.promise.catch(function(data) {value = data}) + deferred.promise["catch"](function(data) {value = data}) deferred.reject("test") return value === "test" }) test(function() { var value var deferred = m.deferred() - deferred.promise.then(null, function() {return "foo"}) - .then(function(data) {value = data}) + deferred.promise.then(null, function() {return "foo"}).then(function(data) {value = data}) deferred.reject("test") return value === "foo" }) test(function() { var value var deferred = m.deferred() - deferred.promise.catch(function() {return "foo"}) - .then(function(data) {value = data}) + deferred.promise["catch"](function() {return "foo"}).then(function(data) {value = data}) deferred.reject("test") return value === "foo" }) test(function() { var value1, value2 var deferred = m.deferred() - deferred.promise.then(function() {throw new Error()}) - .then(function() {value1 = 1}, function(data) {value2 = data}) + deferred.promise.then(function() {throw new Error()}).then(function() {value1 = 1}, function(data) {value2 = data}) deferred.resolve("test") return value1 === undefined && value2 instanceof Error }) test(function() { - // Let unchecked exceptions bubble up in order to allow meaningful error - // messages in common cases like null reference exceptions due to typos - // An unchecked exception is defined as an object that is a subclass of - // Error (but not a direct instance of Error itself) - basically - // anything that can be thrown without an explicit `throw` keyword and - // that we'd never want to programmatically manipulate. In other words, - // an unchecked error is one where we only care about its line number - // and where the only reasonable way to deal with it is to change the - // buggy source code that caused the error to be thrown in the first - // place. By contrast, a checked exception is defined as anything that - // is explicitly thrown via the `throw` keyword and that can be - // programmatically handled, for example to display a validation error - // message on the UI. If an exception is a subclass of Error for - // whatever reason, but it is meant to be handled as a checked exception - // (i.e. follow the rejection rules for A+), it can be rethrown as an - // instance of Error - // - // This test tests two implementation details that differ from the - // Promises/A+ spec: - // 1) A+ requires the `then` callback to be called in a different event - // loop from the resolve call, i.e. it must be asynchronous (this - // requires a setImmediate polyfill, which cannot be implemented in a - // reasonable way for Mithril's purpose - the possible polyfills are - // either too big or too slow) - // 2) A+ swallows exceptions in a unrethrowable way, i.e. it's not - // possible to see default error messages on the console for runtime - // errors thrown from within a promise chain + //Let unchecked exceptions bubble up in order to allow meaningful error messages in common cases like null reference exceptions due to typos + //An unchecked exception is defined as an object that is a subclass of Error (but not a direct instance of Error itself) - basically anything that can be thrown without an explicit `throw` keyword and that we'd never want to programmatically manipulate. In other words, an unchecked error is one where we only care about its line number and where the only reasonable way to deal with it is to change the buggy source code that caused the error to be thrown in the first place. + //By contrast, a checked exception is defined as anything that is explicitly thrown via the `throw` keyword and that can be programmatically handled, for example to display a validation error message on the UI. If an exception is a subclass of Error for whatever reason, but it is meant to be handled as a checked exception (i.e. follow the rejection rules for A+), it can be rethrown as an instance of Error + //This test tests two implementation details that differ from the Promises/A+ spec: + //1) A+ requires the `then` callback to be called in a different event loop from the resolve call, i.e. it must be asynchronous (this requires a setImmediate polyfill, which cannot be implemented in a reasonable way for Mithril's purpose - the possible polyfills are either too big or too slow) + //2) A+ swallows exceptions in a unrethrowable way, i.e. it's not possible to see default error messages on the console for runtime errors thrown from within a promise chain var value1, value2, value3 var deferred = m.deferred() try { deferred.promise - /* eslint-disable no-undef, no-unused-expressions */ - .then(function() {foo.bar.baz}) // throws ReferenceError - /* eslint-enable no-undef, no-unused-expressions */ + .then(function() {foo.bar.baz}) //throws ReferenceError .then(function() {value1 = 1}, function(data) {value2 = data}) deferred.resolve("test") - } catch (e) { - value3 = e } - return value1 === undefined && - value2 === undefined && - (value3 instanceof ReferenceError || value3 instanceof TypeError) + catch (e) {value3 = e} + return value1 === undefined && value2 === undefined && (value3 instanceof ReferenceError || value3 instanceof TypeError) }) test(function() { var deferred1 = m.deferred() @@ -4756,9 +4146,8 @@ function testMithril(mock) { return value1 === 1 && value2 === 2 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value deferred.resolve(1) deferred.promise.then(function(data) { value = data @@ -4766,9 +4155,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value deferred.reject(1) deferred.promise.then(null, function(data) { value = data @@ -4776,9 +4164,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value deferred.resolve(1) deferred.resolve(2) deferred.promise.then(function(data) { @@ -4787,9 +4174,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value deferred.promise.then(function(data) { value = data }) @@ -4798,9 +4184,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value1, value2 + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value1, value2 deferred.promise.then(function(data) { value1 = data }, function(data) { @@ -4811,9 +4196,8 @@ function testMithril(mock) { return value1 === 1 && value2 === undefined }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value1, value2 + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value1, value2 deferred.promise.then(function(data) { value1 = data }, function(data) { @@ -4824,9 +4208,8 @@ function testMithril(mock) { return value1 === undefined && value2 === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/80 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/80 + var deferred = m.deferred(), value deferred.promise.then(null, function(data) { value = data }) @@ -4835,9 +4218,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/85 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/85 + var deferred = m.deferred(), value deferred.resolve() deferred.promise.then(function() { value = 1 @@ -4845,9 +4227,8 @@ function testMithril(mock) { return value === 1 }) test(function() { - // https://github.com/lhorie/mithril.js/issues/85 - var deferred = m.deferred() - var value + //https://github.com/lhorie/mithril.js/issues/85 + var deferred = m.deferred(), value deferred.reject() deferred.promise.then(null, function() { value = 1 @@ -4871,13 +4252,12 @@ function testMithril(mock) { return deferred.promise() === undefined }) - // m.sync + //m.sync test(function() { var value var deferred1 = m.deferred() var deferred2 = m.deferred() - m.sync([deferred1.promise, deferred2.promise]) - .then(function(data) {value = data}) + m.sync([deferred1.promise, deferred2.promise]).then(function(data) {value = data}) deferred1.resolve("test") deferred2.resolve("foo") return value[0] === "test" && value[1] === "foo" @@ -4886,8 +4266,7 @@ function testMithril(mock) { var value var deferred1 = m.deferred() var deferred2 = m.deferred() - m.sync([deferred1.promise, deferred2.promise]) - .then(function(data) {value = data}) + m.sync([deferred1.promise, deferred2.promise]).then(function(data) {value = data}) deferred2.resolve("foo") deferred1.resolve("test") return value[0] === "test" && value[1] === "foo" @@ -4895,7 +4274,7 @@ function testMithril(mock) { test(function() { var value var deferred = m.deferred() - m.sync([deferred.promise]).catch(function(data) {value = data}) + m.sync([deferred.promise])["catch"](function(data) {value = data}) deferred.reject("fail") return value[0] === "fail" }) @@ -4910,7 +4289,7 @@ function testMithril(mock) { return success }) - // m.startComputation/m.endComputation + //m.startComputation/m.endComputation test(function() { mock.requestAnimationFrame.$resolve() @@ -4933,40 +4312,32 @@ function testMithril(mock) { test(function() { var root = mock.document.createElement("div") - var success = false - m.render(root, m("div", { - config: function(elem, isInitialized, ctx) {ctx.data = 1} - })) - m.render(root, m("div", { - config: function(elem, isInitialized, ctx) { - success = ctx.data === 1 - } - })) - return success + var success = false; + m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data=1}})); + m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data===1}})); + return success; }) // more complex config context test(function() { var root = mock.document.createElement("div") - var idx = 0 - var success = true - var statefulConfig = function(elem, isInitialized, ctx) { - ctx.data = idx++ - } - var node = m("div", {config: statefulConfig}) - m.render(root, [node, node]) + var idx = 0; + var success = true; + var statefulConfig = function(elem, isInitialized, ctx) {ctx.data=idx++} + var node = m("div", {config: statefulConfig}); + m.render(root, [node, node]); - idx = 0 + idx = 0; var checkConfig = function(elem, isInitialized, ctx) { success = success && (ctx.data === idx++) } - node = m("div", {config: checkConfig}) - m.render(root, [node, node]) - return success + node = m("div", {config: checkConfig}); + m.render(root, [node, node]); + return success; }) - // console.log presence + //console.log presence test(function() { return m.deps.factory.toString().indexOf("console") < 0 }) @@ -4975,9 +4346,7 @@ function testMithril(mock) { }) } -// mock -testMithril(mock.window) -test.print(function(value) { - "use strict" - console.log(value) -}) +//mock +testMithril(mock.window); + +test.print(function(value) {console.log(value)}) diff --git a/tests/mock.js b/tests/mock.js index f4080b3e..fb97f6d5 100644 --- a/tests/mock.js +++ b/tests/mock.js @@ -1,4 +1,3 @@ -/* eslint-disable no-extend-native, strict */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(item) { for (var i = 0; i < this.length; i++) { @@ -32,11 +31,9 @@ if (!Object.keys) { return keys } } -/* eslint-enable no-extend-native, strict */ var mock = {} mock.window = (function() { - "use strict" var window = {} window.document = {} window.document.childNodes = [] @@ -60,10 +57,9 @@ mock.window = (function() { insertAdjacentHTML: function(position, html) { // todo: accept markup if (position === "beforebegin") { - this.parentNode.insertBefore( - window.document.createTextNode(html), - this) - } else if (position === "beforeend") { + this.parentNode.insertBefore(window.document.createTextNode(html), this) + } + else if (position === "beforeend") { this.appendChild(window.document.createTextNode(html)) } }, @@ -74,7 +70,7 @@ mock.window = (function() { this.namespaceURI = namespace this[name] = value.toString() }, - getAttribute: function(name) { + getAttribute: function(name, value) { return this[name] }, addEventListener: function () {}, @@ -111,22 +107,22 @@ mock.window = (function() { // getElementsByTagName is only used by JSONP tests, it's not required by // Mithril window.document.getElementsByTagName = function(name){ - name = name.toLowerCase() - var out = [] + name = name.toLowerCase(); + var out = []; var traverse = function(node){ if(node.childNodes && node.childNodes.length > 0){ node.childNodes.map(function(curr){ if (curr.nodeName.toLowerCase() === name) { - out.push(curr) + out.push(curr); } - traverse(curr) - }) + traverse(curr); + }); } } - traverse(window.document) - return out + traverse(window.document); + return out; } window.scrollTo = function() {} window.cancelAnimationFrame = function() {} @@ -167,12 +163,10 @@ mock.window = (function() { window.history.$$length = 0 window.history.pushState = function(data, title, url) { window.history.$$length++ - window.location.pathname = window.location.search = - window.location.hash = url + window.location.pathname = window.location.search = window.location.hash = url } window.history.replaceState = function(data, title, url) { - window.location.pathname = window.location.search = - window.location.hash = url + window.location.pathname = window.location.search = window.location.hash = url } return window }()) diff --git a/tests/test.js b/tests/test.js index 984e15ee..844cf8aa 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,19 +1,15 @@ -/* eslint-disable no-console */ if (!this.console) { - var log = function(value) { - "use strict" - document.write("
" + value + "
") - } + var log = function(value) {document.write("
" + value + "
")} this.console = {log: log, error: log} } function test(condition) { - "use strict" test.total++ try { if (!condition()) throw new Error("failed") - } catch (e) { + } + catch (e) { console.error(e) test.failures.push(condition) } @@ -21,7 +17,6 @@ function test(condition) { test.total = 0 test.failures = [] test.print = function(print) { - "use strict" for (var i = 0; i < test.failures.length; i++) { print(test.failures[i].toString()) }