efview-plus
Version:
A high quality Service UI components Library with Vue.js
156 lines (148 loc) • 4.96 kB
JavaScript
const supportPostMessage = 'postMessage' in window
const serverMessageName = 'AMPframe'
const serverProjectName = 'AMP'
const clientMessageName = 'AMPclient'
const clientProjectName = 'AMP'
const clientTargetName = 'AMPframe'
class Target {
constructor(target, name, prefix) {
let errMsg = ''
if (arguments.length < 2) {
errMsg = 'target error - target and name are both required'
} else if (typeof target !== 'object') {
errMsg = 'target error - target itself must be window object'
} else if (typeof name !== 'string') {
errMsg = 'target error - target name must be string type'
}
if (errMsg) {
throw new Error(errMsg)
}
this.target = target
this.name = name
this.prefix = prefix
}
send(msg) {
if (supportPostMessage) {
this.target.postMessage(`${this.prefix}|${this.name}__Messenger__${msg}`, '*')
} else {
const targetFunc = window.navigator[this.prefix + this.name]
if (typeof targetFunc === 'function') {
targetFunc(this.prefix + msg, window)
} else {
throw new Error('target callback function is not defined')
}
}
}
}
class EfuMessenger {
constructor(messengerName, projectName) {
this.targets = {}
this.name = messengerName
this.listenFunc = []
this.prefix = projectName
this.initListen()
}
addTarget(target, name) {
const targetObj = new Target(target, name, this.prefix)
this.targets[name] = targetObj
}
listen(callback) {
let i = 0
const len = this.listenFunc.length
let cbIsExist = false
for (; i < len; i++) {
// 增加多组件对象定义重复声明判断
let o_fn_str = this.listenFunc[i].toString()
let n_fn_str = callback.toString()
if (o_fn_str === n_fn_str) {
this.listenFunc[i] = callback
cbIsExist = true
break
}
}
if (!cbIsExist) {
this.listenFunc.push(callback)
}
}
clear() {
this.listenFunc = []
}
send(msg) {
const { targets } = this
let target
for (target in targets) {
if (targets.hasOwnProperty(target)) {
targets[target].send(msg)
}
}
}
initListen() {
const self = this
const generalCallback = function (msg) {
if (typeof msg === 'object' && msg.data) {
msg = msg.data
}
if (typeof msg === 'string') {
const msgPairs = msg.split('__Messenger__')
var msg = msgPairs[1]
const pairs = msgPairs[0].split('|')
const prefix = pairs[0]
const name = pairs[1]
for (let i = 0; i < self.listenFunc.length; i++) {
if (prefix + name === self.prefix + self.name) {
self.listenFunc[i](msg)
}
}
}
}
if (supportPostMessage) {
if ('addEventListener' in document) {
window.addEventListener('message', generalCallback, false)
} else if ('attachEvent' in document) {
window.attachEvent('onmessage', generalCallback)
}
} else {
// 兼容IE 6/7
window.navigator[this.prefix + this.name] = generalCallback
}
}
}
class server {
constructor(messageName, projectName) {
this.messageName = messageName || serverMessageName
this.projectName = projectName || serverProjectName
return new EfuMessenger(this.messageName, this.projectName)
}
}
class client {
constructor(targetName, messageName, projectName) {
this.messengerOBJ = null
this.messageName = messageName || clientMessageName
this.targetName = targetName || clientTargetName
this.projectName = projectName || clientProjectName
this.init()
}
init() {
this.messengerOBJ = new EfuMessenger(this.messageName, this.projectName)
this.messengerOBJ.addTarget(window.parent, this.targetName)
}
openPortalTabPage(params) {
this.messengerOBJ.targets[this.targetName].send(
JSON.stringify({
name: this.messageName,
action: 'openPortalTabPage',
params: { ...params }
})
)
}
openPortalTabByModuleCode(params) {
this.messengerOBJ.targets[this.targetName].send(
JSON.stringify({
name: this.messageName,
action: 'openPortalTabByModuleCode',
params: { ...params }
})
)
}
}
export { EfuMessenger, server, client }