@@ -34,12 +34,30 @@ final class LifecycleEventsListener extends LoadedWebViewExtension
3434 */
3535 private const string WEBVIEW_HANDLER_STRUCT = <<<'CDATA'
3636 struct {
37- void (*onDomReady)(const saucer_handle *);
38- void (*onNavigated)(const saucer_handle *, const char *);
39- SAUCER_POLICY (*onNavigating)(const saucer_handle *, const saucer_navigation *);
40- void (*onFaviconChanged)(const saucer_handle *, const saucer_icon *);
41- void (*onTitleChanged)(const saucer_handle *, const char *);
42- void (*onLoad)(const saucer_handle *, const SAUCER_STATE *);
37+ // TODO Add permissions event
38+ // TODO Add fullscreen event
39+
40+ // saucer_webview_event_dom_ready
41+ void (*onDomReady)(const saucer_webview *, void *);
42+
43+ // saucer_webview_event_navigated
44+ // TODO Add saucer_url support
45+ void (*onNavigated)(const saucer_webview *, saucer_url *, void *);
46+
47+ // saucer_webview_event_navigate
48+ SAUCER_POLICY (*onNavigating)(const saucer_webview *, const saucer_navigation *, void *);
49+
50+ // saucer_webview_event_favicon
51+ void (*onFaviconChanged)(const saucer_webview *, saucer_icon *, void *);
52+
53+ // saucer_webview_event_title
54+ void (*onTitleChanged)(const saucer_webview *, const char *, size_t, void *);
55+
56+ // saucer_webview_event_load
57+ void (*onLoad)(const saucer_webview *, SAUCER_STATE, void *);
58+
59+ // saucer_webview_event_message
60+ void (*onMessage)(const saucer_webview *, const char *, size_t, void *);
4361 }
4462 CDATA;
4563
@@ -80,6 +98,7 @@ private function createEventHandlers(): CData
8098 $ struct ->onFaviconChanged = $ this ->onSafeFaviconChanged (...);
8199 $ struct ->onTitleChanged = $ this ->onSafeTitleChanged (...);
82100 $ struct ->onLoad = $ this ->onSafeLoad (...);
101+ $ struct ->onMessage = $ this ->onSafeMessageReceived (...);
83102
84103 return $ struct ;
85104 }
@@ -89,16 +108,15 @@ private function listenEvents(): void
89108 /** @phpstan-var CSaucerWebViewEventsStruct $ctx */
90109 $ ctx = $ this ->handlers ;
91110
92- $ ptr = $ this ->webview ->window -> id ->ptr ;
111+ $ ptr = $ this ->webview ->id ->ptr ;
93112
94- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_DOM_READY , $ ctx ->onDomReady );
95- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_NAVIGATED , $ ctx ->onNavigated );
96- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_NAVIGATE , $ ctx ->onNavigating );
97- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_FAVICON , $ ctx ->onFaviconChanged );
98- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_TITLE , $ ctx ->onTitleChanged );
99- $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_LOAD , $ ctx ->onLoad );
100-
101- $ this ->app ->saucer ->saucer_webview_on_message ($ ptr , $ this ->onSafeMessageReceived (...));
113+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_DOM_READY , $ ctx ->onDomReady , false , null );
114+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_NAVIGATED , $ ctx ->onNavigated , false , null );
115+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_NAVIGATE , $ ctx ->onNavigating , false , null );
116+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_FAVICON , $ ctx ->onFaviconChanged , false , null );
117+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_TITLE , $ ctx ->onTitleChanged , false , null );
118+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_LOAD , $ ctx ->onLoad , false , null );
119+ $ this ->app ->saucer ->saucer_webview_on ($ ptr , Event::SAUCER_WEBVIEW_EVENT_MESSAGE , $ ctx ->onLoad , false , null );
102120 }
103121
104122 private function onMessageReceived (string $ message ): bool
@@ -111,7 +129,7 @@ private function onMessageReceived(string $message): bool
111129 return $ event ->isPropagationStopped ;
112130 }
113131
114- private function onSafeMessageReceived (string $ message ): bool
132+ private function onSafeMessageReceived (CData $ _ , string $ message, int $ size ): bool
115133 {
116134 try {
117135 return $ this ->onMessageReceived ($ message );
@@ -140,19 +158,19 @@ private function onSafeDomReady(CData $_): void
140158 }
141159 }
142160
143- private function onNavigated (CData $ _ , string $ url ): void
161+ private function onNavigated (CData $ _ , CData $ url ): void
144162 {
145163 try {
146164 $ this ->dispatch (new WebViewNavigated (
147165 subject: $ this ->webview ,
148- url: Request::castUrl ($ url ),
166+ url: Request::castUrl ($ this -> urlToString ( $ url) ),
149167 ));
150168 } catch (\Throwable $ e ) {
151169 $ this ->webview ->window ->app ->poller ->throw ($ e );
152170 }
153171 }
154172
155- private function onSafeNavigated (CData $ _ , string $ url ): void
173+ private function onSafeNavigated (CData $ _ , CData $ url ): void
156174 {
157175 try {
158176 $ this ->onNavigated ($ _ , $ url );
@@ -161,25 +179,37 @@ private function onSafeNavigated(CData $_, string $url): void
161179 }
162180 }
163181
182+ private function urlToString (CData $ url ): string
183+ {
184+ $ value = $ this ->app ->saucer ->new ('char ' );
185+ $ size = $ this ->app ->saucer ->new ('size_t ' );
186+
187+ $ this ->app ->saucer ->saucer_url_string ($ url , \FFI ::addr ($ value ), \FFI ::addr ($ size ));
188+
189+ if ($ size ->cdata === 0 ) {
190+ return '' ;
191+ }
192+
193+ return \FFI ::string ($ value , $ size ->cdata );
194+ }
195+
164196 private function onNavigating (CData $ _ , CData $ navigation ): int
165197 {
166198 $ this ->changeState (WebViewState::Navigating);
167199
168- $ url = \FFI ::string ($ this ->app ->saucer ->saucer_navigation_url ($ navigation ));
200+ $ saucerUrl = $ this ->app ->saucer ->saucer_navigation_url ($ navigation );
201+ $ bosonUrl = Request::castUrl ($ this ->urlToString ($ saucerUrl ));
202+ $ this ->app ->saucer ->saucer_url_free ($ saucerUrl );
169203
170- try {
171- return $ this ->intent (new WebViewNavigating (
172- subject: $ this ->webview ,
173- url: Request::castUrl ($ url ),
174- isNewWindow: $ this ->app ->saucer ->saucer_navigation_new_window ($ navigation ),
175- isRedirection: $ this ->app ->saucer ->saucer_navigation_redirection ($ navigation ),
176- isUserInitiated: $ this ->app ->saucer ->saucer_navigation_user_initiated ($ navigation ),
177- ))
178- ? Policy::SAUCER_POLICY_ALLOW
179- : Policy::SAUCER_POLICY_BLOCK ;
180- } finally {
181- $ this ->app ->saucer ->saucer_navigation_free ($ navigation );
182- }
204+ return $ this ->intent (new WebViewNavigating (
205+ subject: $ this ->webview ,
206+ url: $ bosonUrl ,
207+ isNewWindow: $ this ->app ->saucer ->saucer_navigation_new_window ($ navigation ),
208+ isRedirection: $ this ->app ->saucer ->saucer_navigation_redirection ($ navigation ),
209+ isUserInitiated: $ this ->app ->saucer ->saucer_navigation_user_initiated ($ navigation ),
210+ ))
211+ ? Policy::SAUCER_POLICY_ALLOW
212+ : Policy::SAUCER_POLICY_BLOCK ;
183213 }
184214
185215 private function onSafeNavigating (CData $ _ , CData $ navigation ): int
@@ -199,13 +229,9 @@ private function onFaviconChanged(CData $ptr, CData $icon): void
199229 return ;
200230 }
201231
202- try {
203- $ this ->app ->saucer ->saucer_window_set_icon ($ ptr , $ icon );
232+ $ this ->app ->saucer ->saucer_window_set_icon ($ this ->webview ->window ->id ->ptr , $ icon );
204233
205- $ this ->dispatch (new WebViewFaviconChanged ($ this ->webview ));
206- } finally {
207- $ this ->app ->saucer ->saucer_icon_free ($ icon );
208- }
234+ $ this ->dispatch (new WebViewFaviconChanged ($ this ->webview ));
209235 }
210236
211237 private function onSafeFaviconChanged (CData $ ptr , CData $ icon ): void
@@ -217,28 +243,31 @@ private function onSafeFaviconChanged(CData $ptr, CData $icon): void
217243 }
218244 }
219245
220- private function onTitleChanged (CData $ ptr , string $ title ): void
246+ private function onTitleChanged (CData $ ptr , string $ title, int $ length ): void
221247 {
222248 if (!$ this ->intent (new WebViewTitleChanging ($ this ->webview , $ title ))) {
223249 return ;
224250 }
225251
226- $ this ->app ->saucer ->saucer_window_set_title ($ ptr , $ title );
252+ $ this ->app ->saucer ->saucer_window_set_title ($ this -> window -> id -> ptr , $ title );
227253 $ this ->dispatch (new WebViewTitleChanged ($ this ->webview , $ title ));
228254 }
229255
230- private function onSafeTitleChanged (CData $ ptr , string $ title ): void
256+ private function onSafeTitleChanged (CData $ ptr , string $ title, int $ length ): void
231257 {
232258 try {
233- $ this ->onTitleChanged ($ ptr , $ title );
259+ $ this ->onTitleChanged ($ ptr , $ title, $ length );
234260 } catch (\Throwable $ e ) {
235261 $ this ->webview ->window ->app ->poller ->throw ($ e );
236262 }
237263 }
238264
239- private function onLoad (CData $ _ , CData $ state ): void
265+ /**
266+ * @param State::SAUCER_STATE_* $state
267+ */
268+ private function onLoad (CData $ _ , int $ state ): void
240269 {
241- if ($ state[ 0 ] === State::SAUCER_STATE_STARTED ) {
270+ if ($ state === State::SAUCER_STATE_STARTED ) {
242271 $ this ->changeState (WebViewState::Loading);
243272
244273 return ;
@@ -247,7 +276,10 @@ private function onLoad(CData $_, CData $state): void
247276 $ this ->changeState (WebViewState::Ready);
248277 }
249278
250- private function onSafeLoad (CData $ _ , CData $ state ): void
279+ /**
280+ * @param State::SAUCER_STATE_* $state
281+ */
282+ private function onSafeLoad (CData $ _ , int $ state ): void
251283 {
252284 $ this ->onLoad ($ _ , $ state );
253285 }
0 commit comments