Evan You 10 лет назад
Родитель
Сommit
0a1c19d468

+ 47 - 39
dist/vue.common.js

@@ -179,12 +179,6 @@ function genStaticKeys(modules) {
 }
 
 var config = {
-
-  /**
-   * Preserve whitespaces between elements.
-   */
-  preserveWhitespace: true,
-
   /**
    * Option merge strategies (used in core/util/options)
    */
@@ -399,7 +393,8 @@ var proxyHandlers = void 0;
 var initProxy = void 0;
 if (process.env.NODE_ENV !== 'production') {
   (function () {
-    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl');
+    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 'require,__webpack_require__' // for Webpack/Browserify
+    );
 
     hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/);
 
@@ -620,10 +615,11 @@ var Watcher = function () {
         if (config.errorHandler) {
           config.errorHandler.call(null, e, this.vm);
         } else {
-          warn(e.stack);
+          throw e;
         }
       }
       // return old value when evaluation fails so the current UI is preserved
+      // if the error was somehow handled by user
       value = this.value;
     }
     // "touch" every property so they are all tracked as
@@ -1304,9 +1300,9 @@ var VNode = function () {
   return VNode;
 }();
 
-var emptyVNode = new VNode(undefined, undefined, undefined, '');
-
-var whitespace = new VNode(undefined, undefined, undefined, ' ');
+var emptyVNode = function emptyVNode() {
+  return new VNode(undefined, undefined, undefined, '');
+};
 
 function normalizeChildren(children) {
   // invoke children thunks.
@@ -1326,13 +1322,8 @@ function normalizeChildren(children) {
       if (Array.isArray(c)) {
         res.push.apply(res, normalizeChildren(c));
       } else if (isPrimitive(c)) {
-        // optimize whitespace
-        if (c === ' ') {
-          res.push(whitespace);
-        } else {
-          // convert primitive to vnode
-          res.push(new VNode(undefined, undefined, undefined, c));
-        }
+        // convert primitive to vnode
+        res.push(new VNode(undefined, undefined, undefined, c));
       } else if (c instanceof VNode) {
         res.push(c);
       }
@@ -1420,9 +1411,7 @@ function lifecycleMixin(Vue) {
     var vm = this;
     vm.$el = el;
     if (!vm.$options.render) {
-      vm.$options.render = function () {
-        return emptyVNode;
-      };
+      vm.$options.render = emptyVNode;
       if (process.env.NODE_ENV !== 'production') {
         /* istanbul ignore if */
         if (vm.$options.template) {
@@ -1799,7 +1788,7 @@ function renderElement(tag, data, namespace) {
   }
   if (!tag) {
     // in case of component :is set to falsy value
-    return emptyVNode;
+    return emptyVNode();
   }
   if (typeof tag === 'string') {
     var Ctor = void 0;
@@ -1853,19 +1842,24 @@ function renderMixin(Vue) {
 
   Vue.prototype._render = function () {
     var vm = this;
+
+    // set current active instance
     var prev = renderState.activeInstance;
     renderState.activeInstance = vm;
-    if (!vm._isMounted) {
-      // render static sub-trees for once on initial render
-      renderStaticTrees(vm);
-    }
+
     var _vm$$options = vm.$options;
     var render = _vm$$options.render;
+    var staticRenderFns = _vm$$options.staticRenderFns;
     var _renderChildren = _vm$$options._renderChildren;
     var _parentVnode = _vm$$options._parentVnode;
+
+
+    if (staticRenderFns && !vm._staticTrees) {
+      // render static sub-trees for once on initial render
+      renderStaticTrees(vm, staticRenderFns);
+    }
     // resolve slots. becaues slots are rendered in parent scope,
     // we set the activeInstance to parent.
-
     if (_renderChildren) {
       resolveSlots(vm, _renderChildren);
     }
@@ -1876,7 +1870,7 @@ function renderMixin(Vue) {
       if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
         warn('Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm);
       }
-      vnode = emptyVNode;
+      vnode = emptyVNode();
     }
     // set parent
     vnode.parent = _parentVnode;
@@ -1949,13 +1943,10 @@ function renderMixin(Vue) {
   };
 }
 
-function renderStaticTrees(vm) {
-  var staticRenderFns = vm.$options.staticRenderFns;
-  if (staticRenderFns) {
-    var trees = vm._staticTrees = new Array(staticRenderFns.length);
-    for (var i = 0; i < staticRenderFns.length; i++) {
-      trees[i] = staticRenderFns[i].call(vm._renderProxy);
-    }
+function renderStaticTrees(vm, fns) {
+  var trees = vm._staticTrees = new Array(fns.length);
+  for (var i = 0; i < fns.length; i++) {
+    trees[i] = fns[i].call(vm._renderProxy);
   }
 }
 
@@ -2680,7 +2671,7 @@ function initAssetRegisters(Vue) {
           }
         }
         if (type === 'component' && isPlainObject(definition)) {
-          definition.name = id;
+          definition.name = definition.name || id;
           definition = Vue.extend(definition);
         }
         this.options[type + 's'][id] = definition;
@@ -2764,7 +2755,7 @@ Object.defineProperty(Vue.prototype, '$isServer', {
   }
 });
 
-Vue.version = '2.0.0-alpha.0';
+Vue.version = '2.0.0-alpha.1';
 
 // attributes that should be using props for binding
 var mustUseProp = makeMap('value,selected,checked,muted');
@@ -2958,6 +2949,10 @@ function childNodes(node) {
   return node.childNodes;
 }
 
+function setAttribute(node, key, val) {
+  node.setAttribute(key, val);
+}
+
 var nodeOps = Object.freeze({
   createElement: createElement,
   createElementNS: createElementNS,
@@ -2969,7 +2964,8 @@ var nodeOps = Object.freeze({
   nextSibling: nextSibling,
   tagName: tagName,
   setTextContent: setTextContent,
-  childNodes: childNodes
+  childNodes: childNodes,
+  setAttribute: setAttribute
 });
 
 var emptyNode = new VNode('', {}, []);
@@ -3045,6 +3041,7 @@ function createPatchFunction(backend) {
       // in that case we can just return the element and be done.
       if (isDef(i = vnode.child)) {
         invokeCreateHooks(vnode, insertedVnodeQueue);
+        setScope(vnode);
         return vnode.elm;
       }
     }
@@ -3052,6 +3049,7 @@ function createPatchFunction(backend) {
     var tag = vnode.tag;
     if (isDef(tag)) {
       elm = vnode.elm = vnode.ns ? nodeOps.createElementNS(vnode.ns, tag) : nodeOps.createElement(tag);
+      setScope(vnode);
       if (Array.isArray(children)) {
         for (i = 0; i < children.length; ++i) {
           nodeOps.appendChild(elm, createElm(children[i], insertedVnodeQueue));
@@ -3079,6 +3077,16 @@ function createPatchFunction(backend) {
     }
   }
 
+  // set scope id attribute for scoped CSS.
+  // this is implemented as a special case to avoid the overhead
+  // of going through the normal attribute patching process.
+  function setScope(vnode) {
+    var i = void 0;
+    if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) {
+      nodeOps.setAttribute(vnode.elm, i, '');
+    }
+  }
+
   function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
     for (; startIdx <= endIdx; ++startIdx) {
       nodeOps.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before);
@@ -3222,6 +3230,7 @@ function createPatchFunction(backend) {
   }
 
   function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
+    if (oldVnode === vnode) return;
     var i = void 0,
         hook = void 0;
     if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
@@ -3230,7 +3239,6 @@ function createPatchFunction(backend) {
     var elm = vnode.elm = oldVnode.elm;
     var oldCh = oldVnode.children;
     var ch = vnode.children;
-    if (oldVnode === vnode) return;
     if (isDef(vnode.data)) {
       for (i = 0; i < cbs.update.length; ++i) {
         cbs.update[i](oldVnode, vnode);

+ 101 - 65
dist/vue.js

@@ -188,12 +188,6 @@
   }
 
   var config = {
-
-    /**
-     * Preserve whitespaces between elements.
-     */
-    preserveWhitespace: true,
-
     /**
      * Option merge strategies (used in core/util/options)
      */
@@ -408,7 +402,8 @@
   var initProxy = void 0;
   if ("development" !== 'production') {
     (function () {
-      var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl');
+      var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 'require,__webpack_require__' // for Webpack/Browserify
+      );
 
       hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/);
 
@@ -629,10 +624,11 @@
           if (config.errorHandler) {
             config.errorHandler.call(null, e, this.vm);
           } else {
-            warn(e.stack);
+            throw e;
           }
         }
         // return old value when evaluation fails so the current UI is preserved
+        // if the error was somehow handled by user
         value = this.value;
       }
       // "touch" every property so they are all tracked as
@@ -1311,9 +1307,9 @@
     return VNode;
   }();
 
-  var emptyVNode = new VNode(undefined, undefined, undefined, '');
-
-  var whitespace = new VNode(undefined, undefined, undefined, ' ');
+  var emptyVNode = function emptyVNode() {
+    return new VNode(undefined, undefined, undefined, '');
+  };
 
   function normalizeChildren(children) {
     // invoke children thunks.
@@ -1333,13 +1329,8 @@
         if (Array.isArray(c)) {
           res.push.apply(res, normalizeChildren(c));
         } else if (isPrimitive(c)) {
-          // optimize whitespace
-          if (c === ' ') {
-            res.push(whitespace);
-          } else {
-            // convert primitive to vnode
-            res.push(new VNode(undefined, undefined, undefined, c));
-          }
+          // convert primitive to vnode
+          res.push(new VNode(undefined, undefined, undefined, c));
         } else if (c instanceof VNode) {
           res.push(c);
         }
@@ -1427,9 +1418,7 @@
       var vm = this;
       vm.$el = el;
       if (!vm.$options.render) {
-        vm.$options.render = function () {
-          return emptyVNode;
-        };
+        vm.$options.render = emptyVNode;
         if ("development" !== 'production') {
           /* istanbul ignore if */
           if (vm.$options.template) {
@@ -1806,7 +1795,7 @@
     }
     if (!tag) {
       // in case of component :is set to falsy value
-      return emptyVNode;
+      return emptyVNode();
     }
     if (typeof tag === 'string') {
       var Ctor = void 0;
@@ -1860,19 +1849,24 @@
 
     Vue.prototype._render = function () {
       var vm = this;
+
+      // set current active instance
       var prev = renderState.activeInstance;
       renderState.activeInstance = vm;
-      if (!vm._isMounted) {
-        // render static sub-trees for once on initial render
-        renderStaticTrees(vm);
-      }
+
       var _vm$$options = vm.$options;
       var render = _vm$$options.render;
+      var staticRenderFns = _vm$$options.staticRenderFns;
       var _renderChildren = _vm$$options._renderChildren;
       var _parentVnode = _vm$$options._parentVnode;
+
+
+      if (staticRenderFns && !vm._staticTrees) {
+        // render static sub-trees for once on initial render
+        renderStaticTrees(vm, staticRenderFns);
+      }
       // resolve slots. becaues slots are rendered in parent scope,
       // we set the activeInstance to parent.
-
       if (_renderChildren) {
         resolveSlots(vm, _renderChildren);
       }
@@ -1883,7 +1877,7 @@
         if ("development" !== 'production' && Array.isArray(vnode)) {
           warn('Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm);
         }
-        vnode = emptyVNode;
+        vnode = emptyVNode();
       }
       // set parent
       vnode.parent = _parentVnode;
@@ -1956,13 +1950,10 @@
     };
   }
 
-  function renderStaticTrees(vm) {
-    var staticRenderFns = vm.$options.staticRenderFns;
-    if (staticRenderFns) {
-      var trees = vm._staticTrees = new Array(staticRenderFns.length);
-      for (var i = 0; i < staticRenderFns.length; i++) {
-        trees[i] = staticRenderFns[i].call(vm._renderProxy);
-      }
+  function renderStaticTrees(vm, fns) {
+    var trees = vm._staticTrees = new Array(fns.length);
+    for (var i = 0; i < fns.length; i++) {
+      trees[i] = fns[i].call(vm._renderProxy);
     }
   }
 
@@ -2685,7 +2676,7 @@
             }
           }
           if (type === 'component' && isPlainObject(definition)) {
-            definition.name = id;
+            definition.name = definition.name || id;
             definition = Vue.extend(definition);
           }
           this.options[type + 's'][id] = definition;
@@ -2769,7 +2760,7 @@
     }
   });
 
-  Vue.version = '2.0.0-alpha.0';
+  Vue.version = '2.0.0-alpha.1';
 
   // attributes that should be using props for binding
   var mustUseProp = makeMap('value,selected,checked,muted');
@@ -2974,6 +2965,10 @@
     return node.childNodes;
   }
 
+  function setAttribute(node, key, val) {
+    node.setAttribute(key, val);
+  }
+
 var nodeOps = Object.freeze({
     createElement: createElement,
     createElementNS: createElementNS,
@@ -2985,7 +2980,8 @@ var nodeOps = Object.freeze({
     nextSibling: nextSibling,
     tagName: tagName,
     setTextContent: setTextContent,
-    childNodes: childNodes
+    childNodes: childNodes,
+    setAttribute: setAttribute
   });
 
   var emptyNode = new VNode('', {}, []);
@@ -3061,6 +3057,7 @@ var nodeOps = Object.freeze({
         // in that case we can just return the element and be done.
         if (isDef(i = vnode.child)) {
           invokeCreateHooks(vnode, insertedVnodeQueue);
+          setScope(vnode);
           return vnode.elm;
         }
       }
@@ -3068,6 +3065,7 @@ var nodeOps = Object.freeze({
       var tag = vnode.tag;
       if (isDef(tag)) {
         elm = vnode.elm = vnode.ns ? nodeOps.createElementNS(vnode.ns, tag) : nodeOps.createElement(tag);
+        setScope(vnode);
         if (Array.isArray(children)) {
           for (i = 0; i < children.length; ++i) {
             nodeOps.appendChild(elm, createElm(children[i], insertedVnodeQueue));
@@ -3095,6 +3093,16 @@ var nodeOps = Object.freeze({
       }
     }
 
+    // set scope id attribute for scoped CSS.
+    // this is implemented as a special case to avoid the overhead
+    // of going through the normal attribute patching process.
+    function setScope(vnode) {
+      var i = void 0;
+      if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) {
+        nodeOps.setAttribute(vnode.elm, i, '');
+      }
+    }
+
     function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
       for (; startIdx <= endIdx; ++startIdx) {
         nodeOps.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before);
@@ -3238,6 +3246,7 @@ var nodeOps = Object.freeze({
     }
 
     function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
+      if (oldVnode === vnode) return;
       var i = void 0,
           hook = void 0;
       if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
@@ -3246,7 +3255,6 @@ var nodeOps = Object.freeze({
       var elm = vnode.elm = oldVnode.elm;
       var oldCh = oldVnode.children;
       var ch = vnode.children;
-      if (oldVnode === vnode) return;
       if (isDef(vnode.data)) {
         for (i = 0; i < cbs.update.length; ++i) {
           cbs.update[i](oldVnode, vnode);
@@ -4676,6 +4684,14 @@ var nodeOps = Object.freeze({
     console.error('[Vue parser]: ' + msg);
   }
 
+  function pluckModuleFunction(modules, key) {
+    return modules ? modules.map(function (m) {
+      return m[key];
+    }).filter(function (_) {
+      return _;
+    }) : [];
+  }
+
   function addProp(el, name, value) {
     (el.props || (el.props = [])).push({ name: name, value: value });
   }
@@ -4763,7 +4779,9 @@ var nodeOps = Object.freeze({
   var warn$1 = void 0;
   var platformGetTagNamespace = void 0;
   var platformMustUseProp = void 0;
-  var platformModules$1 = void 0;
+  var preTransforms = void 0;
+  var transforms = void 0;
+  var postTransforms = void 0;
   var delimiters = void 0;
 
   /**
@@ -4773,7 +4791,9 @@ var nodeOps = Object.freeze({
     warn$1 = options.warn || baseWarn;
     platformGetTagNamespace = options.getTagNamespace || no;
     platformMustUseProp = options.mustUseProp || no;
-    platformModules$1 = options.modules || [];
+    preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
+    transforms = pluckModuleFunction(options.modules, 'transformNode');
+    postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
     delimiters = options.delimiters;
     var stack = [];
     var root = void 0;
@@ -4819,6 +4839,11 @@ var nodeOps = Object.freeze({
           "development" !== 'production' && warn$1('Templates should only be responsbile for mapping the state to the ' + 'UI. Avoid placing tags with side-effects in your templates, such as ' + ('<' + tag + '>.'));
         }
 
+        // apply pre-transforms
+        for (var i = 0; i < preTransforms.length; i++) {
+          preTransforms[i](element, options);
+        }
+
         if (!inPre) {
           processPre(element);
           if (element.pre) {
@@ -4838,8 +4863,8 @@ var nodeOps = Object.freeze({
           processRender(element);
           processSlot(element);
           processComponent(element);
-          for (var i = 0; i < platformModules$1.length; i++) {
-            platformModules$1[i].transformNode(element, options);
+          for (var _i = 0; _i < transforms.length; _i++) {
+            transforms[_i](element, options);
           }
           processAttrs(element);
         }
@@ -4872,6 +4897,10 @@ var nodeOps = Object.freeze({
           currentParent = element;
           stack.push(element);
         }
+        // apply post-transforms
+        for (var _i2 = 0; _i2 < postTransforms.length; _i2++) {
+          postTransforms[_i2](element, options);
+        }
       },
       end: function end() {
         // remove trailing whitespace
@@ -4898,7 +4927,7 @@ var nodeOps = Object.freeze({
         }
         text = currentParent.tag === 'pre' || text.trim() ? decodeHTMLCached(text)
         // only preserve whitespace if its not right after a starting tag
-        : options.preserveWhitespace && currentParent.children.length ? ' ' : '';
+        : currentParent.children.length ? ' ' : '';
         if (text) {
           var expression = void 0;
           if (!inPre && text !== ' ' && (expression = parseText(text, delimiters))) {
@@ -4928,7 +4957,7 @@ var nodeOps = Object.freeze({
   function processRawAttrs(el) {
     var l = el.attrsList.length;
     if (l) {
-      var attrs = el.attrs = new Array(l);
+      var attrs = el.staticAttrs = new Array(l);
       for (var i = 0; i < l; i++) {
         attrs[i] = {
           name: el.attrsList[i].name,
@@ -5300,7 +5329,8 @@ var nodeOps = Object.freeze({
 
   // configurable state
   var warn$2 = void 0;
-  var platformModules$2 = void 0;
+  var transforms$1 = void 0;
+  var dataGenFns = void 0;
   var platformDirectives$1 = void 0;
   var isPlatformReservedTag$1 = void 0;
   var staticRenderFns = void 0;
@@ -5312,7 +5342,8 @@ var nodeOps = Object.freeze({
     var currentStaticRenderFns = staticRenderFns = [];
     currentOptions = options;
     warn$2 = options.warn || baseWarn;
-    platformModules$2 = options.modules || [];
+    transforms$1 = pluckModuleFunction(options.modules, 'transformCode');
+    dataGenFns = pluckModuleFunction(options.modules, 'genData');
     platformDirectives$1 = options.directives || {};
     isPlatformReservedTag$1 = options.isReservedTag || no;
     var code = ast ? genElement(ast) : '_h(_e("div"))';
@@ -5354,12 +5385,9 @@ var nodeOps = Object.freeze({
           code = '_m(' + (staticRenderFns.length - 1) + ')';
         }
       }
-      // platform modules
-      for (var i = 0; i < platformModules$2.length; i++) {
-        var transform = platformModules$2[i].transformCode;
-        if (transform) {
-          code = transform(el, code);
-        }
+      // module transforms
+      for (var i = 0; i < transforms$1.length; i++) {
+        code = transforms$1[i](el, code);
       }
       // check keep-alive
       if (el.component && el.keepAlive) {
@@ -5418,9 +5446,9 @@ var nodeOps = Object.freeze({
     if (el.slotTarget) {
       data += 'slot:' + el.slotTarget + ',';
     }
-    // platform modules
-    for (var i = 0; i < platformModules$2.length; i++) {
-      data += platformModules$2[i].genData(el);
+    // module data generation functions
+    for (var i = 0; i < dataGenFns.length; i++) {
+      data += dataGenFns[i](el);
     }
     // v-show, used to avoid transition being applied
     // since v-show takes it over
@@ -5561,6 +5589,8 @@ var nodeOps = Object.freeze({
     };
   }
 
+  var keywordRE = new RegExp('\\b' + ('do,if,in,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + 'super,throw,while,yield,delete,export,import,return,switch,typeof,default,' + 'extends,finally,continue,debugger,function,arguments,instanceof').split(',').join('\\b|\\b') + '\\b');
+
   // detect problematic expressions in a template
   function detectErrors(ast) {
     var errors = [];
@@ -5591,13 +5621,23 @@ var nodeOps = Object.freeze({
   }
 
   function checkExpression(exp, text, errors) {
-    try {
-      new Function(exp);
-    } catch (e) {
-      errors.push('- invalid expression: ' + text);
+    exp = stripToString(exp);
+    var keywordMatch = exp.match(keywordRE);
+    if (keywordMatch) {
+      errors.push('- avoid using JavaScript keyword as property name: ' + ('"' + keywordMatch[0] + '" in expression ' + text));
+    } else {
+      try {
+        new Function(exp);
+      } catch (e) {
+        errors.push('- invalid expression: ' + text);
+      }
     }
   }
 
+  function stripToString(exp) {
+    return exp.replace(/^_s\((.*)\)$/, '$1');
+  }
+
   function transformNode(el, options) {
     var warn = options.warn || baseWarn;
     var staticClass = getAndRemoveAttr(el, 'class');
@@ -5789,13 +5829,11 @@ var nodeOps = Object.freeze({
     html: html
   };
 
-  var cache1 = Object.create(null);
-  var cache2 = Object.create(null);
+  var cache = Object.create(null);
 
   var baseOptions = {
     isIE: isIE,
     expectHTML: true,
-    preserveWhitespace: true,
     modules: modules$1,
     staticKeys: genStaticKeys(modules$1),
     directives: directives$1,
@@ -5823,7 +5861,6 @@ var nodeOps = Object.freeze({
         }
       }
     }
-    var cache = options && options.preserveWhitespace === false ? cache1 : cache2;
     var key = options && options.delimiters ? String(options.delimiters) + template : template;
     if (cache[key]) {
       return cache[key];
@@ -5884,7 +5921,6 @@ var nodeOps = Object.freeze({
       }
       if (template) {
         var _compileToFunctions = compileToFunctions(template, {
-          preserveWhitespace: config.preserveWhitespace,
           delimiters: options.delimiters,
           warn: warn
         }, this);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/vue.min.js


+ 26 - 35
packages/vue-server-renderer/index.js

@@ -444,12 +444,6 @@ if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
 }
 
 var config = {
-
-  /**
-   * Preserve whitespaces between elements.
-   */
-  preserveWhitespace: true,
-
   /**
    * Option merge strategies (used in core/util/options)
    */
@@ -1224,7 +1218,8 @@ var proxyHandlers = void 0;
 var initProxy = void 0;
 if (process.env.NODE_ENV !== 'production') {
   (function () {
-    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl');
+    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 'require,__webpack_require__' // for Webpack/Browserify
+    );
 
     hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/);
 
@@ -1405,10 +1400,11 @@ var Watcher = function () {
         if (config.errorHandler) {
           config.errorHandler.call(null, e, this.vm);
         } else {
-          warn(e.stack);
+          throw e;
         }
       }
       // return old value when evaluation fails so the current UI is preserved
+      // if the error was somehow handled by user
       value = this.value;
     }
     // "touch" every property so they are all tracked as
@@ -1821,9 +1817,9 @@ var VNode = function () {
   return VNode;
 }();
 
-var emptyVNode = new VNode(undefined, undefined, undefined, '');
-
-var whitespace = new VNode(undefined, undefined, undefined, ' ');
+var emptyVNode = function emptyVNode() {
+  return new VNode(undefined, undefined, undefined, '');
+};
 
 function normalizeChildren(children) {
   // invoke children thunks.
@@ -1843,13 +1839,8 @@ function normalizeChildren(children) {
       if (Array.isArray(c)) {
         res.push.apply(res, normalizeChildren(c));
       } else if (isPrimitive(c)) {
-        // optimize whitespace
-        if (c === ' ') {
-          res.push(whitespace);
-        } else {
-          // convert primitive to vnode
-          res.push(new VNode(undefined, undefined, undefined, c));
-        }
+        // convert primitive to vnode
+        res.push(new VNode(undefined, undefined, undefined, c));
       } else if (c instanceof VNode) {
         res.push(c);
       }
@@ -1938,7 +1929,7 @@ function renderElement(tag, data, namespace) {
   }
   if (!tag) {
     // in case of component :is set to falsy value
-    return emptyVNode;
+    return emptyVNode();
   }
   if (typeof tag === 'string') {
     var Ctor = void 0;
@@ -1992,19 +1983,24 @@ function renderMixin(Vue) {
 
   Vue.prototype._render = function () {
     var vm = this;
+
+    // set current active instance
     var prev = renderState.activeInstance;
     renderState.activeInstance = vm;
-    if (!vm._isMounted) {
-      // render static sub-trees for once on initial render
-      renderStaticTrees(vm);
-    }
+
     var _vm$$options = vm.$options;
     var render = _vm$$options.render;
+    var staticRenderFns = _vm$$options.staticRenderFns;
     var _renderChildren = _vm$$options._renderChildren;
     var _parentVnode = _vm$$options._parentVnode;
+
+
+    if (staticRenderFns && !vm._staticTrees) {
+      // render static sub-trees for once on initial render
+      renderStaticTrees(vm, staticRenderFns);
+    }
     // resolve slots. becaues slots are rendered in parent scope,
     // we set the activeInstance to parent.
-
     if (_renderChildren) {
       resolveSlots(vm, _renderChildren);
     }
@@ -2015,7 +2011,7 @@ function renderMixin(Vue) {
       if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
         warn('Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm);
       }
-      vnode = emptyVNode;
+      vnode = emptyVNode();
     }
     // set parent
     vnode.parent = _parentVnode;
@@ -2088,13 +2084,10 @@ function renderMixin(Vue) {
   };
 }
 
-function renderStaticTrees(vm) {
-  var staticRenderFns = vm.$options.staticRenderFns;
-  if (staticRenderFns) {
-    var trees = vm._staticTrees = new Array(staticRenderFns.length);
-    for (var i = 0; i < staticRenderFns.length; i++) {
-      trees[i] = staticRenderFns[i].call(vm._renderProxy);
-    }
+function renderStaticTrees(vm, fns) {
+  var trees = vm._staticTrees = new Array(fns.length);
+  for (var i = 0; i < fns.length; i++) {
+    trees[i] = fns[i].call(vm._renderProxy);
   }
 }
 
@@ -2222,9 +2215,7 @@ function lifecycleMixin(Vue) {
     var vm = this;
     vm.$el = el;
     if (!vm.$options.render) {
-      vm.$options.render = function () {
-        return emptyVNode;
-      };
+      vm.$options.render = emptyVNode;
       if (process.env.NODE_ENV !== 'production') {
         /* istanbul ignore if */
         if (vm.$options.template) {

+ 1 - 1
packages/vue-server-renderer/package.json

@@ -1,6 +1,6 @@
 {
   "name": "vue-server-renderer",
-  "version": "0.1.0",
+  "version": "2.0.0-alpha.1",
   "description": "server renderer for Vue 2.0",
   "main": "index.js",
   "repository": {

+ 161 - 79
packages/vue-template-compiler/index.js

@@ -4,6 +4,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
 
 var entities = require('entities');
 var deindent = _interopDefault(require('de-indent'));
+var sourceMap = require('source-map');
 
 /**
  * Convert a value to a string that is actually rendered.
@@ -184,12 +185,6 @@ function genStaticKeys(modules) {
 }
 
 var config = {
-
-  /**
-   * Preserve whitespaces between elements.
-   */
-  preserveWhitespace: true,
-
   /**
    * Option merge strategies (used in core/util/options)
    */
@@ -424,7 +419,8 @@ var proxyHandlers = void 0;
 var initProxy = void 0;
 if (process.env.NODE_ENV !== 'production') {
   (function () {
-    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl');
+    var allowedGlobals = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + 'require,__webpack_require__' // for Webpack/Browserify
+    );
 
     hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/);
 
@@ -645,10 +641,11 @@ var Watcher = function () {
         if (config.errorHandler) {
           config.errorHandler.call(null, e, this.vm);
         } else {
-          warn(e.stack);
+          throw e;
         }
       }
       // return old value when evaluation fails so the current UI is preserved
+      // if the error was somehow handled by user
       value = this.value;
     }
     // "touch" every property so they are all tracked as
@@ -1310,9 +1307,9 @@ var VNode = function () {
   return VNode;
 }();
 
-var emptyVNode = new VNode(undefined, undefined, undefined, '');
-
-var whitespace = new VNode(undefined, undefined, undefined, ' ');
+var emptyVNode = function emptyVNode() {
+  return new VNode(undefined, undefined, undefined, '');
+};
 
 function normalizeChildren(children) {
   // invoke children thunks.
@@ -1332,13 +1329,8 @@ function normalizeChildren(children) {
       if (Array.isArray(c)) {
         res.push.apply(res, normalizeChildren(c));
       } else if (isPrimitive(c)) {
-        // optimize whitespace
-        if (c === ' ') {
-          res.push(whitespace);
-        } else {
-          // convert primitive to vnode
-          res.push(new VNode(undefined, undefined, undefined, c));
-        }
+        // convert primitive to vnode
+        res.push(new VNode(undefined, undefined, undefined, c));
       } else if (c instanceof VNode) {
         res.push(c);
       }
@@ -1426,9 +1418,7 @@ function lifecycleMixin(Vue) {
     var vm = this;
     vm.$el = el;
     if (!vm.$options.render) {
-      vm.$options.render = function () {
-        return emptyVNode;
-      };
+      vm.$options.render = emptyVNode;
       if (process.env.NODE_ENV !== 'production') {
         /* istanbul ignore if */
         if (vm.$options.template) {
@@ -1805,7 +1795,7 @@ function renderElement(tag, data, namespace) {
   }
   if (!tag) {
     // in case of component :is set to falsy value
-    return emptyVNode;
+    return emptyVNode();
   }
   if (typeof tag === 'string') {
     var Ctor = void 0;
@@ -1859,19 +1849,24 @@ function renderMixin(Vue) {
 
   Vue.prototype._render = function () {
     var vm = this;
+
+    // set current active instance
     var prev = renderState.activeInstance;
     renderState.activeInstance = vm;
-    if (!vm._isMounted) {
-      // render static sub-trees for once on initial render
-      renderStaticTrees(vm);
-    }
+
     var _vm$$options = vm.$options;
     var render = _vm$$options.render;
+    var staticRenderFns = _vm$$options.staticRenderFns;
     var _renderChildren = _vm$$options._renderChildren;
     var _parentVnode = _vm$$options._parentVnode;
+
+
+    if (staticRenderFns && !vm._staticTrees) {
+      // render static sub-trees for once on initial render
+      renderStaticTrees(vm, staticRenderFns);
+    }
     // resolve slots. becaues slots are rendered in parent scope,
     // we set the activeInstance to parent.
-
     if (_renderChildren) {
       resolveSlots(vm, _renderChildren);
     }
@@ -1882,7 +1877,7 @@ function renderMixin(Vue) {
       if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
         warn('Multiple root nodes returned from render function. Render function ' + 'should return a single root node.', vm);
       }
-      vnode = emptyVNode;
+      vnode = emptyVNode();
     }
     // set parent
     vnode.parent = _parentVnode;
@@ -1955,13 +1950,10 @@ function renderMixin(Vue) {
   };
 }
 
-function renderStaticTrees(vm) {
-  var staticRenderFns = vm.$options.staticRenderFns;
-  if (staticRenderFns) {
-    var trees = vm._staticTrees = new Array(staticRenderFns.length);
-    for (var i = 0; i < staticRenderFns.length; i++) {
-      trees[i] = staticRenderFns[i].call(vm._renderProxy);
-    }
+function renderStaticTrees(vm, fns) {
+  var trees = vm._staticTrees = new Array(fns.length);
+  for (var i = 0; i < fns.length; i++) {
+    trees[i] = fns[i].call(vm._renderProxy);
   }
 }
 
@@ -2960,6 +2952,14 @@ function baseWarn(msg) {
   console.error('[Vue parser]: ' + msg);
 }
 
+function pluckModuleFunction(modules, key) {
+  return modules ? modules.map(function (m) {
+    return m[key];
+  }).filter(function (_) {
+    return _;
+  }) : [];
+}
+
 function addProp(el, name, value) {
   (el.props || (el.props = [])).push({ name: name, value: value });
 }
@@ -3047,7 +3047,9 @@ var decodeHTMLCached = cached(entities.decodeHTML);
 var warn$1 = void 0;
 var platformGetTagNamespace = void 0;
 var platformMustUseProp = void 0;
-var platformModules = void 0;
+var preTransforms = void 0;
+var transforms = void 0;
+var postTransforms = void 0;
 var delimiters = void 0;
 
 /**
@@ -3057,7 +3059,9 @@ function parse(template, options) {
   warn$1 = options.warn || baseWarn;
   platformGetTagNamespace = options.getTagNamespace || no;
   platformMustUseProp = options.mustUseProp || no;
-  platformModules = options.modules || [];
+  preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
+  transforms = pluckModuleFunction(options.modules, 'transformNode');
+  postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
   delimiters = options.delimiters;
   var stack = [];
   var root = void 0;
@@ -3103,6 +3107,11 @@ function parse(template, options) {
         process.env.NODE_ENV !== 'production' && warn$1('Templates should only be responsbile for mapping the state to the ' + 'UI. Avoid placing tags with side-effects in your templates, such as ' + ('<' + tag + '>.'));
       }
 
+      // apply pre-transforms
+      for (var i = 0; i < preTransforms.length; i++) {
+        preTransforms[i](element, options);
+      }
+
       if (!inPre) {
         processPre(element);
         if (element.pre) {
@@ -3122,8 +3131,8 @@ function parse(template, options) {
         processRender(element);
         processSlot(element);
         processComponent(element);
-        for (var i = 0; i < platformModules.length; i++) {
-          platformModules[i].transformNode(element, options);
+        for (var _i = 0; _i < transforms.length; _i++) {
+          transforms[_i](element, options);
         }
         processAttrs(element);
       }
@@ -3156,6 +3165,10 @@ function parse(template, options) {
         currentParent = element;
         stack.push(element);
       }
+      // apply post-transforms
+      for (var _i2 = 0; _i2 < postTransforms.length; _i2++) {
+        postTransforms[_i2](element, options);
+      }
     },
     end: function end() {
       // remove trailing whitespace
@@ -3182,7 +3195,7 @@ function parse(template, options) {
       }
       text = currentParent.tag === 'pre' || text.trim() ? decodeHTMLCached(text)
       // only preserve whitespace if its not right after a starting tag
-      : options.preserveWhitespace && currentParent.children.length ? ' ' : '';
+      : currentParent.children.length ? ' ' : '';
       if (text) {
         var expression = void 0;
         if (!inPre && text !== ' ' && (expression = parseText(text, delimiters))) {
@@ -3212,7 +3225,7 @@ function processPre(el) {
 function processRawAttrs(el) {
   var l = el.attrsList.length;
   if (l) {
-    var attrs = el.attrs = new Array(l);
+    var attrs = el.staticAttrs = new Array(l);
     for (var i = 0; i < l; i++) {
       attrs[i] = {
         name: el.attrsList[i].name,
@@ -3584,7 +3597,8 @@ var baseDirectives = {
 
 // configurable state
 var warn$2 = void 0;
-var platformModules$1 = void 0;
+var transforms$1 = void 0;
+var dataGenFns = void 0;
 var platformDirectives = void 0;
 var isPlatformReservedTag$1 = void 0;
 var staticRenderFns = void 0;
@@ -3596,7 +3610,8 @@ function generate(ast, options) {
   var currentStaticRenderFns = staticRenderFns = [];
   currentOptions = options;
   warn$2 = options.warn || baseWarn;
-  platformModules$1 = options.modules || [];
+  transforms$1 = pluckModuleFunction(options.modules, 'transformCode');
+  dataGenFns = pluckModuleFunction(options.modules, 'genData');
   platformDirectives = options.directives || {};
   isPlatformReservedTag$1 = options.isReservedTag || no;
   var code = ast ? genElement(ast) : '_h(_e("div"))';
@@ -3638,12 +3653,9 @@ function genElement(el) {
         code = '_m(' + (staticRenderFns.length - 1) + ')';
       }
     }
-    // platform modules
-    for (var i = 0; i < platformModules$1.length; i++) {
-      var transform = platformModules$1[i].transformCode;
-      if (transform) {
-        code = transform(el, code);
-      }
+    // module transforms
+    for (var i = 0; i < transforms$1.length; i++) {
+      code = transforms$1[i](el, code);
     }
     // check keep-alive
     if (el.component && el.keepAlive) {
@@ -3702,9 +3714,9 @@ function genData(el) {
   if (el.slotTarget) {
     data += 'slot:' + el.slotTarget + ',';
   }
-  // platform modules
-  for (var i = 0; i < platformModules$1.length; i++) {
-    data += platformModules$1[i].genData(el);
+  // module data generation functions
+  for (var i = 0; i < dataGenFns.length; i++) {
+    data += dataGenFns[i](el);
   }
   // v-show, used to avoid transition being applied
   // since v-show takes it over
@@ -3845,6 +3857,8 @@ function compile$2(template, options) {
   };
 }
 
+var keywordRE = new RegExp('\\b' + ('do,if,in,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + 'super,throw,while,yield,delete,export,import,return,switch,typeof,default,' + 'extends,finally,continue,debugger,function,arguments,instanceof').split(',').join('\\b|\\b') + '\\b');
+
 // detect problematic expressions in a template
 function detectErrors(ast) {
   var errors = [];
@@ -3875,13 +3889,23 @@ function checkNode(node, errors) {
 }
 
 function checkExpression(exp, text, errors) {
-  try {
-    new Function(exp);
-  } catch (e) {
-    errors.push('- invalid expression: ' + text);
+  exp = stripToString(exp);
+  var keywordMatch = exp.match(keywordRE);
+  if (keywordMatch) {
+    errors.push('- avoid using JavaScript keyword as property name: ' + ('"' + keywordMatch[0] + '" in expression ' + text));
+  } else {
+    try {
+      new Function(exp);
+    } catch (e) {
+      errors.push('- invalid expression: ' + text);
+    }
   }
 }
 
+function stripToString(exp) {
+  return exp.replace(/^_s\((.*)\)$/, '$1');
+}
+
 function transformNode(el, options) {
   var warn = options.warn || baseWarn;
   var staticClass = getAndRemoveAttr(el, 'class');
@@ -4073,13 +4097,11 @@ var directives = {
   html: html
 };
 
-var cache1 = Object.create(null);
-var cache2 = Object.create(null);
+var cache = Object.create(null);
 
 var baseOptions = {
   isIE: isIE,
   expectHTML: true,
-  preserveWhitespace: true,
   modules: modules,
   staticKeys: genStaticKeys(modules),
   directives: directives,
@@ -4107,7 +4129,6 @@ function compileToFunctions(template, options, vm) {
       }
     }
   }
-  var cache = options && options.preserveWhitespace === false ? cache1 : cache2;
   var key = options && options.delimiters ? String(options.delimiters) + template : template;
   if (cache[key]) {
     return cache[key];
@@ -4138,19 +4159,23 @@ function makeFunction(code) {
   }
 }
 
+var splitRE = /\r?\n/g;
+var emptyRE = /^(?:\/\/)?\s*$/;
 var isSpecialTag = makeMap('script,style,template', true);
 
 /**
  * Parse a single-file component (*.vue) file into an SFC Descriptor Object.
  */
-function parseSFC(content) {
+function parseComponent(content) {
+  var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
+
   var sfc = {
     template: null,
     script: null,
     styles: []
   };
   var depth = 0;
-  var currentBlock = void 0;
+  var currentBlock = null;
 
   function start(tag, attrs) {
     depth++;
@@ -4158,39 +4183,90 @@ function parseSFC(content) {
       return;
     }
     if (isSpecialTag(tag)) {
-      var block = currentBlock = {
+      currentBlock = {
         type: tag,
         content: ''
       };
-      for (var i = 0; i < attrs.length; i++) {
-        var attr = attrs[i];
-        if (attr.name === 'lang') {
-          block.lang = attr.value;
-        }
-        if (attr.name === 'scoped') {
-          block.scoped = true;
-        }
-        if (attr.name === 'src') {
-          block.src = attr.value;
-        }
-      }
+      checkAttrs(currentBlock, attrs);
       if (tag === 'style') {
-        sfc.styles.push(block);
+        sfc.styles.push(currentBlock);
       } else {
-        sfc[tag] = block;
+        sfc[tag] = currentBlock;
+      }
+    }
+  }
+
+  function checkAttrs(block, attrs) {
+    for (var i = 0; i < attrs.length; i++) {
+      var attr = attrs[i];
+      if (attr.name === 'lang') {
+        block.lang = attr.value;
+      }
+      if (attr.name === 'scoped') {
+        block.scoped = true;
+      }
+      if (attr.name === 'src') {
+        block.src = attr.value;
       }
     }
   }
 
   function end() {
     depth--;
+    if (options.map && currentBlock && !currentBlock.src) {
+      addSourceMap(currentBlock);
+    }
     currentBlock = null;
   }
 
   function chars(text) {
     if (currentBlock) {
-      currentBlock.content = deindent(text);
+      currentBlock.start = content.indexOf(text);
+      currentBlock.end = currentBlock.start + text.length;
+      text = deindent(text);
+      // pad content so that linters and pre-processors can output correct
+      // line numbers in errors and warnings
+      if (currentBlock.type !== 'template' && options.pad) {
+        text = padContent(currentBlock) + text;
+      }
+      currentBlock.content = text;
+    }
+  }
+
+  function padContent(block) {
+    var padChar = block.type === 'script' && !block.lang ? '//\n' : '\n';
+    return Array(getPaddingOffset(block) + 1).join(padChar);
+  }
+
+  function getPaddingOffset(block) {
+    return content.slice(0, block.start).split(splitRE).length - 1;
+  }
+
+  function addSourceMap(block) {
+    var filename = options.map.filename;
+    /* istanbul ignore if */
+    if (!filename) {
+      throw new Error('Should provide original filename in the map option.');
     }
+    var offset = options.pad ? 0 : getPaddingOffset(block);
+    var map = new sourceMap.SourceMapGenerator();
+    map.setSourceContent(filename, content);
+    block.content.split(splitRE).forEach(function (line, index) {
+      if (!emptyRE.test(line)) {
+        map.addMapping({
+          source: filename,
+          original: {
+            line: index + 1 + offset,
+            column: 0
+          },
+          generated: {
+            line: index + 1,
+            column: 0
+          }
+        });
+      }
+    });
+    block.map = JSON.parse(map.toString());
   }
 
   parseHTML(content, {
@@ -4204,8 +4280,14 @@ function parseSFC(content) {
 }
 
 function compile(template, options) {
+  options = options || {};
   var errors = [];
+  // allow injecting modules/directives
+  var modules = options.modules ? baseOptions.modules.concat(options.modules) : baseOptions.modules;
+  var directives = options.directives ? extend(extend({}, baseOptions.directives), options.directives) : baseOptions.directives;
   var compiled = compile$1(template, {
+    modules: modules,
+    directives: directives,
     warn: function warn(msg) {
       errors.push(msg);
     }
@@ -4215,5 +4297,5 @@ function compile(template, options) {
 }
 
 exports.compile = compile;
-exports.parseComponent = parseSFC;
+exports.parseComponent = parseComponent;
 exports.compileToFunctions = compileToFunctions;

+ 1 - 1
packages/vue-template-compiler/package.json

@@ -1,6 +1,6 @@
 {
   "name": "vue-template-compiler",
-  "version": "0.1.0",
+  "version": "2.0.0-alpha.1",
   "description": "template compiler for Vue 2.0",
   "main": "index.js",
   "repository": {

+ 1 - 1
src/core/index.js

@@ -8,6 +8,6 @@ Object.defineProperty(Vue.prototype, '$isServer', {
   get: () => config._isServer
 })
 
-Vue.version = '2.0.0-alpha.0'
+Vue.version = '2.0.0-alpha.1'
 
 export default Vue

Некоторые файлы не были показаны из-за большого количества измененных файлов