diff --git a/mobile/android/base/BrowserApp.java b/mobile/android/base/BrowserApp.java index ee4bc33f543..a3dc626575d 100644 --- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -16,6 +16,7 @@ import org.mozilla.gecko.gfx.PanZoomController; import org.mozilla.gecko.health.BrowserHealthReporter; import org.mozilla.gecko.home.BrowserSearch; import org.mozilla.gecko.home.HomePager; +import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.menu.GeckoMenu; import org.mozilla.gecko.util.Clipboard; import org.mozilla.gecko.util.FloatUtils; @@ -84,7 +85,7 @@ abstract public class BrowserApp extends GeckoApp BrowserSearch.OnSearchListener, BrowserSearch.OnEditSuggestionListener, HomePager.OnNewTabsListener, - HomePager.OnUrlOpenListener { + OnUrlOpenListener { private static final String LOGTAG = "GeckoBrowserApp"; private static final String PREF_CHROME_DYNAMICTOOLBAR = "browser.chrome.dynamictoolbar"; @@ -1262,6 +1263,35 @@ abstract public class BrowserApp extends GeckoApp outState.putInt(STATE_ABOUT_HOME_TOP_PADDING, mHomePagerContainer.getPaddingTop()); } + /** + * Attempts to switch to an open tab with the given URL. + * + * @return true if we successfully switched to a tab, false otherwise. + */ + private boolean maybeSwitchToTab(String url, EnumSet flags) { + if (!flags.contains(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)) { + return false; + } + + final Tabs tabs = Tabs.getInstance(); + final int tabId = tabs.getTabIdForUrl(url); + if (tabId < 0) { + return false; + } + + // If this tab is already selected, just hide the home pager. + if (tabs.isSelectedTab(tabs.getTab(tabId))) { + hideHomePager(); + } else { + tabs.selectTab(tabId); + } + + hideBrowserSearch(); + mBrowserToolbar.cancelEdit(); + + return true; + } + private void openUrl(String url) { openUrl(url, null, false); } @@ -2065,10 +2095,12 @@ abstract public class BrowserApp extends GeckoApp // HomePager.OnUrlOpenListener @Override - public void onUrlOpen(String url) { - openUrl(url); + public void onUrlOpen(String url, EnumSet flags) { + if (!maybeSwitchToTab(url, flags)) { + openUrl(url); + } } - + // BrowserSearch.OnSearchListener @Override public void onSearch(String engineId, String text) { diff --git a/mobile/android/base/Tabs.java b/mobile/android/base/Tabs.java index 1e6c6d39541..09737df9d73 100644 --- a/mobile/android/base/Tabs.java +++ b/mobile/android/base/Tabs.java @@ -585,19 +585,19 @@ public class Tabs implements GeckoEventListener { } /** - * Returns true if any of the tabs has the requested url. - * - * @return true if the url is open currently, false otherwise. + * Looks for an open tab with the given URL. + * + * @return id of an open tab with the given URL; -1 if the tab doesn't exist. */ - public boolean hasUrl(String url) { + public int getTabIdForUrl(String url) { for (Tab tab : mOrder) { if (TextUtils.equals(tab.getURL(), url) || TextUtils.equals(ReaderModeUtils.getUrlFromAboutReader(tab.getURL()), url)) { - return true; + return tab.getId(); } } - return false; + return -1; } /** diff --git a/mobile/android/base/home/BookmarksListView.java b/mobile/android/base/home/BookmarksListView.java index 2692049270f..c3246aede8e 100644 --- a/mobile/android/base/home/BookmarksListView.java +++ b/mobile/android/base/home/BookmarksListView.java @@ -21,6 +21,8 @@ import android.widget.HeaderViewListAdapter; import android.widget.ListAdapter; import android.widget.ListView; +import java.util.EnumSet; + /** * A ListView of bookmarks. */ @@ -134,10 +136,9 @@ public class BookmarksListView extends HomeListView } else { // Otherwise, just open the URL final String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL)); - OnUrlOpenListener listener = getOnUrlOpenListener(); - if (listener != null) { - listener.onUrlOpen(url); - } + + // This item is a TwoLinePageRow, so we allow switch-to-tab. + getOnUrlOpenListener().onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)); } } } diff --git a/mobile/android/base/home/BrowserSearch.java b/mobile/android/base/home/BrowserSearch.java index c2a462f3bda..be3a127ed77 100644 --- a/mobile/android/base/home/BrowserSearch.java +++ b/mobile/android/base/home/BrowserSearch.java @@ -51,6 +51,7 @@ import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; /** @@ -230,7 +231,9 @@ public class BrowserSearch extends HomeFragment position -= getSuggestEngineCount(); final Cursor c = mAdapter.getCursor(position); final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); - mUrlOpenListener.onUrlOpen(url); + + // This item is a TwoLinePageRow, so we allow switch-to-tab. + mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)); } }); diff --git a/mobile/android/base/home/HomePager.java b/mobile/android/base/home/HomePager.java index bc0cb93524b..a1cd7ab460e 100644 --- a/mobile/android/base/home/HomePager.java +++ b/mobile/android/base/home/HomePager.java @@ -40,7 +40,11 @@ public class HomePager extends ViewPager { private EnumMap mPages = new EnumMap(Page.class); public interface OnUrlOpenListener { - public void onUrlOpen(String url); + public enum Flags { + ALLOW_SWITCH_TO_TAB + } + + public void onUrlOpen(String url, EnumSet flags); } public interface OnNewTabsListener { diff --git a/mobile/android/base/home/MostRecentPage.java b/mobile/android/base/home/MostRecentPage.java index 942b7f15270..f60ba43951e 100644 --- a/mobile/android/base/home/MostRecentPage.java +++ b/mobile/android/base/home/MostRecentPage.java @@ -29,6 +29,7 @@ import android.widget.ListView; import android.widget.TextView; import java.util.Date; +import java.util.EnumSet; /** * Fragment that displays recent history in a ListView. @@ -101,7 +102,9 @@ public class MostRecentPage extends HomeFragment { position -= mAdapter.getMostRecentSectionsCountBefore(position); final Cursor c = mAdapter.getCursor(position); final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); - mUrlOpenListener.onUrlOpen(url); + + // This item is a TwoLinePageRow, so we allow switch-to-tab. + mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)); } }); diff --git a/mobile/android/base/home/MostVisitedPage.java b/mobile/android/base/home/MostVisitedPage.java index ed4633ee863..3340e43f0cb 100644 --- a/mobile/android/base/home/MostVisitedPage.java +++ b/mobile/android/base/home/MostVisitedPage.java @@ -25,6 +25,8 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; +import java.util.EnumSet; + /** * Fragment that displays frecency search results in a ListView. */ @@ -95,7 +97,9 @@ public class MostVisitedPage extends HomeFragment { } final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); - mUrlOpenListener.onUrlOpen(url); + + // This item is a TwoLinePageRow, so we allow switch-to-tab. + mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)); } }); diff --git a/mobile/android/base/home/ReadingListPage.java b/mobile/android/base/home/ReadingListPage.java index 7b0050cc93d..306d2a36e0b 100644 --- a/mobile/android/base/home/ReadingListPage.java +++ b/mobile/android/base/home/ReadingListPage.java @@ -26,6 +26,8 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import java.util.EnumSet; + /** * Fragment that displays reading list contents in a ListView. */ @@ -86,7 +88,9 @@ public class ReadingListPage extends HomeFragment { String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); url = ReaderModeUtils.getAboutReaderForUrl(url, true); - mUrlOpenListener.onUrlOpen(url); + + // This item is a TwoLinePageRow, so we allow switch-to-tab. + mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB)); } }); diff --git a/mobile/android/base/home/SearchEngineRow.java b/mobile/android/base/home/SearchEngineRow.java index 5db4da2fb87..fc8c5143fee 100644 --- a/mobile/android/base/home/SearchEngineRow.java +++ b/mobile/android/base/home/SearchEngineRow.java @@ -24,6 +24,8 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import java.util.EnumSet; + class SearchEngineRow extends AnimatedHeightLayout { // Duration for fade-in animation private static final int ANIMATION_DURATION = 250; @@ -77,7 +79,7 @@ class SearchEngineRow extends AnimatedHeightLayout { // search for the term. if (v != mUserEnteredView && !StringUtils.isSearchQuery(suggestion, false)) { if (mUrlOpenListener != null) { - mUrlOpenListener.onUrlOpen(suggestion); + mUrlOpenListener.onUrlOpen(suggestion, EnumSet.noneOf(OnUrlOpenListener.Flags.class)); } } else if (mSearchListener != null) { mSearchListener.onSearch(mSearchEngine.name, suggestion); diff --git a/mobile/android/base/home/TopBookmarksView.java b/mobile/android/base/home/TopBookmarksView.java index d755c7e6be0..84b2cde1b3c 100644 --- a/mobile/android/base/home/TopBookmarksView.java +++ b/mobile/android/base/home/TopBookmarksView.java @@ -24,6 +24,8 @@ import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.GridView; +import java.util.EnumSet; + /** * A grid view of top bookmarks and pinned tabs. * Each cell in the grid is a TopBookmarkItemView. @@ -94,7 +96,7 @@ public class TopBookmarksView extends GridView { // If not, navigate to the page given by the url. if (!TextUtils.isEmpty(url)) { if (mUrlOpenListener != null) { - mUrlOpenListener.onUrlOpen(url); + mUrlOpenListener.onUrlOpen(url, EnumSet.noneOf(OnUrlOpenListener.Flags.class)); } } else { if (mPinBookmarkListener != null) { diff --git a/mobile/android/base/home/TwoLinePageRow.java b/mobile/android/base/home/TwoLinePageRow.java index 72a0ffd190a..2898beacf6f 100644 --- a/mobile/android/base/home/TwoLinePageRow.java +++ b/mobile/android/base/home/TwoLinePageRow.java @@ -134,7 +134,8 @@ public class TwoLinePageRow extends LinearLayout * Replaces the page URL with "Switch to tab" if there is already a tab open with that URL. */ private void updateDisplayedUrl() { - if (!mShowIcons || !Tabs.getInstance().hasUrl(mPageUrl)) { + int tabId = Tabs.getInstance().getTabIdForUrl(mPageUrl); + if (!mShowIcons || tabId < 0) { setUrl(mPageUrl); setUrlIcon(NO_ICON); } else {