1+ /* @flow */
2+
13// this will be preserved during build
4+ // $flow-disable-line
25const VueFactory = require ( './factory' )
36
4- const instances = { }
5-
6- /**
7- * Prepare framework config.
8- * Nothing need to do actually, just an interface provided to weex runtime.
9- */
10- export function init ( ) { }
11-
12- /**
13- * Reset framework config and clear all registrations.
14- */
15- export function reset ( ) {
16- clear ( instances )
17- }
7+ const instanceOptions : { [ key : string ] : WeexInstanceOption } = { }
188
199/**
20- * Delete all keys of an object.
21- * @param {object } obj
10+ * Create instance context.
2211 */
23- function clear ( obj ) {
24- for ( const key in obj ) {
25- delete obj [ key ]
12+ export function createInstanceContext (
13+ instanceId : string ,
14+ runtimeContext : WeexRuntimeContext ,
15+ data : Object = { }
16+ ) : WeexInstanceContext {
17+ const weex : Weex = runtimeContext . weex
18+ const instance : WeexInstanceOption = instanceOptions [ instanceId ] = {
19+ instanceId,
20+ config : weex . config ,
21+ document : weex . document ,
22+ data
2623 }
27- }
28-
29- /**
30- * Create an instance with id, code, config and external data.
31- * @param {string } instanceId
32- * @param {string } appCode
33- * @param {object } config
34- * @param {object } data
35- * @param {object } env { info, config, services }
36- */
37- export function createInstance (
38- instanceId ,
39- appCode = '' ,
40- config = { } ,
41- data ,
42- env = { }
43- ) {
44- const weex = env . weex
45- const document = weex . document
46- const instance = instances [ instanceId ] = {
47- instanceId, config, data,
48- document
49- }
50-
51- const timerAPIs = getInstanceTimer ( instanceId , weex . requireModule )
5224
5325 // Each instance has a independent `Vue` module instance
5426 const Vue = instance . Vue = createVueModuleInstance ( instanceId , weex )
5527
56- // The function which create a closure the JS Bundle will run in.
57- // It will declare some instance variables like `Vue`, HTML5 Timer APIs etc.
58- const instanceVars = Object . assign ( {
59- Vue,
60- weex
61- } , timerAPIs , env . services )
62-
63- appCode = `(function(global){ \n${ appCode } \n })(Object.create(this))`
64- callFunction ( instanceVars , appCode )
28+ // DEPRECATED
29+ const timerAPIs = getInstanceTimer ( instanceId , weex . requireModule )
6530
66- return instance
31+ const instanceContext = Object . assign ( { Vue } , timerAPIs )
32+ Object . freeze ( instanceContext )
33+ return instanceContext
6734}
6835
6936/**
7037 * Destroy an instance with id. It will make sure all memory of
7138 * this instance released and no more leaks.
72- * @param {string } instanceId
7339 */
74- export function destroyInstance ( instanceId ) {
75- const instance = instances [ instanceId ]
40+ export function destroyInstance ( instanceId : string ) : void {
41+ const instance = instanceOptions [ instanceId ]
7642 if ( instance && instance . app instanceof instance . Vue ) {
77- instance . document . destroy ( )
78- instance . app . $destroy ( )
43+ try {
44+ instance . app . $destroy ( )
45+ instance . document . destroy ( )
46+ } catch ( e ) { }
7947 delete instance . document
8048 delete instance . app
8149 }
82- delete instances [ instanceId ]
50+ delete instanceOptions [ instanceId ]
8351}
8452
8553/**
8654 * Refresh an instance with id and new top-level component data.
8755 * It will use `Vue.set` on all keys of the new data. So it's better
8856 * define all possible meaningful keys when instance created.
89- * @param {string } instanceId
90- * @param {object } data
9157 */
92- export function refreshInstance ( instanceId , data ) {
93- const instance = instances [ instanceId ]
58+ export function refreshInstance (
59+ instanceId : string ,
60+ data : Object
61+ ) : Error | void {
62+ const instance = instanceOptions [ instanceId ]
9463 if ( ! instance || ! ( instance . app instanceof instance . Vue ) ) {
9564 return new Error ( `refreshInstance: instance ${ instanceId } not found!` )
9665 }
97- for ( const key in data ) {
98- instance . Vue . set ( instance . app , key , data [ key ] )
66+ if ( instance . Vue && instance . Vue . set ) {
67+ for ( const key in data ) {
68+ instance . Vue . set ( instance . app , key , data [ key ] )
69+ }
9970 }
10071 // Finally `refreshFinish` signal needed.
10172 instance . document . taskCenter . send ( 'dom' , { action : 'refreshFinish' } , [ ] )
10273}
10374
104- /**
105- * Get the JSON object of the root element.
106- * @param {string } instanceId
107- */
108- export function getRoot ( instanceId ) {
109- const instance = instances [ instanceId ]
110- if ( ! instance || ! ( instance . app instanceof instance . Vue ) ) {
111- return new Error ( `getRoot: instance ${ instanceId } not found!` )
112- }
113- return instance . app . $el . toJSON ( )
114- }
115-
11675/**
11776 * Create a fresh instance of Vue for each Weex instance.
11877 */
119- function createVueModuleInstance ( instanceId , weex ) {
78+ function createVueModuleInstance (
79+ instanceId : string ,
80+ weex : Weex
81+ ) : GlobalAPI {
12082 const exports = { }
12183 VueFactory ( exports , weex . document )
12284 const Vue = exports . Vue
12385
124- const instance = instances [ instanceId ]
86+ const instance = instanceOptions [ instanceId ]
12587
12688 // patch reserved tag detection to account for dynamically registered
12789 // components
@@ -161,7 +123,7 @@ function createVueModuleInstance (instanceId, weex) {
161123 mounted ( ) {
162124 const options = this . $options
163125 // root component (vm)
164- if ( options . el && weex . document ) {
126+ if ( options . el && weex . document && instance . app === this ) {
165127 try {
166128 // Send "createFinish" signal to native.
167129 weex . document . taskCenter . send ( 'dom' , { action : 'createFinish' } , [ ] )
@@ -185,16 +147,17 @@ function createVueModuleInstance (instanceId, weex) {
185147}
186148
187149/**
150+ * DEPRECATED
188151 * Generate HTML5 Timer APIs. An important point is that the callback
189152 * will be converted into callback id when sent to native. So the
190153 * framework can make sure no side effect of the callback happened after
191154 * an instance destroyed.
192- * @param {[type] } instanceId [description]
193- * @param {[type] } moduleGetter [description]
194- * @return {[type] } [description]
195155 */
196- function getInstanceTimer ( instanceId , moduleGetter ) {
197- const instance = instances [ instanceId ]
156+ function getInstanceTimer (
157+ instanceId : string ,
158+ moduleGetter : Function
159+ ) : Object {
160+ const instance = instanceOptions [ instanceId ]
198161 const timer = moduleGetter ( 'timer' )
199162 const timerAPIs = {
200163 setTimeout : ( ...args ) => {
@@ -222,22 +185,3 @@ function getInstanceTimer (instanceId, moduleGetter) {
222185 }
223186 return timerAPIs
224187}
225-
226- /**
227- * Call a new function body with some global objects.
228- * @param {object } globalObjects
229- * @param {string } code
230- * @return {any }
231- */
232- function callFunction ( globalObjects , body ) {
233- const globalKeys = [ ]
234- const globalValues = [ ]
235- for ( const key in globalObjects ) {
236- globalKeys . push ( key )
237- globalValues . push ( globalObjects [ key ] )
238- }
239- globalKeys . push ( body )
240-
241- const result = new Function ( ...globalKeys )
242- return result ( ...globalValues )
243- }
0 commit comments