1
1
/* @flow */
2
2
3
- /* global MutationObserver */
4
3
// can we use __proto__?
5
4
export const hasProto = '__proto__' in { }
6
5
@@ -9,40 +8,24 @@ export const inBrowser =
9
8
typeof window !== 'undefined' &&
10
9
Object . prototype . toString . call ( window ) !== '[object Object]'
11
10
12
- // detect devtools
13
- export const devtools = inBrowser && window . __VUE_DEVTOOLS_GLOBAL_HOOK__
14
-
15
- // UA sniffing for working around browser-specific quirks
16
11
export const UA = inBrowser && window . navigator . userAgent . toLowerCase ( )
17
- const isIos = UA && / ( i p h o n e | i p a d | i p o d | i o s ) / i . test ( UA )
18
- const iosVersionMatch = UA && isIos && UA . match ( / o s ( [ \d _ ] + ) / )
19
- const iosVersion = iosVersionMatch && iosVersionMatch [ 1 ] . split ( '_' ) . map ( Number )
12
+ export const isIE = UA && / m s i e | t r i d e n t / . test ( UA )
13
+ export const isIE9 = UA && UA . indexOf ( 'msie 9.0' ) > 0
14
+ export const isAndroid = UA && UA . indexOf ( 'android' ) > 0
20
15
21
- // MutationObserver is unreliable in iOS 9.3 UIWebView
22
- // detecting it by checking presence of IndexedDB
23
- // ref #3027
24
- const hasMutationObserverBug =
25
- iosVersion &&
26
- ! window . indexedDB && (
27
- iosVersion [ 0 ] > 9 || (
28
- iosVersion [ 0 ] === 9 &&
29
- iosVersion [ 1 ] >= 3
30
- )
31
- )
16
+ // detect devtools
17
+ export const devtools = inBrowser && window . __VUE_DEVTOOLS_GLOBAL_HOOK__
32
18
33
19
/**
34
20
* Defer a task to execute it asynchronously. Ideally this
35
- * should be executed as a microtask, so we leverage
36
- * MutationObserver if it's available, and fallback to
37
- * setTimeout(0).
38
- *
39
- * @param {Function } cb
40
- * @param {Object } ctx
21
+ * should be executed as a microtask, but MutationObserver is unreliable
22
+ * in iOS UIWebView so we use a setImmediate shim and fallback to setTimeout.
41
23
*/
42
24
export const nextTick = ( function ( ) {
43
25
let callbacks = [ ]
44
26
let pending = false
45
27
let timerFunc
28
+
46
29
function nextTickHandler ( ) {
47
30
pending = false
48
31
const copies = callbacks . slice ( 0 )
@@ -53,27 +36,24 @@ export const nextTick = (function () {
53
36
}
54
37
55
38
/* istanbul ignore else */
56
- if ( typeof MutationObserver !== 'undefined' && ! hasMutationObserverBug ) {
57
- var counter = 1
58
- var observer = new MutationObserver ( nextTickHandler )
59
- var textNode = document . createTextNode ( String ( counter ) )
60
- observer . observe ( textNode , {
61
- characterData : true
39
+ if ( inBrowser && window . postMessage &&
40
+ ! window . importScripts && // not in WebWorker
41
+ ! ( isAndroid && ! window . requestAnimationFrame ) // not in Android <= 4.3
42
+ ) {
43
+ const NEXT_TICK_TOKEN = '__vue__nextTick__'
44
+ window . addEventListener ( 'message' , e => {
45
+ if ( e . source === window && e . data === NEXT_TICK_TOKEN ) {
46
+ nextTickHandler ( )
47
+ }
62
48
} )
63
- timerFunc = function ( ) {
64
- counter = ( counter + 1 ) % 2
65
- textNode . data = String ( counter )
49
+ timerFunc = ( ) => {
50
+ window . postMessage ( NEXT_TICK_TOKEN , '*' )
66
51
}
67
52
} else {
68
- // webpack attempts to inject a shim for setImmediate
69
- // if it is used as a global, so we have to work around that to
70
- // avoid bundling unnecessary code.
71
- var context = inBrowser
72
- ? window
73
- : typeof global !== 'undefined' ? global : { }
74
- timerFunc = context . setImmediate || setTimeout
53
+ timerFunc = ( typeof global !== 'undefined' && global . setImmediate ) || setTimeout
75
54
}
76
- return function ( cb : Function , ctx ?: Object ) {
55
+
56
+ return function queueNextTick ( cb : Function , ctx ?: Object ) {
77
57
const func = ctx
78
58
? function ( ) { cb . call ( ctx ) }
79
59
: cb
0 commit comments