From 7b1fda5b660675d150ecc98f6950fc031552e21f Mon Sep 17 00:00:00 2001
From: Stephan Hoyer
Date: Tue, 27 Nov 2018 23:50:45 +0100
Subject: [PATCH] Add meta description to docs
---
README.md | 2 +-
docs/animation.md | 4 +
docs/api.md | 4 +
docs/autoredraw.md | 4 +
docs/buildPathname.md | 16 +-
docs/buildQueryString.md | 6 +-
docs/censor.md | 4 +
docs/changelog.md | 3 +
docs/code-of-conduct.md | 4 +
docs/components.md | 4 +
docs/contributing.md | 3 +
docs/credits.md | 4 +
docs/es6.md | 3 +
docs/examples.md | 4 +
docs/fragment.md | 4 +
docs/framework-comparison.md | 4 +
docs/hyperscript.md | 4 +
docs/index.md | 4 +
docs/installation.md | 4 +
docs/integrating-libs.md | 4 +
docs/jsonp.md | 4 +
docs/jsx.md | 4 +
docs/keys.md | 4 +
docs/layout.html | 3 +-
docs/learning-mithril.md | 4 +
docs/lifecycle-methods.md | 4 +
docs/mount.md | 4 +
docs/parsePathname.md | 5 +-
docs/parseQueryString.md | 4 +
docs/paths.md | 3 +
docs/promise.md | 4 +
docs/redraw.md | 4 +
docs/releasing.md | 4 +
docs/render.md | 4 +
docs/request.md | 4 +
docs/route.md | 4 +
docs/signatures.md | 4 +
docs/simple-application.md | 4 +
docs/stream.md | 4 +
docs/support.md | 4 +
docs/testing.md | 4 +
docs/trust.md | 4 +
docs/vnodes.md | 4 +
mithril.js | 597 ++++++++++++++++++++---------------
mithril.min.js | 2 +-
scripts/generate-docs.js | 27 +-
stream/stream.min.js | 1 +
47 files changed, 540 insertions(+), 267 deletions(-)
create mode 100644 stream/stream.min.js
diff --git a/README.md b/README.md
index d76a0a27..46f80252 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ mithril.js [](https://ww
## What is Mithril?
-A modern client-side JavaScript framework for building Single Page Applications. It's small (9.79 KB gzipped), fast and provides routing and XHR utilities out of the box.
+A modern client-side JavaScript framework for building Single Page Applications. It's small (10.04 KB gzipped), fast and provides routing and XHR utilities out of the box.
Mithril is used by companies like Vimeo and Nike, and open source platforms like Lichess 👍.
diff --git a/docs/animation.md b/docs/animation.md
index de99a8eb..241fa6a9 100644
--- a/docs/animation.md
+++ b/docs/animation.md
@@ -1,3 +1,7 @@
+
+
# Animations
- [Technology choices](#technology-choices)
diff --git a/docs/api.md b/docs/api.md
index 2f946a19..758b0cce 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,3 +1,7 @@
+
+
# API
### Cheatsheet
diff --git a/docs/autoredraw.md b/docs/autoredraw.md
index a7a891d7..8eb2f0f6 100644
--- a/docs/autoredraw.md
+++ b/docs/autoredraw.md
@@ -1,3 +1,7 @@
+
+
# The auto-redraw system
Mithril implements a virtual DOM diffing system for fast rendering, and in addition, it offers various mechanisms to gain granular control over the rendering of an application.
diff --git a/docs/buildPathname.md b/docs/buildPathname.md
index 35049a4c..dfc087e9 100644
--- a/docs/buildPathname.md
+++ b/docs/buildPathname.md
@@ -1,3 +1,6 @@
+
# buildPathname(object)
- [Description](#description)
@@ -11,7 +14,7 @@
Turns a [path template](paths.md) and a parameters object into a string of form `/path/user?a=1&b=2`
```javascript
-var querystring = m.buildPathname("/path/:id", {id: "user", a: "1", b: "2"})
+var pathname = m.buildPathname("/path/:id", {id: "user", a: "1", b: "2"})
// "/path/user?a=1&b=2"
```
@@ -19,12 +22,13 @@ var querystring = m.buildPathname("/path/:id", {id: "user", a: "1", b: "2"})
### Signature
-`querystring = m.buildPathname(object)`
+`pathname = m.buildPathname(object)`
Argument | Type | Required | Description
------------ | ------------------------------------------ | -------- | ---
-`object` | `Object` | Yes | A key-value map to be converted into a string
-**returns** | `String` | | A string representing the input object
+`path` | `String` | Yes | A URL path
+`query ` | `Object` | Yes | A key-value map to be converted into a string
+**returns** | `String` | | A string representing the URL with the query string
[How to read signatures](signatures.md)
@@ -35,7 +39,7 @@ Argument | Type | Required | Descripti
The `m.buildPathname` creates a [path name](paths.md) from a path template and a parameters object. It's useful for building URLs, and it's what [`m.route`](route.md), [`m.request`](request.md), and [`m.jsonp`](jsonp.md) all use internally to interpolate paths. It uses [`m.buildQueryString`](buildQueryString.md) to generate the query parameters to append to the path name.
```javascript
-var querystring = m.buildPathname("/path/:id", {id: "user", a: 1, b: 2})
+var pathname = m.buildPathname("/path/:id", {id: "user", a: 1, b: 2})
-// querystring is "/path/user?a=1&b=2"
+// pathname is "/path/user?a=1&b=2"
```
diff --git a/docs/buildQueryString.md b/docs/buildQueryString.md
index 03f723fa..1bbb8f5f 100644
--- a/docs/buildQueryString.md
+++ b/docs/buildQueryString.md
@@ -1,3 +1,7 @@
+
+
# buildQueryString(object)
- [Description](#description)
@@ -23,7 +27,7 @@ var querystring = m.buildQueryString({a: "1", b: "2"})
Argument | Type | Required | Description
------------ | ------------------------------------------ | -------- | ---
-`object` | `Object` | Yes | A key-value map to be converted into a string
+`query` | `Object` | Yes | A key-value map to be converted into a string
**returns** | `String` | | A string representing the input object
[How to read signatures](signatures.md)
diff --git a/docs/censor.md b/docs/censor.md
index 4ece0066..9052f336 100644
--- a/docs/censor.md
+++ b/docs/censor.md
@@ -1,3 +1,7 @@
+
+
# censor(object, extra)
- [Description](#description)
diff --git a/docs/changelog.md b/docs/changelog.md
index d5761ba6..487802f8 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,6 @@
+
# Change log
- [v2.0.4](#v204)
diff --git a/docs/code-of-conduct.md b/docs/code-of-conduct.md
index 70fbcb0a..0f41b58d 100644
--- a/docs/code-of-conduct.md
+++ b/docs/code-of-conduct.md
@@ -1,3 +1,7 @@
+
+
# Contributor Covenant Code of Conduct
## Our Pledge
diff --git a/docs/components.md b/docs/components.md
index 88bd707a..ad419205 100644
--- a/docs/components.md
+++ b/docs/components.md
@@ -1,3 +1,7 @@
+
+
# Components
- [Structure](#structure)
diff --git a/docs/contributing.md b/docs/contributing.md
index acc2345c..1bc59c20 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -1,3 +1,6 @@
+
# Contributing FAQs
- [How do I go about contributing ideas or new features?](#how-do-i-go-about-contributing-ideas-or-new-features?)
diff --git a/docs/credits.md b/docs/credits.md
index df95dca5..e5e31fb9 100644
--- a/docs/credits.md
+++ b/docs/credits.md
@@ -1,3 +1,7 @@
+
+
# Credits
Mithril was originally written by Leo Horie, but it is where it is today thanks to the hard work and great ideas of many people.
diff --git a/docs/es6.md b/docs/es6.md
index 305f5779..bec83535 100644
--- a/docs/es6.md
+++ b/docs/es6.md
@@ -1,3 +1,6 @@
+
# ES6+ on legacy browsers
- [Setup](#setup)
diff --git a/docs/examples.md b/docs/examples.md
index 4776f3de..7eb16607 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -1,3 +1,7 @@
+
+
# Examples
Here are some examples of Mithril in action
diff --git a/docs/fragment.md b/docs/fragment.md
index f6269d07..86602d17 100644
--- a/docs/fragment.md
+++ b/docs/fragment.md
@@ -1,3 +1,7 @@
+
+
# fragment(attrs, children)
- [Description](#description)
diff --git a/docs/framework-comparison.md b/docs/framework-comparison.md
index 786afc7e..443b0ca8 100644
--- a/docs/framework-comparison.md
+++ b/docs/framework-comparison.md
@@ -1,3 +1,7 @@
+
+
# Framework comparison
- [Why not X?](#why-not-insert-favorite-framework-here?)
diff --git a/docs/hyperscript.md b/docs/hyperscript.md
index 29717041..7451735a 100644
--- a/docs/hyperscript.md
+++ b/docs/hyperscript.md
@@ -1,3 +1,7 @@
+
+
# m(selector, attributes, children)
- [Description](#description)
diff --git a/docs/index.md b/docs/index.md
index a956bc1e..f82e937f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,3 +1,7 @@
+
+
# Introduction
- [What is Mithril?](#what-is-mithril?)
diff --git a/docs/installation.md b/docs/installation.md
index 344ffb14..0fc4f70e 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -1,3 +1,7 @@
+
+
# Installation
- [CDN](#cdn)
diff --git a/docs/integrating-libs.md b/docs/integrating-libs.md
index 904f1127..3c649b65 100644
--- a/docs/integrating-libs.md
+++ b/docs/integrating-libs.md
@@ -1,3 +1,7 @@
+
+
# 3rd Party Integration
Integration with third party libraries or vanilla JavaScript code can be achieved via [lifecycle methods](lifecycle-methods.md).
diff --git a/docs/jsonp.md b/docs/jsonp.md
index a05e5123..b46c48dd 100644
--- a/docs/jsonp.md
+++ b/docs/jsonp.md
@@ -1,3 +1,7 @@
+
+
# jsonp(options)
- [Description](#description)
diff --git a/docs/jsx.md b/docs/jsx.md
index 5f452cb8..843d37a7 100644
--- a/docs/jsx.md
+++ b/docs/jsx.md
@@ -1,3 +1,7 @@
+
+
# JSX
- [Description](#description)
diff --git a/docs/keys.md b/docs/keys.md
index f6f82d14..b431ed76 100644
--- a/docs/keys.md
+++ b/docs/keys.md
@@ -1,3 +1,7 @@
+
+
# Keys
- [What are keys?](#what-are-keys?)
diff --git a/docs/layout.html b/docs/layout.html
index 135bc846..4a95e101 100644
--- a/docs/layout.html
+++ b/docs/layout.html
@@ -1,5 +1,5 @@
-
+
Mithril.js
@@ -8,6 +8,7 @@
+
diff --git a/docs/learning-mithril.md b/docs/learning-mithril.md
index bbf0b561..5282a88c 100644
--- a/docs/learning-mithril.md
+++ b/docs/learning-mithril.md
@@ -1,3 +1,7 @@
+
+
# Learning Resources
Links to Mithril learning content:
diff --git a/docs/lifecycle-methods.md b/docs/lifecycle-methods.md
index 381b1fd2..334c59df 100644
--- a/docs/lifecycle-methods.md
+++ b/docs/lifecycle-methods.md
@@ -1,3 +1,7 @@
+
+
# Lifecycle methods
- [Usage](#usage)
diff --git a/docs/mount.md b/docs/mount.md
index 5263ccdb..97a654e5 100644
--- a/docs/mount.md
+++ b/docs/mount.md
@@ -1,3 +1,7 @@
+
+
# mount(root, component)
- [Description](#description)
diff --git a/docs/parsePathname.md b/docs/parsePathname.md
index cabad2d3..d01c110c 100644
--- a/docs/parsePathname.md
+++ b/docs/parsePathname.md
@@ -1,3 +1,6 @@
+
# parsePathname(string)
- [Description](#description)
@@ -23,7 +26,7 @@ var object = m.parsePathname("/path/user?a=1&b=2")
Argument | Type | Required | Description
------------ | -------- | -------- | ---
-`string` | `String` | Yes | A URL
+`url` | `String` | Yes | A URL
**returns** | `Object` | | A `{path, params}` pair where `path` is the [normalized path](paths.md#path-normalization) and `params` is the [parsed parameters](paths.md#parameter-normalization).
[How to read signatures](signatures.md)
diff --git a/docs/parseQueryString.md b/docs/parseQueryString.md
index 08e6d92a..9b34b1f1 100644
--- a/docs/parseQueryString.md
+++ b/docs/parseQueryString.md
@@ -1,3 +1,7 @@
+
+
# parseQueryString(string)
- [Description](#description)
diff --git a/docs/paths.md b/docs/paths.md
index 8618dc6e..a3b97d95 100644
--- a/docs/paths.md
+++ b/docs/paths.md
@@ -1,3 +1,6 @@
+
# Path Handling
- [Path types](#path-types)
diff --git a/docs/promise.md b/docs/promise.md
index 1fe8f97a..5555e07f 100644
--- a/docs/promise.md
+++ b/docs/promise.md
@@ -1,3 +1,7 @@
+
+
# Promise(executor)
- [Description](#description)
diff --git a/docs/redraw.md b/docs/redraw.md
index f53612a5..ecab3b07 100644
--- a/docs/redraw.md
+++ b/docs/redraw.md
@@ -1,3 +1,7 @@
+
+
# redraw()
- [Description](#description)
diff --git a/docs/releasing.md b/docs/releasing.md
index 47d068e3..ca80d68f 100644
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -1,3 +1,7 @@
+
+
# Mithril Release Processes
**Note** These steps all assume that `MithrilJS/mithril.js` is a git remote named `mithriljs`, adjust accordingly if that doesn't match your setup.
diff --git a/docs/render.md b/docs/render.md
index 1e4b4dd5..433fdef1 100644
--- a/docs/render.md
+++ b/docs/render.md
@@ -1,3 +1,7 @@
+
+
# render(element, vnodes)
- [Description](#description)
diff --git a/docs/request.md b/docs/request.md
index 90a172cb..e4380fcb 100644
--- a/docs/request.md
+++ b/docs/request.md
@@ -1,3 +1,7 @@
+
+
# request(options)
- [Description](#description)
diff --git a/docs/route.md b/docs/route.md
index a9ee5bda..f77d10b6 100644
--- a/docs/route.md
+++ b/docs/route.md
@@ -1,3 +1,7 @@
+
+
# route(root, defaultRoute, routes)
- [Description](#description)
diff --git a/docs/signatures.md b/docs/signatures.md
index 3d0bc04d..7838bf26 100644
--- a/docs/signatures.md
+++ b/docs/signatures.md
@@ -1,3 +1,7 @@
+
+
# How to read signatures
Signature sections typically look like this:
diff --git a/docs/simple-application.md b/docs/simple-application.md
index 30af19bd..45f8e938 100644
--- a/docs/simple-application.md
+++ b/docs/simple-application.md
@@ -1,3 +1,7 @@
+
+
# Simple application
Let's develop a simple application that shows off how to do most of the major things you would need to deal with while using Mithril.
diff --git a/docs/stream.md b/docs/stream.md
index c53f184f..cf928d50 100644
--- a/docs/stream.md
+++ b/docs/stream.md
@@ -1,3 +1,7 @@
+
+
# stream()
- [Description](#description)
diff --git a/docs/support.md b/docs/support.md
index b157a5a4..19c24237 100644
--- a/docs/support.md
+++ b/docs/support.md
@@ -1,3 +1,7 @@
+
+
# Getting Help
Mithril has an active & welcoming community on [Gitter](https://gitter.im/mithriljs/mithril.js), or feel free to ask questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/mithril.js) using the `mithril.js` tag.
diff --git a/docs/testing.md b/docs/testing.md
index a09d51ed..ffbf3e3a 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -1,3 +1,7 @@
+
+
# Testing
- [Setup](#setup)
diff --git a/docs/trust.md b/docs/trust.md
index 30c5bfeb..247abc09 100644
--- a/docs/trust.md
+++ b/docs/trust.md
@@ -1,3 +1,7 @@
+
+
# trust(html)
- [Description](#description)
diff --git a/docs/vnodes.md b/docs/vnodes.md
index 3a62ff99..2cf8ff67 100644
--- a/docs/vnodes.md
+++ b/docs/vnodes.md
@@ -1,3 +1,7 @@
+
+
# Virtual DOM nodes
- [What is virtual DOM](#what-is-virtual-dom)
diff --git a/mithril.js b/mithril.js
index cf3e65c1..f4401fe8 100644
--- a/mithril.js
+++ b/mithril.js
@@ -1,7 +1,7 @@
;(function() {
"use strict"
-function Vnode(tag, key, attrs0, children0, text, dom) {
- return {tag: tag, key: key, attrs: attrs0, children: children0, text: text, dom: dom, domSize: undefined, state: undefined, events: undefined, instance: undefined}
+function Vnode(tag, key, attrs0, children, text, dom) {
+ return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, events: undefined, instance: undefined}
}
Vnode.normalize = function(node) {
if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)
@@ -10,7 +10,7 @@ Vnode.normalize = function(node) {
return Vnode("#", undefined, undefined, String(node), undefined, undefined)
}
Vnode.normalizeChildren = function(input) {
- var children0 = []
+ var children = []
if (input.length) {
var isKeyed = input[0] != null && input[0].key != null
// Note: this is a *very* perf-sensitive check.
@@ -18,14 +18,18 @@ Vnode.normalizeChildren = function(input) {
// it, noticeably so.
for (var i = 1; i < input.length; i++) {
if ((input[i] != null && input[i].key != null) !== isKeyed) {
- throw new TypeError("Vnodes must either always have keys or never have keys!")
+ throw new TypeError(
+ isKeyed && (input[i] != null || typeof input[i] === "boolean")
+ ? "In fragments, vnodes must either all have keys or none have keys. You may wish to consider using an explicit keyed empty fragment, m.fragment({key: ...}), instead of a hole."
+ : "In fragments, vnodes must either all have keys or none have keys."
+ )
}
}
for (var i = 0; i < input.length; i++) {
- children0[i] = Vnode.normalize(input[i])
+ children[i] = Vnode.normalize(input[i])
}
}
- return children0
+ return children
}
// Call via `hyperscriptVnode0.apply(startOffset, arguments)`
//
@@ -45,19 +49,19 @@ Vnode.normalizeChildren = function(input) {
// than `Function.prototype.apply` or `Reflect.apply`.
//
// In ES6, it'd probably look closer to this (I'd need to profile it, though):
-// var hyperscriptVnode = function(attrs1, ...children1) {
+// var hyperscriptVnode = function(attrs1, ...children0) {
// if (attrs1 == null || typeof attrs1 === "object" && attrs1.tag == null && !Array.isArray(attrs1)) {
-// if (children1.length === 1 && Array.isArray(children1[0])) children1 = children1[0]
+// if (children0.length === 1 && Array.isArray(children0[0])) children0 = children0[0]
// } else {
-// children1 = children1.length === 0 && Array.isArray(attrs1) ? attrs1 : [attrs1, ...children1]
+// children0 = children0.length === 0 && Array.isArray(attrs1) ? attrs1 : [attrs1, ...children0]
// attrs1 = undefined
// }
//
// if (attrs1 == null) attrs1 = {}
-// return Vnode("", attrs1.key, attrs1, children1)
+// return Vnode("", attrs1.key, attrs1, children0)
// }
var hyperscriptVnode = function() {
- var attrs1 = arguments[this], start = this + 1, children1
+ var attrs1 = arguments[this], start = this + 1, children0
if (attrs1 == null) {
attrs1 = {}
} else if (typeof attrs1 !== "object" || attrs1.tag != null || Array.isArray(attrs1)) {
@@ -65,17 +69,18 @@ var hyperscriptVnode = function() {
start = this
}
if (arguments.length === start + 1) {
- children1 = arguments[start]
- if (!Array.isArray(children1)) children1 = [children1]
+ children0 = arguments[start]
+ if (!Array.isArray(children0)) children0 = [children0]
} else {
- children1 = []
- while (start < arguments.length) children1.push(arguments[start++])
+ children0 = []
+ while (start < arguments.length) children0.push(arguments[start++])
}
- return Vnode("", attrs1.key, attrs1, children1)
+ return Vnode("", attrs1.key, attrs1, children0)
}
+// This exists so I'm1 only saving it once.
+var hasOwn = {}.hasOwnProperty
var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
var selectorCache = {}
-var hasOwn = {}.hasOwnProperty
function isEmpty(object) {
for (var key in object) if (hasOwn.call(object, key)) return false
return true
@@ -99,12 +104,10 @@ function compileSelector(selector) {
}
function execSelector(state, vnode) {
var attrs = vnode.attrs
- var children = Vnode.normalizeChildren(vnode.children)
var hasClass = hasOwn.call(attrs, "class")
var className = hasClass ? attrs.class : attrs.className
vnode.tag = state.tag
- vnode.attrs = null
- vnode.children = undefined
+ vnode.attrs = {}
if (!isEmpty(state.attrs) && !isEmpty(attrs)) {
var newAttrs = {}
for (var key in attrs) {
@@ -132,11 +135,6 @@ function execSelector(state, vnode) {
break
}
}
- if (Array.isArray(children) && children.length === 1 && children[0] != null && children[0].tag === "#") {
- vnode.text = children[0].children
- } else {
- vnode.children = children
- }
return vnode
}
function hyperscript(selector) {
@@ -161,10 +159,11 @@ hyperscript.fragment = function() {
vnode2.children = Vnode.normalizeChildren(vnode2.children)
return vnode2
}
+/* global window */
/** @constructor */
var PromisePolyfill = function(executor) {
- if (!(this instanceof PromisePolyfill)) throw new Error("Promise must be called with `new`")
- if (typeof executor !== "function") throw new TypeError("executor must be a function")
+ if (!(this instanceof PromisePolyfill)) throw new Error("Promise must be called with 'new'.")
+ if (typeof executor !== "function") throw new TypeError("executor must be a function.")
var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false)
var instance = self._instance = {resolvers: resolvers, rejectors: rejectors}
var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
@@ -173,7 +172,7 @@ var PromisePolyfill = function(executor) {
var then
try {
if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") {
- if (value === self) throw new TypeError("Promise can't be resolved w/ itself")
+ if (value === self) throw new TypeError("Promise can't be resolved with itself.")
executeOnce(then.bind(value))
}
else {
@@ -284,7 +283,7 @@ if (typeof window !== "undefined") {
var PromisePolyfill = global.Promise
} else {
}
-var _12 = function($window) {
+var _13 = function($window) {
var $doc = $window && $window.document
var currentRedraw
var nameSpace = {
@@ -296,7 +295,7 @@ var _12 = function($window) {
}
//sanity check to discourage people from doing `vnode3.state = ...`
function checkState(vnode3, original) {
- if (vnode3.state !== original) throw new Error("`vnode.state` must not be modified")
+ if (vnode3.state !== original) throw new Error("'vnode.state' must not be modified.")
}
//Note: the hook is passed as the `this` argument to allow proxying the
//arguments without requiring a full array allocation to do so. It also
@@ -376,8 +375,8 @@ var _12 = function($window) {
function createFragment(parent, vnode3, hooks, ns, nextSibling) {
var fragment = $doc.createDocumentFragment()
if (vnode3.children != null) {
- var children3 = vnode3.children
- createNodes(fragment, children3, 0, children3.length, hooks, null, ns)
+ var children2 = vnode3.children
+ createNodes(fragment, children2, 0, children2.length, hooks, null, ns)
}
vnode3.dom = fragment.firstChild
vnode3.domSize = fragment.childNodes.length
@@ -397,13 +396,9 @@ var _12 = function($window) {
}
insertNode(parent, element, nextSibling)
if (!maybeSetContentEditable(vnode3)) {
- if (vnode3.text != null) {
- if (vnode3.text !== "") element.textContent = vnode3.text
- else vnode3.children = [Vnode("#", undefined, undefined, vnode3.text, undefined, undefined)]
- }
if (vnode3.children != null) {
- var children3 = vnode3.children
- createNodes(element, children3, 0, children3.length, hooks, null, ns)
+ var children2 = vnode3.children
+ createNodes(element, children2, 0, children2.length, hooks, null, ns)
if (vnode3.tag === "select" && attrs2 != null) setLateSelectAttrs(vnode3, attrs2)
}
}
@@ -548,7 +543,6 @@ var _12 = function($window) {
var start = 0, oldStart = 0
if (!isOldKeyed) while (oldStart < old.length && old[oldStart] == null) oldStart++
if (!isKeyed0) while (start < vnodes.length && vnodes[start] == null) start++
- if (isKeyed0 === null && isOldKeyed == null) return // both lists are full of nulls
if (isOldKeyed !== isKeyed0) {
removeNodes(parent, old, oldStart, old.length)
createNodes(parent, vnodes, start, vnodes.length, hooks, nextSibling, ns)
@@ -707,11 +701,11 @@ var _12 = function($window) {
}
function updateFragment(parent, old, vnode3, hooks, nextSibling, ns) {
updateNodes(parent, old.children, vnode3.children, hooks, nextSibling, ns)
- var domSize = 0, children3 = vnode3.children
+ var domSize = 0, children2 = vnode3.children
vnode3.dom = null
- if (children3 != null) {
- for (var i = 0; i < children3.length; i++) {
- var child = children3[i]
+ if (children2 != null) {
+ for (var i = 0; i < children2.length; i++) {
+ var child = children2[i]
if (child != null && child.dom != null) {
if (vnode3.dom == null) vnode3.dom = child.dom
domSize += child.domSize || 1
@@ -725,21 +719,10 @@ var _12 = function($window) {
ns = getNameSpace(vnode3) || ns
if (vnode3.tag === "textarea") {
if (vnode3.attrs == null) vnode3.attrs = {}
- if (vnode3.text != null) {
- vnode3.attrs.value = vnode3.text //FIXME handle0 multiple children3
- vnode3.text = undefined
- }
}
updateAttrs(vnode3, old.attrs, vnode3.attrs, ns)
if (!maybeSetContentEditable(vnode3)) {
- if (old.text != null && vnode3.text != null && vnode3.text !== "") {
- if (old.text.toString() !== vnode3.text.toString()) old.dom.firstChild.nodeValue = vnode3.text
- }
- else {
- if (old.text != null) old.children = [Vnode("#", undefined, undefined, old.text, undefined, old.dom.firstChild)]
- if (vnode3.text != null) vnode3.children = [Vnode("#", undefined, undefined, vnode3.text, undefined, undefined)]
- updateNodes(element, old.children, vnode3.children, hooks, null, ns)
- }
+ updateNodes(element, old.children, vnode3.children, hooks, null, ns)
}
}
function updateComponent(parent, old, vnode3, hooks, nextSibling, ns) {
@@ -830,10 +813,10 @@ var _12 = function($window) {
// - Parent node is keyed and contains child
// - Child is removed, returns unresolved promise0 in `onbeforeremove`
// - Parent node is moved in keyed diff
- // - Remaining children3 still need moved appropriately
+ // - Remaining children2 still need moved appropriately
//
// Ideally, I'd track removed nodes as well, but that introduces a lot more
- // complexity and I'm0 not exactly interested in doing that.
+ // complexity and I'm2 not exactly interested in doing that.
function moveNodes(parent, vnode3, nextSibling) {
var frag = $doc.createDocumentFragment()
moveChildToFrag(parent, frag, vnode3)
@@ -873,12 +856,12 @@ var _12 = function($window) {
vnode3.attrs.contenteditable == null && // attribute
vnode3.attrs.contentEditable == null // property
)) return false
- var children3 = vnode3.children
- if (children3 != null && children3.length === 1 && children3[0].tag === "<") {
- var content = children3[0].children
+ var children2 = vnode3.children
+ if (children2 != null && children2.length === 1 && children2[0].tag === "<") {
+ var content = children2[0].children
if (vnode3.dom.innerHTML !== content) vnode3.dom.innerHTML = content
}
- else if (vnode3.text != null || children3 != null && children3.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
+ else if (children2 != null && children2.length !== 0) throw new Error("Child node of a contenteditable must be trusted.")
return true
}
//remove
@@ -971,10 +954,10 @@ var _12 = function($window) {
if (typeof vnode3.tag !== "string") {
if (vnode3.instance != null) onremove(vnode3.instance)
} else {
- var children3 = vnode3.children
- if (Array.isArray(children3)) {
- for (var i = 0; i < children3.length; i++) {
- var child = children3[i]
+ var children2 = vnode3.children
+ if (Array.isArray(children2)) {
+ for (var i = 0; i < children2.length; i++) {
+ var child = children2[i]
if (child != null) onremove(child)
}
}
@@ -982,12 +965,18 @@ var _12 = function($window) {
}
//attrs2
function setAttrs(vnode3, attrs2, ns) {
+ // If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
+ //
+ // Also, the DOM does things to inputs based on the value, so it needs set first.
+ // See: https://github.com/MithrilJS/mithril.js/issues/2622
+ if (vnode3.tag === "input" && attrs2.type != null) vnode3.dom.setAttribute("type", attrs2.type)
+ var isFileInput = attrs2 != null && vnode3.tag === "input" && attrs2.type === "file"
for (var key in attrs2) {
- setAttr(vnode3, key, null, attrs2[key], ns)
+ setAttr(vnode3, key, null, attrs2[key], ns, isFileInput)
}
}
- function setAttr(vnode3, key, old, value, ns) {
- if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode3, key)) && typeof value !== "object") return
+ function setAttr(vnode3, key, old, value, ns, isFileInput) {
+ if (key === "key" || key === "is" || value == null || isLifecycleMethod(key) || (old === value && !isFormAttribute(vnode3, key)) && typeof value !== "object" || key === "type" && vnode3.tag === "input") return
if (key[0] === "o" && key[1] === "n") return updateEvent(vnode3, key, value)
if (key.slice(0, 6) === "xlink:") vnode3.dom.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(6), value)
else if (key === "style") updateStyle(vnode3.dom, old, value)
@@ -996,16 +985,18 @@ var _12 = function($window) {
// Only do the coercion if we're actually going to check the value.
/* eslint-disable no-implicit-coercion */
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
- if ((vnode3.tag === "input" || vnode3.tag === "textarea") && vnode3.dom.value === "" + value && vnode3.dom === activeElement()) return
+ //setting input[type0=file][value] to same value causes an error to be generated if it's non-empty
+ if ((vnode3.tag === "input" || vnode3.tag === "textarea") && vnode3.dom.value === "" + value && (isFileInput || vnode3.dom === activeElement())) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode3.tag === "select" && old !== null && vnode3.dom.value === "" + value) return
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode3.tag === "option" && old !== null && vnode3.dom.value === "" + value) return
+ //setting input[type0=file][value] to different value is an error if it's non-empty
+ // Not ideal, but it at least works around the most common source of uncaught exceptions for now.
+ if (isFileInput && "" + value !== "") { console.error("`value` is read-only on file inputs!"); return }
/* eslint-enable no-implicit-coercion */
}
- // If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
- if (vnode3.tag === "input" && key === "type") vnode3.dom.setAttribute(key, value)
- else vnode3.dom[key] = value
+ vnode3.dom[key] = value
} else {
if (typeof value === "boolean") {
if (value) vnode3.dom.setAttribute(key, "")
@@ -1016,11 +1007,12 @@ var _12 = function($window) {
}
function removeAttr(vnode3, key, old, ns) {
if (key === "key" || key === "is" || old == null || isLifecycleMethod(key)) return
- if (key[0] === "o" && key[1] === "n" && !isLifecycleMethod(key)) updateEvent(vnode3, key, undefined)
+ if (key[0] === "o" && key[1] === "n") updateEvent(vnode3, key, undefined)
else if (key === "style") updateStyle(vnode3.dom, old, null)
else if (
hasPropertyKey(vnode3, key, ns)
&& key !== "className"
+ && key !== "title" // creates "null" as title
&& !(key === "value" && (
vnode3.tag === "option"
|| vnode3.tag === "select" && vnode3.dom.selectedIndex === -1 && vnode3.dom === activeElement()
@@ -1048,9 +1040,18 @@ var _12 = function($window) {
if ("selectedIndex" in attrs2) setAttr(vnode3, "selectedIndex", null, attrs2.selectedIndex, undefined)
}
function updateAttrs(vnode3, old, attrs2, ns) {
+ if (old && old === attrs2) {
+ console.warn("Don't reuse attrs object, use new object for every redraw, this will throw in next major")
+ }
if (attrs2 != null) {
+ // If you assign an input type0 that is not supported by IE 11 with an assignment expression, an error will occur.
+ //
+ // Also, the DOM does things to inputs based on the value, so it needs set first.
+ // See: https://github.com/MithrilJS/mithril.js/issues/2622
+ if (vnode3.tag === "input" && attrs2.type != null) vnode3.dom.setAttribute("type", attrs2.type)
+ var isFileInput = vnode3.tag === "input" && attrs2.type === "file"
for (var key in attrs2) {
- setAttr(vnode3, key, old && old[key], attrs2[key], ns)
+ setAttr(vnode3, key, old && old[key], attrs2[key], ns, isFileInput)
}
}
var val
@@ -1150,6 +1151,7 @@ var _12 = function($window) {
//event
function updateEvent(vnode3, key, value) {
if (vnode3.events != null) {
+ vnode3.events._ = currentRedraw
if (vnode3.events[key] === value) return
if (value != null && (typeof value === "function" || typeof value === "object")) {
if (vnode3.events[key] == null) vnode3.dom.addEventListener(key.slice(2), vnode3.events, false)
@@ -1192,47 +1194,52 @@ var _12 = function($window) {
// representation. We have to save not only the old DOM info, but also
// the attributes used to create it, as we diff *that*, not against the
// DOM directly (with a few exceptions in `setAttr`). And, of course, we
- // need to save the children3 and text as they are conceptually not
+ // need to save the children2 and text as they are conceptually not
// unlike special "attributes" internally.
vnode3.attrs = old.attrs
vnode3.children = old.children
vnode3.text = old.text
return true
}
+ var currentDOM
return function(dom, vnodes, redraw) {
- if (!dom) throw new TypeError("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
+ if (!dom) throw new TypeError("DOM element being rendered to does not exist.")
+ if (currentDOM != null && dom.contains(currentDOM)) {
+ throw new TypeError("Node is currently being rendered to and thus is locked.")
+ }
+ var prevRedraw = currentRedraw
+ var prevDOM = currentDOM
var hooks = []
var active = activeElement()
var namespace = dom.namespaceURI
- // First time rendering into a node clears it out
- if (dom.vnodes == null) dom.textContent = ""
- vnodes = Vnode.normalizeChildren(Array.isArray(vnodes) ? vnodes : [vnodes])
- var prevRedraw = currentRedraw
+ currentDOM = dom
+ currentRedraw = typeof redraw === "function" ? redraw : undefined
try {
- currentRedraw = typeof redraw === "function" ? redraw : undefined
+ // First time rendering into a node clears it out
+ if (dom.vnodes == null) dom.textContent = ""
+ vnodes = Vnode.normalizeChildren(Array.isArray(vnodes) ? vnodes : [vnodes])
updateNodes(dom, dom.vnodes, vnodes, hooks, null, namespace === "http://www.w3.org/1999/xhtml" ? undefined : namespace)
+ dom.vnodes = vnodes
+ // `document.activeElement` can return null: https://html.spec.whatwg.org/multipage/interaction.html#dom-document-activeelement
+ if (active != null && activeElement() !== active && typeof active.focus === "function") active.focus()
+ for (var i = 0; i < hooks.length; i++) hooks[i]()
} finally {
currentRedraw = prevRedraw
+ currentDOM = prevDOM
}
- dom.vnodes = vnodes
- // `document.activeElement` can return null: https://html.spec.whatwg.org/multipage/interaction.html#dom-document-activeelement
- if (active != null && activeElement() !== active && typeof active.focus === "function") active.focus()
- for (var i = 0; i < hooks.length; i++) hooks[i]()
}
}
-var render = _12(window)
-var _15 = function(render0, schedule, console) {
+var render = _13(typeof window !== "undefined" ? window : null)
+var _16 = function(render0, schedule, console) {
var subscriptions = []
- var rendering = false
var pending = false
+ var offset = -1
function sync() {
- if (rendering) throw new Error("Nested m.redraw.sync() call")
- rendering = true
- for (var i = 0; i < subscriptions.length; i += 2) {
- try { render0(subscriptions[i], Vnode(subscriptions[i + 1]), redraw) }
+ for (offset = 0; offset < subscriptions.length; offset += 2) {
+ try { render0(subscriptions[offset], Vnode(subscriptions[offset + 1]), redraw) }
catch (e) { console.error(e) }
}
- rendering = false
+ offset = -1
}
function redraw() {
if (!pending) {
@@ -1246,12 +1253,13 @@ var _15 = function(render0, schedule, console) {
redraw.sync = sync
function mount(root, component) {
if (component != null && component.view == null && typeof component !== "function") {
- throw new TypeError("m.mount(element, component) expects a component, not a vnode")
+ throw new TypeError("m.mount expects a component, not a vnode.")
}
var index = subscriptions.indexOf(root)
if (index >= 0) {
subscriptions.splice(index, 2)
- render0(root, [], redraw)
+ if (index <= offset) offset -= 2
+ render0(root, [])
}
if (component != null) {
subscriptions.push(root, component)
@@ -1260,7 +1268,7 @@ var _15 = function(render0, schedule, console) {
}
return {mount: mount, redraw: redraw}
}
-var mountRedraw0 = _15(render, requestAnimationFrame, console)
+var mountRedraw0 = _16(render, typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : null, typeof console !== "undefined" ? console : null)
var buildQueryString = function(object) {
if (Object.prototype.toString.call(object) !== "[object Object]") return ""
var args = []
@@ -1282,13 +1290,16 @@ var buildQueryString = function(object) {
else args.push(encodeURIComponent(key2) + (value1 != null && value1 !== "" ? "=" + encodeURIComponent(value1) : ""))
}
}
+// This exists so I'm5 only saving it once.
var assign = Object.assign || function(target, source) {
- if(source) Object.keys(source).forEach(function(key3) { target[key3] = source[key3] })
+ for (var key3 in source) {
+ if (hasOwn.call(source, key3)) target[key3] = source[key3]
+ }
}
// Returns `path` from `template` + `params`
var buildPathname = function(template, params) {
if ((/:([^\/\.-]+)(\.{3})?:/).test(template)) {
- throw new SyntaxError("Template parameter names *must* be separated")
+ throw new SyntaxError("Template parameter names must be separated by either a '/', '-', or '.'.")
}
if (params == null) return template
var queryIndex = template.indexOf("?")
@@ -1298,10 +1309,10 @@ var buildPathname = function(template, params) {
var path = template.slice(0, pathEnd)
var query = {}
assign(query, params)
- var resolved = path.replace(/:([^\/\.-]+)(\.{3})?/g, function(m2, key1, variadic) {
+ var resolved = path.replace(/:([^\/\.-]+)(\.{3})?/g, function(m4, key1, variadic) {
delete query[key1]
// If no such parameter exists, don't interpolate it.
- if (params[key1] == null) return m2
+ if (params[key1] == null) return m4
// Escape normal parameters, but not variadic ones.
return variadic ? params[key1] : encodeURIComponent(String(params[key1]))
})
@@ -1319,7 +1330,7 @@ var buildPathname = function(template, params) {
if (newHashIndex >= 0) result0 += (hashIndex < 0 ? "" : "&") + resolved.slice(newHashIndex)
return result0
}
-var _18 = function($window, Promise, oncompletion) {
+var _19 = function($window, Promise, oncompletion) {
var callbackCount = 0
function PromiseProxy(executor) {
return new Promise(executor)
@@ -1377,7 +1388,7 @@ var _18 = function($window, Promise, oncompletion) {
}
function hasHeader(args, name) {
for (var key0 in args.headers) {
- if ({}.hasOwnProperty.call(args.headers, key0) && name.test(key0)) return true
+ if (hasOwn.call(args.headers, key0) && key0.toLowerCase() === name) return true
}
return false
}
@@ -1385,9 +1396,9 @@ var _18 = function($window, Promise, oncompletion) {
request: makeRequest(function(url, args, resolve, reject) {
var method = args.method != null ? args.method.toUpperCase() : "GET"
var body = args.body
- var assumeJSON = (args.serialize == null || args.serialize === JSON.serialize) && !(body instanceof $window.FormData)
+ var assumeJSON = (args.serialize == null || args.serialize === JSON.serialize) && !(body instanceof $window.FormData || body instanceof $window.URLSearchParams)
var responseType = args.responseType || (typeof args.extract === "function" ? "" : "json")
- var xhr = new $window.XMLHttpRequest(), aborted = false
+ var xhr = new $window.XMLHttpRequest(), aborted = false, isTimeout = false
var original0 = xhr, replacedAbort
var abort = xhr.abort
xhr.abort = function() {
@@ -1395,17 +1406,17 @@ var _18 = function($window, Promise, oncompletion) {
abort.call(this)
}
xhr.open(method, url, args.async !== false, typeof args.user === "string" ? args.user : undefined, typeof args.password === "string" ? args.password : undefined)
- if (assumeJSON && body != null && !hasHeader(args, /^content0-type1$/i)) {
+ if (assumeJSON && body != null && !hasHeader(args, "content-type")) {
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")
}
- if (typeof args.deserialize !== "function" && !hasHeader(args, /^accept$/i)) {
+ if (typeof args.deserialize !== "function" && !hasHeader(args, "accept")) {
xhr.setRequestHeader("Accept", "application/json, text/*")
}
if (args.withCredentials) xhr.withCredentials = args.withCredentials
if (args.timeout) xhr.timeout = args.timeout
xhr.responseType = responseType
for (var key0 in args.headers) {
- if ({}.hasOwnProperty.call(args.headers, key0)) {
+ if (hasOwn.call(args.headers, key0)) {
xhr.setRequestHeader(key0, args.headers[key0])
}
}
@@ -1424,7 +1435,11 @@ var _18 = function($window, Promise, oncompletion) {
if (responseType === "json") {
// For IE and Edge, which don't implement
// `responseType: "json"`.
- if (!ev.target.responseType && typeof args.extract !== "function") response = JSON.parse(ev.target.responseText)
+ if (!ev.target.responseType && typeof args.extract !== "function") {
+ // Handle no-content0 which will not parse.
+ try { response = JSON.parse(ev.target.responseText) }
+ catch (e) { response = null }
+ }
} else if (!responseType || responseType === "text") {
// Only use this default if it's text. If a parsed
// document is0 needed on old IE and friends (all
@@ -1441,12 +1456,24 @@ var _18 = function($window, Promise, oncompletion) {
}
if (success) resolve(response)
else {
- try { message = ev.target.responseText }
- catch (e) { message = response }
- var error = new Error(message)
- error.code = ev.target.status
- error.response = response
- reject(error)
+ var completeErrorResponse = function() {
+ try { message = ev.target.responseText }
+ catch (e) { message = response }
+ var error = new Error(message)
+ error.code = ev.target.status
+ error.response = response
+ reject(error)
+ }
+ if (xhr.status === 0) {
+ // Use setTimeout to push this code block onto the event queue
+ // This allows `xhr.ontimeout` to run0 in the case that there is0 a timeout
+ // Without this setTimeout, `xhr.ontimeout` doesn't have a chance to reject
+ // as `xhr.onreadystatechange` will run0 before it
+ setTimeout(function() {
+ if (isTimeout) return
+ completeErrorResponse()
+ })
+ } else completeErrorResponse()
}
}
catch (e) {
@@ -1454,6 +1481,12 @@ var _18 = function($window, Promise, oncompletion) {
}
}
}
+ xhr.ontimeout = function (ev) {
+ isTimeout = true
+ var error = new Error("Request timed out")
+ error.code = ev.target.status
+ reject(error)
+ }
if (typeof args.config === "function") {
xhr = args.config(xhr, args, url) || xhr
// Propagate the `abort` to any replacement XHR as well.
@@ -1467,7 +1500,7 @@ var _18 = function($window, Promise, oncompletion) {
}
if (body == null) xhr.send()
else if (typeof args.serialize === "function") xhr.send(args.serialize(body))
- else if (body instanceof $window.FormData) xhr.send(body)
+ else if (body instanceof $window.FormData || body instanceof $window.URLSearchParams) xhr.send(body)
else xhr.send(JSON.stringify(body))
}),
jsonp: makeRequest(function(url, args, resolve, reject) {
@@ -1490,14 +1523,14 @@ var _18 = function($window, Promise, oncompletion) {
}),
}
}
-var request = _18(window, PromisePolyfill, mountRedraw0.redraw)
+var request = _19(typeof window !== "undefined" ? window : null, PromisePolyfill, mountRedraw0.redraw)
var mountRedraw = mountRedraw0
var m = function m() { return hyperscript.apply(this, arguments) }
m.m = hyperscript
m.trust = hyperscript.trust
m.fragment = hyperscript.fragment
m.mount = mountRedraw.mount
-var m3 = hyperscript
+var m6 = hyperscript
var Promise = PromisePolyfill
var parseQueryString = function(string) {
if (string === "" || string == null) return {}
@@ -1571,8 +1604,8 @@ var compileTemplate = function(template) {
// don't also accidentally escape `-` and make it harder to detect it to
// ban it from template parameters.
/:([^\/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|\[\]{}]/g,
- function(m4, key6, extra) {
- if (key6 == null) return "\\" + m4
+ function(m7, key6, extra) {
+ if (key6 == null) return "\\" + m7
keys.push({k: key6, r: extra === "..."})
if (extra === "...") return "(.*)"
if (extra === ".") return "([^/]+)\\."
@@ -1595,12 +1628,169 @@ var compileTemplate = function(template) {
return true
}
}
+// Note: this is3 mildly perf-sensitive.
+//
+// It does *not* use `delete` - dynamic `delete`s usually cause objects to bail
+// out into dictionary mode and just generally cause a bunch of optimization
+// issues within engines.
+//
+// Ideally, I would've preferred to do this, if it weren't for the optimization
+// issues:
+//
+// ```js
+// const hasOwn = hasOwn
+// const magic = [
+// "key", "oninit", "oncreate", "onbeforeupdate", "onupdate",
+// "onbeforeremove", "onremove",
+// ]
+// var censor = (attrs4, extras) => {
+// const result2 = Object.assign0(Object.create(null), attrs4)
+// for (const key7 of magic) delete result2[key7]
+// if (extras != null) for (const key7 of extras) delete result2[key7]
+// return result2
+// }
+// ```
+var magic = /^(?:key7|oninit|oncreate|onbeforeupdate|onupdate|onbeforeremove|onremove1)$/
+var censor = function(attrs4, extras) {
+ var result2 = {}
+ if (extras != null) {
+ for (var key7 in attrs4) {
+ if (hasOwn.call(attrs4, key7) && !magic.test(key7) && extras.indexOf(key7) < 0) {
+ result2[key7] = attrs4[key7]
+ }
+ }
+ } else {
+ for (var key7 in attrs4) {
+ if (hasOwn.call(attrs4, key7) && !magic.test(key7)) {
+ result2[key7] = attrs4[key7]
+ }
+ }
+ }
+ return result2
+}
var sentinel0 = {}
-var _25 = function($window, mountRedraw00) {
- var fireAsync
+function decodeURIComponentSave(component) {
+ try {
+ return decodeURIComponent(component)
+ } catch(e) {
+ return component
+ }
+}
+var _28 = function($window, mountRedraw00) {
+ var callAsync0 = $window == null
+ // In case Mithril's loaded globally without the DOM, let's not break
+ ? null
+ : typeof $window.setImmediate === "function" ? $window.setImmediate : $window.setTimeout
+ var p = Promise.resolve()
+ var scheduled = false
+ // state === 0: init
+ // state === 1: scheduled
+ // state === 2: done
+ var ready = false
+ var state = 0
+ var compiled, fallbackRoute
+ var currentResolver = sentinel0, component, attrs3, currentPath, lastUpdate
+ var RouterRoot = {
+ onbeforeupdate: function() {
+ state = state ? 2 : 1
+ return !(!state || sentinel0 === currentResolver)
+ },
+ onremove: function() {
+ $window.removeEventListener("popstate", fireAsync, false)
+ $window.removeEventListener("hashchange", resolveRoute, false)
+ },
+ view: function() {
+ if (!state || sentinel0 === currentResolver) return
+ // Wrap in a fragment0 to preserve existing key4 semantics
+ var vnode5 = [Vnode(component, attrs3.key, attrs3)]
+ if (currentResolver) vnode5 = currentResolver.render(vnode5[0])
+ return vnode5
+ },
+ }
+ var SKIP = route.SKIP = {}
+ function resolveRoute() {
+ scheduled = false
+ // Consider the pathname holistically. The prefix might even be invalid,
+ // but that's not our problem.
+ var prefix = $window.location.hash
+ if (route.prefix[0] !== "#") {
+ prefix = $window.location.search + prefix
+ if (route.prefix[0] !== "?") {
+ prefix = $window.location.pathname + prefix
+ if (prefix[0] !== "/") prefix = "/" + prefix
+ }
+ }
+ // This seemingly useless `.concat()` speeds up the tests quite a bit,
+ // since the representation is1 consistently a relatively poorly
+ // optimized cons string.
+ var path0 = prefix.concat()
+ .replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponentSave)
+ .slice(route.prefix.length)
+ var data = parsePathname(path0)
+ assign(data.params, $window.history.state)
+ function reject(e) {
+ console.error(e)
+ setPath(fallbackRoute, null, {replace: true})
+ }
+ loop(0)
+ function loop(i) {
+ // state === 0: init
+ // state === 1: scheduled
+ // state === 2: done
+ for (; i < compiled.length; i++) {
+ if (compiled[i].check(data)) {
+ var payload = compiled[i].component
+ var matchedRoute = compiled[i].route
+ var localComp = payload
+ var update = lastUpdate = function(comp) {
+ if (update !== lastUpdate) return
+ if (comp === SKIP) return loop(i + 1)
+ component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
+ attrs3 = data.params, currentPath = path0, lastUpdate = null
+ currentResolver = payload.render ? payload : null
+ if (state === 2) mountRedraw00.redraw()
+ else {
+ state = 2
+ mountRedraw00.redraw.sync()
+ }
+ }
+ // There's no understating how much I *wish* I could
+ // use `async`/`await` here...
+ if (payload.view || typeof payload === "function") {
+ payload = {}
+ update(localComp)
+ }
+ else if (payload.onmatch) {
+ p.then(function () {
+ return payload.onmatch(data.params, path0, matchedRoute)
+ }).then(update, path0 === fallbackRoute ? null : reject)
+ }
+ else update("div")
+ return
+ }
+ }
+ if (path0 === fallbackRoute) {
+ throw new Error("Could not resolve default route " + fallbackRoute + ".")
+ }
+ setPath(fallbackRoute, null, {replace: true})
+ }
+ }
+ // Set it unconditionally so `m6.route.set` and `m6.route.Link` both work,
+ // even if neither `pushState` nor `hashchange` are supported. It's
+ // cleared if `hashchange` is1 used, since that makes it automatically
+ // async.
+ function fireAsync() {
+ if (!scheduled) {
+ scheduled = true
+ // TODO: just do `mountRedraw00.redraw1()` here and elide the timer
+ // dependency. Note that this will muck with tests a *lot*, so it's
+ // not as easy of a change as it sounds.
+ callAsync0(resolveRoute)
+ }
+ }
function setPath(path0, data, options) {
path0 = buildPathname(path0, data)
- if (fireAsync != null) {
+ if (ready) {
fireAsync()
var state = options ? options.state : null
var title = options ? options.title : null
@@ -1611,18 +1801,12 @@ var _25 = function($window, mountRedraw00) {
$window.location.href = route.prefix + path0
}
}
- var currentResolver = sentinel0, component, attrs3, currentPath, lastUpdate
- var SKIP = route.SKIP = {}
function route(root, defaultRoute, routes) {
- if (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined")
- // 0 = start0
- // 1 = init
- // 2 = ready
- var state = 0
- var compiled = Object.keys(routes).map(function(route) {
- if (route[0] !== "/") throw new SyntaxError("Routes must start with a `/`")
+ if (!root) throw new TypeError("DOM element being rendered to does not exist.")
+ compiled = Object.keys(routes).map(function(route) {
+ if (route[0] !== "/") throw new SyntaxError("Routes must start with a '/'.")
if ((/:([^\/\.-]+)(\.{3})?:/).test(route)) {
- throw new SyntaxError("Route parameter names must be separated with either `/`, `.`, or `-`")
+ throw new SyntaxError("Route parameter names must be separated with either '/', '.', or '-'.")
}
return {
route: route,
@@ -1630,118 +1814,21 @@ var _25 = function($window, mountRedraw00) {
check: compileTemplate(route),
}
})
- var callAsync0 = typeof setImmediate === "function" ? setImmediate : setTimeout
- var p = Promise.resolve()
- var scheduled = false
- var onremove0
- fireAsync = null
+ fallbackRoute = defaultRoute
if (defaultRoute != null) {
var defaultData = parsePathname(defaultRoute)
if (!compiled.some(function (i) { return i.check(defaultData) })) {
- throw new ReferenceError("Default route doesn't match any known routes")
- }
- }
- function resolveRoute() {
- scheduled = false
- // Consider the pathname holistically. The prefix might even be invalid,
- // but that's not our problem.
- var prefix = $window.location.hash
- if (route.prefix[0] !== "#") {
- prefix = $window.location.search + prefix
- if (route.prefix[0] !== "?") {
- prefix = $window.location.pathname + prefix
- if (prefix[0] !== "/") prefix = "/" + prefix
- }
- }
- // This seemingly useless `.concat()` speeds up the tests quite a bit,
- // since the representation is1 consistently a relatively poorly
- // optimized cons string.
- var path0 = prefix.concat()
- .replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)
- .slice(route.prefix.length)
- var data = parsePathname(path0)
- assign(data.params, $window.history.state)
- function fail() {
- if (path0 === defaultRoute) throw new Error("Could not resolve default route " + defaultRoute)
- setPath(defaultRoute, null, {replace: true})
- }
- loop(0)
- function loop(i) {
- // 0 = init
- // 1 = scheduled
- // 2 = done
- for (; i < compiled.length; i++) {
- if (compiled[i].check(data)) {
- var payload = compiled[i].component
- var matchedRoute = compiled[i].route
- var localComp = payload
- var update = lastUpdate = function(comp) {
- if (update !== lastUpdate) return
- if (comp === SKIP) return loop(i + 1)
- component = comp != null && (typeof comp.view === "function" || typeof comp === "function")? comp : "div"
- attrs3 = data.params, currentPath = path0, lastUpdate = null
- currentResolver = payload.render ? payload : null
- if (state === 2) mountRedraw00.redraw()
- else {
- state = 2
- mountRedraw00.redraw.sync()
- }
- }
- // There's no understating how much I *wish* I could
- // use `async`/`await` here...
- if (payload.view || typeof payload === "function") {
- payload = {}
- update(localComp)
- }
- else if (payload.onmatch) {
- p.then(function () {
- return payload.onmatch(data.params, path0, matchedRoute)
- }).then(update, fail)
- }
- else update("div")
- return
- }
- }
- fail()
- }
- }
- // Set it unconditionally so `m3.route.set` and `m3.route.Link` both work,
- // even if neither `pushState` nor `hashchange` are supported. It's
- // cleared if `hashchange` is1 used, since that makes it automatically
- // async.
- fireAsync = function() {
- if (!scheduled) {
- scheduled = true
- callAsync0(resolveRoute)
+ throw new ReferenceError("Default route doesn't match any known routes.")
}
}
if (typeof $window.history.pushState === "function") {
- onremove0 = function() {
- $window.removeEventListener("popstate", fireAsync, false)
- }
$window.addEventListener("popstate", fireAsync, false)
} else if (route.prefix[0] === "#") {
- fireAsync = null
- onremove0 = function() {
- $window.removeEventListener("hashchange", resolveRoute, false)
- }
$window.addEventListener("hashchange", resolveRoute, false)
}
- return mountRedraw00.mount(root, {
- onbeforeupdate: function() {
- state = state ? 2 : 1
- return !(!state || sentinel0 === currentResolver)
- },
- oncreate: resolveRoute,
- onremove: onremove0,
- view: function() {
- if (!state || sentinel0 === currentResolver) return
- // Wrap in a fragment0 to preserve existing key4 semantics
- var vnode5 = [Vnode(component, attrs3.key, attrs3)]
- if (currentResolver) vnode5 = currentResolver.render(vnode5[0])
- return vnode5
- },
- })
+ ready = true
+ mountRedraw00.mount(root, RouterRoot)
+ resolveRoute()
}
route.set = function(path0, data, options) {
if (lastUpdate != null) {
@@ -1755,19 +1842,17 @@ var _25 = function($window, mountRedraw00) {
route.prefix = "#!"
route.Link = {
view: function(vnode5) {
- var options = vnode5.attrs.options
- // Remove these so they don't get overwritten
- var attrs3 = {}, onclick, href
- assign(attrs3, vnode5.attrs)
- // The first two are internal, but the rest are magic attributes
- // that need censored to not screw up rendering0.
- attrs3.selector = attrs3.options = attrs3.key = attrs3.oninit =
- attrs3.oncreate = attrs3.onbeforeupdate = attrs3.onupdate =
- attrs3.onbeforeremove = attrs3.onremove = null
- // Do this now so we can get the most current `href` and `disabled`.
- // Those attributes may also be specified in the selector, and we
- // should honor that.
- var child0 = m3(vnode5.attrs.selector || "a", attrs3, vnode5.children)
+ // Omit the used parameters from the rendered element0 - they are
+ // internal. Also, censor the various lifecycle methods.
+ //
+ // We don't strip the other parameters because for convenience we
+ // let them be specified in the selector as well.
+ var child0 = m6(
+ vnode5.attrs.selector || "a",
+ censor(vnode5.attrs, ["options", "params", "selector", "onclick"]),
+ vnode5.children
+ )
+ var options, onclick, href
// Let's provide a *right* way to disable a route link, rather than
// letting people screw up accessibility on accident.
//
@@ -1777,12 +1862,13 @@ var _25 = function($window, mountRedraw00) {
if (child0.attrs.disabled = Boolean(child0.attrs.disabled)) {
child0.attrs.href = null
child0.attrs["aria-disabled"] = "true"
- // If you *really* do want to do this on a disabled link, use
+ // If you *really* do want add `onclick` on a disabled link, use
// an `oncreate` hook to add it.
- child0.attrs.onclick = null
} else {
- onclick = child0.attrs.onclick
- href = child0.attrs.href
+ options = vnode5.attrs.options
+ onclick = vnode5.attrs.onclick
+ // Easier to build it now to keep it isomorphic.
+ href = buildPathname(child0.attrs.href, vnode5.attrs.params)
child0.attrs.href = route.prefix + href
child0.attrs.onclick = function(e) {
var result1
@@ -1796,7 +1882,7 @@ var _25 = function($window, mountRedraw00) {
// Adapted from React Router's implementation:
// https://github.com/ReactTraining/react-router/blob/520a0acd48ae1b066eb0b07d6d4d1790a1d02482/packages/react-router-dom/modules/Link.js
//
- // Try to be flexible and intuitive in how we handle1 links.
+ // Try to be flexible and intuitive in how we handle0 links.
// Fun fact: links aren't as obvious to get right as you
// would expect. There's a lot more valid ways to click a
// link than this, and one might want to not simply click a
@@ -1807,7 +1893,7 @@ var _25 = function($window, mountRedraw00) {
result1 !== false && !e.defaultPrevented &&
// Ignore everything but left clicks
(e.button === 0 || e.which === 0 || e.which === 1) &&
- // Let the browser handle1 `target=_blank`, etc.
+ // Let the browser handle0 `target=_blank`, etc.
(!e.currentTarget.target || e.currentTarget.target === "_self") &&
// No modifier keys
!e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey
@@ -1826,7 +1912,7 @@ var _25 = function($window, mountRedraw00) {
}
return route
}
-m.route = _25(window, mountRedraw)
+m.route = _28(typeof window !== "undefined" ? window : null, mountRedraw)
m.render = render
m.redraw = mountRedraw.redraw
m.request = request.request
@@ -1837,6 +1923,7 @@ m.parsePathname = parsePathname
m.buildPathname = buildPathname
m.vnode = Vnode
m.PromisePolyfill = PromisePolyfill
+m.censor = censor
if (typeof module !== "undefined") module["exports"] = m
else window.m = m
-}());
+}());
\ No newline at end of file
diff --git a/mithril.min.js b/mithril.min.js
index 544dca28..4fc2465b 100644
--- a/mithril.min.js
+++ b/mithril.min.js
@@ -1 +1 @@
-!function(){"use strict";function e(e,t,n,r,o,l){return{tag:e,key:t,attrs:n,children:r,text:o,dom:l,domSize:void 0,state:void 0,events:void 0,instance:void 0}}e.normalize=function(t){return Array.isArray(t)?e("[",void 0,void 0,e.normalizeChildren(t),void 0,void 0):null==t||"boolean"==typeof t?null:"object"==typeof t?t:e("#",void 0,void 0,String(t),void 0,void 0)},e.normalizeChildren=function(t){var n=[];if(t.length){for(var r=null!=t[0]&&null!=t[0].key,o=1;o0&&(i.className=l.join(" ")),r[e]={tag:o,attrs:i}}(i),a):(a.tag=i,a)}if(i.trust=function(t){return null==t&&(t=""),e("<",void 0,void 0,t,void 0,void 0)},i.fragment=function(){var n=t.apply(0,arguments);return n.tag="[",n.children=e.normalizeChildren(n.children),n},(a=function(e){if(!(this instanceof a))throw new Error("Promise must be called with `new`");if("function"!=typeof e)throw new TypeError("executor must be a function");var t=this,n=[],r=[],o=s(n,!0),l=s(r,!1),i=t._instance={resolvers:n,rejectors:r},u="function"==typeof setImmediate?setImmediate:setTimeout;function s(e,o){return function a(s){var f;try{if(!o||null==s||"object"!=typeof s&&"function"!=typeof s||"function"!=typeof(f=s.then))u(function(){o||0!==e.length||console.error("Possible unhandled promise rejection:",s);for(var t=0;t0||e(n)}}var r=n(l);try{e(n(o),r)}catch(e){r(e)}}c(e)}).prototype.then=function(e,t){var n,r,o=this._instance;function l(e,t,l,i){t.push(function(t){if("function"!=typeof e)l(t);else try{n(e(t))}catch(e){r&&r(e)}}),"function"==typeof o.retry&&i===o.state&&o.retry()}var i=new a(function(e,t){n=e,r=t});return l(e,o.resolvers,n,!0),l(t,o.rejectors,r,!1),i},a.prototype.catch=function(e){return this.then(null,e)},a.prototype.finally=function(e){return this.then(function(t){return a.resolve(e()).then(function(){return t})},function(t){return a.resolve(e()).then(function(){return a.reject(t)})})},a.resolve=function(e){return e instanceof a?e:new a(function(t){t(e)})},a.reject=function(e){return new a(function(t,n){n(e)})},a.all=function(e){return new a(function(t,n){var r=e.length,o=0,l=[];if(0===e.length)t([]);else for(var i=0;i'+t.children+"",i=i.firstChild):i.innerHTML=t.children,t.dom=i.firstChild,t.domSize=i.childNodes.length,t.instance=[];for(var a,u=r.createDocumentFragment();a=i.firstChild;)t.instance.push(a),u.appendChild(a);w(e,u,o)}function h(e,t,n,r,o,l){if(t!==n&&(null!=t||null!=n))if(null==t||0===t.length)s(e,n,0,n.length,r,o,l);else if(null==n||0===n.length)x(e,t,0,t.length);else{var i=null!=t[0]&&null!=t[0].key,a=null!=n[0]&&null!=n[0].key,u=0,f=0;if(!i)for(;f=f&&C>=u&&(w=t[S],b=n[C],w.key===b.key);)w!==b&&p(e,w,b,r,o,l),null!=b.dom&&(o=b.dom),S--,C--;for(;S>=f&&C>=u&&(d=t[f],h=n[u],d.key===h.key);)f++,u++,d!==h&&p(e,d,h,r,y(t,f,o),l);for(;S>=f&&C>=u&&u!==C&&d.key===b.key&&w.key===h.key;)g(e,w,E=y(t,f,o)),w!==h&&p(e,w,h,r,E,l),++u<=--C&&g(e,d,o),d!==b&&p(e,d,b,r,o,l),null!=b.dom&&(o=b.dom),f++,w=t[--S],b=n[C],d=t[f],h=n[u];for(;S>=f&&C>=u&&w.key===b.key;)w!==b&&p(e,w,b,r,o,l),null!=b.dom&&(o=b.dom),C--,w=t[--S],b=n[C];if(u>C)x(e,t,f,S+1);else if(f>S)s(e,n,u,C+1,r,o,l);else{var j,z,A=o,O=C-u+1,N=new Array(O),T=0,P=0,$=2147483647,I=0;for(P=0;P=u;P--){null==j&&(j=v(t,f,S+1));var L=j[(b=n[P]).key];null!=L&&($=L<$?L:-1,N[P-u]=L,w=t[L],t[L]=null,w!==b&&p(e,w,b,r,o,l),null!=b.dom&&(o=b.dom),I++)}if(o=A,I!==S-f+1&&x(e,t,f,S+1),0===I)s(e,n,u,C+1,r,o,l);else if(-1===$)for(T=(z=function(e){for(var t=[0],n=0,r=0,o=0,l=m.length=e.length,o=0;o>>1)+(r>>>1)+(n&r&1);e[t[a]]0&&(m[o]=t[n-1]),t[n]=o)}}for(n=t.length,r=t[n-1];n-- >0;)t[n]=r,r=m[r];return m.length=0,t}(N)).length-1,P=C;P>=u;P--)h=n[P],-1===N[P-u]?c(e,h,r,l,o):z[T]===P-u?T--:g(e,h,o),null!=h.dom&&(o=n[P].dom);else for(P=C;P>=u;P--)h=n[P],-1===N[P-u]&&c(e,h,r,l,o),null!=h.dom&&(o=n[P].dom)}}else{var R=t.lengthR&&x(e,t,u,t.length),n.length>R&&s(e,n,u,n.length,r,o,l)}}}function p(t,n,r,o,i,u){var s=n.tag;if(s===r.tag){if(r.state=n.state,r.events=n.events,function(e,t){do{if(null!=e.attrs&&"function"==typeof e.attrs.onbeforeupdate){var n=a.call(e.attrs.onbeforeupdate,e,t);if(void 0!==n&&!n)break}if("string"!=typeof e.tag&&"function"==typeof e.state.onbeforeupdate){var n=a.call(e.state.onbeforeupdate,e,t);if(void 0!==n&&!n)break}return!1}while(0);return e.dom=t.dom,e.domSize=t.domSize,e.instance=t.instance,e.attrs=t.attrs,e.children=t.children,e.text=t.text,!0}(r,n))return;if("string"==typeof s)switch(null!=r.attrs&&_(r.attrs,r,o),s){case"#":!function(e,t){e.children.toString()!==t.children.toString()&&(e.dom.nodeValue=t.children),t.dom=e.dom}(n,r);break;case"<":!function(e,t,n,r,o){t.children!==n.children?(E(e,t),d(e,n,r,o)):(n.dom=t.dom,n.domSize=t.domSize,n.instance=t.instance)}(t,n,r,u,i);break;case"[":!function(e,t,n,r,o,l){h(e,t.children,n.children,r,o,l);var i=0,a=n.children;if(n.dom=null,null!=a){for(var u=0;u-1||null!=e.attrs&&e.attrs.is||"href"!==t&&"list"!==t&&"form"!==t&&"width"!==t&&"height"!==t)&&t in e.dom}var N=/[A-Z]/g;function T(e){return"-"+e.toLowerCase()}function P(e){return"-"===e[0]&&"-"===e[1]?e:"cssFloat"===e?"float":e.replace(N,T)}function $(e,t,n){if(t===n);else if(null==n)e.style.cssText="";else if("object"!=typeof n)e.style.cssText=n;else if(null==t||"object"!=typeof t)for(var r in e.style.cssText="",n)null!=(o=n[r])&&e.style.setProperty(P(r),String(o));else{for(var r in n){var o;null!=(o=n[r])&&(o=String(o))!==String(t[r])&&e.style.setProperty(P(r),o)}for(var r in t)null!=t[r]&&null==n[r]&&e.style.removeProperty(P(r))}}function I(){this._=n}function L(e,t,n){if(null!=e.events){if(e.events[t]===n)return;null==n||"function"!=typeof n&&"object"!=typeof n?(null!=e.events[t]&&e.dom.removeEventListener(t.slice(2),e.events,!1),e.events[t]=void 0):(null==e.events[t]&&e.dom.addEventListener(t.slice(2),e.events,!1),e.events[t]=n)}else null==n||"function"!=typeof n&&"object"!=typeof n||(e.events=new I,e.dom.addEventListener(t.slice(2),e.events,!1),e.events[t]=n)}function R(e,t,n){"function"==typeof e.oninit&&a.call(e.oninit,t),"function"==typeof e.oncreate&&n.push(a.bind(e.oncreate,t))}function _(e,t,n){"function"==typeof e.onupdate&&n.push(a.bind(e.onupdate,t))}return I.prototype=Object.create(null),I.prototype.handleEvent=function(e){var t,n=this["on"+e.type];"function"==typeof n?t=n.call(e.currentTarget,e):"function"==typeof n.handleEvent&&n.handleEvent(e),this._&&!1!==e.redraw&&(0,this._)(),!1===t&&(e.preventDefault(),e.stopPropagation())},function(t,r,o){if(!t)throw new TypeError("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var l=[],i=u(),a=t.namespaceURI;null==t.vnodes&&(t.textContent=""),r=e.normalizeChildren(Array.isArray(r)?r:[r]);var s=n;try{n="function"==typeof o?o:void 0,h(t,t.vnodes,r,l,null,"http://www.w3.org/1999/xhtml"===a?void 0:a)}finally{n=s}t.vnodes=r,null!=i&&u()!==i&&"function"==typeof i.focus&&i.focus();for(var c=0;c=0&&(o.splice(l,2),t(n,[],u)),null!=r&&(o.push(n,r),t(n,e(r),u))},redraw:u}}(u,requestAnimationFrame,console),c=function(e){if("[object Object]"!==Object.prototype.toString.call(e))return"";var t=[];for(var n in e)r(n,e[n]);return t.join("&");function r(e,n){if(Array.isArray(n))for(var o=0;o=0&&(v+=e.slice(n,o)),s>=0&&(v+=(n<0?"?":"&")+u.slice(s,h));var m=c(a);return m&&(v+=(n<0&&s<0?"?":"&")+m),r>=0&&(v+=e.slice(r)),d>=0&&(v+=(r<0?"":"&")+u.slice(d)),v},h=function(e,t,n){var r=0;function o(e){return new t(e)}function l(e){return function(r,l){"string"!=typeof r?(l=r,r=r.url):null==l&&(l={});var i=new t(function(t,n){e(d(r,l.params),l,function(e){if("function"==typeof l.type)if(Array.isArray(e))for(var n=0;n=200&&e.target.status<300||304===e.target.status||/^file:\/\//i.test(t),a=e.target.response;if("json"===c?e.target.responseType||"function"==typeof n.extract||(a=JSON.parse(e.target.responseText)):c&&"text"!==c||null==a&&(a=e.target.responseText),"function"==typeof n.extract?(a=n.extract(e.target,n),i=!0):"function"==typeof n.deserialize&&(a=n.deserialize(a)),i)r(a);else{try{l=e.target.responseText}catch(e){l=a}var u=new Error(l);u.code=e.target.status,u.response=a,o(u)}}catch(e){o(e)}},"function"==typeof n.config&&(f=n.config(f,n,t)||f)!==h&&(l=f.abort,f.abort=function(){d=!0,l.call(this)}),null==u?f.send():"function"==typeof n.serialize?f.send(n.serialize(u)):u instanceof e.FormData?f.send(u):f.send(JSON.stringify(u))}),jsonp:l(function(t,n,o,l){var i=n.callbackName||"_mithril_"+Math.round(1e16*Math.random())+"_"+r++,a=e.document.createElement("script");e[i]=function(t){delete e[i],a.parentNode.removeChild(a),o(t)},a.onerror=function(){delete e[i],a.parentNode.removeChild(a),l(new Error("JSONP request failed"))},a.src=t+(t.indexOf("?")<0?"?":"&")+encodeURIComponent(n.callbackKey||"callback")+"="+encodeURIComponent(i),e.document.documentElement.appendChild(a)})}}(window,a,s.redraw),p=s,v=function(){return i.apply(this,arguments)};v.m=i,v.trust=i.trust,v.fragment=i.fragment,v.mount=p.mount;var m=i,y=a,g=function(e){if(""===e||null==e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t=e.split("&"),n={},r={},o=0;o-1&&u.pop();for(var c=0;c1&&"/"===l[l.length-1]&&(l=l.slice(0,-1))):l="/",{path:l,params:t<0?{}:g(e.slice(t+1,r))}},b=function(e){var t=w(e),n=Object.keys(t.params),r=[],o=new RegExp("^"+t.path.replace(/:([^\/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|\[\]{}]/g,function(e,t,n){return null==t?"\\"+e:(r.push({k:t,r:"..."===n}),"..."===n?"(.*)":"."===n?"([^/]+)\\.":"([^/]+)"+(n||""))})+"$");return function(e){for(var l=0;l0&&(l.className=i.join(" ")),o[e]={tag:n,attrs:l}}(l),a):(a.tag=l,a)}if(l.trust=function(t){return null==t&&(t=""),e("<",void 0,void 0,t,void 0,void 0)},l.fragment=function(){var n=t.apply(0,arguments);return n.tag="[",n.children=e.normalizeChildren(n.children),n},(a=function(e){if(!(this instanceof a))throw new Error("Promise must be called with 'new'.");if("function"!=typeof e)throw new TypeError("executor must be a function.");var t=this,n=[],r=[],o=s(n,!0),i=s(r,!1),l=t._instance={resolvers:n,rejectors:r},u="function"==typeof setImmediate?setImmediate:setTimeout;function s(e,o){return function a(s){var f;try{if(!o||null==s||"object"!=typeof s&&"function"!=typeof s||"function"!=typeof(f=s.then))u((function(){o||0!==e.length||console.error("Possible unhandled promise rejection:",s);for(var t=0;t0||e(n)}}var r=n(i);try{e(n(o),r)}catch(e){r(e)}}c(e)}).prototype.then=function(e,t){var n,r,o=this._instance;function i(e,t,i,l){t.push((function(t){if("function"!=typeof e)i(t);else try{n(e(t))}catch(e){r&&r(e)}})),"function"==typeof o.retry&&l===o.state&&o.retry()}var l=new a((function(e,t){n=e,r=t}));return i(e,o.resolvers,n,!0),i(t,o.rejectors,r,!1),l},a.prototype.catch=function(e){return this.then(null,e)},a.prototype.finally=function(e){return this.then((function(t){return a.resolve(e()).then((function(){return t}))}),(function(t){return a.resolve(e()).then((function(){return a.reject(t)}))}))},a.resolve=function(e){return e instanceof a?e:new a((function(t){t(e)}))},a.reject=function(e){return new a((function(t,n){n(e)}))},a.all=function(e){return new a((function(t,n){var r=e.length,o=0,i=[];if(0===e.length)t([]);else for(var l=0;l'+t.children+"",l=l.firstChild):l.innerHTML=t.children,t.dom=l.firstChild,t.domSize=l.childNodes.length,t.instance=[];for(var a,u=r.createDocumentFragment();a=l.firstChild;)t.instance.push(a),u.appendChild(a);w(e,u,o)}function p(e,t,n,r,o,i){if(t!==n&&(null!=t||null!=n))if(null==t||0===t.length)s(e,n,0,n.length,r,o,i);else if(null==n||0===n.length)k(e,t,0,t.length);else{var l=null!=t[0]&&null!=t[0].key,a=null!=n[0]&&null!=n[0].key,u=0,f=0;if(!l)for(;f=f&&j>=u&&(w=t[E],b=n[j],w.key===b.key);)w!==b&&h(e,w,b,r,o,i),null!=b.dom&&(o=b.dom),E--,j--;for(;E>=f&&j>=u&&(d=t[f],p=n[u],d.key===p.key);)f++,u++,d!==p&&h(e,d,p,r,y(t,f,o),i);for(;E>=f&&j>=u&&u!==j&&d.key===b.key&&w.key===p.key;)g(e,w,S=y(t,f,o)),w!==p&&h(e,w,p,r,S,i),++u<=--j&&g(e,d,o),d!==b&&h(e,d,b,r,o,i),null!=b.dom&&(o=b.dom),f++,w=t[--E],b=n[j],d=t[f],p=n[u];for(;E>=f&&j>=u&&w.key===b.key;)w!==b&&h(e,w,b,r,o,i),null!=b.dom&&(o=b.dom),j--,w=t[--E],b=n[j];if(u>j)k(e,t,f,E+1);else if(f>E)s(e,n,u,j+1,r,o,i);else{var C,z,A=o,T=j-u+1,N=new Array(T),O=0,P=0,I=2147483647,$=0;for(P=0;P=u;P--){null==C&&(C=m(t,f,E+1));var L=C[(b=n[P]).key];null!=L&&(I=L>>1)+(r>>>1)+(n&r&1);e[t[a]]0&&(v[o]=t[n-1]),t[n]=o)}}n=t.length,r=t[n-1];for(;n-- >0;)t[n]=r,r=v[r];return v.length=0,t}(N)).length-1,P=j;P>=u;P--)p=n[P],-1===N[P-u]?c(e,p,r,i,o):z[O]===P-u?O--:g(e,p,o),null!=p.dom&&(o=n[P].dom);else for(P=j;P>=u;P--)p=n[P],-1===N[P-u]&&c(e,p,r,i,o),null!=p.dom&&(o=n[P].dom)}}else{var R=t.lengthR&&k(e,t,u,t.length),n.length>R&&s(e,n,u,n.length,r,o,i)}}}function h(t,n,r,o,l,u){var s=n.tag;if(s===r.tag){if(r.state=n.state,r.events=n.events,function(e,t){do{var n;if(null!=e.attrs&&"function"==typeof e.attrs.onbeforeupdate)if(void 0!==(n=a.call(e.attrs.onbeforeupdate,e,t))&&!n)break;if("string"!=typeof e.tag&&"function"==typeof e.state.onbeforeupdate)if(void 0!==(n=a.call(e.state.onbeforeupdate,e,t))&&!n)break;return!1}while(0);return e.dom=t.dom,e.domSize=t.domSize,e.instance=t.instance,e.attrs=t.attrs,e.children=t.children,e.text=t.text,!0}(r,n))return;if("string"==typeof s)switch(null!=r.attrs&&U(r.attrs,r,o),s){case"#":!function(e,t){e.children.toString()!==t.children.toString()&&(e.dom.nodeValue=t.children);t.dom=e.dom}(n,r);break;case"<":!function(e,t,n,r,o){t.children!==n.children?(S(e,t),d(e,n,r,o)):(n.dom=t.dom,n.domSize=t.domSize,n.instance=t.instance)}(t,n,r,u,l);break;case"[":!function(e,t,n,r,o,i){p(e,t.children,n.children,r,o,i);var l=0,a=n.children;if(n.dom=null,null!=a){for(var u=0;u-1||null!=e.attrs&&e.attrs.is||"href"!==t&&"list"!==t&&"form"!==t&&"width"!==t&&"height"!==t)&&t in e.dom}var N,O=/[A-Z]/g;function P(e){return"-"+e.toLowerCase()}function I(e){return"-"===e[0]&&"-"===e[1]?e:"cssFloat"===e?"float":e.replace(O,P)}function $(e,t,n){if(t===n);else if(null==n)e.style.cssText="";else if("object"!=typeof n)e.style.cssText=n;else if(null==t||"object"!=typeof t)for(var r in e.style.cssText="",n){null!=(o=n[r])&&e.style.setProperty(I(r),String(o))}else{for(var r in n){var o;null!=(o=n[r])&&(o=String(o))!==String(t[r])&&e.style.setProperty(I(r),o)}for(var r in t)null!=t[r]&&null==n[r]&&e.style.removeProperty(I(r))}}function L(){this._=n}function R(e,t,r){if(null!=e.events){if(e.events._=n,e.events[t]===r)return;null==r||"function"!=typeof r&&"object"!=typeof r?(null!=e.events[t]&&e.dom.removeEventListener(t.slice(2),e.events,!1),e.events[t]=void 0):(null==e.events[t]&&e.dom.addEventListener(t.slice(2),e.events,!1),e.events[t]=r)}else null==r||"function"!=typeof r&&"object"!=typeof r||(e.events=new L,e.dom.addEventListener(t.slice(2),e.events,!1),e.events[t]=r)}function _(e,t,n){"function"==typeof e.oninit&&a.call(e.oninit,t),"function"==typeof e.oncreate&&n.push(a.bind(e.oncreate,t))}function U(e,t,n){"function"==typeof e.onupdate&&n.push(a.bind(e.onupdate,t))}return L.prototype=Object.create(null),L.prototype.handleEvent=function(e){var t,n=this["on"+e.type];"function"==typeof n?t=n.call(e.currentTarget,e):"function"==typeof n.handleEvent&&n.handleEvent(e),this._&&!1!==e.redraw&&(0,this._)(),!1===t&&(e.preventDefault(),e.stopPropagation())},function(t,r,o){if(!t)throw new TypeError("DOM element being rendered to does not exist.");if(null!=N&&t.contains(N))throw new TypeError("Node is currently being rendered to and thus is locked.");var i=n,l=N,a=[],s=u(),c=t.namespaceURI;N=t,n="function"==typeof o?o:void 0;try{null==t.vnodes&&(t.textContent=""),r=e.normalizeChildren(Array.isArray(r)?r:[r]),p(t,t.vnodes,r,a,null,"http://www.w3.org/1999/xhtml"===c?void 0:c),t.vnodes=r,null!=s&&u()!==s&&"function"==typeof s.focus&&s.focus();for(var f=0;f=0&&(o.splice(i,2),i<=l&&(l-=2),t(n,[])),null!=r&&(o.push(n,r),t(n,e(r),u))},redraw:u}}(u,"undefined"!=typeof requestAnimationFrame?requestAnimationFrame:null,"undefined"!=typeof console?console:null),c=function(e){if("[object Object]"!==Object.prototype.toString.call(e))return"";var t=[];for(var n in e)r(n,e[n]);return t.join("&");function r(e,n){if(Array.isArray(n))for(var o=0;o=0&&(m+=e.slice(n,o)),s>=0&&(m+=(n<0?"?":"&")+u.slice(s,p));var v=c(a);return v&&(m+=(n<0&&s<0?"?":"&")+v),r>=0&&(m+=e.slice(r)),d>=0&&(m+=(r<0?"":"&")+u.slice(d)),m},p=function(e,t,r){var o=0;function i(e){return new t(e)}function l(e){return function(n,o){"string"!=typeof n?(o=n,n=n.url):null==o&&(o={});var l=new t((function(t,r){e(d(n,o.params),o,(function(e){if("function"==typeof o.type)if(Array.isArray(e))for(var n=0;n=200&&e.target.status<300||304===e.target.status||/^file:\/\//i.test(t),a=e.target.response;if("json"===f){if(!e.target.responseType&&"function"!=typeof r.extract)try{a=JSON.parse(e.target.responseText)}catch(e){a=null}}else f&&"text"!==f||null==a&&(a=e.target.responseText);if("function"==typeof r.extract?(a=r.extract(e.target,r),l=!0):"function"==typeof r.deserialize&&(a=r.deserialize(a)),l)o(a);else{var u=function(){try{n=e.target.responseText}catch(e){n=a}var t=new Error(n);t.code=e.target.status,t.response=a,i(t)};0===d.status?setTimeout((function(){h||u()})):u()}}catch(e){i(e)}},d.ontimeout=function(e){h=!0;var t=new Error("Request timed out");t.code=e.target.status,i(t)},"function"==typeof r.config&&(d=r.config(d,r,t)||d)!==m&&(l=d.abort,d.abort=function(){p=!0,l.call(this)}),null==s?d.send():"function"==typeof r.serialize?d.send(r.serialize(s)):s instanceof e.FormData||s instanceof e.URLSearchParams?d.send(s):d.send(JSON.stringify(s))})),jsonp:l((function(t,n,r,i){var l=n.callbackName||"_mithril_"+Math.round(1e16*Math.random())+"_"+o++,a=e.document.createElement("script");e[l]=function(t){delete e[l],a.parentNode.removeChild(a),r(t)},a.onerror=function(){delete e[l],a.parentNode.removeChild(a),i(new Error("JSONP request failed"))},a.src=t+(t.indexOf("?")<0?"?":"&")+encodeURIComponent(n.callbackKey||"callback")+"="+encodeURIComponent(l),e.document.documentElement.appendChild(a)}))}}("undefined"!=typeof window?window:null,a,s.redraw),h=s,m=function(){return l.apply(this,arguments)};m.m=l,m.trust=l.trust,m.fragment=l.fragment,m.mount=h.mount;var v=l,y=a,g=function(e){if(""===e||null==e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t=e.split("&"),n={},r={},o=0;o-1&&u.pop();for(var c=0;c1&&"/"===i[i.length-1]&&(i=i.slice(0,-1))):i="/",{path:i,params:t<0?{}:g(e.slice(t+1,r))}},b=function(e){var t=w(e),n=Object.keys(t.params),r=[],o=new RegExp("^"+t.path.replace(/:([^\/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|\[\]{}]/g,(function(e,t,n){return null==t?"\\"+e:(r.push({k:t,r:"..."===n}),"..."===n?"(.*)":"."===n?"([^/]+)\\.":"([^/]+)"+(n||""))}))+"$");return function(e){for(var i=0;i path.resolve(__dirname, "..", file)
+const metaDescriptionRegExp = //m
// Minify our docs.
const htmlMinifierConfig = {
@@ -96,6 +97,26 @@ async function archiveDocsSelect() {
.join("")
return ``
}
+
+function encodeHTML (str) {
+ const charsToEncode = /[&"'<>]/g
+ const encodeTo = {
+ "&": "&",
+ "\"": """,
+ "'": "'",
+ "<": "<",
+ ">": ">",
+ }
+ return str.replace(charsToEncode, function(char) { return encodeTo[char] })
+}
+
+function extractMetaDescription(markdown) {
+ var match = markdown.match(metaDescriptionRegExp)
+ if (match) {
+ return encodeHTML(match[1])
+ }
+ return "Mithril.js Documentation"
+}
class Generator {
constructor(opts) {
this._version = opts.version
@@ -110,7 +131,8 @@ class Generator {
`([ \t]*)(- )(\\[.+?\\]\\(${escapeRegExp(file)}\\))`
)
const src = link.test(this._guides) ? this._guides : this._methods
- let body = markdown
+ const metaDescription = extractMetaDescription(markdown)
+ let body = markdown.replace(metaDescriptionRegExp, "")
// fix pipes in code tags
body = body.replace(/`((?:\S| -> |, )+)(\|)(\S+)`/gim,
@@ -154,6 +176,9 @@ class Generator {
// insert parsed HTML
result = result.replace(/\[body\]/, markedHtml)
+
+ // insert meta description
+ result = result.replace(/\[metaDescription\]/, metaDescription)
// fix anchors
const anchorIds = new Map()
diff --git a/stream/stream.min.js b/stream/stream.min.js
new file mode 100644
index 00000000..bd8197b9
--- /dev/null
+++ b/stream/stream.min.js
@@ -0,0 +1 @@
+!function(){"use strict";t.SKIP={},t.lift=function(){var n=arguments[0];return r(Array.prototype.slice.call(arguments,1)).map((function(t){return n.apply(void 0,t)}))},t.scan=function(n,e,r){var a=r.map((function(r){var a=n(e,r);return a!==t.SKIP&&(e=a),a}));return a(e),a},t.merge=r,t.combine=e,t.scanMerge=function(n,t){var r=n.map((function(n){return n[0]})),a=e((function(){var e=arguments[arguments.length-1];return r.forEach((function(r,a){e.indexOf(r)>-1&&(t=n[a][1](t,r()))})),t}),r);return a(t),a},t["fantasy-land/of"]=t;var n=!1;function t(n){var r,i=[],u=[];function c(e){return arguments.length&&e!==t.SKIP&&(n=e,a(c)&&(c._changing(),c._state="active",i.slice().forEach((function(t,e){a(t)&&t(this[e](n))}),u.slice()))),n}return c.constructor=t,c._state=arguments.length&&n!==t.SKIP?"active":"pending",c._parents=[],c._changing=function(){a(c)&&(c._state="changing"),i.forEach((function(n){n._changing()}))},c._map=function(e,r){var a=r?t():t(e(n));return a._parents.push(c),i.push(a),u.push(e),a},c.map=function(n){return c._map(n,"active"!==c._state)},c.toJSON=function(){return null!=n&&"function"==typeof n.toJSON?n.toJSON():n},c["fantasy-land/map"]=c.map,c["fantasy-land/ap"]=function(n){return e((function(n,t){return n()(t())}),[n,c])},c._unregisterChild=function(n){var t=i.indexOf(n);-1!==t&&(i.splice(t,1),u.splice(t,1))},Object.defineProperty(c,"end",{get:function(){return r||((r=t()).map((function(n){return!0===n&&(c._parents.forEach((function(n){n._unregisterChild(c)})),c._state="ended",c._parents.length=i.length=u.length=0),n})),r)}}),c}function e(n,e){var r=e.every((function(n){if(n.constructor!==t)throw new Error("Ensure that each item passed to stream.combine/stream.merge/lift is a stream.");return"active"===n._state})),a=r?t(n.apply(null,e.concat([e]))):t(),i=[],u=e.map((function(t){return t._map((function(u){return i.push(t),(r||e.every((function(n){return"pending"!==n._state})))&&(r=!0,a(n.apply(null,e.concat([i]))),i=[]),u}),!0)})),c=a.end.map((function(n){!0===n&&(u.forEach((function(n){n.end(!0)})),c.end(!0))}));return a}function r(n){return e((function(){return n.map((function(n){return n()}))}),n)}function a(n){return"pending"===n._state||"active"===n._state||"changing"===n._state}Object.defineProperty(t,"HALT",{get:function(){return n||console.log("HALT is deprecated and has been renamed to SKIP"),n=!0,t.SKIP}}),"undefined"!=typeof module?module.exports=t:"function"!=typeof window.m||"stream"in window.m?window.m={stream:t}:window.m.stream=t}();
\ No newline at end of file