@haohuawu/js-bridge
Version:
Hybrid消息通信js组件
156 lines (127 loc) • 4.1 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var foreach = _interopDefault(require('lodash.foreach'));
var ua = _interopDefault(require('@haohuawu/ua'));
var host = window.location.host;
var uuid = 0;
var dispatchers = [];
var channels = {};
function noop() {}
function createEvent(id, eventName) {
var payload = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return { id: '-' + id + '-', eventName: eventName, payload: payload, host: host };
}
function createCallbackEvent(id, eventName) {
var payload = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return { id: id, eventName: eventName, payload: payload, host: host };
}
var nativeDispatcher = {
callbacks: {},
send: function send(event, done) {
this.dispatch('event', event, done);
},
sendCallback: function sendCallback(id, eventName, payload) {
this.dispatch('callback', createCallbackEvent(id, eventName, payload), noop);
},
triggerCallback: function triggerCallback(id, payload) {
var _this = this;
setTimeout(function () {
_this.callbacks[id](payload);
}, 0);
},
dispatch: function dispatch(type, event, done) {
var _this2 = this;
var src = 'jsbridge://' + type + '/' + event.id + '?' + encodeURIComponent(JSON.stringify(event));
var iframe = void 0;
this.callbacks[event.id] = function (payload) {
done(payload);
delete _this2.callbacks[event.id];
};
iframe = document.createElement('iframe');
iframe.setAttribute('src', src);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
};
function $emit(eventName) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$payload = options.payload,
payload = _options$payload === undefined ? {} : _options$payload,
_options$done = options.done,
done = _options$done === undefined ? noop : _options$done;
var event = createEvent(uuid, eventName, payload);
foreach(dispatchers, function (dispatcher) {
dispatcher.send(event, done);
});
uuid++;
}
function emit(eventName) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
eventName.split(', ').forEach(function (name) {
$emit(name, options);
});
}
function $on(eventName, func) {
if (!channels[eventName]) {
channels[eventName] = [];
}
channels[eventName].push(func);
}
function on(eventName, func) {
eventName.split(', ').forEach(function (name) {
$on(name, func);
});
}
function $off(eventName, func) {
var listeners = channels[eventName];
var index = -1;
if (!listeners) {
return false;
}
if (!eventName && !func) {
channels = {};
return true;
}
if (listeners && !func) {
delete channels[eventName];
return true;
}
index = listeners.indexOf(func);
if (index >= 0) {
return listeners.splice(index, 1).length > 0;
}
return false;
}
function off(eventName, func) {
eventName.split(', ').forEach(function (name) {
$off(name, func);
});
}
function trigger(eventName, id, payload) {
var executedCount = 0;
var listeners = channels[eventName] || [];
function done(payload) {
executedCount++;
if (executedCount >= listeners.length) {
foreach(dispatchers, function (dispatcher) {
dispatcher.sendCallback(id, eventName, payload);
});
}
}
foreach(listeners, function (listener) {
listener(payload, done);
});
}
function triggerCallback(id, payload) {
foreach(dispatchers, function (dispatcher) {
dispatcher.triggerCallback(id, payload);
});
}
function restrictIframeDispatcher(domain, w) {}
if (ua.isIOS() && ua.isUIWebView() || ua.isAndroid()) {
dispatchers.push(nativeDispatcher);
}
window.jsBridge = { trigger: trigger, triggerCallback: triggerCallback, restrictIframeDispatcher: restrictIframeDispatcher };
var index = { on: on, off: off, emit: emit };
module.exports = index;