(function () {
if (window.CD) {
console.log('已经存在 window.CD变量');
return;
}
const CD = () => {};
CD.prototype = {
version: '1.0.0',
component: {},
components: {},
interfaces: {},
init: () => {
window.CD.component = {
type: window.CD.isMaster() ? 'MASTER' : 'SLAVE',
name: window.CD.isMaster() ? 'MASTER' : window.name,
url: window.location.host,
port: window.location.port || 80
};
if (!window.CD.component.name) {
throw new Error('Error iframe must has a name');
}
window.CD.register(window.CD.component);
window.CD.extendFun('register', data => {
window.CD.components[data.component.name] = data.component;
});
},
isMaster: () => {
return window === window.top;
},
register: () => {
const param = {
componentName: 'MASTER',
methodFunc: 'register',
dataV: {
info: 'i m coming register!',
component: window.CD.component
}
};
window.CD.send(param);
},
extendFun: (name, fun) => {
window.CD.interfaces[name] = fun;
},
log: mesg => {
if (!window.console || typeof window.console === 'undefined') {
return;
}
window.console.log(`[${new Date()}'][${window.CD.version}][${window.CD.component.type}][${window.CD.component.name}][${mesg.type}][${window.JSON.stringify(mesg)}]`);
},
postMessage: (targetWindow, targetUrl, mesg) => {
window.CD.log(mesg);
if (targetWindow) {
targetWindow.postMessage(JSON.stringify(mesg), targetUrl);
}
},
send: dataParam => {
const {
componentName,
methodFunc,
dataV,
callback,
typeV
} = dataParam;
if (window.CD.isMaster() && componentName === 'MASTER') {
return;
}
const sourceV = window.CD.component.name;
const mesg = {
source: sourceV,
target: componentName,
method: methodFunc,
data: dataV,
type: typeV || 'REQUEST'
};
if (callback) {
window.CD.extendFun(methodFunc + 'Callback', callback);
}
const w = window.CD.isMaster() ? window.document[componentName] : window.top;
window.CD.postMessage(w, '*', mesg);
},
process: event => {
if (!event.data) {
console.log('event is null!');
return;
}
try {
const mesg = JSON.parse(event.data);
window.CD.log(mesg);
const interface1 = window.CD.interfaces[mesg.method];
let result;
if (interface1) {
result = interface1.call(window.CD, mesg.data);
} else {
throw new Error(`[${window.CD.component.name}] not have interface:[${mesg.method}]`);
}
if (result) {
const param = {
componentName: mesg.source,
methodFunc: `${mesg.method}Callback`,
dataV: result,
callback: null,
typeV: 'RETURN'
};
window.CD.send(param);
}
} catch (e) {
}
},
listen: () => {
if (window.addEventListener) {
window.addEventListener('message', event => {
window.CD.process(event);
}, false);
} else {
window.attachEvent('onmessage', event => {
window.CD.process(event);
});
}
}
};
window.CD = new CD();
window.CD.init();
window.CD.listen();
})();