@lcap/nasl 3.2.0-beta.4 → 3.3.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (774) hide show
  1. package/out/automate/upgrader/2.20.js +1 -1
  2. package/out/automate/upgrader/2.20.js.map +1 -1
  3. package/out/bak/translator.js +11 -15
  4. package/out/bak/translator.js.map +1 -1
  5. package/out/breakpoint/generator/AfterStartNode.js +3 -1
  6. package/out/breakpoint/generator/AfterStartNode.js.map +1 -1
  7. package/out/breakpoint/generator/BeforeEndNode.js.map +1 -1
  8. package/out/breakpoint/generator/BreakpointNode.d.ts +1 -0
  9. package/out/breakpoint/generator/BreakpointNode.js +48 -15
  10. package/out/breakpoint/generator/BreakpointNode.js.map +1 -1
  11. package/out/breakpoint/generator/CallbackNode.d.ts +4 -0
  12. package/out/breakpoint/generator/CallbackNode.js +22 -0
  13. package/out/breakpoint/generator/CallbackNode.js.map +1 -0
  14. package/out/breakpoint/generator/FragmentNode.d.ts +4 -0
  15. package/out/breakpoint/generator/FragmentNode.js +18 -0
  16. package/out/breakpoint/generator/FragmentNode.js.map +1 -0
  17. package/out/breakpoint/generator/index.js +25 -4
  18. package/out/breakpoint/generator/index.js.map +1 -1
  19. package/out/breakpoint/shared/constants.d.ts +3 -0
  20. package/out/breakpoint/shared/constants.js +6 -1
  21. package/out/breakpoint/shared/constants.js.map +1 -1
  22. package/out/breakpoint/shared/operations.js.map +1 -1
  23. package/out/breakpoint/shared/socket.d.ts +1 -1
  24. package/out/breakpoint/shared/socket.js +36 -7
  25. package/out/breakpoint/shared/socket.js.map +1 -1
  26. package/out/breakpoint/shared/utils.d.ts +2 -0
  27. package/out/breakpoint/shared/utils.js +15 -2
  28. package/out/breakpoint/shared/utils.js.map +1 -1
  29. package/out/breakpoint/store/core.d.ts +48 -2
  30. package/out/breakpoint/store/core.js +58 -32
  31. package/out/breakpoint/store/core.js.map +1 -1
  32. package/out/breakpoint/store/dock.js +1 -1
  33. package/out/breakpoint/store/dock.js.map +1 -1
  34. package/out/common/BaseNode.d.ts +1 -1
  35. package/out/common/BaseNode.js +105 -51
  36. package/out/common/BaseNode.js.map +1 -1
  37. package/out/common/Command.d.ts +13 -2
  38. package/out/common/Command.js +37 -9
  39. package/out/common/Command.js.map +1 -1
  40. package/out/common/EventEmitter.js.map +1 -1
  41. package/out/common/Messager.d.ts +3 -3
  42. package/out/common/Messager.js +6 -7
  43. package/out/common/Messager.js.map +1 -1
  44. package/out/common/asyncFuncMap.js.map +1 -1
  45. package/out/concepts/Abort__.js +6 -5
  46. package/out/concepts/Abort__.js.map +1 -1
  47. package/out/concepts/Anchor__.d.ts +4 -3
  48. package/out/concepts/Anchor__.js +24 -7
  49. package/out/concepts/Anchor__.js.map +1 -1
  50. package/out/concepts/AnonymousFunction__.d.ts +22 -21
  51. package/out/concepts/AnonymousFunction__.js +48 -22
  52. package/out/concepts/AnonymousFunction__.js.map +1 -1
  53. package/out/concepts/App__.d.ts +421 -247
  54. package/out/concepts/App__.js +286 -54
  55. package/out/concepts/App__.js.map +1 -1
  56. package/out/concepts/Argument__.d.ts +4 -3
  57. package/out/concepts/Argument__.js +42 -11
  58. package/out/concepts/Argument__.js.map +1 -1
  59. package/out/concepts/Assignee__.d.ts +45 -45
  60. package/out/concepts/Assignee__.js +15 -15
  61. package/out/concepts/Assignee__.js.map +1 -1
  62. package/out/concepts/AssignmentLine__.js +6 -5
  63. package/out/concepts/AssignmentLine__.js.map +1 -1
  64. package/out/concepts/Assignment__.d.ts +7 -6
  65. package/out/concepts/Assignment__.js +40 -22
  66. package/out/concepts/Assignment__.js.map +1 -1
  67. package/out/concepts/Attribute__.d.ts +3 -3
  68. package/out/concepts/Attribute__.js +8 -7
  69. package/out/concepts/Attribute__.js.map +1 -1
  70. package/out/concepts/AuthInterface__.js +4 -3
  71. package/out/concepts/AuthInterface__.js.map +1 -1
  72. package/out/concepts/AuthLogicForCallInterface__.d.ts +15 -15
  73. package/out/concepts/AuthLogicForCallInterface__.js +46 -27
  74. package/out/concepts/AuthLogicForCallInterface__.js.map +1 -1
  75. package/out/concepts/AuthLogic__.js +27 -13
  76. package/out/concepts/AuthLogic__.js.map +1 -1
  77. package/out/concepts/BackendVariable__.d.ts +5 -5
  78. package/out/concepts/BackendVariable__.js +23 -26
  79. package/out/concepts/BackendVariable__.js.map +1 -1
  80. package/out/concepts/Backend__.d.ts +18 -18
  81. package/out/concepts/Backend__.js +13 -13
  82. package/out/concepts/Backend__.js.map +1 -1
  83. package/out/concepts/BatchAssignment__.d.ts +34 -33
  84. package/out/concepts/BatchAssignment__.js +83 -43
  85. package/out/concepts/BatchAssignment__.js.map +1 -1
  86. package/out/concepts/BinaryExpression__.d.ts +7 -6
  87. package/out/concepts/BinaryExpression__.js +60 -24
  88. package/out/concepts/BinaryExpression__.js.map +1 -1
  89. package/out/concepts/BindAttribute__.d.ts +37 -37
  90. package/out/concepts/BindAttribute__.js +101 -48
  91. package/out/concepts/BindAttribute__.js.map +1 -1
  92. package/out/concepts/BindDirective__.d.ts +13 -13
  93. package/out/concepts/BindDirective__.js +23 -21
  94. package/out/concepts/BindDirective__.js.map +1 -1
  95. package/out/concepts/BindEvent__.d.ts +28 -28
  96. package/out/concepts/BindEvent__.js +99 -48
  97. package/out/concepts/BindEvent__.js.map +1 -1
  98. package/out/concepts/BindStyle__.d.ts +14 -15
  99. package/out/concepts/BindStyle__.js +16 -16
  100. package/out/concepts/BindStyle__.js.map +1 -1
  101. package/out/concepts/BooleanLiteral__.d.ts +1 -0
  102. package/out/concepts/BooleanLiteral__.js +12 -5
  103. package/out/concepts/BooleanLiteral__.js.map +1 -1
  104. package/out/concepts/CallAuthInterface__.d.ts +15 -15
  105. package/out/concepts/CallAuthInterface__.js +23 -22
  106. package/out/concepts/CallAuthInterface__.js.map +1 -1
  107. package/out/concepts/CallConnector__.d.ts +11 -9
  108. package/out/concepts/CallConnector__.js +79 -36
  109. package/out/concepts/CallConnector__.js.map +1 -1
  110. package/out/concepts/CallFunction__.d.ts +17 -16
  111. package/out/concepts/CallFunction__.js +95 -63
  112. package/out/concepts/CallFunction__.js.map +1 -1
  113. package/out/concepts/CallInterface__.d.ts +9 -8
  114. package/out/concepts/CallInterface__.js +71 -30
  115. package/out/concepts/CallInterface__.js.map +1 -1
  116. package/out/concepts/CallLogic__.d.ts +20 -19
  117. package/out/concepts/CallLogic__.js +155 -52
  118. package/out/concepts/CallLogic__.js.map +1 -1
  119. package/out/concepts/CallQueryComponent__.d.ts +51 -51
  120. package/out/concepts/CallQueryComponent__.js +66 -63
  121. package/out/concepts/CallQueryComponent__.js.map +1 -1
  122. package/out/concepts/Comment__.d.ts +1 -0
  123. package/out/concepts/Comment__.js +13 -6
  124. package/out/concepts/Comment__.js.map +1 -1
  125. package/out/concepts/CompletionProperty__.d.ts +3 -3
  126. package/out/concepts/CompletionProperty__.js +8 -7
  127. package/out/concepts/CompletionProperty__.js.map +1 -1
  128. package/out/concepts/ConfigGroup__.d.ts +15 -15
  129. package/out/concepts/ConfigGroup__.js +9 -9
  130. package/out/concepts/ConfigGroup__.js.map +1 -1
  131. package/out/concepts/ConfigPropertyValue__.js +4 -3
  132. package/out/concepts/ConfigPropertyValue__.js.map +1 -1
  133. package/out/concepts/ConfigProperty__.d.ts +15 -15
  134. package/out/concepts/ConfigProperty__.js +10 -10
  135. package/out/concepts/ConfigProperty__.js.map +1 -1
  136. package/out/concepts/Configuration__.d.ts +15 -15
  137. package/out/concepts/Configuration__.js +9 -9
  138. package/out/concepts/Configuration__.js.map +1 -1
  139. package/out/concepts/Connection__.d.ts +166 -0
  140. package/out/concepts/Connection__.js +332 -0
  141. package/out/concepts/Connection__.js.map +1 -0
  142. package/out/concepts/ConnectorTrigger__.js +4 -3
  143. package/out/concepts/ConnectorTrigger__.js.map +1 -1
  144. package/out/concepts/Connector__.d.ts +66 -66
  145. package/out/concepts/Connector__.js +16 -15
  146. package/out/concepts/Connector__.js.map +1 -1
  147. package/out/concepts/Constant__.d.ts +3 -3
  148. package/out/concepts/Constant__.js +8 -7
  149. package/out/concepts/Constant__.js.map +1 -1
  150. package/out/concepts/DataElement__.d.ts +3 -3
  151. package/out/concepts/DataElement__.js +6 -5
  152. package/out/concepts/DataElement__.js.map +1 -1
  153. package/out/concepts/DataSource__.d.ts +15 -15
  154. package/out/concepts/DataSource__.js +55 -39
  155. package/out/concepts/DataSource__.js.map +1 -1
  156. package/out/concepts/DatabaseTypeAnnotation__.js +4 -3
  157. package/out/concepts/DatabaseTypeAnnotation__.js.map +1 -1
  158. package/out/concepts/Destination__.d.ts +12 -11
  159. package/out/concepts/Destination__.js +93 -36
  160. package/out/concepts/Destination__.js.map +1 -1
  161. package/out/concepts/End__.js +15 -13
  162. package/out/concepts/End__.js.map +1 -1
  163. package/out/concepts/EntityIndex__.d.ts +1 -1
  164. package/out/concepts/EntityIndex__.js +6 -5
  165. package/out/concepts/EntityIndex__.js.map +1 -1
  166. package/out/concepts/EntityProperty__.d.ts +8 -7
  167. package/out/concepts/EntityProperty__.js +39 -24
  168. package/out/concepts/EntityProperty__.js.map +1 -1
  169. package/out/concepts/Entity__.d.ts +31 -30
  170. package/out/concepts/Entity__.js +40 -16
  171. package/out/concepts/Entity__.js.map +1 -1
  172. package/out/concepts/EnumItem__.d.ts +1 -0
  173. package/out/concepts/EnumItem__.js +12 -5
  174. package/out/concepts/EnumItem__.js.map +1 -1
  175. package/out/concepts/Enum__.d.ts +9 -8
  176. package/out/concepts/Enum__.js +24 -11
  177. package/out/concepts/Enum__.js.map +1 -1
  178. package/out/concepts/Event__.d.ts +15 -15
  179. package/out/concepts/Event__.js +6 -5
  180. package/out/concepts/Event__.js.map +1 -1
  181. package/out/concepts/ExternalDestination__.d.ts +6 -6
  182. package/out/concepts/ExternalDestination__.js +12 -11
  183. package/out/concepts/ExternalDestination__.js.map +1 -1
  184. package/out/concepts/ForEachStatement__.d.ts +25 -24
  185. package/out/concepts/ForEachStatement__.js +101 -36
  186. package/out/concepts/ForEachStatement__.js.map +1 -1
  187. package/out/concepts/FrontendLibrary__.d.ts +30 -30
  188. package/out/concepts/FrontendLibrary__.js +12 -13
  189. package/out/concepts/FrontendLibrary__.js.map +1 -1
  190. package/out/concepts/FrontendVariable__.js +4 -3
  191. package/out/concepts/FrontendVariable__.js.map +1 -1
  192. package/out/concepts/Frontend__.d.ts +64 -65
  193. package/out/concepts/Frontend__.js +23 -27
  194. package/out/concepts/Frontend__.js.map +1 -1
  195. package/out/concepts/Function__.d.ts +64 -63
  196. package/out/concepts/Function__.js +49 -21
  197. package/out/concepts/Function__.js.map +1 -1
  198. package/out/concepts/Identifier__.js +37 -31
  199. package/out/concepts/Identifier__.js.map +1 -1
  200. package/out/concepts/IfStatement__.d.ts +20 -19
  201. package/out/concepts/IfStatement__.js +64 -34
  202. package/out/concepts/IfStatement__.js.map +1 -1
  203. package/out/concepts/Integration__.d.ts +3 -3
  204. package/out/concepts/Integration__.js +8 -7
  205. package/out/concepts/Integration__.js.map +1 -1
  206. package/out/concepts/InterfaceParam__.d.ts +3 -3
  207. package/out/concepts/InterfaceParam__.js +7 -6
  208. package/out/concepts/InterfaceParam__.js.map +1 -1
  209. package/out/concepts/Interface__.d.ts +33 -33
  210. package/out/concepts/Interface__.js +19 -20
  211. package/out/concepts/Interface__.js.map +1 -1
  212. package/out/concepts/JSBlock__.d.ts +1 -0
  213. package/out/concepts/JSBlock__.js +12 -5
  214. package/out/concepts/JSBlock__.js.map +1 -1
  215. package/out/concepts/JavaLogic__.js +10 -9
  216. package/out/concepts/JavaLogic__.js.map +1 -1
  217. package/out/concepts/LogicItem__.d.ts +6 -0
  218. package/out/concepts/LogicItem__.js +14 -5
  219. package/out/concepts/LogicItem__.js.map +1 -1
  220. package/out/concepts/Logic__.d.ts +80 -79
  221. package/out/concepts/Logic__.js +204 -58
  222. package/out/concepts/Logic__.js.map +1 -1
  223. package/out/concepts/MatchCase__.d.ts +39 -38
  224. package/out/concepts/MatchCase__.js +122 -37
  225. package/out/concepts/MatchCase__.js.map +1 -1
  226. package/out/concepts/Match__.d.ts +13 -11
  227. package/out/concepts/Match__.js +128 -60
  228. package/out/concepts/Match__.js.map +1 -1
  229. package/out/concepts/MemberExpression__.d.ts +7 -6
  230. package/out/concepts/MemberExpression__.js +52 -22
  231. package/out/concepts/MemberExpression__.js.map +1 -1
  232. package/out/concepts/MicroApp__.js +4 -3
  233. package/out/concepts/MicroApp__.js.map +1 -1
  234. package/out/concepts/Module__.d.ts +239 -155
  235. package/out/concepts/Module__.js +139 -33
  236. package/out/concepts/Module__.js.map +1 -1
  237. package/out/concepts/MsgTriggerEvent__.d.ts +15 -15
  238. package/out/concepts/MsgTriggerEvent__.js +6 -5
  239. package/out/concepts/MsgTriggerEvent__.js.map +1 -1
  240. package/out/concepts/MsgTriggerLauncher__.d.ts +23 -15
  241. package/out/concepts/MsgTriggerLauncher__.js +24 -5
  242. package/out/concepts/MsgTriggerLauncher__.js.map +1 -1
  243. package/out/concepts/Namespace__.d.ts +180 -180
  244. package/out/concepts/Namespace__.js +33 -34
  245. package/out/concepts/Namespace__.js.map +1 -1
  246. package/out/concepts/NewComposite__.d.ts +49 -48
  247. package/out/concepts/NewComposite__.js +164 -49
  248. package/out/concepts/NewComposite__.js.map +1 -1
  249. package/out/concepts/NewList__.d.ts +19 -18
  250. package/out/concepts/NewList__.js +29 -12
  251. package/out/concepts/NewList__.js.map +1 -1
  252. package/out/concepts/NewMap__.d.ts +34 -33
  253. package/out/concepts/NewMap__.js +81 -72
  254. package/out/concepts/NewMap__.js.map +1 -1
  255. package/out/concepts/New__.js +6 -5
  256. package/out/concepts/New__.js.map +1 -1
  257. package/out/concepts/NullLiteral__.js +6 -5
  258. package/out/concepts/NullLiteral__.js.map +1 -1
  259. package/out/concepts/NumericLiteral__.d.ts +4 -3
  260. package/out/concepts/NumericLiteral__.js +15 -8
  261. package/out/concepts/NumericLiteral__.js.map +1 -1
  262. package/out/concepts/OqlQueryComponent__.d.ts +4 -3
  263. package/out/concepts/OqlQueryComponent__.js +25 -16
  264. package/out/concepts/OqlQueryComponent__.js.map +1 -1
  265. package/out/concepts/OverriddenLogic__.d.ts +79 -79
  266. package/out/concepts/OverriddenLogic__.js +79 -58
  267. package/out/concepts/OverriddenLogic__.js.map +1 -1
  268. package/out/concepts/Param__.d.ts +6 -5
  269. package/out/concepts/Param__.js +66 -29
  270. package/out/concepts/Param__.js.map +1 -1
  271. package/out/concepts/Point__.js +4 -3
  272. package/out/concepts/Point__.js.map +1 -1
  273. package/out/concepts/ProcessComponent__.d.ts +30 -30
  274. package/out/concepts/ProcessComponent__.js +8 -7
  275. package/out/concepts/ProcessComponent__.js.map +1 -1
  276. package/out/concepts/ProcessElement__.d.ts +96 -96
  277. package/out/concepts/ProcessElement__.js +34 -34
  278. package/out/concepts/ProcessElement__.js.map +1 -1
  279. package/out/concepts/ProcessOutcome__.js +6 -5
  280. package/out/concepts/ProcessOutcome__.js.map +1 -1
  281. package/out/concepts/ProcessOutcomes__.js +6 -5
  282. package/out/concepts/ProcessOutcomes__.js.map +1 -1
  283. package/out/concepts/Process__.d.ts +75 -75
  284. package/out/concepts/Process__.js +33 -30
  285. package/out/concepts/Process__.js.map +1 -1
  286. package/out/concepts/QueryAggregateExpression__.d.ts +3 -3
  287. package/out/concepts/QueryAggregateExpression__.js +8 -7
  288. package/out/concepts/QueryAggregateExpression__.js.map +1 -1
  289. package/out/concepts/QueryFieldExpression__.js +7 -6
  290. package/out/concepts/QueryFieldExpression__.js.map +1 -1
  291. package/out/concepts/QueryFromExpression__.d.ts +8 -8
  292. package/out/concepts/QueryFromExpression__.js +8 -7
  293. package/out/concepts/QueryFromExpression__.js.map +1 -1
  294. package/out/concepts/QueryGroupByExpression__.d.ts +3 -3
  295. package/out/concepts/QueryGroupByExpression__.js +9 -10
  296. package/out/concepts/QueryGroupByExpression__.js.map +1 -1
  297. package/out/concepts/QueryJoinExpression__.d.ts +23 -23
  298. package/out/concepts/QueryJoinExpression__.js +11 -10
  299. package/out/concepts/QueryJoinExpression__.js.map +1 -1
  300. package/out/concepts/QueryLimitExpression__.d.ts +6 -6
  301. package/out/concepts/QueryLimitExpression__.js +9 -8
  302. package/out/concepts/QueryLimitExpression__.js.map +1 -1
  303. package/out/concepts/QueryOrderByExpression__.d.ts +6 -6
  304. package/out/concepts/QueryOrderByExpression__.js +9 -8
  305. package/out/concepts/QueryOrderByExpression__.js.map +1 -1
  306. package/out/concepts/QuerySelectExpression__.d.ts +30 -30
  307. package/out/concepts/QuerySelectExpression__.js +9 -8
  308. package/out/concepts/QuerySelectExpression__.js.map +1 -1
  309. package/out/concepts/Rect__.js +4 -3
  310. package/out/concepts/Rect__.js.map +1 -1
  311. package/out/concepts/Return__.d.ts +4 -3
  312. package/out/concepts/Return__.js +37 -18
  313. package/out/concepts/Return__.js.map +1 -1
  314. package/out/concepts/Role__.js +9 -9
  315. package/out/concepts/Role__.js.map +1 -1
  316. package/out/concepts/SelectMembers__.d.ts +18 -18
  317. package/out/concepts/SelectMembers__.js +10 -9
  318. package/out/concepts/SelectMembers__.js.map +1 -1
  319. package/out/concepts/Slot__.d.ts +3 -3
  320. package/out/concepts/Slot__.js +6 -5
  321. package/out/concepts/Slot__.js.map +1 -1
  322. package/out/concepts/SqlQueryComponent__.d.ts +4 -3
  323. package/out/concepts/SqlQueryComponent__.js +21 -12
  324. package/out/concepts/SqlQueryComponent__.js.map +1 -1
  325. package/out/concepts/Start__.js +6 -5
  326. package/out/concepts/Start__.js.map +1 -1
  327. package/out/concepts/StringInterpolation__.d.ts +16 -15
  328. package/out/concepts/StringInterpolation__.js +37 -14
  329. package/out/concepts/StringInterpolation__.js.map +1 -1
  330. package/out/concepts/StringLiteral__.d.ts +1 -0
  331. package/out/concepts/StringLiteral__.js +13 -8
  332. package/out/concepts/StringLiteral__.js.map +1 -1
  333. package/out/concepts/StructureProperty__.d.ts +4 -3
  334. package/out/concepts/StructureProperty__.js +22 -9
  335. package/out/concepts/StructureProperty__.js.map +1 -1
  336. package/out/concepts/Structure__.d.ts +31 -30
  337. package/out/concepts/Structure__.js +27 -15
  338. package/out/concepts/Structure__.js.map +1 -1
  339. package/out/concepts/SwitchCase__.d.ts +12 -11
  340. package/out/concepts/SwitchCase__.js +69 -31
  341. package/out/concepts/SwitchCase__.js.map +1 -1
  342. package/out/concepts/SwitchStatement__.d.ts +9 -8
  343. package/out/concepts/SwitchStatement__.js +27 -7
  344. package/out/concepts/SwitchStatement__.js.map +1 -1
  345. package/out/concepts/Theme__.js +4 -3
  346. package/out/concepts/Theme__.js.map +1 -1
  347. package/out/concepts/Transactional__.js +4 -3
  348. package/out/concepts/Transactional__.js.map +1 -1
  349. package/out/concepts/TriggerEvent__.d.ts +15 -15
  350. package/out/concepts/TriggerEvent__.js +6 -5
  351. package/out/concepts/TriggerEvent__.js.map +1 -1
  352. package/out/concepts/TriggerLauncher__.d.ts +15 -10
  353. package/out/concepts/TriggerLauncher__.js +54 -32
  354. package/out/concepts/TriggerLauncher__.js.map +1 -1
  355. package/out/concepts/TypeAnnotation__.d.ts +28 -27
  356. package/out/concepts/TypeAnnotation__.js +144 -124
  357. package/out/concepts/TypeAnnotation__.js.map +1 -1
  358. package/out/concepts/TypeParam__.d.ts +1 -0
  359. package/out/concepts/TypeParam__.js +12 -5
  360. package/out/concepts/TypeParam__.js.map +1 -1
  361. package/out/concepts/UnaryExpression__.d.ts +4 -3
  362. package/out/concepts/UnaryExpression__.js +31 -20
  363. package/out/concepts/UnaryExpression__.js.map +1 -1
  364. package/out/concepts/Unparsed__.d.ts +1 -0
  365. package/out/concepts/Unparsed__.js +12 -5
  366. package/out/concepts/Unparsed__.js.map +1 -1
  367. package/out/concepts/UseComponent__.js +4 -3
  368. package/out/concepts/UseComponent__.js.map +1 -1
  369. package/out/concepts/ValidationRule__.d.ts +14 -14
  370. package/out/concepts/ValidationRule__.js +19 -17
  371. package/out/concepts/ValidationRule__.js.map +1 -1
  372. package/out/concepts/Variable__.d.ts +4 -3
  373. package/out/concepts/Variable__.js +39 -23
  374. package/out/concepts/Variable__.js.map +1 -1
  375. package/out/concepts/ViewBlock__.js +4 -3
  376. package/out/concepts/ViewBlock__.js.map +1 -1
  377. package/out/concepts/ViewComponent__.d.ts +90 -90
  378. package/out/concepts/ViewComponent__.js +16 -15
  379. package/out/concepts/ViewComponent__.js.map +1 -1
  380. package/out/concepts/ViewElement__.d.ts +91 -86
  381. package/out/concepts/ViewElement__.js +218 -146
  382. package/out/concepts/ViewElement__.js.map +1 -1
  383. package/out/concepts/View__.d.ts +92 -92
  384. package/out/concepts/View__.js +135 -60
  385. package/out/concepts/View__.js.map +1 -1
  386. package/out/concepts/WhileStatement__.d.ts +12 -11
  387. package/out/concepts/WhileStatement__.js +46 -23
  388. package/out/concepts/WhileStatement__.js.map +1 -1
  389. package/out/concepts/index__.d.ts +2 -1
  390. package/out/concepts/index__.js +2 -1
  391. package/out/concepts/index__.js.map +1 -1
  392. package/out/concepts/types__.d.ts +2 -1
  393. package/out/decorators/index.d.ts +1 -1
  394. package/out/decorators/index.js +20 -7
  395. package/out/decorators/index.js.map +1 -1
  396. package/out/decorators/promise.d.ts +7 -0
  397. package/out/decorators/promise.js +28 -0
  398. package/out/decorators/promise.js.map +1 -0
  399. package/out/enums/KEYWORDS.js.map +1 -1
  400. package/out/enums/LEVEL_NAME_MAP.js.map +1 -1
  401. package/out/generator/compileComponent.js.map +1 -1
  402. package/out/generator/genBundleFiles.d.ts +4 -1
  403. package/out/generator/genBundleFiles.js +15 -11
  404. package/out/generator/genBundleFiles.js.map +1 -1
  405. package/out/generator/genHash.js.map +1 -1
  406. package/out/generator/genMetaData.js +12 -8
  407. package/out/generator/genMetaData.js.map +1 -1
  408. package/out/generator/genReleaseBody.js +33 -35
  409. package/out/generator/genReleaseBody.js.map +1 -1
  410. package/out/generator/microApp.js +2 -1
  411. package/out/generator/microApp.js.map +1 -1
  412. package/out/generator/permission.js +16 -14
  413. package/out/generator/permission.js.map +1 -1
  414. package/out/generator/styleReplacer.js +4 -7
  415. package/out/generator/styleReplacer.js.map +1 -1
  416. package/out/index.d.ts +0 -2
  417. package/out/index.js +0 -3
  418. package/out/index.js.map +1 -1
  419. package/out/manager/diagnostic.d.ts +1 -1
  420. package/out/manager/diagnostic.js.map +1 -1
  421. package/out/manager/stepRecorder.js +13 -9
  422. package/out/manager/stepRecorder.js.map +1 -1
  423. package/out/natural/RequirementAnalyzer.d.ts +22 -0
  424. package/out/natural/RequirementAnalyzer.js +196 -0
  425. package/out/natural/RequirementAnalyzer.js.map +1 -0
  426. package/out/natural/RequirementExecutor.d.ts +51 -0
  427. package/out/natural/RequirementExecutor.js +692 -0
  428. package/out/natural/RequirementExecutor.js.map +1 -0
  429. package/out/natural/componentData.d.ts +31 -0
  430. package/out/natural/componentData.js +85 -0
  431. package/out/natural/componentData.js.map +1 -0
  432. package/out/natural/genNaturalTS.d.ts +3 -0
  433. package/out/natural/genNaturalTS.js +76 -0
  434. package/out/natural/genNaturalTS.js.map +1 -0
  435. package/out/natural/index.d.ts +4 -0
  436. package/out/natural/index.js +21 -0
  437. package/out/natural/index.js.map +1 -0
  438. package/out/natural/knowledgeMap.d.ts +4 -0
  439. package/out/natural/knowledgeMap.js +40 -0
  440. package/out/natural/knowledgeMap.js.map +1 -0
  441. package/out/natural/naslStdlibMap.d.ts +2 -0
  442. package/out/natural/naslStdlibMap.js +26 -0
  443. package/out/natural/naslStdlibMap.js.map +1 -0
  444. package/out/natural/transformTSCode.d.ts +7 -0
  445. package/out/natural/transformTSCode.js +760 -0
  446. package/out/natural/transformTSCode.js.map +1 -0
  447. package/out/sentry/index.d.ts +2 -1
  448. package/out/sentry/index.js.map +1 -1
  449. package/out/server/createUiTs.js +28 -16
  450. package/out/server/createUiTs.js.map +1 -1
  451. package/out/server/entity2LogicNamespace.js +24 -22
  452. package/out/server/entity2LogicNamespace.js.map +1 -1
  453. package/out/server/event.js.map +1 -1
  454. package/out/server/extendBaseNode.js +55 -70
  455. package/out/server/extendBaseNode.js.map +1 -1
  456. package/out/server/formatTsUtils.js +46 -50
  457. package/out/server/formatTsUtils.js.map +1 -1
  458. package/out/server/getConnector.d.ts +3 -3
  459. package/out/server/getConnector.js +7 -8
  460. package/out/server/getConnector.js.map +1 -1
  461. package/out/server/getExtensionModules.js +2 -2
  462. package/out/server/getExtensionModules.js.map +1 -1
  463. package/out/server/getFunctions.js.map +1 -1
  464. package/out/server/getInterfaces.js.map +1 -1
  465. package/out/server/getLogging.js.map +1 -1
  466. package/out/server/getLogics.d.ts +1 -1
  467. package/out/server/getLogics.js +34 -16
  468. package/out/server/getLogics.js.map +1 -1
  469. package/out/server/getMemberIdentifier.js +13 -10
  470. package/out/server/getMemberIdentifier.js.map +1 -1
  471. package/out/server/getProcessComponents.js.map +1 -1
  472. package/out/server/getProcesses.js +21 -29
  473. package/out/server/getProcesses.js.map +1 -1
  474. package/out/server/getScope.js.map +1 -1
  475. package/out/server/getValidates.js.map +1 -1
  476. package/out/server/index.js +0 -1
  477. package/out/server/index.js.map +1 -1
  478. package/out/server/naslServer.d.ts +99 -94
  479. package/out/server/naslServer.js +485 -465
  480. package/out/server/naslServer.js.map +1 -1
  481. package/out/server/naslStdlibMap.js +4 -2
  482. package/out/server/naslStdlibMap.js.map +1 -1
  483. package/out/server/process2LogicNamespace.js.map +1 -1
  484. package/out/server/translator.d.ts +1 -1
  485. package/out/server/translator.js +52 -47
  486. package/out/server/translator.js.map +1 -1
  487. package/out/service/storage/init.d.ts +15 -1
  488. package/out/service/storage/init.js +65 -56
  489. package/out/service/storage/init.js.map +1 -1
  490. package/out/templator/genCallComponentLogic.js +1 -2
  491. package/out/templator/genCallComponentLogic.js.map +1 -1
  492. package/out/templator/genCreateBlock.js +13 -8
  493. package/out/templator/genCreateBlock.js.map +1 -1
  494. package/out/templator/genCurdEditMultipleKeyBlock.js +19 -10
  495. package/out/templator/genCurdEditMultipleKeyBlock.js.map +1 -1
  496. package/out/templator/genCurdMultipleKeyBlock.js +22 -26
  497. package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
  498. package/out/templator/genEditTableBlock.js +11 -12
  499. package/out/templator/genEditTableBlock.js.map +1 -1
  500. package/out/templator/genEnumSelectBlock.js +1 -1
  501. package/out/templator/genEnumSelectBlock.js.map +1 -1
  502. package/out/templator/genGetBlock.js +2 -2
  503. package/out/templator/genGetBlock.js.map +1 -1
  504. package/out/templator/genGridViewBlock.js +10 -14
  505. package/out/templator/genGridViewBlock.js.map +1 -1
  506. package/out/templator/genListViewBlock.js +4 -7
  507. package/out/templator/genListViewBlock.js.map +1 -1
  508. package/out/templator/genQueryComponent.js +22 -15
  509. package/out/templator/genQueryComponent.js.map +1 -1
  510. package/out/templator/genSelectBlock.js +12 -33
  511. package/out/templator/genSelectBlock.js.map +1 -1
  512. package/out/templator/genTableBlock.js +8 -10
  513. package/out/templator/genTableBlock.js.map +1 -1
  514. package/out/templator/genUpdateBlock.js +12 -7
  515. package/out/templator/genUpdateBlock.js.map +1 -1
  516. package/out/templator/index.d.ts +4 -2
  517. package/out/templator/index.js +2 -2
  518. package/out/templator/index.js.map +1 -1
  519. package/out/templator/utils.d.ts +2 -2
  520. package/out/templator/utils.js +21 -22
  521. package/out/templator/utils.js.map +1 -1
  522. package/out/translator/index.js +27 -28
  523. package/out/translator/index.js.map +1 -1
  524. package/out/utils/index.d.ts +2 -1
  525. package/out/utils/index.js +8 -14
  526. package/out/utils/index.js.map +1 -1
  527. package/out/utils/logger.js.map +1 -1
  528. package/out/utils/sortTsString.js +3 -1
  529. package/out/utils/sortTsString.js.map +1 -1
  530. package/out/utils/string.js +8 -11
  531. package/out/utils/string.js.map +1 -1
  532. package/out/utils/time-slicing.d.ts +41 -0
  533. package/out/utils/time-slicing.js +81 -0
  534. package/out/utils/time-slicing.js.map +1 -0
  535. package/out/utils/traverse.js +4 -6
  536. package/out/utils/traverse.js.map +1 -1
  537. package/package.json +11 -7
  538. package/sandbox/stdlib/nasl.auth.ts +49 -46
  539. package/sandbox/stdlib/nasl.http.ts +29 -31
  540. package/sandbox/stdlib/nasl.ui.definition.ts +13 -1
  541. package/sandbox-natural/stdlib/nasl.core.ts +36 -0
  542. package/sandbox-natural/stdlib/nasl.oql.ts +8 -0
  543. package/sandbox-natural/stdlib/nasl.ui.ts +56 -0
  544. package/sandbox-natural/stdlib/nasl.util.ts +26 -0
  545. package/sandbox-natural/tsconfig.json +12 -0
  546. package/src/automate/upgrader/2.20.js +1 -1
  547. package/src/bak/translator.js +92 -99
  548. package/src/breakpoint/generator/AfterStartNode.ts +19 -17
  549. package/src/breakpoint/generator/BeforeEndNode.ts +17 -17
  550. package/src/breakpoint/generator/BreakpointNode.ts +243 -195
  551. package/src/breakpoint/generator/CallbackNode.ts +20 -0
  552. package/src/breakpoint/generator/FragmentNode.ts +14 -0
  553. package/src/breakpoint/generator/index.ts +107 -80
  554. package/src/breakpoint/shared/constants.ts +59 -53
  555. package/src/breakpoint/shared/operations.ts +6 -6
  556. package/src/breakpoint/shared/socket.ts +277 -223
  557. package/src/breakpoint/shared/utils.ts +166 -146
  558. package/src/breakpoint/store/core.ts +326 -297
  559. package/src/breakpoint/store/dock.ts +103 -103
  560. package/src/breakpoint/types/index.d.ts +11 -11
  561. package/src/common/BaseNode.ts +1102 -1024
  562. package/src/common/Command.ts +46 -16
  563. package/src/common/ComponentAPI.ts +72 -72
  564. package/src/common/EventEmitter.ts +80 -76
  565. package/src/common/Messager.ts +223 -224
  566. package/src/common/asyncFuncMap.ts +12 -12
  567. package/src/concepts/Abort__.ts +53 -60
  568. package/src/concepts/Anchor__.ts +158 -149
  569. package/src/concepts/AnonymousFunction__.ts +584 -551
  570. package/src/concepts/App__.ts +4278 -3671
  571. package/src/concepts/Argument__.ts +234 -210
  572. package/src/concepts/Assignee__.ts +680 -656
  573. package/src/concepts/AssignmentLine__.ts +80 -84
  574. package/src/concepts/Assignment__.ts +275 -264
  575. package/src/concepts/Attribute__.ts +183 -184
  576. package/src/concepts/AuthInterface__.ts +61 -63
  577. package/src/concepts/AuthLogicForCallInterface__.ts +540 -511
  578. package/src/concepts/AuthLogic__.ts +210 -194
  579. package/src/concepts/BackendVariable__.ts +414 -415
  580. package/src/concepts/Backend__.ts +317 -303
  581. package/src/concepts/BatchAssignment__.ts +987 -939
  582. package/src/concepts/BinaryExpression__.ts +370 -341
  583. package/src/concepts/BindAttribute__.ts +1057 -1007
  584. package/src/concepts/BindDirective__.ts +540 -542
  585. package/src/concepts/BindEvent__.ts +992 -911
  586. package/src/concepts/BindStyle__.ts +442 -451
  587. package/src/concepts/BooleanLiteral__.ts +89 -90
  588. package/src/concepts/CallAuthInterface__.ts +458 -433
  589. package/src/concepts/CallConnector__.ts +209 -164
  590. package/src/concepts/CallFunction__.ts +600 -600
  591. package/src/concepts/CallInterface__.ts +752 -721
  592. package/src/concepts/CallLogic__.ts +1324 -1200
  593. package/src/concepts/CallQueryComponent__.ts +1580 -1501
  594. package/src/concepts/Comment__.ts +69 -68
  595. package/src/concepts/CompletionProperty__.ts +250 -255
  596. package/src/concepts/ConfigGroup__.ts +312 -296
  597. package/src/concepts/ConfigPropertyValue__.ts +92 -93
  598. package/src/concepts/ConfigProperty__.ts +374 -357
  599. package/src/concepts/Configuration__.ts +288 -276
  600. package/src/concepts/Connection__.ts +426 -0
  601. package/src/concepts/ConnectorTrigger__.ts +146 -142
  602. package/src/concepts/Connector__.ts +1090 -1048
  603. package/src/concepts/Constant__.ts +226 -219
  604. package/src/concepts/DataElement__.ts +108 -115
  605. package/src/concepts/DataSource__.ts +508 -472
  606. package/src/concepts/DatabaseTypeAnnotation__.ts +53 -59
  607. package/src/concepts/Destination__.ts +808 -746
  608. package/src/concepts/End__.ts +85 -89
  609. package/src/concepts/EntityIndex__.ts +206 -202
  610. package/src/concepts/EntityProperty__.ts +825 -791
  611. package/src/concepts/Entity__.ts +921 -864
  612. package/src/concepts/EnumItem__.ts +133 -125
  613. package/src/concepts/Enum__.ts +347 -337
  614. package/src/concepts/Event__.ts +305 -292
  615. package/src/concepts/ExternalDestination__.ts +269 -280
  616. package/src/concepts/ForEachStatement__.ts +583 -531
  617. package/src/concepts/FrontendLibrary__.ts +507 -485
  618. package/src/concepts/FrontendVariable__.ts +44 -49
  619. package/src/concepts/Frontend__.ts +1239 -1187
  620. package/src/concepts/Function__.ts +1110 -1045
  621. package/src/concepts/Identifier__.ts +276 -272
  622. package/src/concepts/IfStatement__.ts +467 -436
  623. package/src/concepts/Integration__.ts +136 -137
  624. package/src/concepts/InterfaceParam__.ts +239 -238
  625. package/src/concepts/Interface__.ts +969 -948
  626. package/src/concepts/JSBlock__.ts +83 -83
  627. package/src/concepts/JavaLogic__.ts +101 -106
  628. package/src/concepts/LogicItem__.ts +307 -237
  629. package/src/concepts/Logic__.ts +2301 -2088
  630. package/src/concepts/MatchCase__.ts +886 -779
  631. package/src/concepts/Match__.ts +728 -659
  632. package/src/concepts/MemberExpression__.ts +330 -311
  633. package/src/concepts/MicroApp__.ts +91 -97
  634. package/src/concepts/Module__.ts +2590 -2278
  635. package/src/concepts/MsgTriggerEvent__.ts +297 -281
  636. package/src/concepts/MsgTriggerLauncher__.ts +286 -256
  637. package/src/concepts/Namespace__.ts +2579 -2466
  638. package/src/concepts/NewComposite__.ts +1487 -1350
  639. package/src/concepts/NewList__.ts +464 -450
  640. package/src/concepts/NewMap__.ts +691 -674
  641. package/src/concepts/New__.ts +42 -49
  642. package/src/concepts/NullLiteral__.ts +66 -72
  643. package/src/concepts/NumericLiteral__.ts +169 -169
  644. package/src/concepts/OqlQueryComponent__.ts +282 -279
  645. package/src/concepts/OverriddenLogic__.ts +2142 -2097
  646. package/src/concepts/Param__.ts +500 -442
  647. package/src/concepts/Point__.ts +53 -59
  648. package/src/concepts/ProcessComponent__.ts +497 -475
  649. package/src/concepts/ProcessElement__.ts +1852 -1780
  650. package/src/concepts/ProcessOutcome__.ts +59 -64
  651. package/src/concepts/ProcessOutcomes__.ts +59 -64
  652. package/src/concepts/Process__.ts +1491 -1428
  653. package/src/concepts/QueryAggregateExpression__.ts +135 -142
  654. package/src/concepts/QueryFieldExpression__.ts +138 -142
  655. package/src/concepts/QueryFromExpression__.ts +246 -254
  656. package/src/concepts/QueryGroupByExpression__.ts +130 -136
  657. package/src/concepts/QueryJoinExpression__.ts +441 -438
  658. package/src/concepts/QueryLimitExpression__.ts +159 -166
  659. package/src/concepts/QueryOrderByExpression__.ts +173 -180
  660. package/src/concepts/QuerySelectExpression__.ts +464 -439
  661. package/src/concepts/Rect__.ts +73 -79
  662. package/src/concepts/Return__.ts +366 -345
  663. package/src/concepts/Role__.ts +146 -147
  664. package/src/concepts/SelectMembers__.ts +358 -350
  665. package/src/concepts/Slot__.ts +152 -153
  666. package/src/concepts/SqlQueryComponent__.ts +230 -228
  667. package/src/concepts/Start__.ts +45 -52
  668. package/src/concepts/StringInterpolation__.ts +323 -296
  669. package/src/concepts/StringLiteral__.ts +113 -115
  670. package/src/concepts/StructureProperty__.ts +306 -295
  671. package/src/concepts/Structure__.ts +615 -578
  672. package/src/concepts/SwitchCase__.ts +326 -290
  673. package/src/concepts/SwitchStatement__.ts +236 -229
  674. package/src/concepts/Theme__.ts +64 -68
  675. package/src/concepts/Transactional__.ts +159 -153
  676. package/src/concepts/TriggerEvent__.ts +285 -274
  677. package/src/concepts/TriggerLauncher__.ts +232 -196
  678. package/src/concepts/TypeAnnotation__.ts +1049 -1011
  679. package/src/concepts/TypeParam__.ts +48 -50
  680. package/src/concepts/UnaryExpression__.ts +163 -153
  681. package/src/concepts/Unparsed__.ts +81 -82
  682. package/src/concepts/UseComponent__.ts +53 -59
  683. package/src/concepts/ValidationRule__.ts +524 -544
  684. package/src/concepts/Variable__.ts +419 -397
  685. package/src/concepts/ViewBlock__.ts +58 -64
  686. package/src/concepts/ViewComponent__.ts +1323 -1261
  687. package/src/concepts/ViewElement__.ts +2538 -2350
  688. package/src/concepts/View__.ts +2447 -2268
  689. package/src/concepts/WhileStatement__.ts +293 -272
  690. package/src/concepts/index__.ts +2 -1
  691. package/src/concepts/types__.ts +123 -121
  692. package/src/decorators/index.ts +75 -77
  693. package/src/decorators/promise.ts +28 -0
  694. package/src/enums/KEYWORDS.ts +1228 -1228
  695. package/src/enums/LEVEL_NAME_MAP.ts +24 -24
  696. package/src/generator/compileComponent.ts +10 -10
  697. package/src/generator/genBundleFiles.ts +300 -291
  698. package/src/generator/genHash.ts +2 -2
  699. package/src/generator/genMetaData.ts +280 -261
  700. package/src/generator/genReleaseBody.ts +312 -291
  701. package/src/generator/icestark.ts +1 -1
  702. package/src/generator/microApp.ts +17 -20
  703. package/src/generator/permission.ts +227 -218
  704. package/src/generator/qiankun.ts +1 -1
  705. package/src/generator/styleReplacer.ts +28 -31
  706. package/src/index.ts +0 -3
  707. package/src/manager/diagnostic.ts +84 -82
  708. package/src/manager/stepRecorder.ts +106 -94
  709. package/src/natural/RequirementAnalyzer.ts +208 -0
  710. package/src/natural/RequirementExecutor.ts +685 -0
  711. package/src/natural/componentData.ts +81 -0
  712. package/src/natural/genNaturalTS.ts +77 -0
  713. package/src/natural/index.ts +4 -0
  714. package/src/natural/knowledgeMap.ts +39 -0
  715. package/src/natural/naslStdlibMap.ts +24 -0
  716. package/src/natural/transformTSCode.ts +692 -0
  717. package/src/sentry/index.ts +109 -104
  718. package/src/server/createUiTs.ts +190 -184
  719. package/src/server/entity2LogicNamespace.ts +379 -359
  720. package/src/server/event.js +145 -145
  721. package/src/server/extendBaseNode.ts +461 -456
  722. package/src/server/formatTsUtils.ts +712 -713
  723. package/src/server/getConnector.ts +33 -33
  724. package/src/server/getExtensionModules.ts +23 -22
  725. package/src/server/getFunctions.ts +6 -6
  726. package/src/server/getInterfaces.ts +38 -37
  727. package/src/server/getLogging.ts +1 -1
  728. package/src/server/getLogics.ts +390 -344
  729. package/src/server/getMemberIdentifier.ts +286 -281
  730. package/src/server/getProcessComponents.ts +2 -2
  731. package/src/server/getProcesses.ts +548 -534
  732. package/src/server/getScope.ts +51 -51
  733. package/src/server/getValidates.ts +3 -3
  734. package/src/server/index.ts +29 -30
  735. package/src/server/naslServer.ts +4302 -4225
  736. package/src/server/naslStdlibMap.ts +43 -41
  737. package/src/server/process2LogicNamespace.ts +97 -97
  738. package/src/server/translator.ts +740 -746
  739. package/src/service/storage/init.ts +761 -728
  740. package/src/templator/genCallComponentLogic.ts +14 -15
  741. package/src/templator/genCreateBlock.ts +257 -229
  742. package/src/templator/genCurdEditMultipleKeyBlock.ts +332 -316
  743. package/src/templator/genCurdMultipleKeyBlock.ts +501 -473
  744. package/src/templator/genEditTableBlock.ts +192 -182
  745. package/src/templator/genEnumSelectBlock.ts +13 -7
  746. package/src/templator/genGetBlock.ts +57 -55
  747. package/src/templator/genGridViewBlock.ts +191 -201
  748. package/src/templator/genListViewBlock.ts +59 -64
  749. package/src/templator/genQueryComponent.ts +337 -287
  750. package/src/templator/genSelectBlock.ts +276 -285
  751. package/src/templator/genTableBlock.ts +157 -160
  752. package/src/templator/genUpdateBlock.ts +269 -255
  753. package/src/templator/index.ts +4 -4
  754. package/src/templator/utils.ts +490 -464
  755. package/src/translator/index.ts +84 -84
  756. package/src/translator/lsp.ts +22 -22
  757. package/src/translator/tsp.ts +6 -6
  758. package/src/utils/index.ts +115 -117
  759. package/src/utils/logger.ts +3 -4
  760. package/src/utils/sortTsString.ts +34 -32
  761. package/src/utils/string.ts +47 -48
  762. package/src/utils/time-slicing.ts +109 -0
  763. package/src/utils/traverse.ts +114 -126
  764. package/test/concepts/match/__snapshots__/toEmbeddedTS.spec.ts.snap +66 -0
  765. package/test/concepts/match/__snapshots__/toJS.spec.ts.snap +40 -0
  766. package/test/concepts/match/constant.ts +5 -0
  767. package/test/concepts/match/fixtures/isExpression.json +259 -0
  768. package/test/concepts/match/fixtures/lastBodyIf.json +268 -0
  769. package/test/concepts/match/fixtures/noExpression.json +176 -0
  770. package/test/concepts/match/toEmbeddedTS.spec.ts +14 -0
  771. package/test/concepts/match/toJS.spec.ts +14 -0
  772. package/test/setup.ts +2 -1
  773. package/ts-worker/src/index.js +0 -2
  774. package/tsconfig.json +21 -21
@@ -1,2439 +1,2627 @@
1
- import { TranslatorState, shiftState, withSourceMap, indent } from '../translator';
2
- import { stdlibNamespace } from '../concepts';
3
-
4
1
  import * as babelParser from '@babel/parser';
5
2
  import * as json5 from 'json5';
6
3
  import * as compiler from 'vue-template-compiler';
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ import { TranslatorState, shiftState, withSourceMap, indent } from '../translator';
6
+ import { stdlibNamespace } from '../concepts';
7
7
 
8
- import LogicItem from './LogicItem__';
9
- import { traverse } from '../utils';
10
-
11
- import { config, Logic } from '..';
8
+ import { LogicItem } from './LogicItem__';
9
+ import { Logic } from './Logic__';
10
+ import { config } from '../config';
12
11
  import MemberExpression from './MemberExpression__';
13
12
  import Identifier from './Identifier__';
13
+ import { kebab2Camel } from '../utils';
14
+ //= ===============================================================================
15
+ // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
16
+ // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
17
+ //= ===============================================================================
18
+ import { EventPayload, Params } from '../common/EventEmitter';
19
+ import { concept, excludedInJSON, property } from '../decorators';
20
+
21
+ import * as utils from '../utils';
22
+ import BaseNode from '../common/BaseNode';
23
+ import classMap from '../common/classMap';
24
+ import BindAttribute from './BindAttribute__';
25
+ import BindEvent from './BindEvent__';
26
+ import BindDirective from './BindDirective__';
27
+ import BindStyle from './BindStyle__';
28
+ import View from './View__';
29
+ import Module from './Module__';
30
+ import App from './App__';
31
+ import Frontend from './Frontend__';
32
+
14
33
  export interface ParseContext {
15
- [key: string]: any;
34
+ [key: string]: any;
16
35
  }
17
36
 
18
37
  /**
19
38
  * 自闭合标签
20
39
  */
21
- const selfClosingTag = [
22
- 'base',
23
- 'meta',
24
- 'area',
25
- 'embed',
26
- 'link',
27
- 'img',
28
- 'input',
29
- 'param',
30
- 'hr',
31
- 'br',
32
- 'source',
33
- 'track',
34
- 'wbr',
35
- 'col',
36
- ];
40
+ const selfClosingTag = ['base', 'meta', 'area', 'embed', 'link', 'img', 'input', 'param', 'hr', 'br', 'source', 'track', 'wbr', 'col'];
37
41
 
38
42
  function genArgumentMemberExpression(arr: string[]) {
39
- let expressionNode: any;
40
- const propertyName = arr.pop();
41
- if (arr.length >= 1) {
42
- expressionNode = {
43
- concept: 'MemberExpression',
44
- name: '',
45
- kind: 'Expression',
46
- object: genArgumentMemberExpression(arr),
47
- property: {
48
- concept: 'Identifier',
49
- kind: 'Expression',
50
- name: propertyName,
51
- },
52
- };
53
- } else {
54
- return {
55
- concept: 'Identifier',
56
- kind: 'Expression',
57
- name: propertyName,
58
- };
59
- }
60
- return expressionNode;
43
+ let expressionNode: any;
44
+ const propertyName = arr.pop();
45
+ if (arr.length >= 1) {
46
+ expressionNode = {
47
+ concept: 'MemberExpression',
48
+ name: '',
49
+ kind: 'Expression',
50
+ object: genArgumentMemberExpression(arr),
51
+ property: {
52
+ concept: 'Identifier',
53
+ kind: 'Expression',
54
+ name: propertyName,
55
+ },
56
+ };
57
+ } else {
58
+ return {
59
+ concept: 'Identifier',
60
+ kind: 'Expression',
61
+ name: propertyName,
62
+ };
63
+ }
64
+ return expressionNode;
61
65
  }
62
66
  export interface ElementToVueOptions {
63
- indentStyle?: 'space' | 'tab';
64
- tabSize?: number;
65
- indentLevel?: number;
66
- aslIdAttr?: string | boolean;
67
- nodePathAttr?: string | boolean;
68
- getExtraParts?: (element?: ViewElement) => Array<string>;
69
- attrFormat?: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => string | false;
70
- bindStylesFormat?: (bindStyles: BindStyle[], element?: ViewElement, defaultResult?: string) => string | false;
71
- finalCode?: boolean;
72
- currentList?: string[];
67
+ indentStyle?: 'space' | 'tab';
68
+ tabSize?: number;
69
+ indentLevel?: number;
70
+ aslIdAttr?: string | boolean;
71
+ nodePathAttr?: string | boolean;
72
+ getExtraParts?: (element?: ViewElement) => Array<string>;
73
+ attrFormat?: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => string | false;
74
+ bindStylesFormat?: (bindStyles: BindStyle[], element?: ViewElement, defaultResult?: string) => string | false;
75
+ finalCode?: boolean;
76
+ currentList?: string[];
73
77
  }
74
78
 
75
79
  function transAstNodeToNaslNode(astNode: any, namespace?: string): any {
76
- let node = null;
77
- if (astNode.type === 'CallExpression' && astNode.callee.object.name === '$utils') {
78
- const calleeName = astNode.callee.property.name || astNode.callee.property.value;
79
- node = {
80
- concept: 'CallFunction',
81
- name: '',
82
- label: '调用内置函数',
83
- kind: 'Expression',
84
- calleeNamespace: 'nasl.util',
85
- calleeName,
86
- arguments: astNode.arguments.map((argument: any) => ({
87
- concept: 'Argument',
88
- name: '',
89
- kind: 'Statement',
90
- keyword: '',
91
- expression: transAstNodeToNaslNode(Object.assign({}, argument)),
92
- })).filter((item: any) => item.expression),
93
- typeArguments: astNode.arguments.map((argument: any) => (transAstNodeToNaslTypeNode(Object.assign({}, argument)))).filter((item: any) => item),
94
- };
95
- } else if (astNode.type === 'MemberExpression') {
96
- if (astNode.object?.name === '$global') {
97
- if (astNode.property?.name === 'userInfo') {
98
- // 目前只有权限相关的
99
- node = transAstNodeToNaslNode(astNode.property, 'nasl.auth');
100
- } else if (astNode.property?.name === 'frontendVariables') {
101
- node = 'app.frontendVariables';
102
- }
103
- } else if (astNode.object?.name === 'frontendVariables') {
104
- node = transAstNodeToNaslNode(astNode.property, 'app.frontendVariables');
105
- } else {
106
- const object = transAstNodeToNaslNode(astNode.object);
107
- // object如果返回字符串,则将它当成namespace处理
108
- if (Object.prototype.toString.call(object) === '[object String]') {
109
- node = transAstNodeToNaslNode(astNode.property, object);
110
- } else {
111
- const property = transAstNodeToNaslNode(astNode.property);
112
- node = {
113
- concept: 'MemberExpression',
114
- name: '',
115
- kind: 'Expression',
116
- object,
117
- property,
118
- };
119
- }
120
- }
121
- } else if (astNode.type === 'Identifier') {
122
- node = {
123
- concept: 'Identifier',
124
- namespace: namespace || '',
125
- name: astNode.name,
126
- kind: 'Expression',
127
- };
128
- } else if (astNode.type === 'ArrayExpression' || astNode.type === 'ObjectExpression') {
129
- node = {
130
- concept: 'Unparsed',
131
- label: '原子项',
132
- code: astNode.value,
133
- };
134
- } else if (astNode.type === 'StringLiteral') {
135
- // 单独特殊处理枚举因为他不是MemberExpression,而是Identifier_
136
- if (astNode?.value?.startsWith('__enumTypeAnnotation_')) {
137
- return null;
138
- } else {
139
- node = {
140
- concept: 'StringLiteral',
141
- kind: 'Expression',
142
- name: '',
143
- value: astNode.value,
144
- };
145
- }
146
- } else if (astNode.type === 'UnaryExpression') {
147
- const argument = astNode.argument;
148
- if (argument.type === 'NumericLiteral') {
149
- node = {
150
- concept: 'NumericLiteral',
151
- value: astNode.operator + argument.value,
152
- };
153
- } else {
154
- node = {
155
- concept: 'UnaryExpression',
156
- kind: 'Expression',
157
- name: '',
158
- operator: astNode.operator,
159
- argument: transAstNodeToNaslNode(astNode.argument),
160
- };
161
- }
162
- } else if (astNode.type === 'NumericLiteral') {
163
- const numberString = typeof astNode.value === 'number' ? astNode.value.toString() : astNode.value;
80
+ let node = null;
81
+ if (astNode.type === 'CallExpression' && astNode.callee.object.name === '$utils') {
82
+ const calleeName = astNode.callee.property.name || astNode.callee.property.value;
83
+ node = {
84
+ concept: 'CallFunction',
85
+ name: '',
86
+ label: '调用内置函数',
87
+ kind: 'Expression',
88
+ calleeNamespace: 'nasl.util',
89
+ calleeName,
90
+ arguments: astNode.arguments
91
+ .map((argument: any) => ({
92
+ concept: 'Argument',
93
+ name: '',
94
+ kind: 'Statement',
95
+ keyword: '',
96
+ expression: transAstNodeToNaslNode({ ...argument }),
97
+ }))
98
+ .filter((item: any) => item.expression),
99
+ typeArguments: astNode.arguments.map((argument: any) => transAstNodeToNaslTypeNode({ ...argument })).filter((item: any) => item),
100
+ };
101
+ } else if (astNode.type === 'MemberExpression') {
102
+ if (astNode.object?.name === '$global') {
103
+ if (astNode.property?.name === 'userInfo') {
104
+ // 目前只有权限相关的
105
+ node = transAstNodeToNaslNode(astNode.property, 'nasl.auth');
106
+ } else if (astNode.property?.name === 'frontendVariables') {
107
+ node = 'app.frontendVariables';
108
+ }
109
+ } else if (astNode.object?.name === 'frontendVariables') {
110
+ node = transAstNodeToNaslNode(astNode.property, 'app.frontendVariables');
111
+ } else {
112
+ const object = transAstNodeToNaslNode(astNode.object);
113
+ // object如果返回字符串,则将它当成namespace处理
114
+ if (Object.prototype.toString.call(object) === '[object String]') {
115
+ node = transAstNodeToNaslNode(astNode.property, object);
116
+ } else {
117
+ const property = transAstNodeToNaslNode(astNode.property);
164
118
  node = {
165
- concept: 'NumericLiteral',
166
- value: numberString,
119
+ concept: 'MemberExpression',
120
+ name: '',
121
+ kind: 'Expression',
122
+ object,
123
+ property,
167
124
  };
125
+ }
126
+ }
127
+ } else if (astNode.type === 'Identifier') {
128
+ node = {
129
+ concept: 'Identifier',
130
+ namespace: namespace || '',
131
+ name: astNode.name,
132
+ kind: 'Expression',
133
+ };
134
+ } else if (astNode.type === 'ArrayExpression' || astNode.type === 'ObjectExpression') {
135
+ node = {
136
+ concept: 'Unparsed',
137
+ label: '原子项',
138
+ code: astNode.value,
139
+ };
140
+ } else if (astNode.type === 'StringLiteral') {
141
+ // 单独特殊处理枚举因为他不是MemberExpression,而是Identifier_
142
+ if (astNode?.value?.startsWith('__enumTypeAnnotation_')) {
143
+ return null;
144
+ }
145
+ node = {
146
+ concept: 'StringLiteral',
147
+ kind: 'Expression',
148
+ name: '',
149
+ value: astNode.value,
150
+ };
151
+ } else if (astNode.type === 'UnaryExpression') {
152
+ const { argument } = astNode;
153
+ if (argument.type === 'NumericLiteral') {
154
+ node = {
155
+ concept: 'NumericLiteral',
156
+ value: astNode.operator + argument.value,
157
+ };
168
158
  } else {
169
- node = astNode;
170
- node.concept = astNode.type;
171
- }
172
- return node;
159
+ node = {
160
+ concept: 'UnaryExpression',
161
+ kind: 'Expression',
162
+ name: '',
163
+ operator: astNode.operator,
164
+ argument: transAstNodeToNaslNode(astNode.argument),
165
+ };
166
+ }
167
+ } else if (astNode.type === 'NumericLiteral') {
168
+ const numberString = typeof astNode.value === 'number' ? astNode.value.toString() : astNode.value;
169
+ node = {
170
+ concept: 'NumericLiteral',
171
+ value: numberString,
172
+ };
173
+ } else {
174
+ node = astNode;
175
+ node.concept = astNode.type;
176
+ }
177
+ return node;
173
178
  }
174
179
 
175
180
  function transAstNodeToNaslTypeNode(astNode: any, namespace?: string): any {
176
- let node = null;
177
- // 单独特殊处理枚举因为他不是MemberExpression,而是Identifier_
178
- if (astNode?.value?.startsWith('__enumTypeAnnotation_')) {
179
- const valueArr = astNode.value.replace('__enumTypeAnnotation_', '')?.split('.');
180
- const name = valueArr.pop();
181
- const namespace = valueArr.join('.');
182
- node = {
183
- concept: 'TypeAnnotation',
184
- typeNamespace: namespace || '',
185
- typeName: name || '',
186
- typeKind: 'reference',
187
- };
188
- }
189
- return node;
181
+ let node = null;
182
+ // 单独特殊处理枚举因为他不是MemberExpression,而是Identifier_
183
+ if (astNode?.value?.startsWith('__enumTypeAnnotation_')) {
184
+ const valueArr = astNode.value.replace('__enumTypeAnnotation_', '')?.split('.');
185
+ const name = valueArr.pop();
186
+ const namespace = valueArr.join('.');
187
+ node = {
188
+ concept: 'TypeAnnotation',
189
+ typeNamespace: namespace || '',
190
+ typeName: name || '',
191
+ typeKind: 'reference',
192
+ };
193
+ }
194
+ return node;
190
195
  }
191
- //================================================================================
192
- // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
193
- // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
194
- //================================================================================
195
- import { EventPayload, Params } from '../common/EventEmitter';
196
- import { concept, excludedInJSON, property } from '../decorators';
197
-
198
- import * as utils from '../utils';
199
- import { v4 as uuidv4 } from 'uuid';
200
- import BaseNode from '../common/BaseNode';
201
- import classMap from '../common/classMap';
202
- import BindAttribute from './BindAttribute__';
203
- import BindEvent from './BindEvent__';
204
- import BindDirective from './BindDirective__';
205
- import BindStyle from './BindStyle__';
206
- import View from './View__';
207
- import Module from './Module__';
208
- import App from './App__';
209
- import Frontend from './Frontend__';
210
196
 
211
197
  /**
212
198
  * 页面元素
213
199
  */
214
200
  @concept('页面元素')
215
201
  export class ViewElement extends BaseNode {
216
- /**
217
- * 产品概念
218
- */
219
- @property()
220
- concept: 'ViewElement' = 'ViewElement';
221
-
222
- /**
223
- * 类型
224
- */
225
- @property()
226
- type: 0 = undefined;
227
-
228
- /**
229
- * 元素标签
230
- */
231
- @property()
232
- tag: string = undefined;
233
-
234
- /**
235
- * 页面元素名称
236
- */
237
- @property()
238
- name: string = undefined;
239
-
240
- /**
241
- * 静态 class 名
242
- */
243
- @property()
244
- staticClass: string = undefined;
245
-
246
- /**
247
- * 静态 style
248
- */
249
- @property()
250
- staticStyle: string = undefined;
251
-
252
- /**
253
- * 权限资源描述
254
- */
255
- @property()
256
- authDescription: string = undefined;
257
-
258
- /**
259
- * 插槽目标
260
- */
261
- @property()
262
- slotTarget: string = undefined;
263
-
264
- /**
265
- * 插槽 scope 表达式
266
- */
267
- @property()
268
- slotScope: string = undefined;
269
-
270
- /**
271
- * 元素绑定属性列表
272
- */
273
- @property('BindAttribute')
274
- bindAttrs: Array<BindAttribute> = [];
275
-
276
- /**
277
- * 元素绑定事件列表
278
- */
279
- @property('BindEvent')
280
- bindEvents: Array<BindEvent> = [];
281
-
282
- /**
283
- * 元素指令列表
284
- */
285
- @property('BindDirective')
286
- bindDirectives: Array<BindDirective> = [];
287
-
288
- /**
289
- * 绑定的角色
290
- */
291
- @property()
292
- bindRoles: Array<string> = [];
293
-
294
- /**
295
- * 元素绑定样式列表
296
- */
297
- @property('BindStyle')
298
- bindStyles: Array<BindStyle> = [];
299
-
300
- /**
301
- * 子元素列表
302
- */
303
- @property('ViewElement')
304
- children: Array<ViewElement> = [];
305
-
306
- /**
307
- * 祖先 View
308
- */
309
- get view() {
310
- return this.getAncestor('View') as View;
311
- }
312
- /**
313
- * 祖先 Module
314
- */
315
- get module() {
316
- return this.getAncestor('Module') as Module;
317
- }
318
- /**
319
- * 祖先 App
320
- */
321
- get app() {
322
- return this.getAncestor('App') as App;
323
- }
324
- /**
325
- * 祖先 Frontend
326
- */
327
- get frontend() {
328
- return this.getAncestor('Frontend') as Frontend;
329
- }
330
-
331
- /**
332
- * @param source 需要合并的部分参数
333
- */
334
- constructor(source?: Partial<ViewElement>) {
335
- source = Object.assign({}, ViewElement.getDefaultOptions(), source);
336
- super(source);
337
- super.subConstructor(source);
338
- }
339
- getClassName() {
340
- return 'ViewElement';
341
- }
342
-
343
- /**
344
- * 从父级删除该节点
345
- * @internal
346
- */
347
- _delete() {
348
- let params: Params = null;
349
- if (this.parentNode) {
350
- params = (this.parentNode as any)?.__removeViewElement?.(this);
351
- }
352
- return params;
353
- }
354
- /**
355
- * 设置页面元素名称
356
- */
357
- setName(name: string) {
358
- const object = {
359
- name,
360
- };
361
- this.update({
362
- ...object,
363
- field: 'name',
364
- });
365
- }
366
-
367
- /**
368
- * 设置静态 style
369
- */
370
- setStaticStyle(staticStyle: string) {
371
- const object = {
372
- staticStyle,
373
- };
374
- this.update({
375
- ...object,
376
- });
377
- }
378
-
379
- /**
380
- * 设置权限资源描述
381
- */
382
- setAuthDescription(authDescription: string) {
383
- const object = {
384
- authDescription,
385
- };
386
- this.update({
387
- ...object,
388
- });
389
- }
390
-
391
- getBindAttributeExistingNames(excludedList: Array<BindAttribute> = []) {
392
- const excludedSet = new Set(excludedList);
393
- return ((this.bindAttrs as BindAttribute[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
394
- }
395
- getBindAttributeUniqueName(name = 'bindAttribute1') {
396
- return utils.unique(name, this.getBindAttributeExistingNames(), undefined, false);
202
+ /**
203
+ * 产品概念
204
+ */
205
+ @property()
206
+ concept: 'ViewElement' = 'ViewElement';
207
+
208
+ /**
209
+ * 类型
210
+ */
211
+ @property()
212
+ type: 0 = undefined;
213
+
214
+ /**
215
+ * 元素标签
216
+ */
217
+ @property()
218
+ tag: string = undefined;
219
+
220
+ /**
221
+ * 页面元素名称
222
+ */
223
+ @property()
224
+ name: string = undefined;
225
+
226
+ /**
227
+ * 静态 class 名
228
+ */
229
+ @property()
230
+ staticClass: string = undefined;
231
+
232
+ /**
233
+ * 静态 style
234
+ */
235
+ @property()
236
+ staticStyle: string = undefined;
237
+
238
+ /**
239
+ * 权限资源描述
240
+ */
241
+ @property()
242
+ authDescription: string = undefined;
243
+
244
+ /**
245
+ * 插槽目标
246
+ */
247
+ @property()
248
+ slotTarget: string = undefined;
249
+
250
+ /**
251
+ * 插槽 scope 表达式
252
+ */
253
+ @property()
254
+ slotScope: string = undefined;
255
+
256
+ /**
257
+ * 元素绑定属性列表
258
+ */
259
+ @property('BindAttribute')
260
+ bindAttrs: Array<BindAttribute> = [];
261
+
262
+ /**
263
+ * 元素绑定事件列表
264
+ */
265
+ @property('BindEvent')
266
+ bindEvents: Array<BindEvent> = [];
267
+
268
+ /**
269
+ * 元素指令列表
270
+ */
271
+ @property('BindDirective')
272
+ bindDirectives: Array<BindDirective> = [];
273
+
274
+ /**
275
+ * 绑定的角色
276
+ */
277
+ @property()
278
+ bindRoles: Array<string> = [];
279
+
280
+ /**
281
+ * 元素绑定样式列表
282
+ */
283
+ @property('BindStyle')
284
+ bindStyles: Array<BindStyle> = [];
285
+
286
+ /**
287
+ * 子元素列表
288
+ */
289
+ @property('ViewElement')
290
+ children: Array<ViewElement> = [];
291
+
292
+ /**
293
+ * 祖先 View
294
+ */
295
+ get view() {
296
+ return this.getAncestor('View') as View;
297
+ }
298
+
299
+ /**
300
+ * 祖先 Module
301
+ */
302
+ get module() {
303
+ return this.getAncestor('Module') as Module;
304
+ }
305
+
306
+ /**
307
+ * 祖先 App
308
+ */
309
+ get app() {
310
+ return this.getAncestor('App') as App;
311
+ }
312
+
313
+ /**
314
+ * 祖先 Frontend
315
+ */
316
+ get frontend() {
317
+ return this.getAncestor('Frontend') as Frontend;
318
+ }
319
+
320
+ /**
321
+ * @param source 需要合并的部分参数
322
+ */
323
+ constructor(source?: Partial<ViewElement>) {
324
+ // @ts-ignore
325
+ source = { ...ViewElement.getDefaultOptions(), ...source };
326
+ super(source);
327
+ super.subConstructor(source);
328
+ }
329
+
330
+ getClassName() {
331
+ return 'ViewElement';
332
+ }
333
+
334
+ /**
335
+ * 从父级删除该节点
336
+ * @internal
337
+ */
338
+ _delete() {
339
+ let params: Params = null;
340
+ if (this.parentNode) {
341
+ params = (this.parentNode as any)?.__removeViewElement?.(this);
342
+ }
343
+ return params;
344
+ }
345
+
346
+ /**
347
+ * 设置页面元素名称
348
+ */
349
+ setName(name: string) {
350
+ const object = {
351
+ name,
352
+ };
353
+ this.update({
354
+ ...object,
355
+ field: 'name',
356
+ });
357
+ }
358
+
359
+ /**
360
+ * 设置静态 style
361
+ */
362
+ setStaticStyle(staticStyle: string) {
363
+ const object = {
364
+ staticStyle,
365
+ };
366
+ this.update({
367
+ ...object,
368
+ });
369
+ }
370
+
371
+ /**
372
+ * 设置权限资源描述
373
+ */
374
+ setAuthDescription(authDescription: string) {
375
+ const object = {
376
+ authDescription,
377
+ };
378
+ this.update({
379
+ ...object,
380
+ });
381
+ }
382
+
383
+ getBindAttributeExistingNames(excludedList: Array<BindAttribute> = []) {
384
+ const excludedSet = new Set(excludedList);
385
+ return ((this.bindAttrs as BindAttribute[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
386
+ }
387
+
388
+ getBindAttributeUniqueName(name = 'bindAttribute1') {
389
+ return utils.unique(name, this.getBindAttributeExistingNames(), undefined, false);
390
+ }
391
+
392
+ /**
393
+ * 插入元素绑定属性
394
+ * @internal
395
+ * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
396
+ */
397
+ _insertBindAttributeAt(name: string, index: number): BindAttribute;
398
+
399
+ /**
400
+ * 插入元素绑定属性
401
+ * @internal
402
+ * @param bindAttributeOptions 元素绑定属性参数
403
+ */
404
+ _insertBindAttributeAt(bindAttributeOptions: Partial<BindAttribute>, index: number): BindAttribute;
405
+
406
+ /**
407
+ * 插入元素绑定属性
408
+ * @internal
409
+ * @param bindAttribute 已有的元素绑定属性实例
410
+ */
411
+ _insertBindAttributeAt(bindAttribute: BindAttribute, index: number): BindAttribute;
412
+
413
+ _insertBindAttributeAt(options: string | Partial<BindAttribute> | BindAttribute, index: number) {
414
+ const bindAttributeOptions: any = {};
415
+ const relationOptions = { parentNode: this, parentKey: 'bindAttrs' };
416
+ let bindAttribute: BindAttribute;
417
+ if (!options) {
418
+ bindAttribute = BindAttribute.from(
419
+ {
420
+ ...bindAttributeOptions,
421
+ name: this.getBindAttributeUniqueName(),
422
+ },
423
+ this,
424
+ 'bindAttrs'
425
+ );
426
+ } else if (typeof options === 'string') {
427
+ bindAttribute = BindAttribute.from(
428
+ {
429
+ ...bindAttributeOptions,
430
+ name: options,
431
+ },
432
+ this,
433
+ 'bindAttrs'
434
+ );
435
+ } else if (options instanceof BindAttribute) {
436
+ options.ensureDelete(); // 同一实例不支持多处存在
437
+ bindAttribute = options;
438
+ Object.assign(bindAttribute, relationOptions);
439
+ } else {
440
+ bindAttribute = BindAttribute.from(
441
+ {
442
+ ...bindAttributeOptions,
443
+ ...options,
444
+ },
445
+ this,
446
+ 'bindAttrs'
447
+ );
448
+ }
449
+ this.bindAttrs.splice(index, 0, bindAttribute);
450
+ return bindAttribute;
451
+ }
452
+
453
+ /**
454
+ * 插入元素绑定属性
455
+ * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
456
+ */
457
+ insertBindAttributeAt(name: string, index: number): BindAttribute;
458
+
459
+ /**
460
+ * 插入元素绑定属性
461
+ * @param bindAttributeOptions 元素绑定属性参数
462
+ */
463
+ insertBindAttributeAt(bindAttributeOptions: Partial<BindAttribute>, index: number): BindAttribute;
464
+
465
+ /**
466
+ * 插入元素绑定属性
467
+ * @param bindAttribute 已有的元素绑定属性实例
468
+ */
469
+ insertBindAttributeAt(bindAttribute: BindAttribute, index: number): BindAttribute;
470
+
471
+ insertBindAttributeAt(options: string | Partial<BindAttribute> | BindAttribute, index: number) {
472
+ const node = this._insertBindAttributeAt(options as any, index);
473
+ node.create({
474
+ index,
475
+ parentNode: this,
476
+ parentKey: 'bindAttrs',
477
+ });
478
+ return node;
479
+ }
480
+
481
+ /**
482
+ * 添加元素绑定属性
483
+ * @internal
484
+ * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
485
+ */
486
+ _addBindAttribute(name?: string): BindAttribute;
487
+
488
+ /**
489
+ * 添加元素绑定属性
490
+ * @internal
491
+ * @param bindAttributeOptions 元素绑定属性参数
492
+ */
493
+ _addBindAttribute(bindAttributeOptions: Partial<BindAttribute>): BindAttribute;
494
+
495
+ /**
496
+ * 添加元素绑定属性
497
+ * @internal
498
+ * @param bindAttribute 已有的元素绑定属性实例
499
+ */
500
+ _addBindAttribute(bindAttribute: BindAttribute): BindAttribute;
501
+
502
+ _addBindAttribute(options?: string | Partial<BindAttribute> | BindAttribute) {
503
+ const index = this.bindAttrs.length;
504
+ return this._insertBindAttributeAt(options as any, index);
505
+ }
506
+
507
+ /**
508
+ * 添加元素绑定属性
509
+ * @internal
510
+ * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
511
+ */
512
+ addBindAttribute(name?: string): BindAttribute;
513
+
514
+ /**
515
+ * 添加元素绑定属性
516
+ * @param bindAttributeOptions 元素绑定属性参数
517
+ */
518
+ addBindAttribute(bindAttributeOptions: Partial<BindAttribute>): BindAttribute;
519
+
520
+ /**
521
+ * 添加元素绑定属性
522
+ * @param bindAttribute 已有的元素绑定属性实例
523
+ */
524
+ addBindAttribute(bindAttribute: BindAttribute): BindAttribute;
525
+
526
+ addBindAttribute(options?: string | Partial<BindAttribute> | BindAttribute) {
527
+ const node = this._addBindAttribute(options as any);
528
+ const index = this.bindAttrs.indexOf(node);
529
+ node.create({
530
+ index,
531
+ parentNode: this,
532
+ parentKey: 'bindAttrs',
533
+ });
534
+ return node;
535
+ }
536
+
537
+ getBindEventExistingNames(excludedList: Array<BindEvent> = []) {
538
+ const excludedSet = new Set(excludedList);
539
+ return ((this.bindEvents as BindEvent[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
540
+ }
541
+
542
+ getBindEventUniqueName(name = 'bindEvent1') {
543
+ return utils.unique(name, this.getBindEventExistingNames(), undefined, false);
544
+ }
545
+
546
+ /**
547
+ * 插入元素绑定事件
548
+ * @internal
549
+ * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
550
+ */
551
+ _insertBindEventAt(name: string, index: number): BindEvent;
552
+
553
+ /**
554
+ * 插入元素绑定事件
555
+ * @internal
556
+ * @param bindEventOptions 元素绑定事件参数
557
+ */
558
+ _insertBindEventAt(bindEventOptions: Partial<BindEvent>, index: number): BindEvent;
559
+
560
+ /**
561
+ * 插入元素绑定事件
562
+ * @internal
563
+ * @param bindEvent 已有的元素绑定事件实例
564
+ */
565
+ _insertBindEventAt(bindEvent: BindEvent, index: number): BindEvent;
566
+
567
+ _insertBindEventAt(options: string | Partial<BindEvent> | BindEvent, index: number) {
568
+ const bindEventOptions: any = {};
569
+ const relationOptions = { parentNode: this, parentKey: 'bindEvents' };
570
+ let bindEvent: BindEvent;
571
+ if (!options) {
572
+ bindEvent = BindEvent.from(
573
+ {
574
+ ...bindEventOptions,
575
+ name: this.getBindEventUniqueName(),
576
+ },
577
+ this,
578
+ 'bindEvents'
579
+ );
580
+ } else if (typeof options === 'string') {
581
+ bindEvent = BindEvent.from(
582
+ {
583
+ ...bindEventOptions,
584
+ name: options,
585
+ },
586
+ this,
587
+ 'bindEvents'
588
+ );
589
+ } else if (options instanceof BindEvent) {
590
+ options.ensureDelete(); // 同一实例不支持多处存在
591
+ bindEvent = options;
592
+ Object.assign(bindEvent, relationOptions);
593
+ } else {
594
+ bindEvent = BindEvent.from(
595
+ {
596
+ ...bindEventOptions,
597
+ ...options,
598
+ },
599
+ this,
600
+ 'bindEvents'
601
+ );
602
+ }
603
+ this.bindEvents.splice(index, 0, bindEvent);
604
+ return bindEvent;
605
+ }
606
+
607
+ /**
608
+ * 插入元素绑定事件
609
+ * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
610
+ */
611
+ insertBindEventAt(name: string, index: number): BindEvent;
612
+
613
+ /**
614
+ * 插入元素绑定事件
615
+ * @param bindEventOptions 元素绑定事件参数
616
+ */
617
+ insertBindEventAt(bindEventOptions: Partial<BindEvent>, index: number): BindEvent;
618
+
619
+ /**
620
+ * 插入元素绑定事件
621
+ * @param bindEvent 已有的元素绑定事件实例
622
+ */
623
+ insertBindEventAt(bindEvent: BindEvent, index: number): BindEvent;
624
+
625
+ insertBindEventAt(options: string | Partial<BindEvent> | BindEvent, index: number) {
626
+ const node = this._insertBindEventAt(options as any, index);
627
+ node.create({
628
+ index,
629
+ parentNode: this,
630
+ parentKey: 'bindEvents',
631
+ });
632
+ return node;
633
+ }
634
+
635
+ /**
636
+ * 添加元素绑定事件
637
+ * @internal
638
+ * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
639
+ */
640
+ _addBindEvent(name?: string): BindEvent;
641
+
642
+ /**
643
+ * 添加元素绑定事件
644
+ * @internal
645
+ * @param bindEventOptions 元素绑定事件参数
646
+ */
647
+ _addBindEvent(bindEventOptions: Partial<BindEvent>): BindEvent;
648
+
649
+ /**
650
+ * 添加元素绑定事件
651
+ * @internal
652
+ * @param bindEvent 已有的元素绑定事件实例
653
+ */
654
+ _addBindEvent(bindEvent: BindEvent): BindEvent;
655
+
656
+ _addBindEvent(options?: string | Partial<BindEvent> | BindEvent) {
657
+ const index = this.bindEvents.length;
658
+ return this._insertBindEventAt(options as any, index);
659
+ }
660
+
661
+ /**
662
+ * 添加元素绑定事件
663
+ * @internal
664
+ * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
665
+ */
666
+ addBindEvent(name?: string): BindEvent;
667
+
668
+ /**
669
+ * 添加元素绑定事件
670
+ * @param bindEventOptions 元素绑定事件参数
671
+ */
672
+ addBindEvent(bindEventOptions: Partial<BindEvent>): BindEvent;
673
+
674
+ /**
675
+ * 添加元素绑定事件
676
+ * @param bindEvent 已有的元素绑定事件实例
677
+ */
678
+ addBindEvent(bindEvent: BindEvent): BindEvent;
679
+
680
+ addBindEvent(options?: string | Partial<BindEvent> | BindEvent) {
681
+ const node = this._addBindEvent(options as any);
682
+ const index = this.bindEvents.indexOf(node);
683
+ node.create({
684
+ index,
685
+ parentNode: this,
686
+ parentKey: 'bindEvents',
687
+ });
688
+ return node;
689
+ }
690
+
691
+ getBindDirectiveExistingNames(excludedList: Array<BindDirective> = []) {
692
+ const excludedSet = new Set(excludedList);
693
+ return ((this.bindDirectives as BindDirective[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
694
+ }
695
+
696
+ getBindDirectiveUniqueName(name = 'bindDirective1') {
697
+ return utils.unique(name, this.getBindDirectiveExistingNames(), undefined, false);
698
+ }
699
+
700
+ /**
701
+ * 插入元素指令
702
+ * @internal
703
+ * @param name 元素指令名称,如果不填会自动生成一个唯一名称
704
+ */
705
+ _insertBindDirectiveAt(name: string, index: number): BindDirective;
706
+
707
+ /**
708
+ * 插入元素指令
709
+ * @internal
710
+ * @param bindDirectiveOptions 元素指令参数
711
+ */
712
+ _insertBindDirectiveAt(bindDirectiveOptions: Partial<BindDirective>, index: number): BindDirective;
713
+
714
+ /**
715
+ * 插入元素指令
716
+ * @internal
717
+ * @param bindDirective 已有的元素指令实例
718
+ */
719
+ _insertBindDirectiveAt(bindDirective: BindDirective, index: number): BindDirective;
720
+
721
+ _insertBindDirectiveAt(options: string | Partial<BindDirective> | BindDirective, index: number) {
722
+ const bindDirectiveOptions: any = {};
723
+ const relationOptions = { parentNode: this, parentKey: 'bindDirectives' };
724
+ let bindDirective: BindDirective;
725
+ if (!options) {
726
+ bindDirective = BindDirective.from(
727
+ {
728
+ ...bindDirectiveOptions,
729
+ name: this.getBindDirectiveUniqueName(),
730
+ },
731
+ this,
732
+ 'bindDirectives'
733
+ );
734
+ } else if (typeof options === 'string') {
735
+ bindDirective = BindDirective.from(
736
+ {
737
+ ...bindDirectiveOptions,
738
+ name: options,
739
+ },
740
+ this,
741
+ 'bindDirectives'
742
+ );
743
+ } else if (options instanceof BindDirective) {
744
+ options.ensureDelete(); // 同一实例不支持多处存在
745
+ bindDirective = options;
746
+ Object.assign(bindDirective, relationOptions);
747
+ } else {
748
+ bindDirective = BindDirective.from(
749
+ {
750
+ ...bindDirectiveOptions,
751
+ ...options,
752
+ },
753
+ this,
754
+ 'bindDirectives'
755
+ );
756
+ }
757
+ this.bindDirectives.splice(index, 0, bindDirective);
758
+ return bindDirective;
759
+ }
760
+
761
+ /**
762
+ * 插入元素指令
763
+ * @param name 元素指令名称,如果不填会自动生成一个唯一名称
764
+ */
765
+ insertBindDirectiveAt(name: string, index: number): BindDirective;
766
+
767
+ /**
768
+ * 插入元素指令
769
+ * @param bindDirectiveOptions 元素指令参数
770
+ */
771
+ insertBindDirectiveAt(bindDirectiveOptions: Partial<BindDirective>, index: number): BindDirective;
772
+
773
+ /**
774
+ * 插入元素指令
775
+ * @param bindDirective 已有的元素指令实例
776
+ */
777
+ insertBindDirectiveAt(bindDirective: BindDirective, index: number): BindDirective;
778
+
779
+ insertBindDirectiveAt(options: string | Partial<BindDirective> | BindDirective, index: number) {
780
+ const node = this._insertBindDirectiveAt(options as any, index);
781
+ node.create({
782
+ index,
783
+ parentNode: this,
784
+ parentKey: 'bindDirectives',
785
+ });
786
+ return node;
787
+ }
788
+
789
+ /**
790
+ * 添加元素指令
791
+ * @internal
792
+ * @param name 元素指令名称,如果不填会自动生成一个唯一名称
793
+ */
794
+ _addBindDirective(name?: string): BindDirective;
795
+
796
+ /**
797
+ * 添加元素指令
798
+ * @internal
799
+ * @param bindDirectiveOptions 元素指令参数
800
+ */
801
+ _addBindDirective(bindDirectiveOptions: Partial<BindDirective>): BindDirective;
802
+
803
+ /**
804
+ * 添加元素指令
805
+ * @internal
806
+ * @param bindDirective 已有的元素指令实例
807
+ */
808
+ _addBindDirective(bindDirective: BindDirective): BindDirective;
809
+
810
+ _addBindDirective(options?: string | Partial<BindDirective> | BindDirective) {
811
+ const index = this.bindDirectives.length;
812
+ return this._insertBindDirectiveAt(options as any, index);
813
+ }
814
+
815
+ /**
816
+ * 添加元素指令
817
+ * @internal
818
+ * @param name 元素指令名称,如果不填会自动生成一个唯一名称
819
+ */
820
+ addBindDirective(name?: string): BindDirective;
821
+
822
+ /**
823
+ * 添加元素指令
824
+ * @param bindDirectiveOptions 元素指令参数
825
+ */
826
+ addBindDirective(bindDirectiveOptions: Partial<BindDirective>): BindDirective;
827
+
828
+ /**
829
+ * 添加元素指令
830
+ * @param bindDirective 已有的元素指令实例
831
+ */
832
+ addBindDirective(bindDirective: BindDirective): BindDirective;
833
+
834
+ addBindDirective(options?: string | Partial<BindDirective> | BindDirective) {
835
+ const node = this._addBindDirective(options as any);
836
+ const index = this.bindDirectives.indexOf(node);
837
+ node.create({
838
+ index,
839
+ parentNode: this,
840
+ parentKey: 'bindDirectives',
841
+ });
842
+ return node;
843
+ }
844
+
845
+ getBindStyleExistingNames(excludedList: Array<BindStyle> = []) {
846
+ const excludedSet = new Set(excludedList);
847
+ return ((this.bindStyles as BindStyle[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
848
+ }
849
+
850
+ getBindStyleUniqueName(name = 'bindStyle1') {
851
+ return utils.unique(name, this.getBindStyleExistingNames(), undefined, false);
852
+ }
853
+
854
+ /**
855
+ * 插入元素绑定样式
856
+ * @internal
857
+ * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
858
+ */
859
+ _insertBindStyleAt(name: string, index: number): BindStyle;
860
+
861
+ /**
862
+ * 插入元素绑定样式
863
+ * @internal
864
+ * @param bindStyleOptions 元素绑定样式参数
865
+ */
866
+ _insertBindStyleAt(bindStyleOptions: Partial<BindStyle>, index: number): BindStyle;
867
+
868
+ /**
869
+ * 插入元素绑定样式
870
+ * @internal
871
+ * @param bindStyle 已有的元素绑定样式实例
872
+ */
873
+ _insertBindStyleAt(bindStyle: BindStyle, index: number): BindStyle;
874
+
875
+ _insertBindStyleAt(options: string | Partial<BindStyle> | BindStyle, index: number) {
876
+ const bindStyleOptions: any = {};
877
+ const relationOptions = { parentNode: this, parentKey: 'bindStyles' };
878
+ let bindStyle: BindStyle;
879
+ if (!options) {
880
+ bindStyle = BindStyle.from(
881
+ {
882
+ ...bindStyleOptions,
883
+ name: this.getBindStyleUniqueName(),
884
+ },
885
+ this,
886
+ 'bindStyles'
887
+ );
888
+ } else if (typeof options === 'string') {
889
+ bindStyle = BindStyle.from(
890
+ {
891
+ ...bindStyleOptions,
892
+ name: options,
893
+ },
894
+ this,
895
+ 'bindStyles'
896
+ );
897
+ } else if (options instanceof BindStyle) {
898
+ options.ensureDelete(); // 同一实例不支持多处存在
899
+ bindStyle = options;
900
+ Object.assign(bindStyle, relationOptions);
901
+ } else {
902
+ bindStyle = BindStyle.from(
903
+ {
904
+ ...bindStyleOptions,
905
+ ...options,
906
+ },
907
+ this,
908
+ 'bindStyles'
909
+ );
910
+ }
911
+ this.bindStyles.splice(index, 0, bindStyle);
912
+ return bindStyle;
913
+ }
914
+
915
+ /**
916
+ * 插入元素绑定样式
917
+ * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
918
+ */
919
+ insertBindStyleAt(name: string, index: number): BindStyle;
920
+
921
+ /**
922
+ * 插入元素绑定样式
923
+ * @param bindStyleOptions 元素绑定样式参数
924
+ */
925
+ insertBindStyleAt(bindStyleOptions: Partial<BindStyle>, index: number): BindStyle;
926
+
927
+ /**
928
+ * 插入元素绑定样式
929
+ * @param bindStyle 已有的元素绑定样式实例
930
+ */
931
+ insertBindStyleAt(bindStyle: BindStyle, index: number): BindStyle;
932
+
933
+ insertBindStyleAt(options: string | Partial<BindStyle> | BindStyle, index: number) {
934
+ const node = this._insertBindStyleAt(options as any, index);
935
+ node.create({
936
+ index,
937
+ parentNode: this,
938
+ parentKey: 'bindStyles',
939
+ });
940
+ return node;
941
+ }
942
+
943
+ /**
944
+ * 添加元素绑定样式
945
+ * @internal
946
+ * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
947
+ */
948
+ _addBindStyle(name?: string): BindStyle;
949
+
950
+ /**
951
+ * 添加元素绑定样式
952
+ * @internal
953
+ * @param bindStyleOptions 元素绑定样式参数
954
+ */
955
+ _addBindStyle(bindStyleOptions: Partial<BindStyle>): BindStyle;
956
+
957
+ /**
958
+ * 添加元素绑定样式
959
+ * @internal
960
+ * @param bindStyle 已有的元素绑定样式实例
961
+ */
962
+ _addBindStyle(bindStyle: BindStyle): BindStyle;
963
+
964
+ _addBindStyle(options?: string | Partial<BindStyle> | BindStyle) {
965
+ const index = this.bindStyles.length;
966
+ return this._insertBindStyleAt(options as any, index);
967
+ }
968
+
969
+ /**
970
+ * 添加元素绑定样式
971
+ * @internal
972
+ * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
973
+ */
974
+ addBindStyle(name?: string): BindStyle;
975
+
976
+ /**
977
+ * 添加元素绑定样式
978
+ * @param bindStyleOptions 元素绑定样式参数
979
+ */
980
+ addBindStyle(bindStyleOptions: Partial<BindStyle>): BindStyle;
981
+
982
+ /**
983
+ * 添加元素绑定样式
984
+ * @param bindStyle 已有的元素绑定样式实例
985
+ */
986
+ addBindStyle(bindStyle: BindStyle): BindStyle;
987
+
988
+ addBindStyle(options?: string | Partial<BindStyle> | BindStyle) {
989
+ const node = this._addBindStyle(options as any);
990
+ const index = this.bindStyles.indexOf(node);
991
+ node.create({
992
+ index,
993
+ parentNode: this,
994
+ parentKey: 'bindStyles',
995
+ });
996
+ return node;
997
+ }
998
+
999
+ /**
1000
+ * 插入页面元素
1001
+ * @internal
1002
+ * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1003
+ */
1004
+ _insertViewElementAt(name: string, index: number): ViewElement;
1005
+
1006
+ /**
1007
+ * 插入页面元素
1008
+ * @internal
1009
+ * @param viewElementOptions 页面元素参数
1010
+ */
1011
+ _insertViewElementAt(viewElementOptions: Partial<ViewElement>, index: number): ViewElement;
1012
+
1013
+ /**
1014
+ * 插入页面元素
1015
+ * @internal
1016
+ * @param viewElement 已有的页面元素实例
1017
+ */
1018
+ _insertViewElementAt(viewElement: ViewElement, index: number): ViewElement;
1019
+
1020
+ _insertViewElementAt(options: string | Partial<ViewElement> | ViewElement, index: number) {
1021
+ const viewElementOptions: any = {};
1022
+ const relationOptions = { parentNode: this, parentKey: 'children' };
1023
+ let viewElement: ViewElement;
1024
+ if (!options) {
1025
+ viewElement = ViewElement.from(
1026
+ {
1027
+ ...viewElementOptions,
1028
+ name: this.getViewElementUniqueName(),
1029
+ },
1030
+ this,
1031
+ 'children'
1032
+ );
1033
+ } else if (typeof options === 'string') {
1034
+ viewElement = ViewElement.from(
1035
+ {
1036
+ ...viewElementOptions,
1037
+ name: options,
1038
+ },
1039
+ this,
1040
+ 'children'
1041
+ );
1042
+ } else if (options instanceof ViewElement) {
1043
+ options.ensureDelete(); // 同一实例不支持多处存在
1044
+ viewElement = options;
1045
+ Object.assign(viewElement, relationOptions);
1046
+ } else {
1047
+ viewElement = ViewElement.from(
1048
+ {
1049
+ ...viewElementOptions,
1050
+ ...options,
1051
+ },
1052
+ this,
1053
+ 'children'
1054
+ );
1055
+ }
1056
+ this.children.splice(index, 0, viewElement);
1057
+ return viewElement;
1058
+ }
1059
+
1060
+ /**
1061
+ * 插入页面元素
1062
+ * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1063
+ */
1064
+ insertViewElementAt(name: string, index: number): ViewElement;
1065
+
1066
+ /**
1067
+ * 插入页面元素
1068
+ * @param viewElementOptions 页面元素参数
1069
+ */
1070
+ insertViewElementAt(viewElementOptions: Partial<ViewElement>, index: number): ViewElement;
1071
+
1072
+ /**
1073
+ * 插入页面元素
1074
+ * @param viewElement 已有的页面元素实例
1075
+ */
1076
+ insertViewElementAt(viewElement: ViewElement, index: number): ViewElement;
1077
+
1078
+ insertViewElementAt(options: string | Partial<ViewElement> | ViewElement, index: number) {
1079
+ const node = this._insertViewElementAt(options as any, index);
1080
+ node.create({
1081
+ index,
1082
+ parentNode: this,
1083
+ parentKey: 'children',
1084
+ });
1085
+ return node;
1086
+ }
1087
+
1088
+ /**
1089
+ * 添加页面元素
1090
+ * @internal
1091
+ * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1092
+ */
1093
+ _addViewElement(name?: string): ViewElement;
1094
+
1095
+ /**
1096
+ * 添加页面元素
1097
+ * @internal
1098
+ * @param viewElementOptions 页面元素参数
1099
+ */
1100
+ _addViewElement(viewElementOptions: Partial<ViewElement>): ViewElement;
1101
+
1102
+ /**
1103
+ * 添加页面元素
1104
+ * @internal
1105
+ * @param viewElement 已有的页面元素实例
1106
+ */
1107
+ _addViewElement(viewElement: ViewElement): ViewElement;
1108
+
1109
+ _addViewElement(options?: string | Partial<ViewElement> | ViewElement) {
1110
+ const index = this.children.length;
1111
+ return this._insertViewElementAt(options as any, index);
1112
+ }
1113
+
1114
+ /**
1115
+ * 添加页面元素
1116
+ * @internal
1117
+ * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1118
+ */
1119
+ addViewElement(name?: string): ViewElement;
1120
+
1121
+ /**
1122
+ * 添加页面元素
1123
+ * @param viewElementOptions 页面元素参数
1124
+ */
1125
+ addViewElement(viewElementOptions: Partial<ViewElement>): ViewElement;
1126
+
1127
+ /**
1128
+ * 添加页面元素
1129
+ * @param viewElement 已有的页面元素实例
1130
+ */
1131
+ addViewElement(viewElement: ViewElement): ViewElement;
1132
+
1133
+ addViewElement(options?: string | Partial<ViewElement> | ViewElement) {
1134
+ const node = this._addViewElement(options as any);
1135
+ const index = this.children.indexOf(node);
1136
+ node.create({
1137
+ index,
1138
+ parentNode: this,
1139
+ parentKey: 'children',
1140
+ });
1141
+ return node;
1142
+ }
1143
+
1144
+ /**
1145
+ * 删除元素绑定属性
1146
+ * @param name 元素绑定属性名称
1147
+ */
1148
+ removeBindAttribute(name: string): void;
1149
+
1150
+ /**
1151
+ * 删除元素绑定属性
1152
+ * @param bindAttribute 已有的元素绑定属性实例
1153
+ */
1154
+ removeBindAttribute(bindAttribute: BindAttribute): void;
1155
+
1156
+ removeBindAttribute(options: string | BindAttribute) {
1157
+ let bindAttribute: BindAttribute;
1158
+ if (typeof options === 'string') {
1159
+ bindAttribute = (this.bindAttrs as BindAttribute[]).find((item) => item.name === options);
1160
+ if (!bindAttribute) {
1161
+ throw new Error(`找不到元素绑定属性 ${options}`);
1162
+ }
1163
+ } else {
1164
+ bindAttribute = options;
1165
+ }
1166
+ return bindAttribute.delete();
1167
+ }
1168
+
1169
+ __removeBindAttribute(bindAttribute: BindAttribute) {
1170
+ const { parentKey } = bindAttribute;
1171
+ const params: Params = {
1172
+ parentNode: this,
1173
+ parentKey,
1174
+ index: -1,
1175
+ object: null,
1176
+ oldObject: bindAttribute,
1177
+ };
1178
+ if (parentKey) {
1179
+ params.parentKey = parentKey;
1180
+ if (Array.isArray((this as any)[parentKey])) {
1181
+ const index = (this as any)[parentKey].indexOf(bindAttribute);
1182
+ ~index && (this as any)[parentKey].splice(index, 1);
1183
+ params.index = index;
1184
+ } else if ((this as any)[parentKey] === bindAttribute) {
1185
+ params.index = 0;
1186
+ (this as any)[parentKey] = undefined;
1187
+ }
1188
+ }
1189
+ return params;
1190
+ }
1191
+
1192
+ /**
1193
+ * 删除元素绑定事件
1194
+ * @param name 元素绑定事件名称
1195
+ */
1196
+ removeBindEvent(name: string): void;
1197
+
1198
+ /**
1199
+ * 删除元素绑定事件
1200
+ * @param bindEvent 已有的元素绑定事件实例
1201
+ */
1202
+ removeBindEvent(bindEvent: BindEvent): void;
1203
+
1204
+ removeBindEvent(options: string | BindEvent) {
1205
+ let bindEvent: BindEvent;
1206
+ if (typeof options === 'string') {
1207
+ bindEvent = (this.bindEvents as BindEvent[]).find((item) => item.name === options);
1208
+ if (!bindEvent) {
1209
+ throw new Error(`找不到元素绑定事件 ${options}`);
1210
+ }
1211
+ } else {
1212
+ bindEvent = options;
1213
+ }
1214
+ return bindEvent.delete();
1215
+ }
1216
+
1217
+ __removeBindEvent(bindEvent: BindEvent) {
1218
+ const { parentKey } = bindEvent;
1219
+ const params: Params = {
1220
+ parentNode: this,
1221
+ parentKey,
1222
+ index: -1,
1223
+ object: null,
1224
+ oldObject: bindEvent,
1225
+ };
1226
+ if (parentKey) {
1227
+ params.parentKey = parentKey;
1228
+ if (Array.isArray((this as any)[parentKey])) {
1229
+ const index = (this as any)[parentKey].indexOf(bindEvent);
1230
+ ~index && (this as any)[parentKey].splice(index, 1);
1231
+ params.index = index;
1232
+ } else if ((this as any)[parentKey] === bindEvent) {
1233
+ params.index = 0;
1234
+ (this as any)[parentKey] = undefined;
1235
+ }
1236
+ }
1237
+ return params;
1238
+ }
1239
+
1240
+ /**
1241
+ * 删除元素指令
1242
+ * @param name 元素指令名称
1243
+ */
1244
+ removeBindDirective(name: string): void;
1245
+
1246
+ /**
1247
+ * 删除元素指令
1248
+ * @param bindDirective 已有的元素指令实例
1249
+ */
1250
+ removeBindDirective(bindDirective: BindDirective): void;
1251
+
1252
+ removeBindDirective(options: string | BindDirective) {
1253
+ let bindDirective: BindDirective;
1254
+ if (typeof options === 'string') {
1255
+ bindDirective = (this.bindDirectives as BindDirective[]).find((item) => item.name === options);
1256
+ if (!bindDirective) {
1257
+ throw new Error(`找不到元素指令 ${options}`);
1258
+ }
1259
+ } else {
1260
+ bindDirective = options;
1261
+ }
1262
+ return bindDirective.delete();
1263
+ }
1264
+
1265
+ __removeBindDirective(bindDirective: BindDirective) {
1266
+ const { parentKey } = bindDirective;
1267
+ const params: Params = {
1268
+ parentNode: this,
1269
+ parentKey,
1270
+ index: -1,
1271
+ object: null,
1272
+ oldObject: bindDirective,
1273
+ };
1274
+ if (parentKey) {
1275
+ params.parentKey = parentKey;
1276
+ if (Array.isArray((this as any)[parentKey])) {
1277
+ const index = (this as any)[parentKey].indexOf(bindDirective);
1278
+ ~index && (this as any)[parentKey].splice(index, 1);
1279
+ params.index = index;
1280
+ } else if ((this as any)[parentKey] === bindDirective) {
1281
+ params.index = 0;
1282
+ (this as any)[parentKey] = undefined;
1283
+ }
1284
+ }
1285
+ return params;
1286
+ }
1287
+
1288
+ /**
1289
+ * 删除元素绑定样式
1290
+ * @param name 元素绑定样式名称
1291
+ */
1292
+ removeBindStyle(name: string): void;
1293
+
1294
+ /**
1295
+ * 删除元素绑定样式
1296
+ * @param bindStyle 已有的元素绑定样式实例
1297
+ */
1298
+ removeBindStyle(bindStyle: BindStyle): void;
1299
+
1300
+ removeBindStyle(options: string | BindStyle) {
1301
+ let bindStyle: BindStyle;
1302
+ if (typeof options === 'string') {
1303
+ bindStyle = (this.bindStyles as BindStyle[]).find((item) => item.name === options);
1304
+ if (!bindStyle) {
1305
+ throw new Error(`找不到元素绑定样式 ${options}`);
1306
+ }
1307
+ } else {
1308
+ bindStyle = options;
1309
+ }
1310
+ return bindStyle.delete();
1311
+ }
1312
+
1313
+ __removeBindStyle(bindStyle: BindStyle) {
1314
+ const { parentKey } = bindStyle;
1315
+ const params: Params = {
1316
+ parentNode: this,
1317
+ parentKey,
1318
+ index: -1,
1319
+ object: null,
1320
+ oldObject: bindStyle,
1321
+ };
1322
+ if (parentKey) {
1323
+ params.parentKey = parentKey;
1324
+ if (Array.isArray((this as any)[parentKey])) {
1325
+ const index = (this as any)[parentKey].indexOf(bindStyle);
1326
+ ~index && (this as any)[parentKey].splice(index, 1);
1327
+ params.index = index;
1328
+ } else if ((this as any)[parentKey] === bindStyle) {
1329
+ params.index = 0;
1330
+ (this as any)[parentKey] = undefined;
1331
+ }
1332
+ }
1333
+ return params;
1334
+ }
1335
+
1336
+ /**
1337
+ * 删除页面元素
1338
+ * @param name 页面元素名称
1339
+ */
1340
+ removeViewElement(name: string): void;
1341
+
1342
+ /**
1343
+ * 删除页面元素
1344
+ * @param viewElement 已有的页面元素实例
1345
+ */
1346
+ removeViewElement(viewElement: ViewElement): void;
1347
+
1348
+ removeViewElement(options: string | ViewElement) {
1349
+ let viewElement: ViewElement;
1350
+ if (typeof options === 'string') {
1351
+ viewElement = (this.children as ViewElement[]).find((item) => item.name === options);
1352
+ if (!viewElement) {
1353
+ throw new Error(`找不到页面元素 ${options}`);
1354
+ }
1355
+ } else {
1356
+ viewElement = options;
1357
+ }
1358
+ return viewElement.delete();
1359
+ }
1360
+
1361
+ __removeViewElement(viewElement: ViewElement) {
1362
+ const { parentKey } = viewElement;
1363
+ const params: Params = {
1364
+ parentNode: this,
1365
+ parentKey,
1366
+ index: -1,
1367
+ object: null,
1368
+ oldObject: viewElement,
1369
+ };
1370
+ if (parentKey) {
1371
+ params.parentKey = parentKey;
1372
+ if (Array.isArray((this as any)[parentKey])) {
1373
+ const index = (this as any)[parentKey].indexOf(viewElement);
1374
+ ~index && (this as any)[parentKey].splice(index, 1);
1375
+ params.index = index;
1376
+ } else if ((this as any)[parentKey] === viewElement) {
1377
+ params.index = 0;
1378
+ (this as any)[parentKey] = undefined;
1379
+ }
1380
+ }
1381
+ return params;
1382
+ }
1383
+
1384
+ //= ===============================================================================
1385
+ // ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
1386
+ // 自动生成的代码已结束。下面可以手动编写。
1387
+ //= ===============================================================================
1388
+
1389
+ /* 主页面有没有权限 */
1390
+ get parentAuth() {
1391
+ const _nameSpace = this.view.getNamespace();
1392
+ const mainViewName = _nameSpace.split('.')[2];
1393
+ return this.view.parentNode.concept === 'App' ? this.view.auth : this.frontend.views.find((item) => item.name === mainViewName)?.auth;
1394
+ }
1395
+
1396
+ // IDE内展示需要屏蔽掉“系统统一路径前缀”
1397
+ get uiPath() {
1398
+ return `${this.view.uiPath}/${this.name}`;
1399
+ }
1400
+
1401
+ /**
1402
+ * 权限领域的资源路径
1403
+ */
1404
+ get authPath() {
1405
+ return `${this.view.path}/${this.name}`;
1406
+ }
1407
+
1408
+ get auth() {
1409
+ return this.bindDirectives.find((directive) => directive.name === 'auth');
1410
+ }
1411
+
1412
+ getViewElementUniqueName(name = 'viewElement1') {
1413
+ return this.view?.getViewElementUniqueName(name);
1414
+ }
1415
+
1416
+ public static readonly TAG_NAME_PREFIX_REG?: RegExp = /^([lieu]|van)[-_]/;
1417
+
1418
+ static from(source: any, parentNode?: any, parentKey?: string): ViewElement {
1419
+ const node = super.from(source, parentNode, parentKey) as ViewElement;
1420
+ if (!node.name) {
1421
+ const tagName = node.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1422
+ node.name = node.getViewElementUniqueName(`${tagName}1`);
397
1423
  }
398
-
399
- /**
400
- * 插入元素绑定属性
401
- * @internal
402
- * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
403
- */
404
- _insertBindAttributeAt(name: string, index: number): BindAttribute;
405
-
406
- /**
407
- * 插入元素绑定属性
408
- * @internal
409
- * @param bindAttributeOptions 元素绑定属性参数
410
- */
411
- _insertBindAttributeAt(bindAttributeOptions: Partial<BindAttribute>, index: number): BindAttribute;
412
-
413
- /**
414
- * 插入元素绑定属性
415
- * @internal
416
- * @param bindAttribute 已有的元素绑定属性实例
417
- */
418
- _insertBindAttributeAt(bindAttribute: BindAttribute, index: number): BindAttribute;
419
-
420
- _insertBindAttributeAt(options: string | Partial<BindAttribute> | BindAttribute, index: number) {
421
- const bindAttributeOptions: any = {};
422
- const relationOptions = { parentNode: this, parentKey: 'bindAttrs' };
423
- let bindAttribute: BindAttribute;
424
- if (!options) {
425
- bindAttribute = BindAttribute.from({
426
- ...bindAttributeOptions,
427
- name: this.getBindAttributeUniqueName(),
428
- }, this, 'bindAttrs');
429
- } else if (typeof options === 'string') {
430
- bindAttribute = BindAttribute.from({
431
- ...bindAttributeOptions,
432
- name: options,
433
- }, this, 'bindAttrs');
434
- } else if (options instanceof BindAttribute) {
435
- options.ensureDelete(); // 同一实例不支持多处存在
436
- bindAttribute = options;
437
- Object.assign(bindAttribute, relationOptions);
1424
+ return node;
1425
+ }
1426
+
1427
+ /**
1428
+ * 设置组件权限
1429
+ */
1430
+ setBindRoles(bindRoles: string[]) {
1431
+ const object = {
1432
+ bindRoles,
1433
+ };
1434
+ this.update({
1435
+ ...object,
1436
+ });
1437
+ }
1438
+
1439
+ getBindAttribute(name: string) {
1440
+ return this.bindAttrs.find((bindAttr) => bindAttr.name === name);
1441
+ }
1442
+
1443
+ toHump(name: string): string {
1444
+ return name.replace(/-(\w)/g, (all, letter) => letter.toUpperCase());
1445
+ }
1446
+
1447
+ toFirstUpper(name: string): string {
1448
+ return name.replace(/^\S/, (s) => s.toUpperCase());
1449
+ }
1450
+
1451
+ haveScope(): boolean {
1452
+ return Boolean(this.slotScope);
1453
+ }
1454
+
1455
+ toEmbeddedTSDefinition(state?: TranslatorState): string {
1456
+ let code = '';
1457
+ code += indent((state?.tabSize || 0) + 1);
1458
+ // 登录组件不翻译
1459
+ if (this.toHump(this.tag) === 'lcapLogin' || this.staticClass === 'login-form') {
1460
+ code += `${this.name}: nasl.ui.div<any>;\n`;
1461
+ } else if (this.tag === 'u-table-view-column-dynamic') {
1462
+ code += `${this.name}: nasl.ui.${this.toHump(this.tag)}<any, any>;\n`;
1463
+ } else {
1464
+ code += `${this.name}: nasl.ui.${this.toHump(this.tag)}<any>;\n`;
1465
+ }
1466
+ if (Array.isArray(this.children)) {
1467
+ this.children.forEach((element) => {
1468
+ code += element.toEmbeddedTSDefinition(shiftState(state, code));
1469
+ });
1470
+ }
1471
+ return code;
1472
+ }
1473
+
1474
+ getTypeArgmentsStr(state?: TranslatorState): string {
1475
+ // 登录组件不翻译
1476
+ if (this.toHump(this.tag) === 'lcapLogin' || this.staticClass === 'login-form') return '<any>';
1477
+ let code = '';
1478
+ // formItem的单独处理
1479
+ if (this.tag === 'u-form-item') {
1480
+ if (Array.isArray(this.children) && this.children.length) {
1481
+ const { tag } = this.children[0];
1482
+ if (tag === 'u-input') {
1483
+ code += '<nasl.core.String>';
1484
+ } else if (tag === 'u-input-number') {
1485
+ code += '<nasl.core.Long>';
438
1486
  } else {
439
- bindAttribute = BindAttribute.from({
440
- ...bindAttributeOptions,
441
- ...options,
442
- }, this, 'bindAttrs');
1487
+ code += '<any>';
443
1488
  }
444
- this.bindAttrs.splice(index, 0, bindAttribute);
445
- return bindAttribute;
446
- }
447
-
448
- /**
449
- * 插入元素绑定属性
450
- * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
451
- */
452
- insertBindAttributeAt(name: string, index: number): BindAttribute;
453
-
454
- /**
455
- * 插入元素绑定属性
456
- * @param bindAttributeOptions 元素绑定属性参数
457
- */
458
- insertBindAttributeAt(bindAttributeOptions: Partial<BindAttribute>, index: number): BindAttribute;
459
-
460
- /**
461
- * 插入元素绑定属性
462
- * @param bindAttribute 已有的元素绑定属性实例
463
- */
464
- insertBindAttributeAt(bindAttribute: BindAttribute, index: number): BindAttribute;
465
-
466
- insertBindAttributeAt(options: string | Partial<BindAttribute> | BindAttribute, index: number) {
467
- const node = this._insertBindAttributeAt(options as any, index);
468
- node.create({
469
- index,
470
- parentNode: this,
471
- parentKey: 'bindAttrs',
472
- });
473
- return node;
474
- }
475
-
476
- /**
477
- * 添加元素绑定属性
478
- * @internal
479
- * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
480
- */
481
- _addBindAttribute(name?: string): BindAttribute;
482
-
483
- /**
484
- * 添加元素绑定属性
485
- * @internal
486
- * @param bindAttributeOptions 元素绑定属性参数
487
- */
488
- _addBindAttribute(bindAttributeOptions: Partial<BindAttribute>): BindAttribute;
489
-
490
- /**
491
- * 添加元素绑定属性
492
- * @internal
493
- * @param bindAttribute 已有的元素绑定属性实例
494
- */
495
- _addBindAttribute(bindAttribute: BindAttribute): BindAttribute;
496
-
497
- _addBindAttribute(options?: string | Partial<BindAttribute> | BindAttribute) {
498
- const index = this.bindAttrs.length;
499
- return this._insertBindAttributeAt(options as any, index);
500
- }
501
-
502
- /**
503
- * 添加元素绑定属性
504
- * @internal
505
- * @param name 元素绑定属性名称,如果不填会自动生成一个唯一名称
506
- */
507
- addBindAttribute(name?: string): BindAttribute;
508
-
509
- /**
510
- * 添加元素绑定属性
511
- * @param bindAttributeOptions 元素绑定属性参数
512
- */
513
- addBindAttribute(bindAttributeOptions: Partial<BindAttribute>): BindAttribute;
514
-
515
- /**
516
- * 添加元素绑定属性
517
- * @param bindAttribute 已有的元素绑定属性实例
518
- */
519
- addBindAttribute(bindAttribute: BindAttribute): BindAttribute;
520
-
521
- addBindAttribute(options?: string | Partial<BindAttribute> | BindAttribute) {
522
- const node = this._addBindAttribute(options as any);
523
- const index = this.bindAttrs.indexOf(node);
524
- node.create({
525
- index,
526
- parentNode: this,
527
- parentKey: 'bindAttrs',
528
- });
529
- return node;
530
- }
531
-
532
- getBindEventExistingNames(excludedList: Array<BindEvent> = []) {
533
- const excludedSet = new Set(excludedList);
534
- return ((this.bindEvents as BindEvent[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
535
- }
536
- getBindEventUniqueName(name = 'bindEvent1') {
537
- return utils.unique(name, this.getBindEventExistingNames(), undefined, false);
538
- }
539
-
540
- /**
541
- * 插入元素绑定事件
542
- * @internal
543
- * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
544
- */
545
- _insertBindEventAt(name: string, index: number): BindEvent;
546
-
547
- /**
548
- * 插入元素绑定事件
549
- * @internal
550
- * @param bindEventOptions 元素绑定事件参数
551
- */
552
- _insertBindEventAt(bindEventOptions: Partial<BindEvent>, index: number): BindEvent;
553
-
554
- /**
555
- * 插入元素绑定事件
556
- * @internal
557
- * @param bindEvent 已有的元素绑定事件实例
558
- */
559
- _insertBindEventAt(bindEvent: BindEvent, index: number): BindEvent;
560
-
561
- _insertBindEventAt(options: string | Partial<BindEvent> | BindEvent, index: number) {
562
- const bindEventOptions: any = {};
563
- const relationOptions = { parentNode: this, parentKey: 'bindEvents' };
564
- let bindEvent: BindEvent;
565
- if (!options) {
566
- bindEvent = BindEvent.from({
567
- ...bindEventOptions,
568
- name: this.getBindEventUniqueName(),
569
- }, this, 'bindEvents');
570
- } else if (typeof options === 'string') {
571
- bindEvent = BindEvent.from({
572
- ...bindEventOptions,
573
- name: options,
574
- }, this, 'bindEvents');
575
- } else if (options instanceof BindEvent) {
576
- options.ensureDelete(); // 同一实例不支持多处存在
577
- bindEvent = options;
578
- Object.assign(bindEvent, relationOptions);
1489
+ }
1490
+ return code;
1491
+ }
1492
+ const { bindAttrs } = this;
1493
+ if (bindAttrs && bindAttrs.length) {
1494
+ const attr = bindAttrs.find((item) => item.name === 'data-source');
1495
+ if (attr && attr.expression) {
1496
+ if (this.tag === 'u-table-view-column-dynamic') {
1497
+ code += `<${(this.parentNode as any).__tsDataSourceTypeName}, ${(this as any).__tsDataSourceTypeName}>`;
579
1498
  } else {
580
- bindEvent = BindEvent.from({
581
- ...bindEventOptions,
582
- ...options,
583
- }, this, 'bindEvents');
1499
+ code += `<${(this as any).__tsDataSourceTypeName}>`;
584
1500
  }
585
- this.bindEvents.splice(index, 0, bindEvent);
586
- return bindEvent;
587
- }
588
-
589
- /**
590
- * 插入元素绑定事件
591
- * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
592
- */
593
- insertBindEventAt(name: string, index: number): BindEvent;
594
-
595
- /**
596
- * 插入元素绑定事件
597
- * @param bindEventOptions 元素绑定事件参数
598
- */
599
- insertBindEventAt(bindEventOptions: Partial<BindEvent>, index: number): BindEvent;
600
-
601
- /**
602
- * 插入元素绑定事件
603
- * @param bindEvent 已有的元素绑定事件实例
604
- */
605
- insertBindEventAt(bindEvent: BindEvent, index: number): BindEvent;
606
-
607
- insertBindEventAt(options: string | Partial<BindEvent> | BindEvent, index: number) {
608
- const node = this._insertBindEventAt(options as any, index);
609
- node.create({
610
- index,
611
- parentNode: this,
612
- parentKey: 'bindEvents',
613
- });
614
- return node;
615
- }
616
-
617
- /**
618
- * 添加元素绑定事件
619
- * @internal
620
- * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
621
- */
622
- _addBindEvent(name?: string): BindEvent;
623
-
624
- /**
625
- * 添加元素绑定事件
626
- * @internal
627
- * @param bindEventOptions 元素绑定事件参数
628
- */
629
- _addBindEvent(bindEventOptions: Partial<BindEvent>): BindEvent;
630
-
631
- /**
632
- * 添加元素绑定事件
633
- * @internal
634
- * @param bindEvent 已有的元素绑定事件实例
635
- */
636
- _addBindEvent(bindEvent: BindEvent): BindEvent;
637
-
638
- _addBindEvent(options?: string | Partial<BindEvent> | BindEvent) {
639
- const index = this.bindEvents.length;
640
- return this._insertBindEventAt(options as any, index);
641
- }
642
-
643
- /**
644
- * 添加元素绑定事件
645
- * @internal
646
- * @param name 元素绑定事件名称,如果不填会自动生成一个唯一名称
647
- */
648
- addBindEvent(name?: string): BindEvent;
649
-
650
- /**
651
- * 添加元素绑定事件
652
- * @param bindEventOptions 元素绑定事件参数
653
- */
654
- addBindEvent(bindEventOptions: Partial<BindEvent>): BindEvent;
655
-
656
- /**
657
- * 添加元素绑定事件
658
- * @param bindEvent 已有的元素绑定事件实例
659
- */
660
- addBindEvent(bindEvent: BindEvent): BindEvent;
661
-
662
- addBindEvent(options?: string | Partial<BindEvent> | BindEvent) {
663
- const node = this._addBindEvent(options as any);
664
- const index = this.bindEvents.indexOf(node);
665
- node.create({
666
- index,
667
- parentNode: this,
668
- parentKey: 'bindEvents',
669
- });
670
- return node;
671
- }
672
-
673
- getBindDirectiveExistingNames(excludedList: Array<BindDirective> = []) {
674
- const excludedSet = new Set(excludedList);
675
- return ((this.bindDirectives as BindDirective[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
676
- }
677
- getBindDirectiveUniqueName(name = 'bindDirective1') {
678
- return utils.unique(name, this.getBindDirectiveExistingNames(), undefined, false);
679
- }
680
-
681
- /**
682
- * 插入元素指令
683
- * @internal
684
- * @param name 元素指令名称,如果不填会自动生成一个唯一名称
685
- */
686
- _insertBindDirectiveAt(name: string, index: number): BindDirective;
687
-
688
- /**
689
- * 插入元素指令
690
- * @internal
691
- * @param bindDirectiveOptions 元素指令参数
692
- */
693
- _insertBindDirectiveAt(bindDirectiveOptions: Partial<BindDirective>, index: number): BindDirective;
694
-
695
- /**
696
- * 插入元素指令
697
- * @internal
698
- * @param bindDirective 已有的元素指令实例
699
- */
700
- _insertBindDirectiveAt(bindDirective: BindDirective, index: number): BindDirective;
701
-
702
- _insertBindDirectiveAt(options: string | Partial<BindDirective> | BindDirective, index: number) {
703
- const bindDirectiveOptions: any = {};
704
- const relationOptions = { parentNode: this, parentKey: 'bindDirectives' };
705
- let bindDirective: BindDirective;
706
- if (!options) {
707
- bindDirective = BindDirective.from({
708
- ...bindDirectiveOptions,
709
- name: this.getBindDirectiveUniqueName(),
710
- }, this, 'bindDirectives');
711
- } else if (typeof options === 'string') {
712
- bindDirective = BindDirective.from({
713
- ...bindDirectiveOptions,
714
- name: options,
715
- }, this, 'bindDirectives');
716
- } else if (options instanceof BindDirective) {
717
- options.ensureDelete(); // 同一实例不支持多处存在
718
- bindDirective = options;
719
- Object.assign(bindDirective, relationOptions);
720
- } else {
721
- bindDirective = BindDirective.from({
722
- ...bindDirectiveOptions,
723
- ...options,
724
- }, this, 'bindDirectives');
1501
+ }
1502
+ }
1503
+ return code;
1504
+ }
1505
+
1506
+ getDatasourceTypeCodeStr(state?: TranslatorState, eleArr?: Array<ViewElement>): string {
1507
+ let code = '';
1508
+ (eleArr || []).forEach((element, index) => {
1509
+ const { bindAttrs } = element;
1510
+ if (bindAttrs && bindAttrs.length) {
1511
+ const attr = bindAttrs.find((item) => item.name === 'data-source');
1512
+ if (attr && attr.expression) {
1513
+ const datasourceName = `datasourceName${index}`;
1514
+ (element as any).__tsDataSourceTypeName = datasourceName;
1515
+ if (attr.expression instanceof MemberExpression || attr.expression instanceof Identifier) {
1516
+ const value = attr.expression.toEmbeddedTS(shiftState(state, code));
1517
+ code += `type ${datasourceName} = `;
1518
+ code += `nasl.ui.GetItemTypeFromDataSource<typeof ${value}>;\n`;
1519
+ } else {
1520
+ code += `const __funcName${index} = () => { return`;
1521
+ code += attr.expression.toEmbeddedTS(shiftState(state, code));
1522
+ code += '};\n';
1523
+ code += `type ${datasourceName} = `;
1524
+ code += `nasl.ui.GetItemTypeFromDataSource<ReturnType<typeof __funcName${index}>>;\n`;
1525
+ }
725
1526
  }
726
- this.bindDirectives.splice(index, 0, bindDirective);
727
- return bindDirective;
728
- }
729
-
730
- /**
731
- * 插入元素指令
732
- * @param name 元素指令名称,如果不填会自动生成一个唯一名称
733
- */
734
- insertBindDirectiveAt(name: string, index: number): BindDirective;
735
-
736
- /**
737
- * 插入元素指令
738
- * @param bindDirectiveOptions 元素指令参数
739
- */
740
- insertBindDirectiveAt(bindDirectiveOptions: Partial<BindDirective>, index: number): BindDirective;
741
-
742
- /**
743
- * 插入元素指令
744
- * @param bindDirective 已有的元素指令实例
745
- */
746
- insertBindDirectiveAt(bindDirective: BindDirective, index: number): BindDirective;
747
-
748
- insertBindDirectiveAt(options: string | Partial<BindDirective> | BindDirective, index: number) {
749
- const node = this._insertBindDirectiveAt(options as any, index);
750
- node.create({
751
- index,
752
- parentNode: this,
753
- parentKey: 'bindDirectives',
754
- });
755
- return node;
756
- }
757
-
758
- /**
759
- * 添加元素指令
760
- * @internal
761
- * @param name 元素指令名称,如果不填会自动生成一个唯一名称
762
- */
763
- _addBindDirective(name?: string): BindDirective;
764
-
765
- /**
766
- * 添加元素指令
767
- * @internal
768
- * @param bindDirectiveOptions 元素指令参数
769
- */
770
- _addBindDirective(bindDirectiveOptions: Partial<BindDirective>): BindDirective;
771
-
772
- /**
773
- * 添加元素指令
774
- * @internal
775
- * @param bindDirective 已有的元素指令实例
776
- */
777
- _addBindDirective(bindDirective: BindDirective): BindDirective;
778
-
779
- _addBindDirective(options?: string | Partial<BindDirective> | BindDirective) {
780
- const index = this.bindDirectives.length;
781
- return this._insertBindDirectiveAt(options as any, index);
782
- }
783
-
784
- /**
785
- * 添加元素指令
786
- * @internal
787
- * @param name 元素指令名称,如果不填会自动生成一个唯一名称
788
- */
789
- addBindDirective(name?: string): BindDirective;
790
-
791
- /**
792
- * 添加元素指令
793
- * @param bindDirectiveOptions 元素指令参数
794
- */
795
- addBindDirective(bindDirectiveOptions: Partial<BindDirective>): BindDirective;
796
-
797
- /**
798
- * 添加元素指令
799
- * @param bindDirective 已有的元素指令实例
800
- */
801
- addBindDirective(bindDirective: BindDirective): BindDirective;
802
-
803
- addBindDirective(options?: string | Partial<BindDirective> | BindDirective) {
804
- const node = this._addBindDirective(options as any);
805
- const index = this.bindDirectives.indexOf(node);
806
- node.create({
807
- index,
808
- parentNode: this,
809
- parentKey: 'bindDirectives',
1527
+ }
1528
+ });
1529
+ code += '\n';
1530
+ code += indent((state?.tabSize || 0) + 2);
1531
+ return code;
1532
+ }
1533
+
1534
+ @withSourceMap()
1535
+ toEmbeddedTS(state?: TranslatorState, parentLevel?: number): string {
1536
+ const { parentNode, app, tag, staticClass, name, bindDirectives, bindRoles, bindEvents, children } = this;
1537
+
1538
+ const chineseTsName = (name: string) => {
1539
+ let tsName = name;
1540
+ // 匹配所有特殊字符都转为_
1541
+ tsName = tsName.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '_');
1542
+ if (/^\d/.test(tsName)) {
1543
+ tsName = `$${tsName}`;
1544
+ }
1545
+ return tsName;
1546
+ };
1547
+
1548
+ // 过滤模板的登录中的一些翻译,这里只过滤h5表格中的两个列
1549
+ if ((parentNode.concept === 'ViewElement' && parentNode.tag && this.toHump(parentNode.tag) === 'lcapLogin') || staticClass === 'login-cell') {
1550
+ return '';
1551
+ }
1552
+ // pc事件翻译
1553
+ if (this.toHump(tag) === 'lcapLogin') {
1554
+ let code = `new nasl.ui.div({name: __elements.${this.name},\n`;
1555
+ // 事件
1556
+ if (Array.isArray(this.bindEvents)) {
1557
+ this.bindEvents.forEach((event) => {
1558
+ code += event.toEmbeddedTS(
1559
+ shiftState(state, code, {
1560
+ tabSize: (state?.tabSize || 0) + 2,
1561
+ })
1562
+ );
1563
+ code += '\n';
810
1564
  });
811
- return node;
812
- }
813
-
814
- getBindStyleExistingNames(excludedList: Array<BindStyle> = []) {
815
- const excludedSet = new Set(excludedList);
816
- return ((this.bindStyles as BindStyle[]) || []).filter((item) => !excludedSet.has(item)).map((item) => item.name);
817
- }
818
- getBindStyleUniqueName(name = 'bindStyle1') {
819
- return utils.unique(name, this.getBindStyleExistingNames(), undefined, false);
820
- }
821
-
822
- /**
823
- * 插入元素绑定样式
824
- * @internal
825
- * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
826
- */
827
- _insertBindStyleAt(name: string, index: number): BindStyle;
828
-
829
- /**
830
- * 插入元素绑定样式
831
- * @internal
832
- * @param bindStyleOptions 元素绑定样式参数
833
- */
834
- _insertBindStyleAt(bindStyleOptions: Partial<BindStyle>, index: number): BindStyle;
835
-
836
- /**
837
- * 插入元素绑定样式
838
- * @internal
839
- * @param bindStyle 已有的元素绑定样式实例
840
- */
841
- _insertBindStyleAt(bindStyle: BindStyle, index: number): BindStyle;
842
-
843
- _insertBindStyleAt(options: string | Partial<BindStyle> | BindStyle, index: number) {
844
- const bindStyleOptions: any = {};
845
- const relationOptions = { parentNode: this, parentKey: 'bindStyles' };
846
- let bindStyle: BindStyle;
847
- if (!options) {
848
- bindStyle = BindStyle.from({
849
- ...bindStyleOptions,
850
- name: this.getBindStyleUniqueName(),
851
- }, this, 'bindStyles');
852
- } else if (typeof options === 'string') {
853
- bindStyle = BindStyle.from({
854
- ...bindStyleOptions,
855
- name: options,
856
- }, this, 'bindStyles');
857
- } else if (options instanceof BindStyle) {
858
- options.ensureDelete(); // 同一实例不支持多处存在
859
- bindStyle = options;
860
- Object.assign(bindStyle, relationOptions);
861
- } else {
862
- bindStyle = BindStyle.from({
863
- ...bindStyleOptions,
864
- ...options,
865
- }, this, 'bindStyles');
866
- }
867
- this.bindStyles.splice(index, 0, bindStyle);
868
- return bindStyle;
1565
+ }
1566
+
1567
+ code += `}),\n`;
1568
+ return code;
1569
+ }
1570
+ let levelIndex = parentLevel || 0;
1571
+ if (tag === 'template' && this.haveScope()) {
1572
+ const slotTarget = !this.slotTarget ? 'slotDefault' : `slot${this.toFirstUpper(this.toHump(this.slotTarget))}`;
1573
+ let code = '';
1574
+ code += `${slotTarget}: (current${levelIndex === 0 ? '' : levelIndex})=> {\n`;
1575
+ code += this.getDatasourceTypeCodeStr(state, this.children);
1576
+ levelIndex++;
1577
+ code += 'return [';
1578
+ this.children.forEach((element) => {
1579
+ code += element.toEmbeddedTS(
1580
+ shiftState(state, code, {
1581
+ tabSize: state?.tabSize || 0,
1582
+ }),
1583
+ levelIndex
1584
+ );
1585
+ });
1586
+ code += ']';
1587
+ code += '\n';
1588
+ code += '},\n';
1589
+ return code;
1590
+ }
1591
+ if (tag === 'template') {
1592
+ const slotTarget = !this.slotTarget ? 'slotDefault' : `slot${this.toFirstUpper(this.toHump(this.slotTarget))}`;
1593
+ let code = '';
1594
+ code += `${slotTarget}: ()=> {\n`;
1595
+ code += this.getDatasourceTypeCodeStr(state, this.children);
1596
+ code += 'return [';
1597
+ this.children.forEach((element) => {
1598
+ code += element.toEmbeddedTS(
1599
+ shiftState(state, code, {
1600
+ tabSize: state?.tabSize || 0,
1601
+ }),
1602
+ levelIndex
1603
+ );
1604
+ });
1605
+ code += indent((state?.tabSize || 0) + 2);
1606
+ code += ']';
1607
+ code += '\n';
1608
+ code += '},\n';
1609
+ return code;
1610
+ }
1611
+
1612
+ // 后面那个name是为了查找引用的时候用的
1613
+ let code = `new nasl.ui.${this.toHump(tag)}${this.getTypeArgmentsStr(state)}({name: __elements.${name},\n`;
1614
+ // 是否开启权限
1615
+ // const hasAuth = Array.isArray(bindDirectives)
1616
+ // ? !!bindDirectives.filter((directive) => directive.name === 'auth').length
1617
+ // : false;
1618
+ // 角色
1619
+ if (Array.isArray(bindRoles) && bindRoles.length) {
1620
+ code += indent((state?.tabSize || 0) + 2);
1621
+ code += 'roles = [\n';
1622
+ bindRoles.forEach((role) => {
1623
+ code += indent((state?.tabSize || 0) + 3);
1624
+ code += `${app.getNamespace()}.roles.${chineseTsName(role)}.${chineseTsName(role)},`;
1625
+ code += '\n';
1626
+ });
1627
+ code += indent((state?.tabSize || 0) + 2);
1628
+ code += '],\n';
1629
+ }
1630
+
1631
+ // 事件
1632
+ if (Array.isArray(bindEvents)) {
1633
+ bindEvents.forEach((event) => {
1634
+ code += event.toEmbeddedTS(
1635
+ shiftState(state, code, {
1636
+ tabSize: (state?.tabSize || 0) + 2,
1637
+ })
1638
+ );
1639
+ code += '\n';
1640
+ });
869
1641
  }
870
1642
 
871
- /**
872
- * 插入元素绑定样式
873
- * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
874
- */
875
- insertBindStyleAt(name: string, index: number): BindStyle;
876
-
877
- /**
878
- * 插入元素绑定样式
879
- * @param bindStyleOptions 元素绑定样式参数
880
- */
881
- insertBindStyleAt(bindStyleOptions: Partial<BindStyle>, index: number): BindStyle;
882
-
883
- /**
884
- * 插入元素绑定样式
885
- * @param bindStyle 已有的元素绑定样式实例
886
- */
887
- insertBindStyleAt(bindStyle: BindStyle, index: number): BindStyle;
888
-
889
- insertBindStyleAt(options: string | Partial<BindStyle> | BindStyle, index: number) {
890
- const node = this._insertBindStyleAt(options as any, index);
891
- node.create({
892
- index,
893
- parentNode: this,
894
- parentKey: 'bindStyles',
895
- });
896
- return node;
897
- }
1643
+ // 子元素
1644
+ if (Array.isArray(children)) {
1645
+ code += indent((state?.tabSize || 0) + 1);
898
1646
 
899
- /**
900
- * 添加元素绑定样式
901
- * @internal
902
- * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
903
- */
904
- _addBindStyle(name?: string): BindStyle;
905
-
906
- /**
907
- * 添加元素绑定样式
908
- * @internal
909
- * @param bindStyleOptions 元素绑定样式参数
910
- */
911
- _addBindStyle(bindStyleOptions: Partial<BindStyle>): BindStyle;
912
-
913
- /**
914
- * 添加元素绑定样式
915
- * @internal
916
- * @param bindStyle 已有的元素绑定样式实例
917
- */
918
- _addBindStyle(bindStyle: BindStyle): BindStyle;
919
-
920
- _addBindStyle(options?: string | Partial<BindStyle> | BindStyle) {
921
- const index = this.bindStyles.length;
922
- return this._insertBindStyleAt(options as any, index);
923
- }
1647
+ if (Array.isArray(this.bindAttrs)) {
1648
+ code += `bindAttr: () => [\n`;
1649
+ this.bindAttrs.forEach((attr) => (code += `${attr.toEmbeddedTS(shiftState(state, code, { tabSize: 1 }))},\n`));
1650
+ this.bindDirectives.forEach((directive) => (code += `${directive.toEmbeddedTS(shiftState(state, code, { tabSize: 1 }))},\n`));
1651
+ this.bindStyles.forEach((bindStyle) => (code += `${bindStyle.toEmbeddedTS(shiftState(state, code, { tabSize: 1 }))},\n`));
1652
+ code += `${indent((state?.tabSize || 0) + 2)}],\n`;
1653
+ }
924
1654
 
925
- /**
926
- * 添加元素绑定样式
927
- * @internal
928
- * @param name 元素绑定样式名称,如果不填会自动生成一个唯一名称
929
- */
930
- addBindStyle(name?: string): BindStyle;
931
-
932
- /**
933
- * 添加元素绑定样式
934
- * @param bindStyleOptions 元素绑定样式参数
935
- */
936
- addBindStyle(bindStyleOptions: Partial<BindStyle>): BindStyle;
937
-
938
- /**
939
- * 添加元素绑定样式
940
- * @param bindStyle 已有的元素绑定样式实例
941
- */
942
- addBindStyle(bindStyle: BindStyle): BindStyle;
943
-
944
- addBindStyle(options?: string | Partial<BindStyle> | BindStyle) {
945
- const node = this._addBindStyle(options as any);
946
- const index = this.bindStyles.indexOf(node);
947
- node.create({
948
- index,
949
- parentNode: this,
950
- parentKey: 'bindStyles',
1655
+ // 如果子集中有插槽的就
1656
+ if (children.find((item) => item.tag === 'template' && item.slotTarget)) {
1657
+ code += indent((state?.tabSize || 0) + 2);
1658
+ const defaultArr: ViewElement[] = [];
1659
+ // 先把插槽翻译了
1660
+ children.forEach((element) => {
1661
+ if (element.tag === 'template') {
1662
+ code += element.toEmbeddedTS(
1663
+ shiftState(state, code, {
1664
+ tabSize: state?.tabSize || 0,
1665
+ }),
1666
+ levelIndex
1667
+ );
1668
+ } else {
1669
+ defaultArr.push(element);
1670
+ }
951
1671
  });
952
- return node;
953
- }
954
-
955
- /**
956
- * 插入页面元素
957
- * @internal
958
- * @param name 页面元素名称,如果不填会自动生成一个唯一名称
959
- */
960
- _insertViewElementAt(name: string, index: number): ViewElement;
961
-
962
- /**
963
- * 插入页面元素
964
- * @internal
965
- * @param viewElementOptions 页面元素参数
966
- */
967
- _insertViewElementAt(viewElementOptions: Partial<ViewElement>, index: number): ViewElement;
968
-
969
- /**
970
- * 插入页面元素
971
- * @internal
972
- * @param viewElement 已有的页面元素实例
973
- */
974
- _insertViewElementAt(viewElement: ViewElement, index: number): ViewElement;
975
-
976
- _insertViewElementAt(options: string | Partial<ViewElement> | ViewElement, index: number) {
977
- const viewElementOptions: any = {};
978
- const relationOptions = { parentNode: this, parentKey: 'children' };
979
- let viewElement: ViewElement;
980
- if (!options) {
981
- viewElement = ViewElement.from({
982
- ...viewElementOptions,
983
- name: this.getViewElementUniqueName(),
984
- }, this, 'children');
985
- } else if (typeof options === 'string') {
986
- viewElement = ViewElement.from({
987
- ...viewElementOptions,
988
- name: options,
989
- }, this, 'children');
990
- } else if (options instanceof ViewElement) {
991
- options.ensureDelete(); // 同一实例不支持多处存在
992
- viewElement = options;
993
- Object.assign(viewElement, relationOptions);
994
- } else {
995
- viewElement = ViewElement.from({
996
- ...viewElementOptions,
997
- ...options,
998
- }, this, 'children');
1672
+ // 翻译其余的子集
1673
+ if (defaultArr.length) {
1674
+ code += indent((state?.tabSize || 0) + 2);
1675
+ code += `slotDefault: ()=> {\n`;
1676
+ code += this.getDatasourceTypeCodeStr(state, defaultArr);
1677
+ code += 'return [';
1678
+ defaultArr.forEach((element) => {
1679
+ code += element.toEmbeddedTS(
1680
+ shiftState(state, code, {
1681
+ tabSize: (state?.tabSize || 0) + 2,
1682
+ }),
1683
+ levelIndex
1684
+ );
1685
+ code += '\n';
1686
+ });
1687
+ code += indent((state?.tabSize || 0) + 2);
1688
+ code += ']\n';
1689
+ code += indent((state?.tabSize || 0) + 1);
1690
+ code += '}\n';
999
1691
  }
1000
- this.children.splice(index, 0, viewElement);
1001
- return viewElement;
1002
- }
1003
-
1004
- /**
1005
- * 插入页面元素
1006
- * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1007
- */
1008
- insertViewElementAt(name: string, index: number): ViewElement;
1009
-
1010
- /**
1011
- * 插入页面元素
1012
- * @param viewElementOptions 页面元素参数
1013
- */
1014
- insertViewElementAt(viewElementOptions: Partial<ViewElement>, index: number): ViewElement;
1015
-
1016
- /**
1017
- * 插入页面元素
1018
- * @param viewElement 已有的页面元素实例
1019
- */
1020
- insertViewElementAt(viewElement: ViewElement, index: number): ViewElement;
1021
-
1022
- insertViewElementAt(options: string | Partial<ViewElement> | ViewElement, index: number) {
1023
- const node = this._insertViewElementAt(options as any, index);
1024
- node.create({
1025
- index,
1026
- parentNode: this,
1027
- parentKey: 'children',
1028
- });
1029
- return node;
1030
- }
1031
-
1032
- /**
1033
- * 添加页面元素
1034
- * @internal
1035
- * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1036
- */
1037
- _addViewElement(name?: string): ViewElement;
1038
-
1039
- /**
1040
- * 添加页面元素
1041
- * @internal
1042
- * @param viewElementOptions 页面元素参数
1043
- */
1044
- _addViewElement(viewElementOptions: Partial<ViewElement>): ViewElement;
1045
-
1046
- /**
1047
- * 添加页面元素
1048
- * @internal
1049
- * @param viewElement 已有的页面元素实例
1050
- */
1051
- _addViewElement(viewElement: ViewElement): ViewElement;
1052
-
1053
- _addViewElement(options?: string | Partial<ViewElement> | ViewElement) {
1054
- const index = this.children.length;
1055
- return this._insertViewElementAt(options as any, index);
1056
- }
1057
-
1058
- /**
1059
- * 添加页面元素
1060
- * @internal
1061
- * @param name 页面元素名称,如果不填会自动生成一个唯一名称
1062
- */
1063
- addViewElement(name?: string): ViewElement;
1064
-
1065
- /**
1066
- * 添加页面元素
1067
- * @param viewElementOptions 页面元素参数
1068
- */
1069
- addViewElement(viewElementOptions: Partial<ViewElement>): ViewElement;
1070
-
1071
- /**
1072
- * 添加页面元素
1073
- * @param viewElement 已有的页面元素实例
1074
- */
1075
- addViewElement(viewElement: ViewElement): ViewElement;
1076
-
1077
- addViewElement(options?: string | Partial<ViewElement> | ViewElement) {
1078
- const node = this._addViewElement(options as any);
1079
- const index = this.children.indexOf(node);
1080
- node.create({
1081
- index,
1082
- parentNode: this,
1083
- parentKey: 'children',
1692
+ } else {
1693
+ code += indent((state?.tabSize || 0) + 2);
1694
+ code += `slotDefault: ()=> {\n`;
1695
+ code += this.getDatasourceTypeCodeStr(state, children);
1696
+ code += 'return [';
1697
+ children.forEach((element) => {
1698
+ code += element.toEmbeddedTS(
1699
+ shiftState(state, code, {
1700
+ tabSize: (state?.tabSize || 0) + 2,
1701
+ }),
1702
+ levelIndex
1703
+ );
1704
+ code += '\n';
1084
1705
  });
1085
- return node;
1086
- }
1087
-
1088
- /**
1089
- * 删除元素绑定属性
1090
- * @param name 元素绑定属性名称
1091
- */
1092
- removeBindAttribute(name: string): void;
1093
-
1094
- /**
1095
- * 删除元素绑定属性
1096
- * @param bindAttribute 已有的元素绑定属性实例
1097
- */
1098
- removeBindAttribute(bindAttribute: BindAttribute): void;
1099
-
1100
- removeBindAttribute(options: string | BindAttribute) {
1101
- let bindAttribute: BindAttribute;
1102
- if (typeof options === 'string') {
1103
- bindAttribute = (this.bindAttrs as BindAttribute[]).find((item) => item.name === options);
1104
- if (!bindAttribute) {
1105
- throw new Error('找不到元素绑定属性 ' + options);
1106
- }
1107
- } else {
1108
- bindAttribute = options;
1109
- }
1110
- return bindAttribute.delete();
1706
+ code += indent((state?.tabSize || 0) + 2);
1707
+ code += ']\n';
1708
+ code += indent((state?.tabSize || 0) + 1);
1709
+ code += '}\n';
1710
+ }
1111
1711
  }
1112
1712
 
1113
- __removeBindAttribute(bindAttribute: BindAttribute) {
1114
- const parentKey = bindAttribute.parentKey;
1115
- const params: Params = {
1116
- parentNode: this,
1117
- parentKey,
1118
- index: -1,
1119
- object: null,
1120
- oldObject: bindAttribute,
1121
- };
1122
- if (parentKey) {
1123
- params.parentKey = parentKey;
1124
- if (Array.isArray((this as any)[parentKey])) {
1125
- const index = (this as any)[parentKey].indexOf(bindAttribute);
1126
- ~index && (this as any)[parentKey].splice(index, 1);
1127
- params.index = index;
1128
- } else if ((this as any)[parentKey] === bindAttribute) {
1129
- params.index = 0;
1130
- (this as any)[parentKey] = undefined;
1131
- }
1132
- }
1133
- return params;
1134
- }
1713
+ code += `${indent(state?.tabSize || 0)}})`;
1135
1714
 
1136
- /**
1137
- * 删除元素绑定事件
1138
- * @param name 元素绑定事件名称
1139
- */
1140
- removeBindEvent(name: string): void;
1141
-
1142
- /**
1143
- * 删除元素绑定事件
1144
- * @param bindEvent 已有的元素绑定事件实例
1145
- */
1146
- removeBindEvent(bindEvent: BindEvent): void;
1147
-
1148
- removeBindEvent(options: string | BindEvent) {
1149
- let bindEvent: BindEvent;
1150
- if (typeof options === 'string') {
1151
- bindEvent = (this.bindEvents as BindEvent[]).find((item) => item.name === options);
1152
- if (!bindEvent) {
1153
- throw new Error('找不到元素绑定事件 ' + options);
1154
- }
1155
- } else {
1156
- bindEvent = options;
1157
- }
1158
- return bindEvent.delete();
1715
+ // 顶层元素是单独的表达式
1716
+ if (parentNode.concept === 'View') {
1717
+ code += ';\n';
1718
+ } else {
1719
+ code += ',\n';
1159
1720
  }
1160
1721
 
1161
- __removeBindEvent(bindEvent: BindEvent) {
1162
- const parentKey = bindEvent.parentKey;
1163
- const params: Params = {
1164
- parentNode: this,
1165
- parentKey,
1166
- index: -1,
1167
- object: null,
1168
- oldObject: bindEvent,
1169
- };
1170
- if (parentKey) {
1171
- params.parentKey = parentKey;
1172
- if (Array.isArray((this as any)[parentKey])) {
1173
- const index = (this as any)[parentKey].indexOf(bindEvent);
1174
- ~index && (this as any)[parentKey].splice(index, 1);
1175
- params.index = index;
1176
- } else if ((this as any)[parentKey] === bindEvent) {
1177
- params.index = 0;
1178
- (this as any)[parentKey] = undefined;
1179
- }
1180
- }
1181
- return params;
1182
- }
1722
+ return code;
1723
+ }
1183
1724
 
1184
- /**
1185
- * 删除元素指令
1186
- * @param name 元素指令名称
1187
- */
1188
- removeBindDirective(name: string): void;
1189
-
1190
- /**
1191
- * 删除元素指令
1192
- * @param bindDirective 已有的元素指令实例
1193
- */
1194
- removeBindDirective(bindDirective: BindDirective): void;
1195
-
1196
- removeBindDirective(options: string | BindDirective) {
1197
- let bindDirective: BindDirective;
1198
- if (typeof options === 'string') {
1199
- bindDirective = (this.bindDirectives as BindDirective[]).find((item) => item.name === options);
1200
- if (!bindDirective) {
1201
- throw new Error('找不到元素指令 ' + options);
1202
- }
1203
- } else {
1204
- bindDirective = options;
1205
- }
1206
- return bindDirective.delete();
1207
- }
1208
-
1209
- __removeBindDirective(bindDirective: BindDirective) {
1210
- const parentKey = bindDirective.parentKey;
1211
- const params: Params = {
1212
- parentNode: this,
1213
- parentKey,
1214
- index: -1,
1215
- object: null,
1216
- oldObject: bindDirective,
1217
- };
1218
- if (parentKey) {
1219
- params.parentKey = parentKey;
1220
- if (Array.isArray((this as any)[parentKey])) {
1221
- const index = (this as any)[parentKey].indexOf(bindDirective);
1222
- ~index && (this as any)[parentKey].splice(index, 1);
1223
- params.index = index;
1224
- } else if ((this as any)[parentKey] === bindDirective) {
1225
- params.index = 0;
1226
- (this as any)[parentKey] = undefined;
1227
- }
1725
+ @withSourceMap()
1726
+ toNaturalTS(state?: TranslatorState, parentLevel?: number): string {
1727
+ let code = '';
1728
+ const levelIndex = parentLevel || 0;
1729
+ if (Array.isArray(this.bindEvents)) {
1730
+ this.bindEvents.forEach((event) => {
1731
+ code += event.toNaturalTS(shiftState(state, code, {
1732
+ tabSize: state.tabSize,
1733
+ }));
1734
+ // code += '\n';
1735
+ });
1736
+ }
1737
+
1738
+ if (Array.isArray(this.children)) {
1739
+ if (this.children.find((item) => item.tag === 'template' && item.slotTarget)) {
1740
+ // code += indent(state.tabSize + 2);
1741
+ const defaultArr: ViewElement[] = [];
1742
+ // 先把插槽翻译了
1743
+ this.children.forEach((element) => {
1744
+ if (element.tag === 'template') {
1745
+ code += element.toNaturalTS(shiftState(state, code, {
1746
+ tabSize: state.tabSize,
1747
+ }), levelIndex);
1748
+ } else {
1749
+ defaultArr.push(element);
1750
+ }
1751
+ });
1752
+ // 翻译其余的子集
1753
+ if (defaultArr.length) {
1754
+ defaultArr.forEach((element) => {
1755
+ code += element.toNaturalTS(shiftState(state, code, {
1756
+ tabSize: state.tabSize,
1757
+ }), levelIndex);
1758
+ });
1228
1759
  }
1229
- return params;
1230
- }
1231
-
1232
- /**
1233
- * 删除元素绑定样式
1234
- * @param name 元素绑定样式名称
1235
- */
1236
- removeBindStyle(name: string): void;
1237
-
1238
- /**
1239
- * 删除元素绑定样式
1240
- * @param bindStyle 已有的元素绑定样式实例
1241
- */
1242
- removeBindStyle(bindStyle: BindStyle): void;
1243
-
1244
- removeBindStyle(options: string | BindStyle) {
1245
- let bindStyle: BindStyle;
1246
- if (typeof options === 'string') {
1247
- bindStyle = (this.bindStyles as BindStyle[]).find((item) => item.name === options);
1248
- if (!bindStyle) {
1249
- throw new Error('找不到元素绑定样式 ' + options);
1250
- }
1251
- } else {
1252
- bindStyle = options;
1760
+ } else {
1761
+ this.children.forEach((element) => {
1762
+ code += element.toNaturalTS(shiftState(state, code, {
1763
+ tabSize: state.tabSize,
1764
+ }), levelIndex);
1765
+ });
1766
+ }
1767
+ }
1768
+
1769
+ return code;
1770
+ }
1771
+
1772
+ toNaturalTSDefinition(state?: TranslatorState): string {
1773
+ let code = '';
1774
+
1775
+ if (['u-button', 'u-form', 'u-modal', 'u-table-view', 'u-select', 'u-input', 'u-number-input'].includes(this.tag)) {
1776
+ code += indent(state.tabSize + 1);
1777
+ // 登录组件不翻译
1778
+ // if (this.toHump(this.tag) === 'lcapLogin' || this.staticClass === 'login-form') {
1779
+ // code += `${this.name}: nasl.ui.div;\n`;
1780
+ // } else {
1781
+ code += `${this.name}: nasl.ui.${kebab2Camel(this.tag.replace(/^\w-/, ''))},\n`;
1782
+ // }
1783
+ }
1784
+
1785
+ if (Array.isArray(this.children)) {
1786
+ this.children.forEach((element) => {
1787
+ code += element.toNaturalTSDefinition(shiftState(state, code));
1788
+ });
1789
+ }
1790
+ return code;
1791
+ }
1792
+
1793
+ _duplicate() {
1794
+ const element = ViewElement.from(this.toTemplateJSON());
1795
+ const nameMap = element.deepRenameElements(this);
1796
+
1797
+ utils.traverse(
1798
+ (current) => {
1799
+ const node = current.node as any;
1800
+ if (node.concept === 'CallLogic' && /elements.(.+).logics/.test(node.calleeNamespace)) {
1801
+ const oldName = node.calleeNamespace.split('.')[1];
1802
+ if (nameMap.has(oldName)) {
1803
+ const newName = nameMap.get(oldName);
1804
+ node.calleeNamespace = `elements.${newName}.logics`;
1805
+ }
1253
1806
  }
1254
- return bindStyle.delete();
1255
- }
1256
-
1257
- __removeBindStyle(bindStyle: BindStyle) {
1258
- const parentKey = bindStyle.parentKey;
1259
- const params: Params = {
1260
- parentNode: this,
1261
- parentKey,
1262
- index: -1,
1263
- object: null,
1264
- oldObject: bindStyle,
1265
- };
1266
- if (parentKey) {
1267
- params.parentKey = parentKey;
1268
- if (Array.isArray((this as any)[parentKey])) {
1269
- const index = (this as any)[parentKey].indexOf(bindStyle);
1270
- ~index && (this as any)[parentKey].splice(index, 1);
1271
- params.index = index;
1272
- } else if ((this as any)[parentKey] === bindStyle) {
1273
- params.index = 0;
1274
- (this as any)[parentKey] = undefined;
1275
- }
1807
+ },
1808
+ { node: element },
1809
+ { mode: 'anyObject', excludedKeySet: element.JSON_EXCLUDED_KEYS }
1810
+ );
1811
+
1812
+ this.view.existingViewElement.clear();
1813
+ return element;
1814
+ }
1815
+
1816
+ // 递归遍历组件
1817
+ public traverseChildren(cb: (ele: ViewElement) => void): void {
1818
+ utils.traverse(
1819
+ (current) => {
1820
+ cb(current.node);
1821
+ },
1822
+ { node: this }
1823
+ );
1824
+ }
1825
+
1826
+ // 递归生成组件名
1827
+ public deepRenameElements(node: ViewElement) {
1828
+ const map = new Map<string, string>();
1829
+ this.traverseChildren((ele: ViewElement) => {
1830
+ const oldName = ele.name;
1831
+ const tagName = ele.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1832
+ ele.name = node.getViewElementUniqueName(`${tagName}1`);
1833
+ map.set(oldName, ele.name);
1834
+ });
1835
+ return map;
1836
+ }
1837
+
1838
+ /**
1839
+ * 解析属性中的表达式
1840
+ * @param value
1841
+ * @param $def 目前 $def 只用来查找 $def.variables 和 $def.structures
1842
+ * @param dataSchema
1843
+ */
1844
+ private static _parseExpression(value: string) {
1845
+ try {
1846
+ const ast = babelParser.parseExpression(value) as any;
1847
+ const node = transAstNodeToNaslNode(ast);
1848
+ return LogicItem.from(node, null, null);
1849
+ } catch (e) {
1850
+ return null;
1851
+ }
1852
+ }
1853
+
1854
+ private static _parseValidationRule(value: string) {
1855
+ let calleeName = value;
1856
+ let args: any[] = [];
1857
+ try {
1858
+ const ast = babelParser.parseExpression(value) as any;
1859
+ const validationNamespace = stdlibNamespace.findChild('validation');
1860
+ if (ast.type === 'CallExpression') {
1861
+ calleeName = (ast.callee?.property?.name ?? ast.callee?.property?.value ?? ast.callee?.name).replace(/\(.*/, '');
1862
+ const func = validationNamespace.functions.find((item) => item.name === calleeName);
1863
+ args = ast.arguments.map((argument: any, index: number) => ({
1864
+ concept: 'Argument',
1865
+ name: '',
1866
+ kind: 'Statement',
1867
+ keyword: func?.params?.[index]?.name ?? '',
1868
+ expression: transAstNodeToNaslNode({ ...argument }),
1869
+ }));
1870
+ }
1871
+ } catch (error) { }
1872
+
1873
+ return {
1874
+ concept: 'ValidationRule',
1875
+ name: '',
1876
+ label: '验证规则',
1877
+ kind: 'Expression',
1878
+ calleeNamespace: 'nasl.validation',
1879
+ arguments: args,
1880
+ calleeName,
1881
+ };
1882
+ }
1883
+
1884
+ /**
1885
+ * 从 Vue 的 ASTNode 转换成 ASL 元素
1886
+ * @param astNode Vue 的 ASTNode
1887
+ */
1888
+ private static _fromASTNode(astNode: compiler.ASTElement, context?: ParseContext): ViewElement {
1889
+ const view: View = context?.view;
1890
+ // 临时处理组件的 text
1891
+ // h5-mock
1892
+ if (
1893
+ ['u-text', 'van-text', 'u-link', 'u-button', 'u-label', 'u-radio', 'u-checkbox', 'u-navbar-item', 'u-sidebar-item', 'u-menu-item'].includes(
1894
+ astNode.tag
1895
+ ) &&
1896
+ astNode.children.length === 1 &&
1897
+ astNode.children[0].type === 3
1898
+ ) {
1899
+ astNode.attrs = astNode.attrs || [];
1900
+ astNode.attrs.push({
1901
+ name: 'text',
1902
+ value: JSON.stringify(astNode.children[0].text),
1903
+ });
1904
+ astNode.children = [];
1905
+ }
1906
+ // 将 scopedSlots 合并到 children 中
1907
+ if (astNode.scopedSlots) {
1908
+ astNode.children = astNode.children || [];
1909
+ Object.keys(astNode.scopedSlots).forEach((key) => {
1910
+ if (!astNode.children.find((child) => key === (child as compiler.ASTElement).slotTarget)) {
1911
+ astNode.children.unshift(astNode.scopedSlots[key]);
1276
1912
  }
1277
- return params;
1278
- }
1279
-
1280
- /**
1281
- * 删除页面元素
1282
- * @param name 页面元素名称
1283
- */
1284
- removeViewElement(name: string): void;
1285
-
1286
- /**
1287
- * 删除页面元素
1288
- * @param viewElement 已有的页面元素实例
1289
- */
1290
- removeViewElement(viewElement: ViewElement): void;
1291
-
1292
- removeViewElement(options: string | ViewElement) {
1293
- let viewElement: ViewElement;
1294
- if (typeof options === 'string') {
1295
- viewElement = (this.children as ViewElement[]).find((item) => item.name === options);
1296
- if (!viewElement) {
1297
- throw new Error('找不到页面元素 ' + options);
1298
- }
1913
+ });
1914
+ delete astNode.scopedSlots;
1915
+ }
1916
+
1917
+ // 提示不支持的属性
1918
+ [
1919
+ 'component',
1920
+ 'inlineTemplate',
1921
+ 'pre',
1922
+ 'ns',
1923
+ 'transition',
1924
+ 'transitionOnAppear',
1925
+ 'transitionMode',
1926
+ 'slotName',
1927
+ 'classBinding',
1928
+ 'styleBinding',
1929
+ ].forEach((key) => {
1930
+ if ((astNode as any)[key]) console.warn(`[warn] ViewElement NASL unsupports '${key}' field in node `, astNode);
1931
+ });
1932
+
1933
+ let element: ViewElement;
1934
+ if (astNode.type === 1) {
1935
+ if (astNode.tag === 'router-view') {
1936
+ if (view.frontend.type === 'h5') {
1937
+ astNode.tag = 'van-router-view';
1299
1938
  } else {
1300
- viewElement = options;
1301
- }
1302
- return viewElement.delete();
1303
- }
1304
-
1305
- __removeViewElement(viewElement: ViewElement) {
1306
- const parentKey = viewElement.parentKey;
1307
- const params: Params = {
1308
- parentNode: this,
1309
- parentKey,
1310
- index: -1,
1311
- object: null,
1312
- oldObject: viewElement,
1313
- };
1314
- if (parentKey) {
1315
- params.parentKey = parentKey;
1316
- if (Array.isArray((this as any)[parentKey])) {
1317
- const index = (this as any)[parentKey].indexOf(viewElement);
1318
- ~index && (this as any)[parentKey].splice(index, 1);
1319
- params.index = index;
1320
- } else if ((this as any)[parentKey] === viewElement) {
1321
- params.index = 0;
1322
- (this as any)[parentKey] = undefined;
1323
- }
1324
- }
1325
- return params;
1326
- }
1327
-
1328
- //================================================================================
1329
- // ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
1330
- // 自动生成的代码已结束。下面可以手动编写。
1331
- //================================================================================
1332
-
1333
- /* 主页面有没有权限 */
1334
- get parentAuth() {
1335
- const _nameSpace = this.view.getNamespace();
1336
- const mainViewName = _nameSpace.split('.')[2];
1337
- return this.view.parentNode.concept === 'App' ? this.view.auth : this.frontend.views.find((item) => item.name === mainViewName)?.auth;
1338
- }
1339
-
1340
- // IDE内展示需要屏蔽掉“系统统一路径前缀”
1341
- get uiPath() {
1342
- return `${this.view.uiPath}/${this.name}`;
1343
- }
1344
-
1345
- /**
1346
- * 权限领域的资源路径
1347
- */
1348
- get authPath() {
1349
- return `${this.view.path}/${this.name}`;
1350
- }
1351
-
1352
- get auth() {
1353
- return this.bindDirectives.find((directive) => directive.name === 'auth');
1354
- }
1355
-
1356
- getViewElementUniqueName(name = 'viewElement1') {
1357
- return this.view?.getViewElementUniqueName(name);
1358
- }
1359
-
1360
- public static readonly TAG_NAME_PREFIX_REG?: RegExp = /^([lieu]|van)[-_]/;
1361
-
1362
- static from(source: any, parentNode?: any, parentKey?: string): ViewElement {
1363
- const node = super.from(source, parentNode, parentKey) as ViewElement;
1364
- if (!node.name) {
1365
- const tagName = node.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1366
- node.name = node.getViewElementUniqueName(`${tagName}1`);
1939
+ astNode.tag = 'u-router-view';
1367
1940
  }
1368
- return node;
1369
- }
1370
-
1371
- /**
1372
- * 设置组件权限
1373
- */
1374
- setBindRoles(bindRoles: string[]) {
1375
- const object = {
1376
- bindRoles,
1941
+ }
1942
+ const tagName = astNode.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1943
+ let newContext: any = {};
1944
+ if (context) {
1945
+ newContext = {
1946
+ ...context,
1377
1947
  };
1378
- this.update({
1379
- ...object,
1380
- });
1381
- }
1382
-
1383
- getBindAttribute(name: string) {
1384
- return this.bindAttrs.find((bindAttr) => bindAttr.name === name);
1385
- }
1386
-
1387
- toHump(name: string): string {
1388
- return name.replace(/-(\w)/g, (all, letter) => letter.toUpperCase());
1389
- }
1390
- toFirstUpper(name: string): string {
1391
- return name.replace(/^\S/, (s) => s.toUpperCase());
1392
- }
1393
-
1394
- haveScope(): boolean {
1395
- return Boolean(this.slotScope);
1396
- }
1397
-
1398
- toEmbeddedTSDefinition(state?: TranslatorState): string {
1399
- let code = '';
1400
- code += indent((state?.tabSize || 0) + 1);
1401
- // 登录组件不翻译
1402
- if (this.toHump(this.tag) === 'lcapLogin' || this.staticClass === 'login-form') {
1403
- code += `${this.name}: nasl.ui.div<any>;\n`;
1404
- } else if (this.tag === 'u-table-view-column-dynamic') {
1405
- code += `${this.name}: nasl.ui.${this.toHump(this.tag)}<any, any>;\n`;
1948
+ }
1949
+ element = new ViewElement({
1950
+ tag: astNode.tag,
1951
+ name: astNode.attrsMap.ref || view.getViewElementUniqueName(`${tagName}1`),
1952
+ staticClass: astNode.attrsMap.class,
1953
+ staticStyle: astNode.attrsMap.style,
1954
+ slotTarget: astNode.slotTarget && json5.parse(astNode.slotTarget),
1955
+ slotScope: astNode.slotScope === '_empty_' ? '' : astNode.slotScope,
1956
+ children: astNode.children.map((item) => this._fromASTNode(item as compiler.ASTElement, newContext)) as unknown as Array<ViewElement>,
1957
+ });
1958
+ astNode?.attrs?.forEach((oldAttr) => {
1959
+ let attr: BindAttribute;
1960
+ // 获取原始属性
1961
+ const orginAttrCode = (context?.code || '').substr((oldAttr as any).start, (oldAttr as any).end - (oldAttr as any).start);
1962
+ if (oldAttr.value === '""' && orginAttrCode.trim() === oldAttr.name) {
1963
+ attr = new BindAttribute({
1964
+ type: 'static',
1965
+ name: oldAttr.name,
1966
+ value: 'true',
1967
+ });
1406
1968
  } else {
1407
- code += `${this.name}: nasl.ui.${this.toHump(this.tag)}<any>;\n`;
1408
- }
1409
- if (Array.isArray(this.children)) {
1410
- this.children.forEach((element) => {
1411
- code += element.toEmbeddedTSDefinition(shiftState(state, code));
1412
- });
1413
- }
1414
- return code;
1415
- }
1416
-
1417
- getTypeArgmentsStr(state?: TranslatorState): string {
1418
- // 登录组件不翻译
1419
- if (this.toHump(this.tag) === 'lcapLogin' || this.staticClass === 'login-form')
1420
- return '<any>';
1421
- let code = '';
1422
- // formItem的单独处理
1423
- if (this.tag === 'u-form-item') {
1424
- if (Array.isArray(this.children) && this.children.length) {
1425
- const tag = this.children[0].tag;
1426
- if (tag === 'u-input') {
1427
- code += '<nasl.core.String>';
1428
- } else if (tag === 'u-input-number') {
1429
- code += '<nasl.core.Long>';
1430
- } else {
1431
- code += '<any>';
1432
- }
1433
- }
1434
- return code;
1435
- }
1436
- const bindAttrs = this.bindAttrs;
1437
- if (bindAttrs && bindAttrs.length) {
1438
- const attr = bindAttrs.find((item) => item.name === 'data-source');
1439
- if (attr && attr.expression) {
1440
- if (this.tag === 'u-table-view-column-dynamic') {
1441
- code += `<${(this.parentNode as any).__tsDataSourceTypeName}, ${(this as any).__tsDataSourceTypeName}>`;
1442
- } else {
1443
- code += `<${(this as any).__tsDataSourceTypeName}>`;
1444
- }
1445
- }
1446
- }
1447
- return code;
1448
- }
1449
- getDatasourceTypeCodeStr(state?: TranslatorState, eleArr?: Array<ViewElement>): string {
1450
- let code = '';
1451
- (eleArr || []).forEach((element, index) => {
1452
- const bindAttrs = element.bindAttrs;
1453
- if (bindAttrs && bindAttrs.length) {
1454
- const attr = bindAttrs.find((item) => item.name === 'data-source');
1455
- if (attr && attr.expression) {
1456
- const datasourceName = `datasourceName${index}`;
1457
- (element as any).__tsDataSourceTypeName = datasourceName;
1458
- if (attr.expression instanceof MemberExpression || attr.expression instanceof Identifier) {
1459
- const value = attr.expression.toEmbeddedTS(shiftState(state, code));
1460
- code += `type ${datasourceName} = `;
1461
- code += `nasl.ui.GetItemTypeFromDataSource<typeof ${value}>;\n`;
1462
- } else {
1463
- code += `const __funcName${index} = () => { return`;
1464
- code += attr.expression.toEmbeddedTS(shiftState(state, code));
1465
- code += '};\n';
1466
- code += `type ${datasourceName} = `;
1467
- code += `nasl.ui.GetItemTypeFromDataSource<ReturnType<typeof __funcName${index}>>;\n`;
1468
- }
1469
- }
1470
- }
1471
- });
1472
- code += '\n';
1473
- code += indent((state?.tabSize || 0) + 2);
1474
- return code;
1475
- }
1476
- @withSourceMap()
1477
- toEmbeddedTS(state?: TranslatorState, parentLevel?: number): string {
1478
- const {
1479
- parentNode,
1480
- app,
1481
- tag,
1482
- staticClass,
1483
- name,
1484
- bindDirectives,
1485
- bindRoles,
1486
- bindEvents,
1487
- children,
1488
- } = this;
1489
-
1490
- const chineseTsName = (name: string) => {
1491
- let tsName = name;
1492
- // 匹配所有特殊字符都转为_
1493
- tsName = tsName.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '_');
1494
- if (/^\d/.test(tsName)) {
1495
- tsName = '$' + tsName;
1496
- }
1497
- return tsName;
1498
- }
1499
-
1500
- // 过滤模板的登录中的一些翻译,这里只过滤h5表格中的两个列
1501
- if (
1502
- parentNode.concept === 'ViewElement' &&
1503
- parentNode.tag && this.toHump(parentNode.tag) === 'lcapLogin' ||
1504
- staticClass === 'login-cell'
1505
- ) {
1506
- return '';
1507
- }
1508
- // pc事件翻译
1509
- if (this.toHump(tag) === 'lcapLogin') {
1510
- let code = `new nasl.ui.div({name: __elements.${this.name},\n`;
1511
- // 事件
1512
- if (Array.isArray(this.bindEvents)) {
1513
- this.bindEvents.forEach((event) => {
1514
- code += event.toEmbeddedTS(shiftState(state, code, {
1515
- tabSize: (state?.tabSize || 0) + 2,
1516
- }));
1517
- code += '\n';
1518
- });
1969
+ try {
1970
+ const tmp = json5.parse(oldAttr.value);
1971
+ const source: any = {
1972
+ type: typeof tmp === 'string' ? 'string' : 'static',
1973
+ name: oldAttr.name,
1974
+ value: typeof tmp === 'string' ? tmp : oldAttr.value,
1975
+ };
1976
+ if (oldAttr.name === 'rules') {
1977
+ source.rules = tmp?.split('|').map((ruleStr: string) => this._parseValidationRule(ruleStr.trim()));
1519
1978
  }
1520
-
1521
- code += `}),\n`;
1522
- return code;
1523
- }
1524
- let levelIndex = parentLevel || 0;
1525
- if (tag === 'template' && this.haveScope()) {
1526
- const slotTarget = !this.slotTarget ? 'slotDefault' : 'slot' + this.toFirstUpper(this.toHump(this.slotTarget));
1527
- let code = '';
1528
- code += `${slotTarget}: (current${levelIndex === 0 ? '' : levelIndex})=> {\n`;
1529
- code += this.getDatasourceTypeCodeStr(state, this.children);
1530
- levelIndex++;
1531
- code += 'return [';
1532
- this.children.forEach((element) => {
1533
- code += element.toEmbeddedTS(shiftState(state, code, {
1534
- tabSize: (state?.tabSize || 0),
1535
- }), levelIndex);
1536
- });
1537
- code += ']';
1538
- code += '\n';
1539
- code += '},\n';
1540
- return code;
1541
- } else if (tag === 'template') {
1542
- const slotTarget = !this.slotTarget ? 'slotDefault' : 'slot' + this.toFirstUpper(this.toHump(this.slotTarget));
1543
- let code = '';
1544
- code += `${slotTarget}: ()=> {\n`;
1545
- code += this.getDatasourceTypeCodeStr(state, this.children);
1546
- code += 'return [';
1547
- this.children.forEach((element) => {
1548
- code += element.toEmbeddedTS(shiftState(state, code, {
1549
- tabSize: (state?.tabSize || 0),
1550
- }), levelIndex);
1551
- });
1552
- code += indent((state?.tabSize || 0) + 2);
1553
- code += ']';
1554
- code += '\n';
1555
- code += '},\n';
1556
- return code;
1557
- }
1558
-
1559
- // 后面那个name是为了查找引用的时候用的
1560
- let code = `new nasl.ui.${this.toHump(tag)}${this.getTypeArgmentsStr(state)}({name: __elements.${name},\n`;
1561
- // 是否开启权限
1562
- // const hasAuth = Array.isArray(bindDirectives)
1563
- // ? !!bindDirectives.filter((directive) => directive.name === 'auth').length
1564
- // : false;
1565
- // 角色
1566
- if (Array.isArray(bindRoles) && bindRoles.length) {
1567
- code += indent((state?.tabSize || 0) + 2);
1568
- code += 'roles = [\n';
1569
- bindRoles.forEach((role) => {
1570
- code += indent((state?.tabSize || 0) + 3);
1571
- code += `${app.getNamespace()}.roles.${chineseTsName(role)}.${chineseTsName(role)},`;
1572
- code += '\n';
1979
+ attr = new BindAttribute(source);
1980
+ } catch (e) {
1981
+ const expression = <any>this._parseExpression(oldAttr.value);
1982
+ attr = new BindAttribute({
1983
+ type: 'dynamic',
1984
+ name: oldAttr.name,
1985
+ value: expression ? '' : oldAttr.value,
1986
+ expression,
1573
1987
  });
1574
- code += indent((state?.tabSize || 0) + 2);
1575
- code += '],\n';
1576
- }
1577
-
1578
- // 事件
1579
- if (Array.isArray(bindEvents)) {
1580
- bindEvents.forEach((event) => {
1581
- code += event.toEmbeddedTS(shiftState(state, code, {
1582
- tabSize: (state?.tabSize || 0) + 2,
1583
- }));
1584
- code += '\n';
1585
- });
1586
- }
1587
-
1588
- // 子元素
1589
- if (Array.isArray(children)) {
1590
- code += indent((state?.tabSize || 0) + 1);
1591
-
1592
- if (Array.isArray(this.bindAttrs)) {
1593
- code += `bindAttr: () => [\n`;
1594
- this.bindAttrs.forEach((attr) => code += attr.toEmbeddedTS(shiftState(state, code, { tabSize: 1 })) + ',\n');
1595
- this.bindDirectives.forEach((directive) => code += directive.toEmbeddedTS(shiftState(state, code, { tabSize: 1 })) + ',\n');
1596
- this.bindStyles.forEach((bindStyle) => code += bindStyle.toEmbeddedTS(shiftState(state, code, { tabSize: 1 })) + ',\n');
1597
- code += indent((state?.tabSize || 0) + 2) + '],\n';
1598
- }
1599
-
1600
- // 如果子集中有插槽的就
1601
- if (children.find((item) => item.tag === 'template' && item.slotTarget)) {
1602
- code += indent((state?.tabSize || 0) + 2);
1603
- const defaultArr: ViewElement[] = [];
1604
- // 先把插槽翻译了
1605
- children.forEach((element) => {
1606
- if (element.tag === 'template') {
1607
- code += element.toEmbeddedTS(shiftState(state, code, {
1608
- tabSize: (state?.tabSize || 0),
1609
- }), levelIndex);
1610
- } else {
1611
- defaultArr.push(element);
1612
- }
1613
- });
1614
- // 翻译其余的子集
1615
- if (defaultArr.length) {
1616
- code += indent((state?.tabSize || 0) + 2);
1617
- code += `slotDefault: ()=> {\n`;
1618
- code += this.getDatasourceTypeCodeStr(state, defaultArr);
1619
- code += 'return [';
1620
- defaultArr.forEach((element) => {
1621
- code += element.toEmbeddedTS(shiftState(state, code, {
1622
- tabSize: (state?.tabSize || 0) + 2,
1623
- }), levelIndex);
1624
- code += '\n';
1625
- });
1626
- code += indent((state?.tabSize || 0) + 2);
1627
- code += ']\n';
1628
- code += indent((state?.tabSize || 0) + 1);
1629
- code += '}\n';
1630
- }
1631
- } else {
1632
- code += indent((state?.tabSize || 0) + 2);
1633
- code += `slotDefault: ()=> {\n`;
1634
- code += this.getDatasourceTypeCodeStr(state, children);
1635
- code += 'return [';
1636
- children.forEach((element) => {
1637
- code += element.toEmbeddedTS(shiftState(state, code, {
1638
- tabSize: (state?.tabSize || 0) + 2,
1639
- }), levelIndex);
1640
- code += '\n';
1641
- });
1642
- code += indent((state?.tabSize || 0) + 2);
1643
- code += ']\n';
1644
- code += indent((state?.tabSize || 0) + 1);
1645
- code += '}\n';
1646
- }
1647
- }
1648
-
1649
- code += indent((state?.tabSize || 0)) + '})';
1650
-
1651
- // 顶层元素是单独的表达式
1652
- if (parentNode.concept === 'View') {
1653
- code += ';\n';
1654
- } else {
1655
- code += ',\n';
1656
- }
1657
-
1658
- return code;
1659
- }
1660
-
1661
- _duplicate() {
1662
- const element = ViewElement.from(this.toTemplateJSON());
1663
- const nameMap = element.deepRenameElements(this);
1664
-
1665
- utils.traverse((current) => {
1666
- const node = current.node as any;
1667
- if (node.concept === 'CallLogic' && /elements.(.+).logics/.test(node.calleeNamespace)) {
1668
- const oldName = node.calleeNamespace.split('.')[1];
1669
- if(nameMap.has(oldName)) {
1670
- const newName = nameMap.get(oldName);
1671
- node.calleeNamespace = `elements.${newName}.logics`
1672
- }
1673
- }
1674
- }, { node: element }, { mode: 'anyObject', excludedKeySet: element.JSON_EXCLUDED_KEYS });
1675
-
1676
- this.view.existingViewElement.clear();
1677
- return element;
1678
- }
1679
-
1680
- // 递归遍历组件
1681
- public traverseChildren(cb: (ele: ViewElement) => void): void {
1682
- utils.traverse((current) => {
1683
- cb(current.node);
1684
- }, { node: this });
1685
- }
1686
-
1687
- // 递归生成组件名
1688
- public deepRenameElements(node: ViewElement) {
1689
- const map = new Map<string, string>();
1690
- this.traverseChildren((ele: ViewElement) => {
1691
- const oldName = ele.name;
1692
- const tagName = ele.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1693
- ele.name = node.getViewElementUniqueName(`${tagName}1`);
1694
- map.set(oldName, ele.name);
1695
- });
1696
- return map;
1697
- }
1698
-
1699
- /**
1700
- * 解析属性中的表达式
1701
- * @param value
1702
- * @param $def 目前 $def 只用来查找 $def.variables 和 $def.structures
1703
- * @param dataSchema
1704
- */
1705
- private static _parseExpression(value: string) {
1706
- try {
1707
- const ast = babelParser.parseExpression(value) as any;
1708
- const node = transAstNodeToNaslNode(ast);
1709
- return LogicItem.from(node, null, null);
1710
- } catch (e) {
1711
- return null;
1712
- }
1713
- }
1714
-
1715
- private static _parseValidationRule(value: string) {
1716
- let calleeName = value;
1717
- let args: any[] = [];
1718
- try {
1719
- const ast = babelParser.parseExpression(value) as any;
1720
- const validationNamespace = stdlibNamespace.findChild('validation');
1721
- if (ast.type === 'CallExpression') {
1722
- calleeName = (ast.callee?.property?.name ?? ast.callee?.property?.value ?? ast.callee?.name).replace(/\(.*/, '');
1723
- const func = validationNamespace.functions.find((item) => item.name === calleeName);
1724
- args = ast.arguments.map((argument: any, index: number) => ({
1725
- concept: 'Argument',
1726
- name: '',
1727
- kind: 'Statement',
1728
- keyword: func?.params?.[index]?.name ?? '',
1729
- expression: transAstNodeToNaslNode(Object.assign({}, argument)),
1730
- }));
1988
+ if (astNode.attrsMap[`:${attr.name}.sync`]) {
1989
+ attr.sync = true;
1731
1990
  }
1732
- } catch (error) { }
1733
-
1734
- return {
1735
- concept: 'ValidationRule',
1736
- name: '',
1737
- label: '验证规则',
1738
- kind: 'Expression',
1739
- calleeNamespace: 'nasl.validation',
1740
- arguments: args,
1741
- calleeName,
1742
- };
1743
- }
1744
-
1745
- /**
1746
- * 从 Vue 的 ASTNode 转换成 ASL 元素
1747
- * @param astNode Vue 的 ASTNode
1748
- */
1749
- private static _fromASTNode(astNode: compiler.ASTElement, context?: ParseContext): ViewElement {
1750
- const view: View = context?.view;
1751
- // 临时处理组件的 text
1752
- //h5-mock
1753
- if (
1754
- ['u-text', 'van-text', 'u-link', 'u-button', 'u-label', 'u-radio', 'u-checkbox', 'u-navbar-item', 'u-sidebar-item', 'u-menu-item'].includes(astNode.tag)
1755
- && astNode.children.length === 1
1756
- && astNode.children[0].type === 3
1757
- ) {
1758
- astNode.attrs = astNode.attrs || [];
1759
- astNode.attrs.push({
1760
- name: 'text',
1761
- value: JSON.stringify(astNode.children[0].text),
1762
- });
1763
- astNode.children = [];
1764
- }
1765
- // 将 scopedSlots 合并到 children 中
1766
- if (astNode.scopedSlots) {
1767
- astNode.children = astNode.children || [];
1768
- Object.keys(astNode.scopedSlots).forEach((key) => {
1769
- if (!astNode.children.find((child) => key === (child as compiler.ASTElement).slotTarget)) {
1770
- astNode.children.unshift(astNode.scopedSlots[key]);
1771
- }
1772
- });
1773
- delete astNode.scopedSlots;
1991
+ }
1774
1992
  }
1775
-
1776
- // 提示不支持的属性
1777
- ['component', 'inlineTemplate', 'pre', 'ns', 'transition', 'transitionOnAppear', 'transitionMode', 'slotName', 'classBinding', 'styleBinding'].forEach((key) => {
1778
- if ((astNode as any)[key])
1779
- console.warn(`[warn] ViewElement NASL unsupports '${key}' field in node `, astNode);
1780
- });
1781
-
1782
- let element: ViewElement;
1783
- if (astNode.type === 1) {
1784
- if (astNode.tag === 'router-view') {
1785
- if (view.frontend.type === 'h5') {
1786
- astNode.tag = 'van-router-view';
1787
- } else {
1788
- astNode.tag = 'u-router-view';
1789
- }
1993
+ element.addBindAttribute(attr);
1994
+ });
1995
+
1996
+ // compiler 处理:value.sync 时会加上update:value事件,需要过滤
1997
+ astNode.events &&
1998
+ Object.keys(astNode.events)
1999
+ .filter((name) => !name.startsWith('update:'))
2000
+ .forEach((name) => {
2001
+ const oldEvent = astNode.events[name] as compiler.ASTElementHandler;
2002
+ const str = oldEvent.value;
2003
+ const calleeName = str.split('(')[0];
2004
+ const matchArr = str.match(/\(([^)]*)\)/) || [];
2005
+ let argsStr = '';
2006
+ if (matchArr?.length >= 2) {
2007
+ argsStr = matchArr[1];
1790
2008
  }
1791
- const tagName = astNode.tag.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1792
- let newContext: any = {};
1793
- if (context) {
1794
- newContext = {
1795
- ...context,
2009
+ let args: any[] = [];
2010
+ const argStrs: string[] = argsStr.split(',');
2011
+ args = argStrs
2012
+ .filter((argStr) => !!argStr)
2013
+ .map((argStr) => {
2014
+ const keyword = argStr.trim().split('.');
2015
+ return {
2016
+ concept: 'Argument',
2017
+ expression: genArgumentMemberExpression(keyword),
1796
2018
  };
2019
+ });
2020
+ const viewLogics = context?.definition?.viewLogics || [];
2021
+ const currentLogic = viewLogics.find((item: Logic) => item.name === calleeName);
2022
+ if (currentLogic) {
2023
+ element.addBindEvent(
2024
+ new BindEvent({
2025
+ name,
2026
+ calleeNamespace: '',
2027
+ calleeName: '',
2028
+ arguments: args,
2029
+ logics: [currentLogic],
2030
+ })
2031
+ );
1797
2032
  }
1798
- element = new ViewElement({
1799
- tag: astNode.tag,
1800
- name: astNode.attrsMap.ref || view.getViewElementUniqueName(`${tagName}1`),
1801
- staticClass: astNode.attrsMap.class,
1802
- staticStyle: astNode.attrsMap.style,
1803
- slotTarget: astNode.slotTarget && json5.parse(astNode.slotTarget),
1804
- slotScope: astNode.slotScope === '_empty_' ? '' : astNode.slotScope,
1805
- children: astNode.children.map((item) => this._fromASTNode(item as compiler.ASTElement, newContext)) as unknown as Array<ViewElement>,
1806
- });
1807
- astNode?.attrs?.forEach((oldAttr) => {
1808
- let attr: BindAttribute;
1809
- // 获取原始属性
1810
- const orginAttrCode = (context?.code || '').substr((oldAttr as any).start, (oldAttr as any).end - (oldAttr as any).start);
1811
- if (oldAttr.value === '""' && orginAttrCode.trim() === oldAttr.name) {
1812
- attr = new BindAttribute({
1813
- type: 'static',
1814
- name: oldAttr.name,
1815
- value: 'true',
1816
- });
1817
- } else {
1818
- try {
1819
- const tmp = json5.parse(oldAttr.value);
1820
- const source: any = {
1821
- type: typeof tmp === 'string' ? 'string' : 'static',
1822
- name: oldAttr.name,
1823
- value: typeof tmp === 'string' ? tmp : oldAttr.value,
1824
- };
1825
- if (oldAttr.name === 'rules') {
1826
- source.rules = tmp?.split('|').map((ruleStr: string) => this._parseValidationRule(ruleStr.trim()));
1827
- }
1828
- attr = new BindAttribute(source);
1829
- } catch (e) {
1830
- const expression = <any> this._parseExpression(oldAttr.value);
1831
- attr = new BindAttribute({
1832
- type: 'dynamic',
1833
- name: oldAttr.name,
1834
- value: expression ? '' : oldAttr.value,
1835
- expression,
1836
- });
1837
- if (astNode.attrsMap[`:${attr.name}.sync`]) {
1838
- attr.sync = true;
1839
- }
1840
- }
1841
- }
1842
- element.addBindAttribute(attr);
1843
- });
1844
-
1845
- // compiler 处理:value.sync 时会加上update:value事件,需要过滤
1846
- astNode.events
1847
- && Object.keys(astNode.events)
1848
- .filter((name) => !name.startsWith('update:'))
1849
- .forEach((name) => {
1850
- const oldEvent = astNode.events[name] as compiler.ASTElementHandler;
1851
- const str = oldEvent.value;
1852
- const calleeName = str.split('(')[0];
1853
- const matchArr = str.match(/\(([^)]*)\)/) || [];
1854
- let argsStr = '';
1855
- if (matchArr?.length >= 2) {
1856
- argsStr = matchArr[1];
1857
- }
1858
- let args: any[] = [];
1859
- const argStrs: string[] = argsStr.split(',');
1860
- args = argStrs
1861
- .filter((argStr) => !!argStr)
1862
- .map((argStr) => {
1863
- const keyword = argStr.trim().split('.');
1864
- return {
1865
- concept: 'Argument',
1866
- expression: genArgumentMemberExpression(keyword),
1867
- };
1868
- });
1869
- const viewLogics = context?.definition?.viewLogics || [];
1870
- const currentLogic = viewLogics.find((item: Logic) => item.name === calleeName);
1871
- if (currentLogic) {
1872
- element.addBindEvent(new BindEvent({
1873
- name,
1874
- calleeNamespace: '',
1875
- calleeName: '',
1876
- arguments: args,
1877
- logics: [currentLogic],
1878
- }));
1879
- }
1880
- });
1881
-
1882
- astNode.directives
1883
- && astNode.directives.forEach((directive) => {
1884
- if (directive.name === 'model') {
1885
- const valueAttr = astNode.attrs && astNode.attrs.find((attr) => attr.name === 'value');
1886
- if (!valueAttr) {
1887
- const expression = <any> this._parseExpression(directive.value);
1888
- element.addBindAttribute(new BindAttribute({
1889
- type: 'dynamic',
1890
- name: 'value',
1891
- value: expression ? '' : directive.value,
1892
- expression,
1893
- sync: true,
1894
- }));
1895
- }
1896
- } else {
1897
- const expression = <any> this._parseExpression(directive.value);
1898
- element.addBindDirective(new BindDirective({
1899
- type: expression ? 'string' : 'dynamic',
1900
- name: directive.name,
1901
- rawName: directive.rawName,
1902
- value: expression ? '' : directive.value,
1903
- expression,
1904
- arg: directive.arg,
1905
- // modifiers: directive.modifiers,
1906
- }));
1907
- }
1908
- });
1909
-
1910
- if (astNode.if) {
1911
- element.addBindDirective(new BindDirective({
1912
- type: 'dynamic',
1913
- name: 'if',
1914
- rawName: 'v-if',
1915
- value: '',
1916
- expression: <any> this._parseExpression(astNode.if),
1917
- }));
2033
+ });
2034
+
2035
+ astNode.directives &&
2036
+ astNode.directives.forEach((directive) => {
2037
+ if (directive.name === 'model') {
2038
+ const valueAttr = astNode.attrs && astNode.attrs.find((attr) => attr.name === 'value');
2039
+ if (!valueAttr) {
2040
+ const expression = <any>this._parseExpression(directive.value);
2041
+ element.addBindAttribute(
2042
+ new BindAttribute({
2043
+ type: 'dynamic',
2044
+ name: 'value',
2045
+ value: expression ? '' : directive.value,
2046
+ expression,
2047
+ sync: true,
2048
+ })
2049
+ );
1918
2050
  }
1919
- } else if (astNode.type === 2) {
1920
- const tagName = config.scope === 'h5' ? 'van-text' : 'u-text';
1921
- const baseName = tagName.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1922
- element = new ViewElement({
1923
- tag: tagName,
1924
- name: view.getViewElementUniqueName(`${baseName}1`),
1925
- });
1926
- const value = astNode.text?.match(/{{(.*?)}}/)[1].trim();
1927
- const expression = <any> this._parseExpression(value);
1928
- element.addBindAttribute(new BindAttribute({
1929
- type: 'dynamic',
1930
- name: 'text',
1931
- value: expression ? '' : value,
2051
+ } else {
2052
+ const expression = <any>this._parseExpression(directive.value);
2053
+ element.addBindDirective(
2054
+ new BindDirective({
2055
+ type: expression ? 'string' : 'dynamic',
2056
+ name: directive.name,
2057
+ rawName: directive.rawName,
2058
+ value: expression ? '' : directive.value,
1932
2059
  expression,
1933
- }));
1934
- } else if (astNode.type === 3) {
1935
- const tagName = config.scope === 'h5' ? 'van-text' : 'u-text';
1936
- const baseName = tagName.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
1937
- element = new ViewElement({
1938
- tag: tagName,
1939
- name: view.getViewElementUniqueName(`${baseName}1`),
1940
- });
1941
- element.addBindAttribute(new BindAttribute({
1942
- name: 'text',
1943
- type: 'string',
1944
- value: astNode.text?.trim(),
1945
- }));
1946
- }
1947
- return element;
1948
- }
1949
-
1950
- /**
1951
- * 解析 Vue 模板
1952
- * 该方法不会绑定 view 和 parent,如果是添加元素优先使用 fromHTML
1953
- * @param html Vue 的模板
1954
- * @TODO 处理多个元素的问题
1955
- */
1956
- public static parse(code: string, context?: ParseContext) {
1957
- code = code || '<div></div>';
1958
-
1959
- const compilerOptions: compiler.CompilerOptions = {
1960
- preserveWhitespace: false,
1961
- outputSourceRange: true,
1962
- };
1963
-
1964
- let ast = compiler.compile(code, compilerOptions).ast;
1965
- if (ast.tag === 'template' && !ast.slotTarget)
1966
- ast = ast.children[0] as compiler.ASTElement;
1967
- return this._fromASTNode(ast, {
1968
- ...context,
1969
- code,
2060
+ arg: directive.arg,
2061
+ // modifiers: directive.modifiers,
2062
+ })
2063
+ );
2064
+ }
1970
2065
  });
1971
- }
1972
-
1973
- /**
1974
- * 从模板生成规范的 ViewElement 对象
1975
- */
1976
- public static fromHTML(html: string, context?: ParseContext) {
1977
- return this.parse(html, context);
1978
- }
1979
-
1980
- /**
1981
- * 转换成设计器中使用的 Vue 文件
1982
- * @param options
1983
- */
1984
- toDesignerVue() {
1985
- return this.toVue({
1986
- finalCode: false,
1987
- nodePathAttr: true,
1988
- attrFormat: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => {
1989
- if (attr.concept === 'BindAttribute' && !['href', 'destination', 'externalDestination', 'download'].includes(attr.name)) {
1990
- const api = config?.allNodesAPI?.[element.tag];
1991
- const apiOfAttr = api && api.attrs && api.attrs.find((_attr) => _attr.name === attr.name);
1992
- if (['u-form-item', 'u-validator', 'van-field'].includes(element.tag) && attr.name === 'rules') {
1993
- return `${attr.name}=""`;
1994
- }
1995
- if (apiOfAttr && apiOfAttr['designer-value'] !== undefined) {
1996
- let designerValue = apiOfAttr['designer-value'];
1997
- //对流程模板拖拽进行特判
1998
- element.bindAttrs.forEach((property) => {
1999
- if (property.name === 'repeat' && property.value === '1')
2000
- designerValue = '[{}, {}]';
2001
- });
2002
- if (typeof designerValue === 'string') {
2003
- designerValue = designerValue.replace(/"/g, "'");
2004
- }
2005
- try {
2006
- json5.parse(designerValue);
2007
- return `:${attr.name}="${designerValue}"`;
2008
- } catch (e) {
2009
- return `${attr.name}="${designerValue}"`;
2010
- }
2011
- }
2012
- if ((attr as BindAttribute).type === 'dynamic' && !(element.tag === 'u-cascade-select' && attr.name === 'categories'))
2013
- return defaultResult.replace(/:?([\w-]+)(?:.*?)="(.*)"/, (m, name, value) => {
2014
- try {
2015
- const tempValue = json5.parse(value);
2016
- if (typeof tempValue === 'boolean' || typeof tempValue === 'number') {
2017
- // 简单类型走属性
2018
- return `:${name}="${value.replace(/"/g, "'")}"`;
2019
- }
2020
- } catch (e) {
2021
- if (apiOfAttr && !apiOfAttr.type.includes('string'))
2022
- return '';
2023
- }
2024
- value = value
2025
- .replace(/"/g, "'")
2026
- .replace(/\$utils\['(.+?)'\]/g, '$1')
2027
- .replace(/\$refs./g, 'elements.')
2028
- .replace(/\$global.userInfo/g, 'nasl.auth.userInfo')
2029
- .replace(/\$global./g, 'nasl.')
2030
- .replace(/\bscope\.item\.\b/g, '')
2031
- .replace(/\bcurrent\.item\.\b/g, '');
2032
- return `${name}="{{ ${value} }}"`;
2033
- });
2034
- else
2035
- return defaultResult;
2036
- }
2037
- return false;
2038
- },
2039
- bindStylesFormat: (bindStyles: BindStyle[], element?: ViewElement) => false,
2040
- getExtraParts: (el: ViewElement) => {
2041
- const parts = [];
2042
-
2043
- const api = config.allNodesAPI[el.tag];
2044
- const emptySlot = api && api.slots && api.slots.find((slot) => slot.name === 'default' && slot['empty-background']);
2045
- const hasSupport = api && api.slots && api.slots.some((slot) => slot.support);
2046
- if (emptySlot || hasSupport) {
2047
- // 有些限制的组件如侧边栏分组有title插槽但要限制子元素放入
2048
- const validChildren = el.children.filter((elem) => !(elem.tag === 'template' && elem.slotTarget !== 'default'));
2049
- let childEmpty = !validChildren.length;
2050
- const defaultSlot = el.children.find((elem) => elem.tag === 'template' && elem.slotTarget === 'default');
2051
- if (defaultSlot) {
2052
- childEmpty = !defaultSlot.children.length;
2053
- }
2054
- if (childEmpty) {
2055
- let addEmpty = true;
2056
- if (['u-grid-view',
2057
- 'u-list-view',
2058
- 'van-list-view',
2059
- 'van-grid-view',
2060
- 'u-carousel'].includes(el.tag)) {
2061
- const hasDataSource = el.bindAttrs.find((attr) => attr.name === 'data-source');
2062
- addEmpty = !hasDataSource;
2063
- }
2064
- if (el.tag === 'u-crumb') {
2065
- const attrList = el.bindAttrs;
2066
- const hasAuto = attrList.some((attr) => attr.name === 'auto' && String(attr.value) === 'true');
2067
- if (hasAuto)
2068
- addEmpty = false;
2069
- }
2070
- if (['u-select', 'u-dropdown', 'u-panel', 'u-toc', 'u-toc-item', 'u-tree-view-new', 'u-tree-view-node-new', 'u-tree-select', 'u-tree-select-new', 'u-anchor', 'u-drawer', 'u-timeline', 'u-tabs'].includes(el.tag)) {
2071
- addEmpty = false;
2072
- }
2073
- const background = (emptySlot && emptySlot['empty-background']) || (hasSupport ? 'add-sub' : '');
2074
- addEmpty && parts.push(`vusion-empty-background="${background}"`);
2075
- }
2076
- }
2077
-
2078
- if (['u-router-view', 'van-router-view'].includes(el.tag)) {
2079
- const excludes = ['background-color:', 'background:', 'background-image:'];
2080
- if (excludes.some((key) => (el.staticStyle && el.staticStyle.includes(key)))) {
2081
- parts.push(':designer="false"');
2082
- }
2083
- }
2084
-
2085
- return parts;
2086
- },
2087
- });
2088
- }
2089
-
2090
- // 获取currentList
2091
- getCurrentList() {
2092
- const argsList: string[] = [];
2093
- let parent = this.parentNode;
2094
- let index = 0;
2095
- while (parent && parent.concept !== 'View') {
2096
- if ((parent as ViewElement).slotScope) {
2097
- argsList.push(index === 0 ? 'current' : 'current' + index);
2098
- index++;
2099
- }
2100
- parent = parent.parentNode;
2101
- }
2102
- return argsList;
2103
- }
2104
2066
 
2105
- get refName() {
2106
- let refName = this.name;
2107
- const list = this.getCurrentList();
2108
- if (Array.isArray(list) && list.length) {
2109
- list.forEach((item) => {
2110
- refName += `_\${(${item} || {}).__nodeKey || (${item} || {}).index}`;
2067
+ if (astNode.if) {
2068
+ element.addBindDirective(
2069
+ new BindDirective({
2070
+ type: 'dynamic',
2071
+ name: 'if',
2072
+ rawName: 'v-if',
2073
+ value: '',
2074
+ expression: <any>this._parseExpression(astNode.if),
2075
+ })
2076
+ );
2077
+ }
2078
+ } else if (astNode.type === 2) {
2079
+ const tagName = config.scope === 'h5' ? 'van-text' : 'u-text';
2080
+ const baseName = tagName.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
2081
+ element = new ViewElement({
2082
+ tag: tagName,
2083
+ name: view.getViewElementUniqueName(`${baseName}1`),
2084
+ });
2085
+ const value = astNode.text?.match(/{{(.*?)}}/)[1].trim();
2086
+ const expression = <any>this._parseExpression(value);
2087
+ element.addBindAttribute(
2088
+ new BindAttribute({
2089
+ type: 'dynamic',
2090
+ name: 'text',
2091
+ value: expression ? '' : value,
2092
+ expression,
2093
+ })
2094
+ );
2095
+ } else if (astNode.type === 3) {
2096
+ const tagName = config.scope === 'h5' ? 'van-text' : 'u-text';
2097
+ const baseName = tagName.replace(ViewElement.TAG_NAME_PREFIX_REG, '').replace(/-/g, '_');
2098
+ element = new ViewElement({
2099
+ tag: tagName,
2100
+ name: view.getViewElementUniqueName(`${baseName}1`),
2101
+ });
2102
+ element.addBindAttribute(
2103
+ new BindAttribute({
2104
+ name: 'text',
2105
+ type: 'string',
2106
+ value: astNode.text?.trim(),
2107
+ })
2108
+ );
2109
+ }
2110
+ return element;
2111
+ }
2112
+
2113
+ /**
2114
+ * 解析 Vue 模板
2115
+ * 该方法不会绑定 view 和 parent,如果是添加元素优先使用 fromHTML
2116
+ * @param html Vue 的模板
2117
+ * @TODO 处理多个元素的问题
2118
+ */
2119
+ public static parse(code: string, context?: ParseContext) {
2120
+ code = code || '<div></div>';
2121
+
2122
+ const compilerOptions: compiler.CompilerOptions = {
2123
+ preserveWhitespace: false,
2124
+ outputSourceRange: true,
2125
+ };
2126
+
2127
+ let { ast } = compiler.compile(code, compilerOptions);
2128
+ if (ast.tag === 'template' && !ast.slotTarget) ast = ast.children[0] as compiler.ASTElement;
2129
+ return this._fromASTNode(ast, {
2130
+ ...context,
2131
+ code,
2132
+ });
2133
+ }
2134
+
2135
+ /**
2136
+ * 从模板生成规范的 ViewElement 对象
2137
+ */
2138
+ public static fromHTML(html: string, context?: ParseContext) {
2139
+ return this.parse(html, context);
2140
+ }
2141
+
2142
+ /**
2143
+ * 转换成设计器中使用的 Vue 文件
2144
+ * @param options
2145
+ */
2146
+ toDesignerVue() {
2147
+ return this.toVue({
2148
+ finalCode: false,
2149
+ nodePathAttr: true,
2150
+ attrFormat: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => {
2151
+ if (attr.concept === 'BindAttribute' && !['href', 'destination', 'externalDestination', 'download'].includes(attr.name)) {
2152
+ const api = config?.allNodesAPI?.[element.tag];
2153
+ const apiOfAttr = api && api.attrs && api.attrs.find((_attr) => _attr.name === attr.name);
2154
+ if (['u-form-item', 'u-validator', 'van-field'].includes(element.tag) && attr.name === 'rules') {
2155
+ return `${attr.name}=""`;
2156
+ }
2157
+ if (apiOfAttr && apiOfAttr['designer-value'] !== undefined) {
2158
+ let designerValue = apiOfAttr['designer-value'];
2159
+ // 对流程模板拖拽进行特判
2160
+ element.bindAttrs.forEach((property) => {
2161
+ if (property.name === 'repeat' && property.value === '1') designerValue = '[{}, {}]';
2111
2162
  });
2112
- }
2113
- return refName;
2114
- }
2115
-
2116
- /**
2117
- * 转换成 Vue 的模板格式
2118
- */
2119
- toVue(options?: ElementToVueOptions) {
2120
- let currentList: string[] = [];
2121
- if (Array.isArray(options?.currentList)) {
2122
- currentList = [...options?.currentList];
2123
- }
2124
- if (this.slotScope) {
2125
- currentList.unshift(this.slotScope);
2126
- }
2127
-
2128
- const newOptions: ElementToVueOptions = Object.assign({
2129
- indentStyle: 'space',
2130
- tabSize: 4,
2131
- indentLevel: 0,
2132
- aslIdAttr: false,
2133
- nodePathAttr: false,
2134
- getExtraParts: () => [],
2135
- attrFormat: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => defaultResult,
2136
- bindStylesFormat: (bindStyles: BindStyle[], element?: ViewElement) => {
2137
- if (bindStyles.length === 0)
2138
- return false;
2139
-
2140
- return `:style="{${bindStyles
2141
- .map((item) => item.toVue())
2142
- .filter((item) => item !== undefined)
2143
- .join(', ')}}"`;
2144
- },
2145
- }, options, {
2146
- currentList,
2147
- });
2148
- const tabString = ' '.repeat(newOptions.tabSize * newOptions.indentLevel);
2149
- const insideTabString = ' '.repeat(newOptions.tabSize * (newOptions.indentLevel + 1));
2150
- let shouldIndent = true;
2151
- const content: string = !this.children ? '' : this.children
2152
- .map((element) => {
2153
- const childOptions = Object.assign({}, newOptions);
2154
- childOptions.indentLevel++;
2155
- return (shouldIndent ? '\n' + insideTabString : '') + element?.toVue(childOptions);
2156
- })
2157
- .join('');
2158
- if (!content.length) {
2159
- shouldIndent = false;
2160
- }
2161
- const parts: string[] = [];
2162
- if (newOptions.aslIdAttr) {
2163
- if (newOptions.aslIdAttr === true) {
2164
- newOptions.aslIdAttr = 'asl-id';
2163
+ if (typeof designerValue === 'string') {
2164
+ designerValue = designerValue.replace(/"/g, "'");
2165
2165
  }
2166
- parts.push(`${newOptions.aslIdAttr}="${this.id}"`);
2167
- }
2168
- if (newOptions.nodePathAttr) {
2169
- // 注入 asl 的 node-path
2170
- parts.push(`vusion-node-path="${this.nodePath}"`);
2171
- }
2172
- // 模板里解析时候,可能会有多级嵌套的 current,所以当前有多少的长度,当前就是多大的下标
2173
- this.slotTarget && parts.push(`#${this.slotTarget}` + (this.slotScope ? `="${currentList.length > 1 ? this.slotScope + (currentList.length - 1) : this.slotScope}"` : ''));
2174
- this.refName && parts.push(`:ref="\`${this.refName}\`"`);
2175
- this.staticClass && parts.push(`class="${this.staticClass}"`);
2176
- this.staticStyle && parts.push(`style="${this.staticStyle}"`);
2177
-
2178
- const vIfs: string[] = [];
2179
- [].concat(this.bindAttrs, this.bindDirectives, this.bindEvents).forEach((attr: BindAttribute | BindDirective | BindEvent) => {
2180
- const result = newOptions.attrFormat(attr, this, attr?.toVue(newOptions));
2181
-
2182
- // v-auth v-if 都翻译成 v-if
2183
- if (attr instanceof BindDirective && ['if', 'auth'].includes(attr.name) && result !== false) {
2184
- const expr = result.replace(/v-(if|auth)="(.*)"/, (match, p1, p2) => p2);
2185
- if (expr)
2186
- vIfs.push(attr.name === 'if' ? expr : `$auth.has(${expr})`);
2187
-
2188
- return;
2166
+ try {
2167
+ json5.parse(designerValue);
2168
+ return `:${attr.name}="${designerValue}"`;
2169
+ } catch (e) {
2170
+ return `${attr.name}="${designerValue}"`;
2189
2171
  }
2190
-
2191
- result && parts.push(result);
2192
- });
2193
-
2194
- if (vIfs.length === 2)
2195
- parts.push(`v-if="(${vIfs[0]}) && (${vIfs[1]})"`);
2196
- else if (vIfs.length === 1)
2197
- parts.push(`v-if="${vIfs[0]}"`);
2198
-
2199
- const bindStyles = newOptions.bindStylesFormat(this.bindStyles, this);
2200
- if (bindStyles)
2201
- parts.push(bindStyles);
2202
-
2203
- newOptions.getExtraParts(this).forEach((part) => parts.push(part));
2204
-
2205
- if (['u-modal', 'u-drawer'].includes(this.tag)) {
2206
- this.children.forEach((citem) => {
2207
- if (citem.tag === 'template' && !citem.children.length) {
2208
- parts.push(`:is-${citem.slotTarget}-slot-empty=true`);
2172
+ }
2173
+ if ((attr as BindAttribute).type === 'dynamic' && !(element.tag === 'u-cascade-select' && attr.name === 'categories'))
2174
+ return defaultResult.replace(/:?([\w-]+)(?:.*?)="([\s\S]*)"/, (m, name, value) => {
2175
+ try {
2176
+ const tempValue = json5.parse(value);
2177
+ if (typeof tempValue === 'boolean' || typeof tempValue === 'number') {
2178
+ // 简单类型走属性
2179
+ return `:${name}="${value.replace(/"/g, "'")}"`;
2209
2180
  }
2181
+ } catch (e) {
2182
+ if (apiOfAttr && !apiOfAttr.type.includes('string')) return '';
2183
+ }
2184
+ value = value
2185
+ .replace(/"/g, "'")
2186
+ .replace(/\$utils\['(.+?)'\]/g, '$1')
2187
+ .replace(/\$refs./g, 'elements.')
2188
+ .replace(/\$global.userInfo/g, 'nasl.auth.userInfo')
2189
+ .replace(/\$global./g, 'nasl.')
2190
+ .replace(/\bscope\.item\.\b/g, '')
2191
+ .replace(/\bcurrent\.item\.\b/g, '');
2192
+ return `${name}="{{ ${value} }}"`;
2210
2193
  });
2194
+ return defaultResult;
2211
2195
  }
2212
- // 部分组件增加 key 唯一标识,防止 vue 判断重复节点,导致渲染异常
2213
- if (this.name && ['u-table-view', 'u-list-view', 'u-grid-view', 'u-list-components', 'u-form', 'u-select'].includes(this.tag)) {
2214
- this.name && parts.push(`key="${this.name}"`);
2215
- }
2216
-
2217
- let partsLength = 0;
2218
- let partsString = '';
2219
- parts.forEach((part) => {
2220
- if (partsLength >= 120 || part.length >= 120) {
2221
- partsString += '\n' + tabString + ' '.repeat(3); // ' '.repeat(el.tag.length + 1);
2222
- partsLength = 0;
2196
+ return false;
2197
+ },
2198
+ bindStylesFormat: (bindStyles: BindStyle[], element?: ViewElement) => false,
2199
+ getExtraParts: (el: ViewElement) => {
2200
+ const parts = [];
2201
+
2202
+ const api = config.allNodesAPI[el.tag];
2203
+ const emptySlot = api && api.slots && api.slots.find((slot) => slot.name === 'default' && slot['empty-background']);
2204
+ const hasSupport = api && api.slots && api.slots.some((slot) => slot.support);
2205
+ if (emptySlot || hasSupport) {
2206
+ // 有些限制的组件如侧边栏分组有title插槽但要限制子元素放入
2207
+ const validChildren = el.children.filter((elem) => !(elem.tag === 'template' && elem.slotTarget !== 'default'));
2208
+ let childEmpty = !validChildren.length;
2209
+ const defaultSlot = el.children.find((elem) => elem.tag === 'template' && elem.slotTarget === 'default');
2210
+ if (defaultSlot) {
2211
+ childEmpty = !defaultSlot.children.length;
2212
+ }
2213
+ if (childEmpty) {
2214
+ let addEmpty = true;
2215
+ if (['u-grid-view', 'u-list-view', 'van-list-view', 'van-grid-view', 'u-carousel'].includes(el.tag)) {
2216
+ const hasDataSource = el.bindAttrs.find((attr) => attr.name === 'data-source');
2217
+ addEmpty = !hasDataSource;
2223
2218
  }
2224
- partsString += ' ' + part;
2225
- partsLength += part.length;
2226
- });
2227
- let htmlContent = `<${this.tag}${partsString.length ? partsString : ''}>` + content + (shouldIndent ? '\n' + tabString : '') + `</${this.tag}>`;
2228
- if (!content.trim() && selfClosingTag.includes(this.tag)) {
2229
- htmlContent = `<${this.tag}${partsString.length ? partsString : ''} />`;
2230
- }
2231
- return htmlContent;
2232
- }
2233
-
2234
- /**
2235
- * 从父级删除该节点
2236
- * @internal
2237
- */
2238
- delete() {
2239
- super.delete();
2240
- if (this.parentNode) {
2241
- this.traverseChildren((ele: ViewElement) => {
2242
- (this.view as any)?.removeExistingViewElement(ele);
2243
- });
2244
- }
2245
- }
2246
-
2247
- findElementByName(name: string): ViewElement {
2248
- return utils.traverse((current) => {
2249
- if (current.node.name === name)
2250
- return current.node;
2251
- }, { node: this });
2252
- }
2253
-
2254
- findElementByTag(tag: string): ViewElement {
2255
- return utils.traverse((current) => {
2256
- if (current.node.tag === tag)
2257
- return current.node;
2258
- }, { node: this });
2259
- }
2260
-
2261
- findElementByAttr(name: string, value: string): ViewElement {
2262
- return utils.traverse((current) => {
2263
- if (current.node.bindAttrs.some((attr) => attr.name === name && attr.value === value))
2264
- return current.node;
2265
- }, { node: this });
2266
- }
2267
-
2268
- @excludedInJSON()
2269
- computedStyle: object = {};
2270
- getCurrentName() {
2271
- let current = 'current';
2272
- let parent = this.parentNode;
2273
- let index = 0;
2274
- while (parent && parent.concept !== 'View') {
2275
- if ((parent as ViewElement).slotScope) {
2276
- index++;
2219
+ if (el.tag === 'u-crumb') {
2220
+ const attrList = el.bindAttrs;
2221
+ const hasAuto = attrList.some((attr) => attr.name === 'auto' && String(attr.value) === 'true');
2222
+ if (hasAuto) addEmpty = false;
2277
2223
  }
2278
- parent = parent.parentNode;
2224
+ if (
2225
+ [
2226
+ 'u-select',
2227
+ 'u-dropdown',
2228
+ 'u-panel',
2229
+ 'u-toc',
2230
+ 'u-toc-item',
2231
+ 'u-tree-view-new',
2232
+ 'u-tree-view-node-new',
2233
+ 'u-tree-select',
2234
+ 'u-tree-select-new',
2235
+ 'u-anchor',
2236
+ 'u-drawer',
2237
+ 'u-timeline',
2238
+ 'u-tabs',
2239
+ ].includes(el.tag)
2240
+ ) {
2241
+ addEmpty = false;
2242
+ }
2243
+ const background = (emptySlot && emptySlot['empty-background']) || (hasSupport ? 'add-sub' : '');
2244
+ addEmpty && parts.push(`vusion-empty-background="${background}"`);
2245
+ }
2279
2246
  }
2280
- current = (index === 0 ? 'current' : 'current' + index);
2281
- return current;
2282
- }
2283
2247
 
2284
- /**
2285
- * 计算约束样式
2286
- * @param positionData 位置数据
2287
- * @param doNotRecordLastWidthHeight 是否不记录上一次的宽高
2288
- */
2289
- computeConstraintStyle(positionData: {
2290
- nodeRect: DOMRect,
2291
- parentRect: DOMRect,
2292
- parentBorder: { top: number, right: number, bottom: number, left: number }
2293
- },
2294
- doNotRecordLastWidthHeight = false) {
2295
- const {nodeRect, parentRect, parentBorder} = positionData;
2296
- const staticWidth = nodeRect.width;
2297
- const staticHeight = nodeRect.height;
2298
- const staticLeft = nodeRect.x - parentRect.x - parentBorder.left;
2299
- const staticTop = nodeRect.y - parentRect.y - parentBorder.top;
2300
- const staticRight = (parentRect.width - nodeRect.width - staticLeft - parentBorder.right - parentBorder.left);
2301
- const staticBottom = (parentRect.height - nodeRect.height - staticTop - parentBorder.bottom - parentBorder.top);
2302
- const styleObj = this.parseStyleToObject(this.staticStyle);
2303
- const constraintX = styleObj['--constraint-x'] || 'left';
2304
- const constraintY = styleObj['--constraint-y'] || 'top';
2305
- const rawWidth = styleObj.width || '';
2306
- const rawHeight = styleObj.height || '';
2307
- let left = '';
2308
- let right = '';
2309
- let top = '';
2310
- let bottom = '';
2311
- let transform = '';
2312
- // 如果宽高被约束规则改成 auto 了,就还原为上次的宽高,防止用户设置的宽高信息在切换约束时候丢失
2313
- let width = Number(styleObj['--constraint-width-auto']) ? styleObj['--last-width'] : rawWidth;
2314
- let height = Number(styleObj['--constraint-height-auto']) ? styleObj['--last-height'] : rawHeight;
2315
- // 用于记录宽高是否被约束规则改成 auto 了
2316
- let constraintWidthAuto = 0;
2317
- let constraintHeightAuto = 0;
2318
-
2319
- const parentWidth = staticLeft + staticWidth + staticRight;
2320
- const parentHeight = staticTop + staticHeight + staticBottom;
2321
-
2322
- if (constraintX === 'left') {
2323
- left = staticLeft + 'px';
2324
- right = '';
2325
- } else if (constraintX === 'right') {
2326
- left = '';
2327
- right = staticRight + 'px';
2328
- } else if (constraintX === 'center') {
2329
- const offset = staticLeft + staticWidth / 2 - parentWidth / 2;
2330
- left = `calc(50% ${offset > 0 ? '+' : '-'} ${Math.abs(offset)}px)`;
2331
- right = '';
2332
- transform = 'translateX(-50%)';
2333
- } else if (constraintX === 'scale') {
2334
- left = staticLeft * 100 / parentWidth + '%';
2335
- right = '';
2336
- width = staticWidth * 100 / parentWidth + '%';
2337
- constraintWidthAuto = 1;
2338
- } else if (constraintX === 'left-right') {
2339
- left = staticLeft + 'px';
2340
- right = staticRight + 'px';
2341
- width = 'auto';
2342
- constraintWidthAuto = 1;
2248
+ if (['u-router-view', 'van-router-view'].includes(el.tag)) {
2249
+ const excludes = ['background-color:', 'background:', 'background-image:'];
2250
+ if (excludes.some((key) => el.staticStyle && el.staticStyle.includes(key))) {
2251
+ parts.push(':designer="false"');
2252
+ }
2343
2253
  }
2344
2254
 
2345
- if (constraintY === 'top') {
2346
- top = staticTop + 'px';
2347
- bottom = '';
2348
- } else if (constraintY === 'bottom') {
2349
- top = '';
2350
- bottom = staticBottom + 'px';
2351
- } else if (constraintY === 'center') {
2352
- const offset = staticTop + staticHeight / 2 - parentHeight / 2;
2353
- top = `calc(50% ${offset > 0 ? '+' : '-'} ${Math.abs(offset)}px)`;
2354
- bottom = '';
2355
- transform = transform ? 'translate(-50%, -50%)' : 'translateY(-50%)';
2356
- } else if (constraintY === 'scale') {
2357
- top = staticTop * 100 / parentHeight + '%';
2358
- bottom = '';
2359
- height = staticHeight * 100 / parentHeight + '%';
2360
- constraintHeightAuto = 1;
2361
- } else if (constraintY === 'top-bottom') {
2362
- top = staticTop + 'px';
2363
- bottom = staticBottom + 'px';
2364
- height = 'auto';
2365
- constraintHeightAuto = 1;
2255
+ return parts;
2256
+ },
2257
+ });
2258
+ }
2259
+
2260
+ // 获取currentList
2261
+ getCurrentList() {
2262
+ const argsList: string[] = [];
2263
+ let parent = this.parentNode;
2264
+ let index = 0;
2265
+ while (parent && parent.concept !== 'View') {
2266
+ if ((parent as ViewElement).slotScope) {
2267
+ argsList.push(index === 0 ? 'current' : `current${index}`);
2268
+ index++;
2269
+ }
2270
+ parent = parent.parentNode;
2271
+ }
2272
+ return argsList;
2273
+ }
2274
+
2275
+ get refName() {
2276
+ let refName = this.name;
2277
+ const list = this.getCurrentList();
2278
+ if (Array.isArray(list) && list.length) {
2279
+ list.forEach((item) => {
2280
+ refName += `_\${(${item} || {}).__nodeKey || (${item} || {}).index}`;
2281
+ });
2282
+ }
2283
+ return refName;
2284
+ }
2285
+
2286
+ /**
2287
+ * 转换成 Vue 的模板格式
2288
+ */
2289
+ toVue(options?: ElementToVueOptions) {
2290
+ let currentList: string[] = [];
2291
+ if (Array.isArray(options?.currentList)) {
2292
+ currentList = [...options?.currentList];
2293
+ }
2294
+ if (this.slotScope) {
2295
+ currentList.unshift(this.slotScope);
2296
+ }
2297
+
2298
+ const newOptions: ElementToVueOptions = {
2299
+ indentStyle: 'space',
2300
+ tabSize: 4,
2301
+ indentLevel: 0,
2302
+ aslIdAttr: false,
2303
+ nodePathAttr: false,
2304
+ getExtraParts: () => [],
2305
+ attrFormat: (attr: BindAttribute | BindEvent | BindDirective, element?: ViewElement, defaultResult?: string) => defaultResult,
2306
+ bindStylesFormat: (bindStyles: BindStyle[], element?: ViewElement) => {
2307
+ if (bindStyles.length === 0) return false;
2308
+
2309
+ return `:style="{${bindStyles
2310
+ .map((item) => item.toVue())
2311
+ .filter((item) => item !== undefined)
2312
+ .join(', ')}}"`;
2313
+ },
2314
+ ...options,
2315
+ currentList,
2316
+ };
2317
+ const tabString = ' '.repeat(newOptions.tabSize * newOptions.indentLevel);
2318
+ const insideTabString = ' '.repeat(newOptions.tabSize * (newOptions.indentLevel + 1));
2319
+ let shouldIndent = true;
2320
+ const content: string = !this.children
2321
+ ? ''
2322
+ : this.children
2323
+ .map((element) => {
2324
+ const childOptions = { ...newOptions };
2325
+ childOptions.indentLevel++;
2326
+ return (shouldIndent ? `\n${insideTabString}` : '') + element?.toVue(childOptions);
2327
+ })
2328
+ .join('');
2329
+ if (!content.length) {
2330
+ shouldIndent = false;
2331
+ }
2332
+ const parts: string[] = [];
2333
+ if (newOptions.aslIdAttr) {
2334
+ if (newOptions.aslIdAttr === true) {
2335
+ newOptions.aslIdAttr = 'asl-id';
2336
+ }
2337
+ parts.push(`${newOptions.aslIdAttr}="${this.id}"`);
2338
+ }
2339
+ if (newOptions.nodePathAttr) {
2340
+ // 注入 asl 的 node-path
2341
+ parts.push(`vusion-node-path="${this.nodePath}"`);
2342
+ }
2343
+ // 模板里解析时候,可能会有多级嵌套的 current,所以当前有多少的长度,当前就是多大的下标
2344
+ this.slotTarget &&
2345
+ parts.push(
2346
+ `#${this.slotTarget}${this.slotScope ? `="${currentList.length > 1 ? this.slotScope + (currentList.length - 1) : this.slotScope}"` : ''}`
2347
+ );
2348
+ this.refName && parts.push(`:ref="\`${this.refName}\`"`);
2349
+ this.staticClass && parts.push(`class="${this.staticClass}"`);
2350
+ this.staticStyle && parts.push(`style="${this.staticStyle}"`);
2351
+
2352
+ const vIfs: string[] = [];
2353
+ [].concat(this.bindAttrs, this.bindDirectives, this.bindEvents).forEach((attr: BindAttribute | BindDirective | BindEvent) => {
2354
+ const result = newOptions.attrFormat(attr, this, attr?.toVue(newOptions));
2355
+
2356
+ // v-auth v-if 都翻译成 v-if
2357
+ if (attr instanceof BindDirective && ['if', 'auth'].includes(attr.name) && result !== false) {
2358
+ const expr = result.replace(/v-(if|auth)="(.*)"/, (match, p1, p2) => p2);
2359
+ if (expr) vIfs.push(attr.name === 'if' ? expr : `$auth.has(${expr})`);
2360
+
2361
+ return;
2362
+ }
2363
+
2364
+ result && parts.push(result);
2365
+ });
2366
+
2367
+ if (vIfs.length === 2) parts.push(`v-if="(${vIfs[0]}) && (${vIfs[1]})"`);
2368
+ else if (vIfs.length === 1) parts.push(`v-if="${vIfs[0]}"`);
2369
+
2370
+ const bindStyles = newOptions.bindStylesFormat(this.bindStyles, this);
2371
+ if (bindStyles) parts.push(bindStyles);
2372
+
2373
+ newOptions.getExtraParts(this).forEach((part) => parts.push(part));
2374
+
2375
+ if (['u-modal', 'u-drawer'].includes(this.tag)) {
2376
+ this.children.forEach((citem) => {
2377
+ if (citem.tag === 'template' && !citem.children.length) {
2378
+ parts.push(`:is-${citem.slotTarget}-slot-empty=true`);
2366
2379
  }
2367
- const newStyleObj: Record<string, any> = {
2368
- ...styleObj,
2369
- left,
2370
- right,
2371
- top,
2372
- bottom,
2373
- transform,
2374
- width,
2375
- height,
2376
- '--constraint-width-auto': constraintWidthAuto,
2377
- '--constraint-height-auto': constraintHeightAuto,
2378
- // 如果上次已经是 auto 了,就用上上次的宽高
2379
- '--last-width': rawWidth === 'auto' ? styleObj['--last-width'] : rawWidth,
2380
- '--last-height': rawHeight === 'auto' ? styleObj['--last-height'] : rawHeight,
2381
- };
2382
- if(!doNotRecordLastWidthHeight){
2383
- if(rawWidth !== 'auto'){
2384
- newStyleObj['--last-width'] = rawWidth;
2385
- }
2386
- if(rawHeight !== 'auto'){
2387
- newStyleObj['--last-height'] = rawHeight;
2388
- }
2389
- }
2390
- const newStaticStyle = this.stringifyStyleAttr(newStyleObj);
2391
- this.update({
2392
- staticStyle: newStaticStyle,
2393
- });
2394
- }
2395
- updateStyleObj(styleObj: Record<string, string | number>) {
2396
- this.setStaticStyle(this.stringifyStyleAttr({
2397
- ...this.parseStyleToObject(this.staticStyle),
2398
- ...styleObj,
2399
- }));
2400
- }
2401
- parseStyleToObject(styleStr: string = '') {
2402
- const styleObj = styleStr.split(/;/gim).reduce((obj:Record<string, string | number>, item) => {
2403
- // background-image:url(http://www...)
2404
- item = item.trim();
2405
- const pos = item.indexOf(':');
2406
- if (pos >= 0) {
2407
- const key = item.slice(0, pos).trim();
2408
- const value = item.slice(pos + 1).trim();
2409
- obj[key] = value;
2410
- }
2411
- return obj;
2412
- }, {});
2413
- return styleObj;
2414
- }
2415
- stringifyStyleAttr(styleObj: Record<string, string | number>) {
2416
- return Object.keys(styleObj)
2417
- .map((key) => `${key}:${String(styleObj[key]).trim()};`)
2418
- .join('');
2419
- }
2420
- // 批量更新绑定属性
2421
- batchUpdateBindAttrs(attrOptions: Record<string, any>[]) {
2422
- const oldBindAttrs = this.bindAttrs.filter(it => !attrOptions.some(item => item.name === it.name));
2423
- const newBindAttrs = attrOptions.map(it => BindAttribute.from(it, this, 'bindAttrs'));
2424
- this.update({
2425
- bindAttrs: [...oldBindAttrs, ...newBindAttrs],
2426
- });
2427
- }
2428
- //================================================================================
2429
- // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
2430
- // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
2431
- //================================================================================
2380
+ });
2381
+ }
2382
+ // 部分组件增加 key 唯一标识,防止 vue 判断重复节点,导致渲染异常
2383
+ if (this.name && ['u-table-view', 'u-list-view', 'u-grid-view', 'u-list-components', 'u-form', 'u-select'].includes(this.tag)) {
2384
+ this.name && parts.push(`key="${this.name}"`);
2385
+ }
2386
+
2387
+ let partsLength = 0;
2388
+ let partsString = '';
2389
+ parts.forEach((part) => {
2390
+ if (partsLength >= 120 || part.length >= 120) {
2391
+ partsString += `\n${tabString}${' '.repeat(3)}`; // ' '.repeat(el.tag.length + 1);
2392
+ partsLength = 0;
2393
+ }
2394
+ partsString += ` ${part}`;
2395
+ partsLength += part.length;
2396
+ });
2397
+ let htmlContent = `<${this.tag}${partsString.length ? partsString : ''}>${content}${shouldIndent ? `\n${tabString}` : ''}</${this.tag}>`;
2398
+ if (!content.trim() && selfClosingTag.includes(this.tag)) {
2399
+ htmlContent = `<${this.tag}${partsString.length ? partsString : ''} />`;
2400
+ }
2401
+ return htmlContent;
2402
+ }
2403
+
2404
+ /**
2405
+ * 从父级删除该节点
2406
+ * @internal
2407
+ */
2408
+ delete() {
2409
+ super.delete();
2410
+ if (this.parentNode) {
2411
+ this.traverseChildren((ele: ViewElement) => {
2412
+ (this.view as any)?.removeExistingViewElement(ele);
2413
+ });
2414
+ }
2415
+ }
2416
+
2417
+ findElementByName(name: string): ViewElement {
2418
+ return utils.traverse(
2419
+ (current) => {
2420
+ if (current.node.name === name) return current.node;
2421
+ },
2422
+ { node: this }
2423
+ );
2424
+ }
2425
+
2426
+ findElementByTag(tag: string): ViewElement {
2427
+ return utils.traverse(
2428
+ (current) => {
2429
+ if (current.node.tag === tag) return current.node;
2430
+ },
2431
+ { node: this }
2432
+ );
2433
+ }
2434
+
2435
+ findElementByAttr(name: string, value: string): ViewElement {
2436
+ return utils.traverse(
2437
+ (current) => {
2438
+ if (current.node.bindAttrs.some((attr) => attr.name === name && attr.value === value)) return current.node;
2439
+ },
2440
+ { node: this }
2441
+ );
2442
+ }
2443
+
2444
+ @excludedInJSON()
2445
+ computedStyle: object = {};
2446
+
2447
+ getCurrentName() {
2448
+ let current = 'current';
2449
+ let parent = this.parentNode;
2450
+ let index = 0;
2451
+ while (parent && parent.concept !== 'View') {
2452
+ if ((parent as ViewElement).slotScope) {
2453
+ index++;
2454
+ }
2455
+ parent = parent.parentNode;
2456
+ }
2457
+ current = index === 0 ? 'current' : `current${index}`;
2458
+ return current;
2459
+ }
2460
+
2461
+ /**
2462
+ * 计算约束样式
2463
+ * @param positionData 位置数据
2464
+ * @param doNotRecordLastWidthHeight 是否不记录上一次的宽高
2465
+ */
2466
+ computeConstraintStyle(
2467
+ positionData: {
2468
+ nodeRect: DOMRect;
2469
+ parentRect: DOMRect;
2470
+ parentBorder: { top: number; right: number; bottom: number; left: number };
2471
+ },
2472
+ ops: {
2473
+ doNotRecordLastWidthHeight?: boolean;
2474
+ beforeSetStyleCb?: (newStyleObj: Record<string, any>) => void;
2475
+ } = {}
2476
+ ) {
2477
+ const { nodeRect, parentRect, parentBorder } = positionData;
2478
+ const staticWidth = nodeRect.width;
2479
+ const staticHeight = nodeRect.height;
2480
+ const staticLeft = nodeRect.left - parentRect.left - parentBorder.left;
2481
+ const staticTop = nodeRect.top - parentRect.top - parentBorder.top;
2482
+ const staticRight = parentRect.width - nodeRect.width - staticLeft - parentBorder.right - parentBorder.left;
2483
+ const staticBottom = parentRect.height - nodeRect.height - staticTop - parentBorder.bottom - parentBorder.top;
2484
+ const styleObj = this.parseStyleToObject(this.staticStyle);
2485
+ const constraintX = styleObj['--constraint-x'] || 'left';
2486
+ const constraintY = styleObj['--constraint-y'] || 'top';
2487
+ const rawWidth = styleObj.width || '';
2488
+ const rawHeight = styleObj.height || '';
2489
+ let left = '';
2490
+ let right = '';
2491
+ let top = '';
2492
+ let bottom = '';
2493
+ let transform = '';
2494
+ // 如果宽高被约束规则改成 auto 了,就还原为上次的宽高,防止用户设置的宽高信息在切换约束时候丢失
2495
+ let width = Number(styleObj['--constraint-width-auto']) ? styleObj['--last-width'] : rawWidth;
2496
+ let height = Number(styleObj['--constraint-height-auto']) ? styleObj['--last-height'] : rawHeight;
2497
+ // 用于记录宽高是否被约束规则改成 auto 了
2498
+ let constraintWidthAuto = 0;
2499
+ let constraintHeightAuto = 0;
2500
+
2501
+ const parentWidth = staticLeft + staticWidth + staticRight;
2502
+ const parentHeight = staticTop + staticHeight + staticBottom;
2503
+
2504
+ if (constraintX === 'left') {
2505
+ left = `${staticLeft}px`;
2506
+ right = '';
2507
+ } else if (constraintX === 'right') {
2508
+ left = '';
2509
+ right = `${staticRight}px`;
2510
+ } else if (constraintX === 'center') {
2511
+ const offset = staticLeft + staticWidth / 2 - parentWidth / 2;
2512
+ left = `calc(50% ${offset > 0 ? '+' : '-'} ${Math.abs(offset)}px)`;
2513
+ right = '';
2514
+ transform = 'translateX(-50%)';
2515
+ } else if (constraintX === 'scale') {
2516
+ left = `${(staticLeft * 100) / parentWidth}%`;
2517
+ right = '';
2518
+ width = `${(staticWidth * 100) / parentWidth}%`;
2519
+ constraintWidthAuto = 1;
2520
+ } else if (constraintX === 'left-right') {
2521
+ left = `${staticLeft}px`;
2522
+ right = `${staticRight}px`;
2523
+ width = 'auto';
2524
+ constraintWidthAuto = 1;
2525
+ }
2526
+
2527
+ if (constraintY === 'top') {
2528
+ top = `${staticTop}px`;
2529
+ bottom = '';
2530
+ } else if (constraintY === 'bottom') {
2531
+ top = '';
2532
+ bottom = `${staticBottom}px`;
2533
+ } else if (constraintY === 'center') {
2534
+ const offset = staticTop + staticHeight / 2 - parentHeight / 2;
2535
+ top = `calc(50% ${offset > 0 ? '+' : '-'} ${Math.abs(offset)}px)`;
2536
+ bottom = '';
2537
+ transform = transform ? 'translate(-50%, -50%)' : 'translateY(-50%)';
2538
+ } else if (constraintY === 'scale') {
2539
+ top = `${(staticTop * 100) / parentHeight}%`;
2540
+ bottom = '';
2541
+ height = `${(staticHeight * 100) / parentHeight}%`;
2542
+ constraintHeightAuto = 1;
2543
+ } else if (constraintY === 'top-bottom') {
2544
+ top = `${staticTop}px`;
2545
+ bottom = `${staticBottom}px`;
2546
+ height = 'auto';
2547
+ constraintHeightAuto = 1;
2548
+ }
2549
+ const newStyleObj: Record<string, any> = {
2550
+ ...styleObj,
2551
+ left,
2552
+ right,
2553
+ top,
2554
+ bottom,
2555
+ transform,
2556
+ width,
2557
+ height,
2558
+ '--constraint-width-auto': constraintWidthAuto,
2559
+ '--constraint-height-auto': constraintHeightAuto,
2560
+ };
2561
+ if (!ops.doNotRecordLastWidthHeight) {
2562
+ if (rawWidth !== 'auto') {
2563
+ newStyleObj['--last-width'] = rawWidth;
2564
+ }
2565
+ if (rawHeight !== 'auto') {
2566
+ newStyleObj['--last-height'] = rawHeight;
2567
+ }
2568
+ }
2569
+ ops.beforeSetStyleCb?.(newStyleObj);
2570
+ const newStaticStyle = this.stringifyStyleAttr(newStyleObj);
2571
+ this.setStaticStyle(newStaticStyle);
2572
+ }
2573
+
2574
+ updateStyleObj(styleObj: Record<string, string | number>) {
2575
+ this.setStaticStyle(
2576
+ this.stringifyStyleAttr({
2577
+ ...this.parseStyleToObject(this.staticStyle),
2578
+ ...styleObj,
2579
+ })
2580
+ );
2581
+ }
2582
+
2583
+ parseStyleToObject(styleStr: string = '') {
2584
+ const styleObj = styleStr.split(/;/gim).reduce((obj: Record<string, string | number>, item) => {
2585
+ // background-image:url(http://www...)
2586
+ item = item.trim();
2587
+ const pos = item.indexOf(':');
2588
+ if (pos >= 0) {
2589
+ const key = item.slice(0, pos).trim();
2590
+ const value = item.slice(pos + 1).trim();
2591
+ obj[key] = value;
2592
+ }
2593
+ return obj;
2594
+ }, {});
2595
+ return styleObj;
2596
+ }
2597
+
2598
+ stringifyStyleAttr(styleObj: Record<string, string | number>) {
2599
+ return (
2600
+ Object.keys(styleObj)
2601
+ // 空字符串是允许的,因为有时候想要覆盖之前的样式。undefined 则不允许
2602
+ .filter((key) => styleObj[key] !== undefined)
2603
+ .map((key) => `${key}:${String(styleObj[key]).trim()};`)
2604
+ .join('')
2605
+ );
2606
+ }
2607
+
2608
+ // 批量更新绑定属性
2609
+ batchUpdateBindAttrs(attrOptions: Record<string, any>[]) {
2610
+ const oldBindAttrs = this.bindAttrs.filter((it) => !attrOptions.some((item) => item.name === it.name));
2611
+ const newBindAttrs = attrOptions.map((it) => BindAttribute.from(it, this, 'bindAttrs'));
2612
+ this.update({
2613
+ bindAttrs: [...oldBindAttrs, ...newBindAttrs],
2614
+ });
2615
+ }
2616
+ //= ===============================================================================
2617
+ // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
2618
+ // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
2619
+ //= ===============================================================================
2432
2620
  }
2433
2621
 
2434
2622
  classMap.ViewElement = ViewElement;
2435
2623
  export default ViewElement;
2436
- //================================================================================
2624
+ //= ===============================================================================
2437
2625
  // ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
2438
2626
  // 自动生成的代码已结束。下面可以手动编写。
2439
- //================================================================================
2627
+ //= ===============================================================================