Mholloway has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/379819 )

Change subject: Hygiene: Page load cleanup
......................................................................

Hygiene: Page load cleanup

* Removes all page load logic from PageActivity.
* Reorganizes the contents of PageActivity and PageFragment to something
  more logical.
* Streamlines things where possible.

Bug: T150797
Change-Id: I0f526705a50f82d3ac78f808c23b5b48cff58d80
---
M app/src/main/java/org/wikipedia/LongPressHandler.java
M app/src/main/java/org/wikipedia/main/MainActivity.java
M app/src/main/java/org/wikipedia/page/PageActivity.java
M app/src/main/java/org/wikipedia/page/PageContainerLongPressHandler.java
M app/src/main/java/org/wikipedia/page/PageFragment.java
M app/src/main/java/org/wikipedia/page/PageInfoDialog.java
D app/src/main/java/org/wikipedia/page/PageLoadCallbacks.java
M app/src/main/java/org/wikipedia/page/bottomcontent/BottomContentHandler.java
M app/src/main/java/org/wikipedia/search/SearchResultsFragment.java
9 files changed, 494 insertions(+), 702 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/19/379819/1

diff --git a/app/src/main/java/org/wikipedia/LongPressHandler.java 
b/app/src/main/java/org/wikipedia/LongPressHandler.java
index a7b812e..d4508f2 100644
--- a/app/src/main/java/org/wikipedia/LongPressHandler.java
+++ b/app/src/main/java/org/wikipedia/LongPressHandler.java
@@ -73,10 +73,10 @@
     public boolean onMenuItemClick(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.menu_long_press_open_page:
-                contextMenuListener.onOpenLink(title, entry);
+                contextMenuListener.onOpenLink(entry);
                 return true;
             case R.id.menu_long_press_open_in_new_tab:
-                contextMenuListener.onOpenInNewTab(title, entry);
+                contextMenuListener.onOpenInNewTab(entry);
                 return true;
             case R.id.menu_long_press_copy_page:
                 contextMenuListener.onCopyLink(title);
@@ -94,8 +94,8 @@
     }
 
     public interface ContextMenuListener {
-        void onOpenLink(PageTitle title, HistoryEntry entry);
-        void onOpenInNewTab(PageTitle title, HistoryEntry entry);
+        void onOpenLink(HistoryEntry entry);
+        void onOpenInNewTab(HistoryEntry entry);
         void onCopyLink(PageTitle title);
         void onShareLink(PageTitle title);
         void onAddToList(PageTitle title, AddToReadingListDialog.InvokeSource 
source);
diff --git a/app/src/main/java/org/wikipedia/main/MainActivity.java 
b/app/src/main/java/org/wikipedia/main/MainActivity.java
index cb0c8e8..004f1f1 100644
--- a/app/src/main/java/org/wikipedia/main/MainActivity.java
+++ b/app/src/main/java/org/wikipedia/main/MainActivity.java
@@ -5,10 +5,14 @@
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v7.preference.PreferenceManager;
 import android.support.v7.view.ActionMode;
 import android.view.View;
 
+import net.hockeyapp.android.metrics.MetricsManager;
+
 import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
 import org.wikipedia.activity.SingleFragmentToolbarActivity;
 import org.wikipedia.appshortcuts.AppShortcuts;
 import org.wikipedia.navtab.NavTab;
@@ -20,6 +24,8 @@
 public class MainActivity extends SingleFragmentToolbarActivity<MainFragment>
         implements MainFragment.Callback {
 
+    private WikipediaApp app = WikipediaApp.getInstance();
+
     public static Intent newIntent(@NonNull Context context) {
         return new Intent(context, MainActivity.class);
     }
@@ -29,6 +35,10 @@
         super.onCreate(savedInstanceState);
         setSharedElementTransitions();
         new AppShortcuts().init();
+        MetricsManager.register(app, app);
+        app.checkCrashes(this);
+
+        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
 
         //TODO: remove pre-beta feature flag when ready.
         if (ReleaseUtil.isPreBetaRelease()
diff --git a/app/src/main/java/org/wikipedia/page/PageActivity.java 
b/app/src/main/java/org/wikipedia/page/PageActivity.java
index f9af558..8f40169 100644
--- a/app/src/main/java/org/wikipedia/page/PageActivity.java
+++ b/app/src/main/java/org/wikipedia/page/PageActivity.java
@@ -1,7 +1,6 @@
 package org.wikipedia.page;
 
 import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
 import android.app.SearchManager;
 import android.appwidget.AppWidgetManager;
 import android.content.ComponentName;
@@ -9,34 +8,26 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.location.Location;
-import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
 import android.support.design.widget.BottomSheetDialog;
 import android.support.design.widget.BottomSheetDialogFragment;
 import android.support.v4.app.Fragment;
 import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.preference.PreferenceManager;
 import android.support.v7.widget.Toolbar;
-import android.text.format.DateUtils;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.Toast;
 
 import com.squareup.otto.Bus;
 import com.squareup.otto.Subscribe;
-
-import net.hockeyapp.android.metrics.MetricsManager;
 
 import org.apache.commons.lang3.StringUtils;
 import org.wikipedia.Constants;
@@ -44,44 +35,29 @@
 import org.wikipedia.WikipediaApp;
 import org.wikipedia.activity.BaseActivity;
 import org.wikipedia.analytics.IntentFunnel;
-import org.wikipedia.analytics.LinkPreviewFunnel;
 import org.wikipedia.dataclient.WikiSite;
 import org.wikipedia.descriptions.DescriptionEditRevertHelpView;
 import org.wikipedia.events.ChangeTextSizeEvent;
-import org.wikipedia.feed.continuereading.ContinueReadingCard;
-import org.wikipedia.feed.continuereading.ContinueReadingClient;
-import org.wikipedia.feed.dataclient.FeedClient;
-import org.wikipedia.feed.mainpage.MainPageClient;
-import org.wikipedia.feed.model.Card;
 import org.wikipedia.gallery.GalleryActivity;
 import org.wikipedia.history.HistoryEntry;
 import org.wikipedia.language.LangLinksActivity;
 import org.wikipedia.page.linkpreview.LinkPreviewDialog;
-import org.wikipedia.page.tabs.TabsProvider;
-import org.wikipedia.page.tabs.TabsProvider.TabPosition;
-import org.wikipedia.random.RandomArticleRequestHandler;
 import org.wikipedia.readinglist.AddToReadingListDialog;
 import org.wikipedia.search.SearchFragment;
 import org.wikipedia.search.SearchInvokeSource;
 import org.wikipedia.settings.SettingsActivity;
 import org.wikipedia.theme.ThemeChooserDialog;
-import org.wikipedia.useroption.sync.UserOptionContentResolver;
 import org.wikipedia.util.ClipboardUtil;
-import org.wikipedia.util.DeviceUtil;
 import org.wikipedia.util.FeedbackUtil;
 import org.wikipedia.util.ShareUtil;
-import org.wikipedia.util.log.L;
 import org.wikipedia.widgets.WidgetProviderFeaturedPage;
 import org.wikipedia.wiktionary.WiktionaryDialog;
-
-import java.util.List;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.Unbinder;
 
-import static org.wikipedia.settings.Prefs.isLinkPreviewEnabled;
-import static org.wikipedia.util.UriUtil.visitInExternalBrowser;
+import static org.wikipedia.util.DeviceUtil.hideSoftKeyboard;
 
 public class PageActivity extends BaseActivity implements 
PageFragment.Callback,
         LinkPreviewDialog.Callback, SearchFragment.Callback, 
ThemeChooserDialog.Callback,
@@ -95,46 +71,52 @@
     public static final String EXTRA_HISTORYENTRY  = 
"org.wikipedia.history.historyentry";
     public static final String ACTION_APP_SHORTCUT = 
"org.wikipedia.app_shortcut";
 
-    private static final String LANGUAGE_CODE_BUNDLE_KEY = "language";
+    private static final String IS_SEARCHING = "isSearching";
 
-    @BindView(R.id.tabs_container) View tabsContainerView;
+    @BindView(R.id.tabs_container) FrameLayout tabsContainerView;
     @BindView(R.id.page_progress_bar) ProgressBar progressBar;
-    @BindView(R.id.page_toolbar_container) View toolbarContainerView;
+    @BindView(R.id.page_toolbar_container) LinearLayout toolbarContainerView;
     @BindView(R.id.page_toolbar) Toolbar toolbar;
+
     @Nullable private Unbinder unbinder;
-
-    private PageFragment pageFragment;
-
-    private WikipediaApp app;
     @Nullable private Bus bus;
+    private PageFragment pageFragment;
+    private WikipediaApp app = WikipediaApp.getInstance();
     private EventBusMethods busMethods;
     private ActionMode currentActionMode;
-
     private PageToolbarHideHandler toolbarHideHandler;
-
     private ExclusiveBottomSheetPresenter bottomSheetPresenter = new 
ExclusiveBottomSheetPresenter();
-    @Nullable private PageLoadCallbacks pageLoadCallbacks;
-
-    private DialogInterface.OnDismissListener listDialogDismissListener = new 
DialogInterface.OnDismissListener() {
-        @Override
-        public void onDismiss(DialogInterface dialogInterface) {
-            pageFragment.updateBookmarkFromDao();
-        }
-    };
+    private DialogInterface.OnDismissListener listDialogDismissListener = new 
ListDialogDismissListener();
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        app = (WikipediaApp) getApplicationContext();
-        MetricsManager.register(app, app);
-        app.checkCrashes(this);
+        setContentView(R.layout.activity_page);
+        unbinder = ButterKnife.bind(this);
+        busMethods = new EventBusMethods();
+        registerBus();
 
-        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+        pageFragment = (PageFragment) 
getSupportFragmentManager().findFragmentById(R.id.page_fragment);
+        toolbarHideHandler = new PageToolbarHideHandler(toolbarContainerView);
 
+        setSupportActionBar(toolbar);
+        clearActionBarTitle();
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        updateProgressBar(false, true, 0);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        handleIntent(getIntent());
+    }
+
+    @Override
+    public void setContentView(View v) {
         try {
-            setContentView(R.layout.activity_page);
+            super.setContentView(v);
         } catch (Exception e) {
-            if (e.getMessage().contains("WebView")) {
+            if (e.getMessage().toLowerCase().contains("webview")) {
                 // If the system failed to inflate our activity because of the 
WebView (which could
                 // be one of several types of exceptions), it likely means 
that the system WebView
                 // is in the process of being updated. In this case, show the 
user a message and
@@ -145,55 +127,79 @@
             }
             throw e;
         }
+    }
 
-        unbinder = ButterKnife.bind(this);
+    @Override
+    protected void onResume() {
+        super.onResume();
+        app.resetWikiSite();
+        app.getSessionFunnel().touchSession();
+    }
 
-        busMethods = new EventBusMethods();
-        registerBus();
-
-        updateProgressBar(false, true, 0);
-
-        pageFragment = (PageFragment) 
getSupportFragmentManager().findFragmentById(R.id.page_fragment);
-
-        setSupportActionBar(toolbar);
-        clearActionBarTitle();
-        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
-        toolbarHideHandler = new PageToolbarHideHandler(toolbarContainerView);
-
-        boolean languageChanged = false;
-        if (savedInstanceState != null) {
-            if (savedInstanceState.getBoolean("isSearching")) {
-                openSearchFragment(SearchInvokeSource.TOOLBAR, null);
-            }
-            String language = 
savedInstanceState.getString(LANGUAGE_CODE_BUNDLE_KEY);
-            languageChanged = 
!app.getAppOrSystemLanguageCode().equals(language);
-
-            // Note: when system language is enabled, and the system language 
is changed outside of
-            // the app, MRU languages are not updated. There's no harm in 
doing that here but since
-            // the user didn't choose that language in app, it may be 
unexpected.
+    @Override
+    public void onPause() {
+        if (isCabOpen()) {
+            // Explicitly close any current ActionMode (see T147191)
+            currentActionMode.finish();
         }
+        super.onPause();
+    }
 
-        if (languageChanged) {
-            app.resetWikiSite();
-            loadMainPageInForegroundTab();
-        }
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(IS_SEARCHING, isSearching());
+    }
 
-        if (savedInstanceState == null) {
-            // if there's no savedInstanceState, and we're not coming back 
from a Theme change,
-            // then we must have been launched with an Intent, so... handle it!
-            handleIntent(getIntent());
-
-            UserOptionContentResolver.requestManualSync();
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        if (savedInstanceState.getBoolean(IS_SEARCHING)) {
+            openSearchFragment(SearchInvokeSource.TOOLBAR, null);
         }
     }
 
-    private void finishActionMode() {
-        currentActionMode.finish();
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, final Intent 
data) {
+        if (requestCode == SettingsActivity.ACTIVITY_REQUEST_SHOW_SETTINGS) {
+            handleSettingsActivityResult(resultCode);
+        } else if (newArticleLanguageSelected(requestCode, resultCode) || 
galleryPageSelected(requestCode, resultCode)) {
+            handleLangLinkOrPageResult(data);
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
     }
 
-    public void hideSoftKeyboard() {
-        DeviceUtil.hideSoftKeyboard(this);
+    @Override
+    protected void onStop() {
+        app.getSessionFunnel().persistSession();
+        super.onStop();
+    }
+
+    @Override
+    public void onDestroy() {
+        if (unbinder != null) {
+            unbinder.unbind();
+        }
+        unregisterBus();
+        super.onDestroy();
+    }
+
+    @Override
+    public void onActionModeStarted(ActionMode mode) {
+        super.onActionModeStarted(mode);
+        if (!isCabOpen() && mode.getTag() == null) {
+            Menu menu = mode.getMenu();
+            menu.clear();
+            mode.getMenuInflater().inflate(R.menu.menu_text_select, menu);
+            pageFragment.onActionModeShown(mode);
+        }
+    }
+
+    @Override
+    public void onActionModeFinished(android.view.ActionMode mode) {
+        super.onActionModeFinished(mode);
+        currentActionMode = null;
     }
 
     @Override
@@ -216,6 +222,24 @@
         showToolbar();
         openSearchFragment(SearchInvokeSource.TOOLBAR, null);
         return true;
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        handleIntent(intent);
+    }
+
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if ((event.isCtrlPressed() && keyCode == KeyEvent.KEYCODE_F)
+                || (!event.isCtrlPressed() && keyCode == KeyEvent.KEYCODE_F3)) 
{
+            pageFragment.showFindInPage();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
     }
 
     public void showToolbar() {
@@ -262,51 +286,6 @@
         return new Intent(ACTION_SHOW_TAB_LIST).setClass(context, 
PageActivity.class);
     }
 
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        setIntent(intent);
-        handleIntent(intent);
-    }
-
-    private void handleIntent(@NonNull Intent intent) {
-        if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() 
!= null) {
-            WikiSite wiki = new WikiSite(intent.getData().getAuthority());
-            PageTitle title = wiki.titleForUri(intent.getData());
-            HistoryEntry historyEntry = new HistoryEntry(title, 
HistoryEntry.SOURCE_EXTERNAL_LINK);
-            loadPageInForegroundTab(title, historyEntry);
-        } else if (ACTION_LOAD_IN_NEW_TAB.equals(intent.getAction())
-                || ACTION_LOAD_IN_CURRENT_TAB.equals(intent.getAction())) {
-            PageTitle title = intent.getParcelableExtra(EXTRA_PAGETITLE);
-            HistoryEntry historyEntry = 
intent.getParcelableExtra(EXTRA_HISTORYENTRY);
-            if (ACTION_LOAD_IN_NEW_TAB.equals(intent.getAction())) {
-                loadPageInForegroundTab(title, historyEntry);
-            } else if (ACTION_LOAD_IN_CURRENT_TAB.equals(intent.getAction())) {
-                loadPageInCurrentTab(title, historyEntry);
-            }
-            if (intent.hasExtra(Constants.INTENT_EXTRA_REVERT_QNUMBER)) {
-                
showDescriptionEditRevertDialog(intent.getStringExtra(Constants.INTENT_EXTRA_REVERT_QNUMBER));
-            }
-        } else if (ACTION_SHOW_TAB_LIST.equals(intent.getAction())
-                || ACTION_RESUME_READING.equals(intent.getAction())) {
-            // do nothing, since this will be handled indirectly by 
PageFragment.
-        } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
-            String query = intent.getStringExtra(SearchManager.QUERY);
-            PageTitle title = new PageTitle(query, app.getWikiSite());
-            HistoryEntry historyEntry = new HistoryEntry(title, 
HistoryEntry.SOURCE_SEARCH);
-            loadPageInForegroundTab(title, historyEntry);
-        } else if 
(intent.hasExtra(Constants.INTENT_FEATURED_ARTICLE_FROM_WIDGET)) {
-            new IntentFunnel(app).logFeaturedArticleWidgetTap();
-            loadMainPageInForegroundTab();
-        } else if (intent.hasExtra(Constants.INTENT_APP_SHORTCUT_RANDOM)) {
-            loadRandomPage();
-        } else if 
(intent.hasExtra(Constants.INTENT_APP_SHORTCUT_CONTINUE_READING)) {
-            loadContinueReadingPage();
-        } else {
-            loadMainPageInCurrentTab();
-        }
-    }
-
     /**
      * Update the state of the main progress bar that is shown inside the 
ActionBar of the activity.
      * @param visible Whether the progress bar is visible.
@@ -331,121 +310,6 @@
         return searchFragment != null && searchFragment.isSearchActive();
     }
 
-    /**
-     * Load a new page, and put it on top of the backstack.
-     * @param title Title of the page to load.
-     * @param entry HistoryEntry associated with this page.
-     */
-    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry) {
-        loadPage(title, entry, TabPosition.CURRENT_TAB);
-    }
-
-    /**
-     * Load a new page, and put it on top of the backstack, optionally 
allowing state loss of the
-     * fragment manager. Useful for when this function is called from an 
AsyncTask result.
-     * @param title Title of the page to load.
-     * @param entry HistoryEntry associated with this page.
-     * @param position Whether to open this page in the current tab, a new 
background tab, or new
-     *                 foreground tab.
-     */
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    public void loadPage(@NonNull final PageTitle title,
-                         @NonNull final HistoryEntry entry,
-                         @NonNull final TabPosition position) {
-        if (isDestroyed()) {
-            return;
-        }
-
-        if (entry.getSource() != HistoryEntry.SOURCE_INTERNAL_LINK || 
!isLinkPreviewEnabled()) {
-            new LinkPreviewFunnel(app, entry.getSource()).logNavigate();
-        }
-
-        app.putCrashReportProperty("api", title.getWikiSite().authority());
-        app.putCrashReportProperty("title", title.toString());
-
-        if (title.isSpecial()) {
-            visitInExternalBrowser(this, Uri.parse(title.getMobileUri()));
-            return;
-        }
-
-        tabsContainerView.post(new Runnable() {
-            @Override
-            public void run() {
-                if (!pageFragment.isAdded()) {
-                    return;
-                }
-                // Close the link preview, if one is open.
-                hideLinkPreview();
-
-                pageFragment.closeFindInPage();
-                if (position == TabPosition.CURRENT_TAB) {
-                    pageFragment.loadPage(title, entry, true);
-                } else if (position == TabPosition.NEW_TAB_BACKGROUND) {
-                    pageFragment.openInNewBackgroundTabFromMenu(title, entry);
-                } else {
-                    pageFragment.openInNewForegroundTabFromMenu(title, entry);
-                }
-                app.getSessionFunnel().pageViewed(entry);
-            }
-        });
-    }
-
-    public void loadPageInForegroundTab(@NonNull PageTitle title, @NonNull 
HistoryEntry entry) {
-        loadPage(title, entry, TabPosition.NEW_TAB_FOREGROUND);
-    }
-
-    public void loadPageInCurrentTab(@NonNull PageTitle title, @NonNull 
HistoryEntry entry) {
-        loadPage(title, entry, TabPosition.CURRENT_TAB);
-    }
-
-    public void loadMainPageInForegroundTab() {
-        loadMainPage(TabPosition.NEW_TAB_FOREGROUND);
-    }
-
-    private void loadMainPageInCurrentTab() {
-        loadMainPage(TabPosition.CURRENT_TAB);
-    }
-
-    /**
-     * Go directly to the Main Page of the current Wiki, optionally allowing 
state loss of the
-     * fragment manager. Useful for when this function is called from an 
AsyncTask result.
-     */
-    public void loadMainPage(TabPosition position) {
-        PageTitle title = MainPageClient.getMainPageTitle();
-        HistoryEntry historyEntry = new HistoryEntry(title, 
HistoryEntry.SOURCE_MAIN_PAGE);
-        loadPage(title, historyEntry, position);
-    }
-
-    private void loadContinueReadingPage() {
-        new ContinueReadingClient().request(this, app.getWikiSite(), 1, new 
FeedClient.Callback() {
-            @Override
-            public void success(@NonNull List<? extends Card> cards) {
-                ContinueReadingCard card = (ContinueReadingCard) cards.get(0); 
// top?
-                loadPageInForegroundTab(card.pageTitle(), new 
HistoryEntry(card.pageTitle(), 
HistoryEntry.SOURCE_APP_SHORTCUT_CONTINUE_READING));
-            }
-
-            @Override
-            public void error(@NonNull Throwable caught) {
-                loadMainPageInForegroundTab();
-            }
-        });
-    }
-
-    private void loadRandomPage() {
-        RandomArticleRequestHandler.getRandomPage(new 
RandomArticleRequestHandler.Callback() {
-            @Override
-            public void onSuccess(@NonNull PageTitle pageTitle) {
-                loadPageInForegroundTab(pageTitle, new HistoryEntry(pageTitle, 
HistoryEntry.SOURCE_APP_SHORTCUT_RANDOM));
-            }
-
-            @Override
-            public void onError(Throwable t) {
-                loadMainPageInForegroundTab();
-            }
-        });
-
-    }
-
     public void showLinkPreview(@NonNull PageTitle title, int entrySource) {
         showLinkPreview(title, entrySource, null);
     }
@@ -453,10 +317,6 @@
     public void showLinkPreview(@NonNull PageTitle title, int entrySource, 
@Nullable Location location) {
         bottomSheetPresenter.show(getSupportFragmentManager(),
                 LinkPreviewDialog.newInstance(title, entrySource, location));
-    }
-
-    private void hideLinkPreview() {
-        bottomSheetPresenter.dismiss(getSupportFragmentManager());
     }
 
     public void showAddToListDialog(@NonNull PageTitle title, @NonNull 
AddToReadingListDialog.InvokeSource source) {
@@ -467,7 +327,7 @@
     @Override
     public void onBackPressed() {
         if (isCabOpen()) {
-            finishActionMode();
+            currentActionMode.finish();
             return;
         }
 
@@ -507,18 +367,14 @@
     }
 
     @Override
-    public void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry) {
-        loadPage(title, entry);
+    public void onPageLoadPage(@NonNull HistoryEntry entry) {
+        hideLinkPreview();
+        app.getSessionFunnel().pageViewed(entry);
     }
 
     @Override
     public void onPageShowLinkPreview(@NonNull PageTitle title, int source) {
         showLinkPreview(title, source);
-    }
-
-    @Override
-    public void onPageLoadMainPageInForegroundTab() {
-        loadMainPageInForegroundTab();
     }
 
     @Override
@@ -555,19 +411,7 @@
 
     @Override
     public void onPageHideSoftKeyboard() {
-        hideSoftKeyboard();
-    }
-
-    @Nullable
-    @Override
-    public PageLoadCallbacks onPageGetPageLoadCallbacks() {
-        return pageLoadCallbacks;
-    }
-
-    @Override
-    public void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry,
-                               @NonNull TabPosition tabPosition) {
-        loadPage(title, entry, tabPosition);
+        hideSoftKeyboard(this);
     }
 
     @Override
@@ -581,7 +425,7 @@
         if (!pageFragment.isAdded()) {
             return;
         }
-        FeedbackUtil.showMessage(getActivity(),
+        FeedbackUtil.showMessage(this,
                 getString(R.string.reading_list_item_deleted, 
title.getDisplayText()));
         pageFragment.updateBookmarkFromDao();
     }
@@ -625,8 +469,11 @@
 
     @Override
     public void onSearchSelectPage(@NonNull HistoryEntry entry, boolean 
inNewTab) {
-        loadPage(entry.getTitle(), entry, inNewTab ? 
TabsProvider.TabPosition.NEW_TAB_BACKGROUND
-                : TabsProvider.TabPosition.CURRENT_TAB);
+        if (inNewTab) {
+            pageFragment.openInNewBackgroundTab(entry);
+        } else {
+            pageFragment.loadPage(entry);
+        }
     }
 
     @Override
@@ -641,7 +488,7 @@
             closeSearchFragment(fragment);
         }
         toolbarContainerView.setVisibility(View.VISIBLE);
-        hideSoftKeyboard();
+        hideSoftKeyboard(this);
     }
 
     @Override
@@ -656,7 +503,11 @@
 
     @Override
     public void onLinkPreviewLoadPage(@NonNull PageTitle title, @NonNull 
HistoryEntry entry, boolean inNewTab) {
-        loadPage(title, entry, inNewTab ? TabPosition.NEW_TAB_BACKGROUND : 
TabPosition.CURRENT_TAB);
+        if (inNewTab) {
+            pageFragment.openInNewBackgroundTab(entry);
+        } else {
+            pageFragment.loadPage(entry);
+        }
     }
 
     @Override
@@ -704,6 +555,66 @@
         pageFragment.refreshPage(pageFragment.getWebView().getScrollY());
     }
 
+    protected void clearActionBarTitle() {
+        getSupportActionBar().setTitle("");
+    }
+
+    private void handleIntent(@NonNull Intent intent) {
+        if (pageFragment == null) {
+            return;
+        }
+        if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() 
!= null) {
+            handleIntentActionView(intent);
+        } else if (ACTION_LOAD_IN_NEW_TAB.equals(intent.getAction())
+                || ACTION_LOAD_IN_CURRENT_TAB.equals(intent.getAction())) {
+            handleIntentActionLoadInTab(intent);
+        } else if (ACTION_SHOW_TAB_LIST.equals(intent.getAction())
+                || ACTION_RESUME_READING.equals(intent.getAction())) {
+            // do nothing, since this will be handled indirectly by 
PageFragment.
+        } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
+            handleIntentActionSearch(intent);
+        } else if 
(intent.hasExtra(Constants.INTENT_FEATURED_ARTICLE_FROM_WIDGET)) {
+            handleIntentFeaturedArticleFromWidget();
+        } else if (intent.hasExtra(Constants.INTENT_APP_SHORTCUT_RANDOM)) {
+            pageFragment.loadRandomPage();
+        } else if 
(intent.hasExtra(Constants.INTENT_APP_SHORTCUT_CONTINUE_READING)) {
+            pageFragment.loadContinueReadingPage();
+        } else {
+            pageFragment.loadMainPage();
+        }
+    }
+
+    private void handleIntentActionView(@NonNull Intent intent) {
+        WikiSite wiki = new WikiSite(intent.getData().getAuthority());
+        PageTitle title = wiki.titleForUri(intent.getData());
+        HistoryEntry entry = new HistoryEntry(title, 
HistoryEntry.SOURCE_EXTERNAL_LINK);
+        pageFragment.openInNewForegroundTab(entry);
+    }
+
+    private void handleIntentActionLoadInTab(@NonNull Intent intent) {
+        HistoryEntry entry = intent.getParcelableExtra(EXTRA_HISTORYENTRY);
+        if (ACTION_LOAD_IN_NEW_TAB.equals(intent.getAction())) {
+            pageFragment.openInNewForegroundTab(entry);
+        } else if (ACTION_LOAD_IN_CURRENT_TAB.equals(intent.getAction())) {
+            pageFragment.loadPage(entry);
+        }
+        if (intent.hasExtra(Constants.INTENT_EXTRA_REVERT_QNUMBER)) {
+            
showDescriptionEditRevertDialog(intent.getStringExtra(Constants.INTENT_EXTRA_REVERT_QNUMBER));
+        }
+    }
+
+    private void handleIntentActionSearch(@NonNull Intent intent) {
+        String query = intent.getStringExtra(SearchManager.QUERY);
+        PageTitle title = new PageTitle(query, app.getWikiSite());
+        HistoryEntry entry = new HistoryEntry(title, 
HistoryEntry.SOURCE_SEARCH);
+        pageFragment.openInNewForegroundTab(entry);
+    }
+
+    private void handleIntentFeaturedArticleFromWidget() {
+        new IntentFunnel(app).logFeaturedArticleWidgetTap();
+        pageFragment.loadMainPage();
+    }
+
     private void copyLink(@NonNull String url) {
         ClipboardUtil.setPlainText(this, null, url);
     }
@@ -712,104 +623,14 @@
         FeedbackUtil.showMessage(this, R.string.address_copied);
     }
 
-    @Nullable
-    @Override
-    public AppCompatActivity getActivity() {
-        return this;
-    }
-
     private boolean shouldRecreateMainActivity() {
         return getIntent().getAction() == null
                 || getIntent().getAction().equals(Intent.ACTION_VIEW);
     }
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-        app.resetWikiSite();
-        app.getSessionFunnel().touchSession();
-    }
-
-    @Override
-    public void onPause() {
-        if (isCabOpen()) {
-            // Explicitly close any current ActionMode (see T147191)
-            finishActionMode();
-        }
-        super.onPause();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        saveState(outState);
-    }
-
-    private void saveState(@NonNull Bundle outState) {
-        outState.putBoolean("isSearching", isSearching());
-        outState.putString(LANGUAGE_CODE_BUNDLE_KEY, 
app.getAppOrSystemLanguageCode());
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, final Intent 
data) {
-        if (settingsActivityRequested(requestCode)) {
-            handleSettingsActivityResult(resultCode);
-        } else if (newArticleLanguageSelected(requestCode, resultCode) || 
galleryPageSelected(requestCode, resultCode)) {
-            handleLangLinkOrPageResult(data);
-        } else {
-            super.onActivityResult(requestCode, resultCode, data);
-        }
-    }
-
-    private void handleLangLinkOrPageResult(final Intent data) {
-        tabsContainerView.post(new Runnable() {
-            @Override
-            public void run() {
-                handleIntent(data);
-            }
-        });
-    }
-
-    @Override
-    protected void onStop() {
-        app.getSessionFunnel().persistSession();
-        super.onStop();
-    }
-
-    @Override
-    public void onDestroy() {
-        if (unbinder != null) {
-            unbinder.unbind();
-        }
-        unregisterBus();
-        super.onDestroy();
-    }
-
-    @Override
-    public void onActionModeStarted(ActionMode mode) {
-        super.onActionModeStarted(mode);
-        if (!isCabOpen() && mode.getTag() == null) {
-            Menu menu = mode.getMenu();
-            menu.clear();
-            mode.getMenuInflater().inflate(R.menu.menu_text_select, menu);
-            pageFragment.onActionModeShown(mode);
-        }
-    }
-
-    @Override
-    public void onActionModeFinished(android.view.ActionMode mode) {
-        super.onActionModeFinished(mode);
-        currentActionMode = null;
-    }
-
-    protected void clearActionBarTitle() {
-        getSupportActionBar().setTitle("");
-    }
-
     private void registerBus() {
         bus = app.getBus();
         bus.register(busMethods);
-        L.d("Registered bus.");
     }
 
     private void unregisterBus() {
@@ -817,17 +638,13 @@
             bus.unregister(busMethods);
         }
         bus = null;
-        L.d("Unregistered bus.");
     }
 
     private void handleSettingsActivityResult(int resultCode) {
-        if (languageChanged(resultCode)) {
-            loadNewLanguageMainPage();
+        if (languageChanged(resultCode) && pageFragment != null) {
+            pageFragment.loadNewLanguageMainPage();
+            updateFeaturedPageWidget();
         }
-    }
-
-    private boolean settingsActivityRequested(int requestCode) {
-        return requestCode == SettingsActivity.ACTIVITY_REQUEST_SHOW_SETTINGS;
     }
 
     private boolean newArticleLanguageSelected(int requestCode, int 
resultCode) {
@@ -842,20 +659,21 @@
         return resultCode == SettingsActivity.ACTIVITY_RESULT_LANGUAGE_CHANGED;
     }
 
-    /**
-     * Reload the main page in the new language, after delaying for one second 
in order to:
-     * (1) Make sure that onStart in MainActivity gets called, thus 
registering the activity for the bus.
-     * (2) Ensure a smooth transition, which is very jarring without a delay.
-     */
-    private void loadNewLanguageMainPage() {
-        Handler uiThread = new Handler(Looper.getMainLooper());
-        uiThread.postDelayed(new Runnable() {
+    private void handleLangLinkOrPageResult(final Intent data) {
+        tabsContainerView.post(new Runnable() {
             @Override
             public void run() {
-                loadMainPageInForegroundTab();
-                updateFeaturedPageWidget();
+                handleIntent(data);
             }
-        }, DateUtils.SECOND_IN_MILLIS);
+        });
+    }
+
+    private boolean languageChanged(@Nullable String lang) {
+        return !app.getAppOrSystemLanguageCode().equals(lang);
+    }
+
+    private void hideLinkPreview() {
+        bottomSheetPresenter.dismiss(getSupportFragmentManager());
     }
 
     /**
@@ -879,11 +697,6 @@
                 .show();
     }
 
-    @VisibleForTesting
-    public void setPageLoadCallbacks(@Nullable PageLoadCallbacks 
pageLoadCallbacks) {
-        this.pageLoadCallbacks = pageLoadCallbacks;
-    }
-
     @SuppressLint("CommitTransaction")
     private void openSearchFragment(@NonNull SearchInvokeSource source, 
@Nullable String query) {
         Fragment fragment = searchFragment();
@@ -901,9 +714,17 @@
         
getSupportFragmentManager().beginTransaction().remove(fragment).commitNowAllowingStateLoss();
     }
 
-    @Nullable private SearchFragment searchFragment() {
+    @Nullable
+    private SearchFragment searchFragment() {
         return (SearchFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.activity_page_container);
+    }
+
+    private class ListDialogDismissListener implements 
DialogInterface.OnDismissListener {
+        @Override
+        public void onDismiss(DialogInterface dialogInterface) {
+            pageFragment.updateBookmarkFromDao();
+        }
     }
 
     private class EventBusMethods {
@@ -912,15 +733,5 @@
                 pageFragment.updateFontSize();
             }
         }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if ((event.isCtrlPressed() && keyCode == KeyEvent.KEYCODE_F)
-                || (!event.isCtrlPressed() && keyCode == KeyEvent.KEYCODE_F3)) 
{
-            pageFragment.showFindInPage();
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
     }
 }
diff --git 
a/app/src/main/java/org/wikipedia/page/PageContainerLongPressHandler.java 
b/app/src/main/java/org/wikipedia/page/PageContainerLongPressHandler.java
index c539260..0a9b481 100644
--- a/app/src/main/java/org/wikipedia/page/PageContainerLongPressHandler.java
+++ b/app/src/main/java/org/wikipedia/page/PageContainerLongPressHandler.java
@@ -4,29 +4,29 @@
 
 import org.wikipedia.LongPressHandler;
 import org.wikipedia.R;
+import org.wikipedia.dataclient.WikiSite;
 import org.wikipedia.history.HistoryEntry;
-import org.wikipedia.page.tabs.TabsProvider;
 import org.wikipedia.readinglist.AddToReadingListDialog;
 import org.wikipedia.util.ClipboardUtil;
 import org.wikipedia.util.FeedbackUtil;
 import org.wikipedia.util.ShareUtil;
 
-public abstract class PageContainerLongPressHandler implements 
LongPressHandler.ContextMenuListener {
-    @NonNull
-    private final PageFragment.Callback container;
+public class PageContainerLongPressHandler implements 
LongPressHandler.ContextMenuListener,
+        LongPressHandler.WebViewContextMenuListener {
+    @NonNull private PageFragment fragment;
 
-    public PageContainerLongPressHandler(@NonNull PageFragment.Callback 
container) {
-        this.container = container;
+    public PageContainerLongPressHandler(@NonNull PageFragment fragment) {
+        this.fragment = fragment;
     }
 
     @Override
-    public void onOpenLink(PageTitle title, HistoryEntry entry) {
-        container.onPageLoadPage(title, entry);
+    public void onOpenLink(HistoryEntry entry) {
+        fragment.loadPage(entry);
     }
 
     @Override
-    public void onOpenInNewTab(PageTitle title, HistoryEntry entry) {
-        container.onPageLoadPage(title, entry, 
TabsProvider.TabPosition.NEW_TAB_BACKGROUND);
+    public void onOpenInNewTab(HistoryEntry entry) {
+        fragment.openInNewBackgroundTab(entry);
     }
 
     @Override
@@ -37,19 +37,24 @@
 
     @Override
     public void onShareLink(PageTitle title) {
-        ShareUtil.shareText(container.getActivity(), title);
+        ShareUtil.shareText(fragment.getActivity(), title);
     }
 
     @Override
     public void onAddToList(PageTitle title, 
AddToReadingListDialog.InvokeSource source) {
-        container.onPageAddToReadingList(title, source);
+        fragment.addToReadingList(title, source);
+    }
+
+    @Override
+    public WikiSite getWikiSite() {
+        return fragment.getTitleOriginal().getWikiSite();
     }
 
     private void copyLink(String url) {
-        ClipboardUtil.setPlainText(container.getActivity(), null, url);
+        ClipboardUtil.setPlainText(fragment.getActivity(), null, url);
     }
 
     private void showCopySuccessMessage() {
-        FeedbackUtil.showMessage(container.getActivity(), 
R.string.address_copied);
+        FeedbackUtil.showMessage(fragment.getActivity(), 
R.string.address_copied);
     }
 }
diff --git a/app/src/main/java/org/wikipedia/page/PageFragment.java 
b/app/src/main/java/org/wikipedia/page/PageFragment.java
index 39d3626..ea73234 100755
--- a/app/src/main/java/org/wikipedia/page/PageFragment.java
+++ b/app/src/main/java/org/wikipedia/page/PageFragment.java
@@ -6,6 +6,8 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.design.widget.BottomSheetDialog;
@@ -15,8 +17,8 @@
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.ActionMode;
@@ -49,6 +51,11 @@
 import org.wikipedia.dataclient.okhttp.OkHttpWebViewClient;
 import org.wikipedia.descriptions.DescriptionEditActivity;
 import org.wikipedia.edit.EditHandler;
+import org.wikipedia.feed.continuereading.ContinueReadingCard;
+import org.wikipedia.feed.continuereading.ContinueReadingClient;
+import org.wikipedia.feed.dataclient.FeedClient;
+import org.wikipedia.feed.mainpage.MainPageClient;
+import org.wikipedia.feed.model.Card;
 import org.wikipedia.gallery.GalleryActivity;
 import org.wikipedia.history.HistoryEntry;
 import org.wikipedia.history.UpdateHistoryTask;
@@ -62,6 +69,7 @@
 import org.wikipedia.page.shareafact.ShareHandler;
 import org.wikipedia.page.tabs.Tab;
 import org.wikipedia.page.tabs.TabsProvider;
+import org.wikipedia.random.RandomArticleRequestHandler;
 import org.wikipedia.readinglist.AddToReadingListDialog;
 import org.wikipedia.readinglist.ReadingList;
 import org.wikipedia.readinglist.ReadingListBookmarkMenu;
@@ -90,6 +98,10 @@
 import java.util.Date;
 import java.util.List;
 
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
 import static android.app.Activity.RESULT_OK;
 import static butterknife.ButterKnife.findById;
 import static org.wikipedia.settings.Prefs.isLinkPreviewEnabled;
@@ -107,11 +119,8 @@
         void onPageShowBottomSheet(@NonNull BottomSheetDialogFragment dialog);
         void onPageDismissBottomSheet();
         @Nullable PageToolbarHideHandler onPageGetToolbarHideHandler();
-        void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry);
-        void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry,
-                            @NonNull TabsProvider.TabPosition tabPosition);
+        void onPageLoadPage(@NonNull HistoryEntry entry);
         void onPageShowLinkPreview(@NonNull PageTitle title, int source);
-        void onPageLoadMainPageInForegroundTab();
         void onPageUpdateProgressBar(boolean visible, boolean indeterminate, 
int value);
         void onPageSearchRequested();
         boolean onPageIsSearching();
@@ -120,14 +129,12 @@
         @Nullable ActionMode onPageStartSupportActionMode(@NonNull 
ActionMode.Callback callback);
         void onPageShowToolbar();
         void onPageHideSoftKeyboard();
-        @Nullable PageLoadCallbacks onPageGetPageLoadCallbacks();
         void onPageAddToReadingList(@NonNull PageTitle title,
                                     @NonNull 
AddToReadingListDialog.InvokeSource source);
         void onPageRemoveFromReadingLists(@NonNull PageTitle title);
         @Nullable View onPageGetContentView();
         @Nullable View onPageGetTabsContainerView();
         void onPagePopFragment();
-        @Nullable AppCompatActivity getActivity();
         void onPageInvalidateOptionsMenu();
         void onPageLoadError(@NonNull PageTitle title);
         void onPageLoadErrorBackPressed();
@@ -138,15 +145,13 @@
     public static final int TOC_ACTION_SHOW = 0;
     public static final int TOC_ACTION_HIDE = 1;
     public static final int TOC_ACTION_TOGGLE = 2;
-
-    private boolean pageRefreshed;
-    private boolean errorState = false;
-
     private static final int REFRESH_SPINNER_ADDITIONAL_OFFSET = (int) (16 * 
DimenUtil.getDensityScalar());
 
-    private PageFragmentLoadState pageFragmentLoadState;
-    private PageViewModel model;
-    private PageInfo pageInfo;
+    @BindView(R.id.page_web_view) ObservableWebView webView;
+    @BindView(R.id.page_toc_drawer) WikiDrawerLayout tocDrawer;
+    @BindView(R.id.page_refresh_container) SwipeRefreshLayoutWithScroll 
refreshView;
+    @BindView(R.id.page_actions_tab_layout) ConfigurableTabLayout tabLayout;
+    @BindView(R.id.page_error) WikiPageErrorView errorView;
 
     /**
      * List of tabs, each of which contains a backstack of page titles.
@@ -154,17 +159,11 @@
      * savedInstanceState of the fragment.
      */
     @NonNull private final List<Tab> tabList = new ArrayList<>();
-
     @NonNull private TabFunnel tabFunnel = new TabFunnel();
 
     private PageScrollFunnel pageScrollFunnel;
     private LeadImagesHandler leadImagesHandler;
     private PageToolbarHideHandler toolbarHideHandler;
-    private ObservableWebView webView;
-    private SwipeRefreshLayoutWithScroll refreshView;
-    private WikiPageErrorView errorView;
-    private WikiDrawerLayout tocDrawer;
-    private ConfigurableTabLayout tabLayout;
     private ToCHandler tocHandler;
     private CommunicationBridge bridge;
     private DarkModeSwitch darkModeSwitch;
@@ -174,85 +173,14 @@
     private ShareHandler shareHandler;
     private TabsProvider tabsProvider;
     private ActiveTimer activeTimer = new ActiveTimer();
+    private WikipediaApp app = WikipediaApp.getInstance();
+    private PageFragmentLoadState pageFragmentLoadState;
+    private PageViewModel model;
+    private PageInfo pageInfo;
+    private Unbinder unbinder;
 
-    private WikipediaApp app;
-
-    @NonNull
-    private final SwipeRefreshLayout.OnRefreshListener pageRefreshListener = 
new SwipeRefreshLayout.OnRefreshListener() {
-        @Override
-        public void onRefresh() {
-            refreshPage();
-        }
-    };
-
-    @NonNull
-    private final TabLayout.OnTabSelectedListener pageActionTabListener
-            = new TabLayout.OnTabSelectedListener() {
-        @Override
-        public void onTabSelected(TabLayout.Tab tab) {
-            if (tabLayout.isEnabled(tab)) {
-                
PageActionTab.of(tab.getPosition()).select(pageActionTabsCallback);
-            }
-        }
-
-        @Override
-        public void onTabUnselected(TabLayout.Tab tab) {
-
-        }
-
-        @Override
-        public void onTabReselected(TabLayout.Tab tab) {
-            onTabSelected(tab);
-        }
-    };
-
-    private PageActionTab.Callback pageActionTabsCallback = new 
PageActionTab.Callback() {
-        @Override
-        public void onAddToReadingListTabSelected() {
-            if (model.isInReadingList()) {
-                new ReadingListBookmarkMenu(tabLayout, new 
ReadingListBookmarkMenu.Callback() {
-                    @Override
-                    public void onAddRequest(@Nullable ReadingListPage page) {
-                        
addToReadingList(AddToReadingListDialog.InvokeSource.BOOKMARK_BUTTON);
-                    }
-
-                    @Override
-                    public void onDeleted(@Nullable ReadingListPage page) {
-                        if (callback() != null) {
-                            
callback().onPageRemoveFromReadingLists(getTitle());
-                        }
-                    }
-                }).show(getTitle());
-            } else {
-                
addToReadingList(AddToReadingListDialog.InvokeSource.BOOKMARK_BUTTON);
-            }
-        }
-
-        @Override
-        public void onSharePageTabSelected() {
-            sharePageLink();
-        }
-
-        @Override
-        public void onChooseLangTabSelected() {
-            startLangLinksActivity();
-        }
-
-        @Override
-        public void onFindInPageTabSelected() {
-            showFindInPage();
-        }
-
-        @Override
-        public void onViewToCTabSelected() {
-            toggleToC(TOC_ACTION_TOGGLE);
-        }
-
-        @Override
-        public void updateBookmark(boolean pageSaved) {
-            setBookmarkIconForPageSavedState(pageSaved);
-        }
-    };
+    private boolean pageRefreshed;
+    private boolean errorState = false;
 
     public ObservableWebView getWebView() {
         return webView;
@@ -274,10 +202,6 @@
         return model.getPage();
     }
 
-    public HistoryEntry getHistoryEntry() {
-        return model.getCurEntry();
-    }
-
     public EditHandler getEditHandler() {
         return editHandler;
     }
@@ -285,10 +209,8 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        app = (WikipediaApp) getActivity().getApplicationContext();
         model = new PageViewModel();
         pageFragmentLoadState = new PageFragmentLoadState();
-
         initTabs();
     }
 
@@ -296,30 +218,25 @@
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              final Bundle savedInstanceState) {
         View rootView = inflater.inflate(R.layout.fragment_page, container, 
false);
+        unbinder = ButterKnife.bind(this, rootView);
 
-        webView = (ObservableWebView) 
rootView.findViewById(R.id.page_web_view);
-        initWebViewListeners();
-
-        tocDrawer = (WikiDrawerLayout) 
rootView.findViewById(R.id.page_toc_drawer);
         
tocDrawer.setDragEdgeWidth(getResources().getDimensionPixelSize(R.dimen.drawer_drag_margin));
-
-        refreshView = (SwipeRefreshLayoutWithScroll) rootView
-                .findViewById(R.id.page_refresh_container);
-        int swipeOffset = getContentTopOffsetPx(getActivity()) + 
REFRESH_SPINNER_ADDITIONAL_OFFSET;
-        refreshView.setProgressViewOffset(false, -swipeOffset, swipeOffset);
+        refreshView.setProgressViewOffset(false, -getSwipeOffset(), 
getSwipeOffset());
         refreshView.setColorSchemeResources(getThemedAttributeId(getContext(), 
R.attr.colorAccent));
         refreshView.setScrollableChild(webView);
         refreshView.setOnRefreshListener(pageRefreshListener);
-
-        tabLayout = (ConfigurableTabLayout) 
rootView.findViewById(R.id.page_actions_tab_layout);
         tabLayout.addOnTabSelectedListener(pageActionTabListener);
 
         PageActionToolbarHideHandler pageActionToolbarHideHandler = new 
PageActionToolbarHideHandler(tabLayout);
         pageActionToolbarHideHandler.setScrollView(webView);
 
-        errorView = (WikiPageErrorView) rootView.findViewById(R.id.page_error);
+        initWebViewListeners();
 
         return rootView;
+    }
+
+    private int getSwipeOffset() {
+        return getContentTopOffsetPx(getActivity()) + 
REFRESH_SPINNER_ADDITIONAL_OFFSET;
     }
 
     @Override
@@ -331,6 +248,7 @@
         webView.clearAllListeners();
         ((ViewGroup) webView.getParent()).removeView(webView);
         webView = null;
+        unbinder.unbind();
         super.onDestroyView();
     }
 
@@ -398,7 +316,7 @@
 
         if (callback() != null) {
             LongPressHandler.WebViewContextMenuListener contextMenuListener
-                    = new PageFragmentLongPressHandler(callback());
+                    = new PageContainerLongPressHandler(this);
             new LongPressHandler(webView, HistoryEntry.SOURCE_INTERNAL_LINK, 
contextMenuListener);
         }
 
@@ -456,8 +374,8 @@
         dismissBottomSheet();
         if (title.namespace() != Namespace.MAIN || !isLinkPreviewEnabled()
                 || (!DeviceUtil.isOnline() && 
OfflineManager.instance().titleExists(title.getDisplayText()))) {
-            HistoryEntry historyEntry = new HistoryEntry(title, 
HistoryEntry.SOURCE_INTERNAL_LINK);
-            loadPage(title, historyEntry);
+            HistoryEntry entry = new HistoryEntry(title, 
HistoryEntry.SOURCE_INTERNAL_LINK);
+            loadPage(entry);
         } else {
             showLinkPreview(title, HistoryEntry.SOURCE_INTERNAL_LINK);
         }
@@ -504,7 +422,7 @@
         @Override
         public void onNewTabRequested() {
             // just load the main page into a new tab...
-            loadMainPageInForegroundTab();
+            loadMainPage();
             tabFunnel.logCreateNew(tabList.size());
 
             // Set the current tab to the new opened tab
@@ -590,23 +508,26 @@
         tabsProvider.invalidate();
     }
 
-    public void openInNewBackgroundTabFromMenu(@NonNull PageTitle title, 
@NonNull HistoryEntry entry) {
+    public void openInNewBackgroundTab(@NonNull HistoryEntry entry) {
         if (noPagesOpen()) {
-            openInNewForegroundTabFromMenu(title, entry);
+            openInNewForegroundTab(entry);
         } else {
-            openInNewTabFromMenu(title, entry, getBackgroundTabPosition());
+            openInNewTab(entry, getBackgroundTabPosition());
             tabsProvider.showAndHideTabs();
         }
     }
 
-    public void openInNewForegroundTabFromMenu(@NonNull PageTitle title, 
@NonNull HistoryEntry entry) {
-        openInNewTabFromMenu(title, entry, getForegroundTabPosition());
+    public void openInNewForegroundTab(@NonNull HistoryEntry entry) {
+        openInNewTab(entry, getForegroundTabPosition());
         pageFragmentLoadState.loadFromBackStack();
     }
 
-    public void openInNewTabFromMenu(@NonNull PageTitle title, @NonNull 
HistoryEntry entry, int position) {
-        openInNewTab(title, entry, position);
-        tabFunnel.logOpenInNew(tabList.size());
+    public void loadPage(@NonNull HistoryEntry entry) {
+        loadPage(entry.getTitle(), entry);
+    }
+
+    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry) {
+        loadPage(title, entry, false);
     }
 
     public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry, boolean pushBackStack) {
@@ -625,8 +546,8 @@
         loadPage(title, entry, pushBackStack, 0);
     }
 
-    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry entry,
-                         boolean pushBackStack, int stagedScrollY) {
+    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry, boolean pushBackStack,
+                         int stagedScrollY) {
         loadPage(title, entry, pushBackStack, stagedScrollY, false);
     }
 
@@ -635,12 +556,11 @@
      * This shall be the single point of entry for loading content into the 
WebView, whether it's
      * loading an entirely new page, refreshing the current page, retrying a 
failed network
      * request, etc.
-     * @param title Title of the new page to load.
      * @param entry HistoryEntry associated with the new page.
      * @param pushBackStack Whether to push the new page onto the backstack.
      */
-    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry entry,
-                         boolean pushBackStack, int stagedScrollY, boolean 
pageRefreshed) {
+    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry, boolean pushBackStack,
+                         int stagedScrollY, boolean pageRefreshed) {
         // clear the title in case the previous page load had failed.
         clearActivityActionBarTitle();
 
@@ -667,6 +587,20 @@
         closePageScrollFunnel();
         pageFragmentLoadState.load(pushBackStack, stagedScrollY);
         updateBookmark();
+
+        if (callback() != null) {
+            callback().onPageLoadPage(entry);
+        }
+    }
+
+    /**
+     * Go directly to the Main Page of the current Wiki, optionally allowing 
state loss of the
+     * fragment manager. Useful for when this function is called from an 
AsyncTask result.
+     */
+    public void loadMainPage() {
+        PageTitle title = MainPageClient.getMainPageTitle();
+        HistoryEntry entry = new HistoryEntry(title, 
HistoryEntry.SOURCE_MAIN_PAGE);
+        openInNewForegroundTab(entry);
     }
 
     public Bitmap getLeadImageBitmap() {
@@ -902,10 +836,6 @@
         // TODO: update this title in the db to be queued for saving by the 
service.
 
         checkAndShowSelectTextOnboarding();
-
-        if (getPageLoadCallbacks() != null) {
-            getPageLoadCallbacks().onLoadComplete();
-        }
     }
 
     public void onPageLoadError(@NonNull Throwable caught) {
@@ -939,10 +869,6 @@
         if (callback() != null) {
             callback().onPageLoadError(getTitle());
         }
-
-        if (getPageLoadCallbacks() != null) {
-            getPageLoadCallbacks().onLoadError(caught);
-        }
     }
 
     public void refreshPage() {
@@ -965,7 +891,6 @@
     }
 
     public void toggleToC(int action) {
-        // tocHandler could still be null while the page is loading
         if (tocHandler == null) {
             return;
         }
@@ -986,6 +911,51 @@
             default:
                 throw new RuntimeException("Unknown action!");
         }
+    }
+
+    /**
+     * Reload the main page in the new language, after delaying for one second 
in order to:
+     * (1) Make sure that onStart in MainActivity gets called, thus 
registering the activity for the bus.
+     * (2) Ensure a smooth transition, which is very jarring without a delay.
+     */
+    void loadNewLanguageMainPage() {
+        Handler uiThread = new Handler(Looper.getMainLooper());
+        uiThread.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                loadMainPage();
+            }
+
+        }, DateUtils.SECOND_IN_MILLIS);
+    }
+
+    void loadContinueReadingPage() {
+        new ContinueReadingClient().request(getContext(), app.getWikiSite(), 
1, new FeedClient.Callback() {
+            @Override
+            public void success(@NonNull List<? extends Card> cards) {
+                ContinueReadingCard card = (ContinueReadingCard) cards.get(0); 
// top?
+                openInNewForegroundTab(new HistoryEntry(card.pageTitle(), 
HistoryEntry.SOURCE_APP_SHORTCUT_CONTINUE_READING));
+            }
+
+            @Override
+            public void error(@NonNull Throwable caught) {
+                loadMainPage();
+            }
+        });
+    }
+
+    void loadRandomPage() {
+        RandomArticleRequestHandler.getRandomPage(new 
RandomArticleRequestHandler.Callback() {
+            @Override
+            public void onSuccess(@NonNull PageTitle pageTitle) {
+                openInNewForegroundTab(new HistoryEntry(pageTitle, 
HistoryEntry.SOURCE_APP_SHORTCUT_RANDOM));
+            }
+
+            @Override
+            public void onError(Throwable t) {
+                loadMainPage();
+            }
+        });
     }
 
     CommunicationBridge getBridge() {
@@ -1048,7 +1018,7 @@
         }
     }
 
-    private void openInNewTab(@NonNull PageTitle title, @NonNull HistoryEntry 
entry, int position) {
+    private void openInNewTab(@NonNull HistoryEntry entry, int position) {
         if (shouldCreateNewTab()) {
             // create a new tab
             Tab tab = new Tab();
@@ -1061,10 +1031,11 @@
             trimTabCount();
             tabsProvider.invalidate();
             // add the requested page to its backstack
-            tab.getBackStack().add(new PageBackStackItem(title, entry));
+            tab.getBackStack().add(new PageBackStackItem(entry.getTitle(), 
entry));
             getActivity().supportInvalidateOptionsMenu();
+            tabFunnel.logOpenInNew(tabList.size());
         } else {
-            getTopMostTab().getBackStack().add(new PageBackStackItem(title, 
entry));
+            getTopMostTab().getBackStack().add(new 
PageBackStackItem(entry.getTitle(), entry));
         }
     }
 
@@ -1269,37 +1240,21 @@
         pageScrollFunnel = null;
     }
 
-    private class PageFragmentLongPressHandler extends 
PageContainerLongPressHandler
-            implements LongPressHandler.WebViewContextMenuListener {
-
-        PageFragmentLongPressHandler(@NonNull PageFragment.Callback callback) {
-            super(callback);
-        }
-
-        @Override
-        public WikiSite getWikiSite() {
-            return model.getTitleOriginal().getWikiSite();
-        }
-    }
-
     public void showBottomSheet(@NonNull BottomSheetDialog dialog) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageShowBottomSheet(dialog);
+        if (callback() != null) {
+            callback().onPageShowBottomSheet(dialog);
         }
     }
 
     public void showBottomSheet(@NonNull BottomSheetDialogFragment dialog) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageShowBottomSheet(dialog);
+        if (callback() != null) {
+            callback().onPageShowBottomSheet(dialog);
         }
     }
 
     private void dismissBottomSheet() {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageDismissBottomSheet();
+        if (callback() != null) {
+            callback().onPageDismissBottomSheet();
         }
     }
 
@@ -1313,119 +1268,69 @@
         return handler;
     }
 
-    public void loadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageLoadPage(title, entry);
-        }
-    }
-
     private void showLinkPreview(@NonNull PageTitle title, int source) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageShowLinkPreview(title, source);
-        }
-    }
-
-    private void loadMainPageInForegroundTab() {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageLoadMainPageInForegroundTab();
+        if (callback() != null) {
+            callback().onPageShowLinkPreview(title, source);
         }
     }
 
     private void updateProgressBar(boolean visible, boolean indeterminate, int 
value) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageUpdateProgressBar(visible, indeterminate, value);
+        if (callback() != null) {
+            callback().onPageUpdateProgressBar(visible, indeterminate, value);
         }
     }
 
     private boolean isSearching() {
-        boolean isSearching = false;
-        Callback callback = callback();
-        if (callback != null) {
-            isSearching = callback.onPageIsSearching();
-        }
-        return isSearching;
+        return callback() != null && callback().onPageIsSearching();
     }
 
     @Nullable
     private Fragment getHostTopFragment() {
-        Fragment fragment = null;
-        Callback callback = callback();
-        if (callback != null) {
-            fragment = callback.onPageGetTopFragment();
-        }
-        return fragment;
+        return callback() != null ? callback().onPageGetTopFragment() : null;
     }
 
     private void showThemeChooser() {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageShowThemeChooser();
+        if (callback() != null) {
+            callback().onPageShowThemeChooser();
         }
     }
 
     @Nullable
     public ActionMode startSupportActionMode(@NonNull ActionMode.Callback 
actionModeCallback) {
-        ActionMode actionMode = null;
-        Callback callback = callback();
-        if (callback != null) {
-            actionMode = 
callback.onPageStartSupportActionMode(actionModeCallback);
-        }
-        return actionMode;
+        return callback() != null ? 
callback().onPageStartSupportActionMode(actionModeCallback) : null;
     }
 
     public void showToolbar() {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageShowToolbar();
+        if (callback() != null) {
+            callback().onPageShowToolbar();
         }
     }
 
     public void hideSoftKeyboard() {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageHideSoftKeyboard();
+        if (callback() != null) {
+            callback().onPageHideSoftKeyboard();
         }
-    }
-
-    @Nullable
-    private PageLoadCallbacks getPageLoadCallbacks() {
-        PageLoadCallbacks callbacks = null;
-        Callback callback = callback();
-        if (callback != null) {
-            callbacks = callback.onPageGetPageLoadCallbacks();
-        }
-        return callbacks;
     }
 
     public void addToReadingList(@NonNull AddToReadingListDialog.InvokeSource 
source) {
-        Callback callback = callback();
-        if (callback != null) {
-            callback.onPageAddToReadingList(getTitle(), source);
+        addToReadingList(getTitle(), source);
+    }
+
+    public void addToReadingList(@NonNull PageTitle title,
+                                 @NonNull AddToReadingListDialog.InvokeSource 
source) {
+        if (callback() != null) {
+            callback().onPageAddToReadingList(title, source);
         }
     }
 
     @Nullable
     public View getContentView() {
-        View view = null;
-        Callback callback = callback();
-        if (callback != null) {
-            view = callback.onPageGetContentView();
-        }
-        return view;
+        return callback() != null ? callback().onPageGetContentView() : null;
     }
 
     @Nullable
     public View getTabsContainerView() {
-        View view = null;
-        Callback callback = callback();
-        if (callback != null) {
-            view = callback.onPageGetTabsContainerView();
-        }
-        return view;
+        return callback() != null ? callback().onPageGetTabsContainerView() : 
null;
     }
 
     private void startLangLinksActivity() {
@@ -1470,6 +1375,84 @@
         }
     }
 
+
+    @NonNull
+    private final SwipeRefreshLayout.OnRefreshListener pageRefreshListener = 
new SwipeRefreshLayout.OnRefreshListener() {
+        @Override
+        public void onRefresh() {
+            refreshPage();
+        }
+    };
+
+    @NonNull
+    private final TabLayout.OnTabSelectedListener pageActionTabListener
+            = new TabLayout.OnTabSelectedListener() {
+        @Override
+        public void onTabSelected(TabLayout.Tab tab) {
+            if (tabLayout.isEnabled(tab)) {
+                
PageActionTab.of(tab.getPosition()).select(pageActionTabsCallback);
+            }
+        }
+
+        @Override
+        public void onTabUnselected(TabLayout.Tab tab) {
+
+        }
+
+        @Override
+        public void onTabReselected(TabLayout.Tab tab) {
+            onTabSelected(tab);
+        }
+    };
+
+    private PageActionTab.Callback pageActionTabsCallback = new 
PageActionTab.Callback() {
+        @Override
+        public void onAddToReadingListTabSelected() {
+            if (model.isInReadingList()) {
+                new ReadingListBookmarkMenu(tabLayout, new 
ReadingListBookmarkMenu.Callback() {
+                    @Override
+                    public void onAddRequest(@Nullable ReadingListPage page) {
+                        
addToReadingList(AddToReadingListDialog.InvokeSource.BOOKMARK_BUTTON);
+                    }
+
+                    @Override
+                    public void onDeleted(@Nullable ReadingListPage page) {
+                        if (callback() != null) {
+                            
callback().onPageRemoveFromReadingLists(getTitle());
+                        }
+                    }
+                }).show(getTitle());
+            } else {
+                
addToReadingList(AddToReadingListDialog.InvokeSource.BOOKMARK_BUTTON);
+            }
+        }
+
+        @Override
+        public void onSharePageTabSelected() {
+            sharePageLink();
+        }
+
+        @Override
+        public void onChooseLangTabSelected() {
+            startLangLinksActivity();
+        }
+
+        @Override
+        public void onFindInPageTabSelected() {
+            showFindInPage();
+        }
+
+        @Override
+        public void onViewToCTabSelected() {
+            toggleToC(TOC_ACTION_TOGGLE);
+        }
+
+        @Override
+        public void updateBookmark(boolean pageSaved) {
+            setBookmarkIconForPageSavedState(pageSaved);
+        }
+    };
+
     @Nullable
     public Callback callback() {
         return FragmentUtil.getCallback(this, Callback.class);
diff --git a/app/src/main/java/org/wikipedia/page/PageInfoDialog.java 
b/app/src/main/java/org/wikipedia/page/PageInfoDialog.java
index c627a4b..ac4e642 100644
--- a/app/src/main/java/org/wikipedia/page/PageInfoDialog.java
+++ b/app/src/main/java/org/wikipedia/page/PageInfoDialog.java
@@ -56,16 +56,12 @@
                 PageTitle title = ((DisambigResult) 
disambigList.getAdapter().getItem(position)).getTitle();
                 HistoryEntry historyEntry = new HistoryEntry(title, 
HistoryEntry.SOURCE_DISAMBIG);
                 dismiss();
-                fragment.loadPage(title, historyEntry);
+                fragment.loadPage(historyEntry);
             }
         });
 
-        if (fragment.callback() != null) {
-            ListViewContextMenuListener contextMenuListener
-                    = new LongPressHandler(fragment.callback());
-            new org.wikipedia.LongPressHandler(disambigList, 
HistoryEntry.SOURCE_DISAMBIG,
-                    contextMenuListener);
-        }
+        ListViewContextMenuListener contextMenuListener = new 
LongPressHandler(fragment);
+        new org.wikipedia.LongPressHandler(disambigList, 
HistoryEntry.SOURCE_DISAMBIG, contextMenuListener);
 
         if (pageInfo.getSimilarTitles().length > 0) {
             disambigHeading.setOnClickListener(new View.OnClickListener() {
@@ -126,8 +122,9 @@
 
     private class LongPressHandler extends PageContainerLongPressHandler
             implements ListViewContextMenuListener {
-        LongPressHandler(@NonNull PageFragment.Callback callback) {
-            super(callback);
+
+        LongPressHandler(@NonNull PageFragment fragment) {
+            super(fragment);
         }
 
         @Override
@@ -136,14 +133,14 @@
         }
 
         @Override
-        public void onOpenLink(PageTitle title, HistoryEntry entry) {
-            super.onOpenLink(title, entry);
+        public void onOpenLink(HistoryEntry entry) {
+            super.onOpenLink(entry);
             dismiss();
         }
 
         @Override
-        public void onOpenInNewTab(PageTitle title, HistoryEntry entry) {
-            super.onOpenInNewTab(title, entry);
+        public void onOpenInNewTab(HistoryEntry entry) {
+            super.onOpenInNewTab(entry);
             dismiss();
         }
 
diff --git a/app/src/main/java/org/wikipedia/page/PageLoadCallbacks.java 
b/app/src/main/java/org/wikipedia/page/PageLoadCallbacks.java
deleted file mode 100644
index 8383bf7..0000000
--- a/app/src/main/java/org/wikipedia/page/PageLoadCallbacks.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.wikipedia.page;
-
-import android.support.annotation.NonNull;
-
-/**
- * Callback methods for page load state feedback
- */
-public interface PageLoadCallbacks {
-    /** Called when page has finished loading */
-    void onLoadComplete();
-    void onLoadError(@NonNull Throwable e);
-}
diff --git 
a/app/src/main/java/org/wikipedia/page/bottomcontent/BottomContentHandler.java 
b/app/src/main/java/org/wikipedia/page/bottomcontent/BottomContentHandler.java
index 97c17f4..4da6f29 100644
--- 
a/app/src/main/java/org/wikipedia/page/bottomcontent/BottomContentHandler.java
+++ 
b/app/src/main/java/org/wikipedia/page/bottomcontent/BottomContentHandler.java
@@ -105,13 +105,9 @@
             }
         });
 
-        if (parentFragment.callback() != null) {
-            ListViewContextMenuListener contextMenuListener
-                    = new LongPressHandler(parentFragment.callback());
-
-            new org.wikipedia.LongPressHandler(readMoreList, 
HistoryEntry.SOURCE_INTERNAL_LINK,
-                    contextMenuListener);
-        }
+        ListViewContextMenuListener contextMenuListener = new 
LongPressHandler(parentFragment);
+        new org.wikipedia.LongPressHandler(readMoreList, 
HistoryEntry.SOURCE_INTERNAL_LINK,
+                contextMenuListener);
 
         // set up pass-through scroll functionality for the ListView
         readMoreList.setOnTouchListener(new View.OnTouchListener() {
@@ -412,9 +408,11 @@
 
     private class LongPressHandler extends PageContainerLongPressHandler
             implements ListViewContextMenuListener {
+
         private int lastPosition;
-        LongPressHandler(@NonNull PageFragment.Callback callback) {
-            super(callback);
+
+        LongPressHandler(@NonNull PageFragment fragment) {
+            super(fragment);
         }
 
         @Override
@@ -424,14 +422,14 @@
         }
 
         @Override
-        public void onOpenLink(PageTitle title, HistoryEntry entry) {
-            super.onOpenLink(title, entry);
+        public void onOpenLink(HistoryEntry entry) {
+            super.onOpenLink(entry);
             funnel.logSuggestionClicked(pageTitle, readMoreItems.getResults(), 
lastPosition);
         }
 
         @Override
-        public void onOpenInNewTab(PageTitle title, HistoryEntry entry) {
-            super.onOpenInNewTab(title, entry);
+        public void onOpenInNewTab(HistoryEntry entry) {
+            super.onOpenInNewTab(entry);
             funnel.logSuggestionClicked(pageTitle, readMoreItems.getResults(), 
lastPosition);
         }
     }
diff --git a/app/src/main/java/org/wikipedia/search/SearchResultsFragment.java 
b/app/src/main/java/org/wikipedia/search/SearchResultsFragment.java
index dcb9306..1ba6b3f 100644
--- a/app/src/main/java/org/wikipedia/search/SearchResultsFragment.java
+++ b/app/src/main/java/org/wikipedia/search/SearchResultsFragment.java
@@ -418,18 +418,18 @@
         }
 
         @Override
-        public void onOpenLink(PageTitle title, HistoryEntry entry) {
+        public void onOpenLink(HistoryEntry entry) {
             Callback callback = callback();
             if (callback != null) {
-                callback.navigateToTitle(title, false, lastPositionRequested);
+                callback.navigateToTitle(entry.getTitle(), false, 
lastPositionRequested);
             }
         }
 
         @Override
-        public void onOpenInNewTab(PageTitle title, HistoryEntry entry) {
+        public void onOpenInNewTab(HistoryEntry entry) {
             Callback callback = callback();
             if (callback != null) {
-                callback.navigateToTitle(title, true, lastPositionRequested);
+                callback.navigateToTitle(entry.getTitle(), true, 
lastPositionRequested);
             }
         }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/379819
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0f526705a50f82d3ac78f808c23b5b48cff58d80
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to