This commit is contained in:
Evan You 2016-04-12 18:30:40 -04:00
parent fe3761aad6
commit 68c99b26f2
18 changed files with 146 additions and 435 deletions

9
.eslintrc.js Normal file
View File

@ -0,0 +1,9 @@
module.exports = {
root: true,
extends: 'standard',
'rules': {
'arrow-parens': 0,
'no-new-func': 0,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}

View File

@ -6,7 +6,8 @@
"scripts": {
"dev": "webpack --watch",
"test": "mocha",
"build": "NODE_ENV=production node build/build.js"
"build": "NODE_ENV=production node build/build.js",
"lint": "eslint src"
},
"repository": {
"type": "git",
@ -27,6 +28,11 @@
"babel-preset-es2015": "^6.0.0",
"babel-preset-es2015-rollup": "^1.1.1",
"babel-preset-stage-2": "^6.0.0",
"eslint": "^2.7.0",
"eslint-config-standard": "^5.1.0",
"eslint-loader": "^1.3.0",
"eslint-plugin-promise": "^1.1.0",
"eslint-plugin-standard": "^1.3.2",
"rollup": "^0.25.8",
"rollup-plugin-alias": "^1.0.2",
"rollup-plugin-babel": "^2.4.0",

View File

@ -49,7 +49,7 @@ export function genEvents (events) {
function genHandler (handler) {
if (!handler) {
return `function(){}`
return 'function(){}'
} else if (isArray(handler)) {
return `[${handler.map(genHandler).join(',')}]`
} else if (!handler.modifiers || !handler.modifiers.length) {

View File

@ -1,6 +1,6 @@
export function getAndRemoveAttr (el, attr) {
let val
if (val = el.attrsMap[attr]) {
if ((val = el.attrsMap[attr])) {
el.attrsMap[attr] = null
for (let i = 0, l = el.attrs.length; i < l; i++) {
if (el.attrs[i].name === attr) {
@ -32,17 +32,14 @@ export function parseText (text) {
}
var tokens = []
var lastIndex = tagRE.lastIndex = 0
var match, index, value
/* eslint-disable no-cond-assign */
while (match = tagRE.exec(text)) {
/* eslint-enable no-cond-assign */
var match, index
while ((match = tagRE.exec(text))) {
index = match.index
// push text token
if (index > lastIndex) {
tokens.push(JSON.stringify(text.slice(lastIndex, index)))
}
// tag token
value = match[1]
tokens.push('(' + match[1].trim() + ')')
lastIndex = index + match[0].length
}

View File

@ -14,19 +14,19 @@ const mustUsePropsRE = /^(value|selected|checked|muted)$/
export function generate (ast) {
const code = genElement(ast)
return new Function (`with (this) { return ${code}}`)
return new Function(`with (this) { return ${code}}`)
}
function genElement (el, key) {
let exp
if (exp = getAndRemoveAttr(el, 'v-for')) {
if ((exp = getAndRemoveAttr(el, 'v-for'))) {
return genFor(el, exp)
} else if (exp = getAndRemoveAttr(el, 'v-if')) {
} else if ((exp = getAndRemoveAttr(el, 'v-if'))) {
return genIf(el, exp)
} else if (el.tag === 'template') {
return genChildren(el)
} else {
return `__h__('${el.tag}', ${genData(el, key) }, ${genChildren(el)})`
return `__h__('${el.tag}', ${genData(el, key)}, ${genChildren(el)})`
}
}
@ -37,13 +37,13 @@ function genIf (el, exp) {
function genFor (el, exp) {
const inMatch = exp.match(/([a-zA-Z_][\w]*)\s+(?:in|of)\s+(.*)/)
if (!inMatch) {
throw new Error('Invalid v-for expression: '+ exp)
throw new Error('Invalid v-for expression: ' + exp)
}
const alias = inMatch[1].trim()
exp = inMatch[2].trim()
let key = getAndRemoveAttr(el, 'track-by')
if (!key) {
key ='undefined'
key = 'undefined'
} else if (key !== '$index') {
key = alias + '["' + key + '"]'
}
@ -56,8 +56,8 @@ function genData (el, key) {
}
let data = '{'
let attrs = `attrs:{`
let props = `props:{`
let attrs = 'attrs:{'
let props = 'props:{'
let events = {}
let hasAttrs = false
let hasProps = false

View File

@ -68,84 +68,82 @@ function makeAttrsMap (attrs) {
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
*/
function makeMap(values) {
function makeMap (values) {
values = values.split(/,/)
var map = {}
values.forEach(function(value) {
values.forEach(function (value) {
map[value] = 1
})
return function(value) {
return function (value) {
return map[value.toLowerCase()] === 1
}
}
// Regular Expressions for parsing tags and attributes
var singleAttrIdentifier = /([^\s"'<>\/=]+)/,
singleAttrAssign = /=/,
singleAttrAssigns = [singleAttrAssign],
singleAttrValues = [
// attr value double quotes
/"([^"]*)"+/.source,
// attr value, single quotes
/'([^']*)'+/.source,
// attr value, no quotes
/([^\s"'=<>`]+)/.source
],
qnameCapture = (function() {
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
// but for Vue templates we can enforce a simple charset
var ncname = '[a-zA-Z_][\\w\\-\\.]*'
return '((?:' + ncname + '\\:)?' + ncname + ')'
})(),
startTagOpen = new RegExp('^<' + qnameCapture),
startTagClose = /^\s*(\/?)>/,
endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>'),
doctype = /^<!DOCTYPE [^>]+>/i
const singleAttrIdentifier = /([^\s"'<>\/=]+)/
const singleAttrAssign = /=/
const singleAttrAssigns = [singleAttrAssign]
const singleAttrValues = [
// attr value double quotes
/"([^"]*)"+/.source,
// attr value, single quotes
/'([^']*)'+/.source,
// attr value, no quotes
/([^\s"'=<>`]+)/.source
]
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
// but for Vue templates we can enforce a simple charset
const ncname = '[a-zA-Z_][\\w\\-\\.]*'
const qnameCapture = '((?:' + ncname + '\\:)?' + ncname + ')'
const startTagOpen = new RegExp('^<' + qnameCapture)
const startTagClose = /^\s*(\/?)>/
const endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>')
const doctype = /^<!DOCTYPE [^>]+>/i
var IS_REGEX_CAPTURING_BROKEN = false
'x'.replace(/x(.)?/g, function(m, g) {
let IS_REGEX_CAPTURING_BROKEN = false
'x'.replace(/x(.)?/g, function (m, g) {
IS_REGEX_CAPTURING_BROKEN = g === ''
})
// Empty Elements
var empty = makeMap('area,base,basefont,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr')
const empty = makeMap('area,base,basefont,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr')
// Inline Elements
var inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,noscript,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,svg,textarea,tt,u,var')
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,noscript,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,svg,textarea,tt,u,var')
// Elements that you can, intentionally, leave open
// (and which close themselves)
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source')
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source')
// Attributes that have their values filled in disabled='disabled'
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected')
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected')
// Special Elements (can contain anything)
var special = makeMap('script,style')
const special = makeMap('script,style')
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
var nonPhrasing = makeMap('address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track')
const nonPhrasing = makeMap('address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track')
var reCache = {}
const reCache = {}
function attrForHandler(handler) {
var pattern = singleAttrIdentifier.source +
'(?:\\s*(' + joinSingleAttrAssigns(handler) + ')' +
'\\s*(?:' + singleAttrValues.join('|') + '))?'
function attrForHandler (handler) {
const pattern = singleAttrIdentifier.source +
'(?:\\s*(' + joinSingleAttrAssigns(handler) + ')' +
'\\s*(?:' + singleAttrValues.join('|') + '))?'
return new RegExp('^\\s*' + pattern)
}
function joinSingleAttrAssigns(handler) {
return singleAttrAssigns.map(function(assign) {
function joinSingleAttrAssigns (handler) {
return singleAttrAssigns.map(function (assign) {
return '(?:' + assign.source + ')'
}).join('|')
}
export default function HTMLParser(html, handler) {
var stack = [], lastTag
var attribute = attrForHandler(handler)
var last, prevTag, nextTag
export default function HTMLParser (html, handler) {
const stack = []
const attribute = attrForHandler(handler)
let last, prevTag, nextTag, lastTag
while (html) {
last = html
// Make sure we're not in a script or style element
@ -208,8 +206,7 @@ export default function HTMLParser(html, handler) {
if (textEnd >= 0) {
text = html.substring(0, textEnd)
html = html.substring(textEnd)
}
else {
} else {
text = html
html = ''
}
@ -218,13 +215,11 @@ export default function HTMLParser(html, handler) {
var nextTagMatch = parseStartTag(html)
if (nextTagMatch) {
nextTag = nextTagMatch.tagName
}
else {
} else {
nextTagMatch = html.match(endTag)
if (nextTagMatch) {
nextTag = '/' + nextTagMatch[1]
}
else {
} else {
nextTag = ''
}
}
@ -233,23 +228,19 @@ export default function HTMLParser(html, handler) {
handler.chars(text, prevTag, nextTag)
}
prevTag = ''
}
else {
} else {
var stackedTag = lastTag.toLowerCase()
var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)</' + stackedTag + '[^>]*>', 'i'))
html = html.replace(reStackedTag, function(all, text) {
html = html.replace(reStackedTag, function (all, text) {
if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') {
text = text
.replace(/<!--([\s\S]*?)-->/g, '$1')
.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, '$1')
}
if (handler.chars) {
handler.chars(text)
}
return ''
})
@ -266,7 +257,7 @@ export default function HTMLParser(html, handler) {
parseEndTag()
}
function parseStartTag(input) {
function parseStartTag (input) {
var start = input.match(startTagOpen)
if (start) {
var match = {
@ -287,7 +278,7 @@ export default function HTMLParser(html, handler) {
}
}
function handleStartTag(match) {
function handleStartTag (match) {
var tagName = match.tagName
var unarySlash = match.unarySlash
@ -307,7 +298,7 @@ export default function HTMLParser(html, handler) {
var unary = empty(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash
var attrs = match.attrs.map(function(args) {
var attrs = match.attrs.map(function (args) {
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
if (args[3] === '') { delete args[3] }
@ -316,7 +307,7 @@ export default function HTMLParser(html, handler) {
}
return {
name: args[1],
value: args[3] || args[4] || (args[5] && fillAttrs(args[5]) ? name : '')
value: args[3] || args[4] || (args[5] && fillAttrs(args[5]) ? args[1] : '')
}
})
@ -331,7 +322,7 @@ export default function HTMLParser(html, handler) {
}
}
function parseEndTag(tag, tagName) {
function parseEndTag (tag, tagName) {
var pos
// Find the closest opened tag of the same type
@ -342,9 +333,8 @@ export default function HTMLParser(html, handler) {
break
}
}
}
// If no tag name is provided, clean shop
else {
} else {
// If no tag name is provided, clean shop
pos = 0
}
@ -359,13 +349,11 @@ export default function HTMLParser(html, handler) {
// Remove the open elements from the stack
stack.length = pos
lastTag = pos && stack[pos - 1].tag
}
else if (tagName.toLowerCase() === 'br') {
} else if (tagName.toLowerCase() === 'br') {
if (handler.start) {
handler.start(tagName, [], true, '')
}
}
else if (tagName.toLowerCase() === 'p') {
} else if (tagName.toLowerCase() === 'p') {
if (handler.start) {
handler.start(tagName, [], false, '', true)
}

View File

@ -1,12 +1,12 @@
import { observe } from '../observer/index'
import Watcher from '../observer/watcher'
import { h, patch } from '../vdom/index'
import { nextTick, isReserved } from '../util/index'
import { nextTick, isReserved, query } from '../util/index'
export default function Component (options) {
this.$options = options
this._data = options.data
const el = this._el = document.querySelector(options.el)
this._el = query(options.el)
this._el.innerHTML = ''
Object.keys(options.data).forEach(key => proxy(this, key))
if (options.methods) {

View File

@ -1,8 +1,7 @@
import config from '../config'
import {
warn,
nextTick,
devtools
nextTick
} from '../util/index'
// we have two separate queues: one for directive updates

View File

@ -3,10 +3,8 @@ import Dep from './dep'
import { pushWatcher } from './batcher'
import {
extend,
warn,
isArray,
isObject,
nextTick,
_Set as Set
} from '../util/index'

View File

@ -1,7 +1,5 @@
import config from '../config'
import { isIE9 } from './env'
import { warn } from './debug'
import { camelize } from './lang'
/**
* Query an element selector if it's not an element already.
@ -43,157 +41,6 @@ export function inDoc (node) {
!!(parent && parent.nodeType === 1 && (doc.contains(parent)))
}
/**
* Get and remove an attribute from a node.
*
* @param {Node} node
* @param {String} _attr
*/
export function getAttr (node, _attr) {
var val = node.getAttribute(_attr)
if (val !== null) {
node.removeAttribute(_attr)
}
return val
}
/**
* Get an attribute with colon or v-bind: prefix.
*
* @param {Node} node
* @param {String} name
* @return {String|null}
*/
export function getBindAttr (node, name) {
var val = getAttr(node, ':' + name)
if (val === null) {
val = getAttr(node, 'v-bind:' + name)
}
return val
}
/**
* Check the presence of a bind attribute.
*
* @param {Node} node
* @param {String} name
* @return {Boolean}
*/
export function hasBindAttr (node, name) {
return node.hasAttribute(name) ||
node.hasAttribute(':' + name) ||
node.hasAttribute('v-bind:' + name)
}
/**
* Insert el before target
*
* @param {Element} el
* @param {Element} target
*/
export function before (el, target) {
target.parentNode.insertBefore(el, target)
}
/**
* Insert el after target
*
* @param {Element} el
* @param {Element} target
*/
export function after (el, target) {
if (target.nextSibling) {
before(el, target.nextSibling)
} else {
target.parentNode.appendChild(el)
}
}
/**
* Remove el from DOM
*
* @param {Element} el
*/
export function remove (el) {
el.parentNode.removeChild(el)
}
/**
* Prepend el to target
*
* @param {Element} el
* @param {Element} target
*/
export function prepend (el, target) {
if (target.firstChild) {
before(el, target.firstChild)
} else {
target.appendChild(el)
}
}
/**
* Replace target with el
*
* @param {Element} target
* @param {Element} el
*/
export function replace (target, el) {
var parent = target.parentNode
if (parent) {
parent.replaceChild(el, target)
}
}
/**
* Add event listener shorthand.
*
* @param {Element} el
* @param {String} event
* @param {Function} cb
* @param {Boolean} [useCapture]
*/
export function on (el, event, cb, useCapture) {
el.addEventListener(event, cb, useCapture)
}
/**
* Remove event listener shorthand.
*
* @param {Element} el
* @param {String} event
* @param {Function} cb
*/
export function off (el, event, cb) {
el.removeEventListener(event, cb)
}
/**
* For IE9 compat: when both class and :class are present
* getAttribute('class') returns wrong value...
*
* @param {Element} el
* @return {String}
*/
function getClass (el) {
var classname = el.className
if (typeof classname === 'object') {
classname = classname.baseVal || ''
}
return classname
}
/**
* In IE9, setAttribute('class') will result in empty class
* if the element also has the :class attribute; However in
@ -213,103 +60,6 @@ export function setClass (el, cls) {
}
}
/**
* Add class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/
export function addClass (el, cls) {
if (el.classList) {
el.classList.add(cls)
} else {
var cur = ' ' + getClass(el) + ' '
if (cur.indexOf(' ' + cls + ' ') < 0) {
setClass(el, (cur + cls).trim())
}
}
}
/**
* Remove class with compatibility for IE & SVG
*
* @param {Element} el
* @param {String} cls
*/
export function removeClass (el, cls) {
if (el.classList) {
el.classList.remove(cls)
} else {
var cur = ' ' + getClass(el) + ' '
var tar = ' ' + cls + ' '
while (cur.indexOf(tar) >= 0) {
cur = cur.replace(tar, ' ')
}
setClass(el, cur.trim())
}
if (!el.className) {
el.removeAttribute('class')
}
}
/**
* Extract raw content inside an element into a temporary
* container div
*
* @param {Element} el
* @param {Boolean} asFragment
* @return {Element|DocumentFragment}
*/
export function extractContent (el, asFragment) {
var child
var rawContent
/* istanbul ignore if */
if (isTemplate(el) && isFragment(el.content)) {
el = el.content
}
if (el.hasChildNodes()) {
trimNode(el)
rawContent = asFragment
? document.createDocumentFragment()
: document.createElement('div')
/* eslint-disable no-cond-assign */
while (child = el.firstChild) {
/* eslint-enable no-cond-assign */
rawContent.appendChild(child)
}
}
return rawContent
}
/**
* Trim possible empty head/tail text and comment
* nodes inside a parent.
*
* @param {Node} node
*/
export function trimNode (node) {
var child
/* eslint-disable no-sequences */
while (child = node.firstChild, isTrimmable(child)) {
node.removeChild(child)
}
while (child = node.lastChild, isTrimmable(child)) {
node.removeChild(child)
}
/* eslint-enable no-sequences */
}
function isTrimmable (node) {
return node && (
(node.nodeType === 3 && !node.data.trim()) ||
node.nodeType === 8
)
}
/**
* Check if an element is a template tag.
* Note if the template appears inside an SVG its tagName
@ -323,52 +73,6 @@ export function isTemplate (el) {
el.tagName.toLowerCase() === 'template'
}
/**
* Create an "anchor" for performing dom insertion/removals.
* This is used in a number of scenarios:
* - fragment instance
* - v-html
* - v-if
* - v-for
* - component
*
* @param {String} content
* @param {Boolean} persist - IE trashes empty textNodes on
* cloneNode(true), so in certain
* cases the anchor needs to be
* non-empty to be persisted in
* templates.
* @return {Comment|Text}
*/
export function createAnchor (content, persist) {
var anchor = config.debug
? document.createComment(content)
: document.createTextNode(persist ? ' ' : '')
anchor.__v_anchor = true
return anchor
}
/**
* Find a component ref attribute that starts with $.
*
* @param {Element} node
* @return {String|undefined}
*/
var refRE = /^v-ref:/
export function findRef (node) {
if (node.hasAttributes()) {
var attrs = node.attributes
for (var i = 0, l = attrs.length; i < l; i++) {
var name = attrs[i].name
if (refRE.test(name)) {
return camelize(name.replace(refRE, ''))
}
}
}
}
/**
* Get outerHTML of elements, taking care
* of SVG elements in IE as well.

View File

@ -1,39 +1,39 @@
export function createElement(tagName){
export function createElement (tagName) {
return document.createElement(tagName)
}
export function createElementNS(namespaceURI, qualifiedName){
export function createElementNS (namespaceURI, qualifiedName) {
return document.createElementNS(namespaceURI, qualifiedName)
}
export function createTextNode(text){
export function createTextNode (text) {
return document.createTextNode(text)
}
export function insertBefore(parentNode, newNode, referenceNode){
export function insertBefore (parentNode, newNode, referenceNode) {
parentNode.insertBefore(newNode, referenceNode)
}
export function removeChild(node, child){
export function removeChild (node, child) {
node.removeChild(child)
}
export function appendChild(node, child){
export function appendChild (node, child) {
node.appendChild(child)
}
export function parentNode(node){
export function parentNode (node) {
return node.parentElement
}
export function nextSibling(node){
export function nextSibling (node) {
return node.nextSibling
}
export function tagName(node){
export function tagName (node) {
return node.tagName
}
export function setTextContent(node, text){
export function setTextContent (node, text) {
node.textContent = text
}

View File

@ -1,7 +1,7 @@
import VNode from './vnode'
import { isPrimitive, isArray } from '../util/index'
function addNS(data, children) {
function addNS (data, children) {
data.ns = 'http://www.w3.org/2000/svg'
if (children !== undefined) {
for (var i = 0; i < children.length; ++i) {

View File

@ -1,10 +1,10 @@
const booleanAttrs = [
"allowfullscreen", "async", "autofocus", "autoplay", "checked", "compact", "controls", "declare",
"default", "defaultchecked", "defaultmuted", "defaultselected", "defer", "disabled", "draggable",
"enabled", "formnovalidate", "hidden", "indeterminate", "inert", "ismap", "itemscope", "loop", "multiple",
"muted", "nohref", "noresize", "noshade", "novalidate", "nowrap", "open", "pauseonexit", "readonly",
"required", "reversed", "scoped", "seamless", "selected", "sortable", "spellcheck", "translate",
"truespeed", "typemustmatch", "visible"
'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'compact', 'controls', 'declare',
'default', 'defaultchecked', 'defaultmuted', 'defaultselected', 'defer', 'disabled', 'draggable',
'enabled', 'formnovalidate', 'hidden', 'indeterminate', 'inert', 'ismap', 'itemscope', 'loop', 'multiple',
'muted', 'nohref', 'noresize', 'noshade', 'novalidate', 'nowrap', 'open', 'pauseonexit', 'readonly',
'required', 'reversed', 'scoped', 'seamless', 'selected', 'sortable', 'spellcheck', 'translate',
'truespeed', 'typemustmatch', 'visible'
]
const booleanAttrsDict = {}
@ -24,13 +24,14 @@ function updateAttrs (oldVnode, vnode) {
old = oldAttrs[key]
if (old !== cur) {
// TODO: add support to namespaced attributes (setAttributeNS)
if(booleanAttrsDict[key] && cur == null)
if (booleanAttrsDict[key] && cur == null) {
elm.removeAttribute(key)
else
} else {
elm.setAttribute(key, cur)
}
}
}
//remove removed attributes
// remove removed attributes
// use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
// the other option is to remove all attributes with value == undefined
for (key in oldAttrs) {

View File

@ -1,5 +1,5 @@
function arrInvoker(arr) {
return function() {
function arrInvoker (arr) {
return function () {
// Special case when length is two, for performance
arr.length === 2
? arr[0](arr[1])
@ -7,11 +7,11 @@ function arrInvoker(arr) {
}
}
function fnInvoker(o) {
return function(ev) { o.fn(ev) }
function fnInvoker (o) {
return function (ev) { o.fn(ev) }
}
function updateEventListeners(oldVnode, vnode) {
function updateEventListeners (oldVnode, vnode) {
let name, cur, old, event, capture
const elm = vnode.elm
const oldOn = oldVnode.data.on || {}
@ -34,7 +34,7 @@ function updateEventListeners(oldVnode, vnode) {
// Deliberately modify old array since it's captured in closure created with `arrInvoker`
old.length = cur.length
for (var i = 0; i < old.length; ++i) old[i] = cur[i]
on[name] = old
on[name] = old
} else {
old.fn = cur
on[name] = old

View File

@ -1,4 +1,4 @@
function updateProps(oldVnode, vnode) {
function updateProps (oldVnode, vnode) {
let key, cur, old
const elm = vnode.elm
const oldProps = oldVnode.data.props || {}

View File

@ -1,7 +1,7 @@
// TODO:
// - include prefix sniffing of v-bind:style
function updateStyle(oldVnode, vnode) {
function updateStyle (oldVnode, vnode) {
let cur, name
const elm = vnode.elm
const oldStyle = oldVnode.data.style || {}

View File

@ -18,7 +18,8 @@ function sameVnode (vnode1, vnode2) {
}
function createKeyToOldIdx (children, beginIdx, endIdx) {
var i, map = {}, key
let i, key
const map = {}
for (i = beginIdx; i <= endIdx; ++i) {
key = children[i].key
if (isDef(key)) map[key] = i
@ -27,7 +28,8 @@ function createKeyToOldIdx (children, beginIdx, endIdx) {
}
export default function createPatchFunction (modules, api) {
var i, j, cbs = {}
let i, j
const cbs = {}
if (isUndef(api)) api = dom
@ -43,24 +45,26 @@ export default function createPatchFunction (modules, api) {
}
function createRmCb (childElm, listeners) {
return function() {
return function () {
if (--listeners === 0) {
var parent = api.parentNode(childElm)
const parent = api.parentNode(childElm)
api.removeChild(parent, childElm)
}
}
}
function createElm (vnode, insertedVnodeQueue) {
var i, thunk, data = vnode.data
let i, thunk, elm
const data = vnode.data
if (isDef(data)) {
if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode)
if (isDef(i = data.vnode)) {
thunk = vnode
vnode = i
thunk = vnode
vnode = i
}
}
var elm, children = vnode.children, tag = vnode.sel
const children = vnode.children
const tag = vnode.sel
if (isDef(tag)) {
elm = vnode.elm = isDef(data) && isDef(i = data.ns)
? api.createElementNS(i, tag)
@ -92,7 +96,8 @@ export default function createPatchFunction (modules, api) {
}
function invokeDestroyHook (vnode) {
var i, j, data = vnode.data
let i, j
const data = vnode.data
if (isDef(data)) {
if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode)
for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode)
@ -107,7 +112,8 @@ export default function createPatchFunction (modules, api) {
function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
for (; startIdx <= endIdx; ++startIdx) {
var i, listeners, rm, ch = vnodes[startIdx]
let i, listeners, rm
const ch = vnodes[startIdx]
if (isDef(ch)) {
if (isDef(ch.sel)) {
invokeDestroyHook(ch)
@ -127,14 +133,15 @@ export default function createPatchFunction (modules, api) {
}
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue) {
var oldStartIdx = 0, newStartIdx = 0
var oldEndIdx = oldCh.length - 1
var oldStartVnode = oldCh[0]
var oldEndVnode = oldCh[oldEndIdx]
var newEndIdx = newCh.length - 1
var newStartVnode = newCh[0]
var newEndVnode = newCh[newEndIdx]
var oldKeyToIdx, idxInOld, elmToMove, before
let oldStartIdx = 0
let newStartIdx = 0
let oldEndIdx = oldCh.length - 1
let oldStartVnode = oldCh[0]
let oldEndVnode = oldCh[oldEndIdx]
let newEndIdx = newCh.length - 1
let newStartVnode = newCh[0]
let newEndVnode = newCh[newEndIdx]
let oldKeyToIdx, idxInOld, elmToMove, before
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
if (isUndef(oldStartVnode)) {
@ -175,7 +182,7 @@ export default function createPatchFunction (modules, api) {
}
}
if (oldStartIdx > oldEndIdx) {
before = isUndef(newCh[newEndIdx+1]) ? null : newCh[newEndIdx+1].elm
before = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
} else if (newStartIdx > newEndIdx) {
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
@ -183,7 +190,7 @@ export default function createPatchFunction (modules, api) {
}
function patchVnode (oldVnode, vnode, insertedVnodeQueue) {
var i, hook
let i, hook
if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
i(oldVnode, vnode)
}
@ -193,7 +200,9 @@ export default function createPatchFunction (modules, api) {
vnode.elm = i.elm
return
}
var elm = vnode.elm = oldVnode.elm, oldCh = oldVnode.children, ch = vnode.children
let elm = vnode.elm = oldVnode.elm
const oldCh = oldVnode.children
const ch = vnode.children
if (oldVnode === vnode) return
if (!sameVnode(oldVnode, vnode)) {
var parentElm = api.parentNode(oldVnode.elm)

View File

@ -15,7 +15,7 @@ module.exports = {
},
module: {
loaders: [
{ test: /\.js/, loader: 'babel', exclude: /node_modules/ }
{ test: /\.js/, loader: 'babel!eslint', exclude: /node_modules/ }
]
}
}