зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to central, a=merge
This commit is contained in:
Коммит
8cf0c01db1
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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">
|
||||
|
|
|
@ -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"/>
|
||||
|
||||
|
|
|
@ -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. -->
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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?">
|
||||
|
|
Загрузка…
Ссылка в новой задаче