Skip to content

Commit 83bc7ff

Browse files
committed
Merge branch 'dev' of https://github.com/vuejs/vue into dev
* 'dev' of https://github.com/vuejs/vue: build: use cross-platform hook installation with shelljs build: move test config files into /test build: add script for generating release note build: add git commit message validation fix(v-model): use consistent behavior during IME composition for other text-like input types (fix vuejs#5902) simplify source with rest params fix slot resolved incorrect with abstract component (fix vuejs#5888) (vuejs#5895) test:improve reserved props test test:add bind object test fix:when using object syntax in v-bind, special attribute have no effect Be able to use string type index in array (vuejs#5889) Merge inject when extending a component (vuejs#5827) # Conflicts: # .gitignore # src/core/util/options.js
2 parents fb8d5b5 + b5f08f3 commit 83bc7ff

33 files changed

+851
-86
lines changed

.github/COMMIT_CONVENTION.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
## Git Commit Message Convention
2+
3+
> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-angular/convention.md).
4+
5+
#### Examples
6+
7+
Appears under "Features" header, pencil subheader:
8+
9+
```
10+
feat(pencil): add 'graphiteWidth' option
11+
```
12+
13+
Appears under "Bug Fixes" header, graphite subheader, with a link to issue #28:
14+
15+
```
16+
fix(graphite): stop graphite breaking when width < 0.1
17+
18+
close #28
19+
```
20+
21+
Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
22+
23+
```
24+
perf(pencil): remove graphiteWidth option
25+
26+
BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason.
27+
```
28+
29+
The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
30+
31+
```
32+
revert: feat(pencil): add 'graphiteWidth' option
33+
34+
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
35+
```
36+
37+
### Full Message Format
38+
39+
A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
40+
41+
```
42+
<type>(<scope>): <subject>
43+
<BLANK LINE>
44+
<body>
45+
<BLANK LINE>
46+
<footer>
47+
```
48+
49+
The **header** is mandatory and the **scope** of the header is optional.
50+
51+
### Revert
52+
53+
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
54+
55+
### Type
56+
57+
If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.
58+
59+
Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.
60+
61+
### Scope
62+
63+
The scope could be anything specifying place of the commit change. For example `core`, `compiler`, `ssr`, `v-model`, `transition` etc...
64+
65+
### Subject
66+
67+
The subject contains succinct description of the change:
68+
69+
* use the imperative, present tense: "change" not "changed" nor "changes"
70+
* don't capitalize first letter
71+
* no dot (.) at the end
72+
73+
### Body
74+
75+
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
76+
The body should include the motivation for the change and contrast this with previous behavior.
77+
78+
### Footer
79+
80+
The footer should contain any information about **Breaking Changes** and is also the place to
81+
reference GitHub issues that this commit **Closes**.
82+
83+
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

.github/CONTRIBUTING.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ After cloning the repo, run:
4343
$ npm install
4444
```
4545

46-
If you are on a Unix-like system, optionally install the Git pre-commit hook with:
46+
This will also run the `postinstall` script which links two git hooks:
4747

48-
``` bash
49-
$ npm run install:hooks
50-
```
48+
- `pre-commit`: runs ESLint on staged files.
49+
- `commit-msg`: validates commit message format (see below).
50+
51+
### Commiting Changes
5152

52-
This will run ESLint on changed files before each commit.
53+
Commit messages should follow the [commit message convention](./COMMIT_CONVENTION.md) so that changelogs can be automatically generated. If git hooks have been properly linked, commit messages will be automatically validated upon commit. It is recommended to use `npm run commit` instead of `git commit`, which provides an interactive CLI for generating proper commit messages.
5354

5455
### Commonly used NPM scripts
5556

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ dist/vue.common.min.js
99
test/e2e/reports
1010
test/e2e/screenshots
1111
coverage
12+
RELEASE_NOTE*.md
1213
.idea/
1314
components/
1415
test/vue.test.js
16+

build/.eslintrc

-5
This file was deleted.

build/gen-release-note.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const version = process.env.VERSION
2+
const cc = require('conventional-changelog')
3+
const file = `./RELEASE_NOTE_${version}.md`
4+
const fileStream = require('fs').createWriteStream(file)
5+
6+
cc({
7+
preset: 'angular',
8+
pkg: {
9+
transform (pkg) {
10+
pkg.version = `v${version}`
11+
return pkg
12+
}
13+
}
14+
}).pipe(fileStream).on('close', () => {
15+
console.log(`Generated release note at ${file}`)
16+
})

build/git-hooks/commit-msg

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
3+
# Validate commit log
4+
commit_regex='^Merge.+|(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,50}'
5+
6+
if ! grep -iqE "$commit_regex" "$1"; then
7+
echo
8+
echo " Error: proper commit message format is required for automated changelog generation."
9+
echo
10+
echo " - Use \`npm run commit\` to interactively generate a commit message."
11+
echo " - See .github/COMMIT_CONVENTION.md for more details."
12+
echo
13+
exit 1
14+
fi

build/install-hooks.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const { test, ln, chmod } = require('shelljs')
2+
3+
if (test('-e', '.git/hooks')) {
4+
ln('-sf', '../../build/git-hooks/pre-commit', '.git/hooks/pre-commit')
5+
chmod('+x', '.git/hooks/pre-commit')
6+
ln('-sf', '../../build/git-hooks/commit-msg', '.git/hooks/commit-msg')
7+
chmod('+x', '.git/hooks/commit-msg')
8+
}

build/release.sh

+3
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
5858
else
5959
npm publish --tag $RELEASE_TAG
6060
fi
61+
62+
# generate release note
63+
VERSION=$VERSION npm run release:note
6164
fi

flow/vnode.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ declare interface VNodeData {
3535
key?: string | number;
3636
slot?: string;
3737
ref?: string;
38+
is?: string;
3839
pre?: boolean;
3940
tag?: string;
4041
staticClass?: string;

package.json

+16-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev",
1616
"dev:cjs": "rollup -w -c build/config.js --environment TARGET:web-runtime-cjs",
1717
"dev:esm": "rollup -w -c build/config.js --environment TARGET:web-runtime-esm",
18-
"dev:test": "karma start build/karma.dev.config.js",
18+
"dev:test": "karma start test/unit/karma.dev.config.js",
1919
"dev:ssr": "rollup -w -c build/config.js --environment TARGET:web-server-renderer",
2020
"dev:compiler": "rollup -w -c build/config.js --environment TARGET:web-compiler ",
2121
"dev:weex": "rollup -w -c build/config.js --environment TARGET:weex-framework ",
@@ -24,20 +24,22 @@
2424
"build:ssr": "npm run build -- vue.runtime.common.js,vue-server-renderer",
2525
"build:weex": "npm run build -- weex-vue-framework,weex-template-compiler",
2626
"test": "npm run lint && flow check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex",
27-
"test:unit": "karma start build/karma.unit.config.js",
28-
"test:cover": "karma start build/karma.cover.config.js",
27+
"test:unit": "karma start test/unit/karma.unit.config.js",
28+
"test:cover": "karma start test/unit/karma.cover.config.js",
2929
"test:e2e": "npm run build -- vue.min.js && node test/e2e/runner.js",
3030
"test:weex": "npm run build:weex && jasmine JASMINE_CONFIG_PATH=test/weex/jasmine.json",
3131
"test:ssr": "npm run build:ssr && jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.json",
3232
"test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2",
3333
"test:types": "tsc -p ./types/test/tsconfig.json",
3434
"lint": "eslint src build test",
3535
"flow": "flow check",
36-
"sauce": "karma start build/karma.sauce.config.js",
36+
"sauce": "karma start test/unit/karma.sauce.config.js",
3737
"bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js",
3838
"release": "bash build/release.sh",
3939
"release:weex": "bash build/release-weex.sh",
40-
"install:hooks": "ln -fs ../../build/git-hooks/pre-commit .git/hooks/pre-commit"
40+
"release:note": "node build/gen-release-note.js",
41+
"postinstall": "node build/install-hooks.js",
42+
"commit": "git-cz"
4143
},
4244
"repository": {
4345
"type": "git",
@@ -67,7 +69,10 @@
6769
"chalk": "^1.1.3",
6870
"chromedriver": "^2.30.1",
6971
"codecov.io": "^0.1.6",
72+
"commitizen": "^2.9.6",
73+
"conventional-changelog": "^1.1.3",
7074
"cross-spawn": "^5.1.0",
75+
"cz-conventional-changelog": "^2.0.0",
7176
"de-indent": "^1.0.2",
7277
"es6-promise": "^4.1.0",
7378
"eslint": "^3.0.0",
@@ -112,10 +117,16 @@
112117
"rollup-watch": "^4.0.0",
113118
"selenium-server": "^2.53.1",
114119
"serialize-javascript": "^1.3.0",
120+
"shelljs": "^0.7.8",
115121
"typescript": "^2.3.4",
116122
"uglify-js": "^3.0.15",
117123
"webpack": "^2.6.1",
118124
"weex-js-runtime": "^0.20.5",
119125
"weex-vdom-tester": "^0.2.0"
126+
},
127+
"config": {
128+
"commitizen": {
129+
"path": "./node_modules/cz-conventional-changelog"
130+
}
120131
}
121132
}

src/core/instance/inject.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,14 @@ export function initInjections (vm: Component) {
3838
export function resolveInject (inject: any, vm: Component): ?Object {
3939
if (inject) {
4040
// inject is :any because flow is not smart enough to figure out cached
41-
// isArray here
42-
const isArray = Array.isArray(inject)
4341
const result = Object.create(null)
44-
const keys = isArray
45-
? inject
46-
: hasSymbol
42+
const keys = hasSymbol
4743
? Reflect.ownKeys(inject)
4844
: Object.keys(inject)
4945

5046
for (let i = 0; i < keys.length; i++) {
5147
const key = keys[i]
52-
const provideKey = isArray ? key : inject[key]
48+
const provideKey = inject[key]
5349
let source = vm
5450
while (source) {
5551
if (source._provided && provideKey in source._provided) {

src/core/instance/render-helpers/bind-object-props.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
/* @flow */
22

33
import config from 'core/config'
4-
import { isObject, warn, toObject } from 'core/util/index'
4+
5+
import {
6+
warn,
7+
isObject,
8+
toObject,
9+
isReservedAttribute
10+
} from 'core/util/index'
511

612
/**
713
* Runtime helper for merging v-bind="object" into a VNode's data.
@@ -24,7 +30,11 @@ export function bindObjectProps (
2430
}
2531
let hash
2632
for (const key in value) {
27-
if (key === 'class' || key === 'style') {
33+
if (
34+
key === 'class' ||
35+
key === 'style' ||
36+
isReservedAttribute(key)
37+
) {
2838
hash = data
2939
} else {
3040
const type = data.attrs && data.attrs.type

src/core/instance/state.js

+3-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import {
2020
isReserved,
2121
handleError,
2222
validateProp,
23-
isPlainObject
23+
isPlainObject,
24+
isReservedAttribute
2425
} from '../util/index'
2526

2627
const sharedPropertyDefinition = {
@@ -54,12 +55,6 @@ export function initState (vm: Component) {
5455
if (opts.watch) initWatch(vm, opts.watch)
5556
}
5657

57-
const isReservedProp = {
58-
key: 1,
59-
ref: 1,
60-
slot: 1
61-
}
62-
6358
function checkOptionType (vm: Component, name: string) {
6459
const option = vm.$options[name]
6560
if (!isPlainObject(option)) {
@@ -84,7 +79,7 @@ function initProps (vm: Component, propsOptions: Object) {
8479
const value = validateProp(key, propsOptions, propsData, vm)
8580
/* istanbul ignore else */
8681
if (process.env.NODE_ENV !== 'production') {
87-
if (isReservedProp[key] || config.isReservedAttr(key)) {
82+
if (isReservedAttribute(key) || config.isReservedAttr(key)) {
8883
warn(
8984
`"${key}" is a reserved attribute and cannot be used as component prop.`,
9085
vm

src/core/observer/array.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,7 @@ export const arrayMethods = Object.create(arrayProto)
2323
.forEach(function (method) {
2424
// cache original method
2525
const original = arrayProto[method]
26-
def(arrayMethods, method, function mutator () {
27-
// avoid leaking arguments:
28-
// http://jsperf.com/closure-with-arguments
29-
let i = arguments.length
30-
const args = new Array(i)
31-
while (i--) {
32-
args[i] = arguments[i]
33-
}
26+
def(arrayMethods, method, function mutator (...args) {
3427
const result = original.apply(this, args)
3528
const ob = this.__ob__
3629
let inserted

src/core/observer/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export function defineReactive (
189189
* already exist.
190190
*/
191191
export function set (target: Array<any> | Object, key: any, val: any): any {
192-
if (Array.isArray(target) && typeof key === 'number') {
192+
if (Array.isArray(target) && (typeof key === 'number' || /^\d+$/.test(key))) {
193193
target.length = Math.max(target.length, key)
194194
target.splice(key, 1, val)
195195
return val

src/core/util/options.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
182182
*/
183183
strats.props =
184184
strats.methods =
185-
strats.computed = function (parentVal: ?Odject, childVal: ?Object): ?Object {
185+
strats.inject =
186+
strats.computed = function (parentVal: ?Object, childVal: ?Object): ?Object {
186187
if (!childVal) return Object.create(parentVal || null)
187188
if (!parentVal) return childVal
188189
const ret = Object.create(null)
@@ -247,6 +248,19 @@ function normalizeProps (options: Object) {
247248
options.props = res
248249
}
249250

251+
/**
252+
* Normalize all injections into Object-based format
253+
*/
254+
function normalizeInject (options: Object) {
255+
const inject = options.inject
256+
if (Array.isArray(inject)) {
257+
const normalized = options.inject = {}
258+
for (let i = 0; i < inject.length; i++) {
259+
normalized[inject[i]] = inject[i]
260+
}
261+
}
262+
}
263+
250264
/**
251265
* Normalize raw function directives into object format.
252266
*/
@@ -280,6 +294,7 @@ export function mergeOptions (
280294
}
281295

282296
normalizeProps(child)
297+
normalizeInject(child)
283298
normalizeDirectives(child)
284299
const extendsFrom = child.extends
285300
if (extendsFrom) {

src/core/vdom/create-component.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,14 @@ export function createComponent (
169169

170170
if (isTrue(Ctor.options.abstract)) {
171171
// abstract components do not keep anything
172-
// other than props & listeners
172+
// other than props & listeners & slot
173+
174+
// work around flow
175+
const slot = data.slot
173176
data = {}
177+
if (slot) {
178+
data.slot = slot
179+
}
174180
}
175181

176182
// merge component management hooks onto the placeholder node

0 commit comments

Comments
 (0)