@@ -3,15 +3,23 @@ import type {
33 BrickEventHandler ,
44 BrickEventsMap ,
55 BuiltinBrickEventHandler ,
6- RouteConf ,
76 RouteConfOfBricks ,
87 RuntimeStoryboard ,
8+ Storyboard ,
99} from "@next-core/types" ;
1010import { isEvaluable } from "@next-core/cook" ;
11+ import { hasOwnProperty } from "@next-core/utils/general" ;
12+ import {
13+ parseStoryboard ,
14+ traverse ,
15+ parseEvents ,
16+ type StoryboardNodeEvent ,
17+ type StoryboardNodeRoute ,
18+ } from "@next-core/utils/storyboard" ;
1119import { uniqueId } from "lodash" ;
1220import { hooks } from "./Runtime.js" ;
1321import { registerAppI18n } from "./registerAppI18n.js" ;
14- import { isBuiltinHandler } from "./bindListeners.js" ;
22+ import { isBuiltinHandler , isCustomHandler } from "./bindListeners.js" ;
1523
1624export async function fulfilStoryboard ( storyboard : RuntimeStoryboard ) {
1725 if ( storyboard . $$fulfilled ) {
@@ -26,70 +34,58 @@ export async function fulfilStoryboard(storyboard: RuntimeStoryboard) {
2634async function doFulfilStoryboard ( storyboard : RuntimeStoryboard ) {
2735 await hooks ?. fulfilStoryboard ?.( storyboard ) ;
2836 registerAppI18n ( storyboard ) ;
29- initializeSeguesForRoutes ( storyboard . routes ) ;
37+ // initializeSeguesForRoutes(storyboard.routes);
38+ initializeSegues ( storyboard ) ;
3039 Object . assign ( storyboard , {
3140 $$fulfilled : true ,
3241 $$fulfilling : null ,
3342 } ) ;
3443}
3544
45+ type SceneConf = Pick < BrickConf , "properties" | "events" > ;
46+
3647interface SegueConf {
37- by : "drawer" | "modal" ;
48+ type : "drawer" | "modal" ;
3849 route ?: {
3950 path : string ;
40- params : SegueRouteParam [ ] ;
51+ params : Record < string , string > ;
4152 } ;
42- eventsMapping ?: Record < string , string > ;
43- events ?: BrickEventsMap ;
44- }
45-
46- interface SegueRouteParam {
47- key : string ;
48- value : string ;
53+ modal ?: SceneConf ;
54+ scene ?: SceneConf ;
4955}
5056
51- function initializeSeguesForRoutes ( routes : RouteConf [ ] ) {
52- for ( const route of routes ) {
53- if ( route . type !== "redirect" && route . type !== "routes" ) {
54- initializeSeguesForBricks ( route . bricks , route ) ;
55- }
56- }
57- }
57+ function initializeSegues ( storyboard : Storyboard ) {
58+ const ast = parseStoryboard ( storyboard ) ;
5859
59- function initializeSeguesForBricks (
60- bricks : BrickConf [ ] ,
61- routeParent : RouteConfOfBricks
62- ) {
63- for ( const brick of bricks ) {
64- if ( brick . events ) {
65- for ( const [ eventType , handlers ] of Object . entries ( brick . events ) ) {
66- if ( Array . isArray ( handlers ) ) {
67- handlers . forEach ( ( handler , index ) => {
68- if ( isBuiltinHandler ( handler ) && handler . action === "segue.go" ) {
69- replaceSegues ( handler , handlers , index , routeParent ) ;
70- }
71- } ) ;
72- } else if (
73- isBuiltinHandler ( handlers ) &&
74- handlers . action === "segue.go"
75- ) {
76- replaceSegues ( handlers , brick . events , eventType , routeParent ) ;
60+ traverse ( ast , ( node , nodePath ) => {
61+ switch ( node . type ) {
62+ case "EventHandler" :
63+ if ( isBuiltinHandler ( node . raw ) && node . raw . action === "segue.go" ) {
64+ const parent = nodePath [ nodePath . length - 1 ] as StoryboardNodeEvent ;
65+ const routeParent = (
66+ nodePath . findLast (
67+ ( node ) => node . type === "Route" && node . raw . type === "bricks"
68+ ) as StoryboardNodeRoute
69+ ) . raw as RouteConfOfBricks ;
70+ if ( typeof node . rawKey === "number" ) {
71+ replaceSegues (
72+ node . raw ,
73+ parent . rawContainer [ parent . rawKey ] as BrickEventHandler [ ] ,
74+ node . rawKey ,
75+ routeParent
76+ ) ;
77+ } else {
78+ replaceSegues (
79+ node . raw ,
80+ parent . rawContainer ,
81+ parent . rawKey ,
82+ routeParent
83+ ) ;
84+ }
7785 }
78- }
79- }
80-
81- if ( brick . slots ) {
82- for ( const slotConf of Object . values ( brick . slots ) ) {
83- if ( slotConf . type === "routes" ) {
84- initializeSeguesForRoutes ( slotConf . routes ) ;
85- } else {
86- initializeSeguesForBricks ( slotConf . bricks , routeParent ) ;
87- }
88- }
89- } else if ( Array . isArray ( brick . children ) ) {
90- initializeSeguesForBricks ( brick . children , routeParent ) ;
86+ break ;
9187 }
92- }
88+ } ) ;
9389}
9490
9591function replaceSegues (
@@ -106,17 +102,18 @@ function replaceSegues(
106102 typeof segueTarget === "string" ) &&
107103 ( segueConf = handler . args [ 1 ] as SegueConf )
108104 ) {
109- switch ( segueConf . by ) {
105+ switch ( segueConf . type ) {
110106 case "drawer" : {
111107 if ( segueConf . route ) {
112108 const { params, path } = segueConf . route ;
113- const targetUrlExpr = path . replace ( / : ( \w + ) / g, ( _ , key ) => {
114- const param = params . find ( ( param ) => param . key === key ) ;
115- return param
116- ? typeof param . value === "string" && isEvaluable ( param . value )
117- ? `\${${ param . value . replace ( / ^ \s * < % [ ~ = ] ? \s | \s % > \s * $ / g, "" ) } }`
118- : String ( param . value ) . replace ( / [ ` \\ ] / g, "\\$&" )
119- : `\${PATH.${ key } }` ;
109+ const targetUrlExpr = path . replace ( / : ( \w + ) / g, ( _ , k ) => {
110+ const hasParam = hasOwnProperty ( params , k ) ;
111+ const paramValue = hasParam ? params [ k ] : undefined ;
112+ return hasParam
113+ ? typeof paramValue === "string" && isEvaluable ( paramValue )
114+ ? `\${${ paramValue . replace ( / ^ \s * < % [ ~ = ] ? \s | \s % > \s * $ / g, "" ) } }`
115+ : String ( paramValue ) . replace ( / [ ` \\ ] / g, "\\$&" )
116+ : `\${PATH.${ k } }` ;
120117 } ) ;
121118 ( handlers as BrickEventsMap ) [ key ] = {
122119 action : "history.push" ,
@@ -126,6 +123,7 @@ function replaceSegues(
126123 const drawerTarget = `#${ drawerId } ` ;
127124 routeParent . bricks . push ( {
128125 brick : "eo-drawer" ,
126+ iid : drawerId ,
129127 portal : true ,
130128 properties : {
131129 id : drawerId ,
@@ -150,10 +148,7 @@ function replaceSegues(
150148 {
151149 brick : segueTarget ,
152150 properties : Object . fromEntries (
153- params . map ( ( param ) => [
154- param . key ,
155- `<% PATH.${ param . key } %>` ,
156- ] )
151+ Object . keys ( params ) . map ( ( k ) => [ k , `<% PATH.${ k } %>` ] )
157152 ) ,
158153 lifeCycle : {
159154 onMount : {
@@ -185,32 +180,33 @@ function replaceSegues(
185180 target : modalTarget ,
186181 method : "open" ,
187182 } ;
183+
184+ const replacements = new Map < string , string > ( [
185+ [ "_modal" , modalTarget ] ,
186+ [ "_scene" , sceneTarget ] ,
187+ ] ) ;
188+ replaceSceneTarget ( segueConf . modal ?. events , replacements ) ;
189+ replaceSceneTarget ( segueConf . scene ?. events , replacements ) ;
190+
188191 routeParent . bricks . push ( {
189192 brick : "eo-modal" ,
193+ iid : modalId ,
190194 portal : true ,
191195 properties : {
192- id : modalId ,
193- modalTitle : "Create" ,
194196 closeWhenConfirm : false ,
197+ ...segueConf . modal ?. properties ,
198+ id : modalId ,
195199 } ,
196- events : segueConf . eventsMapping
197- ? Object . fromEntries (
198- Object . entries ( segueConf . eventsMapping ) . map ( ( [ from , to ] ) => [
199- from ,
200- {
201- target : sceneTarget ,
202- method : to ,
203- } ,
204- ] )
205- )
206- : undefined ,
200+ events : segueConf . modal ?. events ,
207201 children : [
208202 {
209203 brick : segueTarget ,
204+ iid : sceneId ,
210205 properties : {
206+ ...segueConf . scene ?. properties ,
211207 id : sceneId ,
212208 } ,
213- events : segueConf . events ,
209+ events : segueConf . scene ?. events ,
214210 } ,
215211 ] ,
216212 } ) ;
@@ -219,3 +215,22 @@ function replaceSegues(
219215 }
220216 }
221217}
218+
219+ function replaceSceneTarget (
220+ events : BrickEventsMap | undefined ,
221+ replacements : Map < string , string >
222+ ) {
223+ const ast = parseEvents ( events ) ;
224+
225+ traverse ( ast , ( node ) => {
226+ switch ( node . type ) {
227+ case "EventHandler" :
228+ if ( isCustomHandler ( node . raw ) && typeof node . raw . target === "string" ) {
229+ const replacement = replacements . get ( node . raw . target ) ;
230+ if ( replacement !== undefined ) {
231+ node . raw . target = replacement ;
232+ }
233+ }
234+ }
235+ } ) ;
236+ }
0 commit comments