Evan You пре 10 година
родитељ
комит
354b7df4e9

+ 17 - 1
build/grunt-tasks/build.js

@@ -3,7 +3,21 @@
  */
 
 module.exports = function (grunt) {
-  grunt.registerTask('build', function () {
+
+  grunt.registerTask('build-vendor', function () {
+    var webpack = require('webpack')
+    webpack({
+      entry: './node_modules/notevil/index.js',
+      output: {
+        path: './vendor',
+        filename: 'notevil.js',
+        library: 'notevil',
+        libraryTarget: 'commonjs2'
+      }
+    }, this.async())
+  })
+
+  grunt.registerTask('build-self', function () {
 
     var done = this.async()
     var fs = require('fs')
@@ -47,4 +61,6 @@ module.exports = function (grunt) {
       return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m'
     }
   })
+
+  grunt.registerTask('build', ['build-vendor', 'build-self'])
 }

+ 3 - 0
gruntfile.js

@@ -24,10 +24,12 @@ module.exports = function (grunt) {
         files: [
           'test/unit/lib/util.js',
           'test/unit/lib/jquery.js',
+          'vendor/*.js',
           'src/**/*.js',
           'test/unit/specs/**/*.js'
         ],
         preprocessors: {
+          'vendor/*.js': ['commonjs'],
           'src/**/*.js': ['commonjs'],
           'test/unit/specs/**/*.js': ['commonjs']
         },
@@ -44,6 +46,7 @@ module.exports = function (grunt) {
           browsers: ['PhantomJS'],
           reporters: ['progress', 'coverage'],
           preprocessors: {
+            'vendor/*.js': ['commonjs'],
             'src/**/*.js': ['commonjs', 'coverage'],
             'test/unit/specs/**/*.js': ['commonjs']
           },

+ 1 - 0
package.json

@@ -45,6 +45,7 @@
     "karma-phantomjs-launcher": "^0.2.1",
     "karma-safari-launcher": "^0.1.1",
     "karma-sauce-launcher": "^0.2.14",
+    "notevil": "^1.0.0",
     "phantomjs": "^1.9.17",
     "semver": "^5.0.1",
     "shell-task": "^1.0.0",

+ 4 - 9
src/api/child.js

@@ -25,15 +25,10 @@ exports.$addChild = function (opts, BaseCtor) {
     var ctors = context._childCtors
     ChildVue = ctors[BaseCtor.cid]
     if (!ChildVue) {
-      var optionName = BaseCtor.options.name
-      var className = optionName
-        ? _.classify(optionName)
-        : 'VueComponent'
-      ChildVue = new Function(
-        'return function ' + className + ' (options) {' +
-        'this.constructor = ' + className + ';' +
-        'this._init(options) }'
-      )()
+      ChildVue = function VueComponent (options) {
+        this.constructor = ChildVue
+        this._init(options)
+      }
       ChildVue.options = BaseCtor.options
       ChildVue.linker = BaseCtor.linker
       ChildVue.prototype = context

+ 3 - 21
src/api/global.js

@@ -36,11 +36,9 @@ var cid = 1
 exports.extend = function (extendOptions) {
   extendOptions = extendOptions || {}
   var Super = this
-  var Sub = createClass(
-    extendOptions.name ||
-    Super.options.name ||
-    'VueComponent'
-  )
+  var Sub = function VueComponent (options) {
+    _.Vue.call(this, options)
+  }
   Sub.prototype = Object.create(Super.prototype)
   Sub.prototype.constructor = Sub
   Sub.cid = cid++
@@ -59,22 +57,6 @@ exports.extend = function (extendOptions) {
   return Sub
 }
 
-/**
- * A function that returns a sub-class constructor with the
- * given name. This gives us much nicer output when
- * logging instances in the console.
- *
- * @param {String} name
- * @return {Function}
- */
-
-function createClass (name) {
-  return new Function(
-    'return function ' + _.classify(name) +
-    ' (options) { this._init(options) }'
-  )()
-}
-
 /**
  * Plugin system
  *

+ 17 - 2
src/parsers/expression.js

@@ -1,6 +1,7 @@
 var _ = require('../util')
 var Path = require('./path')
 var Cache = require('../cache')
+var notevil = require('../../vendor/notevil')
 var expressionCache = new Cache(1000)
 
 var allowedKeywords =
@@ -173,7 +174,13 @@ function compilePathFns (exp) {
 
 function makeGetter (body) {
   try {
-    return new Function('scope', 'return ' + body + ';')
+    var fn = notevil.Function(
+      'scope', 'Math',
+      'return ' + body + ';'
+    )
+    return function (scope) {
+      return fn.call(this, scope, Math)
+    }
   } catch (e) {
     process.env.NODE_ENV !== 'production' && _.warn(
       'Invalid expression. ' +
@@ -198,7 +205,15 @@ function makeGetter (body) {
 
 function makeSetter (body) {
   try {
-    return new Function('scope', 'value', body + '=value;')
+    var fn = notevil.Function(
+      'scope', 'value', 'Math',
+      body + ' = value;'
+    )
+    return function (scope, value) {
+      try {
+        fn.call(this, scope, value, Math)
+      } catch (e) {}
+    }
   } catch (e) {
     process.env.NODE_ENV !== 'production' && _.warn(
       'Invalid setter function body: ' + body

+ 17 - 22
src/parsers/path.js

@@ -1,7 +1,7 @@
 var _ = require('../util')
 var Cache = require('../cache')
 var pathCache = new Cache(1000)
-var identRE = exports.identRE = /^[$_a-zA-Z]+[\w$]*$/
+exports.identRE = /^[$_a-zA-Z]+[\w$]*$/
 
 // actions
 var APPEND = 0
@@ -229,25 +229,6 @@ function parsePath (path) {
   }
 }
 
-/**
- * Format a accessor segment based on its type.
- *
- * @param {String} key
- * @return {Boolean}
- */
-
-function formatAccessor (key) {
-  if (identRE.test(key)) { // identifier
-    return '.' + key
-  } else if (+key === key >>> 0) { // bracket index
-    return '[' + key + ']'
-  } else if (key.charAt(0) === '*') {
-    return '[o' + formatAccessor(key.slice(1)) + ']'
-  } else { // bracket string
-    return '["' + key.replace(/"/g, '\\"') + '"]'
-  }
-}
-
 /**
  * Compiles a getter function with a fixed path.
  * The fixed path getter supresses errors.
@@ -257,8 +238,22 @@ function formatAccessor (key) {
  */
 
 exports.compileGetter = function (path) {
-  var body = 'return o' + path.map(formatAccessor).join('')
-  return new Function('o', body)
+  return function get (obj) {
+    var original = obj
+    var segment
+    for (var i = 0, l = path.length; i < l; i++) {
+      segment = path[i]
+      if (segment.charAt(0) === '*') {
+        segment = original[segment.slice(1)]
+      }
+      obj = obj[segment]
+      if (i === l - 1) {
+        return obj
+      } else if (!_.isObject(obj)) {
+        return
+      }
+    }
+  }
 }
 
 /**

+ 0 - 10
test/unit/specs/api/child_spec.js

@@ -66,14 +66,4 @@ describe('Child API', function () {
     var child2 = vm.$addChild(null, Ctor)
     expect(child1.constructor).toBe(child2.constructor)
   })
-
-  it('Use proper constructor name with inherit', function () {
-    var Ctor = Vue.extend({
-      name: 'vue-test',
-      inherit: true
-    })
-    var child = vm.$addChild(null, Ctor)
-    expect(child.constructor.toString().match(/^function VueTest\s?\(/)).toBeTruthy()
-  })
-
 })

+ 0 - 33
test/unit/specs/api/data_spec.js

@@ -44,26 +44,6 @@ describe('Data API', function () {
     expect(hasWarned(_, 'Consider pre-initializing')).toBe(true)
   })
 
-  it('$set invalid', function () {
-    // invalid, should throw
-    if (leftHandThrows()) {
-      // if creating a function with invalid left hand
-      // expression throws, the exp parser will catch the
-      // error and warn.
-      vm.$set('c + d', 1)
-      expect(hasWarned(_, 'Invalid setter function body')).toBe(true)
-    } else {
-      // otherwise it will throw when calling the setter.
-      expect(function () {
-        try {
-          vm.$set('c + d', 1)
-        } catch (e) {
-          return true
-        }
-      }()).toBe(true)
-    }
-  })
-
   it('$add', function () {
     vm._digest = jasmine.createSpy()
     vm.$add('c', 1)
@@ -187,16 +167,3 @@ describe('Data API', function () {
   }
 
 })
-
-/**
- * check if creating a new Function with invalid left-hand
- * assignment would throw
- */
-
-function leftHandThrows () {
-  try {
-    new Function('a + b = 1')
-  } catch (e) {
-    return true
-  }
-}

+ 0 - 2
test/unit/specs/api/global_spec.js

@@ -19,8 +19,6 @@ describe('Global API', function () {
     expect(Test.options.a).toBe(1)
     expect(Test.options.b).toBe(2)
     expect(Test.super).toBe(Vue)
-    // function.name is not available in IE
-    expect(Test.toString().match(/^function Test\s?\(/)).toBeTruthy()
     var t = new Test({
       a: 2
     })

+ 0 - 21
test/unit/specs/parsers/expression_spec.js

@@ -198,33 +198,12 @@ var testCases = [
     expected: true,
     paths: []
   },
-  {
-    // Date global
-    exp: 'Date.now() > new Date("2000-01-01")',
-    scope: {},
-    expected: true,
-    paths: []
-  },
   // typeof operator
   {
     exp: 'typeof test === "string"',
     scope: { test: '123' },
     expected: true,
     paths: ['test']
-  },
-  // isNaN
-  {
-    exp: 'isNaN(a)',
-    scope: { a: 2 },
-    expected: false,
-    paths: ['a']
-  },
-  // parseFloat & parseInt
-  {
-    exp: 'parseInt(a, 10) + parseFloat(b)',
-    scope: { a: 2.33, b: '3.45' },
-    expected: 5.45,
-    paths: ['a', 'b']
   }
 ]
 

Разлика између датотеке није приказан због своје велике величине
+ 748 - 0
vendor/notevil.js


Неке датотеке нису приказане због велике количине промена