aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/platforms/web/runtime/directives
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vue/src/platforms/web/runtime/directives')
-rw-r--r--node_modules/vue/src/platforms/web/runtime/directives/index.js7
-rw-r--r--node_modules/vue/src/platforms/web/runtime/directives/model.js147
-rw-r--r--node_modules/vue/src/platforms/web/runtime/directives/show.js60
3 files changed, 214 insertions, 0 deletions
diff --git a/node_modules/vue/src/platforms/web/runtime/directives/index.js b/node_modules/vue/src/platforms/web/runtime/directives/index.js
new file mode 100644
index 00000000..b673f11a
--- /dev/null
+++ b/node_modules/vue/src/platforms/web/runtime/directives/index.js
@@ -0,0 +1,7 @@
+import model from './model'
+import show from './show'
+
+export default {
+ model,
+ show
+}
diff --git a/node_modules/vue/src/platforms/web/runtime/directives/model.js b/node_modules/vue/src/platforms/web/runtime/directives/model.js
new file mode 100644
index 00000000..cba8ded0
--- /dev/null
+++ b/node_modules/vue/src/platforms/web/runtime/directives/model.js
@@ -0,0 +1,147 @@
+/**
+ * Not type checking this file because flow doesn't like attaching
+ * properties to Elements.
+ */
+
+import { isTextInputType } from 'web/util/element'
+import { looseEqual, looseIndexOf } from 'shared/util'
+import { mergeVNodeHook } from 'core/vdom/helpers/index'
+import { warn, isIE9, isIE, isEdge } from 'core/util/index'
+
+/* istanbul ignore if */
+if (isIE9) {
+ // http://www.matts411.com/post/internet-explorer-9-oninput/
+ document.addEventListener('selectionchange', () => {
+ const el = document.activeElement
+ if (el && el.vmodel) {
+ trigger(el, 'input')
+ }
+ })
+}
+
+const directive = {
+ inserted (el, binding, vnode, oldVnode) {
+ if (vnode.tag === 'select') {
+ // #6903
+ if (oldVnode.elm && !oldVnode.elm._vOptions) {
+ mergeVNodeHook(vnode, 'postpatch', () => {
+ directive.componentUpdated(el, binding, vnode)
+ })
+ } else {
+ setSelected(el, binding, vnode.context)
+ }
+ el._vOptions = [].map.call(el.options, getValue)
+ } else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
+ el._vModifiers = binding.modifiers
+ if (!binding.modifiers.lazy) {
+ el.addEventListener('compositionstart', onCompositionStart)
+ el.addEventListener('compositionend', onCompositionEnd)
+ // Safari < 10.2 & UIWebView doesn't fire compositionend when
+ // switching focus before confirming composition choice
+ // this also fixes the issue where some browsers e.g. iOS Chrome
+ // fires "change" instead of "input" on autocomplete.
+ el.addEventListener('change', onCompositionEnd)
+ /* istanbul ignore if */
+ if (isIE9) {
+ el.vmodel = true
+ }
+ }
+ }
+ },
+
+ componentUpdated (el, binding, vnode) {
+ if (vnode.tag === 'select') {
+ setSelected(el, binding, vnode.context)
+ // in case the options rendered by v-for have changed,
+ // it's possible that the value is out-of-sync with the rendered options.
+ // detect such cases and filter out values that no longer has a matching
+ // option in the DOM.
+ const prevOptions = el._vOptions
+ const curOptions = el._vOptions = [].map.call(el.options, getValue)
+ if (curOptions.some((o, i) => !looseEqual(o, prevOptions[i]))) {
+ // trigger change event if
+ // no matching option found for at least one value
+ const needReset = el.multiple
+ ? binding.value.some(v => hasNoMatchingOption(v, curOptions))
+ : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions)
+ if (needReset) {
+ trigger(el, 'change')
+ }
+ }
+ }
+ }
+}
+
+function setSelected (el, binding, vm) {
+ actuallySetSelected(el, binding, vm)
+ /* istanbul ignore if */
+ if (isIE || isEdge) {
+ setTimeout(() => {
+ actuallySetSelected(el, binding, vm)
+ }, 0)
+ }
+}
+
+function actuallySetSelected (el, binding, vm) {
+ const value = binding.value
+ const isMultiple = el.multiple
+ if (isMultiple && !Array.isArray(value)) {
+ process.env.NODE_ENV !== 'production' && warn(
+ `<select multiple v-model="${binding.expression}"> ` +
+ `expects an Array value for its binding, but got ${
+ Object.prototype.toString.call(value).slice(8, -1)
+ }`,
+ vm
+ )
+ return
+ }
+ let selected, option
+ for (let i = 0, l = el.options.length; i < l; i++) {
+ option = el.options[i]
+ if (isMultiple) {
+ selected = looseIndexOf(value, getValue(option)) > -1
+ if (option.selected !== selected) {
+ option.selected = selected
+ }
+ } else {
+ if (looseEqual(getValue(option), value)) {
+ if (el.selectedIndex !== i) {
+ el.selectedIndex = i
+ }
+ return
+ }
+ }
+ }
+ if (!isMultiple) {
+ el.selectedIndex = -1
+ }
+}
+
+function hasNoMatchingOption (value, options) {
+ return options.every(o => !looseEqual(o, value))
+}
+
+function getValue (option) {
+ return '_value' in option
+ ? option._value
+ : option.value
+}
+
+function onCompositionStart (e) {
+ e.target.composing = true
+}
+
+function onCompositionEnd (e) {
+ // prevent triggering an input event for no reason
+ if (!e.target.composing) return
+ e.target.composing = false
+ trigger(e.target, 'input')
+}
+
+function trigger (el, type) {
+ const e = document.createEvent('HTMLEvents')
+ e.initEvent(type, true, true)
+ el.dispatchEvent(e)
+}
+
+export default directive
diff --git a/node_modules/vue/src/platforms/web/runtime/directives/show.js b/node_modules/vue/src/platforms/web/runtime/directives/show.js
new file mode 100644
index 00000000..17fb5dec
--- /dev/null
+++ b/node_modules/vue/src/platforms/web/runtime/directives/show.js
@@ -0,0 +1,60 @@
+/* @flow */
+
+import { enter, leave } from '../modules/transition'
+
+// recursively search for possible transition defined inside the component root
+function locateNode (vnode: VNode): VNodeWithData {
+ return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
+ ? locateNode(vnode.componentInstance._vnode)
+ : vnode
+}
+
+export default {
+ bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
+ vnode = locateNode(vnode)
+ const transition = vnode.data && vnode.data.transition
+ const originalDisplay = el.__vOriginalDisplay =
+ el.style.display === 'none' ? '' : el.style.display
+ if (value && transition) {
+ vnode.data.show = true
+ enter(vnode, () => {
+ el.style.display = originalDisplay
+ })
+ } else {
+ el.style.display = value ? originalDisplay : 'none'
+ }
+ },
+
+ update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
+ /* istanbul ignore if */
+ if (!value === !oldValue) return
+ vnode = locateNode(vnode)
+ const transition = vnode.data && vnode.data.transition
+ if (transition) {
+ vnode.data.show = true
+ if (value) {
+ enter(vnode, () => {
+ el.style.display = el.__vOriginalDisplay
+ })
+ } else {
+ leave(vnode, () => {
+ el.style.display = 'none'
+ })
+ }
+ } else {
+ el.style.display = value ? el.__vOriginalDisplay : 'none'
+ }
+ },
+
+ unbind (
+ el: any,
+ binding: VNodeDirective,
+ vnode: VNodeWithData,
+ oldVnode: VNodeWithData,
+ isDestroy: boolean
+ ) {
+ if (!isDestroy) {
+ el.style.display = el.__vOriginalDisplay
+ }
+ }
+}