// The swipe refresh layout top padding is used when exiting full screen browsing mode. It is used in an inner class in `initializeWebView()`.
private int swipeRefreshLayoutPaddingTop;
+ // The URL sanitizers are set in `applyAppSettings()` and used in `sanitizeUrl()`.
+ private boolean sanitizeGoogleAnalytics;
+ private boolean sanitizeFacebookClickIds;
+
// The download strings are used in `onCreate()`, `onRequestPermissionResult()` and `initializeWebView()`.
private String downloadUrl;
private String downloadContentDisposition;
// Get the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- // Add a new tab if specified in the preferences.
- if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
- // Set the loading new intent flag.
- loadingNewIntent = true;
-
- // Add a new tab.
- addTab(null);
- }
-
// Create a URL string.
String url;
url = intentUriData.toString();
}
- // Load the URL.
- loadUrl(url);
+ // Add a new tab if specified in the preferences.
+ if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { // Load the URL in a new tab.
+ // Set the loading new intent flag.
+ loadingNewIntent = true;
+
+ // Add a new tab.
+ addNewTab(url);
+ } else { // Load the URL in the current tab.
+ // Make it so.
+ loadUrl(url);
+ }
// Get a handle for the drawer layout.
DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
drawerLayout.closeDrawer(GravityCompat.END);
}
-
- // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
- currentWebView.requestFocus();
}
}
// Add an Open in New Tab entry.
menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
- // Add a new tab.
- addTab(null);
-
- // Load the URL.
- loadUrl(linkUrl);
+ // Load the link URL in a new tab.
+ addNewTab(linkUrl);
return false;
});
// Add an Open in New Tab entry.
menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> {
- // Add a new tab.
- addTab(null);
-
- // Load the URL.
- loadUrl(imageUrl);
+ // Load the image URL in a new tab.
+ addNewTab(imageUrl);
return false;
});
}
private void loadUrl(String url) {
+ // Sanitize the URL.
+ url = sanitizeUrl(url);
+
// Apply the domain settings.
applyDomainSettings(currentWebView, url, true, false);
// Store the values from the shared preferences in variables.
incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false);
boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false);
+ sanitizeGoogleAnalytics = sharedPreferences.getBoolean("google_analytics", true);
+ sanitizeFacebookClickIds = sharedPreferences.getBoolean("facebook_click_ids", true);
proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
hideAppBar = sharedPreferences.getBoolean("hide_app_bar", true);
startActivity(openWithBrowserIntent);
}
+ private String sanitizeUrl(String url) {
+ // Sanitize Google Analytics.
+ if (sanitizeGoogleAnalytics) {
+ // Remove `?utm_`.
+ if (url.contains("?utm_")) {
+ url = url.substring(0, url.indexOf("?utm_"));
+ }
+
+ // Remove `&utm_`.
+ if (url.contains("&utm_")) {
+ url = url.substring(0, url.indexOf("&utm_"));
+ }
+ }
+
+ // Sanitize Facebook Click IDs.
+ if (sanitizeFacebookClickIds) {
+ // Remove `?fbclid=`.
+ if (url.contains("?fbclid=")) {
+ url = url.substring(0, url.indexOf("?fbclid="));
+ }
+
+ // Remove &fbclid=`.
+ if (url.contains("&fbclid=")) {
+ url = url.substring(0, url.indexOf("&fbclid="));
+ }
+ }
+
+ // Return the sanitized URL.
+ return url;
+ }
+
public void addTab(View view) {
+ // Add a new tab with a blank URL.
+ addNewTab("");
+ }
+
+ private void addNewTab(String url) {
+ // Sanitize the URL.
+ url = sanitizeUrl(url);
+
// Get a handle for the tab layout and the view pager.
TabLayout tabLayout = findViewById(R.id.tablayout);
ViewPager webViewPager = findViewById(R.id.webviewpager);
newTab.setCustomView(R.layout.tab_custom_view);
// Add the new WebView page.
- webViewPagerAdapter.addPage(newTabNumber, webViewPager);
+ webViewPagerAdapter.addPage(newTabNumber, webViewPager, url);
}
public void closeTab(View view) {
}
@Override
- public void initializeWebView(NestedScrollWebView nestedScrollWebView, int pageNumber, ProgressBar progressBar) {
+ public void initializeWebView(NestedScrollWebView nestedScrollWebView, int pageNumber, ProgressBar progressBar, String url) {
// Get handles for the activity views.
FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
registerForContextMenu(nestedScrollWebView);
// Allow the downloading of files.
- nestedScrollWebView.setDownloadListener((String url, String userAgent, String contentDisposition, String mimetype, long contentLength) -> {
+ nestedScrollWebView.setDownloadListener((String downloadUrl, String userAgent, String contentDisposition, String mimetype, long contentLength) -> {
// Check if the download should be processed by an external app.
if (downloadWithExternalApp) { // Download with an external app.
// Create a download intent. Not specifying the action type will display the maximum number of options.
Intent downloadIntent = new Intent();
// Set the URI and the MIME type. Specifying `text/html` displays a good number of options.
- downloadIntent.setDataAndType(Uri.parse(url), "text/html");
+ downloadIntent.setDataAndType(Uri.parse(downloadUrl), "text/html");
// Flag the intent to open in a new task.
downloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// The WRITE_EXTERNAL_STORAGE permission needs to be requested.
// Store the variables for future use by `onRequestPermissionsResult()`.
- downloadUrl = url;
+ this.downloadUrl = downloadUrl;
downloadContentDisposition = contentDisposition;
downloadContentLength = contentLength;
}
} else { // The storage permission has already been granted.
// Get a handle for the download file alert dialog.
- DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength);
+ DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(downloadUrl, contentDisposition, contentLength);
// Show the download file alert dialog.
downloadFileDialogFragment.show(getSupportFragmentManager(), getString(R.string.download));
// The deprecated `shouldOverrideUrlLoading` must be used until API >= 24.
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ // Sanitize the url.
+ url = sanitizeUrl(url);
+
if (url.startsWith("http")) { // Load the URL in Privacy Browser.
// Apply the domain settings for the new URL. This doesn't do anything if the domain has not changed.
boolean userAgentChanged = applyDomainSettings(nestedScrollWebView, url, true, false);
}
}
}
+ } else { // This is not the first tab.
+ // Apply the domain settings.
+ applyDomainSettings(nestedScrollWebView, url, false, false);
+
+ // Load the URL.
+ nestedScrollWebView.loadUrl(url, customHeaders);
+
+ // Display the keyboard if the URL is blank.
+ if (url.equals("")) {
+ inputMethodManager.showSoftInput(urlEditText, 0);
+ }
}
}
}
\ No newline at end of file