UNPKG

@haohuawu/js-bridge

Version:

Hybrid消息通信js组件

156 lines (127 loc) 4.1 kB
'use strict'; 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;