blob: 2bf389342b3f2e433fd21c5029e9ae65817c58ff [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Create the action object.
* @param {string} name
* @param {array} arguments
* @return {object} action
*/
function createAction (name, args = []) {
return { module: 'dom', method: name, args: args }
}
export default class Listener {
constructor (id, handler) {
this.id = id
this.batched = false
this.updates = []
if (typeof handler === 'function') {
Object.defineProperty(this, 'handler', {
configurable: true,
enumerable: true,
writable: true,
value: handler
})
}
else {
console.error('[JS Runtime] invalid parameter, handler must be a function')
}
}
/**
* Send the "createFinish" signal.
* @param {function} callback
* @return {undefined | number} the signal sent by native
*/
createFinish (callback) {
const handler = this.handler
return handler([createAction('createFinish')], callback)
}
/**
* Send the "updateFinish" signal.
* @param {function} callback
* @return {undefined | number} the signal sent by native
*/
updateFinish (callback) {
const handler = this.handler
return handler([createAction('updateFinish')], callback)
}
/**
* Send the "refreshFinish" signal.
* @param {function} callback
* @return {undefined | number} the signal sent by native
*/
refreshFinish (callback) {
const handler = this.handler
return handler([createAction('refreshFinish')], callback)
}
/**
* Send the "createBody" signal.
* @param {object} element
* @return {undefined | number} the signal sent by native
*/
createBody (element) {
const body = element.toJSON()
const children = body.children
delete body.children
const actions = [createAction('createBody', [body])]
if (children) {
actions.push.apply(actions, children.map(child => {
return createAction('addElement', [body.ref, child, -1])
}))
}
return this.addActions(actions)
}
/**
* Send the "addElement" signal.
* @param {object} element
* @param {stirng} reference id
* @param {number} index
* @return {undefined | number} the signal sent by native
*/
addElement (element, ref, index) {
if (!(index >= 0)) {
index = -1
}
return this.addActions(createAction('addElement', [ref, element.toJSON(), index]))
}
/**
* Send the "removeElement" signal.
* @param {stirng} reference id
* @return {undefined | number} the signal sent by native
*/
removeElement (ref) {
if (Array.isArray(ref)) {
const actions = ref.map((r) => createAction('removeElement', [r]))
return this.addActions(actions)
}
return this.addActions(createAction('removeElement', [ref]))
}
/**
* Send the "moveElement" signal.
* @param {stirng} target reference id
* @param {stirng} parent reference id
* @param {number} index
* @return {undefined | number} the signal sent by native
*/
moveElement (targetRef, parentRef, index) {
return this.addActions(createAction('moveElement', [targetRef, parentRef, index]))
}
/**
* Send the "updateAttrs" signal.
* @param {stirng} reference id
* @param {stirng} key
* @param {stirng} value
* @return {undefined | number} the signal sent by native
*/
setAttr (ref, key, value) {
const result = {}
result[key] = value
return this.addActions(createAction('updateAttrs', [ref, result]))
}
/**
* Send the "updateStyle" signal, update a sole style.
* @param {stirng} reference id
* @param {stirng} key
* @param {stirng} value
* @return {undefined | number} the signal sent by native
*/
setStyle (ref, key, value) {
const result = {}
result[key] = value
return this.addActions(createAction('updateStyle', [ref, result]))
}
/**
* Send the "updateStyle" signal.
* @param {stirng} reference id
* @param {object} style
* @return {undefined | number} the signal sent by native
*/
setStyles (ref, style) {
return this.addActions(createAction('updateStyle', [ref, style]))
}
/**
* Send the "addEvent" signal.
* @param {stirng} reference id
* @param {string} event type
* @return {undefined | number} the signal sent by native
*/
addEvent (ref, type) {
return this.addActions(createAction('addEvent', [ref, type]))
}
/**
* Send the "removeEvent" signal.
* @param {stirng} reference id
* @param {string} event type
* @return {undefined | number} the signal sent by native
*/
removeEvent (ref, type) {
return this.addActions(createAction('removeEvent', [ref, type]))
}
/**
* Default handler.
* @param {object | array} actions
* @param {function} callback
* @return {} anything returned by callback function
*/
handler (actions, cb) {
return cb && cb()
}
/**
* Add actions into updates.
* @param {object | array} actions
* @return {undefined | number} the signal sent by native
*/
addActions (actions) {
const updates = this.updates
const handler = this.handler
if (!Array.isArray(actions)) {
actions = [actions]
}
if (this.batched) {
updates.push.apply(updates, actions)
}
else {
return handler(actions)
}
}
}