package com.stoutner.privacybrowser;
import android.annotation.SuppressLint;
-import android.app.Activity;
import android.app.DialogFragment;
import android.app.DownloadManager;
import android.content.Context;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ProgressBar;
import java.io.UnsupportedEncodingException;
SslCertificateError.SslCertificateErrorListener, DownloadFile.DownloadFileListener {
// `appBar` is public static so it can be accessed from `OrbotProxyHelper`.
- // It is also used in `onCreate()` and `onOptionsItemSelected()`.
+ // It is also used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
public static ActionBar appBar;
// `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `BookmarksActivity`, `CreateBookmark`, `CreateBookmarkFolder`, and `EditBookmark`.
// `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
private SslErrorHandler sslErrorHandler;
- private MenuItem toggleJavaScript;
+ // `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
+ private EditText findOnPageEditText;
+
+ // `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`.
+ private InputMethodManager inputMethodManager;
@Override
// Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled. The whole premise of Privacy Browser is built around an understanding of these dangers.
super.onCreate(savedInstanceState);
setContentView(R.layout.main_coordinatorlayout);
+ // Get a handle for `inputMethodManager`.
+ inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
// We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
Toolbar supportAppBar = (Toolbar) findViewById(R.id.appBar);
setSupportActionBar(supportAppBar);
// Set the "go" button on the keyboard to load the URL in urlTextBox.
urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.urlTextBox);
urlTextBox.setOnKeyListener(new View.OnKeyListener() {
+ @Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
- // If the event is a key-down event on the "enter" button, load the URL.
+ // If the event is a key-down event on the `enter` button, load the URL.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Load the URL into the mainWebView and consume the event.
try {
}
});
+ // Get a handle for `find_on_page_edittext`.
+ findOnPageEditText = (EditText) findViewById(R.id.find_on_page_edittext);
+
+ // Set the `go` button on the keyboard to search for the phrase in `find_on_page_edittext`
+ findOnPageEditText.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // If the event is a key-down event on the `enter` button, search for the phrase.
+ if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
+ // Search for the phrase.
+ mainWebView.findAllAsync(findOnPageEditText.getText().toString());
+
+ // Consume the event.
+ return true;
+ } else {
+ // Do not consume the event.
+ return false;
+ }
+ }
+ });
+
final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.fullScreenVideoFrameLayout);
// Implement swipe to refresh
sslErrorHandler = handler;
// Display the SSL error `AlertDialog`.
- DialogFragment sslCertificateErrorDialogFragment = SslCertificateError.displayDialog(error);
- sslCertificateErrorDialogFragment.show(getFragmentManager(), getResources().getString(R.string.ssl_certificate_error));
+ AppCompatDialogFragment sslCertificateErrorDialogFragment = SslCertificateError.displayDialog(error);
+ sslCertificateErrorDialogFragment.show(getSupportFragmentManager(), getResources().getString(R.string.ssl_certificate_error));
}
});
updatePrivacyIcons(false);
// Get handles for the menu items.
- toggleJavaScript = menu.findItem(R.id.toggleJavaScript);
MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies);
MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
mainWebView.getSettings().setTextZoom(200);
return true;
- /*
case R.id.find_on_page:
- appBar.setCustomView(R.layout.find_on_page_app_bar);
- toggleJavaScript.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- appBar.invalidateOptionsMenu();
+ // Hide the URL app bar.
+ Toolbar appBarToolbar = (Toolbar) findViewById(R.id.appBar);
+ appBarToolbar.setVisibility(View.GONE);
+
+ // Show the Find on Page `RelativeLayout`.
+ LinearLayout findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout);
+ findOnPageLinearLayout.setVisibility(View.VISIBLE);
+
+ // Display the keyboard. We have to wait 200 ms before running the command to work around a bug in Android.
+ findOnPageEditText.postDelayed(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ // Set the focus on `findOnPageEditText`.
+ findOnPageEditText.requestFocus();
+
+ // Display the keyboard.
+ inputMethodManager.showSoftInput(findOnPageEditText, 0);
+ }
+ }, 200);
return true;
- */
case R.id.share:
Intent shareIntent = new Intent();
mainWebView.loadUrl(formattedUrlString, customHeaders);
- // Hides the keyboard so we can see the webpage.
- InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
+ // Hides the keyboard so we can see the webpage. `0` indicates no additional flags.
+ inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
+ }
+
+ public void closeFindOnPage(View view) {
+ // Delete the contents of `find_on_page_edittext`.
+ findOnPageEditText.setText(null);
+
+ // Hide the Find on Page `RelativeLayout`.
+ LinearLayout findOnPageLinearLayout = (LinearLayout) findViewById(R.id.find_on_page_linearlayout);
+ findOnPageLinearLayout.setVisibility(View.GONE);
+
+ // Show the URL app bar.
+ Toolbar appBarToolbar = (Toolbar) findViewById(R.id.appBar);
+ appBarToolbar.setVisibility(View.VISIBLE);
+
+ // Hides the keyboard so we can see the webpage. `0` indicates no additional flags.
inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
}
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.app.AppCompatDialogFragment;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import java.util.Date;
-public class SslCertificateError extends DialogFragment {
+public class SslCertificateError extends AppCompatDialogFragment {
private String primaryError;
private String urlWithError;
// `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
@SuppressLint("InflateParams")
@Override
+ @NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the activity's layout inflater.
LayoutInflater layoutInflater = getActivity().getLayoutInflater();
You should have received a copy of the GNU General Public License
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-<RelativeLayout
+<!-- `LinearLayout` is initially `visibility="gone"` so the `url_app_bar` is visible. -->
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/find_on_page_relativelayout"
+ android:id="@+id/find_on_page_linearlayout"
android:layout_height="wrap_content"
- android:layout_width="match_parent" >
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:visibility="gone" >
+
+ <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. -->
+ <EditText
+ android:id="@+id/find_on_page_edittext"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="4dp"
+ android:hint="@string/find_on_page"
+ android:lines="1"
+ android:imeOptions="actionGo"
+ android:inputType="text" />
<ImageView
- android:id="@+id/close_find"
- android:src="@drawable/close"
- android:layout_alignParentEnd="true"
- android:layout_width="30dp"
- android:layout_height="30dp"
- android:layout_centerVertical="true"
- android:contentDescription="@string/close" />
+ android:id="@+id/find_previous"
+ android:src="@drawable/previous"
+ android:layout_width="35dp"
+ android:layout_height="35dp"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/previous" />
<ImageView
android:id="@+id/find_next"
android:src="@drawable/next"
- android:layout_toStartOf="@id/close_find"
- android:layout_width="30dp"
- android:layout_height="30dp"
- android:layout_centerVertical="true"
+ android:layout_width="35dp"
+ android:layout_height="35dp"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:layout_gravity="center_vertical"
android:contentDescription="@string/next" />
<ImageView
- android:id="@+id/find_previous"
- android:src="@drawable/previous"
- android:layout_toStartOf="@id/find_next"
- android:layout_width="30dp"
- android:layout_height="30dp"
- android:layout_centerVertical="true"
- android:contentDescription="@string/previous" />
-
- <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. -->
- <EditText
- android:id="@+id/find_on_page_edittext"
- android:layout_toStartOf="@id/find_previous"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:hint="@string/find_on_page"
- android:imeOptions="actionGo" />
-
-
-</RelativeLayout>
\ No newline at end of file
+ android:id="@+id/close_find"
+ android:src="@drawable/close"
+ android:layout_width="35dp"
+ android:layout_height="35dp"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="8dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/close"
+ android:onClick="closeFindOnPage" />
+</LinearLayout>
\ No newline at end of file
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.stoutner.privacybrowser.MainWebViewActivity"
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:focusable="true"
android:focusableInTouchMode="true" >
<!-- The purpose of the LinearLayout is to place the included main_webview below appBarLayout. -->
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_width="match_parent"
+ android:orientation="vertical" >
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:theme="@style/AppBarOverlay" >
- <android.support.v7.widget.Toolbar
- android:id="@+id/appBar"
- android:layout_width="match_parent"
+ <!-- The `FrameLayout` allows `appBar` and `find_on_page_app_bar` to occupy the same space. -->
+ <FrameLayout
android:layout_height="wrap_content"
- android:background="@color/grey_100"
- app:popupTheme="@style/LightPopupOverlay" />
+ android:layout_width="match_parent" >
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/appBar"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="@color/grey_100"
+ app:popupTheme="@style/LightPopupOverlay" />
+
+ <include layout="@layout/find_on_page_app_bar" />
+ </FrameLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/main_webview" />
The `FrameLayout` needs to be before the `NavigationView` or touches on the navigation drawer will not work after exiting full screen video using the back button.-->
<FrameLayout
android:id="@+id/fullScreenVideoFrameLayout"
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:visibility="gone"
android:background="@color/black" />
<!-- The navigation drawer. -->
<android.support.design.widget.NavigationView
android:id="@+id/navigationView"
- android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_header"
app:menu="@menu/webview_navigation_menu"
</menu>
</item>
- <!--
<item
android:id="@+id/find_on_page"
android:title="@string/find_on_page"
android:orderInCategory="100"
app:showAsAction="never|collapseActionView" />
- -->
<item
android:id="@+id/share"