2727import android .view .SubMenu ;
2828import android .view .View ;
2929import android .view .ViewGroup ;
30+ import android .view .ViewStub ;
3031import android .view .Window ;
3132import android .view .WindowManager ;
3233import android .webkit .JavascriptInterface ;
@@ -96,6 +97,7 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do
9697
9798 private HighlightingEditor _hlEditor ;
9899 private WebView _webView ;
100+ private ViewStub _webViewStub ;
99101 private MarkorWebViewClient _webViewClient ;
100102 private ViewGroup _editorHolder ;
101103 private ViewGroup _textActionsBar ;
@@ -141,7 +143,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
141143 _hlEditor = view .findViewById (R .id .document__fragment__edit__highlighting_editor );
142144 _editorHolder = view .findViewById (R .id .document__fragment__edit__editor_holder );
143145 _textActionsBar = view .findViewById (R .id .document__fragment__edit__text_actions_bar );
144- _webView = view .findViewById (R .id .document__fragment_view_webview );
146+ _webViewStub = view .findViewById (R .id .document__fragment_webview_stub );
145147 _verticalScrollView = view .findViewById (R .id .document__fragment__edit__content_editor__scrolling_parent );
146148 _lineNumbersView = view .findViewById (R .id .document__fragment__edit__line_numbers_view );
147149 _cu = new MarkorContextUtils (activity );
@@ -161,34 +163,6 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
161163 _lineNumbersView .setup (_hlEditor );
162164 _lineNumbersView .setLineNumbersEnabled (_appSettings .getDocumentLineNumbersEnabled (_document .path ));
163165
164- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP && _appSettings .getSetWebViewFulldrawing ()) {
165- WebView .enableSlowWholeDocumentDraw ();
166- }
167-
168- _webViewClient = new MarkorWebViewClient (_webView , activity );
169- _webView .setWebChromeClient (new GsWebViewChromeClient (_webView , activity , view .findViewById (R .id .document__fragment_fullscreen_overlay )));
170- _webView .setWebViewClient (_webViewClient );
171- _webView .addJavascriptInterface (this , "Android" );
172- _webView .setBackgroundColor (Color .TRANSPARENT );
173- WebSettings webSettings = _webView .getSettings ();
174- webSettings .setBuiltInZoomControls (true );
175- webSettings .setDisplayZoomControls (false );
176- webSettings .setTextZoom ((int ) (_appSettings .getDocumentViewFontSize (_document .path ) * VIEW_FONT_SCALE ));
177- webSettings .setCacheMode (WebSettings .LOAD_CACHE_ELSE_NETWORK );
178- webSettings .setDatabaseEnabled (true );
179- webSettings .setGeolocationEnabled (false );
180- webSettings .setJavaScriptEnabled (true );
181- webSettings .setDomStorageEnabled (true );
182- webSettings .setAllowFileAccess (true );
183- webSettings .setAllowContentAccess (true );
184- webSettings .setAllowFileAccessFromFileURLs (true );
185- webSettings .setAllowUniversalAccessFromFileURLs (false );
186- webSettings .setMediaPlaybackRequiresUserGesture (false );
187-
188- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP && BuildConfig .IS_TEST_BUILD && BuildConfig .DEBUG ) {
189- WebView .setWebContentsDebuggingEnabled (true ); // Inspect on computer chromium browser: chrome://inspect/#devices
190- }
191-
192166 // Upon construction, the document format has been determined from extension etc
193167 // Here we replace it with the last saved format.
194168 applyTextFormat (_appSettings .getDocumentFormat (_document .path , _document .getFormat ()));
@@ -259,12 +233,14 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
259233 });
260234 }
261235
262- _verticalScrollView . getViewTreeObserver (). addOnGlobalLayoutListener ( () -> _hlEditor .post (() -> {
236+ final Runnable ensureMinHeight = () -> _hlEditor .post (() -> {
263237 final int height = _verticalScrollView .getHeight ();
264- if (height != _hlEditor .getMinHeight ()) {
238+ if (height > 0 && height != _hlEditor .getMinHeight ()) {
265239 _hlEditor .setMinHeight (height );
266240 }
267- }));
241+ });
242+ _verticalScrollView .addOnLayoutChangeListener ((v , left , top , right , bottom , oldLeft , oldTop , oldRight , oldBottom ) -> ensureMinHeight .run ());
243+ _verticalScrollView .post (ensureMinHeight );
268244 }
269245
270246 @ Override
@@ -289,7 +265,9 @@ protected void onFragmentFirstTimeVisible() {
289265
290266 @ Override
291267 public void onResume () {
292- _webView .onResume ();
268+ if (_webView != null ) {
269+ _webView .onResume ();
270+ }
293271 loadDocument ();
294272 if (_editTextUndoRedoHelper != null && _editTextUndoRedoHelper .getTextView () != _hlEditor ) {
295273 _editTextUndoRedoHelper .setTextView (_hlEditor );
@@ -300,7 +278,9 @@ public void onResume() {
300278 @ Override
301279 public void onPause () {
302280 saveDocument (false );
303- _webView .onPause ();
281+ if (_webView != null ) {
282+ _webView .onPause ();
283+ }
304284 _appSettings .addRecentFile (_document .file );
305285 _appSettings .setDocumentPreviewState (_document .path , _isPreviewVisible );
306286 _appSettings .setLastEditPosition (_document .path , TextViewUtils .getSelection (_hlEditor )[0 ]);
@@ -528,16 +508,18 @@ public boolean onOptionsItemSelected(@NonNull final MenuItem item) {
528508 _nextConvertToPrintMode = true ;
529509 setViewModeVisibility (true );
530510 Toast .makeText (activity , R .string .please_wait , Toast .LENGTH_LONG ).show ();
531- _webView .postDelayed (() -> {
532- if (itemId == R .id .action_share_pdf ) {
533- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .KITKAT ) {
534- _cu .printOrCreatePdfFromWebview (_webView , _document , getTextString ().contains ("beamer\n " ));
511+ if (_webView != null ) {
512+ _webView .postDelayed (() -> {
513+ if (itemId == R .id .action_share_pdf ) {
514+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .KITKAT ) {
515+ _cu .printOrCreatePdfFromWebview (_webView , _document , getTextString ().contains ("beamer\n " ));
516+ }
517+ } else {
518+ Bitmap bmp = _cu .getBitmapFromWebView (_webView , itemId == R .id .action_share_image );
519+ _cu .shareImage (getContext (), bmp , null );
535520 }
536- } else {
537- Bitmap bmp = _cu .getBitmapFromWebView (_webView , itemId == R .id .action_share_image );
538- _cu .shareImage (getContext (), bmp , null );
539- }
540- }, 7000 );
521+ }, 7000 );
522+ }
541523 }
542524
543525 return true ;
@@ -625,7 +607,9 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
625607 final int current = _isPreviewVisible ? _appSettings .getDocumentViewFontSize (_document .path ) : _appSettings .getDocumentFontSize (_document .path );
626608 MarkorDialogFactory .showFontSizeDialog (activity , current , (newSize ) -> {
627609 if (_isPreviewVisible ) {
628- _webView .getSettings ().setTextZoom ((int ) (newSize * VIEW_FONT_SCALE ));
610+ if (_webView != null ) {
611+ _webView .getSettings ().setTextZoom ((int ) (newSize * VIEW_FONT_SCALE ));
612+ }
629613 _appSettings .setDocumentViewFontSize (_document .path , newSize );
630614 } else {
631615 _hlEditor .setTextSize (TypedValue .COMPLEX_UNIT_SP , (float ) newSize );
@@ -644,7 +628,6 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
644628 }
645629 }
646630 }
647-
648631 public void checkTextChangeState () {
649632 final boolean isTextChanged = !_document .isContentSame (_hlEditor .getText ());
650633 Drawable d ;
@@ -680,12 +663,14 @@ private void showHideActionBar() {
680663 final View parent = activity .findViewById (R .id .document__fragment__edit__text_actions_bar__scrolling_parent );
681664 final View viewScroll = activity .findViewById (R .id .document__fragment_view_webview );
682665
683- if (bar != null && parent != null && _verticalScrollView != null && viewScroll != null ) {
666+ if (bar != null && parent != null && _verticalScrollView != null ) {
684667 final boolean hide = _textActionsBar .getChildCount () == 0 ;
685668 parent .setVisibility (hide ? View .GONE : View .VISIBLE );
686669 final int marginBottom = hide ? 0 : (int ) getResources ().getDimension (R .dimen .textactions_bar_height );
687670 setMarginBottom (_verticalScrollView , marginBottom );
688- setMarginBottom (viewScroll , marginBottom );
671+ if (viewScroll != null ) {
672+ setMarginBottom (viewScroll , marginBottom );
673+ }
689674 }
690675 }
691676 }
@@ -699,19 +684,33 @@ private void setSearchView(SearchView searchView) {
699684 _menuSearchViewForViewMode .setQueryHint (getString (R .string .search ));
700685 _menuSearchViewForViewMode .setOnQueryTextListener (new SearchView .OnQueryTextListener () {
701686 private String searchText = "" ;
702- private final Runnable searchTask = TextViewUtils .makeDebounced (_webView .getHandler (), 500 , () -> _webView .findAllAsync (searchText ));
687+ private final Runnable searchTask ;
688+
689+ private boolean search (String text ) {
690+ if (_webView == null ) {
691+ return false ;
692+ }
693+ if (searchTask == null ) {
694+ searchTask = TextViewUtils .makeDebounced (_webView .getHandler (), 500 , () -> _webView .findAllAsync (text ));
695+ }
696+
697+ searchText = text ;
698+ searchTask .run ();
699+ return true ;
700+ }
703701
704702 @ Override
705703 public boolean onQueryTextSubmit (String query ) {
706- _webView .findNext (true );
707- return true ;
704+ if (_webView != null ) {
705+ _webView .findNext (true );
706+ return true ;
707+ }
708+ return false ;
708709 }
709710
710711 @ Override
711712 public boolean onQueryTextChange (String text ) {
712- searchText = text ;
713- searchTask .run ();
714- return true ;
713+ return search (text );
715714 }
716715 });
717716
@@ -919,6 +918,9 @@ private boolean isDisplayedAtMainActivity() {
919918 }
920919
921920 public void updateViewModeText () {
921+ if (_webView == null ) {
922+ return ;
923+ }
922924 // Don't let text to view mode crash app
923925 try {
924926 _format .getConverter ().convertMarkupShowInWebView (_document , getTextString (), getActivity (), _webView , _nextConvertToPrintMode , _lineNumbersView .isLineNumbersEnabled ());
@@ -931,6 +933,37 @@ public void setViewModeVisibility(final boolean show) {
931933 setViewModeVisibility (show , true );
932934 }
933935
936+ private void setupWebViewIfNeeded (final Activity activity ) {
937+ if (_webView == null ) {
938+ _webView = (WebView ) _webViewStub .inflate ();
939+ _webView .setWebChromeClient (new GsWebViewChromeClient (_webView , activity , activity .findViewById (R .id .document__fragment_fullscreen_overlay )));
940+ _webView .addJavascriptInterface (this , "Android" );
941+ _webView .setBackgroundColor (Color .TRANSPARENT );
942+ WebSettings webSettings = _webView .getSettings ();
943+ webSettings .setBuiltInZoomControls (true );
944+ webSettings .setDisplayZoomControls (false );
945+ webSettings .setTextZoom ((int ) (_appSettings .getDocumentViewFontSize (_document .path ) * VIEW_FONT_SCALE ));
946+ webSettings .setCacheMode (WebSettings .LOAD_CACHE_ELSE_NETWORK );
947+ webSettings .setDatabaseEnabled (true );
948+ webSettings .setGeolocationEnabled (false );
949+ webSettings .setJavaScriptEnabled (true );
950+ webSettings .setDomStorageEnabled (true );
951+ webSettings .setAllowFileAccess (true );
952+ webSettings .setAllowContentAccess (true );
953+ webSettings .setAllowFileAccessFromFileURLs (true );
954+ webSettings .setAllowUniversalAccessFromFileURLs (false );
955+ webSettings .setMediaPlaybackRequiresUserGesture (false );
956+
957+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP && BuildConfig .IS_TEST_BUILD && BuildConfig .DEBUG ) {
958+ WebView .setWebContentsDebuggingEnabled (true ); // Inspect on computer chromium browser: chrome://inspect/#devices
959+ }
960+
961+ _webViewClient = new MarkorWebViewClient (_webView , activity );
962+ _webView .setWebViewClient (_webViewClient );
963+ }
964+ }
965+
966+ @ SuppressLint ({"AddJavascriptInterface" , "SetJavaScriptEnabled" })
934967 public void setViewModeVisibility (boolean show , final boolean animate ) {
935968 final Activity activity = getActivity ();
936969 if (activity == null ) {
@@ -941,13 +974,16 @@ public void setViewModeVisibility(boolean show, final boolean animate) {
941974 _format .getActions ().recreateActionButtons (_textActionsBar , show ? ActionButtonBase .ActionItem .DisplayMode .VIEW : ActionButtonBase .ActionItem .DisplayMode .EDIT );
942975 showHideActionBar ();
943976 if (show ) {
977+ setupWebViewIfNeeded (activity );
944978 updateViewModeText ();
945979 _cu .showSoftKeyboard (activity , false , _hlEditor );
946980 _hlEditor .clearFocus ();
947981 _hlEditor .postDelayed (() -> _cu .showSoftKeyboard (activity , false , _hlEditor ), 300 );
948982 GsContextUtils .fadeInOut (_webView , _verticalScrollView , animate );
949983 } else {
950- _webViewClient .setRestoreScrollY (_webView .getScrollY ());
984+ if (_webView != null ) {
985+ _webViewClient .setRestoreScrollY (_webView .getScrollY ());
986+ }
951987 GsContextUtils .fadeInOut (_verticalScrollView , _webView , animate );
952988 }
953989
@@ -986,10 +1022,12 @@ protected boolean onToolbarLongClicked(View v) {
9861022
9871023 @ Override
9881024 public void onDestroy () {
989- try {
990- _webView .loadUrl ("about:blank" );
991- _webView .destroy ();
992- } catch (Exception ignored ) {
1025+ if (_webView != null ) {
1026+ try {
1027+ _webView .loadUrl ("about:blank" );
1028+ _webView .destroy ();
1029+ } catch (Exception ignored ) {
1030+ }
9931031 }
9941032 super .onDestroy ();
9951033 }
0 commit comments