Merge remote-tracking branch 'upstream/rewrite' into rewrite

This commit is contained in:
Barney Carroll 2017-01-04 14:22:38 +00:00
commit ec9e258ae9
14 changed files with 154 additions and 29 deletions

View file

@ -4,7 +4,7 @@
## How do I go about contributing ideas or new features?
Create an [issue thread on Github](https://github.com/lhorie/mithril.js/issues/new) to suggest your idea so the community can discuss it. And don't worry, we're nice :)
Create an [issue thread on Github](https://github.com/lhorie/mithril.js/issues/new) to suggest your idea so the community can discuss it.
If the consensus is that it's a good idea, the fastest way to get it into a release is to send a pull request. Without a PR, the time to implement the feature will depend on the bandwidth of the development team and its list of priorities.

View file

@ -10,6 +10,23 @@
Allows attaching lifecycle methods to a fragment [vnode](vnodes.md)
```javascript
var groupVisible = true
var log = function() {
console.log("group is now visible")
}
m("ul", [
m("li", "child 1"),
m("li", "child 2"),
groupVisible ? m.fragment({oninit: log}, [
// a fragment containing two elements
m("li", "child 3"),
m("li", "child 4"),
]) : null
])
```
---
### Signature

View file

@ -1,5 +1,9 @@
# Framework comparison
- [React](#react)
- [Angular](#angular)
- [Vue](#vue)
If you're reading this page, you probably have used other frameworks to build applications, and you want to know if Mithril would help you solve your problems more effectively.
In this page, you will find common arguments about other frameworks and comments on where Mithril is similar or why it differs from them.

View file

@ -1,7 +1,7 @@
- Tutorials
- [Installation](installation.md)
- [Introduction](introduction.md)
- [Tutorial](tutorial.md)
- [Tutorial](simple-application.md)
- [Testing](testing.md)
- [Examples](examples.md)
- Key concepts
@ -11,7 +11,9 @@
- [Keys](keys.md)
- Social
- [Community chat](https://gitter.im/lhorie/mithril.js)
- [Contributing](contributing.md)
- [Mithril Jobs](https://github.com/lhorie/mithril.js/wiki/JOBS)
- [How to contribute](contributing.md)
- [Credits](credits.md)
- Misc
- [Framework comparison](framework-comparison.md)
- [Change log/Migration](change-log.md)

View file

@ -1,5 +1,8 @@
# Installation
- [CDN](#cdn)
- [NPM](#npm)
### CDN
If you're new to Javascript or just want a very simple setup to get your feet wet, you can get Mithril from a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network):
@ -12,7 +15,7 @@ If you're new to Javascript or just want a very simple setup to get your feet we
### NPM
#### Quick start
#### Quick start with Webpack
```bash
# 1) install
@ -26,8 +29,13 @@ npm install webpack --save
# 3) create an `index.js` file
# 4) run bundler
# 4) create an `index.html` file loading `app.js`
# 5) run bundler
npm run build
# 6) open `index.html` in the (default) browser
open index.html
```
#### Step by step
@ -43,12 +51,14 @@ npm init --yes
# creates a file called package.json
```
Then, run `npm install mithril@rewrite --save` to install Mithril. This will create a folder called `node_modules`, and a `mithril` folder inside of it. It will also add an entry under `dependencies` in the `package.json` file
Then, run
```bash
npm install mithril@rewrite --save
```
to install Mithril. This will create a folder called `node_modules`, and a `mithril` folder inside of it. It will also add an entry under `dependencies` in the `package.json` file
You are now ready to start using Mithril. The recommended way to structure code is to modularize it via CommonJS modules:
```javascript
@ -128,9 +138,33 @@ m.mount(document.body, MyComponent)
Note that in this example, we're using `m.mount`, which wires up the component to Mithril's autoredraw system. In most applications, you will want to use `m.mount` (or `m.route` if your application has multiple screens) instead of `m.render` to take advantage of the autoredraw system, rather than re-rendering manually every time a change occurs.
#### Alternate ways to use Mithril
---
##### Mithril bundler
### Alternate ways to use Mithril
#### Live reload development environment
Live reload is a feature where code changes automatically trigger the page to reload. [Budo](https://github.com/mattdesl/budo) is one tool that enables live reloading.
```bash
# 1) install
npm install mithril@rewrite --save
npm install budo -g
# 2) add this line into the scripts section in package.json
# "scripts": {
# "start": "budo --live --open index.js"
# }
# 3) create an `index.js` file
# 4) run budo
npm start
```
The source file `index.js` will be compiled (bundled) and a browser window opens showing the result. Any changes in the source files will instantly get recompiled and the browser will refresh reflecting the changes.
#### Mithril bundler
Mithril comes with a bundler tool of its own. It is sufficient for projects that have no other dependencies other than Mithril, but it's currently considered experimental for projects that require other NPM dependencies. It produces smaller bundles than webpack, but you should not use it in production yet.
@ -145,7 +179,7 @@ If you want to try it and give feedback, you can open `package.json` and change
}
```
##### Vanilla
#### Vanilla
If you don't have the ability to run a bundler script due to company security policies, there's an options to not use a module system at all:

View file

@ -12,15 +12,16 @@
### What is Mithril?
Mithril is a client-side Javascript framework for building Single Page Applications. It's small and batteries-included.
Mithril is a client-side Javascript framework for building Single Page Applications.
It's small (< 8kb gzip), fast and batteries-included.
If you are an experienced developer and want to know how Mithril compares to other frameworks, see the [framework comparison](framework-comparison.md) page.
---
### Getting started
Note: This introduction assumes you have basic level of Javacript knowledge. If you don't, there are many great resources to learn. [Speaking Javascript](http://speakingjs.com/es5/index.html) is a good e-book for absolute beginners. If you're already familiar with other programming languages, the [Eloquent Javascript](http://eloquentjavascript.net/) e-book might be more suitable for you. [Codecademy](https://www.codecademy.com/learn/javascript) is another good resource that emphasizes learning via interactivity.
This introduction assumes you know Javacript. If you don't, there are many great resources to learn. [Speaking Javascript](http://speakingjs.com/es5/index.html) is a good e-book for absolute beginners. If you're already familiar with other programming languages, the [Eloquent Javascript](http://eloquentjavascript.net/) e-book might be more suitable for you. [Codecademy](https://www.codecademy.com/learn/javascript) is another good resource that emphasizes learning via interactivity.
### Getting started
The easiest way to try out Mithril is to include it from a CDN, and follow this tutorial. It'll cover the majority of the API surface but it'll only take 10 minutes.

View file

@ -132,9 +132,7 @@ users.map(function(u) {
// PREFER
users.map(function(u) {
return {tag: "[", key: u.id, children: [
m("button", u.name)
]}
return m.fragment({key: u.id}, m("button", u.name))
})
```

View file

@ -16,5 +16,4 @@
- Optional
- [Stream](stream.md)
- Tooling
- [Bundler](bundler.md)
- [Ospec](ospec.md)
- [Ospec](https://github.com/lhorie/mithril.js/blob/rewrite/ospec)

View file

@ -5,8 +5,11 @@ nav a {border-left:1px solid #ddd;padding:0 10px;}
nav a:first-child {border:0;padding-left:0;}
main {margin-bottom:100px;}
main section {margin-left:270px;}
h1 {margin:0 0 15px;}
h5 {font-style:italic;}
h1 {font-size:24px;margin:0 0 15px;}
h2 {font-size:22px;margin:30px 0 15px;}
h3 {font-size:20px;margin:30px 0 15px;}
h4 {font-size:18px;margin:15px 0 15px;}
h5 {font-weight:bold;margin:15px 0 15px;}
pre,code {background:#eee;font-family:monospace;}
pre {border-left:3px solid #1e5799;overflow:auto;padding:10px 20px;}
code {border:1px solid #ddd;display:inline-block;margin:0 0 1px;padding:3px;white-space:pre;}

View file

@ -8,11 +8,7 @@ The easist way to setup the test runner is to create an NPM script for it. Open
{
"name": "my-project",
"scripts": {
"build": "bundle index.js --output app.js --watch",
"test": "ospec"
},
"dependencies": {
"mithril": "^1.0.0-rc.5"
}
}
```
@ -48,3 +44,42 @@ Writing tests upfront requires specifications to be frozen. Upfront tests are a
Writing tests after the fact is a way to document the behavior of a system and avoid regressions. They are useful to ensure that obscure corner cases are not inadvertedly broken and that previously fixed bugs do not get re-introduced by unrelated changes.
---
### Unit testing
Unit testing is the practice of isolating a part of an application (typically a single module), and asserting that, given some inputs, it produces the expected outputs.
Testing a Mithril component is easy. Let's assume we have a simple component like this:
```javascript
// MyComponent.js
var m = require("mithril")
module.exports = {
view: function() {
return m("div", "Hello world")
}
}
```
We can then create a `tests/MyComponent.js` file and create a test for this component like this:
```javascript
var MyComponent = require("MyComponent")
o.spec("MyComponent", function() {
o("returns a div", function() {
var vnode = MyComponent.view()
o(vnode.tag).equals("div")
o(vnode.children.length).equals(1)
o(vnode.children[0].tag).equals("#")
o(vnode.children[0].children).equals("Hello world")
})
})
```
Typically, you wouldn't test the structure of the vnode tree so granularly, and you would instead only test non-trivial, dynamic aspects of the view. A tool that can help making testing easier with deep vnode trees is [Mithril Query](https://github.com/StephanHoyer/mithril-query).
Sometimes, you need to mock the dependencies of a module in order to test the module in isolation. [Mockery](https://github.com/mfncooper/mockery) is one tool that allows you to do that.

View file

@ -4,7 +4,7 @@
Noiseless testing framework
Version: 1.2.1
Version: 1.2.2
License: MIT
## About

View file

@ -135,7 +135,7 @@ module.exports = new function init() {
var aIsArgs = isArguments(a), bIsArgs = isArguments(b)
if (a.constructor === Object && b.constructor === Object && !aIsArgs && !bIsArgs) {
for (var i in a) {
if (!deepEqual(a[i], b[i])) return false
if ((!(i in b)) || !deepEqual(a[i], b[i])) return false
}
for (var i in b) {
if (!(i in a)) return false
@ -143,8 +143,10 @@ module.exports = new function init() {
return true
}
if (a.length === b.length && (a instanceof Array && b instanceof Array || aIsArgs && bIsArgs)) {
for (var i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i])) return false
var aKeys = Object.getOwnPropertyNames(a), bKeys = Object.getOwnPropertyNames(b)
if (aKeys.length !== bKeys.length) return false
for (var i = 0; i < aKeys.length; i++) {
if (!b.hasOwnProperty(aKeys[i]) || !deepEqual(a[aKeys[i]], b[aKeys[i]])) return false
}
return true
}

View file

@ -1,6 +1,6 @@
{
"name": "ospec",
"version": "1.2.1",
"version": "1.2.2",
"description": "Noiseless testing framework",
"main": "ospec.js",
"directories": {

View file

@ -8,7 +8,7 @@ new function(o) {
o.spec("ospec", function() {
o("skipped", function() {
o(1).equals(1)
o(true).equals(false)
})
o.only(".only()", function() {
o(2).equals(2)
@ -37,6 +37,36 @@ o.spec("ospec", function() {
o({a: [1, 2], b: 3}).deepEquals({a: [1, 2], b: 3})
o([{a: 1, b: 2}, {c: 3}]).deepEquals([{a: 1, b: 2}, {c: 3}])
var undef1 = {undef: void 0}
var undef2 = {UNDEF: void 0}
o(undef1).notDeepEquals(undef2)
o(undef1).notDeepEquals({})
o({}).notDeepEquals(undef1)
var sparse1 = [void 1, void 2, void 3]
delete sparse1[0]
var sparse2 = [void 1, void 2, void 3]
delete sparse2[1]
o(sparse1).notDeepEquals(sparse2)
var monkeypatch1 = [1, 2]
monkeypatch1.field = 3
var monkeypatch2 = [1, 2]
monkeypatch2.field = 4
o(monkeypatch1).notDeepEquals([1, 2])
o(monkeypatch1).notDeepEquals(monkeypatch2)
monkeypatch2.field = 3
o(monkeypatch1).deepEquals(monkeypatch2)
monkeypatch1.undef = undefined
monkeypatch2.UNDEF = undefined
o(monkeypatch1).notDeepEquals(monkeypatch2)
var values = ["a", "", 1, 0, true, false, null, undefined, Date(0), ["a"], [], function() {return arguments}.call(), new Uint8Array(), {a: 1}, {}]
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values.length; j++) {