@@ -949,13 +949,52 @@ int handleSourceChanged(long pView, long pArgs) {
949949 // to an empty string. Navigations with NavigateToString set the Source
950950 // to about:blank. Initial Source is about:blank. If Source value
951951 // is the same between navigations, SourceChanged isn't fired.
952- // Calling LocationListener#changed() was moved to
953- // handleNavigationCompleted() to have consistent/symmetric
952+ // Since we do not use NavigateToString (but always use a dummy file)
953+ // we always see a proper (file:// URI).
954+ // The main location events are fired from
955+ // handleNavigationStarting() / handleNavigationCompleted()
956+ // to get consistent/symmetric
954957 // LocationListener.changing() -> LocationListener.changed() behavior.
955- // TODO: #fragment navigation inside a page does not result in
956- // NavigationStarted / NavigationCompleted events from WebView2.
957- // so for now we cannot send consistent changing() + changed() events
958- // for those scenarios.
958+ // For #fragment navigation within a page, no NavigationStarted/NavigationCompleted
959+ // events are send from WebView2.
960+ // Instead, SourceChanged is fired.
961+ // We therefore also handle this event specifically for in-same-document scenario.
962+ // Since SourceChanged cannot be blocked, we only send out
963+ // LocationListener#changed() events, no changing() events.
964+ int [] isNewDocument = new int [1 ];
965+ ICoreWebView2SourceChangedEventArgs args = new ICoreWebView2SourceChangedEventArgs (pArgs );
966+ args .get_IsNewDocument (isNewDocument );
967+ if (isNewDocument [0 ] == 0 ) {
968+ // #fragment navigation inside the same document
969+ long [] ppsz = new long [1 ];
970+ int hr = webViewProvider .getWebView (true ).get_Source (ppsz );
971+ if (hr != COM .S_OK ) return hr ;
972+ String url = wstrToString (ppsz [0 ], true );
973+ int fragmentIndex = url .indexOf ('#' );
974+ String urlWithoutFragment = fragmentIndex == -1 ? url : url .substring (0 ,fragmentIndex );
975+ String location ;
976+ if (isLocationForCustomText (urlWithoutFragment )) {
977+ if (fragmentIndex != -1 ) {
978+ location = ABOUT_BLANK .toString () + url .substring (fragmentIndex );
979+ } else {
980+ location = ABOUT_BLANK .toString ();
981+ }
982+ } else {
983+ location = url ;
984+ }
985+ browser .getDisplay ().asyncExec (() -> {
986+ if (browser .isDisposed ()) return ;
987+ LocationEvent event = new LocationEvent (browser );
988+ event .display = browser .getDisplay ();
989+ event .widget = browser ;
990+ event .location = location ;
991+ event .top = true ;
992+ for (LocationListener listener : locationListeners ) {
993+ listener .changed (event );
994+ if (browser .isDisposed ()) return ;
995+ }
996+ });
997+ }
959998 return COM .S_OK ;
960999}
9611000
0 commit comments