public void Navigate(string uriString) { _isNavigating = true; bool cancelled = false; var uri = new Uri(uriString); var normalisedUri = UriTester.NormaliseUri(uri); var siteIdentity = new SiteIdentity(normalisedUri, Session.Instance); var fullQuery = normalisedUri.OriginalString; //sanity check we have a valid URL syntax at least if (normalisedUri.Scheme == null) { ToastNotify("Invalid URL: " + normalisedUri.OriginalString, ToastMessageStyles.Error); cancelled = true; } ToggleContainerControlsForBrowser(false); //these are the only ones we "navigate" to. We do this by downloading the GMI content //converting to HTML and then actually navigating to that. if (normalisedUri.Scheme == "gemini") { var geminiNavigator = new GeminiNavigator(this); cancelled = geminiNavigator.NavigateGeminiScheme(fullQuery, uri, siteIdentity); } else if (normalisedUri.Scheme == "gopher") { var gopherNavigator = new GopherNavigator(this); cancelled = gopherNavigator.NavigateGopherScheme(fullQuery, uri, siteIdentity); } else if (normalisedUri.Scheme == "about") { var aboutNavigator = new AboutNavigator(this); cancelled = aboutNavigator.NavigateAboutScheme(uri, siteIdentity); } else if (normalisedUri.Scheme.StartsWith("http")) //both http and https { //detect ctrl click if (_settings.HandleWebLinks == "System web browser") { //open in system web browser var launcher = new ExternalNavigator(this); launcher.LaunchExternalUri(uri.ToString()); ToggleContainerControlsForBrowser(true); cancelled = true; } else if (_settings.HandleWebLinks == "Gemini HTTP proxy") { // use a gemini proxy for http links var geminiNavigator = new GeminiNavigator(this); cancelled = geminiNavigator.NavigateGeminiScheme(fullQuery, uri, siteIdentity); } else { //use internal navigator var httpNavigator = new HttpNavigator(this); cancelled = httpNavigator.NavigateHttpScheme(fullQuery, uri, siteIdentity, "web-launch-external"); } } else if (normalisedUri.Scheme == "file") { //just load the converted html file //no further action. BrowserControl.Text = File.ReadAllText(normalisedUri.LocalPath); } else { //we don't care about any other protocols //so we open those in system web browser to deal with var launcher = new ExternalNavigator(this); launcher.LaunchExternalUri(uri.ToString()); ToggleContainerControlsForBrowser(true); cancelled = true; } if (!cancelled) { uriString = uri.ToString(); //look up the URL that this HTML page shows var regex = new Regex(@".*/([a-f0-9]+)\.(.*)"); if (regex.IsMatch(uriString)) { var match = regex.Match(uriString); var hash = match.Groups[1].ToString(); string geminiUrl = _urlsByHash[hash]; if (geminiUrl != null) { //now show the actual gemini URL in the address bar txtUrl.Text = geminiUrl; ShowTitle(BrowserControl); var originalUri = new UriBuilder(geminiUrl); if (originalUri.Scheme == "http" || originalUri.Scheme == "https") { ShowLinkRenderMode(BrowserControl.Text); } } //if a text file (i.e. view->source), explicitly set the charset //to UTF-8 so ascii art looks correct etc. if ("txt" == match.Groups[2].ToString().ToLower()) { //set text files (GMI source) to be UTF-8 for now HtmlPanelExtensions.SetCharsetUtf8(BrowserControl.Text); } } BrowserControl.Focus(); ShowTitle(BrowserControl); //we need to turn on/off other elements so focus doesnt move elsewhere //in that case the keyboard events go elsewhere and you have to click //into the browser to get it to work again //see https://stackoverflow.com/questions/8495857/webbrowser-steals-focus ToggleContainerControlsForBrowser(true); } _isNavigating = false; }
private void BrowserControl_Navigating(object sender, NavigatingCancelEventArgs e) { _isNavigating = true; var normalisedUri = UriTester.NormaliseUri(e.Uri); var siteIdentity = new SiteIdentity(normalisedUri, Session.Instance); var fullQuery = normalisedUri.OriginalString; //sanity check we have a valid URL syntax at least if (e.Uri.Scheme == null) { ToastNotify("Invalid URL: " + normalisedUri.OriginalString, ToastMessageStyles.Error); e.Cancel = true; } var settings = new UserSettings(); ToggleContainerControlsForBrowser(false); //these are the only ones we "navigate" to. We do this by downloading the GMI content //converting to HTML and then actually navigating to that. if (normalisedUri.Scheme == "gemini") { var geminiNavigator = new GeminiNavigator(this, this.BrowserControl); geminiNavigator.NavigateGeminiScheme(fullQuery, e, siteIdentity); } else if (normalisedUri.Scheme == "nimigem") { var nimigemNavigator = new NimigemNavigator(this, this.BrowserControl); var document = (HTMLDocument)BrowserControl.Document; var firstTextarea = (IHTMLTextAreaElement)document.getElementsByTagName("textarea").item(0); string payload; if (firstTextarea != null) { payload = firstTextarea.value; } else { payload = ""; } nimigemNavigator.NavigateNimigemScheme(fullQuery, e, payload); } else if (normalisedUri.Scheme == "gopher") { var gopherNavigator = new GopherNavigator(this, this.BrowserControl); gopherNavigator.NavigateGopherScheme(fullQuery, e, siteIdentity); } else if (normalisedUri.Scheme == "about") { var aboutNavigator = new AboutNavigator(this, this.BrowserControl); aboutNavigator.NavigateAboutScheme(e, siteIdentity); } else if (normalisedUri.Scheme.StartsWith("http")) //both http and https { var linkId = ""; ////doc might be null - you need to check when using! var doc = (HTMLDocument)BrowserControl.Document; ////this is how we could detect a click on a link to an image... if (doc?.activeElement != null) { linkId = doc.activeElement.id; } //detect ctrl click if ( Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl) || settings.HandleWebLinks == "System web browser" || linkId == "web-launch-external" ) { //open in system web browser var launcher = new ExternalNavigator(this); launcher.LaunchExternalUri(e.Uri.ToString()); ToggleContainerControlsForBrowser(true); e.Cancel = true; } else if (settings.HandleWebLinks == "Gemini HTTP proxy") { // use a gemini proxy for http links var geminiNavigator = new GeminiNavigator(this, this.BrowserControl); geminiNavigator.NavigateGeminiScheme(fullQuery, e, siteIdentity); } else { //use internal navigator var httpNavigator = new HttpNavigator(this, this.BrowserControl); httpNavigator.NavigateHttpScheme(fullQuery, e, siteIdentity, linkId); } } else if (normalisedUri.Scheme == "file") { //just load the converted html file //no further action. } else { //we don't care about any other protocols //so we open those in system web browser to deal with var launcher = new ExternalNavigator(this); launcher.LaunchExternalUri(e.Uri.ToString()); ToggleContainerControlsForBrowser(true); e.Cancel = true; } if (e.Cancel) { _isNavigating = false; } }