import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.HashSet;
// `proxyThroughOrbot` is used in `onCreate()` and `applySettings()`
private boolean proxyThroughOrbot;
- // `currentDomain` is used in `onCreate() and `applyDomainSettings()`.
+ // `currentDomain` is used in `onCreate(), `onNavigationItemSelected()`, and `applyDomainSettings()`.
private String currentDomain;
// `pendingUrl` is used in `onCreate()` and `applySettings()`
@Override
public void onDrawerStateChanged(int newState) {
- // Update the `Back`, `Forward`, and `History` menu items every time the drawer opens.
- navigationBackMenuItem.setEnabled(mainWebView.canGoBack());
- navigationForwardMenuItem.setEnabled(mainWebView.canGoForward());
- navigationHistoryMenuItem.setEnabled((mainWebView.canGoBack() || mainWebView.canGoForward()));
+ if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) { // The drawer is opening or closing.
+ // Update the `Back`, `Forward`, and `History` menu items.
+ navigationBackMenuItem.setEnabled(mainWebView.canGoBack());
+ navigationForwardMenuItem.setEnabled(mainWebView.canGoForward());
+ navigationHistoryMenuItem.setEnabled((mainWebView.canGoBack() || mainWebView.canGoForward()));
- // Hide the keyboard so we can see the navigation menu. `0` indicates no additional flags.
- inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
+ // Hide the keyboard so we can see the navigation menu. `0` indicates no additional flags.
+ inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
+ }
}
});
public void onPageFinished(WebView view, String url) {
// Check to see if we are waiting on Orbot.
if (pendingUrl.isEmpty()) { // we are not waiting on Orbot, so we need to process the URL.
- formattedUrlString = url;
+ // Check to see if `WebView` has set `url` to be `about:blank`.
+ if (url.equals("about:blank")) { // `WebView` is blank, so `formattedUrlString` should be `""` and `urlTextBox` should display a hint.
+ // Set `formattedUrlString` to `""`.
+ formattedUrlString = "";
- // Only update urlTextBox if the user is not typing in it.
- if (!urlTextBox.hasFocus()) {
+ // Update `urlTextBox`.
urlTextBox.setText(formattedUrlString);
+
+ // Request focus for `urlTextBox`.
+ urlTextBox.requestFocus();
+
+ // Display the keyboard.
+ inputMethodManager.showSoftInput(urlTextBox, 0);
+ } else { // `WebView` has loaded a webpage.
+ // Set `formattedUrlString`.
+ formattedUrlString = url;
+
+ // Only update `urlTextBox` if the user is not typing in it.
+ if (!urlTextBox.hasFocus()) {
+ urlTextBox.setText(formattedUrlString);
+ }
}
// Store the SSL certificate so it can be accessed from `ViewSslCertificateDialog`.
break;
case R.id.settings:
+ // Reset `currentDomain` so that domain settings are reapplied after returning to `MainWebViewActivity`.
+ currentDomain = "";
+
// Launch `SettingsActivity`.
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
break;
case R.id.domains:
+ // Reset `currentDomain` so that domain settings are reapplied after returning to `MainWebViewActivity`.
+ currentDomain = "";
+
// Launch `DomainsActivity`.
Intent domainsIntent = new Intent(this, DomainsActivity.class);
startActivity(domainsIntent);
// Get the text from urlTextBox and convert it to a string. trim() removes white spaces from the beginning and end of the string.
String unformattedUrlString = urlTextBox.getText().toString().trim();
- URL unformattedUrl = null;
- Uri.Builder formattedUri = new Uri.Builder();
-
// Check to see if unformattedUrlString is a valid URL. Otherwise, convert it into a Duck Duck Go search.
if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
// Add http:// at the beginning if it is missing. Otherwise the app will segfault.
unformattedUrlString = "http://" + unformattedUrlString;
}
+ // Initialize `unformattedUrl`.
+ URL unformattedUrl = null;
+
// Convert unformattedUrlString to a URL, then to a URI, and then back to a string, which sanitizes the input and adds in any missing components.
try {
unformattedUrl = new URL(unformattedUrlString);
e.printStackTrace();
}
- // The ternary operator (? :) makes sure that a null pointer exception is not thrown, which would happen if .get was called on a null value.
+ // The ternary operator (? :) makes sure that a null pointer exception is not thrown, which would happen if `.get` was called on a `null` value.
final String scheme = unformattedUrl != null ? unformattedUrl.getProtocol() : null;
final String authority = unformattedUrl != null ? unformattedUrl.getAuthority() : null;
final String path = unformattedUrl != null ? unformattedUrl.getPath() : null;
final String query = unformattedUrl != null ? unformattedUrl.getQuery() : null;
final String fragment = unformattedUrl != null ? unformattedUrl.getRef() : null;
+ // Build the URI.
+ Uri.Builder formattedUri = new Uri.Builder();
formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
- formattedUrlString = formattedUri.build().toString();
+
+ // Decode `formattedUri` as a `String` in `UTF-8`.
+ formattedUrlString = URLDecoder.decode(formattedUri.build().toString(), "UTF-8");
} else {
- // Sanitize the search input and convert it to a DuckDuckGo search.
+ // Sanitize the search input and convert it to a search.
final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
// Use the correct search URL.
String hostname = uri.getHost();
// Only apply the domain settings if `hostname` is not the same as `currentDomain`. This allows the user to set temporary settings for JavaScript, Cookies, DOM Storage, etc.
- if (!hostname.equals(currentDomain)) {
+ if (hostname != null && !hostname.equals(currentDomain)) {
// Set the new `hostname` as the `currentDomain`.
currentDomain = hostname;