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