保誠-保戶業務員媒合平台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* @flow */
 
// this will be preserved during build
// $flow-disable-line
const VueFactory = require('./factory')
 
const instanceOptions: { [key: string]: WeexInstanceOption } = {}
 
/**
 * Create instance context.
 */
export function createInstanceContext (
  instanceId: string,
  runtimeContext: WeexRuntimeContext,
  data: Object = {}
): WeexInstanceContext {
  const weex: Weex = runtimeContext.weex
  const instance: WeexInstanceOption = instanceOptions[instanceId] = {
    instanceId,
    config: weex.config,
    document: weex.document,
    data
  }
 
  // Each instance has a independent `Vue` module instance
  const Vue = instance.Vue = createVueModuleInstance(instanceId, weex)
 
  // DEPRECATED
  const timerAPIs = getInstanceTimer(instanceId, weex.requireModule)
 
  const instanceContext = Object.assign({ Vue }, timerAPIs)
  Object.freeze(instanceContext)
  return instanceContext
}
 
/**
 * Destroy an instance with id. It will make sure all memory of
 * this instance released and no more leaks.
 */
export function destroyInstance (instanceId: string): void {
  const instance = instanceOptions[instanceId]
  if (instance && instance.app instanceof instance.Vue) {
    try {
      instance.app.$destroy()
      instance.document.destroy()
    } catch (e) {}
    delete instance.document
    delete instance.app
  }
  delete instanceOptions[instanceId]
}
 
/**
 * Refresh an instance with id and new top-level component data.
 * It will use `Vue.set` on all keys of the new data. So it's better
 * define all possible meaningful keys when instance created.
 */
export function refreshInstance (
  instanceId: string,
  data: Object
): Error | void {
  const instance = instanceOptions[instanceId]
  if (!instance || !(instance.app instanceof instance.Vue)) {
    return new Error(`refreshInstance: instance ${instanceId} not found!`)
  }
  if (instance.Vue && instance.Vue.set) {
    for (const key in data) {
      instance.Vue.set(instance.app, key, data[key])
    }
  }
  // Finally `refreshFinish` signal needed.
  instance.document.taskCenter.send('dom', { action: 'refreshFinish' }, [])
}
 
/**
 * Create a fresh instance of Vue for each Weex instance.
 */
function createVueModuleInstance (
  instanceId: string,
  weex: Weex
): GlobalAPI {
  const exports = {}
  VueFactory(exports, weex.document)
  const Vue = exports.Vue
 
  const instance = instanceOptions[instanceId]
 
  // patch reserved tag detection to account for dynamically registered
  // components
  const weexRegex = /^weex:/i
  const isReservedTag = Vue.config.isReservedTag || (() => false)
  const isRuntimeComponent = Vue.config.isRuntimeComponent || (() => false)
  Vue.config.isReservedTag = name => {
    return (!isRuntimeComponent(name) && weex.supports(`@component/${name}`)) ||
      isReservedTag(name) ||
      weexRegex.test(name)
  }
  Vue.config.parsePlatformTagName = name => name.replace(weexRegex, '')
 
  // expose weex-specific info
  Vue.prototype.$instanceId = instanceId
  Vue.prototype.$document = instance.document
 
  // expose weex native module getter on subVue prototype so that
  // vdom runtime modules can access native modules via vnode.context
  Vue.prototype.$requireWeexModule = weex.requireModule
 
  // Hack `Vue` behavior to handle instance information and data
  // before root component created.
  Vue.mixin({
    beforeCreate () {
      const options = this.$options
      // root component (vm)
      if (options.el) {
        // set external data of instance
        const dataOption = options.data
        const internalData = (typeof dataOption === 'function' ? dataOption() : dataOption) || {}
        options.data = Object.assign(internalData, instance.data)
        // record instance by id
        instance.app = this
      }
    },
    mounted () {
      const options = this.$options
      // root component (vm)
      if (options.el && weex.document && instance.app === this) {
        try {
          // Send "createFinish" signal to native.
          weex.document.taskCenter.send('dom', { action: 'createFinish' }, [])
        } catch (e) {}
      }
    }
  })
 
  /**
   * @deprecated Just instance variable `weex.config`
   * Get instance config.
   * @return {object}
   */
  Vue.prototype.$getConfig = function () {
    if (instance.app instanceof Vue) {
      return instance.config
    }
  }
 
  return Vue
}
 
/**
 * DEPRECATED
 * Generate HTML5 Timer APIs. An important point is that the callback
 * will be converted into callback id when sent to native. So the
 * framework can make sure no side effect of the callback happened after
 * an instance destroyed.
 */
function getInstanceTimer (
  instanceId: string,
  moduleGetter: Function
): Object {
  const instance = instanceOptions[instanceId]
  const timer = moduleGetter('timer')
  const timerAPIs = {
    setTimeout: (...args) => {
      const handler = function () {
        args[0](...args.slice(2))
      }
 
      timer.setTimeout(handler, args[1])
      return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
    },
    setInterval: (...args) => {
      const handler = function () {
        args[0](...args.slice(2))
      }
 
      timer.setInterval(handler, args[1])
      return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
    },
    clearTimeout: (n) => {
      timer.clearTimeout(n)
    },
    clearInterval: (n) => {
      timer.clearInterval(n)
    }
  }
  return timerAPIs
}