A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/vuejs/vue/commit/6e41679a96582da3e0a60bdbf123c33ba0e86b31 below:

use MessageChannel for nextTick · vuejs/vue@6e41679 · GitHub

File tree Expand file treeCollapse file tree 5 files changed

+113

-46

lines changed

Filter options

Expand file treeCollapse file tree 5 files changed

+113

-46

lines changed Original file line number Diff line number Diff line change

@@ -1,7 +1,6 @@

1 1

/* @flow */

2 -

/* globals MutationObserver */

2 +

/* globals MessageChannel */

3 3 4 -

import { noop } from 'shared/util'

5 4

import { handleError } from './error'

6 5 7 6

// can we use __proto__?

@@ -80,41 +79,29 @@ export const nextTick = (function () {

80 79

}

81 80

}

82 81 83 -

// the nextTick behavior leverages the microtask queue, which can be accessed

84 -

// via either native Promise.then or MutationObserver.

85 -

// MutationObserver has wider support, however it is seriously bugged in

86 -

// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It

87 -

// completely stops working after triggering a few times... so, if native

88 -

// Promise is available, we will use it:

89 -

/* istanbul ignore if */ // $flow-disable-line

90 -

if (typeof Promise !== 'undefined' && isNative(Promise)) {

91 -

var p = Promise.resolve()

92 -

var logError = err => { handleError(err, null, 'nextTick') }

82 +

// An asynchronous deferring mechanism.

83 +

// In pre 2.4, we used to use microtasks (Promise/MutationObserver)

84 +

// but microtasks actually has too high a priority and fires in between

85 +

// supposedly sequential events (e.g. #4521, #6690) or even between

86 +

// bubbling of the same event (#6566). Technically setImmediate should be

87 +

// the ideal choice, but it's not available everywhere; and the only polyfill

88 +

// that consistently queues the callback after all DOM events triggered in the

89 +

// same loop is by using MessageChannel.

90 +

/* istanbul ignore if */

91 +

if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {

93 92

timerFunc = () => {

94 -

p.then(nextTickHandler).catch(logError)

95 -

// in problematic UIWebViews, Promise.then doesn't completely break, but

96 -

// it can get stuck in a weird state where callbacks are pushed into the

97 -

// microtask queue but the queue isn't being flushed, until the browser

98 -

// needs to do some other work, e.g. handle a timer. Therefore we can

99 -

// "force" the microtask queue to be flushed by adding an empty timer.

100 -

if (isIOS) setTimeout(noop)

93 +

setImmediate(nextTickHandler)

101 94

}

102 -

} else if (!isIE && typeof MutationObserver !== 'undefined' && (

103 -

isNative(MutationObserver) ||

104 -

// PhantomJS and iOS 7.x

105 -

MutationObserver.toString() === '[object MutationObserverConstructor]'

95 +

} else if (typeof MessageChannel !== 'undefined' && (

96 +

isNative(MessageChannel) ||

97 +

// PhantomJS

98 +

MessageChannel.toString() === '[object MessageChannelConstructor]'

106 99

)) {

107 -

// use MutationObserver where native Promise is not available,

108 -

// e.g. PhantomJS, iOS7, Android 4.4

109 -

var counter = 1

110 -

var observer = new MutationObserver(nextTickHandler)

111 -

var textNode = document.createTextNode(String(counter))

112 -

observer.observe(textNode, {

113 -

characterData: true

114 -

})

100 +

const channel = new MessageChannel()

101 +

const port = channel.port2

102 +

channel.port1.onmessage = nextTickHandler

115 103

timerFunc = () => {

116 -

counter = (counter + 1) % 2

117 -

textNode.data = String(counter)

104 +

port.postMessage(1)

118 105

}

119 106

} else {

120 107

// fallback to setTimeout

Original file line number Diff line number Diff line change

@@ -9,7 +9,6 @@ let warn

9 9

// in some cases, the event used has to be determined at runtime

10 10

// so we used some reserved tokens during compile.

11 11

export const RANGE_TOKEN = '__r'

12 -

export const CHECKBOX_RADIO_TOKEN = '__c'

13 12 14 13

export default function model (

15 14

el: ASTElement,

@@ -86,7 +85,7 @@ function genCheckboxModel (

86 85

: `:_q(${value},${trueValueBinding})`

87 86

)

88 87

)

89 -

addHandler(el, CHECKBOX_RADIO_TOKEN,

88 +

addHandler(el, 'change',

90 89

`var $$a=${value},` +

91 90

'$$el=$event.target,' +

92 91

`$$c=$$el.checked?(${trueValueBinding}):(${falseValueBinding});` +

@@ -109,7 +108,7 @@ function genRadioModel (

109 108

let valueBinding = getBindingAttr(el, 'value') || 'null'

110 109

valueBinding = number ? `_n(${valueBinding})` : valueBinding

111 110

addProp(el, 'checked', `_q(${value},${valueBinding})`)

112 -

addHandler(el, CHECKBOX_RADIO_TOKEN, genAssignmentCode(value, valueBinding), null, true)

111 +

addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true)

113 112

}

114 113 115 114

function genSelect (

Original file line number Diff line number Diff line change

@@ -2,28 +2,21 @@

2 2 3 3

import { isDef, isUndef } from 'shared/util'

4 4

import { updateListeners } from 'core/vdom/helpers/index'

5 -

import { isChrome, isIE, supportsPassive } from 'core/util/env'

6 -

import { RANGE_TOKEN, CHECKBOX_RADIO_TOKEN } from 'web/compiler/directives/model'

5 +

import { isIE, supportsPassive } from 'core/util/env'

6 +

import { RANGE_TOKEN } from 'web/compiler/directives/model'

7 7 8 8

// normalize v-model event tokens that can only be determined at runtime.

9 9

// it's important to place the event as the first in the array because

10 10

// the whole point is ensuring the v-model callback gets called before

11 11

// user-attached handlers.

12 12

function normalizeEvents (on) {

13 -

let event

14 13

/* istanbul ignore if */

15 14

if (isDef(on[RANGE_TOKEN])) {

16 15

// IE input[type=range] only supports `change` event

17 -

event = isIE ? 'change' : 'input'

16 +

const event = isIE ? 'change' : 'input'

18 17

on[event] = [].concat(on[RANGE_TOKEN], on[event] || [])

19 18

delete on[RANGE_TOKEN]

20 19

}

21 -

if (isDef(on[CHECKBOX_RADIO_TOKEN])) {

22 -

// Chrome fires microtasks in between click/change, leads to #4521

23 -

event = isChrome ? 'click' : 'change'

24 -

on[event] = [].concat(on[CHECKBOX_RADIO_TOKEN], on[event] || [])

25 -

delete on[CHECKBOX_RADIO_TOKEN]

26 -

}

27 20

}

28 21 29 22

let target: HTMLElement

Original file line number Diff line number Diff line change

@@ -0,0 +1,54 @@

1 +

<!DOCTYPE html>

2 +

<html lang="en">

3 +

<head>

4 +

<meta charset="utf-8">

5 +

<title></title>

6 +

<script src="../../../dist/vue.min.js"></script>

7 +

</head>

8 +

<body>

9 + 10 +

<!-- #4510 click and change event on checkbox -->

11 +

<div id="case-1">

12 +

<div @click="num++">

13 +

{{ num }}

14 +

<input type="checkbox" v-model="checked">

15 +

</div>

16 +

</div>

17 +

<script>

18 +

var vm1 = new Vue({

19 +

el: '#case-1',

20 +

data: {

21 +

num: 1,

22 +

checked: false

23 +

}

24 +

})

25 +

</script>

26 + 27 +

<!-- #6566 click event bubbling -->

28 +

<div id="case-2">

29 +

<div v-if="expand">

30 +

<button @click="expand = false, countA++">Expand is True</button>

31 +

</div>

32 +

<div class="header" v-if="!expand" @click="expand = true, countB++">

33 +

<button>Expand is False</button>

34 +

</div>

35 +

<div class="count-a">

36 +

countA: {{countA}}

37 +

</div>

38 +

<div class="count-b">

39 +

countB: {{countB}}

40 +

</div>

41 +

</div>

42 +

<script>

43 +

var vm2 = new Vue({

44 +

el: '#case-2',

45 +

data: {

46 +

expand: true,

47 +

countA: 0,

48 +

countB: 0,

49 +

}

50 +

})

51 +

</script>

52 + 53 +

</body>

54 +

</html>

Original file line number Diff line number Diff line change

@@ -0,0 +1,34 @@

1 +

module.exports = {

2 +

'async edge cases': function (browser) {

3 +

browser

4 +

.url('http://localhost:8080/test/e2e/specs/async-edge-cases.html')

5 +

// #4510

6 +

.assert.containsText('#case-1', '1')

7 +

.assert.checked('#case-1 input', false)

8 + 9 +

.click('#case-1 input')

10 +

.assert.containsText('#case-1', '2')

11 +

.assert.checked('#case-1 input', true)

12 + 13 +

.click('#case-1 input')

14 +

.assert.containsText('#case-1', '3')

15 +

.assert.checked('#case-1 input', false)

16 + 17 +

// #6566

18 +

.assert.containsText('#case-2 button', 'Expand is True')

19 +

.assert.containsText('.count-a', 'countA: 0')

20 +

.assert.containsText('.count-b', 'countB: 0')

21 + 22 +

.click('#case-2 button')

23 +

.assert.containsText('#case-2 button', 'Expand is False')

24 +

.assert.containsText('.count-a', 'countA: 1')

25 +

.assert.containsText('.count-b', 'countB: 0')

26 + 27 +

.click('#case-2 button')

28 +

.assert.containsText('#case-2 button', 'Expand is True')

29 +

.assert.containsText('.count-a', 'countA: 1')

30 +

.assert.containsText('.count-b', 'countB: 1')

31 + 32 +

.end()

33 +

}

34 +

}

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4