1
1
// @flow
2
2
3
- import Vue from 'vue'
4
3
import { compileToFunctions } from 'vue-template-compiler'
5
- import { throwError } from './util'
6
- import { componentNeedsCompiling } from './validators'
7
- import { compileTemplate } from './compile-template'
8
- import { capitalize , camelize , hyphenate } from './util'
9
-
10
- function isVueComponent ( comp ) {
11
- return comp && ( comp . render || comp . template || comp . options )
12
- }
13
-
14
- function isValidStub ( stub : any ) {
15
- return ! ! stub &&
16
- typeof stub === 'string' ||
17
- ( stub === true ) ||
18
- ( isVueComponent ( stub ) )
19
- }
20
-
21
- function isRequiredComponent ( name ) {
22
- return name === 'KeepAlive' || name === 'Transition' || name === 'TransitionGroup'
23
- }
4
+ import { validateStubOptions } from 'shared/stub-components-validate'
5
+ import { componentNeedsCompiling } from 'shared/validators'
6
+ import { compileTemplate } from 'shared/compile-template'
24
7
25
8
function getCoreProperties ( component : Component ) : Object {
9
+ if ( ! component ) return { }
26
10
return {
27
11
attrs : component . attrs ,
28
12
name : component . name ,
@@ -40,147 +24,68 @@ function getCoreProperties (component: Component): Object {
40
24
functional : component . functional
41
25
}
42
26
}
43
- function createStubFromString ( templateString : string , originalComponent : Component ) : Object {
44
- if ( ! compileToFunctions ) {
45
- throwError ( 'vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined' )
46
- }
47
-
48
- if ( templateString . indexOf ( hyphenate ( originalComponent . name ) ) !== - 1 ||
49
- templateString . indexOf ( capitalize ( originalComponent . name ) ) !== - 1 ||
50
- templateString . indexOf ( camelize ( originalComponent . name ) ) !== - 1 ) {
51
- throwError ( 'options.stub cannot contain a circular reference' )
52
- }
53
27
28
+ function createStubFromString ( originalComponent : Component , template : string ) : Object {
54
29
return {
55
30
...getCoreProperties ( originalComponent ) ,
56
- ...compileToFunctions ( templateString )
31
+ ...compileToFunctions ( template )
57
32
}
58
33
}
59
34
60
- function createBlankStub ( originalComponent : Component ) {
35
+ function createBlankStub ( originalComponent : Component ) : Object {
61
36
return {
62
37
...getCoreProperties ( originalComponent ) ,
63
38
render : h => h ( '' )
64
39
}
65
40
}
66
41
67
- export function createComponentStubs ( originalComponents : Object = { } , stubs : Object ) : Object {
68
- const components = { }
69
- if ( ! stubs ) {
70
- return components
71
- }
72
- if ( Array . isArray ( stubs ) ) {
73
- stubs . forEach ( stub => {
74
- if ( stub === false ) {
75
- return
76
- }
42
+ function createStubFromComponent ( component : Component , name : string ) : Object {
43
+ if ( componentNeedsCompiling ( component ) ) compileTemplate ( component )
44
+ return name ? { ...component , name } : component
45
+ }
77
46
78
- if ( typeof stub !== 'string' ) {
79
- throwError ( 'each item in an options.stubs array must be a string' )
80
- }
81
- components [ stub ] = createBlankStub ( { } )
82
- } )
47
+ function createStub ( originalComponent : Component , stubValue ) : Object {
48
+ if ( stubValue === true ) {
49
+ return createBlankStub ( originalComponent )
50
+ } else if ( typeof stubValue === 'string' ) {
51
+ return createStubFromString ( originalComponent , stubValue )
83
52
} else {
84
- Object . keys ( stubs ) . forEach ( stub => {
85
- if ( stubs [ stub ] === false ) {
86
- return
87
- }
88
- if ( ! isValidStub ( stubs [ stub ] ) ) {
89
- throwError ( 'options.stub values must be passed a string or component' )
90
- }
91
- if ( stubs [ stub ] === true ) {
92
- components [ stub ] = createBlankStub ( { } )
93
- return
94
- }
95
-
96
- if ( componentNeedsCompiling ( stubs [ stub ] ) ) {
97
- compileTemplate ( stubs [ stub ] )
98
- }
99
-
100
- if ( originalComponents [ stub ] ) {
101
- // Remove cached constructor
102
- delete originalComponents [ stub ] . _Ctor
103
- if ( typeof stubs [ stub ] === 'string' ) {
104
- components [ stub ] = createStubFromString ( stubs [ stub ] , originalComponents [ stub ] )
105
- } else {
106
- components [ stub ] = {
107
- ...stubs [ stub ] ,
108
- name : originalComponents [ stub ] . name
109
- }
110
- }
111
- } else {
112
- if ( typeof stubs [ stub ] === 'string' ) {
113
- if ( ! compileToFunctions ) {
114
- throwError ( 'vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined' )
115
- }
116
- components [ stub ] = {
117
- ...compileToFunctions ( stubs [ stub ] )
118
- }
119
- } else {
120
- components [ stub ] = {
121
- ...stubs [ stub ]
122
- }
123
- }
124
- }
125
- // ignoreElements does not exist in Vue 2.0.x
126
- if ( Vue . config . ignoredElements ) {
127
- Vue . config . ignoredElements . push ( stub )
128
- }
129
- } )
53
+ return createStubFromComponent ( stubValue , originalComponent && originalComponent . name )
130
54
}
131
- return components
132
- }
133
-
134
- function stubComponents ( components : Object , stubbedComponents : Object ) {
135
- Object . keys ( components ) . forEach ( component => {
136
- // Remove cached constructor
137
- delete components [ component ] . _Ctor
138
- if ( ! components [ component ] . name ) {
139
- components [ component ] . name = component
140
- }
141
- stubbedComponents [ component ] = createBlankStub ( components [ component ] )
142
-
143
- // ignoreElements does not exist in Vue 2.0.x
144
- if ( Vue . config . ignoredElements ) {
145
- Vue . config . ignoredElements . push ( component )
146
- }
147
- } )
148
55
}
149
56
150
- export function createComponentStubsForAll ( component : Component ) : Object {
151
- const stubbedComponents = { }
152
-
153
- if ( component . components ) {
154
- stubComponents ( component . components , stubbedComponents )
57
+ function normalizeStubOptions ( components : ?Object , stubOptions : ?Object | Array < string > ) : Object {
58
+ if ( ! stubOptions ) {
59
+ stubOptions = Object . keys ( components || { } )
155
60
}
156
-
157
- let extended = component . extends
158
-
159
- // Loop through extended component chains to stub all child components
160
- while ( extended ) {
161
- if ( extended . components ) {
162
- stubComponents ( extended . components , stubbedComponents )
163
- }
164
- extended = extended . extends
61
+ if ( Array . isArray ( stubOptions ) ) {
62
+ stubOptions = stubOptions . reduce ( ( object , name ) => {
63
+ object [ name ] = true
64
+ return object
65
+ } , { } )
165
66
}
67
+ return stubOptions
68
+ }
166
69
167
- if ( component . extendOptions && component . extendOptions . components ) {
168
- stubComponents ( component . extendOptions . components , stubbedComponents )
169
- }
70
+ export function createComponentStubs ( components : Object = { } , stubOptions : Object ) : Object {
71
+ validateStubOptions ( stubOptions )
72
+ return createStubs ( components , stubOptions )
73
+ }
170
74
171
- return stubbedComponents
75
+ export function createComponentStubsForAll ( component : Component , stubs : Object = { } ) : Object {
76
+ if ( ! component ) return stubs
77
+ Object . assign ( stubs , createStubs ( component . components ) )
78
+ return createComponentStubsForAll ( component . extends || component . extendOptions , stubs )
172
79
}
173
80
174
- export function createComponentStubsForGlobals ( instance : Component ) : Object {
175
- const components = { }
176
- Object . keys ( instance . options . components ) . forEach ( ( c ) => {
177
- if ( isRequiredComponent ( c ) ) {
178
- return
179
- }
81
+ export function createStubs ( components : Object , stubOptions : ?Object | Array < string > ) : Object {
82
+ const options : Object = normalizeStubOptions ( components , stubOptions )
180
83
181
- components [ c ] = createBlankStub ( instance . options . components [ c ] )
182
- delete instance . options . components [ c ] . _Ctor // eslint-disable-line no-param-reassign
183
- delete components [ c ] . _Ctor // eslint-disable-line no-param-reassign
184
- } )
185
- return components
84
+ return Object . keys ( options )
85
+ . filter ( name => ! [ 'KeepAlive' , 'Transition' , 'TransitionGroup' ] . includes ( name ) )
86
+ . filter ( name => options [ name ] !== false )
87
+ . reduce ( ( stubs , name ) => {
88
+ stubs [ name ] = createStub ( components [ name ] , options [ name ] )
89
+ return stubs
90
+ } , { } )
186
91
}
0 commit comments