diff --git a/browser/devtools/animationinspector/components.js b/browser/devtools/animationinspector/components.js
index 57e38613f04..462963c388a 100644
--- a/browser/devtools/animationinspector/components.js
+++ b/browser/devtools/animationinspector/components.js
@@ -908,6 +908,23 @@ AnimationsTimeline.prototype = {
}
},
+ getAnimationTooltipText: function(state) {
+ let getTime = time => L10N.getFormatStr("player.timeLabel",
+ L10N.numberWithDecimals(time / 1000, 2));
+
+ let title = L10N.getFormatStr("timeline." + state.type + ".nameLabel",
+ state.name);
+ let delay = L10N.getStr("player.animationDelayLabel") + " " +
+ getTime(state.delay);
+ let duration = L10N.getStr("player.animationDurationLabel") + " " +
+ getTime(state.duration);
+ let iterations = L10N.getStr("player.animationIterationCountLabel") + " " +
+ (state.iterationCount ||
+ L10N.getStr("player.infiniteIterationCountText"));
+
+ return [title, duration, iterations, delay].join("\n");
+ },
+
drawTimeBlock: function({state}, el) {
let width = el.offsetWidth;
@@ -940,8 +957,7 @@ AnimationsTimeline.prototype = {
parent: iterations,
attributes: {
"class": "name",
- "title": L10N.getFormatStr("timeline." + state.type + ".nameLabel",
- state.name)
+ "title": this.getAnimationTooltipText(state)
},
textContent: state.name
});
diff --git a/browser/devtools/animationinspector/test/browser.ini b/browser/devtools/animationinspector/test/browser.ini
index ce858c966f6..a6e2ade4e27 100644
--- a/browser/devtools/animationinspector/test/browser.ini
+++ b/browser/devtools/animationinspector/test/browser.ini
@@ -42,6 +42,7 @@ support-files =
[browser_animation_timeline_scrubber_moves.js]
[browser_animation_timeline_shows_delay.js]
[browser_animation_timeline_shows_iterations.js]
+[browser_animation_timeline_shows_time_info.js]
[browser_animation_timeline_takes_rate_into_account.js]
[browser_animation_timeline_ui.js]
[browser_animation_toggle_button_resets_on_navigate.js]
diff --git a/browser/devtools/animationinspector/test/browser_animation_timeline_shows_time_info.js b/browser/devtools/animationinspector/test/browser_animation_timeline_shows_time_info.js
new file mode 100644
index 00000000000..9d6142c7dfc
--- /dev/null
+++ b/browser/devtools/animationinspector/test/browser_animation_timeline_shows_time_info.js
@@ -0,0 +1,29 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Check that the timeline-based UI displays animations' duration, delay and
+// iteration counts in tooltips.
+
+add_task(function*() {
+ yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
+ let {panel} = yield openAnimationInspectorNewUI();
+ yield waitForAllAnimationTargets(panel);
+
+ info("Getting the animation element from the panel");
+ let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
+ let timeBlockNameEls = timelineEl.querySelectorAll(".time-block .name");
+
+ // Verify that each time-block's name element has a tooltip that looks sort of
+ // ok. We don't need to test the actual content.
+ for (let el of timeBlockNameEls) {
+ ok(el.hasAttribute("title"), "The tooltip is defined");
+
+ let title = el.getAttribute("title");
+ ok(title.match(/Delay: [\d.]+s/), "The tooltip shows the delay");
+ ok(title.match(/Duration: [\d.]+s/), "The tooltip shows the delay");
+ ok(title.match(/Repeats: /), "The tooltip shows the iterations");
+ }
+});
diff --git a/browser/devtools/performance/test/browser_perf-loading-01.js b/browser/devtools/performance/test/browser_perf-loading-01.js
index 5f4ff29531f..205cb20f2d5 100644
--- a/browser/devtools/performance/test/browser_perf-loading-01.js
+++ b/browser/devtools/performance/test/browser_perf-loading-01.js
@@ -7,6 +7,9 @@
*/
let test = Task.async(function*() {
+ // This test seems to take a long time to cleanup.
+ requestLongerTimeout(2);
+
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
let { RecordingsView, PerformanceController, PerformanceView,
EVENTS, $, L10N } = panel.panelWin;
diff --git a/browser/devtools/performance/test/browser_perf-loading-02.js b/browser/devtools/performance/test/browser_perf-loading-02.js
index b045058fbc9..bbe94cc9c03 100644
--- a/browser/devtools/performance/test/browser_perf-loading-02.js
+++ b/browser/devtools/performance/test/browser_perf-loading-02.js
@@ -9,6 +9,9 @@
*/
let test = Task.async(function*() {
+ // This test seems to take a long time to cleanup.
+ requestLongerTimeout(2);
+
let { panel } = yield initPerformance(SIMPLE_URL);
let { PerformanceController, PerformanceView, RecordingsView,
EVENTS, $ } = panel.panelWin;
diff --git a/browser/locales/en-US/chrome/browser/devtools/animationinspector.properties b/browser/locales/en-US/chrome/browser/devtools/animationinspector.properties
index 15be119ae6b..1704212ee48 100644
--- a/browser/locales/en-US/chrome/browser/devtools/animationinspector.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/animationinspector.properties
@@ -41,6 +41,12 @@ player.animationIterationCountLabel=Repeats:
# player.animationIterationCountLabel string, instead of a number.
player.infiniteIterationCount=∞
+# LOCALIZATION NOTE (player.infiniteIterationCountText):
+# See player.infiniteIterationCount for a description of what this is.
+# Unlike player.infiniteIterationCount, this string isn't used in HTML, but in
+# a tooltip.
+player.infiniteIterationCountText=∞
+
# LOCALIZATION NOTE (player.timeLabel):
# This string is displayed in each animation player widget, to indicate either
# how long (in seconds) the animation lasts, or what is the animation's current
diff --git a/browser/themes/shared/notification-icons.inc.css b/browser/themes/shared/notification-icons.inc.css
index 54c55ae707a..6505c744d60 100644
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -106,11 +106,20 @@
padding-left: 7px;
}
+/* This changes the direction of the main notification box on the url bar. */
#notification-popup-box:-moz-locale-dir(rtl),
+/* This adds a second flip for the notification anchors, as they don't switch direction
+ for RTL mode. */
.notification-anchor-icon:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}
+/* For the anchor icons in the chat window, we don't have the notification popup box,
+ so we need to cancel the RTL transform. */
+.notification-anchor-icon.chat-toolbarbutton:-moz-locale-dir(rtl) {
+ transform: none;
+}
+
.notification-anchor-icon {
%ifdef MOZ_WIDGET_GTK
list-style-image: url(moz-icon://stock/gtk-dialog-info?size=16);
diff --git a/mobile/android/base/home/HomeConfig.java b/mobile/android/base/home/HomeConfig.java
index 4676548e17c..db253142b0b 100644
--- a/mobile/android/base/home/HomeConfig.java
+++ b/mobile/android/base/home/HomeConfig.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.util.Log;
public final class HomeConfig {
/**
@@ -1218,7 +1219,7 @@ public final class HomeConfig {
private void findNewDefault() {
// Pick the first panel that is neither disabled nor currently
// set as default.
- for (PanelConfig panelConfig : mConfigMap.values()) {
+ for (PanelConfig panelConfig : makeOrderedCopy(false)) {
if (!panelConfig.isDefault() && !panelConfig.isDisabled()) {
setDefault(panelConfig.getId());
return;
diff --git a/mobile/android/base/home/TopSitesPanel.java b/mobile/android/base/home/TopSitesPanel.java
index c9a4999cc9a..00672d2840c 100644
--- a/mobile/android/base/home/TopSitesPanel.java
+++ b/mobile/android/base/home/TopSitesPanel.java
@@ -345,13 +345,17 @@ public class TopSitesPanel extends HomeFragment {
return;
}
+ final Context context = view.getContext();
+
// Long pressed item was a Top Sites GridView item, handle it.
- MenuInflater inflater = new MenuInflater(view.getContext());
+ MenuInflater inflater = new MenuInflater(context);
inflater.inflate(R.menu.home_contextmenu, menu);
// Hide unused menu items.
menu.findItem(R.id.home_edit_bookmark).setVisible(false);
+ menu.findItem(R.id.home_remove).setVisible(RestrictedProfiles.isAllowed(context, Restriction.DISALLOW_CLEAR_HISTORY));
+
TopSitesGridContextMenuInfo info = (TopSitesGridContextMenuInfo) menuInfo;
menu.setHeaderTitle(info.getDisplayTitle());
@@ -372,9 +376,13 @@ public class TopSitesPanel extends HomeFragment {
menu.findItem(R.id.home_share).setVisible(false);
}
- if (!RestrictedProfiles.isAllowed(view.getContext(), Restriction.DISALLOW_PRIVATE_BROWSING)) {
+ if (!RestrictedProfiles.isAllowed(context, Restriction.DISALLOW_PRIVATE_BROWSING)) {
menu.findItem(R.id.home_open_private_tab).setVisible(false);
}
+
+ // We only show these menu items on the reading list panel:
+ menu.findItem(R.id.mark_read).setVisible(false);
+ menu.findItem(R.id.mark_unread).setVisible(false);
}
@Override
diff --git a/mobile/android/base/preferences/GeckoPreferences.java b/mobile/android/base/preferences/GeckoPreferences.java
index c6c146eaef4..9e936d4c8ed 100644
--- a/mobile/android/base/preferences/GeckoPreferences.java
+++ b/mobile/android/base/preferences/GeckoPreferences.java
@@ -132,6 +132,7 @@ OnSharedPreferenceChangeListener
public static final String PREFS_VOICE_INPUT_ENABLED = NON_PREF_PREFIX + "voice_input_enabled";
public static final String PREFS_QRCODE_ENABLED = NON_PREF_PREFIX + "qrcode_enabled";
private static final String PREFS_DEVTOOLS = NON_PREF_PREFIX + "devtools.enabled";
+ private static final String PREFS_DISPLAY = NON_PREF_PREFIX + "display.enabled";
private static final String PREFS_CUSTOMIZE_HOME = NON_PREF_PREFIX + "customize_home";
private static final String PREFS_TRACKING_PROTECTION_PRIVATE_BROWSING = "privacy.trackingprotection.pbmode.enabled";
private static final String PREFS_TRACKING_PROTECTION_LEARN_MORE = NON_PREF_PREFIX + "trackingprotection.learn_more";
@@ -706,12 +707,16 @@ OnSharedPreferenceChangeListener
}
}
if (PREFS_DEVTOOLS.equals(key) &&
- RestrictedProfiles.isUserRestricted(this)) {
+ !RestrictedProfiles.isAllowed(this, Restriction.DISALLOW_DEVELOPER_TOOLS)) {
+ preferences.removePreference(pref);
+ i--;
+ continue;
+ }
+ if (PREFS_DISPLAY.equals(key) && !RestrictedProfiles.isAllowed(this, Restriction.DISALLOW_DISPLAY_SETTINGS)) {
preferences.removePreference(pref);
i--;
continue;
}
-
if (PREFS_CUSTOMIZE_HOME.equals(key)) {
if (!RestrictedProfiles.isAllowed(this, Restriction.DISALLOW_CUSTOMIZE_HOME)) {
preferences.removePreference(pref);
diff --git a/mobile/android/base/resources/values-v21/themes.xml b/mobile/android/base/resources/values-v21/themes.xml
index b278270b0db..d3d2aedcd3e 100644
--- a/mobile/android/base/resources/values-v21/themes.xml
+++ b/mobile/android/base/resources/values-v21/themes.xml
@@ -23,4 +23,16 @@
+
+
diff --git a/mobile/android/base/resources/xml-v11/preferences.xml b/mobile/android/base/resources/xml-v11/preferences.xml
index 4cfde717290..3497d456924 100644
--- a/mobile/android/base/resources/xml-v11/preferences.xml
+++ b/mobile/android/base/resources/xml-v11/preferences.xml
@@ -26,7 +26,8 @@
+ android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment"
+ android:key="android.not_a_preference.display.enabled" >
diff --git a/mobile/android/base/restrictions/GuestProfileConfiguration.java b/mobile/android/base/restrictions/GuestProfileConfiguration.java
index 850fe709ad6..18caf5358a1 100644
--- a/mobile/android/base/restrictions/GuestProfileConfiguration.java
+++ b/mobile/android/base/restrictions/GuestProfileConfiguration.java
@@ -25,7 +25,8 @@ public class GuestProfileConfiguration implements RestrictionConfiguration {
Restriction.DISALLOW_SET_IMAGE,
Restriction.DISALLOW_MODIFY_ACCOUNTS,
Restriction.DISALLOW_REMOTE_DEBUGGING,
- Restriction.DISALLOW_IMPORT_SETTINGS
+ Restriction.DISALLOW_IMPORT_SETTINGS,
+ Restriction.DISALLOW_DEVELOPER_TOOLS
);
@SuppressWarnings("serial")
@@ -38,7 +39,8 @@ public class GuestProfileConfiguration implements RestrictionConfiguration {
);
private static final List BANNED_URLS = Arrays.asList(
- "about:config"
+ "about:config",
+ "about:addons"
);
@Override
@@ -59,6 +61,7 @@ public class GuestProfileConfiguration implements RestrictionConfiguration {
return false;
}
+ url = url.toLowerCase();
for (String banned : BANNED_URLS) {
if (url.startsWith(banned)) {
return false;
diff --git a/mobile/android/base/restrictions/RestrictedProfileConfiguration.java b/mobile/android/base/restrictions/RestrictedProfileConfiguration.java
index a75af7d5c39..b23f8a71027 100644
--- a/mobile/android/base/restrictions/RestrictedProfileConfiguration.java
+++ b/mobile/android/base/restrictions/RestrictedProfileConfiguration.java
@@ -30,7 +30,8 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
Restriction.DISALLOW_DISPLAY_SETTINGS,
Restriction.DISALLOW_CLEAR_HISTORY,
Restriction.DISALLOW_MASTER_PASSWORD,
- Restriction.DISALLOW_GUEST_BROWSING
+ Restriction.DISALLOW_GUEST_BROWSING,
+ Restriction.DISALLOW_DEFAULT_THEME
);
private Context context;
diff --git a/mobile/android/base/restrictions/Restriction.java b/mobile/android/base/restrictions/Restriction.java
index f53c8b3c0e1..c073baad44a 100644
--- a/mobile/android/base/restrictions/Restriction.java
+++ b/mobile/android/base/restrictions/Restriction.java
@@ -54,8 +54,9 @@ public enum Restriction {
DISALLOW_MASTER_PASSWORD(18, "no_master_password", R.string.restriction_disallow_master_password_title),
- DISALLOW_GUEST_BROWSING(19, "no_guest_browsing", R.string.restriction_disallow_guest_browsing_title);
+ DISALLOW_GUEST_BROWSING(19, "no_guest_browsing", R.string.restriction_disallow_guest_browsing_title),
+ DISALLOW_DEFAULT_THEME(20, "no_default_theme", 0);
public final int id;
public final String name;
diff --git a/mobile/android/base/restrictions/RestrictionProvider.java b/mobile/android/base/restrictions/RestrictionProvider.java
index d69427576e3..c21f8477e94 100644
--- a/mobile/android/base/restrictions/RestrictionProvider.java
+++ b/mobile/android/base/restrictions/RestrictionProvider.java
@@ -58,6 +58,11 @@ public class RestrictionProvider extends BroadcastReceiver {
continue;
}
+ if (restriction == Restriction.DISALLOW_DEFAULT_THEME) {
+ // This restriction is not configurable
+ continue;
+ }
+
RestrictionEntry entry = createRestrictionEntryWithDefaultValue(context, restriction,
oldRestrictions.getBoolean(restriction.name, true));
entries.add(entry);
diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js
index 7e7b2445c00..215432959fe 100644
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3080,7 +3080,10 @@ var LightWeightThemeWebInstaller = {
BrowserApp.deck.addEventListener("PreviewBrowserTheme", this, false, true);
BrowserApp.deck.addEventListener("ResetBrowserThemePreview", this, false, true);
- if (ParentalControls.parentalControlsEnabled && !this._manager.currentTheme) {
+ if (ParentalControls.parentalControlsEnabled &&
+ !this._manager.currentTheme &&
+ !ParentalControls.isAllowed(ParentalControls.DEFAULT_THEME)) {
+ // We are using the DEFAULT_THEME restriction to differentiate between restricted profiles & guest mode - Bug 1199596
this._installParentalControlsTheme();
}
},
@@ -5562,7 +5565,12 @@ var FormAssistant = {
if (this._showValidationMessage(focused))
break;
- this._showAutoCompleteSuggestions(focused, function () {});
+ let checkResultsClick = hasResults => {
+ if (!hasResults) {
+ this._hideFormAssistPopup();
+ }
+ };
+ this._showAutoCompleteSuggestions(focused, checkResultsClick);
} else {
// temporarily hide the form assist popup while we're panning or zooming the page
this._hideFormAssistPopup();
diff --git a/toolkit/components/parentalcontrols/nsIParentalControlsService.idl b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
index 0c4f413394a..c0b071db7b0 100644
--- a/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
+++ b/toolkit/components/parentalcontrols/nsIParentalControlsService.idl
@@ -11,7 +11,7 @@ interface nsIFile;
interface nsIInterfaceRequestor;
interface nsIArray;
-[scriptable, uuid(ed14d186-e902-4d41-86cb-8949fd7b53d7)]
+[scriptable, uuid(f9962e65-5369-4346-8c44-84d5319abfc2)]
interface nsIParentalControlsService : nsISupports
{
/**
@@ -36,6 +36,7 @@ interface nsIParentalControlsService : nsISupports
const short CLEAR_HISTORY = 17; // Clear browsing history
const short MASTER_PASSWORD = 18; // Setting master password for logins
const short GUEST_BROWSING = 19; // Disallow usage of guest browsing
+ const short DEFAULT_THEME = 20; // Use default theme or a special parental controls theme
/**
* @returns true if the current user account has parental controls