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 @@ + + + + + + diff --git a/mobile/android/base/resources/menu/top_sites_contextmenu.xml b/mobile/android/base/resources/menu/top_sites_contextmenu.xml deleted file mode 100644 index 336c1f82a9e..00000000000 --- a/mobile/android/base/resources/menu/top_sites_contextmenu.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - -