提交 f3ccbc81 编写于 作者: fxy060608's avatar fxy060608

wip(app): uni-app-plus

......@@ -55,6 +55,7 @@ declare namespace UniApp {
entryPagePath?: string
entryPageQuery?: string
realEntryPagePath?: string
renderer?: 'auto' | 'native'
}
interface UniRoute {
......
import { parseWebviewStyle } from '../src/service/framework/page/webview/style'
import { parseWebviewStyle } from '../src/service/framework/webview/style'
function initDefaultUniConfig() {
return JSON.parse(
JSON.stringify({
......
......@@ -1295,21 +1295,21 @@ var serviceContext = (function (vue) {
},
};
function initBridge(namespace) {
function initBridge(subscribeNamespace) {
// TODO vue3 compatibility builds
const emitter = new E();
return extend(emitter, {
subscribe(event, callback) {
emitter.on(`${namespace}.${event}`, callback);
emitter.on(`${subscribeNamespace}.${event}`, callback);
},
unsubscribe(event, callback) {
emitter.off(`${namespace}.${event}`, callback);
emitter.off(`${subscribeNamespace}.${event}`, callback);
},
subscribeHandler(event, args, pageId) {
if ((process.env.NODE_ENV !== 'production')) {
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
console.log(`[${subscribeNamespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
}
emitter.emit(`${namespace}.${event}`, args, pageId);
emitter.emit(`${subscribeNamespace}.${event}`, args, pageId);
},
});
}
......@@ -1384,7 +1384,7 @@ var serviceContext = (function (vue) {
return '/' + fromRouteArray.concat(toRouteArray).join('/');
}
const ServiceJSBridge = /*#__PURE__*/ extend(initBridge('service'), {
const ServiceJSBridge = /*#__PURE__*/ extend(initBridge('view' /* view 指的是 service 层订阅的是 view 层事件 */), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit('api.' + name, res);
},
......@@ -5018,6 +5018,16 @@ var serviceContext = (function (vue) {
return true;
}
return false;
}
/**
* 注册 view 层通知 service 层事件处理
*/
function registerPlusMessage(type, callback, keepAlive = true) {
if (callbacks[type]) {
return console.warn(`'${type}' registered: ` + callbacks[type].toString());
}
callback.keepAlive = !!keepAlive;
callbacks[type] = callback;
}
function backbuttonListener() {
......@@ -5103,6 +5113,274 @@ var serviceContext = (function (vue) {
});
}
const ON_WEBVIEW_READY = 'onWebviewReady';
function initNVue(webviewStyle, routeMeta, path) {
if (path && routeMeta.isNVue) {
webviewStyle.uniNView = {
path,
defaultFontSize: __uniConfig.defaultFontSize,
viewport: __uniConfig.viewport,
};
}
}
const colorRE = /^#[a-z0-9]{6}$/i;
function isColor(color) {
return color && (colorRE.test(color) || color === 'transparent');
}
function initBackgroundColor(webviewStyle, routeMeta) {
const { backgroundColor } = routeMeta;
if (!backgroundColor) {
return;
}
if (!isColor(backgroundColor)) {
return;
}
if (!webviewStyle.background) {
webviewStyle.background = backgroundColor;
}
if (!webviewStyle.backgroundColorTop) {
webviewStyle.backgroundColorTop = backgroundColor;
}
}
function initPopGesture(webviewStyle, routeMeta) {
// 不支持 hide
if (webviewStyle.popGesture === 'hide') {
delete webviewStyle.popGesture;
}
// 似乎没用了吧?记得是之前流应用时,需要 appback 的逻辑
if (routeMeta.isQuit) {
webviewStyle.popGesture = (plus.os.name === 'iOS' ? 'appback' : 'none');
}
}
function initPullToRefresh(webviewStyle, routeMeta) {
if (!routeMeta.enablePullDownRefresh) {
return;
}
webviewStyle.pullToRefresh = normalizePullToRefreshRpx(extend({}, plus.os.name === 'Android'
? defaultAndroidPullToRefresh
: defaultPullToRefresh, routeMeta.pullToRefresh));
}
const defaultAndroidPullToRefresh = { support: true, style: 'circle' };
const defaultPullToRefresh = {
support: true,
style: 'default',
height: '50px',
range: '200px',
contentdown: {
caption: '',
},
contentover: {
caption: '',
},
contentrefresh: {
caption: '',
},
};
function initTitleNView(webviewStyle, routeMeta) {
const { navigationBar } = routeMeta;
if (navigationBar.style === 'custom') {
return false;
}
let autoBackButton = true;
if (routeMeta.isQuit) {
autoBackButton = false;
}
const titleNView = {
autoBackButton,
};
Object.keys(navigationBar).forEach((name) => {
const value = navigationBar[name];
if (name === 'backgroundColor') {
titleNView.backgroundColor = isColor(value)
? value
: BACKGROUND_COLOR;
}
else if (name === 'titleImage' && value) {
titleNView.tags = createTitleImageTags(value);
}
else if (name === 'buttons' && isArray(value)) {
titleNView.buttons = value.map((button, index) => {
button.onclick = createTitleNViewBtnClick(index);
return button;
});
}
});
webviewStyle.titleNView = titleNView;
}
function createTitleImageTags(titleImage) {
return [
{
tag: 'img',
src: titleImage,
position: {
left: 'auto',
top: 'auto',
width: 'auto',
height: '26px',
},
},
];
}
function createTitleNViewBtnClick(index) {
return function onClick(btn) {
btn.index = index;
invokeHook('onNavigationBarButtonTap', btn);
};
}
function parseWebviewStyle(id, path, routeOptions) {
const webviewStyle = {
bounce: 'vertical',
};
const routeMeta = mergePageMeta(id, routeOptions.meta);
Object.keys(routeMeta).forEach((name) => {
if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) {
webviewStyle[name] =
routeMeta[name];
}
});
initNVue(webviewStyle, routeMeta, path);
initPopGesture(webviewStyle, routeMeta);
initBackgroundColor(webviewStyle, routeMeta);
initTitleNView(webviewStyle, routeMeta);
initPullToRefresh(webviewStyle, routeMeta);
return webviewStyle;
}
const WEBVIEW_STYLE_BLACKLIST = [
'id',
'route',
'isNVue',
'isQuit',
'isEntry',
'isTabBar',
'tabBarIndex',
'windowTop',
'topWindow',
'leftWindow',
'rightWindow',
'maxWidth',
'usingComponents',
'disableScroll',
'enablePullDownRefresh',
'navigationBar',
'pullToRefresh',
'onReachBottomDistance',
'pageOrientation',
'backgroundColor',
];
let id = 2;
let preloadWebview$1;
function getWebviewId() {
return id;
}
function genWebviewId() {
return id++;
}
function getPreloadWebview() {
return preloadWebview$1;
}
function encode(val) {
return val;
}
function initUniPageUrl(path, query) {
const queryString = query ? stringifyQuery$1(query, encode) : '';
return {
path: path.substr(1),
query: queryString ? queryString.substr(1) : queryString,
};
}
function createNVueWebview({ path, query, routeOptions, webviewStyle, }) {
const curWebviewId = genWebviewId();
const curWebviewStyle = parseWebviewStyle(curWebviewId, path, routeOptions);
curWebviewStyle.uniPageUrl = initUniPageUrl(path, query);
if ((process.env.NODE_ENV !== 'production')) {
console.log('[uni-app] createWebview', curWebviewId, path, curWebviewStyle);
}
curWebviewStyle.isTab = !!routeOptions.meta.isTabBar;
return plus.webview.create('', String(curWebviewId), curWebviewStyle, extend({
nvue: true,
}, webviewStyle));
}
let preloadWebview;
function setPreloadWebview(webview) {
preloadWebview = webview;
}
const webviewReadyCallbacks = {};
function consumeWebviewReady(pageId) {
const callbacks = webviewReadyCallbacks[pageId];
isArray(callbacks) && callbacks.forEach((callback) => callback());
delete webviewReadyCallbacks[pageId];
}
function createWebview(options) {
if (options.routeOptions.meta.isNVue) {
return createNVueWebview(options);
}
if (getWebviewId() === 2) {
// 如果首页非 nvue,则直接返回 Launch Webview
return plus.webview.getLaunchWebview();
}
return getPreloadWebview();
}
let isLaunchWebviewReady = false; // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android)
function onWebviewReady(_data, pageId) {
const isLaunchWebview = pageId === '1';
if (isLaunchWebview && isLaunchWebviewReady) {
if ((process.env.NODE_ENV !== 'production')) {
console.log('[uni-app] onLaunchWebviewReady.prevent');
}
return;
}
if (isLaunchWebview) {
// 首页
isLaunchWebviewReady = true;
setPreloadWebview(plus.webview.getLaunchWebview());
}
else if (!preloadWebview) {
// preloadWebview 不存在,重新加载一下
setPreloadWebview(plus.webview.getWebviewById(pageId));
}
if (preloadWebview.id !== pageId) {
return console.error(`webviewReady[${preloadWebview.id}][${pageId}] not match`);
}
preloadWebview.loaded = true; // 标记已 ready
consumeWebviewReady(pageId);
if (!isLaunchWebview) {
return;
}
const entryPagePath = '/' + __uniConfig.entryPagePath;
const routeOptions = __uniRoutes.find((route) => route.path === entryPagePath);
if (!routeOptions.meta.isNVue) {
// 非 nvue 首页,需要主动跳转
const navigateType = routeOptions.meta.isTabBar ? 'switchTab' : 'navigateTo';
return uni[navigateType]({
url: entryPagePath + (__uniConfig.entryPageQuery || ''),
openType: 'appLaunch',
});
}
}
function initSubscribeHandlers() {
const { subscribe, subscribeHandler } = UniServiceJSBridge;
registerPlusMessage('subscribeHandler', (data) => {
subscribeHandler(data.type, data.data, data.pageId);
});
if (__uniConfig.renderer !== 'native') {
// 非纯原生
subscribe(ON_WEBVIEW_READY, onWebviewReady);
}
}
let appCtx;
const defaultApp = {
globalData: {},
......@@ -5118,6 +5396,7 @@ var serviceContext = (function (vue) {
initEntry();
initTabBar();
initGlobalEvent();
initSubscribeHandlers();
initAppLaunch(appVm);
// 10s后清理临时文件
setTimeout(clearTempFile, 10000);
......@@ -5349,212 +5628,6 @@ var serviceContext = (function (vue) {
return routeOptions;
}
function initNVue(webviewStyle, routeMeta, path) {
if (path && routeMeta.isNVue) {
webviewStyle.uniNView = {
path,
defaultFontSize: __uniConfig.defaultFontSize,
viewport: __uniConfig.viewport,
};
}
}
const colorRE = /^#[a-z0-9]{6}$/i;
function isColor(color) {
return color && (colorRE.test(color) || color === 'transparent');
}
function initBackgroundColor(webviewStyle, routeMeta) {
const { backgroundColor } = routeMeta;
if (!backgroundColor) {
return;
}
if (!isColor(backgroundColor)) {
return;
}
if (!webviewStyle.background) {
webviewStyle.background = backgroundColor;
}
if (!webviewStyle.backgroundColorTop) {
webviewStyle.backgroundColorTop = backgroundColor;
}
}
function initPopGesture(webviewStyle, routeMeta) {
// 不支持 hide
if (webviewStyle.popGesture === 'hide') {
delete webviewStyle.popGesture;
}
// 似乎没用了吧?记得是之前流应用时,需要 appback 的逻辑
if (routeMeta.isQuit) {
webviewStyle.popGesture = (plus.os.name === 'iOS' ? 'appback' : 'none');
}
}
function initPullToRefresh(webviewStyle, routeMeta) {
if (!routeMeta.enablePullDownRefresh) {
return;
}
webviewStyle.pullToRefresh = normalizePullToRefreshRpx(extend({}, plus.os.name === 'Android'
? defaultAndroidPullToRefresh
: defaultPullToRefresh, routeMeta.pullToRefresh));
}
const defaultAndroidPullToRefresh = { support: true, style: 'circle' };
const defaultPullToRefresh = {
support: true,
style: 'default',
height: '50px',
range: '200px',
contentdown: {
caption: '',
},
contentover: {
caption: '',
},
contentrefresh: {
caption: '',
},
};
function initTitleNView(webviewStyle, routeMeta) {
const { navigationBar } = routeMeta;
if (navigationBar.style === 'custom') {
return false;
}
let autoBackButton = true;
if (routeMeta.isQuit) {
autoBackButton = false;
}
const titleNView = {
autoBackButton,
};
Object.keys(navigationBar).forEach((name) => {
const value = navigationBar[name];
if (name === 'backgroundColor') {
titleNView.backgroundColor = isColor(value)
? value
: BACKGROUND_COLOR;
}
else if (name === 'titleImage' && value) {
titleNView.tags = createTitleImageTags(value);
}
else if (name === 'buttons' && isArray(value)) {
titleNView.buttons = value.map((button, index) => {
button.onclick = createTitleNViewBtnClick(index);
return button;
});
}
});
webviewStyle.titleNView = titleNView;
}
function createTitleImageTags(titleImage) {
return [
{
tag: 'img',
src: titleImage,
position: {
left: 'auto',
top: 'auto',
width: 'auto',
height: '26px',
},
},
];
}
function createTitleNViewBtnClick(index) {
return function onClick(btn) {
btn.index = index;
invokeHook('onNavigationBarButtonTap', btn);
};
}
function parseWebviewStyle(id, path, routeOptions) {
const webviewStyle = {
bounce: 'vertical',
};
const routeMeta = mergePageMeta(id, routeOptions.meta);
Object.keys(routeMeta).forEach((name) => {
if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) {
webviewStyle[name] =
routeMeta[name];
}
});
initNVue(webviewStyle, routeMeta, path);
initPopGesture(webviewStyle, routeMeta);
initBackgroundColor(webviewStyle, routeMeta);
initTitleNView(webviewStyle, routeMeta);
initPullToRefresh(webviewStyle, routeMeta);
return webviewStyle;
}
const WEBVIEW_STYLE_BLACKLIST = [
'id',
'route',
'isNVue',
'isQuit',
'isEntry',
'isTabBar',
'tabBarIndex',
'windowTop',
'topWindow',
'leftWindow',
'rightWindow',
'maxWidth',
'usingComponents',
'disableScroll',
'enablePullDownRefresh',
'navigationBar',
'pullToRefresh',
'onReachBottomDistance',
'pageOrientation',
'backgroundColor',
];
let id = 2;
let preloadWebview;
function getWebviewId() {
return id;
}
function genWebviewId() {
return id++;
}
function getPreloadWebview() {
return preloadWebview;
}
function encode(val) {
return val;
}
function initUniPageUrl(path, query) {
const queryString = query ? stringifyQuery$1(query, encode) : '';
return {
path: path.substr(1),
query: queryString ? queryString.substr(1) : queryString,
};
}
function createNVueWebview({ path, query, routeOptions, webviewStyle, }) {
const curWebviewId = genWebviewId();
const curWebviewStyle = parseWebviewStyle(curWebviewId, path, routeOptions);
curWebviewStyle.uniPageUrl = initUniPageUrl(path, query);
if ((process.env.NODE_ENV !== 'production')) {
console.log('[uni-app] createWebview', curWebviewId, path, curWebviewStyle);
}
curWebviewStyle.isTab = !!routeOptions.meta.isTabBar;
return plus.webview.create('', String(curWebviewId), curWebviewStyle, extend({
nvue: true,
}, webviewStyle));
}
function createWebview(options) {
if (options.routeOptions.meta.isNVue) {
return createNVueWebview(options);
}
if (getWebviewId() === 2) {
// 如果首页非 nvue,则直接返回 Launch Webview
return plus.webview.getLaunchWebview();
}
return getPreloadWebview();
}
function getStatusbarHeight() {
// 横屏时 iOS 获取的状态栏高度错误,进行纠正
return plus.navigator.isImmersedStatusbar()
......
......@@ -5606,20 +5606,20 @@
return this;
}
};
function initBridge(namespace) {
function initBridge(subscribeNamespace) {
const emitter = new E();
return extend(emitter, {
subscribe(event, callback) {
emitter.on(`${namespace}.${event}`, callback);
emitter.on(`${subscribeNamespace}.${event}`, callback);
},
unsubscribe(event, callback) {
emitter.off(`${namespace}.${event}`, callback);
emitter.off(`${subscribeNamespace}.${event}`, callback);
},
subscribeHandler(event, args, pageId) {
{
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
console.log(`[${subscribeNamespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
}
emitter.emit(`${namespace}.${event}`, args, pageId);
emitter.emit(`${subscribeNamespace}.${event}`, args, pageId);
}
});
}
......@@ -5692,7 +5692,7 @@
fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1);
return "/" + fromRouteArray.concat(toRouteArray).join("/");
}
/* @__PURE__ */ extend(initBridge("service"), {
/* @__PURE__ */ extend(initBridge("view"), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit("api." + name, res);
}
......@@ -6147,12 +6147,9 @@
});
watch(() => extend({}, size2), (value) => emit2("resize", value));
return () => {
const {
width,
height
} = rootRef.value.getBoundingClientRect();
size2.width = width;
size2.height = height;
const rootEl = rootRef.value;
size2.width = rootEl.offsetWidth;
size2.height = rootEl.offsetHeight;
reset2();
};
}
......@@ -6273,8 +6270,8 @@
}
};
const FIX_MODES = {
widthFix: ["width", "height"],
heightFix: ["height", "width"]
widthFix: ["offsetWidth", "height"],
heightFix: ["offsetHeight", "width"]
};
const IMAGE_MODES = {
aspectFit: ["center center", "contain"],
......@@ -6444,8 +6441,7 @@
return;
}
const rootEl = rootRef.value;
const rect = rootEl.getBoundingClientRect();
const value = rect[names[0]];
const value = rootEl[names[0]];
if (value) {
rootEl.style[names[1]] = fixNumber(value / ratio) + "px";
}
......
export const ON_WEBVIEW_READY = 'onWebviewReady'
......@@ -6,7 +6,7 @@ import { initTabBar } from './initTabBar'
import { initGlobalEvent } from './initGlobalEvent'
import { initAppLaunch } from './initAppLaunch'
import { clearTempFile } from './clearTempFile'
import { initSubscribeHandlers } from './initSubscribeHandlers'
import { initSubscribeHandlers } from './subscriber'
let appCtx: ComponentPublicInstance
const defaultApp = {
......
......@@ -2,7 +2,7 @@ import { WEB_INVOKE_APPSERVICE } from '@dcloudio/uni-shared'
interface PlusMessageCallback {
(args: Record<string, any>): void
keepAlive: boolean
keepAlive?: boolean
}
const callbacks: Record<string, PlusMessageCallback> = {}
......
import { ON_WEBVIEW_READY } from 'packages/uni-app-plus/src/constants'
import { registerPlusMessage } from '../plusMessage'
import { onWebviewReady } from './onWebviewReady'
export function initSubscribeHandlers() {
const { subscribe, subscribeHandler } = UniServiceJSBridge
registerPlusMessage('subscribeHandler', (data) => {
subscribeHandler(data.type, data.data, data.pageId)
})
if (__uniConfig.renderer !== 'native') {
// 非纯原生
subscribe(ON_WEBVIEW_READY, onWebviewReady)
}
}
import {
consumeWebviewReady,
preloadWebview,
setPreloadWebview,
} from '../../webview'
let isLaunchWebviewReady = false // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android)
export function onWebviewReady(_data: unknown, pageId: string) {
const isLaunchWebview = pageId === '1'
if (isLaunchWebview && isLaunchWebviewReady) {
if (__DEV__) {
console.log('[uni-app] onLaunchWebviewReady.prevent')
}
return
}
if (isLaunchWebview) {
// 首页
isLaunchWebviewReady = true
setPreloadWebview(plus.webview.getLaunchWebview())
} else if (!preloadWebview) {
// preloadWebview 不存在,重新加载一下
setPreloadWebview(plus.webview.getWebviewById(pageId))
}
if (preloadWebview.id !== pageId) {
return console.error(
`webviewReady[${preloadWebview.id}][${pageId}] not match`
)
}
;(preloadWebview as any).loaded = true // 标记已 ready
consumeWebviewReady(pageId)
if (!isLaunchWebview) {
return
}
const entryPagePath = '/' + __uniConfig.entryPagePath
const routeOptions = __uniRoutes.find(
(route) => route.path === entryPagePath
)!
if (!routeOptions.meta.isNVue) {
// 非 nvue 首页,需要主动跳转
const navigateType = routeOptions.meta.isTabBar ? 'switchTab' : 'navigateTo'
return uni[navigateType]({
url: entryPagePath + (__uniConfig.entryPageQuery || ''),
openType: 'appLaunch',
} as any)
}
}
export const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'
......@@ -2,7 +2,7 @@ import { hasOwn } from '@vue/shared'
import { NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE } from '@dcloudio/uni-shared'
import { initEntry } from '../app/initEntry'
import { initRouteOptions } from './initRouteOptions'
import { createWebview } from './webview'
import { createWebview } from '../webview'
import { createPage } from './define'
import { PageNodeOptions } from '../dom/Page'
import { getStatusbarHeight } from '../../../helpers/statusBar'
......
import { createNVueWebview } from './nvue'
import { getPreloadWebview, getWebviewId } from './utils'
export * from './preload'
export interface CreateWebviewOptions {
path: string
query: Record<string, string>
......
import { isArray } from '@vue/shared'
import { VIEW_WEBVIEW_PATH } from '../constants'
import { genWebviewId } from './utils'
export let preloadWebview: PlusWebviewWebviewObject
export function setPreloadWebview(webview: PlusWebviewWebviewObject) {
preloadWebview = webview
}
export function createPreloadWebview() {
if (!preloadWebview || (preloadWebview as any).__uniapp_route) {
// 不存在,或已被使用
preloadWebview = plus.webview.create(
VIEW_WEBVIEW_PATH,
String(genWebviewId())
)
if (__DEV__) {
console.log(`[uni-app] preloadWebview[${preloadWebview.id}]`)
}
}
return preloadWebview
}
const webviewReadyCallbacks: Record<string, Function[]> = {}
export function registerWebviewReady(pageId: string, callback: Function) {
;(webviewReadyCallbacks[pageId] || (webviewReadyCallbacks[pageId] = [])).push(
callback
)
}
export function consumeWebviewReady(pageId: string) {
const callbacks = webviewReadyCallbacks[pageId]
isArray(callbacks) && callbacks.forEach((callback) => callback())
delete webviewReadyCallbacks[pageId]
}
......@@ -37,8 +37,8 @@ type ImageState = ReturnType<typeof useImageState>
type FixSize = ReturnType<typeof useImageSize>['fixSize']
const FIX_MODES = {
widthFix: ['width', 'height'],
heightFix: ['height', 'width'],
widthFix: ['offsetWidth', 'height'],
heightFix: ['offsetHeight', 'width'],
}
const IMAGE_MODES = {
aspectFit: ['center center', 'contain'],
......@@ -76,6 +76,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({
<div style={modeStyle} />
{imgSrc ? <img src={imgSrc} draggable={props.draggable} /> : <img />}
{FIX_MODES[mode as keyof typeof FIX_MODES] ? (
// @ts-ignore
<ResizeSensor onResize={fixSize} />
) : (
<span></span>
......@@ -209,8 +210,7 @@ function useImageSize(
return
}
const rootEl = rootRef.value!
const rect = rootEl.getBoundingClientRect()
const value = rect[names[0] as keyof DOMRect] as number
const value = rootEl[names[0] as 'offsetWidth' | 'offsetHeight']
if (value) {
rootEl.style[names[1] as 'height' | 'width'] =
fixNumber(value / ratio) + 'px'
......
......@@ -49,9 +49,9 @@ function useResizeSensorUpdate(
(value: typeof size) => emit('resize', value)
)
return () => {
const { width, height } = rootRef.value!.getBoundingClientRect()
size.width = width
size.height = height
const rootEl = rootRef.value!
size.width = rootEl.offsetWidth
size.height = rootEl.offsetHeight
reset()
}
}
......
......@@ -3,26 +3,26 @@ import { extend } from '@vue/shared'
import E from './TinyEmitter'
export function initBridge(
namespace: 'service' | 'view'
subscribeNamespace: 'service' | 'view'
): Partial<UniApp.UniServiceJSBridge> {
// TODO vue3 compatibility builds
const emitter = new E()
return extend(emitter, {
subscribe(event: string, callback: Function): void {
emitter.on(`${namespace}.${event}`, callback)
emitter.on(`${subscribeNamespace}.${event}`, callback)
},
unsubscribe(event: string, callback: Function): void {
emitter.off(`${namespace}.${event}`, callback)
emitter.off(`${subscribeNamespace}.${event}`, callback)
},
subscribeHandler(event: string, args: unknown, pageId: number): void {
if (__DEV__) {
console.log(
`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(
`[${subscribeNamespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(
args
)}, ${pageId}`
)
}
emitter.emit(`${namespace}.${event}`, args, pageId)
emitter.emit(`${subscribeNamespace}.${event}`, args, pageId)
},
})
}
import { extend } from '@vue/shared'
import { initBridge } from '../../helpers/bridge'
export const ServiceJSBridge = /*#__PURE__*/ extend(initBridge('service'), {
invokeOnCallback(name: string, res: unknown) {
return UniServiceJSBridge.emit('api.' + name, res)
},
})
export const ServiceJSBridge = /*#__PURE__*/ extend(
initBridge('view' /* view 指的是 service 层订阅的是 view 层事件 */),
{
invokeOnCallback(name: string, res: unknown) {
return UniServiceJSBridge.emit('api.' + name, res)
},
}
)
import { initBridge } from '../../helpers/bridge'
export const ViewJSBridge = /*#__PURE__*/ initBridge('view')
export const ViewJSBridge = /*#__PURE__*/ initBridge('service')
......@@ -351,24 +351,24 @@ E.prototype = {
return this;
}
};
function initBridge(namespace) {
function initBridge(subscribeNamespace) {
const emitter = new E();
return shared.extend(emitter, {
subscribe(event, callback) {
emitter.on(`${namespace}.${event}`, callback);
emitter.on(`${subscribeNamespace}.${event}`, callback);
},
unsubscribe(event, callback) {
emitter.off(`${namespace}.${event}`, callback);
emitter.off(`${subscribeNamespace}.${event}`, callback);
},
subscribeHandler(event, args, pageId) {
if (process.env.NODE_ENV !== "production") {
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
console.log(`[${subscribeNamespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
}
emitter.emit(`${namespace}.${event}`, args, pageId);
emitter.emit(`${subscribeNamespace}.${event}`, args, pageId);
}
});
}
const ViewJSBridge = /* @__PURE__ */ initBridge("view");
const ViewJSBridge = /* @__PURE__ */ initBridge("service");
uniShared.passive(true);
const onEventPrevent = /* @__PURE__ */ vue.withModifiers(() => {
}, ["prevent"]);
......@@ -529,7 +529,7 @@ function createNativeEvent(evt) {
}
return event;
}
const ServiceJSBridge = /* @__PURE__ */ shared.extend(initBridge("service"), {
const ServiceJSBridge = /* @__PURE__ */ shared.extend(initBridge("view"), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit("api." + name, res);
}
......@@ -1573,12 +1573,9 @@ function useResizeSensorUpdate(rootRef, emit2, reset) {
});
vue.watch(() => shared.extend({}, size), (value) => emit2("resize", value));
return () => {
const {
width,
height
} = rootRef.value.getBoundingClientRect();
size.width = width;
size.height = height;
const rootEl = rootRef.value;
size.width = rootEl.offsetWidth;
size.height = rootEl.offsetHeight;
reset();
};
}
......@@ -2605,8 +2602,8 @@ const props$p = {
}
};
const FIX_MODES = {
widthFix: ["width", "height"],
heightFix: ["height", "width"]
widthFix: ["offsetWidth", "height"],
heightFix: ["offsetHeight", "width"]
};
const IMAGE_MODES = {
aspectFit: ["center center", "contain"],
......@@ -2764,8 +2761,7 @@ function useImageSize(rootRef, props2, state) {
return;
}
const rootEl = rootRef.value;
const rect = rootEl.getBoundingClientRect();
const value = rect[names[0]];
const value = rootEl[names[0]];
if (value) {
rootEl.style[names[1]] = fixNumber(value / ratio) + "px";
}
......
......@@ -440,24 +440,24 @@ E.prototype = {
return this;
}
};
function initBridge(namespace) {
function initBridge(subscribeNamespace) {
const emitter2 = new E();
return extend(emitter2, {
subscribe(event, callback) {
emitter2.on(`${namespace}.${event}`, callback);
emitter2.on(`${subscribeNamespace}.${event}`, callback);
},
unsubscribe(event, callback) {
emitter2.off(`${namespace}.${event}`, callback);
emitter2.off(`${subscribeNamespace}.${event}`, callback);
},
subscribeHandler(event, args, pageId) {
if (process.env.NODE_ENV !== "production") {
console.log(`[${namespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
console.log(`[${subscribeNamespace}][subscribeHandler][${Date.now()}]:${event}, ${JSON.stringify(args)}, ${pageId}`);
}
emitter2.emit(`${namespace}.${event}`, args, pageId);
emitter2.emit(`${subscribeNamespace}.${event}`, args, pageId);
}
});
}
const ViewJSBridge = /* @__PURE__ */ initBridge("view");
const ViewJSBridge = /* @__PURE__ */ initBridge("service");
const LONGPRESS_TIMEOUT = 350;
const LONGPRESS_THRESHOLD = 10;
const passiveOptions$2 = passive(true);
......@@ -1244,7 +1244,7 @@ function initView(app) {
}
initAppConfig$1(app._context.config);
}
const ServiceJSBridge = /* @__PURE__ */ extend(initBridge("service"), {
const ServiceJSBridge = /* @__PURE__ */ extend(initBridge("view"), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit("api." + name, res);
}
......@@ -5780,12 +5780,9 @@ function useResizeSensorUpdate(rootRef, emit2, reset) {
});
watch(() => extend({}, size), (value) => emit2("resize", value));
return () => {
const {
width,
height
} = rootRef.value.getBoundingClientRect();
size.width = width;
size.height = height;
const rootEl = rootRef.value;
size.width = rootEl.offsetWidth;
size.height = rootEl.offsetHeight;
reset();
};
}
......@@ -7539,8 +7536,8 @@ const props$w = {
}
};
const FIX_MODES = {
widthFix: ["width", "height"],
heightFix: ["height", "width"]
widthFix: ["offsetWidth", "height"],
heightFix: ["offsetHeight", "width"]
};
const IMAGE_MODES = {
aspectFit: ["center center", "contain"],
......@@ -7710,8 +7707,7 @@ function useImageSize(rootRef, props2, state2) {
return;
}
const rootEl = rootRef.value;
const rect = rootEl.getBoundingClientRect();
const value = rect[names[0]];
const value = rootEl[names[0]];
if (value) {
rootEl.style[names[1]] = fixNumber(value / ratio) + "px";
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册