blob: 38dab1e9df71a85b2dbaf706a5fda7ffa6e4190e [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.
*/
import Document from '../vdom/Document'
import { isRegisteredModule, getModuleDescription } from './module'
import { isRegisteredComponent } from './component'
import { getTaskCenter } from '../vdom/operation'
const moduleProxies = {}
function setId (weex, id) {
Object.defineProperty(weex, '[[CurrentInstanceId]]', { value: id })
}
function getId (weex) {
return weex['[[CurrentInstanceId]]']
}
function moduleGetter (id, module, method) {
const taskCenter = getTaskCenter(id)
if (!taskCenter || typeof taskCenter.send !== 'function') {
console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
return null
}
return (...args) => taskCenter.send('module', { module, method }, args)
}
function moduleSetter (id, module, method, fn) {
const taskCenter = getTaskCenter(id)
if (!taskCenter || typeof taskCenter.send !== 'function') {
console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
return null
}
if (typeof fn !== 'function') {
console.error(`[JS Framework] ${module}.${method} must be assigned as a function.`)
return null
}
return fn => taskCenter.send('module', { module, method }, [fn])
}
export default class WeexInstance {
constructor (id, config) {
setId(this, String(id))
this.config = config || {}
this.document = new Document(id, this.config.bundleUrl)
this.requireModule = this.requireModule.bind(this)
this.importScript = this.importScript.bind(this)
this.isRegisteredModule = isRegisteredModule
this.isRegisteredComponent = isRegisteredComponent
}
requireModule (moduleName) {
const id = getId(this)
if (!(id && this.document && this.document.taskCenter)) {
console.error(`[JS Framework] Failed to requireModule("${moduleName}"), `
+ `instance (${id}) doesn't exist anymore.`)
return
}
// warn for unknown module
if (!isRegisteredModule(moduleName)) {
console.warn(`[JS Framework] using unregistered weex module "${moduleName}"`)
return
}
// create new module proxy
const proxyName = `${moduleName}#${id}`
if (!moduleProxies[proxyName]) {
// create registered module apis
const moduleDefine = getModuleDescription(moduleName)
const moduleApis = {}
for (const methodName in moduleDefine) {
Object.defineProperty(moduleApis, methodName, {
enumerable: true,
configurable: true,
get: () => moduleGetter(id, moduleName, methodName),
set: fn => moduleSetter(id, moduleName, methodName, fn)
})
}
// create module Proxy
// if (typeof Proxy === 'function') {
// moduleProxies[proxyName] = new Proxy(moduleApis, {
// get (target, methodName) {
// if (methodName in target) {
// return target[methodName]
// }
// console.warn(`[JS Framework] using unregistered method "${moduleName}.${methodName}"`)
// return moduleGetter(id, moduleName, methodName)
// }
// })
// }
moduleProxies[proxyName] = moduleApis
}
return moduleProxies[proxyName]
}
supports (condition) {
if (typeof condition !== 'string') return null
const res = condition.match(/^@(\w+)\/([\w-]+)(\.(\w+))?$/i)
if (res) {
const type = res[1]
const name = res[2]
const method = res[4]
switch (type) {
case 'module': return isRegisteredModule(name, method)
case 'component': return isRegisteredComponent(name)
}
}
return null
}
importScript (src, options = {}) {
const id = getId(this)
const taskCenter = getTaskCenter(id)
return new Promise((resolve, reject) => {
if (!taskCenter || typeof taskCenter.send !== 'function') {
reject(new Error(`[JS Framework] Failed to import script "${src}", `
+ `no taskCenter (${id}) matched.`))
}
try {
taskCenter.send('module', {
module: 'script',
method: 'importScript'
}, [src, options], {
callback: [
result => resolve(result),
error => reject(error)
]
})
}
catch (e) {
reject(e)
}
})
}
// registerStyleSheet (styles) {
// if (this.document) {
// this.document.registerStyleSheet(styles)
// }
// }
}