X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.kt;h=ccaa58fae7121f6afec1d4c23b964424b0d25d4a;hb=8a7255a5e91e2fc907c6d133db99d805ee2f20de;hp=96cd882bca9306d6222076f1da78ac00e1199e29;hpb=6e94010657a160df0c4e55d988155b411a54f71b;p=PrivacyBrowserAndroid.git diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.kt b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.kt index 96cd882b..ccaa58fa 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.kt +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.kt @@ -321,6 +321,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook private lateinit var optionsUserAgentSafariOnIosMenuItem: MenuItem private lateinit var optionsUserAgentSafariOnMacosMenuItem: MenuItem private lateinit var optionsUserAgentWebViewDefaultMenuItem: MenuItem + private lateinit var optionsViewSourceMenuItem: MenuItem private lateinit var optionsWideViewportMenuItem: MenuItem private lateinit var proxyHelper: ProxyHelper private lateinit var redColorSpan: ForegroundColorSpan @@ -685,6 +686,9 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Go back. currentWebView!!.goBack() + + // Update the URL edit text after a delay. + updateUrlEditTextAfterDelay() } else { // Close the current tab. // A view is required because the method is also called by an XML `onClick`. closeTab(null) @@ -774,7 +778,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook } } else { // The app has been restarted. // If the new intent will open a new tab, set the saved tab position to be the size of the saved state array list. - // The tab position is 0 based, meaning the at the new tab will be the tab position that is restored. + // The tab position is 0 based, meaning the new tab will be the tab position that is restored. if ((intentUriData != null) || (intentStringExtra != null) || isWebSearch) savedTabPosition = savedStateArrayList!!.size @@ -1063,6 +1067,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook optionsDisplayImagesMenuItem = menu.findItem(R.id.display_images) optionsDarkWebViewMenuItem = menu.findItem(R.id.dark_webview) optionsFontSizeMenuItem = menu.findItem(R.id.font_size) + optionsViewSourceMenuItem = menu.findItem(R.id.view_source) optionsAddOrEditDomainMenuItem = menu.findItem(R.id.add_or_edit_domain) // Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step. @@ -1075,9 +1080,6 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Disable the clear form data menu item if the API >= 26 so that the status of the main Clear Data is calculated correctly. optionsClearFormDataMenuItem.isEnabled = Build.VERSION.SDK_INT < 26 - // Only display the dark WebView menu item if the API >= 29. - optionsDarkWebViewMenuItem.isVisible = Build.VERSION.SDK_INT >= 29 - // Set the status of the additional app bar icons. Setting the refresh menu item to `SHOW_AS_ACTION_ALWAYS` makes it appear even on small devices like phones. if (displayAdditionalAppBarIcons) { // Display the additional icons. optionsRefreshMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) @@ -1140,7 +1142,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook optionsWideViewportMenuItem.isChecked = currentWebView!!.settings.useWideViewPort optionsDisplayImagesMenuItem.isChecked = currentWebView!!.settings.loadsImagesAutomatically - // Initialize the display names for the filter lists with the number of blocked requests. + // Set the display names for the filter lists with the number of blocked requests. optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + currentWebView!!.getRequestsCount(BLOCKED_REQUESTS) optionsEasyListMenuItem.title = currentWebView!!.getRequestsCount(EASYLIST).toString() + " - " + getString(R.string.easylist) optionsEasyPrivacyMenuItem.title = currentWebView!!.getRequestsCount(EASYPRIVACY).toString() + " - " + getString(R.string.easyprivacy) @@ -1159,9 +1161,15 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Enable dark WebView if night mode is enabled. optionsDarkWebViewMenuItem.isEnabled = (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) - // Set the checkbox status for dark WebView if the device is running API >= 29 and algorithmic darkening is supported. - if ((Build.VERSION.SDK_INT >= 29) && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) + // Set the checkbox status for dark WebView if algorithmic darkening is supported. + if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) optionsDarkWebViewMenuItem.isChecked = WebSettingsCompat.isAlgorithmicDarkeningAllowed(currentWebView!!.settings) + + // Set the view source title according to the current URL. + if (currentWebView!!.currentUrl.startsWith("view-source:")) + optionsViewSourceMenuItem.title = getString(R.string.view_rendered_website) + else + optionsViewSourceMenuItem.title = getString(R.string.view_source) } // Set the cookies menu item checked status. @@ -1918,7 +1926,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook R.id.dark_webview -> { // Dark WebView. // Toggle dark WebView if supported. - if ((Build.VERSION.SDK_INT >= 29) && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) + if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) WebSettingsCompat.setAlgorithmicDarkeningAllowed(currentWebView!!.settings, !WebSettingsCompat.isAlgorithmicDarkeningAllowed(currentWebView!!.settings) ) @@ -2006,15 +2014,29 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook } R.id.view_source -> { // View source. - // Create an intent to launch the view source activity. - val viewSourceIntent = Intent(this, ViewSourceActivity::class.java) + // Open a new tab according to the current URL. + if (currentWebView!!.currentUrl.startsWith("view-source:")) { // The source is currently viewed. + // Open the rendered website in a new tab. + addNewTab(currentWebView!!.currentUrl.substring(12, currentWebView!!.currentUrl.length), true) + } else { // The rendered website is currently viewed. + // Open the source in a new tab. + addNewTab("view-source:${currentWebView!!.currentUrl}", true) + } + + // Consume the event. + true + } + + R.id.view_headers -> { // View headers. + // Create an intent to launch the view headers activity. + val viewHeadersIntent = Intent(this, ViewHeadersActivity::class.java) // Add the variables to the intent. - viewSourceIntent.putExtra(CURRENT_URL, currentWebView!!.url) - viewSourceIntent.putExtra(USER_AGENT, currentWebView!!.settings.userAgentString) + viewHeadersIntent.putExtra(CURRENT_URL, currentWebView!!.url) + viewHeadersIntent.putExtra(USER_AGENT, currentWebView!!.settings.userAgentString) // Make it so. - startActivity(viewSourceIntent) + startActivity(viewHeadersIntent) // Consume the event. true @@ -2212,6 +2234,9 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Load the previous website in the history. currentWebView!!.goBack() + + // Update the URL edit text after a delay. + updateUrlEditTextAfterDelay() } } @@ -2229,6 +2254,9 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Load the next website in the history. currentWebView!!.goForward() + + // Update the URL edit text after a delay. + updateUrlEditTextAfterDelay() } } @@ -3238,8 +3266,8 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook } } - // Set the WebView theme if device is running API >= 29 and algorithmic darkening is supported. - if ((Build.VERSION.SDK_INT >= 29) && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { + // Set the WebView theme if algorithmic darkening is supported. + if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { // Set the WebView theme. when (webViewThemeInt) { // Set the WebView theme. @@ -3358,8 +3386,8 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook else -> nestedScrollWebView.settings.userAgentString = userAgentDataArray[userAgentArrayPosition] } - // Set the WebView theme if the device is running API >= 29 and algorithmic darkening is supported. - if ((Build.VERSION.SDK_INT >= 29) && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { + // Set the WebView theme if algorithmic darkening is supported. + if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { // Set the WebView theme. when (defaultWebViewTheme) { // The light theme is selected. Turn off algorithmic darkening. @@ -3397,6 +3425,10 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook if (reloadWebsite) nestedScrollWebView.reload() + // Disable the wide viewport if the source is being viewed. + if (url.startsWith("view-source:")) + nestedScrollWebView.settings.useWideViewPort = false + // Load the URL if directed. This makes sure that the domain settings are properly loaded before the URL. By using `loadUrl()`, instead of `loadUrlFromBase()`, the Referer header will never be sent. if (loadUrl) nestedScrollWebView.loadUrl(url) @@ -3985,17 +4017,12 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Set the first page as the current WebView. setCurrentWebView(0) } else { // The first tab is not selected. - // Create a handler move to the page. - val setCurrentPageHandler = Handler(Looper.getMainLooper()) - - // Create a runnable to move to the page. - val setCurrentPageRunnable = Runnable { - // Move to the page. - webViewViewPager2.currentItem = savedTabPosition - } + // Switch to the page before the saved tab position. + webViewViewPager2.post { webViewViewPager2.currentItem = (savedTabPosition - 1) } - // Move to the page after 50 milliseconds, which should be enough time to for the WebView state adapter to populate the restored pages. - setCurrentPageHandler.postDelayed(setCurrentPageRunnable, 50) + // Switch to the saved tab position. + // This has to be done twice because, for some reason, if the above step is skipped there is some race condition where nothing happens and the first page is displayed. + webViewViewPager2.post { webViewViewPager2.currentItem = savedTabPosition } } // Get the intent that started the app. @@ -4164,10 +4191,12 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Set the current WebView. setCurrentWebView(position) - // Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled by creating a new tab. - if (tabLayout.selectedTabPosition != position) { - // Wait until the new tab has been created. - tabLayout.post { + // Wait until the new tab has been created. + tabLayout.post { + // Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled by creating a new tab. + // The checking of the position was moved inside the post block to prevent a race condition that caused the tab to be selected twice and the encryption dialog to be displayed. + // + if (tabLayout.selectedTabPosition != position) { // Get a handle for the tab. val tab = tabLayout.getTabAt(position)!! @@ -4443,8 +4472,8 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Get the WebView theme entry values string array. val webViewThemeEntryValuesStringArray = resources.getStringArray(R.array.webview_theme_entry_values) - // Set the WebView theme if device is running API >= 29 and algorithmic darkening is supported. - if (Build.VERSION.SDK_INT >= 29 && WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { + // Set the WebView theme if algorithmic darkening is supported. + if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { // Set the WebView them. A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant. if (webViewTheme == webViewThemeEntryValuesStringArray[1]) { // The light theme is selected. // Turn off algorithmic darkening. @@ -5354,8 +5383,8 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Update the URL text bar if the page is currently selected and the URL edit text is not currently being edited. if ((tabLayout.selectedTabPosition == currentPagePosition) && !urlEditText.hasFocus()) { - // Display the formatted URL text. - urlEditText.setText(url) + // Display the formatted URL text. The nested scroll WebView current URL preserves any initial `view-source:`, and opposed to the method URL variable. + urlEditText.setText(nestedScrollWebView.currentUrl) // Highlight the URL syntax. UrlHelper.highlightSyntax(urlEditText, initialGrayColorSpan, finalGrayColorSpan, redColorSpan) @@ -5697,7 +5726,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook var urlString = "" // Check to see if the unformatted URL string is a valid URL. Otherwise, convert it into a search. - if (unformattedUrlString.startsWith("content://")) { // This is a content URL. + if (unformattedUrlString.startsWith("content://") || unformattedUrlString.startsWith("view-source:")) { // This is a content or source URL. // Load the entire content URL. urlString = unformattedUrlString } else if (Patterns.WEB_URL.matcher(unformattedUrlString).matches() || unformattedUrlString.startsWith("http://") || unformattedUrlString.startsWith("https://") || @@ -5761,6 +5790,9 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Load the history entry. currentWebView!!.goBackOrForward(steps) + + // Update the URL edit text after a delay. + updateUrlEditTextAfterDelay() } override fun openFile(dialogFragment: DialogFragment) { @@ -5871,6 +5903,9 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook // Go back. currentWebView!!.goBack() + + // Update the URL edit text after a delay. + updateUrlEditTextAfterDelay() } private fun sanitizeUrl(urlString: String): String { @@ -6090,4 +6125,22 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook invalidateOptionsMenu() } } + + fun updateUrlEditTextAfterDelay() { + // Create a handler to update the URL edit box. + val urlEditTextUpdateHandler = Handler(Looper.getMainLooper()) + + // Create a runnable to update the URL edit box. + val urlEditTextUpdateRunnable = Runnable { + // Update the URL edit text. + urlEditText.setText(currentWebView!!.url) + + // Disable the wide viewport if the source is being viewed. + if (currentWebView!!.url!!.startsWith("view-source:")) + currentWebView!!.settings.useWideViewPort = false + } + + // Update the URL edit text after 50 milliseconds, so that the WebView has enough time to navigate to the new URL. + urlEditTextUpdateHandler.postDelayed(urlEditTextUpdateRunnable, 50) + } }