Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jsfm] supported return value from native #1992

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions html5/frameworks/legacy/app/ctrl/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ export function refresh (app, data) {
`in instance[${app.id}]`)
const vm = app.vm
if (vm && data) {
// app.doc.close()
if (typeof vm.refreshData === 'function') {
vm.refreshData(data)
}
else {
extend(vm, data)
}
updateActions(app)
app.doc.listener.refreshFinish()
// app.doc.open()
app.differ.flush()
app.doc.taskCenter.send('dom', { action: 'refreshFinish' }, [])
return
}
return new Error(`invalid data "${data}"`)
Expand Down Expand Up @@ -138,11 +136,9 @@ export function fireEvent (app, ref, type, e, domChanges) {
}
const el = app.doc.getRef(ref)
if (el) {
// app.doc.close()
const result = app.doc.fireEvent(el, type, e, domChanges)
updateActions(app)
app.doc.listener.updateFinish()
// app.doc.open()
app.differ.flush()
app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
return result
}
return new Error(`invalid element reference "${ref}"`)
Expand All @@ -160,14 +156,12 @@ export function callback (app, callbackId, data, ifKeepAlive) {
`in instance(${app.id})`)
const callback = app.callbacks[callbackId]
if (typeof callback === 'function') {
// app.doc.close()
callback(data)
if (typeof ifKeepAlive === 'undefined' || ifKeepAlive === false) {
app.callbacks[callbackId] = undefined
}
updateActions(app)
app.doc.listener.updateFinish()
// app.doc.open()
app.differ.flush()
app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
return
}
return new Error(`invalid callback id "${callbackId}"`)
Expand All @@ -179,14 +173,6 @@ export function callback (app, callbackId, data, ifKeepAlive) {
*/
export function updateActions (app) {
app.differ.flush()
const tasks = []
if (app.doc && app.doc.listener && app.doc.listener.updates.length) {
tasks.push(...app.doc.listener.updates)
app.doc.listener.updates = []
}
if (tasks.length) {
return callTasks(app, tasks)
}
}

/**
Expand All @@ -195,16 +181,26 @@ export function updateActions (app) {
* @param {array} tasks
*/
export function callTasks (app, tasks) {
let result

/* istanbul ignore next */
if (typof(tasks) !== 'array') {
tasks = [tasks]
}

tasks.forEach((task) => {
tasks.forEach(task => {
task.args = task.args.map(arg => normalize(arg, app))
result = app.doc.taskCenter.send(
'module',
{
module: task.module,
method: task.method
},
task.args
)
})

return renderer.sendTasks(app.id, tasks, '-1')
return result
}

/**
Expand Down
2 changes: 1 addition & 1 deletion html5/runtime/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const handlerMap = {
* @return {function} taskHandler
*/
export function createHandler (id, handler) {
const defaultHandler = handler || callNative
const defaultHandler = handler || global.callNative

/* istanbul ignore if */
if (typeof defaultHandler !== 'function') {
Expand Down
2 changes: 2 additions & 0 deletions html5/runtime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import * as shared from '../shared'
import { Document, Element, Comment } from './vdom'
import Listener from './listener'
import { TaskCenter } from './task-center'
import init from './init'

const config = {
Document, Element, Comment, Listener,
TaskCenter,
sendTasks (...args) {
return global.callNative(...args)
}
Expand Down
2 changes: 2 additions & 0 deletions html5/runtime/init.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { init as initTaskHandler } from './task-center'
import { registerElement } from './vdom/element-types'

let frameworks
Expand Down Expand Up @@ -143,6 +144,7 @@ export default function init (config) {
}

frameworks = config.frameworks || {}
initTaskHandler()

// Init each framework by `init` method and `config` which contains three
// virtual-DOM Class: `Document`, `Element` & `Comment`, and a JS bridge method:
Expand Down
17 changes: 0 additions & 17 deletions html5/runtime/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,23 +175,6 @@ Object.assign(Listener.prototype, {
return this.addActions(createAction('removeEvent', [ref, type]))
},

/**
* Call a component method with args.
* @param {string} ref
* @param {string} type
* @param {string} method
* @param {array} args
* @return {undefined | number} the signal sent by native
*/
callComponentMethod (ref, type, method, args) {
return this.addActions({
component: type,
method,
ref: ref,
args: [...args]
})
},

/**
* Default handler.
* @param {object | array} actions
Expand Down
56 changes: 56 additions & 0 deletions html5/runtime/task-center.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
let fallback = function () {}

export class TaskCenter {
constructor (id, sendTasks) {
this.instanceId = id
fallback = sendTasks || function () {}
}

send (type, options, args) {
const { action, component, ref, module, method } = options

switch (type) {
case 'dom':
return this[action](this.instanceId, args)
case 'component':
return this.componentHandler(this.instanceId, ref, method, args, { component })
case 'module':
return this.moduleHandler(this.instanceId, module, method, args, {})
}
}
}

export function init () {
const DOM_METHODS = {
createFinish: global.callCreateFinish,
updateFinish: global.callUpdateFinish,
refreshFinish: global.callRefreshFinish,

createBody: global.callCreateBody,

addElement: global.callAddElement,
removeElement: global.callRemoveElement,
moveElement: global.callMoveElement,
updateAttrs: global.callUpdateAttrs,
updateStyle: global.callUpdateStyle,

addEvent: global.callAddEvent,
removeEvent: global.callRemoveEvent
}
const proto = TaskCenter.prototype

for (const name in DOM_METHODS) {
const method = DOM_METHODS[name]
proto[name] = method ?
(id, args) => method(id, ...args) :
(id, args) => fallback(id, [{ module: 'dom', method: name, args }])
}

proto.componentHandler = global.callNativeComponent ||
((id, ref, method, args, options) =>
fallback(id, [{ component: options.component, ref, method, args }]))

proto.moduleHandler = global.callNativeModule ||
((id, module, method, args) =>
fallback(id, [{ module, method, args }]))
}
4 changes: 3 additions & 1 deletion html5/runtime/vdom/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import '../../shared/objectAssign'
import Comment from './comment'
import Element from './element'
import Listener from '../listener'
import { TaskCenter } from '../task-center'
import { createHandler } from '../handler'
import { addDoc, removeDoc, appendBody, setBody } from './operation'

Expand All @@ -18,7 +19,8 @@ export default function Document (id, url, handler) {
addDoc(id, this)
this.nodeMap = {}
const L = Document.Listener || Listener
this.listener = new L(id, handler || createHandler(id, Document.handler))
this.listener = new L(id, handler || createHandler(id, Document.handler)) // deprecated
this.taskCenter = new TaskCenter(id, handler ? (id, ...args) => handler(...args) : Document.handler)
this.createDocumentElement()
}

Expand Down
8 changes: 4 additions & 4 deletions html5/runtime/vdom/element-types.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getListener } from './operation'
import { getTaskCenter } from './operation'

let Element

Expand Down Expand Up @@ -40,9 +40,9 @@ export function registerElement (type, methods) {
// Add methods to prototype.
methods.forEach(methodName => {
XElement.prototype[methodName] = function (...args) {
const listener = getListener(this.docId)
if (listener) {
listener.callComponentMethod(this.ref, type, methodName, args)
const taskCenter = getTaskCenter(this.docId)
if (taskCenter) {
taskCenter.send('component', { ref: this.ref, component: type, method: methodName }, args)
}
}
})
Expand Down
Loading