util.uts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /// <reference types="@dcloudio/uni-app-x/types/native-global" />
  2. // @ts-expect-error
  3. import { IUniNativeDocument } from 'io.dcloud.uniapp.dom'
  4. // @ts-ignore
  5. function getPageId(page: Page): string {
  6. return page.$appPage!.pageId
  7. }
  8. // @ts-ignore
  9. function getPagePath(page: Page): string {
  10. return page.route
  11. }
  12. // @ts-ignore
  13. function getPageQuery(page: Page): UTSJSONObject {
  14. return map2Object(page.options as Map<string, any | null>)
  15. }
  16. // @ts-ignore
  17. function getPageById(id: string): Page | null {
  18. // @ts-ignore
  19. const pages = getCurrentPages()
  20. // @ts-ignore
  21. let result: Page | null = null
  22. // @ts-ignore
  23. pages.forEach((page: Page) => {
  24. if (getPageId(page) == id) {
  25. result = page
  26. }
  27. })
  28. return result
  29. }
  30. // @ts-ignore
  31. export function getPageVm(id: string): Page | null {
  32. return getPageById(id)
  33. }
  34. export function pageGetData(
  35. // @ts-ignore
  36. vm: Page,
  37. // @ts-ignore
  38. ): UTSJSONObject {
  39. // TODO: path 目前无法处理类型问题,暂由服务端处理
  40. return map2Object(vm.$data)
  41. }
  42. // @ts-ignore
  43. export function pageSetData(vm: Page, data: Map<string, any | null>): void {
  44. data.forEach((value: any | null, key: string) => {
  45. vm.$data.set(key, value)
  46. })
  47. }
  48. // @ts-ignore
  49. export function parsePage(page: Page): UTSJSONObject {
  50. return {
  51. id: getPageId(page),
  52. path: getPagePath(page),
  53. query: getPageQuery(page),
  54. // @ts-ignore
  55. } as UTSJSONObject
  56. }
  57. export function getComponentVmBySelector(
  58. pageId: string,
  59. selector: string,
  60. callback: (result: any | null, error: any | null) => void
  61. // @ts-ignore
  62. ): ComponentPublicInstance | null {
  63. const page = getPageVm(pageId)
  64. if (page == null) {
  65. callback(null, { errMsg: `Page[${pageId}] not exists` })
  66. return null
  67. }
  68. const component = page.$children.find(
  69. // @ts-ignore
  70. (child: ComponentPublicInstance): boolean => child.$options.name == selector
  71. )
  72. if (component == null) {
  73. callback(null, { errMsg: `component[${selector}] not exists` })
  74. return null
  75. }
  76. return component
  77. }
  78. export function getComponentVmByNodeId(
  79. pageId: string,
  80. nodeId: number,
  81. callback: (result: any | null, error: any | null) => void
  82. // @ts-ignore
  83. ): ComponentPublicInstance | null {
  84. const page = getPageVm(pageId)
  85. if (page == null) {
  86. callback(null, { errMsg: `Page[${pageId}] not exists` })
  87. return null
  88. }
  89. // @ts-ignore
  90. let component: ComponentPublicInstance | null = null
  91. // @ts-ignore
  92. function getComponentChild(parent: ComponentPublicInstance) {
  93. // @ts-ignore
  94. if (parent.$.uid.toInt() == nodeId.toInt()) {
  95. component = parent
  96. return
  97. }
  98. // @ts-ignore
  99. parent.$children.forEach((child: ComponentPublicInstance) => {
  100. getComponentChild(child)
  101. })
  102. }
  103. getComponentChild(page)
  104. if (component == null) {
  105. callback(null, { errMsg: `component[${nodeId}] not exists` })
  106. return null
  107. }
  108. return component
  109. }
  110. export function getElementByIdOrNodeId(
  111. pageId: string,
  112. elementId: string | null,
  113. nodeId: number | null,
  114. callback: (result: any | null, error: any | null) => void
  115. ): UniElement | null {
  116. if (nodeId != null) {
  117. return getComponentDomByNodeId(pageId, nodeId, callback)
  118. } else if (elementId != null) {
  119. return getElementById(pageId, elementId, callback)
  120. }
  121. return null
  122. }
  123. export function getComponentDomByNodeId(
  124. pageId: string,
  125. nodeId: number,
  126. callback: (result: any | null, error: any | null) => void
  127. ): UniElement | null {
  128. const component = getComponentVmByNodeId(pageId, nodeId, callback)
  129. if (component == null) {
  130. return null
  131. }
  132. return component.$el
  133. }
  134. export function getElementByNodeIdOrElementId(
  135. pageId: string,
  136. nodeId: number | null,
  137. elementId: string | null,
  138. callback: (result: any | null, error: any | null) => void
  139. ): UniElement | null {
  140. const page = getPageVm(pageId)
  141. if (page == null) {
  142. callback(null, { errMsg: `Page[${pageId}] not exists` })
  143. return null
  144. }
  145. if (nodeId != null) {
  146. return getComponentDomByNodeId(pageId, nodeId, callback)
  147. } else if (elementId != null) {
  148. return getElementById(pageId, elementId, callback)
  149. }
  150. return null
  151. }
  152. export function getElementById(
  153. pageId: string,
  154. elementId: string,
  155. callback: (result: any | null, error: any | null) => void
  156. ): UniElement | null {
  157. const page = getPageVm(pageId)
  158. if (page == null) {
  159. callback(null, { errMsg: `Page[${pageId}] not exists` })
  160. return null
  161. }
  162. const document = page.$appPage!.document
  163. const element = (document as IUniNativeDocument).getNativeElementById(elementId)
  164. if (element == null) {
  165. callback(null, { errMsg: `element[${elementId}] not exists` })
  166. return null
  167. }
  168. return element
  169. }
  170. export function getValidComponentsOrNodes(
  171. // @ts-ignore
  172. vnode: VNode | null,
  173. selector: string,
  174. // @ts-ignore
  175. list: UTSJSONObject[],
  176. getAll = false
  177. ): void {
  178. if (vnode == null || (!getAll && list.length > 0)) {
  179. return
  180. }
  181. if (isValidComponentOrNode(vnode, selector)) {
  182. if (vnode.component != null) {
  183. list.push({
  184. // @ts-ignore
  185. nodeId: (vnode.component as ComponentInternalInstance).uid,
  186. // @ts-ignore
  187. tagName: (vnode.component as ComponentInternalInstance).options.name,
  188. elementId: `${Date.now()}`,
  189. })
  190. } else {
  191. list.push({
  192. // @ts-expect-error
  193. elementId: (vnode.el as UniElementImpl).id,
  194. tagName: vnode.el!.tagName,
  195. })
  196. }
  197. if (!getAll) {
  198. return
  199. }
  200. }
  201. // @ts-ignore
  202. if (vnode.children !== null && isArray(vnode.children)) {
  203. ; (vnode.children as any[]).forEach((child) => {
  204. // @ts-ignore
  205. if (child instanceof VNode) {
  206. getValidComponentsOrNodes(child, selector, list, getAll)
  207. }
  208. })
  209. }
  210. if (vnode.component != null) {
  211. const component = vnode.component
  212. getValidComponentsOrNodes(component!.subTree, selector, list, getAll)
  213. }
  214. }
  215. // @ts-ignore
  216. function isValidComponentOrNode(vnode: VNode, selector: string): boolean {
  217. if (
  218. vnode.component != null &&
  219. // @ts-ignore
  220. (vnode.component as ComponentInternalInstance).options.name == selector
  221. ) {
  222. return true
  223. }
  224. if (vnode.el != null) {
  225. const node = vnode.el!
  226. if (selector.startsWith('.')) {
  227. return node.classList.includes(selector.substring(1))
  228. } else if (selector.startsWith('#')) {
  229. return node.getAttribute('id') == selector.substring(1)
  230. }
  231. return node.tagName.toUpperCase() == selector.toUpperCase()
  232. }
  233. return false
  234. }
  235. export function getValidNodes(
  236. node: UniElement | null,
  237. selector: string,
  238. // @ts-ignore
  239. list: UTSJSONObject[],
  240. getAll = false
  241. ): void {
  242. if (node == null) {
  243. return
  244. }
  245. if (isValidNode(node, selector)) {
  246. list.push({
  247. elementId: node.getNodeId(),
  248. tagName: node.tagName,
  249. })
  250. if (!getAll) {
  251. return
  252. }
  253. }
  254. // @ts-ignore
  255. node.childNodes.forEach((child: UniElement) => {
  256. getValidNodes(child, selector, list, getAll)
  257. })
  258. }
  259. function isValidNode(node: UniElement, selector: string): boolean {
  260. if (selector.startsWith('.')) {
  261. // @ts-ignore
  262. return node.classList.includes(selector.substring(1))
  263. } else if (selector.startsWith('#')) {
  264. return node.getAttribute('id') == selector.substring(1)
  265. }
  266. return node.tagName.toUpperCase() == selector.toUpperCase()
  267. }
  268. export function componentGetData(
  269. // @ts-ignore
  270. vm: ComponentPublicInstance,
  271. // @ts-ignore
  272. ): UTSJSONObject {
  273. // TODO: path 目前无法处理类型问题,暂由服务端处理
  274. return map2Object(vm.$data)
  275. }
  276. export function componentSetData(
  277. // @ts-ignore
  278. vm: ComponentPublicInstance,
  279. data: Map<string, any | null>
  280. ): void {
  281. data.forEach((value: any | null, key: string) => {
  282. // @ts-ignore
  283. vm.$data.set(key, value)
  284. })
  285. }
  286. export function getChildrenText(node: UniElement): string {
  287. let result = ''
  288. // @ts-ignore
  289. node.childNodes.forEach((child: UniElement) => {
  290. // @ts-expect-error
  291. if (isTextElement(child)) {
  292. result += child.getAttribute('value')
  293. } else {
  294. result += getChildrenText(child)
  295. }
  296. })
  297. return result
  298. }
  299. export function toCamelCase(str: string): string {
  300. const wordList = str.split('-')
  301. for (let i = 1; i < wordList.length; i++) {
  302. const word = wordList[i]
  303. wordList[i] = word.at(0)!.toUpperCase() + word.substring(1)
  304. }
  305. return wordList.join('')
  306. }
  307. // 不处理用户自定义数据的类型,因为可能存在指定类型,无法处理
  308. // @ts-ignore
  309. function map2Object(data: Map<string, any | null>): UTSJSONObject {
  310. const result = {}
  311. data.forEach((value: any | null, key: string) => {
  312. result[key] = value
  313. })
  314. return result
  315. }