Merge fx-team to central, a=merge

This commit is contained in:
Wes Kocher 2015-08-19 17:02:20 -07:00
commit 8cf0c01db1
25 changed files with 160 additions and 8 deletions

View File

@ -1,9 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
function runTests() {
// set max rows to 1, to avoid scroll events by clicking middle button
Services.prefs.setIntPref(PREF_NEWTAB_ROWS, 1);
yield setLinks("-1");
yield addNewTabPageTab();
// we need a second newtab to honor max rows
yield addNewTabPageTab();
// Remember if the click handler was triggered
let cell = getCell(0);
@ -16,4 +22,5 @@ function runTests() {
// Send a middle-click and make sure it happened
yield EventUtils.synthesizeMouseAtCenter(cell.node, {button: 1}, getContentWindow());
ok(clicked, "middle click triggered click listener");
Services.prefs.clearUserPref(PREF_NEWTAB_ROWS);
}

View File

@ -1,9 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
function runTests() {
// set max rows to 1, to avoid scroll events by clicking middle button
Services.prefs.setIntPref(PREF_NEWTAB_ROWS, 1);
yield setLinks("0");
yield addNewTabPageTab();
// we need a second newtab to honor max rows
yield addNewTabPageTab();
// Remember if the click handler was triggered
let {site} = getCell(0);
@ -22,4 +28,5 @@ function runTests() {
// Make sure the cell didn't actually get blocked
checkGrid("0");
Services.prefs.clearUserPref(PREF_NEWTAB_ROWS);
}

View File

@ -10,7 +10,8 @@ function runTests() {
// Focus count in new tab page.
// 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
// bar; search button; and toggle button.
// bar; search button; and toggle button. Additionaly there may or may not be
// a scroll bar caused by fix to 1180387, which will eat an extra focus
let FOCUS_COUNT = 30;
// Create a new tab page.
@ -42,7 +43,9 @@ function countFocus(aExpectedCount) {
let focusedElement = document.commandDispatcher.focusedElement;
if (focusedElement && focusedElement.classList.contains("urlbar-input")) {
window.removeEventListener("focus", onFocus, true);
is(focusCount, aExpectedCount, "Validate focus count in the new tab page.");
// account for a potential presence of a scroll bar
ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
"Validate focus count in the new tab page.");
executeSoon(TestRunner.next);
} else {
if (focusedElement && focusedElement.ownerDocument == contentDoc &&

View File

@ -587,7 +587,8 @@ function createExternalDropIframe() {
iframe.style.position = "absolute";
iframe.style.zIndex = 50;
let margin = doc.getElementById("newtab-margin-top");
// the frame has to be attached to a visible element
let margin = doc.getElementById("newtab-search-container");
margin.appendChild(iframe);
iframe.addEventListener("load", function onLoad() {

View File

@ -457,6 +457,7 @@ this.MigrationUtils = Object.freeze({
*
* @param aKey internal name of the migration source.
* Supported values: ie (windows),
* edge (windows),
* safari (mac/windows),
* canary (mac/windows),
* chrome (mac/windows/linux),

View File

@ -489,6 +489,7 @@
@RESPATH@/browser/components/FirefoxProfileMigrator.js
#ifdef XP_WIN
@RESPATH@/browser/components/360seProfileMigrator.js
@RESPATH@/browser/components/EdgeProfileMigrator.js
@RESPATH@/browser/components/IEProfileMigrator.js
@RESPATH@/browser/components/SafariProfileMigrator.js
#endif

View File

@ -61,6 +61,10 @@
background-color: ThreeDShadow;
}
#navigator-toolbox:-moz-lwtheme::after {
background-color: rgba(0,0,0,.3);
}
#navigator-toolbox > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar) {
-moz-appearance: none;
border-style: none;

View File

@ -107,19 +107,23 @@
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
#navigator-toolbox:not(:-moz-lwtheme)::after {
#navigator-toolbox::after {
background-color: #aabccf;
}
}
@media (-moz-os-version: windows-win8),
(-moz-os-version: windows-win10) {
#navigator-toolbox:not(:-moz-lwtheme)::after {
#navigator-toolbox::after {
background-color: #c2c2c2;
}
}
}
#navigator-toolbox:-moz-lwtheme::after {
background-color: rgba(0,0,0,.3);
}
#navigator-toolbox > toolbar {
-moz-appearance: none;
border-style: none;

View File

@ -415,7 +415,7 @@ public class BrowserContract {
public static final String DEFAULT_SORT_ORDER = CLIENT_LAST_MODIFIED + " DESC";
public static final String[] DEFAULT_PROJECTION = new String[] { _ID, URL, TITLE, EXCERPT, WORD_COUNT };
public static final String[] DEFAULT_PROJECTION = new String[] { _ID, URL, TITLE, EXCERPT, WORD_COUNT, IS_UNREAD };
// Minimum fields required to create a reading list item.
public static final String[] REQUIRED_FIELDS = { ReadingListItems.URL, ReadingListItems.TITLE };

View File

@ -189,6 +189,14 @@ public class LocalReadingListAccessor implements ReadingListAccessor {
cr.update(mReadingListUriWithProfile, values, ReadingListItems._ID + " = " + itemID, null);
}
@Override
public void markAsUnread(ContentResolver cr, long itemID) {
final ContentValues values = new ContentValues();
values.put(ReadingListItems.IS_UNREAD, 1);
cr.update(mReadingListUriWithProfile, values, ReadingListItems._ID + " = " + itemID, null);
}
@Override
public void updateContent(ContentResolver cr, long itemID, String resolvedTitle, String resolvedURL, String excerpt) {
final ContentValues values = new ContentValues();

View File

@ -37,6 +37,7 @@ public interface ReadingListAccessor {
void registerContentObserver(Context context, ContentObserver observer);
void markAsRead(ContentResolver cr, long itemID);
void markAsUnread(ContentResolver cr, long itemID);
void updateContent(ContentResolver cr, long itemID, String resolvedTitle, String resolvedURL, String excerpt);
void deleteItem(ContentResolver cr, long itemID);
}

View File

@ -73,6 +73,10 @@ class StubReadingListAccessor implements ReadingListAccessor {
public void markAsRead(ContentResolver cr, long itemID) {
}
@Override
public void markAsUnread(ContentResolver cr, long itemID) {
}
@Override
public void updateContent(ContentResolver cr, long itemID, String resolvedTitle, String resolvedURL, String excerpt) {
}

View File

@ -25,6 +25,7 @@ public class HomeContextMenuInfo extends AdapterContextMenuInfo {
public int historyId = -1;
public int bookmarkId = -1;
public int readingListItemId = -1;
public boolean isUnread;
public RemoveItemType itemType = null;
// Item type to be handled with "Remove" selection.

View File

@ -155,6 +155,9 @@ public abstract class HomeFragment extends Fragment {
if (!RestrictedProfiles.isAllowed(view.getContext(), Restriction.DISALLOW_PRIVATE_BROWSING)) {
menu.findItem(R.id.home_open_private_tab).setVisible(false);
}
menu.findItem(R.id.mark_read).setVisible(info.isInReadingList() && info.isUnread);
menu.findItem(R.id.mark_unread).setVisible(info.isInReadingList() && !info.isUnread);
}
@Override
@ -253,6 +256,22 @@ public abstract class HomeFragment extends Fragment {
return true;
}
if (itemId == R.id.mark_read) {
GeckoProfile
.get(context)
.getDB()
.getReadingListAccessor()
.markAsRead(context.getContentResolver(), info.id);
}
if (itemId == R.id.mark_unread) {
GeckoProfile
.get(context)
.getDB()
.getReadingListAccessor()
.markAsUnread(context.getContentResolver(), info.id);
}
return false;
}

View File

@ -90,6 +90,8 @@ public class ReadingListPanel extends HomeFragment {
// This item is a TwoLinePageRow, so we allow switch-to-tab.
mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB));
markAsRead(id);
}
});
@ -100,6 +102,7 @@ public class ReadingListPanel extends HomeFragment {
info.url = cursor.getString(cursor.getColumnIndexOrThrow(ReadingListItems.URL));
info.title = cursor.getString(cursor.getColumnIndexOrThrow(ReadingListItems.TITLE));
info.readingListItemId = cursor.getInt(cursor.getColumnIndexOrThrow(ReadingListItems._ID));
info.isUnread = cursor.getInt(cursor.getColumnIndexOrThrow(ReadingListItems.IS_UNREAD)) == 1;
info.itemType = RemoveItemType.READING_LIST;
return info;
}
@ -107,6 +110,15 @@ public class ReadingListPanel extends HomeFragment {
registerForContextMenu(mList);
}
private void markAsRead(long id) {
final Context context = getActivity();
GeckoProfile.get(context).getDB().getReadingListAccessor().markAsRead(
context.getContentResolver(),
id
);
}
@Override
public void onDestroyView() {
super.onDestroyView();

View File

@ -18,6 +18,7 @@ import android.database.Cursor;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -28,6 +29,7 @@ public class ReadingListRow extends LinearLayout {
private final TextView title;
private final TextView excerpt;
private final TextView readTime;
private final ImageView indicator;
// Average reading speed in words per minute.
private static final int AVERAGE_READING_SPEED = 250;
@ -50,6 +52,7 @@ public class ReadingListRow extends LinearLayout {
title = (TextView) findViewById(R.id.title);
excerpt = (TextView) findViewById(R.id.excerpt);
readTime = (TextView) findViewById(R.id.read_time);
indicator = (ImageView) findViewById(R.id.indicator);
}
public void updateFromCursor(Cursor cursor) {
@ -57,13 +60,19 @@ public class ReadingListRow extends LinearLayout {
return;
}
final boolean isUnread = cursor.getInt(cursor.getColumnIndexOrThrow(ReadingListItems.IS_UNREAD)) == 1;
final String url = cursor.getString(cursor.getColumnIndexOrThrow(ReadingListItems.URL));
final String titleText = cursor.getString(cursor.getColumnIndexOrThrow(ReadingListItems.TITLE));
title.setText(TextUtils.isEmpty(titleText) ? StringUtils.stripCommonSubdomains(StringUtils.stripScheme(url)) : titleText);
title.setTextAppearance(getContext(), isUnread ? R.style.Widget_ReadingListRow_Title_Unread : R.style.Widget_ReadingListRow_Title_Read);
final String excerptText = cursor.getString(cursor.getColumnIndexOrThrow(ReadingListItems.EXCERPT));
excerpt.setText(TextUtils.isEmpty(excerptText) ? url : excerptText);
excerpt.setTextAppearance(getContext(), isUnread ? R.style.Widget_ReadingListRow_Title_Unread : R.style.Widget_ReadingListRow_Title_Read);
indicator.setImageResource(isUnread ? R.drawable.reading_list_indicator_unread : R.drawable.reading_list_indicator_read);
/* Disabled until UX issues are fixed (see bug 1110461).
final int lengthIndex = cursor.getColumnIndexOrThrow(ReadingListItems.LENGTH);

View File

@ -391,6 +391,8 @@ size. -->
<!ENTITY contextmenu_top_sites_pin "Pin Site">
<!ENTITY contextmenu_top_sites_unpin "Unpin Site">
<!ENTITY contextmenu_add_search_engine "Add a Search Engine">
<!ENTITY contextmenu_mark_read "Mark as read">
<!ENTITY contextmenu_mark_unread "Mark as unread">
<!-- Localization note (doorhanger_login_no_username): This string is used in the save-login doorhanger
where normally a username would be displayed. In this case, no username was found, and this placeholder

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<stroke
android:width="1dp"
android:color="@color/disabled_grey" />
<solid
android:color="@android:color/white" />
<size
android:width="16dp"
android:height="16dp" />
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/fennec_ui_orange"/>
<size
android:width="16dp"
android:height="16dp"/>
</shape>

View File

@ -5,11 +5,16 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/indicator"
android:layout_width="64dp"
android:layout_height="match_parent"
android:scaleType="center" />
<LinearLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingLeft="@dimen/reading_list_row_padding_left"
android:paddingRight="@dimen/reading_list_row_padding_right"
android:orientation="vertical"
android:gravity="center_vertical">

View File

@ -29,6 +29,12 @@
<item android:id="@+id/home_edit_bookmark"
android:title="@string/contextmenu_edit_bookmark"/>
<item android:id="@+id/mark_read"
android:title="@string/contextmenu_mark_read" />
<item android:id="@+id/mark_unread"
android:title="@string/contextmenu_mark_unread" />
<item android:id="@+id/home_remove"
android:title="@string/contextmenu_remove"/>

View File

@ -86,7 +86,6 @@
<!-- Reading list row on about:home -->
<dimen name="reading_list_row_height">128dp</dimen>
<dimen name="reading_list_row_padding_left">15dp</dimen>
<dimen name="reading_list_row_padding_right">10dp</dimen>
<!-- Remote Tabs static view top padding. Less in landscape on phones. -->

View File

@ -137,6 +137,14 @@
<item name="android:ellipsize">end</item>
</style>
<style name="Widget.ReadingListRow.Title.Read" parent="Widget.ReadingListRow.Title">
<item name="android:textColor">@color/disabled_grey</item>
</style>
<style name="Widget.ReadingListRow.Title.Unread" parent="Widget.ReadingListRow.Title">
<item name="android:textColor">@color/text_and_tabs_tray_grey</item>
</style>
<style name="Widget.ReadingListRow.Description">
<item name="android:textAppearance">@style/TextAppearance.Widget.Home.ItemDescription</item>
<item name="android:maxLines">3</item>
@ -144,6 +152,14 @@
<item name="android:lineSpacingMultiplier">1.3</item>
</style>
<style name="Widget.ReadingListRow.Description.Read" parent="Widget.ReadingListRow.Description">
<item name="android:textColor">@color/disabled_grey</item>
</style>
<style name="Widget.ReadingListRow.Description.Unread" parent="Widget.ReadingListRow.Description">
<item name="android:textColor">@color/text_and_tabs_tray_grey</item>
</style>
<style name="Widget.ReadingListRow.ReadTime">
<item name="android:textColor">@color/fennec_ui_orange</item>
</style>

View File

@ -360,6 +360,8 @@
<string name="contextmenu_top_sites_pin">&contextmenu_top_sites_pin;</string>
<string name="contextmenu_top_sites_unpin">&contextmenu_top_sites_unpin;</string>
<string name="contextmenu_add_search_engine">&contextmenu_add_search_engine;</string>
<string name="contextmenu_mark_read">&contextmenu_mark_read;</string>
<string name="contextmenu_mark_unread">&contextmenu_mark_unread;</string>
<string name="doorhanger_login_no_username">&doorhanger_login_no_username;</string>
<string name="doorhanger_login_edit_title">&doorhanger_login_edit_title;</string>

View File

@ -8,9 +8,15 @@
is used as a title, with the privatebrowsingpage.title string preceding it but on a separate line.
So the final line will say "Private Browsing + Tracking Protection". -->
<!ENTITY privatebrowsingpage.title.private "+ Tracking Protection">
<!-- Localization note (privatebrowsingpage.title.normal1): "Private Browsing"
is capitalized in English to be consistent with our existing uses of the
term. -->
<!ENTITY privatebrowsingpage.title.normal1 "You are not in Private Browsing">
<!ENTITY privatebrowsingpage.description.private4 "&brandShortName; will prevent you from being tracked and won't remember any history, but downloaded files and new bookmarks will still be saved to your device.">
<!-- Localization note (privatebrowsingpage.description.normal2): "Private
Browsing is capitalized in English to be consistent with our existing uses
of the term. -->
<!ENTITY privatebrowsingpage.description.normal2 "In Private Browsing, we won't keep any of your browsing history or cookies. Bookmarks you add and files you download will still be saved on your device.">
<!ENTITY privatebrowsingpage.link.private "Want to learn more?">