Skip to content

Commit 2deda3d

Browse files
Hanks10100yyx990803
authored andcommitted
refactor(weex): Adjust the weex platform entry file to fit the new weex runtime (#6620)
* trim trailing whitespace * revert(weex): remove the new Function hack for V8, as Weex uses JSC now Remove the `callFunctionNative` method and `compileBundle`, which is provided by modified V8. In order to maintain the consistency of the js engine, Weex also use JSC on Android. The legacy hack for V8 engine should be removed. * refactor(weex): move module and component apis to weex runtime Modules and components should be registered in weex runtime, not the specific framework. The `registerModules`, `registerComponents`, `weex.supports` and `weex.requireModule` api is moved to weex runtime, which is in the "apache/incubator-weex" repo. * test(weex): refactor the test cases to fit the new weex-js-runtime * fix(weex): use document instead of renderer to create Element
1 parent 4441e0f commit 2deda3d

File tree

13 files changed

+525
-1318
lines changed

13 files changed

+525
-1318
lines changed

build/config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const banner =
1717

1818
const weexFactoryPlugin = {
1919
intro () {
20-
return 'module.exports = function weexFactory (exports, renderer) {'
20+
return 'module.exports = function weexFactory (exports, document) {'
2121
},
2222
outro () {
2323
return '}'

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@
122122
"typescript": "^2.3.4",
123123
"uglify-js": "^3.0.15",
124124
"webpack": "^2.6.1",
125-
"weex-js-runtime": "^0.20.5",
126-
"weex-vdom-tester": "^0.2.0"
125+
"weex-js-runtime": "^0.22.0"
127126
},
128127
"config": {
129128
"commitizen": {

src/platforms/weex/entry-framework.js

+16-216
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,19 @@
1-
import TextNode from 'weex/runtime/text-node'
2-
31
// this will be preserved during build
42
const VueFactory = require('./factory')
53

64
const instances = {}
7-
const modules = {}
8-
const components = {}
9-
10-
const renderer = {
11-
TextNode,
12-
instances,
13-
modules,
14-
components
15-
}
165

176
/**
18-
* Prepare framework config, basically about the virtual-DOM and JS bridge.
19-
* @param {object} cfg
7+
* Prepare framework config.
8+
* Nothing need to do actually, just an interface provided to weex runtime.
209
*/
21-
export function init (cfg) {
22-
renderer.Document = cfg.Document
23-
renderer.Element = cfg.Element
24-
renderer.Comment = cfg.Comment
25-
renderer.compileBundle = cfg.compileBundle
26-
}
10+
export function init () {}
2711

2812
/**
2913
* Reset framework config and clear all registrations.
3014
*/
3115
export function reset () {
3216
clear(instances)
33-
clear(modules)
34-
clear(components)
35-
delete renderer.Document
36-
delete renderer.Element
37-
delete renderer.Comment
38-
delete renderer.compileBundle
3917
}
4018

4119
/**
@@ -63,47 +41,31 @@ export function createInstance (
6341
data,
6442
env = {}
6543
) {
66-
// Virtual-DOM object.
67-
const document = new renderer.Document(instanceId, config.bundleUrl)
68-
44+
const weex = env.weex
45+
const document = weex.document
6946
const instance = instances[instanceId] = {
7047
instanceId, config, data,
7148
document
7249
}
7350

74-
// Prepare native module getter and HTML5 Timer APIs.
75-
const moduleGetter = genModuleGetter(instanceId)
76-
const timerAPIs = getInstanceTimer(instanceId, moduleGetter)
77-
78-
// Prepare `weex` instance variable.
79-
const weexInstanceVar = {
80-
config,
81-
document,
82-
supports,
83-
requireModule: moduleGetter
84-
}
85-
Object.freeze(weexInstanceVar)
51+
const timerAPIs = getInstanceTimer(instanceId, weex.requireModule)
8652

8753
// Each instance has a independent `Vue` module instance
88-
const Vue = instance.Vue = createVueModuleInstance(instanceId, moduleGetter)
54+
const Vue = instance.Vue = createVueModuleInstance(instanceId, weex)
8955

9056
// The function which create a closure the JS Bundle will run in.
9157
// It will declare some instance variables like `Vue`, HTML5 Timer APIs etc.
9258
const instanceVars = Object.assign({
9359
Vue,
94-
weex: weexInstanceVar
60+
weex
9561
}, timerAPIs, env.services)
9662

9763
appCode = `(function(global){ \n${appCode}\n })(Object.create(this))`
9864

99-
if (!callFunctionNative(instanceVars, appCode)) {
100-
// If failed to compile functionBody on native side,
101-
// fallback to 'callFunction()'.
102-
callFunction(instanceVars, appCode)
103-
}
65+
callFunction(instanceVars, appCode)
10466

10567
// Send `createFinish` signal to native.
106-
instance.document.taskCenter.send('dom', { action: 'createFinish' }, [])
68+
document.taskCenter.send('dom', { action: 'createFinish' }, [])
10769

10870
return instance
10971
}
@@ -118,6 +80,8 @@ export function destroyInstance (instanceId) {
11880
if (instance && instance.app instanceof instance.Vue) {
11981
instance.document.destroy()
12082
instance.app.$destroy()
83+
delete instance.document
84+
delete instance.app
12185
}
12286
delete instances[instanceId]
12387
}
@@ -200,91 +164,12 @@ export function receiveTasks (id, tasks) {
200164
return new Error(`invalid instance id "${id}" or tasks`)
201165
}
202166

203-
/**
204-
* Register native modules information.
205-
* @param {object} newModules
206-
*/
207-
export function registerModules (newModules) {
208-
for (const name in newModules) {
209-
if (!modules[name]) {
210-
modules[name] = {}
211-
}
212-
newModules[name].forEach(method => {
213-
if (typeof method === 'string') {
214-
modules[name][method] = true
215-
} else {
216-
modules[name][method.name] = method.args
217-
}
218-
})
219-
}
220-
}
221-
222-
/**
223-
* Check whether the module or the method has been registered.
224-
* @param {String} module name
225-
* @param {String} method name (optional)
226-
*/
227-
export function isRegisteredModule (name, method) {
228-
if (typeof method === 'string') {
229-
return !!(modules[name] && modules[name][method])
230-
}
231-
return !!modules[name]
232-
}
233-
234-
/**
235-
* Register native components information.
236-
* @param {array} newComponents
237-
*/
238-
export function registerComponents (newComponents) {
239-
if (Array.isArray(newComponents)) {
240-
newComponents.forEach(component => {
241-
if (!component) {
242-
return
243-
}
244-
if (typeof component === 'string') {
245-
components[component] = true
246-
} else if (typeof component === 'object' && typeof component.type === 'string') {
247-
components[component.type] = component
248-
}
249-
})
250-
}
251-
}
252-
253-
/**
254-
* Check whether the component has been registered.
255-
* @param {String} component name
256-
*/
257-
export function isRegisteredComponent (name) {
258-
return !!components[name]
259-
}
260-
261-
/**
262-
* Detects whether Weex supports specific features.
263-
* @param {String} condition
264-
*/
265-
export function supports (condition) {
266-
if (typeof condition !== 'string') return null
267-
268-
const res = condition.match(/^@(\w+)\/(\w+)(\.(\w+))?$/i)
269-
if (res) {
270-
const type = res[1]
271-
const name = res[2]
272-
const method = res[4]
273-
switch (type) {
274-
case 'module': return isRegisteredModule(name, method)
275-
case 'component': return isRegisteredComponent(name)
276-
}
277-
}
278-
279-
return null
280-
}
281-
282167
/**
283168
* Create a fresh instance of Vue for each Weex instance.
284169
*/
285-
function createVueModuleInstance (instanceId, moduleGetter) {
170+
function createVueModuleInstance (instanceId, weex) {
286171
const exports = {}
287-
VueFactory(exports, renderer)
172+
VueFactory(exports, weex.document)
288173
const Vue = exports.Vue
289174

290175
const instance = instances[instanceId]
@@ -295,7 +180,7 @@ function createVueModuleInstance (instanceId, moduleGetter) {
295180
const isReservedTag = Vue.config.isReservedTag || (() => false)
296181
const isRuntimeComponent = Vue.config.isRuntimeComponent || (() => false)
297182
Vue.config.isReservedTag = name => {
298-
return (!isRuntimeComponent(name) && components[name]) ||
183+
return (!isRuntimeComponent(name) && weex.supports(`@component/${name}`)) ||
299184
isReservedTag(name) ||
300185
weexRegex.test(name)
301186
}
@@ -307,7 +192,7 @@ function createVueModuleInstance (instanceId, moduleGetter) {
307192

308193
// expose weex native module getter on subVue prototype so that
309194
// vdom runtime modules can access native modules via vnode.context
310-
Vue.prototype.$requireWeexModule = moduleGetter
195+
Vue.prototype.$requireWeexModule = weex.requireModule
311196

312197
// Hack `Vue` behavior to handle instance information and data
313198
// before root component created.
@@ -340,39 +225,6 @@ function createVueModuleInstance (instanceId, moduleGetter) {
340225
return Vue
341226
}
342227

343-
/**
344-
* Generate native module getter. Each native module has several
345-
* methods to call. And all the behaviors is instance-related. So
346-
* this getter will return a set of methods which additionally
347-
* send current instance id to native when called.
348-
* @param {string} instanceId
349-
* @return {function}
350-
*/
351-
function genModuleGetter (instanceId) {
352-
const instance = instances[instanceId]
353-
return function (name) {
354-
const nativeModule = modules[name] || []
355-
const output = {}
356-
for (const methodName in nativeModule) {
357-
Object.defineProperty(output, methodName, {
358-
enumerable: true,
359-
configurable: true,
360-
get: function proxyGetter () {
361-
return (...args) => {
362-
return instance.document.taskCenter.send('module', { module: name, method: methodName }, args)
363-
}
364-
},
365-
set: function proxySetter (val) {
366-
if (typeof val === 'function') {
367-
return instance.document.taskCenter.send('module', { module: name, method: methodName }, [val])
368-
}
369-
}
370-
})
371-
}
372-
return output
373-
}
374-
}
375-
376228
/**
377229
* Generate HTML5 Timer APIs. An important point is that the callback
378230
* will be converted into callback id when sent to native. So the
@@ -430,55 +282,3 @@ function callFunction (globalObjects, body) {
430282
const result = new Function(...globalKeys)
431283
return result(...globalValues)
432284
}
433-
434-
/**
435-
* Call a new function generated on the V8 native side.
436-
*
437-
* This function helps speed up bundle compiling. Normally, the V8
438-
* engine needs to download, parse, and compile a bundle on every
439-
* visit. If 'compileBundle()' is available on native side,
440-
* the downloading, parsing, and compiling steps would be skipped.
441-
* @param {object} globalObjects
442-
* @param {string} body
443-
* @return {boolean}
444-
*/
445-
function callFunctionNative (globalObjects, body) {
446-
if (typeof renderer.compileBundle !== 'function') {
447-
return false
448-
}
449-
450-
let fn = void 0
451-
let isNativeCompileOk = false
452-
let script = '(function ('
453-
const globalKeys = []
454-
const globalValues = []
455-
for (const key in globalObjects) {
456-
globalKeys.push(key)
457-
globalValues.push(globalObjects[key])
458-
}
459-
for (let i = 0; i < globalKeys.length - 1; ++i) {
460-
script += globalKeys[i]
461-
script += ','
462-
}
463-
script += globalKeys[globalKeys.length - 1]
464-
script += ') {'
465-
script += body
466-
script += '} )'
467-
468-
try {
469-
const weex = globalObjects.weex || {}
470-
const config = weex.config || {}
471-
fn = renderer.compileBundle(script,
472-
config.bundleUrl,
473-
config.bundleDigest,
474-
config.codeCachePath)
475-
if (fn && typeof fn === 'function') {
476-
fn(...globalValues)
477-
isNativeCompileOk = true
478-
}
479-
} catch (e) {
480-
console.error(e)
481-
}
482-
483-
return isNativeCompileOk
484-
}

src/platforms/weex/runtime/node-ops.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
/* globals renderer */
2-
// renderer is injected by weex factory wrapper
1+
/* globals document */
2+
// document is injected by weex factory wrapper
3+
4+
import TextNode from 'weex/runtime/text-node'
35

46
export const namespaceMap = {}
57

68
export function createElement (tagName) {
7-
return new renderer.Element(tagName)
9+
return document.createElement(tagName)
810
}
911

1012
export function createElementNS (namespace, tagName) {
11-
return new renderer.Element(namespace + ':' + tagName)
13+
return document.createElement(namespace + ':' + tagName)
1214
}
1315

1416
export function createTextNode (text) {
15-
return new renderer.TextNode(text)
17+
return new TextNode(text)
1618
}
1719

1820
export function createComment (text) {
19-
return new renderer.Comment(text)
21+
return document.createComment(text)
2022
}
2123

2224
export function insertBefore (node, target, before) {

src/platforms/weex/util/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* globals renderer */
1+
/* globals document */
22

33
import { makeMap } from 'shared/util'
44

@@ -34,8 +34,8 @@ export function getTagNamespace () { /* console.log('getTagNamespace') */ }
3434
export function isUnknownElement () { /* console.log('isUnknownElement') */ }
3535

3636
export function query (el, document) {
37-
// renderer is injected by weex factory wrapper
38-
const placeholder = new renderer.Comment('root')
37+
// document is injected by weex factory wrapper
38+
const placeholder = document.createComment('root')
3939
placeholder.hasAttribute = placeholder.removeAttribute = function () {} // hack for patch
4040
document.documentElement.appendChild(placeholder)
4141
return placeholder

0 commit comments

Comments
 (0)