diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java index f0cd7de48c7..230fa09a809 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java @@ -949,13 +949,52 @@ int handleSourceChanged(long pView, long pArgs) { // to an empty string. Navigations with NavigateToString set the Source // to about:blank. Initial Source is about:blank. If Source value // is the same between navigations, SourceChanged isn't fired. - // Calling LocationListener#changed() was moved to - // handleNavigationCompleted() to have consistent/symmetric + // Since we do not use NavigateToString (but always use a dummy file) + // we always see a proper (file:// URI). + // The main location events are fired from + // handleNavigationStarting() / handleNavigationCompleted() + // to get consistent/symmetric // LocationListener.changing() -> LocationListener.changed() behavior. - // TODO: #fragment navigation inside a page does not result in - // NavigationStarted / NavigationCompleted events from WebView2. - // so for now we cannot send consistent changing() + changed() events - // for those scenarios. + // For #fragment navigation within a page, no NavigationStarted/NavigationCompleted + // events are send from WebView2. + // Instead, SourceChanged is fired. + // We therefore also handle this event specifically for in-same-document scenario. + // Since SourceChanged cannot be blocked, we only send out + // LocationListener#changed() events, no changing() events. + int[] isNewDocument = new int[1]; + ICoreWebView2SourceChangedEventArgs args = new ICoreWebView2SourceChangedEventArgs(pArgs); + args.get_IsNewDocument(isNewDocument); + if (isNewDocument[0] == 0) { + // #fragment navigation inside the same document + long[] ppsz = new long[1]; + int hr = webViewProvider.getWebView(true).get_Source(ppsz); + if (hr != COM.S_OK) return hr; + String url = wstrToString(ppsz[0], true); + int fragmentIndex = url.indexOf('#'); + String urlWithoutFragment = fragmentIndex == -1 ? url : url.substring(0,fragmentIndex); + String location; + if (isLocationForCustomText(urlWithoutFragment)) { + if (fragmentIndex != -1) { + location = ABOUT_BLANK.toString() + url.substring(fragmentIndex); + } else { + location = ABOUT_BLANK.toString(); + } + } else { + location = url; + } + browser.getDisplay().asyncExec(() -> { + if (browser.isDisposed()) return; + LocationEvent event = new LocationEvent(browser); + event.display = browser.getDisplay(); + event.widget = browser; + event.location = location; + event.top = true; + for (LocationListener listener : locationListeners) { + listener.changed(event); + if (browser.isDisposed()) return; + } + }); + } return COM.S_OK; }