diff --git a/mobile/android/base/home/HomeFragment.java b/mobile/android/base/home/HomeFragment.java
index 34eb43ec393..40428e203a8 100644
--- a/mobile/android/base/home/HomeFragment.java
+++ b/mobile/android/base/home/HomeFragment.java
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
@@ -86,6 +87,11 @@ abstract class HomeFragment extends Fragment {
menu.setHeaderTitle(info.getDisplayTitle());
+ // Hide ununsed menu items.
+ menu.findItem(R.id.top_sites_edit).setVisible(false);
+ menu.findItem(R.id.top_sites_pin).setVisible(false);
+ menu.findItem(R.id.top_sites_unpin).setVisible(false);
+
// Hide the "Edit" menuitem if this item isn't a bookmark,
// or if this is a reading list item.
if (!info.hasBookmarkId() || info.isInReadingList()) {
@@ -152,7 +158,10 @@ abstract class HomeFragment extends Fragment {
flags |= Tabs.LOADURL_PRIVATE;
final String url = (info.isInReadingList() ? ReaderModeUtils.getAboutReaderForUrl(info.url) : info.url);
- Tabs.getInstance().loadUrl(url, flags);
+
+ // Some pinned site items have "user-entered" urls. URLs entered in the PinSiteDialog are wrapped in
+ // a special URI until we can get a valid URL. If the url is a user-entered url, decode the URL before loading it.
+ Tabs.getInstance().loadUrl(decodeUserEnteredUrl(url), flags);
Toast.makeText(context, R.string.new_tab_opened, Toast.LENGTH_SHORT).show();
return true;
}
@@ -218,6 +227,23 @@ abstract class HomeFragment extends Fragment {
return mCanLoadHint;
}
+ /**
+ * Given a url with a user-entered scheme, extract the
+ * scheme-specific component. For e.g, given "user-entered://www.google.com",
+ * this method returns "//www.google.com". If the passed url
+ * does not have a user-entered scheme, the same url will be returned.
+ *
+ * @param url to be decoded
+ * @return url component entered by user
+ */
+ public static String decodeUserEnteredUrl(String url) {
+ Uri uri = Uri.parse(url);
+ if ("user-entered".equals(uri.getScheme())) {
+ return uri.getSchemeSpecificPart();
+ }
+ return url;
+ }
+
protected abstract void load();
protected boolean canLoad() {
diff --git a/mobile/android/base/home/TopSitesGridView.java b/mobile/android/base/home/TopSitesGridView.java
index d6338cbba35..72141509843 100644
--- a/mobile/android/base/home/TopSitesGridView.java
+++ b/mobile/android/base/home/TopSitesGridView.java
@@ -12,7 +12,6 @@ import org.mozilla.gecko.ThumbnailHelper;
import org.mozilla.gecko.db.BrowserDB.TopSitesCursorWrapper;
import org.mozilla.gecko.db.BrowserDB.URLColumns;
import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
-import org.mozilla.gecko.util.StringUtils;
import android.content.Context;
import android.content.res.TypedArray;
@@ -105,7 +104,7 @@ public class TopSitesGridView extends GridView {
TopSitesGridItemView row = (TopSitesGridItemView) view;
// Decode "user-entered" URLs before loading them.
- String url = TopSitesPanel.decodeUserEnteredUrl(row.getUrl());
+ String url = HomeFragment.decodeUserEnteredUrl(row.getUrl());
// If the url is empty, the user can pin a site.
// If not, navigate to the page given by the url.
@@ -125,7 +124,14 @@ public class TopSitesGridView extends GridView {
@Override
public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
- mContextMenuInfo = new TopSitesGridContextMenuInfo(view, position, id, cursor);
+
+ if (cursor == null) {
+ mContextMenuInfo = null;
+ return false;
+ }
+
+ mContextMenuInfo = new TopSitesGridContextMenuInfo(view, position, id);
+ updateContextMenuFromCursor(mContextMenuInfo, cursor);
return showContextMenuForChild(TopSitesGridView.this);
}
});
@@ -221,6 +227,18 @@ public class TopSitesGridView extends GridView {
return mContextMenuInfo;
}
+ /*
+ * Update the fields of a TopSitesGridContextMenuInfo object
+ * from a cursor.
+ *
+ * @param info context menu info object to be updated
+ * @param cursor used to update the context menu info object
+ */
+ private void updateContextMenuFromCursor(TopSitesGridContextMenuInfo info, Cursor cursor) {
+ info.url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
+ info.title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
+ info.isPinned = ((TopSitesCursorWrapper) cursor).isPinned();
+ }
/**
* Set an url open listener to be used by this view.
*
@@ -240,29 +258,13 @@ public class TopSitesGridView extends GridView {
}
/**
- * A ContextMenuInfo for TopBoomarksView that adds details from the cursor.
+ * Stores information regarding the creation of the context menu for a GridView item.
*/
- public static class TopSitesGridContextMenuInfo extends AdapterContextMenuInfo {
+ public static class TopSitesGridContextMenuInfo extends HomeContextMenuInfo {
+ public boolean isPinned = false;
- public String url;
- public String title;
- public boolean isPinned;
-
- public TopSitesGridContextMenuInfo(View targetView, int position, long id, Cursor cursor) {
+ public TopSitesGridContextMenuInfo(View targetView, int position, long id) {
super(targetView, position, id);
-
- if (cursor == null) {
- return;
- }
-
- url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
- title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
- isPinned = ((TopSitesCursorWrapper) cursor).isPinned();
- }
-
- public String getDisplayTitle() {
- return TextUtils.isEmpty(title) ?
- StringUtils.stripCommonSubdomains(StringUtils.stripScheme(url, StringUtils.UrlFlags.STRIP_HTTPS)) : title;
}
}
}
diff --git a/mobile/android/base/home/TopSitesPanel.java b/mobile/android/base/home/TopSitesPanel.java
index a6e084e7c9f..bbc24f4cfe4 100644
--- a/mobile/android/base/home/TopSitesPanel.java
+++ b/mobile/android/base/home/TopSitesPanel.java
@@ -10,9 +10,7 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
-import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.R;
-import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.db.BrowserContract.Combined;
import org.mozilla.gecko.db.BrowserContract.Thumbnails;
import org.mozilla.gecko.db.BrowserDB;
@@ -30,7 +28,6 @@ import org.mozilla.gecko.util.ThreadUtils;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -52,7 +49,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
-import android.widget.Toast;
/**
* Fragment that displays frecency search results in a ListView.
@@ -267,17 +263,21 @@ public class TopSitesPanel extends HomeFragment {
return;
}
- // HomeFragment will handle the default case.
- if (menuInfo instanceof HomeContextMenuInfo) {
- super.onCreateContextMenu(menu, view, menuInfo);
- }
-
if (!(menuInfo instanceof TopSitesGridContextMenuInfo)) {
+ // Long pressed item was not a Top Sites GridView item. Superclass
+ // can handle this.
+ super.onCreateContextMenu(menu, view, menuInfo);
return;
}
+ // Long pressed item was a Top Sites GridView item, handle it.
MenuInflater inflater = new MenuInflater(view.getContext());
- inflater.inflate(R.menu.top_sites_contextmenu, menu);
+ inflater.inflate(R.menu.home_contextmenu, menu);
+
+ // Hide ununsed menu items.
+ menu.findItem(R.id.home_open_in_reader).setVisible(false);
+ menu.findItem(R.id.home_edit_bookmark).setVisible(false);
+ menu.findItem(R.id.home_remove).setVisible(false);
TopSitesGridContextMenuInfo info = (TopSitesGridContextMenuInfo) menuInfo;
menu.setHeaderTitle(info.getDisplayTitle());
@@ -289,8 +289,8 @@ public class TopSitesPanel extends HomeFragment {
menu.findItem(R.id.top_sites_unpin).setVisible(false);
}
} else {
- menu.findItem(R.id.top_sites_open_new_tab).setVisible(false);
- menu.findItem(R.id.top_sites_open_private_tab).setVisible(false);
+ menu.findItem(R.id.home_open_new_tab).setVisible(false);
+ menu.findItem(R.id.home_open_private_tab).setVisible(false);
menu.findItem(R.id.top_sites_pin).setVisible(false);
menu.findItem(R.id.top_sites_unpin).setVisible(false);
}
@@ -298,9 +298,13 @@ public class TopSitesPanel extends HomeFragment {
@Override
public boolean onContextItemSelected(MenuItem item) {
+ if (super.onContextItemSelected(item)) {
+ // HomeFragment was able to handle to selected item.
+ return true;
+ }
+
ContextMenuInfo menuInfo = item.getMenuInfo();
- // HomeFragment will handle the default case.
if (menuInfo == null || !(menuInfo instanceof TopSitesGridContextMenuInfo)) {
return false;
}
@@ -309,21 +313,6 @@ public class TopSitesPanel extends HomeFragment {
final Activity activity = getActivity();
final int itemId = item.getItemId();
- if (itemId == R.id.top_sites_open_new_tab || itemId == R.id.top_sites_open_private_tab) {
- if (info.url == null) {
- Log.e(LOGTAG, "Can't open in new tab because URL is null");
- return false;
- }
-
- int flags = Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_BACKGROUND;
- if (item.getItemId() == R.id.top_sites_open_private_tab)
- flags |= Tabs.LOADURL_PRIVATE;
-
- // Decode "user-entered" URLs before loading them.
- Tabs.getInstance().loadUrl(decodeUserEnteredUrl(info.url), flags);
- Toast.makeText(activity, R.string.new_tab_opened, Toast.LENGTH_SHORT).show();
- return true;
- }
if (itemId == R.id.top_sites_pin) {
final String url = info.url;
@@ -361,28 +350,6 @@ public class TopSitesPanel extends HomeFragment {
return true;
}
- if (itemId == R.id.home_share) {
- if (info.url == null) {
- Log.w(LOGTAG, "Share not enabled for context menu because URL is null.");
- return false;
- } else {
- GeckoAppShell.openUriExternal(info.url, SHARE_MIME_TYPE, "", "",
- Intent.ACTION_SEND, info.getDisplayTitle());
- return true;
- }
- }
-
- if (itemId == R.id.home_add_to_launcher) {
- if (info.url == null) {
- Log.w(LOGTAG, "Not enabling 'Add to home page' because URL is null.");
- return false;
- }
-
- // Fetch an icon big enough for use as a home screen icon.
- Favicons.getPreferredSizeFaviconForPage(info.url, new GeckoAppShell.CreateShortcutFaviconLoadedListener(info.url, info.getDisplayTitle()));
- return true;
- }
-
return false;
}
@@ -403,14 +370,6 @@ public class TopSitesPanel extends HomeFragment {
return Uri.fromParts("user-entered", url, null).toString();
}
- static String decodeUserEnteredUrl(String url) {
- Uri uri = Uri.parse(url);
- if ("user-entered".equals(uri.getScheme())) {
- return uri.getSchemeSpecificPart();
- }
- return url;
- }
-
/**
* Listener for editing pinned sites.
*/
diff --git a/mobile/android/base/resources/menu/home_contextmenu.xml b/mobile/android/base/resources/menu/home_contextmenu.xml
index 3146a7df37c..972f3ad5171 100644
--- a/mobile/android/base/resources/menu/home_contextmenu.xml
+++ b/mobile/android/base/resources/menu/home_contextmenu.xml
@@ -17,6 +17,15 @@