Skip to content

Commit

Permalink
Officially drop IE9-10 support, pull out our hacks [skip ci]
Browse files Browse the repository at this point in the history
- I also fixed a bunch of related comments
- Drive-by: update transpiling info in CONTRIBUTING.md
- Drive-by: we aren't the only ones going semicolon-free
  • Loading branch information
dead-claudia committed Nov 14, 2018
1 parent 76e585c commit 99c722d
Show file tree
Hide file tree
Showing 7 changed files with 16 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -22,7 +22,7 @@ A modern client-side Javascript framework for building Single Page Applications.

Mithril is used by companies like Vimeo and Nike, and open source platforms like Lichess 👍.

Browsers all the way back to IE9 are supported, no polyfills required 👌.
Mithril supports IE11, Firefox ESR, and the last two versions of Firefox, Edge, Safari, and Chrome. No polyfills required. 👌

## Installation

Expand Down
11 changes: 3 additions & 8 deletions api/redraw.js
Expand Up @@ -3,18 +3,13 @@
var coreRenderer = require("../render/render")

function throttle(callback) {
//60fps translates to 16.6ms, round it down since setTimeout requires int
var delay = 16
var last = 0, pending = null
var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
var pending = null
return function() {
var elapsed = Date.now() - last
if (pending === null) {
pending = timeout(function() {
pending = requestAnimationFrame(function() {
pending = null
callback()
last = Date.now()
}, delay - elapsed)
})
}
}
}
Expand Down
8 changes: 3 additions & 5 deletions docs/contributing.md
Expand Up @@ -79,17 +79,15 @@ This simplifies the workflow for bug fixes, which means they can be fixed faster



## Why doesn't the Mithril codebase use ES6 via Babel? Would a PR to upgrade be welcome?
## Why doesn't the Mithril codebase use ES6 via Babel or Bublé? Would a PR to upgrade be welcome?

Being able to run Mithril raw source code in IE is a requirement for all browser-related modules in this repo.

In addition, ES6 features are usually less performant than equivalent ES5 code, and transpiled code is bulkier.
Being able to run Mithril's raw source code in all supported browsers is a requirement for all browser-related modules in this repo. In addition, transpiled code is generally much bulkier.



## Why doesn't the Mithril codebase use trailing semi-colons? Would a PR to add them be welcome?

I don't use them. Adding them means the semi-colon usage in the codebase will eventually become inconsistent.
I don't use them. Adding them means the semi-colon usage in the codebase will eventually become inconsistent. Besides, [we aren't the only one who've decided to drop the semicolon](https://standardjs.com/#who-uses-javascript-standard-style). (We don't use Standard, though.)



Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Expand Up @@ -44,7 +44,7 @@ Mithril is used by companies like Vimeo and Nike, and open source platforms like

If you are an experienced developer and want to know how Mithril compares to other frameworks, see the [framework comparison](framework-comparison.md) page.

Mithril supports browsers all the way back to IE9, no polyfills required.
Mithril supports IE11, Firefox ESR, and the last two versions of Firefox, Edge, Safari, and Chrome. No polyfills required.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/redraw.md
Expand Up @@ -44,12 +44,12 @@ When callbacks outside of Mithril run, you need to notify Mithril's rendering en

To trigger a redraw, call `m.redraw()`. Note that `m.redraw` only works if you used `m.mount` or `m.route`. If you rendered via `m.render`, you should use `m.render` to redraw.

`m.redraw()` always triggers an asynchronous redraws, whereas `m.redraw.sync()` triggers a synchronous one. `m.redraw()` is tied to `window.requestAnimationFrame()` (we provide a fallback for IE9). It will thus typically fire at most 60 times per second. It may fire faster if your monitor has a higher refresh rate.
`m.redraw()` always triggers an asynchronous redraws, whereas `m.redraw.sync()` triggers a synchronous one. `m.redraw()` is tied to `window.requestAnimationFrame()`. It will thus typically fire at most 60 times per second. It may fire faster if your monitor has a higher refresh rate.

`m.redraw.sync()` is mostly intended to make videos play work in iOS. That only works in response to user-triggered events. It comes with several caveat:

- You should not call `m.redraw.sync()` from a [lifecycle method](lifecycle-methods.md) or the `view()` method of a component. Doing so will result in undefined behavior (it throws an error when possible).
- `m.redraw.sync()` called from an event handler can cause the DOM to be modified while an event is bubbling. Depending on the structure of the old and new DOM trees, the event can finish the bubbling phase in the new tree and trigger unwanted handlers.
- It is not throttled. One call to `m.redraw.sync()` causes immediately one `m.render()` call per root registered with [`m.mount()`](mount.md) or [`m.route()`](route.md).

`m.redraw()` doesn't have any of those issues, you can call it from wherever you like.
`m.redraw()` doesn't have any of those issues, you can call it from wherever you like.
6 changes: 3 additions & 3 deletions docs/route.md
Expand Up @@ -218,11 +218,11 @@ The routing strategy dictates how a library might actually implement routing. Th
- Using the querystring. A URL using this strategy typically looks like `http://localhost/?/page1`
- Using the pathname. A URL using this strategy typically looks like `http://localhost/page1`

Using the hash strategy is guaranteed to work in browsers that don't support `history.pushState` (namely, Internet Explorer 9), because it can fall back to using `onhashchange`. Use this strategy if you want to support IE9.
Using the hash strategy is guaranteed to work in browsers that don't support `history.pushState`, because it can fall back to using `onhashchange`. Use this strategy if you want to keep the hashes purely local.

The querystring strategy also technically works in IE9, but it falls back to reloading the page. Use this strategy if you want to support anchored links and you are not able to make the server-side necessary to support the pathname strategy.
The querystring strategy allows server-side detection, but it doesn't appear as a normal path. Use this strategy if you want to support and potentially detect anchored links server-side and you are not able to make the changes necessary to support the pathname strategy (like if you're using Apache and can't modify your .htaccess).

The pathname strategy produces the cleanest looking URLs, but does not work in IE9 *and* requires setting up the server to serve the single page application code from every URL that the application can route to. Use this strategy if you want cleaner-looking URLs and do not need to support IE9.
The pathname strategy produces the cleanest looking URLs, but requires setting up the server to serve the single page application code from every URL that the application can route to. Use this strategy if you want cleaner-looking URLs.

Single page applications that use the hash strategy often use the convention of having an exclamation mark after the hash to indicate that they're using the hash as a routing mechanism and not for the purposes of linking to anchors. The `#!` string is known as a *hashbang*.

Expand Down
6 changes: 3 additions & 3 deletions render/render.js
Expand Up @@ -35,7 +35,7 @@ module.exports = function($window) {
}
}

// IE9 - IE11 (at least) throw an UnspecifiedError when accessing document.activeElement when
// IE11 (at least) throws an UnspecifiedError when accessing document.activeElement when
// inside an iframe. Catch and swallow this error, and heavy-handidly return null.
function activeElement() {
try {
Expand Down Expand Up @@ -255,7 +255,7 @@ module.exports = function($window) {
// When the list is being traversed top-down, at any index, the DOM nodes up to the previous
// vnode reflect the content of the new list, whereas the rest of the DOM nodes reflect the old
// list. The next sibling must be looked for in the old list using `getNextSibling(... oldStart + 1 ...)`.
//
//
// In the other scenarios (swaps, upwards traversal, map-based diff),
// the new vnodes list is traversed upwards. The DOM nodes at the bottom of the list reflect the
// bottom part of the new vnodes list, and we can use the `v.dom` value of the previous node
Expand Down Expand Up @@ -880,7 +880,7 @@ module.exports = function($window) {
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 in IE https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
// `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]()
}
Expand Down

0 comments on commit 99c722d

Please sign in to comment.