diff --git a/packages/uni-app-plus/dist/index.v3.js b/packages/uni-app-plus/dist/index.v3.js index 064c1299532b9d8bf491afacc17157210cf645bb..a4d342419dc01b18999d8fb89672e5c0985dd6a7 100644 --- a/packages/uni-app-plus/dist/index.v3.js +++ b/packages/uni-app-plus/dist/index.v3.js @@ -7140,6 +7140,129 @@ var serviceContext = (function () { } } + const callbacks$1 = {}; + + function createCallbacks (namespace) { + let scopedCallbacks = callbacks$1[namespace]; + if (!scopedCallbacks) { + scopedCallbacks = { + id: 1, + callbacks: Object.create(null) + }; + callbacks$1[namespace] = scopedCallbacks; + } + return { + get (id) { + return scopedCallbacks.callbacks[id] + }, + pop (id) { + const callback = scopedCallbacks.callbacks[id]; + if (callback) { + delete scopedCallbacks.callbacks[id]; + } + return callback + }, + push (callback) { + const id = scopedCallbacks.id++; + scopedCallbacks.callbacks[id] = callback; + return id + } + } + } + + const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo'); + + function requestComponentInfo (pageInstance, queue, callback) { + UniServiceJSBridge.publishHandler('requestComponentInfo', { + reqId: requestComponentInfoCallbacks.push(callback), + reqs: queue + }, pageInstance.$page.id); + } + + function parseDataset (attr) { + const dataset = {}; + + Object.keys(attr || {}).forEach(key => { + if (key.indexOf('data') === 0) { + let str = key.replace('data', ''); + str = str.charAt(0).toLowerCase() + str.slice(1); + dataset[str] = attr[key]; + } + }); + + return dataset + } + + function findAttrs (ids, elm, result) { + let nodes = elm.children; + if (!Array.isArray(nodes)) { + return false + } + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i]; + if (node.attr) { + let index = ids.indexOf(node.attr.id); + if (index >= 0) { + result[index] = { + id: ids[index], + ref: node.ref, + dataset: parseDataset(node.attr) + }; + if (ids.length === 1) { + break + } + } + } + if (node.children) { + findAttrs(ids, node, result); + } + } + } + + function getSelectors (queue) { + let ids = []; + for (let i = 0; i < queue.length; i++) { + const selector = queue[i].selector; + if (selector.indexOf('#') === 0) { + ids.push(selector.substring(1)); + } + } + return ids + } + + function getComponentRectAll (dom, attrs, index, result, callback) { + const attr = attrs[index]; + dom.getComponentRect(attr.ref, option => { + option.size.id = attr.id; + option.size.dataset = attr.dataset; + result.push(option.size); + index += 1; + if (index < attrs.length) { + getComponentRectAll(dom, attrs, index, result, callback); + } else { + callback(result); + } + }); + } + + function requestComponentInfo$1 (pageInstance, queue, callback) { + // TODO 重构,逻辑不对,queue 里的每一项可能有单独的作用域查找(即 component) + const vm = pageInstance.$vm; + const dom = vm._$weex.requireModule('dom'); + const selectors = getSelectors(queue); + let outAttrs = new Array(selectors.length); + findAttrs(selectors, vm.$el, outAttrs); + getComponentRectAll(dom, outAttrs, 0, [], (result) => { + callback(result); + }); + } + + function requestComponentInfo$2 (pageInstance, queue, callback) { + pageInstance.$page.meta.isNVue + ? requestComponentInfo$1(pageInstance, queue, callback) + : requestComponentInfo(pageInstance, queue, callback); + } + var api = /*#__PURE__*/Object.freeze({ @@ -7257,7 +7380,8 @@ var serviceContext = (function () { setTabBarItem: setTabBarItem$2, setTabBarStyle: setTabBarStyle$2, hideTabBar: hideTabBar$2, - showTabBar: showTabBar$2 + showTabBar: showTabBar$2, + requestComponentInfo: requestComponentInfo$2 }); const Emitter = new Vue(); @@ -7482,9 +7606,9 @@ var serviceContext = (function () { 'error', 'waiting' ]; - const callbacks$1 = {}; + const callbacks$2 = {}; eventNames$1.forEach(name => { - callbacks$1[name] = []; + callbacks$2[name] = []; }); const props$1 = [ @@ -7548,7 +7672,7 @@ var serviceContext = (function () { errMsg, errCode }) => { - callbacks$1[state].forEach(callback => { + callbacks$2[state].forEach(callback => { if (typeof callback === 'function') { callback(state === 'error' ? { errMsg, @@ -7600,7 +7724,7 @@ var serviceContext = (function () { eventNames$1.forEach(item => { const name = item[0].toUpperCase() + item.substr(1); BackgroundAudioManager.prototype[`on${name}`] = function (callback) { - callbacks$1[item].push(callback); + callbacks$2[item].push(callback); }; }); @@ -7614,10 +7738,10 @@ var serviceContext = (function () { getBackgroundAudioManager: getBackgroundAudioManager }); - const callbacks$2 = []; + const callbacks$3 = []; onMethod('onAccelerometerChange', function (res) { - callbacks$2.forEach(callbackId => { + callbacks$3.forEach(callbackId => { invoke(callbackId, res); }); }); @@ -7629,7 +7753,7 @@ var serviceContext = (function () { */ function onAccelerometerChange (callbackId) { // TODO 当没有 start 时,添加 on 需要主动 start? - callbacks$2.push(callbackId); + callbacks$3.push(callbackId); if (!isEnable) { startAccelerometer(); } @@ -7684,10 +7808,10 @@ var serviceContext = (function () { onBLECharacteristicValueChange: onBLECharacteristicValueChange$1 }); - const callbacks$3 = []; + const callbacks$4 = []; onMethod('onCompassChange', function (res) { - callbacks$3.forEach(callbackId => { + callbacks$4.forEach(callbackId => { invoke(callbackId, res); }); }); @@ -7699,7 +7823,7 @@ var serviceContext = (function () { */ function onCompassChange (callbackId) { // TODO 当没有 start 时,添加 on 需要主动 start? - callbacks$3.push(callbackId); + callbacks$4.push(callbackId); if (!isEnable$1) { startCompass(); } @@ -7730,23 +7854,23 @@ var serviceContext = (function () { stopCompass: stopCompass }); - const callbacks$4 = []; + const callbacks$5 = []; onMethod('onNetworkStatusChange', res => { - callbacks$4.forEach(callbackId => { + callbacks$5.forEach(callbackId => { invoke(callbackId, res); }); }); function onNetworkStatusChange (callbackId) { - callbacks$4.push(callbackId); + callbacks$5.push(callbackId); } var require_context_module_1_9 = /*#__PURE__*/Object.freeze({ onNetworkStatusChange: onNetworkStatusChange }); - const callbacks$5 = { + const callbacks$6 = { pause: [], resume: [], start: [], @@ -7760,7 +7884,7 @@ var serviceContext = (function () { const state = res.state; delete res.state; delete res.errMsg; - callbacks$5[state].forEach(callback => { + callbacks$6[state].forEach(callback => { if (typeof callback === 'function') { callback(res); } @@ -7768,7 +7892,7 @@ var serviceContext = (function () { }); } onError (callback) { - callbacks$5.error.push(callback); + callbacks$6.error.push(callback); } onFrameRecorded (callback) { @@ -7780,16 +7904,16 @@ var serviceContext = (function () { } onPause (callback) { - callbacks$5.pause.push(callback); + callbacks$6.pause.push(callback); } onResume (callback) { - callbacks$5.resume.push(callback); + callbacks$6.resume.push(callback); } onStart (callback) { - callbacks$5.start.push(callback); + callbacks$6.start.push(callback); } onStop (callback) { - callbacks$5.stop.push(callback); + callbacks$6.stop.push(callback); } pause () { invokeMethod('operateRecorder', { @@ -8090,7 +8214,7 @@ var serviceContext = (function () { const socketTasks$1 = Object.create(null); const socketTasksArray = []; - const callbacks$6 = Object.create(null); + const callbacks$7 = Object.create(null); onMethod('onSocketTaskStateChange', ({ socketTaskId, state, @@ -8111,8 +8235,8 @@ var serviceContext = (function () { if (state === 'open') { socketTask.readyState = socketTask.OPEN; } - if (socketTask === socketTasksArray[0] && callbacks$6[state]) { - invoke(callbacks$6[state], state === 'message' ? { + if (socketTask === socketTasksArray[0] && callbacks$7[state]) { + invoke(callbacks$7[state], state === 'message' ? { data } : {}); } @@ -8171,19 +8295,19 @@ var serviceContext = (function () { } function onSocketOpen (callbackId) { - callbacks$6.open = callbackId; + callbacks$7.open = callbackId; } function onSocketError (callbackId) { - callbacks$6.error = callbackId; + callbacks$7.error = callbackId; } function onSocketMessage (callbackId) { - callbacks$6.message = callbackId; + callbacks$7.message = callbackId; } function onSocketClose (callbackId) { - callbacks$6.close = callbackId; + callbacks$7.close = callbackId; } var require_context_module_1_13 = /*#__PURE__*/Object.freeze({ @@ -8484,19 +8608,132 @@ var serviceContext = (function () { createAnimation: createAnimation }); - const callbacks$7 = []; + class NodesRef { + constructor (selectorQuery, component, selector, single) { + this._selectorQuery = selectorQuery; + this._component = component; + this._selector = selector; + this._single = single; + } + + boundingClientRect (callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, { + id: true, + dataset: true, + rect: true, + size: true + }, + callback); + return this._selectorQuery + } + + fields (fields, callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, + fields, + callback + ); + return this._selectorQuery + } + + scrollOffset (callback) { + this._selectorQuery._push( + this._selector, + this._component, + this._single, { + id: true, + dataset: true, + scrollOffset: true + }, + callback + ); + return this._selectorQuery + } + } + + class SelectorQuery { + constructor (page) { + this._page = page; + this._queue = []; + this._queueCb = []; + } + + exec (callback) { + invokeMethod('requestComponentInfo', this._page, this._queue, res => { + const queueCbs = this._queueCb; + res.forEach((result, index) => { + const queueCb = queueCbs[index]; + if (isFn(queueCb)) { + queueCb.call(this, result); + } + }); + isFn(callback) && callback.call(this, res); + }); + } + + ['in'] (component) { + // app-plus 平台传递 id + this._component = component._$id || component; + return this + } + + select (selector) { + return new NodesRef(this, this._component, selector, true) + } + + selectAll (selector) { + return new NodesRef(this, this._component, selector, false) + } + + selectViewport () { + return new NodesRef(this, 0, '', true) + } + + _push (selector, component, single, fields, callback) { + this._queue.push({ + component, + selector, + single, + fields + }); + this._queueCb.push(callback); + } + } + + function createSelectorQuery (context) { + if (context) { + return new SelectorQuery(context) + } + const pages = getCurrentPages(); + const len = pages.length; + if (!len) { + UniServiceJSBridge.emit('onError', 'createSelectorQuery:fail'); + } + return new SelectorQuery(pages[len - 1]) + } + + var require_context_module_1_17 = /*#__PURE__*/Object.freeze({ + createSelectorQuery: createSelectorQuery + }); + + const callbacks$8 = []; onMethod('onKeyboardHeightChange', res => { - callbacks$7.forEach(callbackId => { + callbacks$8.forEach(callbackId => { invoke(callbackId, res); }); }); function onKeyboardHeightChange (callbackId) { - callbacks$7.push(callbackId); + callbacks$8.push(callbackId); } - var require_context_module_1_17 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_18 = /*#__PURE__*/Object.freeze({ onKeyboardHeightChange: onKeyboardHeightChange }); @@ -8508,7 +8745,7 @@ var serviceContext = (function () { return {} } - var require_context_module_1_18 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_19 = /*#__PURE__*/Object.freeze({ pageScrollTo: pageScrollTo$1 }); @@ -8532,42 +8769,42 @@ var serviceContext = (function () { const hideTabBarRedDot$1 = removeTabBarBadge$1; - const callbacks$8 = []; + const callbacks$9 = []; onMethod('onTabBarMidButtonTap', res => { - callbacks$8.forEach(callbackId => { + callbacks$9.forEach(callbackId => { invoke(callbackId, res); }); }); function onTabBarMidButtonTap (callbackId) { - callbacks$8.push(callbackId); + callbacks$9.push(callbackId); } - var require_context_module_1_19 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_20 = /*#__PURE__*/Object.freeze({ removeTabBarBadge: removeTabBarBadge$1, showTabBarRedDot: showTabBarRedDot$1, hideTabBarRedDot: hideTabBarRedDot$1, onTabBarMidButtonTap: onTabBarMidButtonTap }); - const callbacks$9 = []; + const callbacks$a = []; onMethod('onViewDidResize', res => { - callbacks$9.forEach(callbackId => { + callbacks$a.forEach(callbackId => { invoke(callbackId, res); }); }); function onWindowResize (callbackId) { - callbacks$9.push(callbackId); + callbacks$a.push(callbackId); } function offWindowResize (callbackId) { // 此处和微信平台一致查询不到去掉最后一个 - callbacks$9.splice(callbacks$9.indexOf(callbackId), 1); + callbacks$a.splice(callbacks$a.indexOf(callbackId), 1); } - var require_context_module_1_20 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_21 = /*#__PURE__*/Object.freeze({ onWindowResize: onWindowResize, offWindowResize: offWindowResize }); @@ -8594,10 +8831,11 @@ var serviceContext = (function () { './network/upload-file.js': require_context_module_1_14, './storage/storage.js': require_context_module_1_15, './ui/create-animation.js': require_context_module_1_16, - './ui/keyboard.js': require_context_module_1_17, - './ui/page-scroll-to.js': require_context_module_1_18, - './ui/tab-bar.js': require_context_module_1_19, - './ui/window.js': require_context_module_1_20, + './ui/create-selector-query.js': require_context_module_1_17, + './ui/keyboard.js': require_context_module_1_18, + './ui/page-scroll-to.js': require_context_module_1_19, + './ui/tab-bar.js': require_context_module_1_20, + './ui/window.js': require_context_module_1_21, }; var req = function req(key) { @@ -8635,10 +8873,10 @@ var serviceContext = (function () { pageIds = [pageIds]; } const evalJSCode = - `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${eventType}",${args})`; + `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${eventType}",${args},__PAGE_ID__)`; pageIds.forEach(id => { const webview = plus.webview.getWebviewById(String(id)); - webview && webview.evalJS(evalJSCode); + webview && webview.evalJS(evalJSCode.replace('__PAGE_ID__', id)); }); } @@ -8750,36 +8988,6 @@ var serviceContext = (function () { on('onWebInvokeAppService', onWebInvokeAppService); } - const callbacks$a = {}; - - function createCallbacks (namespace) { - let scopedCallbacks = callbacks$a[namespace]; - if (!scopedCallbacks) { - scopedCallbacks = { - id: 1, - callbacks: Object.create(null) - }; - callbacks$a[namespace] = scopedCallbacks; - } - return { - get (id) { - return scopedCallbacks.callbacks[id] - }, - pop (id) { - const callback = scopedCallbacks.callbacks[id]; - if (callback) { - delete scopedCallbacks.callbacks[id]; - } - return callback - }, - push (callback) { - const id = scopedCallbacks.id++; - scopedCallbacks.callbacks[id] = callback; - return id - } - } - } - function initSubscribe (subscribe, { getApp, getCurrentPages diff --git a/packages/uni-app-plus/dist/view.umd.js b/packages/uni-app-plus/dist/view.umd.js index 4a5862b7f5edd36f2b620cef0819695dd762863b..82149c22933fada437add7db16ab6bacfedb796d 100644 --- a/packages/uni-app-plus/dist/view.umd.js +++ b/packages/uni-app-plus/dist/view.umd.js @@ -9929,7 +9929,8 @@ var handleData = (_handleData = {}, _defineProperty(_handleData, _constants__WEB pageId = _data2[0], pagePath = _data2[1]; - new PageVueComponent({ + var page = getCurrentPages()[0]; + page.$vm = new PageVueComponent({ mpType: 'page', pageId: pageId, pagePath: pagePath @@ -12615,10 +12616,26 @@ function getNodeInfo(el, fields) { return info; } +function getElm(component, pageVm) { + if (!component) { + return pageVm.$el; + } + + if (typeof component === 'string') { + var componentVm = pageVm._$vd.getVm(component); + + if (!componentVm) { + throw new Error("Not Found\uFF1APage[".concat(pageVm.$page.id, "][").concat(component, "]")); + } + + return componentVm.$el; + } + + return component.$el; +} + function getNodesInfo(pageVm, component, selector, single, fields) { - /* eslint-disable no-mixed-operators */ - // TODO 判断 component 是否是 _$id,如果是,从 pageVm 中递归查找该组件实例 - var $el = component && component.$el || pageVm.$el; + var $el = getElm(component, pageVm); if (single) { var node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector)); @@ -12653,15 +12670,15 @@ function requestComponentInfo(_ref, pageId) { reqs = _ref.reqs; var pages = getCurrentPages(); // 跨平台时,View 层也应该实现该方法,举例 App 上,View 层的 getCurrentPages 返回长度为1的当前页面数组 - var pageVm = pages.find(function (page) { + var page = pages.find(function (page) { return page.$page.id === pageId; }); - if (!pageVm) { - // TODO 是否需要 defer + if (!page) { throw new Error("Not Found\uFF1APage[".concat(pageId, "]")); } + var pageVm = page.$vm; var result = []; reqs.forEach(function (_ref2) { var component = _ref2.component, diff --git a/src/platforms/h5/service/api/ui/create-selector-query.js b/src/core/service/api/ui/create-selector-query.js similarity index 69% rename from src/platforms/h5/service/api/ui/create-selector-query.js rename to src/core/service/api/ui/create-selector-query.js index 2860a2b765d49f1880ffd484a8c2a3a93a305b8a..b29dce24f84ac411e0cced5b0e6f902927f3f2c9 100644 --- a/src/platforms/h5/service/api/ui/create-selector-query.js +++ b/src/core/service/api/ui/create-selector-query.js @@ -1,10 +1,9 @@ import { isFn } from 'uni-shared' - -import createCallbacks from 'uni-helpers/callbacks' - -const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo') +import { + invokeMethod +} from '../../platform' class NodesRef { constructor (selectorQuery, component, selector, single) { @@ -54,24 +53,15 @@ class NodesRef { } } -function requestComponentInfo (pageId, queue, callback) { - const reqId = requestComponentInfoCallbacks.push(callback) - - UniServiceJSBridge.publishHandler('requestComponentInfo', { - reqId, - reqs: queue - }, pageId) -} - class SelectorQuery { - constructor (pageId) { - this.pageId = pageId + constructor (page) { + this._page = page this._queue = [] this._queueCb = [] } exec (callback) { - requestComponentInfo(this.pageId, this._queue, res => { + invokeMethod('requestComponentInfo', this._page, this._queue, res => { const queueCbs = this._queueCb res.forEach((result, index) => { const queueCb = queueCbs[index] @@ -83,9 +73,9 @@ class SelectorQuery { }) } - ['in'] (component) { - // TODO 跨平台,非 h5 平台传递 component._$id - this._component = component + ['in'] (component) { + // app-plus 平台传递 id + this._component = component._$id || component return this } @@ -114,12 +104,12 @@ class SelectorQuery { export function createSelectorQuery (context) { if (context) { - return new SelectorQuery(context.$page.id) + return new SelectorQuery(context) } - const app = getApp() - if (app.$route && app.$route.params.__id__) { - return new SelectorQuery(app.$route.params.__id__) - } else { + const pages = getCurrentPages() + const len = pages.length + if (!len) { UniServiceJSBridge.emit('onError', 'createSelectorQuery:fail') } + return new SelectorQuery(pages[len - 1]) } diff --git a/src/core/view/bridge/subscribe/api/request-component-info.js b/src/core/view/bridge/subscribe/api/request-component-info.js index 0f5a0b40e3b47e533828cb298e856ccacaf81b3c..0dc25f08b0677aae314b62a6654d0f2b12997ca9 100644 --- a/src/core/view/bridge/subscribe/api/request-component-info.js +++ b/src/core/view/bridge/subscribe/api/request-component-info.js @@ -73,10 +73,22 @@ function getNodeInfo (el, fields) { return info } +function getElm (component, pageVm) { + if (!component) { + return pageVm.$el + } + if (typeof component === 'string') { + const componentVm = pageVm._$vd.getVm(component) + if (!componentVm) { + throw new Error(`Not Found:Page[${pageVm.$page.id}][${component}]`) + } + return componentVm.$el + } + return component.$el +} + function getNodesInfo (pageVm, component, selector, single, fields) { - /* eslint-disable no-mixed-operators */ - // TODO 判断 component 是否是 _$id,如果是,从 pageVm 中递归查找该组件实例 - const $el = component && component.$el || pageVm.$el + const $el = getElm(component, pageVm) if (single) { const node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector)) if (node) { @@ -106,13 +118,14 @@ export function requestComponentInfo ({ }, pageId) { const pages = getCurrentPages() // 跨平台时,View 层也应该实现该方法,举例 App 上,View 层的 getCurrentPages 返回长度为1的当前页面数组 - const pageVm = pages.find(page => page.$page.id === pageId) + const page = pages.find(page => page.$page.id === pageId) - if (!pageVm) { - // TODO 是否需要 defer + if (!page) { throw new Error(`Not Found:Page[${pageId}]`) } + const pageVm = page.$vm + const result = [] reqs.forEach(function ({ component, diff --git a/src/platforms/app-plus-nvue/service/api/index.js b/src/platforms/app-plus-nvue/service/api/index.js index c0d041b39f3bc6d3343bd2d5d285df6745c7fa86..9a3f89a82cfc5d768e3e297562a0f2fd4b8a866a 100644 --- a/src/platforms/app-plus-nvue/service/api/index.js +++ b/src/platforms/app-plus-nvue/service/api/index.js @@ -2,4 +2,4 @@ export * from './context/live-pusher' export * from './context/map' export * from './context/video' -export * from './ui/create-selector-query' +export * from './ui/request-component-info' diff --git a/src/platforms/app-plus-nvue/service/api/ui/create-selector-query.js b/src/platforms/app-plus-nvue/service/api/ui/create-selector-query.js deleted file mode 100644 index 4f444460828ddde4bbe8095675a9eb42b62da41c..0000000000000000000000000000000000000000 --- a/src/platforms/app-plus-nvue/service/api/ui/create-selector-query.js +++ /dev/null @@ -1,185 +0,0 @@ -import { - isFn -} from 'uni-shared' - -class NodesRef { - constructor (selectorQuery, component, selector, single) { - this._selectorQuery = selectorQuery - this._component = component - this._selector = selector - this._single = single - } - - boundingClientRect (callback) { - this._selectorQuery._push( - this._selector, - this._component, - this._single, { - id: true, - dataset: true, - rect: true, - size: true - }, - callback) - return this._selectorQuery - } - - fields (fields, callback) { - this._selectorQuery._push( - this._selector, - this._component, - this._single, - fields, - callback - ) - return this._selectorQuery - } - - scrollOffset (callback) { - this._selectorQuery._push( - this._selector, - this._component, - this._single, { - id: true, - dataset: true, - scrollOffset: true - }, - callback - ) - return this._selectorQuery - } -} - -function processDataset (attr) { - const dataset = {} - - Object.keys(attr || {}).forEach(key => { - if (key.indexOf('data') === 0) { - let str = key.replace('data', '') - str = str.charAt(0).toLowerCase() + str.slice(1) - dataset[str] = attr[key] - } - }) - - return dataset -} - -function findAttrs (ids, elm, result) { - let nodes = elm.children - if (!Array.isArray(nodes)) { - return false - } - for (let i = 0; i < nodes.length; i++) { - let node = nodes[i] - if (node.attr) { - let index = ids.indexOf(node.attr.id) - if (index >= 0) { - result[index] = { - id: ids[index], - ref: node.ref, - dataset: processDataset(node.attr) - } - if (ids.length === 1) { - break - } - } - } - if (node.children) { - findAttrs(ids, node, result) - } - } -} - -function getSelectors (queue) { - let ids = [] - for (let i = 0; i < queue.length; i++) { - const selector = queue[i].selector - if (selector.indexOf('#') === 0) { - ids.push(selector.substring(1)) - } - } - return ids -} - -function getComponentRectAll (dom, attrs, index, result, callback) { - const attr = attrs[index] - dom.getComponentRect(attr.ref, option => { - option.size.id = attr.id - option.size.dataset = attr.dataset - result.push(option.size) - index += 1 - if (index < attrs.length) { - getComponentRectAll(dom, attrs, index, result, callback) - } else { - callback(result) - } - }) -} - -function requestComponentInfo (dom, component, queue, callback) { - const selectors = getSelectors(queue) - let outAttrs = new Array(selectors.length) - findAttrs(selectors, component.$el, outAttrs) - getComponentRectAll(dom, outAttrs, 0, [], (result) => { - callback(result) - }) -} - -class SelectorQuery { - constructor (pageId) { - this.pageId = pageId - this._queue = [] - this._queueCb = [] - } - - exec (callback) { - if (!this._component) { - return - } - this._dom = this._component._$weex.requireModule('dom') - requestComponentInfo(this._dom, this._component, this._queue, res => { - const queueCbs = this._queueCb - res.forEach((result, index) => { - const queueCb = queueCbs[index] - if (isFn(queueCb)) { - queueCb.call(this, result) - } - }) - isFn(callback) && callback.call(this, res) - }) - } - - ['in'] (component) { - if (!component) { - return console.warn('uni.createSelectorQuery 必须传入当前 vm 对象(this)') - } - this._component = component - return this - } - - select (selector) { - return new NodesRef(this, this._component, selector, true) - } - - selectAll (selector) { - return new NodesRef(this, this._component, selector, false) - } - - selectViewport () { - return new NodesRef(this, 0, '', true) - } - - _push (selector, component, single, fields, callback) { - this._queue.push({ - component, - selector, - single, - fields - }) - this._queueCb.push(callback) - } -} - -export function createSelectorQuery () { - return new SelectorQuery() -} diff --git a/src/platforms/app-plus-nvue/service/api/ui/request-component-info.js b/src/platforms/app-plus-nvue/service/api/ui/request-component-info.js new file mode 100644 index 0000000000000000000000000000000000000000..10332bc92815040490603e4cba833ee2a40ecbf1 --- /dev/null +++ b/src/platforms/app-plus-nvue/service/api/ui/request-component-info.js @@ -0,0 +1,77 @@ +function parseDataset (attr) { + const dataset = {} + + Object.keys(attr || {}).forEach(key => { + if (key.indexOf('data') === 0) { + let str = key.replace('data', '') + str = str.charAt(0).toLowerCase() + str.slice(1) + dataset[str] = attr[key] + } + }) + + return dataset +} + +function findAttrs (ids, elm, result) { + let nodes = elm.children + if (!Array.isArray(nodes)) { + return false + } + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i] + if (node.attr) { + let index = ids.indexOf(node.attr.id) + if (index >= 0) { + result[index] = { + id: ids[index], + ref: node.ref, + dataset: parseDataset(node.attr) + } + if (ids.length === 1) { + break + } + } + } + if (node.children) { + findAttrs(ids, node, result) + } + } +} + +function getSelectors (queue) { + let ids = [] + for (let i = 0; i < queue.length; i++) { + const selector = queue[i].selector + if (selector.indexOf('#') === 0) { + ids.push(selector.substring(1)) + } + } + return ids +} + +function getComponentRectAll (dom, attrs, index, result, callback) { + const attr = attrs[index] + dom.getComponentRect(attr.ref, option => { + option.size.id = attr.id + option.size.dataset = attr.dataset + result.push(option.size) + index += 1 + if (index < attrs.length) { + getComponentRectAll(dom, attrs, index, result, callback) + } else { + callback(result) + } + }) +} + +export function requestComponentInfo (pageInstance, queue, callback) { + // TODO 重构,逻辑不对,queue 里的每一项可能有单独的作用域查找(即 component) + const vm = pageInstance.$vm + const dom = vm._$weex.requireModule('dom') + const selectors = getSelectors(queue) + let outAttrs = new Array(selectors.length) + findAttrs(selectors, vm.$el, outAttrs) + getComponentRectAll(dom, outAttrs, 0, [], (result) => { + callback(result) + }) +} diff --git a/src/platforms/app-plus/service/api/index.js b/src/platforms/app-plus/service/api/index.js index 9b1693b2ea028406da36a4fdef1c48e0bcc5fd5a..0a25a750973d22017372795e97942a5311b94caa 100644 --- a/src/platforms/app-plus/service/api/index.js +++ b/src/platforms/app-plus/service/api/index.js @@ -61,3 +61,5 @@ export { from './ui/pull-down-refresh' export * from './ui/tab-bar' + +export * from './ui/request-component-info' diff --git a/src/platforms/app-plus/service/api/ui/request-component-info.js b/src/platforms/app-plus/service/api/ui/request-component-info.js new file mode 100644 index 0000000000000000000000000000000000000000..581dc945d49c045f4b31a97d0ab5d077e6f9c91c --- /dev/null +++ b/src/platforms/app-plus/service/api/ui/request-component-info.js @@ -0,0 +1,13 @@ +import { + requestComponentInfo as requestVueComponentInfo +} from 'uni-platforms/h5/service/api/ui/request-component-info' + +import { + requestComponentInfo as requestNVueComponentInfo +} from 'uni-platforms/app-plus-nvue/service/api/ui/request-component-info' + +export function requestComponentInfo (pageInstance, queue, callback) { + pageInstance.$page.meta.isNVue + ? requestNVueComponentInfo(pageInstance, queue, callback) + : requestVueComponentInfo(pageInstance, queue, callback) +} diff --git a/src/platforms/app-plus/service/publish-handler.js b/src/platforms/app-plus/service/publish-handler.js index 715d46c0227785643ae2216bca02b73c61a22aec..6104cdd387da88dc7a3147cab2ecd20189017735 100644 --- a/src/platforms/app-plus/service/publish-handler.js +++ b/src/platforms/app-plus/service/publish-handler.js @@ -7,9 +7,9 @@ export function publishHandler (eventType, args, pageIds) { pageIds = [pageIds] } const evalJSCode = - `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${eventType}",${args})` + `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${eventType}",${args},__PAGE_ID__)` pageIds.forEach(id => { const webview = plus.webview.getWebviewById(String(id)) - webview && webview.evalJS(evalJSCode) + webview && webview.evalJS(evalJSCode.replace('__PAGE_ID__', id)) }) } diff --git a/src/platforms/app-plus/view/framework/plugins/data.js b/src/platforms/app-plus/view/framework/plugins/data.js index de3b319fd9aa4a02d6bf3c7b7b8aca9edd49552f..fc51c00c0a0b63284a446a51f3178eae0a46b152 100644 --- a/src/platforms/app-plus/view/framework/plugins/data.js +++ b/src/platforms/app-plus/view/framework/plugins/data.js @@ -50,7 +50,8 @@ const handleData = { }, [PAGE_CREATED]: function onPageCreated (data) { const [pageId, pagePath] = data - new PageVueComponent({ + const page = getCurrentPages()[0] + page.$vm = new PageVueComponent({ mpType: 'page', pageId, pagePath diff --git a/src/platforms/h5/service/api/ui/request-component-info.js b/src/platforms/h5/service/api/ui/request-component-info.js new file mode 100644 index 0000000000000000000000000000000000000000..11d4ab599670b508f0b1ba51edf73a414f866e92 --- /dev/null +++ b/src/platforms/h5/service/api/ui/request-component-info.js @@ -0,0 +1,10 @@ +import createCallbacks from 'uni-helpers/callbacks' + +const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo') + +export function requestComponentInfo (pageInstance, queue, callback) { + UniServiceJSBridge.publishHandler('requestComponentInfo', { + reqId: requestComponentInfoCallbacks.push(callback), + reqs: queue + }, pageInstance.$page.id) +}