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

wip(app-nvue): requestComponentInfo

上级 c7504aef
......@@ -8,6 +8,7 @@ declare module '@vue/runtime-core' {
}
// 目前 H5,APP 平台 getCurrentPages 中获取的 page 对象调整为 vm 对象
$getAppWebview?: () => PlusWebviewWebviewObject
$requireNativePlugin?: (name: string) => unknown
getOpenerEventChannel: () => EventChannel
$page: Page.PageInstance['$page']
$mpType?: 'app' | 'page'
......
......@@ -358,6 +358,18 @@ var serviceContext = (function (vue) {
};
}
function parseNVueDataset(attr) {
const dataset = {};
if (attr) {
Object.keys(attr).forEach((key) => {
if (key.indexOf('data-') === 0) {
dataset[key.replace('data-', '')] = attr[key];
}
});
}
return dataset;
}
class DOMException extends Error {
constructor(message) {
super(message);
......@@ -1351,7 +1363,15 @@ var serviceContext = (function (vue) {
};
}
function requestComponentInfo(page, reqs, callback) {
function requestComponentInfo(pageVm, reqs, callback) {
if (pageVm.$page.meta.isNVue) {
requestNVueComponentInfo(pageVm, reqs, callback);
}
else {
requestVueComponentInfo(pageVm, reqs, callback);
}
}
function requestVueComponentInfo(pageVm, reqs, callback) {
UniServiceJSBridge.invokeViewMethod('requestComponentInfo', {
reqs: reqs.map((req) => {
if (req.component) {
......@@ -1359,7 +1379,65 @@ var serviceContext = (function (vue) {
}
return req;
}),
}, page.$page.id, callback);
}, pageVm.$page.id, callback);
}
function requestNVueComponentInfo(pageVm, reqs, callback) {
const ids = findNVueElementIds(reqs);
const nvueElementInfos = new Array(ids.length);
findNVueElementInfos(ids, pageVm.$el, nvueElementInfos);
findComponentRectAll(pageVm.$requireNativePlugin('dom'), nvueElementInfos, 0, [], (result) => {
callback(result);
});
}
function findNVueElementIds(reqs) {
const ids = [];
for (let i = 0; i < reqs.length; i++) {
const selector = reqs[i].selector;
if (selector.indexOf('#') === 0) {
ids.push(selector.substring(1));
}
}
return ids;
}
function findNVueElementInfos(ids, elm, infos) {
const nodes = elm.children;
if (!isArray$1(nodes)) {
return false;
}
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node.attr) {
const index = ids.indexOf(node.attr.id);
if (index >= 0) {
infos[index] = {
id: ids[index],
ref: node.ref,
dataset: parseNVueDataset(node.attr),
};
if (ids.length === 1) {
break;
}
}
}
if (node.children) {
findNVueElementInfos(ids, node, infos);
}
}
}
function findComponentRectAll(dom, nvueElementInfos, index, result, callback) {
const attr = nvueElementInfos[index];
dom.getComponentRect(attr.ref, (option) => {
option.size.id = attr.id;
option.size.dataset = attr.dataset;
result.push(option.size);
index += 1;
if (index < nvueElementInfos.length) {
findComponentRectAll(dom, nvueElementInfos, index, result, callback);
}
else {
callback(result);
}
});
}
function setCurrentPageMeta(page, options) {
......
import { ComponentPublicInstance } from 'vue'
import { isArray } from '@vue/shared'
import { SelectorQueryRequest, SelectorQueryNodeInfo } from '@dcloudio/uni-api'
import { NVueElement, parseNVueDataset } from '@dcloudio/uni-shared'
export function requestComponentInfo(
page: ComponentPublicInstance,
pageVm: ComponentPublicInstance,
reqs: Array<SelectorQueryRequest>,
callback: (result: Array<SelectorQueryNodeInfo | null>) => void
) {
if (pageVm.$page.meta.isNVue) {
requestNVueComponentInfo(pageVm, reqs, callback)
} else {
requestVueComponentInfo(pageVm, reqs, callback)
}
}
function requestVueComponentInfo(
pageVm: ComponentPublicInstance,
reqs: Array<SelectorQueryRequest>,
callback: (result: Array<SelectorQueryNodeInfo | null>) => void
) {
......@@ -16,7 +30,100 @@ export function requestComponentInfo(
return req
}),
},
page.$page.id,
pageVm.$page.id,
callback
)
}
function requestNVueComponentInfo(
pageVm: ComponentPublicInstance,
reqs: Array<SelectorQueryRequest>,
callback: (result: Array<SelectorQueryNodeInfo | null>) => void
) {
const ids = findNVueElementIds(reqs)
const nvueElementInfos = new Array(ids.length)
findNVueElementInfos(ids, pageVm.$el, nvueElementInfos)
findComponentRectAll(
pageVm.$requireNativePlugin!('dom') as NVueDomModule,
nvueElementInfos,
0,
[],
(result) => {
callback(result)
}
)
}
interface NVueElementInfo {
id: string
ref: string
dataset: Record<string, unknown>
}
interface NVueDomModule {
getComponentRect: (
ref: string,
callback: (res: { size: Record<string, unknown> }) => void
) => void
}
function findNVueElementIds(reqs: Array<SelectorQueryRequest>) {
const ids = []
for (let i = 0; i < reqs.length; i++) {
const selector = reqs[i].selector
if (selector.indexOf('#') === 0) {
ids.push(selector.substring(1))
}
}
return ids
}
function findNVueElementInfos(
ids: string[],
elm: NVueElement,
infos: NVueElementInfo[]
) {
const nodes = elm.children
if (!isArray(nodes)) {
return false
}
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
if (node.attr) {
const index = ids.indexOf(node.attr.id as string)
if (index >= 0) {
infos[index] = {
id: ids[index],
ref: node.ref,
dataset: parseNVueDataset(node.attr),
}
if (ids.length === 1) {
break
}
}
}
if (node.children) {
findNVueElementInfos(ids, node, infos)
}
}
}
function findComponentRectAll(
dom: NVueDomModule,
nvueElementInfos: NVueElementInfo[],
index: number,
result: Array<SelectorQueryNodeInfo | null>,
callback: (result: Array<SelectorQueryNodeInfo | null>) => void
) {
const attr = nvueElementInfos[index]
dom.getComponentRect(attr.ref, (option) => {
option.size.id = attr.id
option.size.dataset = attr.dataset
result.push(option.size)
index += 1
if (index < nvueElementInfos.length) {
findComponentRectAll(dom, nvueElementInfos, index, result, callback)
} else {
callback(result)
}
})
}
......@@ -685,6 +685,18 @@ function formatH5Log(type, filename, ...args) {
console[type].apply(console, [...args, filename]);
}
function parseNVueDataset(attr) {
const dataset = {};
if (attr) {
Object.keys(attr).forEach((key) => {
if (key.indexOf('data-') === 0) {
dataset[key.replace('data-', '')] = attr[key];
}
});
}
return dataset;
}
function plusReady(callback) {
if (typeof callback !== 'function') {
return;
......@@ -1512,6 +1524,7 @@ exports.normalizeTarget = normalizeTarget;
exports.onCreateVueApp = onCreateVueApp;
exports.once = once;
exports.parseEventName = parseEventName;
exports.parseNVueDataset = parseNVueDataset;
exports.parseQuery = parseQuery;
exports.parseUrl = parseUrl;
exports.passive = passive;
......
......@@ -354,6 +354,7 @@ export declare interface NVueElement {
type: string;
ref: string;
text?: string;
attr: Record<string, unknown>;
styleSheet: Record<string, Record<string, Record<string, unknown>>>;
classList: string[];
parentNode: NVueElement | null;
......@@ -528,6 +529,8 @@ export declare type PageUpdateAction = CreateAction | InsertAction | RemoveActio
export declare function parseEventName(name: string): [string, EventListenerOptions | undefined];
export declare function parseNVueDataset(attr?: Record<string, unknown>): Record<string, unknown>;
/**
* https://github.com/vuejs/vue-router-next/blob/master/src/query.ts
* @internal
......
......@@ -681,6 +681,18 @@ function formatH5Log(type, filename, ...args) {
console[type].apply(console, [...args, filename]);
}
function parseNVueDataset(attr) {
const dataset = {};
if (attr) {
Object.keys(attr).forEach((key) => {
if (key.indexOf('data-') === 0) {
dataset[key.replace('data-', '')] = attr[key];
}
});
}
return dataset;
}
function plusReady(callback) {
if (typeof callback !== 'function') {
return;
......@@ -1366,4 +1378,4 @@ function getEnvLocale() {
return (lang && lang.replace(/[.:].*/, '')) || 'en';
}
export { ACTION_TYPE_ADD_EVENT, ACTION_TYPE_ADD_WXS_EVENT, ACTION_TYPE_CREATE, ACTION_TYPE_EVENT, ACTION_TYPE_INSERT, ACTION_TYPE_PAGE_CREATE, ACTION_TYPE_PAGE_CREATED, ACTION_TYPE_PAGE_SCROLL, ACTION_TYPE_REMOVE, ACTION_TYPE_REMOVE_ATTRIBUTE, ACTION_TYPE_REMOVE_EVENT, ACTION_TYPE_SET_ATTRIBUTE, ACTION_TYPE_SET_TEXT, ATTR_CHANGE_PREFIX, ATTR_CLASS, ATTR_INNER_HTML, ATTR_STYLE, ATTR_TEXT_CONTENT, ATTR_V_OWNER_ID, ATTR_V_RENDERJS, ATTR_V_SHOW, BACKGROUND_COLOR, BUILT_IN_TAGS, BUILT_IN_TAG_NAMES, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, E$1 as Emitter, EventChannel, EventModifierFlags, I18N_JSON_DELIMITERS, JSON_PROTOCOL, LINEFEED, MINI_PROGRAM_PAGE_RUNTIME_HOOKS, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, NVUE_BUILT_IN_TAGS, NVUE_U_BUILT_IN_TAGS, ON_ADD_TO_FAVORITES, ON_APP_ENTER_BACKGROUND, ON_APP_ENTER_FOREGROUND, ON_BACK_PRESS, ON_ERROR, ON_HIDE, ON_KEYBOARD_HEIGHT_CHANGE, ON_LAUNCH, ON_LOAD, ON_NAVIGATION_BAR_BUTTON_TAP, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, ON_PAGE_NOT_FOUND, ON_PAGE_SCROLL, ON_PULL_DOWN_REFRESH, ON_REACH_BOTTOM, ON_REACH_BOTTOM_DISTANCE, ON_READY, ON_RESIZE, ON_SHARE_APP_MESSAGE, ON_SHARE_TIMELINE, ON_SHOW, ON_TAB_ITEM_TAP, ON_THEME_CHANGE, ON_UNHANDLE_REJECTION, ON_UNLOAD, ON_WEB_INVOKE_APP_SERVICE, ON_WXS_INVOKE_CALL_METHOD, PLUS_RE, PRIMARY_COLOR, RENDERJS_MODULES, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, SLOT_DEFAULT_NAME, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UNI_STORAGE_LOCALE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniLifecycleHooks, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, WXS_MODULES, WXS_PROTOCOL, addFont, addLeadingSlash, cache, cacheStringFunction, callOptions, createIsCustomElement, createRpx2Unit, createUniEvent, customizeEvent, debounce, decode, decodedQuery, defaultMiniProgramRpx2Unit, defaultNVueRpx2Unit, defaultRpx2Unit, dynamicSlotName, forcePatchProp, formatAppLog, formatDateTime, formatH5Log, formatLog, getCustomDataset, getEnvLocale, getLen, getValueByDataPath, initCustomDatasetOnce, invokeArrayFns, invokeCreateVueAppHook, isAppNVueNativeTag, isAppNativeTag, isBuiltInComponent, isComponentInternalInstance, isComponentTag, isH5CustomElement, isH5NativeTag, isMiniProgramNativeTag, isRootHook, normalizeDataset, normalizeEventType, normalizeTarget, onCreateVueApp, once, parseEventName, parseQuery, parseUrl, passive, plusReady, removeLeadingSlash, resolveComponentInstance, resolveOwnerEl, resolveOwnerVm, sanitise, scrollTo, stringifyQuery, updateElementStyle };
export { ACTION_TYPE_ADD_EVENT, ACTION_TYPE_ADD_WXS_EVENT, ACTION_TYPE_CREATE, ACTION_TYPE_EVENT, ACTION_TYPE_INSERT, ACTION_TYPE_PAGE_CREATE, ACTION_TYPE_PAGE_CREATED, ACTION_TYPE_PAGE_SCROLL, ACTION_TYPE_REMOVE, ACTION_TYPE_REMOVE_ATTRIBUTE, ACTION_TYPE_REMOVE_EVENT, ACTION_TYPE_SET_ATTRIBUTE, ACTION_TYPE_SET_TEXT, ATTR_CHANGE_PREFIX, ATTR_CLASS, ATTR_INNER_HTML, ATTR_STYLE, ATTR_TEXT_CONTENT, ATTR_V_OWNER_ID, ATTR_V_RENDERJS, ATTR_V_SHOW, BACKGROUND_COLOR, BUILT_IN_TAGS, BUILT_IN_TAG_NAMES, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, E$1 as Emitter, EventChannel, EventModifierFlags, I18N_JSON_DELIMITERS, JSON_PROTOCOL, LINEFEED, MINI_PROGRAM_PAGE_RUNTIME_HOOKS, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, NVUE_BUILT_IN_TAGS, NVUE_U_BUILT_IN_TAGS, ON_ADD_TO_FAVORITES, ON_APP_ENTER_BACKGROUND, ON_APP_ENTER_FOREGROUND, ON_BACK_PRESS, ON_ERROR, ON_HIDE, ON_KEYBOARD_HEIGHT_CHANGE, ON_LAUNCH, ON_LOAD, ON_NAVIGATION_BAR_BUTTON_TAP, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, ON_PAGE_NOT_FOUND, ON_PAGE_SCROLL, ON_PULL_DOWN_REFRESH, ON_REACH_BOTTOM, ON_REACH_BOTTOM_DISTANCE, ON_READY, ON_RESIZE, ON_SHARE_APP_MESSAGE, ON_SHARE_TIMELINE, ON_SHOW, ON_TAB_ITEM_TAP, ON_THEME_CHANGE, ON_UNHANDLE_REJECTION, ON_UNLOAD, ON_WEB_INVOKE_APP_SERVICE, ON_WXS_INVOKE_CALL_METHOD, PLUS_RE, PRIMARY_COLOR, RENDERJS_MODULES, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, SLOT_DEFAULT_NAME, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UNI_STORAGE_LOCALE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniLifecycleHooks, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, WXS_MODULES, WXS_PROTOCOL, addFont, addLeadingSlash, cache, cacheStringFunction, callOptions, createIsCustomElement, createRpx2Unit, createUniEvent, customizeEvent, debounce, decode, decodedQuery, defaultMiniProgramRpx2Unit, defaultNVueRpx2Unit, defaultRpx2Unit, dynamicSlotName, forcePatchProp, formatAppLog, formatDateTime, formatH5Log, formatLog, getCustomDataset, getEnvLocale, getLen, getValueByDataPath, initCustomDatasetOnce, invokeArrayFns, invokeCreateVueAppHook, isAppNVueNativeTag, isAppNativeTag, isBuiltInComponent, isComponentInternalInstance, isComponentTag, isH5CustomElement, isH5NativeTag, isMiniProgramNativeTag, isRootHook, normalizeDataset, normalizeEventType, normalizeTarget, onCreateVueApp, once, parseEventName, parseNVueDataset, parseQuery, parseUrl, passive, plusReady, removeLeadingSlash, resolveComponentInstance, resolveOwnerEl, resolveOwnerVm, sanitise, scrollTo, stringifyQuery, updateElementStyle };
import { createApp, ComponentPublicInstance } from 'vue'
export function parseNVueDataset(attr?: Record<string, unknown>) {
const dataset: Record<string, unknown> = {}
if (attr) {
Object.keys(attr).forEach((key) => {
if (key.indexOf('data-') === 0) {
dataset[key.replace('data-', '')] = attr[key]
}
})
}
return dataset
}
export interface Vue {
createApp: typeof createApp
}
......@@ -85,6 +97,7 @@ export interface NVueElement {
ref: string
text?: string
attr: Record<string, unknown>
styleSheet: Record<string, Record<string, Record<string, unknown>>>
classList: string[]
parentNode: NVueElement | null
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册