Or, a lot of things yet again.
1. Prototypes are avoided. Method definitions are avoided at all costs in the
renderer. C-like structs are exclusively used internally. This helps
significantly in both speed and size.
2. The deferred implementation had a couple functions refactored into static
equivalents.
3. Only 1 test fails now.
4. Several names were changed to be much smaller. Some of the exports were
aliased. This was a pure size improvement for free.
5. Regexes are inlined. It's better to let the engine do the caching.
6. The version string was inlined. It's still at the top.
7. `this` is avoided as much as possible in the rendering.
Note that this does *not* memoize `then`, another deviation from spec, but
it's unlikely this will actually cause very many bugs. It's also a breaking
change.
This mostly isolates the implementations for both of these. Now, everything
here calls the method itself, not any of the external methods.
Few driveby fixes as well:
1. Git now ignores archive/ again (it's a build artifact, and can be removed
when updating `master`)
2. Since I had to rewrite most of the Deferred implementation, the new version
passes one of the skipped tests, so it is now enabled.
This changes enough things to merit a new patch release. It changed a few
implementation details in the process, but it's at least much cleaner.
Be ready for every other currently outstanding PR for this file to have merge
conflicts.
Background:
In ES6 we now have `Object.setPrototypeOf` which makes prototype delegation an alternative to *sugary*, fake class coding patterns. This can be accomplished in ES5, but ES6 is much more elegant. Here is a basic example. `new` is never used and `this` is very easy to follow.
Working example with changes to mithril.js on lines 854, 858, 859 *only*.
http://jsbin.com/nopugo/1/edit?js,console,output
```javascript
'use strict'
const m = require('mithril')
const DataModel = {
data: [1,2,3],
getData(){
console.log('getting data from server')
return this.data
},
postData(val){
console.log('sending data to server')
this.data.push(val)
}
}
const ViewModel = {
filterEvenData: function() {
return this.getData().filter((val) => (val % 2 === 0) && (+val !== 0))
},
addNewData: function(val){
console.log('adding new data', val)
this.postData(val)
}
}
var Model = Object.setPrototypeOf(ViewModel, DataModel)
const App = {
controller(){},
view(ctrl){
return m('div', [
m('pre', [ 'EVEN NUMBERS IN DATA\n',
this.filterEvenData().map((key,i) =>`${i+1} = ${key}\n`)
]),
m('div', 'Enter a number'),
m('input[placeholder=number]', {
// addNewData is called with **this** === undefined unless we pass `this` to Function.prototype.call in m.withAttr
onchange: m.withAttr('value', App.addNewData, App),
value: null
}
)
])
}
}
Object.setPrototypeOf(App, Model)
m.mount(document.body, App)
```
When a null component is passed into m.mount(), remove references to the root DOM element from:
- roots
- cellCache
- nodeCache
And remove the associated entries from:
- controllers
- components