diff --git a/packages/uni-app-plus-nvue/dist/service.legacy.js b/packages/uni-app-plus-nvue/dist/service.legacy.js index 404477fa9d2fdcff081ecca3816d4feaea8074ba..d999c3c9e24d51f1edb0a1ff84e946efdb5c751a 100644 --- a/packages/uni-app-plus-nvue/dist/service.legacy.js +++ b/packages/uni-app-plus-nvue/dist/service.legacy.js @@ -72,67 +72,16 @@ function promisify (name, api) { } } -const EPS = 1e-4; -const BASE_DEVICE_WIDTH = 750; -let isIOS = false; -let deviceWidth = 0; -let deviceDPR = 0; - -function upx2px (number, newDeviceWidth) { - number = Number(number); - if (number === 0) { - return 0 - } - let result = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth); - if (result < 0) { - result = -result; - } - result = Math.floor(result + EPS); - if (result === 0) { - if (deviceDPR === 1 || !isIOS) { - return 1 - } else { - return 0.5 - } - } - return number < 0 ? -result : result -} - -function initUpx2px (nvue) { - const env = nvue.config.env; - - deviceDPR = env.scale; - deviceWidth = Math.ceil(env.deviceWidth / deviceDPR); - isIOS = env.platform === 'iOS'; -} - -let getEmitter; - -function apply (ctx, method, args) { - return ctx[method].apply(ctx, args) -} - -function $on () { - return apply(getEmitter(), '$on', [...arguments]) -} -function $off () { - return apply(getEmitter(), '$off', [...arguments]) -} -function $once () { - return apply(getEmitter(), '$once', [...arguments]) -} -function $emit () { - return apply(getEmitter(), '$emit', [...arguments]) -} - -function initEventBus (getGlobalEmitter) { - getEmitter = getGlobalEmitter; -} - const SUCCESS = 'success'; const FAIL = 'fail'; const COMPLETE = 'complete'; const CALLBACKS = [SUCCESS, FAIL, COMPLETE]; + +const UNIAPP_SERVICE_NVUE_ID = '__uniapp__service'; + +function noop$1 () { + +} /** * 调用无参数,或仅一个参数且为 callback 的 API * @param {Object} vm @@ -239,6 +188,201 @@ function normalizeCallback (method, callbacks) { } } +function initSubNVue (nvue, plus, BroadcastChannel) { + let origin; + + const onMessageCallbacks = []; + + const postMessage = nvue.requireModule('plus').postMessage; + + const onSubNVueMessage = function onSubNVueMessage (data) { + onMessageCallbacks.forEach(callback => callback({ + origin, + data + })); + }; + + nvue.requireModule('globalEvent').addEventListener('plusMessage', e => { + if (e.data.type === 'UniAppSubNVue') { + onSubNVueMessage(e.data.data, e.data.options); + } + }); + + const webviewId = plus.webview.currentWebview().id; + + const channel = new BroadcastChannel('UNI-APP-SUBNVUE'); + channel.onmessage = function (event) { + if (event.data.to === webviewId) { + onSubNVueMessage(event.data.data); + } + }; + + const wrapper = function wrapper (webview) { + webview.$processed = true; + + const currentWebviewId = plus.webview.currentWebview().id; + const isPopupNVue = currentWebviewId === webview.id; + + const hostNVueId = webview.__uniapp_origin_type === 'uniNView' && webview.__uniapp_origin_id; + const popupNVueId = webview.id; + + webview.postMessage = function (data) { + if (hostNVueId) { + channel.postMessage({ + data, + to: isPopupNVue ? hostNVueId : popupNVueId + }); + } else { + postMessage({ + type: 'UniAppSubNVue', + data: data + }, UNIAPP_SERVICE_NVUE_ID); + } + }; + webview.onMessage = function (callback) { + onMessageCallbacks.push(callback); + }; + + if (!webview.__uniapp_mask_id) { + return + } + origin = webview.__uniapp_host; + + const maskColor = webview.__uniapp_mask; + + let maskWebview = plus.webview.getWebviewById(webview.__uniapp_mask_id); + maskWebview = maskWebview.parent() || maskWebview; // 再次检测父 + const oldShow = webview.show; + const oldHide = webview.hide; + const oldClose = webview.close; + + const showMask = function () { + maskWebview.setStyle({ + mask: maskColor + }); + }; + const closeMask = function () { + maskWebview.setStyle({ + mask: 'none' + }); + }; + webview.show = function (...args) { + showMask(); + return oldShow.apply(webview, args) + }; + webview.hide = function (...args) { + closeMask(); + return oldHide.apply(webview, args) + }; + webview.close = function (...args) { + closeMask(); + return oldClose.apply(webview, args) + }; + }; + + const getSubNVueById = function getSubNVueById (id) { + const webview = plus.webview.getWebviewById(id); + if (webview && !webview.$processed) { + wrapper(webview); + } + return webview + }; + + return { + getSubNVueById, + getCurrentSubNVue () { + return getSubNVueById(plus.webview.currentWebview().id) + } + } +} + +function initPostMessage (nvue) { + const plus = nvue.requireModule('plus'); + return { + postMessage (data) { + plus.postMessage(data, UNIAPP_SERVICE_NVUE_ID); + } + } +} + +function initTitleNView (nvue) { + const eventMaps = { + onNavigationBarButtonTap: noop$1, + onNavigationBarSearchInputChanged: noop$1, + onNavigationBarSearchInputConfirmed: noop$1, + onNavigationBarSearchInputClicked: noop$1 + }; + nvue.requireModule('globalEvent').addEventListener('plusMessage', e => { + if (eventMaps[e.data.type]) { + eventMaps[e.data.type](e.data.data); + } + }); + const ret = Object.create(null); + Object.keys(eventMaps).forEach(eventType => { + ret[eventType] = function (callback) { + eventMaps[eventType] = callback; + }; + }); + return ret +} + +const EPS = 1e-4; +const BASE_DEVICE_WIDTH = 750; +let isIOS = false; +let deviceWidth = 0; +let deviceDPR = 0; + +function upx2px (number, newDeviceWidth) { + number = Number(number); + if (number === 0) { + return 0 + } + let result = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth); + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS) { + return 1 + } else { + return 0.5 + } + } + return number < 0 ? -result : result +} + +function initUpx2px (nvue) { + const env = nvue.config.env; + + deviceDPR = env.scale; + deviceWidth = Math.ceil(env.deviceWidth / deviceDPR); + isIOS = env.platform === 'iOS'; +} + +let getEmitter; + +function apply (ctx, method, args) { + return ctx[method].apply(ctx, args) +} + +function $on () { + return apply(getEmitter(), '$on', [...arguments]) +} +function $off () { + return apply(getEmitter(), '$off', [...arguments]) +} +function $once () { + return apply(getEmitter(), '$once', [...arguments]) +} +function $emit () { + return apply(getEmitter(), '$emit', [...arguments]) +} + +function initEventBus (getGlobalEmitter) { + getEmitter = getGlobalEmitter; +} + class MapContext { constructor (id, ctx) { this.id = id; @@ -278,6 +422,132 @@ function createMapContext (id, vm) { return new MapContext(id, vm.$refs[ref]) } +class VideoContext { + constructor (id, ctx) { + this.id = id; + this.ctx = ctx; + } + + play () { + return invokeVmMethodWithoutArgs(this.ctx, 'play') + } + + pause () { + return invokeVmMethodWithoutArgs(this.ctx, 'pause') + } + + seek (args) { + return invokeVmMethod(this.ctx, 'seek', args) + } + + stop () { + return invokeVmMethodWithoutArgs(this.ctx, 'stop') + } + + sendDanmu (args) { + return invokeVmMethod(this.ctx, 'sendDanmu', args) + } + + playbackRate (args) { + return invokeVmMethod(this.ctx, 'playbackRate', args) + } + + requestFullScreen (args) { + return invokeVmMethod(this.ctx, 'requestFullScreen', args) + } + + exitFullScreen () { + return invokeVmMethodWithoutArgs(this.ctx, 'exitFullScreen') + } + + showStatusBar () { + return invokeVmMethodWithoutArgs(this.ctx, 'showStatusBar') + } + + hideStatusBar () { + return invokeVmMethodWithoutArgs(this.ctx, 'hideStatusBar') + } +} + +function createVideoContext (id, vm) { + const ref = findRefById(id, vm); + if (!ref) { + global.nativeLog('Can not find `' + id + '`', '__WARN'); + } + return new VideoContext(id, vm.$refs[ref]) +} + +class LivePusherContext { + constructor (id, ctx) { + this.id = id; + this.ctx = ctx; + } + + start (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'start', cbs) + } + + stop (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'stop', cbs) + } + + pause (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'pause', cbs) + } + + resume (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'resume', cbs) + } + + switchCamera (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'switchCamera', cbs) + } + + snapshot (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'snapshot', cbs) + } + + toggleTorch (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'toggleTorch', cbs) + } + + playBGM (args) { + return invokeVmMethod(this.ctx, 'playBGM', args) + } + + stopBGM (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopBGM', cbs) + } + + pauseBGM (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'pauseBGM', cbs) + } + + resumeBGM (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'resumeBGM', cbs) + } + + setBGMVolume (cbs) { + return invokeVmMethod(this.ctx, 'setBGMVolume', cbs) + } + + startPreview (cbs) { + return invokeVmMethodWithoutArgs(this.ctx, 'startPreview', cbs) + } + + stopPreview (args) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopPreview', args) + } +} + +function createLivePusherContext (id, vm) { + const ref = findRefById(id, vm); + if (!ref) { + global.nativeLog('Can not find `' + id + '`', '__WARN'); + } + return new LivePusherContext(id, vm.$refs[ref]) +} + var apis = /*#__PURE__*/Object.freeze({ @@ -286,18 +556,31 @@ var apis = /*#__PURE__*/Object.freeze({ $once: $once, $off: $off, $emit: $emit, - createMapContext: createMapContext + createMapContext: createMapContext, + createVideoContext: createVideoContext, + createLivePusherContext: createLivePusherContext }); -function initUni (uni, nvue) { +function initUni (uni, nvue, plus, BroadcastChannel) { + const { + getSubNVueById, + getCurrentSubNVue + } = initSubNVue(nvue, plus, BroadcastChannel); + + const scopedApis = Object.assign({ + getSubNVueById, + getCurrentSubNVue, + requireNativePlugin: nvue.requireModule + }, initTitleNView(nvue), initPostMessage(nvue)); + if (typeof Proxy !== 'undefined') { return new Proxy({}, { get (target, name) { if (apis[name]) { return apis[name] } - if (name === 'requireNativePlugin') { - return nvue.requireModule + if (scopedApis[name]) { + return scopedApis[name] } if (!hasOwn(uni, name)) { return @@ -312,6 +595,9 @@ function initUni (uni, nvue) { Object.keys(apis).forEach(name => { ret[name] = apis[name]; }); + Object.keys(scopedApis).forEach(name => { + ret[name] = scopedApis[name]; + }); Object.keys(uni).forEach(name => { ret[name] = promisify(name, uni[name]); }); @@ -342,8 +628,8 @@ var index_legacy = { initEventBus(getUniEmitter); }, instance: { - getUni (nvue) { - return initUni(getGlobalUni(), nvue) + getUni (nvue, plus, BroadcastChannel) { + return initUni(getGlobalUni(), nvue, plus, BroadcastChannel) }, getApp () { return getGlobalApp() diff --git a/src/platforms/app-plus-nvue/services/api/legacy/index.js b/src/platforms/app-plus-nvue/services/api/legacy/index.js index 62677459190110cae07e3c2d6b2cc66f2e2039b2..654f40348ae4df8da50d4ec634521bd8bd9faff9 100644 --- a/src/platforms/app-plus-nvue/services/api/legacy/index.js +++ b/src/platforms/app-plus-nvue/services/api/legacy/index.js @@ -6,17 +6,40 @@ import { promisify } from 'uni-core/helpers/promise' +import { + initSubNVue +} from '../sub-nvue' + +import { + initPostMessage +} from '../post-message' + +import { + initTitleNView +} from '../title-nview' + import * as apis from './api' -export default function initUni (uni, nvue) { +export default function initUni (uni, nvue, plus, BroadcastChannel) { + const { + getSubNVueById, + getCurrentSubNVue + } = initSubNVue(nvue, plus, BroadcastChannel) + + const scopedApis = Object.assign({ + getSubNVueById, + getCurrentSubNVue, + requireNativePlugin: nvue.requireModule + }, initTitleNView(nvue), initPostMessage(nvue)) + if (typeof Proxy !== 'undefined') { return new Proxy({}, { get (target, name) { if (apis[name]) { return apis[name] } - if (name === 'requireNativePlugin') { - return nvue.requireModule + if (scopedApis[name]) { + return scopedApis[name] } if (!hasOwn(uni, name)) { return @@ -31,6 +54,9 @@ export default function initUni (uni, nvue) { Object.keys(apis).forEach(name => { ret[name] = apis[name] }) + Object.keys(scopedApis).forEach(name => { + ret[name] = scopedApis[name] + }) Object.keys(uni).forEach(name => { ret[name] = promisify(name, uni[name]) }) diff --git a/src/platforms/app-plus-nvue/services/api/post-message.js b/src/platforms/app-plus-nvue/services/api/post-message.js new file mode 100644 index 0000000000000000000000000000000000000000..63b5d485368ddf8168316b285df25b28cb72a7df --- /dev/null +++ b/src/platforms/app-plus-nvue/services/api/post-message.js @@ -0,0 +1,12 @@ +import { + UNIAPP_SERVICE_NVUE_ID +} from './util' + +export function initPostMessage (nvue) { + const plus = nvue.requireModule('plus') + return { + postMessage (data) { + plus.postMessage(data, UNIAPP_SERVICE_NVUE_ID) + } + } +} diff --git a/src/platforms/app-plus-nvue/services/api/sub-nvue.js b/src/platforms/app-plus-nvue/services/api/sub-nvue.js new file mode 100644 index 0000000000000000000000000000000000000000..a242251d920684fc3e99187356fbe9bdcc864a04 --- /dev/null +++ b/src/platforms/app-plus-nvue/services/api/sub-nvue.js @@ -0,0 +1,111 @@ +import { + UNIAPP_SERVICE_NVUE_ID +} from './util' + +export function initSubNVue (nvue, plus, BroadcastChannel) { + let origin + + const onMessageCallbacks = [] + + const postMessage = nvue.requireModule('plus').postMessage + + const onSubNVueMessage = function onSubNVueMessage (data) { + onMessageCallbacks.forEach(callback => callback({ + origin, + data + })) + } + + nvue.requireModule('globalEvent').addEventListener('plusMessage', e => { + if (e.data.type === 'UniAppSubNVue') { + onSubNVueMessage(e.data.data, e.data.options) + } + }) + + const webviewId = plus.webview.currentWebview().id + + const channel = new BroadcastChannel('UNI-APP-SUBNVUE') + channel.onmessage = function (event) { + if (event.data.to === webviewId) { + onSubNVueMessage(event.data.data) + } + } + + const wrapper = function wrapper (webview) { + webview.$processed = true + + const currentWebviewId = plus.webview.currentWebview().id + const isPopupNVue = currentWebviewId === webview.id + + const hostNVueId = webview.__uniapp_origin_type === 'uniNView' && webview.__uniapp_origin_id + const popupNVueId = webview.id + + webview.postMessage = function (data) { + if (hostNVueId) { + channel.postMessage({ + data, + to: isPopupNVue ? hostNVueId : popupNVueId + }) + } else { + postMessage({ + type: 'UniAppSubNVue', + data: data + }, UNIAPP_SERVICE_NVUE_ID) + } + } + webview.onMessage = function (callback) { + onMessageCallbacks.push(callback) + } + + if (!webview.__uniapp_mask_id) { + return + } + origin = webview.__uniapp_host + + const maskColor = webview.__uniapp_mask + + let maskWebview = plus.webview.getWebviewById(webview.__uniapp_mask_id) + maskWebview = maskWebview.parent() || maskWebview // 再次检测父 + const oldShow = webview.show + const oldHide = webview.hide + const oldClose = webview.close + + const showMask = function () { + maskWebview.setStyle({ + mask: maskColor + }) + } + const closeMask = function () { + maskWebview.setStyle({ + mask: 'none' + }) + } + webview.show = function (...args) { + showMask() + return oldShow.apply(webview, args) + } + webview.hide = function (...args) { + closeMask() + return oldHide.apply(webview, args) + } + webview.close = function (...args) { + closeMask() + return oldClose.apply(webview, args) + } + } + + const getSubNVueById = function getSubNVueById (id) { + const webview = plus.webview.getWebviewById(id) + if (webview && !webview.$processed) { + wrapper(webview) + } + return webview + } + + return { + getSubNVueById, + getCurrentSubNVue () { + return getSubNVueById(plus.webview.currentWebview().id) + } + } +} diff --git a/src/platforms/app-plus-nvue/services/api/title-nview.js b/src/platforms/app-plus-nvue/services/api/title-nview.js new file mode 100644 index 0000000000000000000000000000000000000000..d64d91c858980886cdc8e065777781f36314a059 --- /dev/null +++ b/src/platforms/app-plus-nvue/services/api/title-nview.js @@ -0,0 +1,23 @@ +import { + noop +} from './util' +export function initTitleNView (nvue) { + const eventMaps = { + onNavigationBarButtonTap: noop, + onNavigationBarSearchInputChanged: noop, + onNavigationBarSearchInputConfirmed: noop, + onNavigationBarSearchInputClicked: noop + } + nvue.requireModule('globalEvent').addEventListener('plusMessage', e => { + if (eventMaps[e.data.type]) { + eventMaps[e.data.type](e.data.data) + } + }) + const ret = Object.create(null) + Object.keys(eventMaps).forEach(eventType => { + ret[eventType] = function (callback) { + eventMaps[eventType] = callback + } + }) + return ret +} diff --git a/src/platforms/app-plus-nvue/services/api/util.js b/src/platforms/app-plus-nvue/services/api/util.js index 99d275c8c52a0723421d11f98310d0e631b7a4fe..62de2a7a2cd7dc8bd060c66d427a420698371e86 100644 --- a/src/platforms/app-plus-nvue/services/api/util.js +++ b/src/platforms/app-plus-nvue/services/api/util.js @@ -6,6 +6,12 @@ const SUCCESS = 'success' const FAIL = 'fail' const COMPLETE = 'complete' const CALLBACKS = [SUCCESS, FAIL, COMPLETE] + +export const UNIAPP_SERVICE_NVUE_ID = '__uniapp__service' + +export function noop () { + +} /** * 调用无参数,或仅一个参数且为 callback 的 API * @param {Object} vm diff --git a/src/platforms/app-plus-nvue/services/index.legacy.js b/src/platforms/app-plus-nvue/services/index.legacy.js index de45d157cfa482398d4d8b10af520607dd4733b9..45df2756237e8a5364f548c4d5d9b25143d75a38 100644 --- a/src/platforms/app-plus-nvue/services/index.legacy.js +++ b/src/platforms/app-plus-nvue/services/index.legacy.js @@ -26,8 +26,8 @@ export default { initEventBus(getUniEmitter) }, instance: { - getUni (nvue) { - return initUni(getGlobalUni(), nvue) + getUni (nvue, plus, BroadcastChannel) { + return initUni(getGlobalUni(), nvue, plus, BroadcastChannel) }, getApp () { return getGlobalApp()