Merge mozilla-central to inbound. r=merge a=merge CLOSED TREE

This commit is contained in:
Tiberius Oros 2018-01-05 12:03:34 +02:00
commit 11f2a4970b
89 changed files with 1322 additions and 545 deletions

View File

@ -1038,12 +1038,12 @@ function _loadURIWithFlags(browser, uri, params) {
let mustChangeProcess = requiredRemoteType != currentRemoteType;
let newFrameloader = false;
if (browser.getAttribute("isPreloadBrowser") == "true" && uri != "about:newtab") {
if (browser.getAttribute("preloadedState") === "consumed" && uri != "about:newtab") {
// Leaving about:newtab from a used to be preloaded browser should run the process
// selecting algorithm again.
mustChangeProcess = true;
newFrameloader = true;
browser.removeAttribute("isPreloadBrowser");
browser.removeAttribute("preloadedState");
}
// !requiredRemoteType means we're loading in the parent/this process.
@ -1125,8 +1125,8 @@ function LoadInOtherProcess(browser, loadOptions, historyIndex = -1) {
// Called when a docshell has attempted to load a page in an incorrect process.
// This function is responsible for loading the page in the correct process.
function RedirectLoad({ target: browser, data }) {
if (browser.getAttribute("isPreloadBrowser") == "true") {
browser.removeAttribute("isPreloadBrowser");
if (browser.getAttribute("preloadedState") === "consumed") {
browser.removeAttribute("preloadedState");
data.loadOptions.newFrameloader = true;
}

View File

@ -314,7 +314,7 @@ var AboutNetAndCertErrorListener = {
// and adjusting the date per the interval would make the cert valid, warn the user:
if (Math.abs(difference) > 60 * 60 * 24 && (now - lastFetched) <= 60 * 60 * 24 * 5 &&
certRange.notBefore < approximateDate && certRange.notAfter > approximateDate) {
let formatter = Services.intl.createDateTimeFormat(undefined, {
let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});
let systemDate = formatter.format(new Date());
@ -350,7 +350,7 @@ var AboutNetAndCertErrorListener = {
// so we shouldn't exclude the possibility that the cert has become valid
// since the build date.
if (buildDate > systemDate && new Date(certRange.notAfter) > buildDate) {
let formatter = Services.intl.createDateTimeFormat(undefined, {
let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});

View File

@ -1016,7 +1016,7 @@ function formatDate(datestr, unknown) {
if (!date.valueOf())
return unknown;
const dateTimeFormatter = Services.intl.createDateTimeFormat(undefined, {
const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "long", timeStyle: "long"
});
return dateTimeFormatter.format(date);

View File

@ -2136,8 +2136,11 @@
// Also, we do not need to take care of attaching nsIFormFillControllers
// in the case that the browser is remote, as remote browsers take
// care of that themselves.
if (browser && this.hasAttribute("autocompletepopup")) {
browser.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
if (browser) {
browser.setAttribute("preloadedState", "consumed");
if (this.hasAttribute("autocompletepopup")) {
browser.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
}
}
return browser;
@ -2239,8 +2242,23 @@
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
}
/*
* This attribute is meant to describe if the browser is the
* preloaded browser. There are 2 defined states: "preloaded" or
* "consumed". The order of events goes as follows:
* 1. The preloaded browser is created and the 'preloadedState'
* attribute for that browser is set to "preloaded".
* 2. When a new tab is opened and it is time to show that
* preloaded browser, the 'preloadedState' attribute for that
* browser is set to "consumed"
* 3. When we then navigate away from about:newtab, the "consumed"
* browsers will attempt to switch to a new content process,
* therefore the 'preloadedState' attribute is removed from
* that browser altogether
* See more details on Bug 1420285.
*/
if (aParams.isPreloadBrowser) {
b.setAttribute("isPreloadBrowser", "true");
b.setAttribute("preloadedState", "preloaded");
}
if (this.hasAttribute("selectmenulist"))

View File

@ -151,7 +151,7 @@ add_task(async function checkWrongSystemTimeWarning() {
});
}
let formatter = Services.intl.createDateTimeFormat(undefined, {
let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});

View File

@ -50,16 +50,71 @@ add_task(async function() {
});
}, EXPECTED_OVERFLOW_REFLOWS, window);
await withReflowObserver(async function() {
Assert.ok(gBrowser.tabContainer.hasAttribute("overflow"),
"Tabs should now be overflowed.");
// Now test that opening and closing a tab while overflowed doesn't cause
// us to reflow.
await withReflowObserver(async function(dirtyFrame) {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
let transitionPromise =
BrowserTestUtils.waitForEvent(gBrowser.selectedTab,
"transitionend", false,
e => e.propertyName === "max-width");
await BrowserTestUtils.removeTab(gBrowser.selectedTab, { animate: true });
await transitionPromise;
BrowserOpenTab();
await switchDone;
}, EXPECTED_UNDERFLOW_REFLOWS, window);
await BrowserTestUtils.waitForCondition(() => {
return gBrowser.tabContainer.arrowScrollbox.hasAttribute("scrolledtoend");
});
}, [], window);
await withReflowObserver(async function(dirtyFrame) {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
await BrowserTestUtils.removeTab(gBrowser.selectedTab, { animate: true });
await switchDone;
}, [], window);
// At this point, we have an overflowed tab strip, and we've got the last tab
// selected. This should mean that the first tab is scrolled out of view.
// Let's test that we don't reflow when switching to that first tab.
let lastTab = gBrowser.selectedTab;
let arrowScrollbox = gBrowser.tabContainer.arrowScrollbox;
// First, we'll check that the first tab is actually scrolled
// at least partially out of view.
Assert.ok(arrowScrollbox.scrollPosition > 0,
"First tab should be partially scrolled out of view.");
// Now switch to the first tab. We shouldn't flush layout at all.
await withReflowObserver(async function(dirtyFrame) {
let firstTab = gBrowser.tabContainer.firstChild;
await BrowserTestUtils.switchTab(gBrowser, firstTab);
await BrowserTestUtils.waitForCondition(() => {
return gBrowser.tabContainer.arrowScrollbox.hasAttribute("scrolledtostart");
});
}, [], window);
// Okay, now close the last tab. The tabstrip should stay overflowed, but removing
// one more after that should underflow it.
await BrowserTestUtils.removeTab(lastTab);
Assert.ok(gBrowser.tabContainer.hasAttribute("overflow"),
"Tabs should still be overflowed.");
// Depending on the size of the window, it might take one or more tab
// removals to put the tab strip out of the overflow state, so we'll just
// keep testing removals until that occurs.
while (gBrowser.tabContainer.hasAttribute("overflow")) {
lastTab = gBrowser.tabContainer.lastElementChild;
if (gBrowser.selectedTab !== lastTab) {
await BrowserTestUtils.switchTab(gBrowser, lastTab);
}
// ... and make sure we don't flush layout when closing it, and exiting
// the overflowed state.
await withReflowObserver(async function() {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
await BrowserTestUtils.removeTab(lastTab, { animate: true });
await switchDone;
await BrowserTestUtils.waitForCondition(() => !lastTab.isConnected);
}, EXPECTED_UNDERFLOW_REFLOWS, window);
}
await removeAllButFirstTab();
});

View File

@ -192,7 +192,7 @@ FeedWriter.prototype = {
timeStyle: "short",
dateStyle: "long"
};
this.__dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
this.__dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__dateFormatter;
},

View File

@ -413,7 +413,7 @@ var PlacesOrganizer = {
const dtOptions = {
dateStyle: "long"
};
let dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
let dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
// Remove existing menu items. Last item is the restoreFromFile item.
while (restorePopup.childNodes.length > 1)

View File

@ -556,7 +556,7 @@ PlacesTreeView.prototype = {
get _todayFormatter() {
if (!this.__todayFormatter) {
const dtOptions = { timeStyle: "short" };
this.__todayFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
this.__todayFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__todayFormatter;
},
@ -568,7 +568,7 @@ PlacesTreeView.prototype = {
dateStyle: "short",
timeStyle: "short"
};
this.__dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
this.__dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__dateFormatter;
},

View File

@ -138,7 +138,7 @@
// a redirecting uri could be put in the tree while we test.
break;
}
let timeStr = Services.intl.createDateTimeFormat(undefined, dtOptions).format(timeObj);
let timeStr = new Services.intl.DateTimeFormat(undefined, dtOptions).format(timeObj);
is(text, timeStr, "Date format is correct");
break;

View File

@ -491,7 +491,7 @@ var gCookiesWindow = {
formatExpiresString(aExpires) {
if (aExpires) {
var date = new Date(1000 * aExpires);
const dateTimeFormatter = Services.intl.createDateTimeFormat(undefined, {
const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "long", timeStyle: "long"
});
return dateTimeFormatter.format(date);

View File

@ -246,7 +246,7 @@ this.TelemetryFeed = class TelemetryFeed {
*/
handleNewTabInit(action) {
const session = this.addSession(au.getPortIdOfSender(action), action.data.url);
session.perf.is_preloaded = action.data.browser.getAttribute("isPreloadBrowser") === "true";
session.perf.is_preloaded = action.data.browser.getAttribute("preloadedState") === "preloaded";
}
/**

View File

@ -0,0 +1,149 @@
diff -u python2.7-2.7.9/debian/changelog python2.7-2.7.9/debian/changelog
--- python2.7-2.7.9/debian/changelog
+++ python2.7-2.7.9/debian/changelog
@@ -1,3 +1,17 @@
+python2.7 (2.7.9-2.deb7moz1) wheezy; urgency=medium
+
+ * Mozilla backport for wheezy.
+ * debian/control.in:
+ - Remove gcc 4.9 build dependency, wheezy doesn't have it.
+ - Remove libexpat1-dev dependency from python dev packages. It prevents
+ from co-installing some i386 -dev packages.
+ * debian/rules:
+ - Adapt ar, ranlib and objcopy paths to work on wheezy.
+ * debian/control.in, debian/rules: Don't generate the -doc package, sphinx
+ is too old in wheezy.
+
+ -- Mike Hommey <glandium@mozilla.com> Fri, 13 Oct 2017 19:20:21 +0900
+
python2.7 (2.7.9-2+deb8u1) jessie; urgency=medium
* Backport upstream commit b3ce713fb9beebfff9848cefa0acbd59acc68fe9
diff -u python2.7-2.7.9/debian/control.in python2.7-2.7.9/debian/control.in
--- python2.7-2.7.9/debian/control.in
+++ python2.7-2.7.9/debian/control.in
@@ -3,7 +3,6 @@
Priority: optional
Maintainer: Matthias Klose <doko@debian.org>
Build-Depends: debhelper (>= 5), @bd_dpkgdev@
- gcc (>= 4:4.9.2),
quilt, autoconf, autotools-dev,
lsb-release, sharutils,
libreadline-dev, libtinfo-dev, libncursesw5-dev (>= 5.3), @bd_gcc@
@@ -112,7 +111,7 @@
Package: @PVER@-dev
Architecture: any
Multi-Arch: allowed
-Depends: @PVER@ (= ${binary:Version}), lib@PVER@-dev (= ${binary:Version}), lib@PVER@ (= ${binary:Version}), libexpat1-dev, ${shlibs:Depends}, ${misc:Depends}
+Depends: @PVER@ (= ${binary:Version}), lib@PVER@-dev (= ${binary:Version}), lib@PVER@ (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Recommends: libc6-dev | libc-dev
Replaces: @PVER@ (<< 2.7-3)
Description: Header files and a static library for Python (v@VER@)
@@ -127,7 +126,7 @@
Architecture: any
Multi-Arch: same
Pre-Depends: multiarch-support
-Depends: lib@PVER@-stdlib (= ${binary:Version}), lib@PVER@ (= ${binary:Version}), libexpat1-dev, ${shlibs:Depends}, ${misc:Depends}
+Depends: lib@PVER@-stdlib (= ${binary:Version}), lib@PVER@ (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Replaces: @PVER@ (<< 2.7-3), @PVER@-dev (<< 2.7.3-10), @PVER@-minimal (<< 2.7.3-10)
Recommends: libc6-dev | libc-dev
Description: Header files and a static library for Python (v@VER@)
@@ -161,27 +160,6 @@
IDLE is an Integrated Development Environment for Python (v@VER@).
IDLE is written using Tkinter and therefore quite platform-independent.
-Package: @PVER@-doc
-Section: doc
-Architecture: all
-Depends: libjs-jquery, libjs-underscore, ${misc:Depends}
-Suggests: @PVER@
-Description: Documentation for the high-level object-oriented language Python (v@VER@)
- These is the official set of documentation for the interactive high-level
- object-oriented language Python (v@VER@). All documents are provided
- in HTML format. The package consists of ten documents:
- .
- * What's New in Python@VER@
- * Tutorial
- * Python Library Reference
- * Macintosh Module Reference
- * Python Language Reference
- * Extending and Embedding Python
- * Python/C API Reference
- * Installing Python Modules
- * Documenting Python
- * Distributing Python Modules
-
Package: @PVER@-dbg
Section: debug
Architecture: any
diff -u python2.7-2.7.9/debian/rules python2.7-2.7.9/debian/rules
--- python2.7-2.7.9/debian/rules
+++ python2.7-2.7.9/debian/rules
@@ -121,8 +121,8 @@
CC = $(DEB_HOST_GNU_TYPE)-gcc
CXX=$(DEB_HOST_GNU_TYPE)-g++
-AR=$(DEB_HOST_GNU_TYPE)-ar
-RANLIB=$(DEB_HOST_GNU_TYPE)-ranlib
+AR=$(DEB_HOST_GNU_TYPE)-gcc-ar-4.7
+RANLIB=$(DEB_HOST_GNU_TYPE)-gcc-ranlib-4.7
DPKG_CFLAGS := $(shell dpkg-buildflags --get CPPFLAGS; dpkg-buildflags --get CFLAGS)
DPKG_LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS)
@@ -171,8 +171,6 @@
LTO_CFLAGS += -ffat-lto-objects
endif
EXTRA_OPT_CFLAGS += $(LTO_CFLAGS)
- AR=$(DEB_HOST_GNU_TYPE)-gcc-ar
- RANLIB=$(DEB_HOST_GNU_TYPE)-gcc-ranlib
endif
make_build_target = $(if $(with_pgo),profile-opt)
@@ -628,7 +626,6 @@
stamps/stamp-doc-html:
dh_testdir
- $(MAKE) -C Doc html
touch stamps/stamp-doc-html
build-doc: stamps/stamp-patch stamps/stamp-build-doc
@@ -1215,30 +1212,6 @@
dh_testdir -i
dh_testroot -i
- : # $(p_doc) package
- dh_installdirs -p$(p_doc) \
- usr/share/doc/$(p_base) \
- usr/share/doc/$(p_doc)
- dh_installdocs -p$(p_doc)
- cp -a Doc/build/html $(d_doc)/usr/share/doc/$(p_base)/
- rm -f $(d_doc)/usr/share/doc/$(p_base)/html/_static/jquery.js
- rm -f $(d_doc)/usr/share/doc/$(p_base)/html/_static/underscore.js
- dh_link -p$(p_doc) \
- /usr/share/doc/$(p_base)/html \
- /usr/share/doc/$(p_doc)/html \
- /usr/share/javascript/jquery/jquery.js \
- /usr/share/doc/$(p_base)/html/_static/jquery.js \
- /usr/share/javascript/underscore/underscore.js \
- /usr/share/doc/$(p_base)/html/_static/underscore.js
-
- : # devhelp docs
- $(buildd_static)/python debian/pyhtml2devhelp.py \
- $(d_doc)/usr/share/doc/$(p_base)/html index.html $(VER) \
- > $(d_doc)/usr/share/doc/$(p_base)/html/$(PVER).devhelp
- gzip -9v $(d_doc)/usr/share/doc/$(p_base)/html/$(PVER).devhelp
- dh_link -p$(p_doc) \
- /usr/share/doc/$(p_base)/html /usr/share/devhelp/books/$(PVER)
-
for i in $(p_ltst); do \
rm -rf debian/$$i/usr/share/doc/$$i; \
ln -s $(p_lbase) debian/$$i/usr/share/doc/$$i; \
@@ -1298,7 +1271,7 @@
endif
find $(d_ldbg) $(d_ldev) -name '*.a' ! -type l \
- | xargs -n 1 $(DEB_HOST_GNU_TYPE)-objcopy -p --remove-section=.gnu.lto_.*
+ | xargs -n 1 objcopy -p --remove-section=.gnu.lto_.*
dh_strip -a -N$(p_dbg) -N$(p_ldbg) -Xdebug -Xdbg --dbg-package=$(p_dbg)
cp Tools/gdb/libpython.py $(d_dbg)/usr/lib/debug/usr/bin/$(PVER)-gdb.py
ln -sf $(PVER)-gdb.py $(d_dbg)/usr/lib/debug/usr/bin/$(PVER)-dbg-gdb.py

View File

@ -13,7 +13,7 @@ add_task(function* () {
let { tab, document } = yield openAboutDebugging("workers");
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
let serviceWorkersElement = getServiceWorkerList(document);

View File

@ -12,7 +12,7 @@ function* testBody(url, expecting) {
yield enableServiceWorkerDebugging();
let { tab, document } = yield openAboutDebugging("workers");
let swTab = yield addTab(url);
let swTab = yield addTab(url, {background: true});
let serviceWorkersElement = getServiceWorkerList(document);

View File

@ -22,7 +22,7 @@ add_task(function* () {
let serviceWorkersElement = getServiceWorkerList(document);
// Open a tab that registers a push service worker.
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
info("Make the test page notify us when the service worker sends a message.");

View File

@ -58,7 +58,7 @@ add_task(function* () {
let serviceWorkersElement = document.getElementById("service-workers");
// Open a tab that registers a push service worker.
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
info("Wait until the service worker appears in about:debugging");
yield waitUntilServiceWorkerContainer(SERVICE_WORKER, document);

View File

@ -25,7 +25,7 @@ add_task(function* () {
let serviceWorkersElement = getServiceWorkerList(document);
// Open a tab that registers an empty service worker.
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
// Wait for the service-workers list to update.
info("Wait until the service worker appears in about:debugging");

View File

@ -21,7 +21,7 @@ add_task(function* () {
// Listen for mutations in the service-workers list.
let serviceWorkersElement = getServiceWorkerList(document);
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
info("Wait until the service worker appears in about:debugging");
let container = yield waitUntilServiceWorkerContainer(SERVICE_WORKER, document);

View File

@ -20,7 +20,7 @@ add_task(function* () {
let serviceWorkersElement = getServiceWorkerList(document);
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
info("Wait until the service worker appears in about:debugging");
yield waitUntilServiceWorkerContainer(SERVICE_WORKER, document);

View File

@ -20,7 +20,7 @@ add_task(function* () {
let { tab, document } = yield openAboutDebugging("workers");
// Open a tab that registers an empty service worker.
let swTab = yield addTab(TAB_URL);
let swTab = yield addTab(TAB_URL, { background: true });
info("Wait until the service worker appears in about:debugging");
yield waitUntilServiceWorkerContainer(SERVICE_WORKER, document);

View File

@ -1143,6 +1143,98 @@ waitForAllPaints(() => {
await ensureElementRemoval(scrollDiv);
});
add_task(
async function throttling_animations_in_out_of_view_position_absolute_element() {
if (!offscreenThrottlingEnabled) {
return;
}
var parentDiv = addDiv(null,
{ style: 'position: absolute; top: -1000px;' });
var targetDiv = addDiv(null,
{ style: 'animation: background-color 100s;' });
parentDiv.appendChild(targetDiv);
var animation = targetDiv.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'CSS animation in an out-of-view position absolute element should ' +
'be throttled');
await ensureElementRemoval(parentDiv);
}
);
add_task(
async function throttling_animations_on_out_of_view_position_absolute_element() {
if (!offscreenThrottlingEnabled) {
return;
}
var div = addDiv(null,
{ style: 'animation: background-color 100s; ' +
'position: absolute; top: -1000px;' });
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'CSS animation on an out-of-view position absolute element should ' +
'be throttled');
await ensureElementRemoval(div);
}
);
add_task(
async function throttling_animations_in_out_of_view_position_fixed_element() {
if (!offscreenThrottlingEnabled) {
return;
}
var parentDiv = addDiv(null,
{ style: 'position: fixed; top: -1000px;' });
var targetDiv = addDiv(null,
{ style: 'animation: background-color 100s;' });
parentDiv.appendChild(targetDiv);
var animation = targetDiv.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'CSS animation on an out-of-view position:fixed element should be ' +
'throttled');
await ensureElementRemoval(parentDiv);
}
);
add_task(
async function throttling_animations_on_out_of_view_position_fixed_element() {
if (!offscreenThrottlingEnabled) {
return;
}
var div = addDiv(null,
{ style: 'animation: background-color 100s; ' +
'position: fixed; top: -1000px;' });
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'CSS animation on an out-of-view position:fixed element should be ' +
'throttled');
await ensureElementRemoval(div);
}
);
add_task_if_omta_enabled(
async function no_restyling_for_compositor_animation_on_unrelated_style_change() {
var div = addDiv(null);

View File

@ -2250,7 +2250,7 @@ GK_ATOM(DisplayPortMargins, "_displayportmargins")
GK_ATOM(DisplayPortBase, "_displayportbase")
GK_ATOM(AsyncScrollLayerCreationFailed, "_asyncscrolllayercreationfailed")
GK_ATOM(forcemessagemanager, "forcemessagemanager")
GK_ATOM(isPreloadBrowser, "isPreloadBrowser")
GK_ATOM(preloadedState, "preloadedState")
// Names for system metrics
GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")

View File

@ -1,4 +1,6 @@
const TEST_URL = "http://www.example.com/browser/dom/base/test/dummy.html";
const PRELOADED_STATE = "preloaded";
const CONSUMED_STATE = "consumed";
var ppmm = Services.ppmm;
@ -77,3 +79,30 @@ add_task(async function(){
// not host any tabs reliably.
ppmm.releaseCachedProcesses();
});
add_task(async function preloaded_state_attribute() {
// Wait for a preloaded browser to exist, use it, and then create another one
await ensurePreloaded(gBrowser);
let preloadedTabState = gBrowser._preloadedBrowser.getAttribute("preloadedState");
is(preloadedTabState, PRELOADED_STATE, "Sanity check that the first preloaded browser has the correct attribute");
BrowserOpenTab();
await ensurePreloaded(gBrowser);
// Now check that the tabs have the correct browser attributes set
let consumedTabState = gBrowser.selectedBrowser.getAttribute("preloadedState");
is(consumedTabState, CONSUMED_STATE, "The opened tab consumed the preloaded browser and updated the attribute");
preloadedTabState = gBrowser._preloadedBrowser.getAttribute("preloadedState");
is(preloadedTabState, PRELOADED_STATE, "The preloaded browser has the correct attribute");
// Navigate away and check that the attribute has been removed altogether
gBrowser.selectedBrowser.loadURI(TEST_URL);
let navigatedTabHasState = gBrowser.selectedBrowser.hasAttribute("preloadedState");
ok(!navigatedTabHasState, "Correctly removed the preloadState attribute when navigating away");
// Remove tabs and preloaded browsers
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
gBrowser.removePreloadedBrowser();
});

View File

@ -1136,9 +1136,9 @@ ContentParent::CreateBrowser(const TabContext& aContext,
bool isPreloadBrowser = false;
nsAutoString isPreloadBrowserStr;
if (aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::isPreloadBrowser,
if (aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::preloadedState,
isPreloadBrowserStr)) {
isPreloadBrowser = isPreloadBrowserStr.EqualsLiteral("true");
isPreloadBrowser = isPreloadBrowserStr.EqualsLiteral("preloaded");
}
RefPtr<nsIContentParent> constructorSender;

View File

@ -724,16 +724,18 @@ void
MediaCache::CloseStreamsForPrivateBrowsing()
{
MOZ_ASSERT(NS_IsMainThread());
sThread->Dispatch(
NS_NewRunnableFunction("MediaCache::CloseStreamsForPrivateBrowsing",
[self = RefPtr<MediaCache>(this)]() {
AutoLock lock(self->mMonitor);
for (MediaCacheStream* s : self->mStreams) {
if (s->mIsPrivateBrowsing) {
s->CloseInternal(lock);
}
}
}));
sThread->Dispatch(NS_NewRunnableFunction(
"MediaCache::CloseStreamsForPrivateBrowsing",
[self = RefPtr<MediaCache>(this)]() {
AutoLock lock(self->mMonitor);
// Copy mStreams since CloseInternal() will change the array.
nsTArray<MediaCacheStream*> streams(self->mStreams);
for (MediaCacheStream* s : streams) {
if (s->mIsPrivateBrowsing) {
s->CloseInternal(lock);
}
}
}));
}
/* static */ RefPtr<MediaCache>

View File

@ -390,14 +390,14 @@ VROculusSession::Refresh(bool aForceRefresh)
if (mSession && mTextureSet) {
if (!aForceRefresh) {
// VROculusSession didn't start submitting frames yet.
if (!mSubmitThread) {
// Or, the VR thread has been shut down already.
if (!mSubmitThread || !mSubmitThread->IsActive()) {
return;
}
// ovr_SubmitFrame is running at VR Submit thread,
// so we post this task to VR Submit thread and let it paint
// a black frame.
mDrawBlack = true;
MOZ_ASSERT(mSubmitThread->IsActive());
mSubmitThread->PostTask(NewRunnableMethod<bool>(
"gfx::VROculusSession::Refresh",
this,

View File

@ -452,16 +452,6 @@ nsBlockFrame::GetFrameName(nsAString& aResult) const
}
#endif
#ifdef DEBUG
nsFrameState
nsBlockFrame::GetDebugStateBits() const
{
// We don't want to include our cursor flag in the bits the
// regression tester looks at
return nsContainerFrame::GetDebugStateBits() & ~NS_BLOCK_HAS_LINE_CURSOR;
}
#endif
void
nsBlockFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{

View File

@ -157,7 +157,6 @@ public:
#endif
#ifdef DEBUG
nsFrameState GetDebugStateBits() const override;
const char* LineReflowStatusToString(LineReflowStatus aLineReflowStatus) const;
#endif

View File

@ -7811,55 +7811,6 @@ nsIFrame::RootFrameList(nsPresContext* aPresContext, FILE* out, const char* aPre
}
#endif
#ifdef DEBUG
nsFrameState
nsFrame::GetDebugStateBits() const
{
// We'll ignore these flags for the purposes of comparing frame state:
//
// NS_FRAME_EXTERNAL_REFERENCE
// because this is set by the event state manager or the
// caret code when a frame is focused. Depending on whether
// or not the regression tests are run as the focused window
// will make this value vary randomly.
#define IRRELEVANT_FRAME_STATE_FLAGS NS_FRAME_EXTERNAL_REFERENCE
#define FRAME_STATE_MASK (~(IRRELEVANT_FRAME_STATE_FLAGS))
return GetStateBits() & FRAME_STATE_MASK;
}
void
nsFrame::XMLQuote(nsString& aString)
{
int32_t i, len = aString.Length();
for (i = 0; i < len; i++) {
char16_t ch = aString.CharAt(i);
if (ch == '<') {
nsAutoString tmp(NS_LITERAL_STRING("&lt;"));
aString.Cut(i, 1);
aString.Insert(tmp, i);
len += 3;
i += 3;
}
else if (ch == '>') {
nsAutoString tmp(NS_LITERAL_STRING("&gt;"));
aString.Cut(i, 1);
aString.Insert(tmp, i);
len += 3;
i += 3;
}
else if (ch == '\"') {
nsAutoString tmp(NS_LITERAL_STRING("&quot;"));
aString.Cut(i, 1);
aString.Insert(tmp, i);
len += 5;
i += 5;
}
}
}
#endif
bool
nsIFrame::IsVisibleForPainting(nsDisplayListBuilder* aBuilder) {
if (!StyleVisibility()->IsVisible())
@ -11016,6 +10967,7 @@ IsFrameScrolledOutOfView(nsIFrame* aTarget,
nsIScrollableFrame* scrollableFrame =
nsLayoutUtils::GetNearestScrollableFrame(aParent,
nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
if (!scrollableFrame) {
return false;

View File

@ -494,8 +494,6 @@ public:
// NS_FRAME_IS_DIRTY bit set
static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
static void XMLQuote(nsString& aString);
// Display Reflow Debugging
static void* DisplayReflowEnter(nsPresContext* aPresContext,
nsIFrame* aFrame,
@ -727,11 +725,6 @@ public:
#ifdef DEBUG
public:
/**
* Return the state bits that are relevant to regression tests (that
* is, those bits which indicate a real difference when they differ
*/
nsFrameState GetDebugStateBits() const override;
/**
* See if style tree verification is enabled. To enable style tree
* verification add "styleverifytree:1" to your MOZ_LOG

View File

@ -4550,11 +4550,6 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const = 0;
#endif
#ifdef DEBUG
public:
virtual nsFrameState GetDebugStateBits() const = 0;
#endif
};
//----------------------------------------------------------------------

View File

@ -10261,16 +10261,6 @@ nsTextFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
}
#endif
#ifdef DEBUG
nsFrameState
nsTextFrame::GetDebugStateBits() const
{
// mask out our emptystate flags; those are just caches
return nsFrame::GetDebugStateBits() &
~(TEXT_WHITESPACE_FLAGS | TEXT_REFLOW_FLAGS);
}
#endif
void
nsTextFrame::AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd)
{

View File

@ -172,10 +172,6 @@ public:
void ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const;
#endif
#ifdef DEBUG
nsFrameState GetDebugStateBits() const override;
#endif
ContentOffsets CalcContentOffsetsFromFramePoint(const nsPoint& aPoint) override;
ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint& aPoint);

View File

@ -37,7 +37,7 @@ TEST_DIRS += [
DIRS += ['build', 'media']
if CONFIG['MOZ_DEBUG']:
if CONFIG['MOZ_DEBUG'] and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
TEST_DIRS += ['tools/layout-debug']
CRASHTEST_MANIFESTS += ['../testing/crashtest/crashtests.list']

View File

@ -1802,19 +1802,25 @@ Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
}
}
template <typename StyleType>
static void
EnsureStyleAutoArrayLength(StyleType* aArray, size_t aLen)
{
size_t oldLength = aArray->Length();
aArray->EnsureLengthAtLeast(aLen);
for (size_t i = oldLength; i < aLen; ++i) {
(*aArray)[i].SetInitialValues();
}
}
void
Gecko_EnsureStyleAnimationArrayLength(void* aArray, size_t aLen)
{
auto base =
static_cast<nsStyleAutoArray<StyleAnimation>*>(aArray);
size_t oldLength = base->Length();
base->EnsureLengthAtLeast(aLen);
for (size_t i = oldLength; i < aLen; ++i) {
(*base)[i].SetInitialValues();
}
EnsureStyleAutoArrayLength(base, aLen);
}
void
@ -1822,14 +1828,7 @@ Gecko_EnsureStyleTransitionArrayLength(void* aArray, size_t aLen)
{
auto base =
reinterpret_cast<nsStyleAutoArray<StyleTransition>*>(aArray);
size_t oldLength = base->Length();
base->EnsureLengthAtLeast(aLen);
for (size_t i = oldLength; i < aLen; ++i) {
(*base)[i].SetInitialValues();
}
EnsureStyleAutoArrayLength(base, aLen);
}
void

View File

@ -422,14 +422,14 @@ public:
}
bool BuildKeyframes(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
nsAtom* aName,
const nsTimingFunction& aTimingFunction,
nsTArray<Keyframe>& aKeyframes)
{
ServoStyleSet* styleSet = aPresContext->StyleSet()->AsServo();
MOZ_ASSERT(styleSet);
const nsTimingFunction& timingFunction = aSrc.GetTimingFunction();
return styleSet->GetKeyframesForName(aSrc.GetName(),
timingFunction,
return styleSet->GetKeyframesForName(aName,
aTimingFunction,
aKeyframes);
}
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
@ -493,7 +493,8 @@ public:
}
bool BuildKeyframes(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
nsAtom* aName,
const nsTimingFunction& aTimingFunction,
nsTArray<Keyframe>& aKeyframs);
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
nsTArray<Keyframe>&& aKeyframes)
@ -505,7 +506,7 @@ public:
private:
nsTArray<Keyframe> BuildAnimationFrames(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
const nsTimingFunction& aTimingFunction,
const nsCSSKeyframesRule* aRule);
Maybe<ComputedTimingFunction> GetKeyframeTimingFunction(
nsPresContext* aPresContext,
@ -589,30 +590,37 @@ template<class BuilderType>
static already_AddRefed<CSSAnimation>
BuildAnimation(nsPresContext* aPresContext,
const NonOwningAnimationTarget& aTarget,
const StyleAnimation& aSrc,
const nsStyleDisplay& aStyleDisplay,
uint32_t animIdx,
BuilderType& aBuilder,
nsAnimationManager::CSSAnimationCollection* aCollection)
{
MOZ_ASSERT(aPresContext);
nsAtom* animationName = aStyleDisplay.GetAnimationName(animIdx);
nsTArray<Keyframe> keyframes;
if (!aBuilder.BuildKeyframes(aPresContext, aSrc, keyframes)) {
if (!aBuilder.BuildKeyframes(aPresContext,
animationName,
aStyleDisplay.GetAnimationTimingFunction(animIdx),
keyframes)) {
return nullptr;
}
TimingParams timing = TimingParamsFromCSSParams(aSrc.GetDuration(),
aSrc.GetDelay(),
aSrc.GetIterationCount(),
aSrc.GetDirection(),
aSrc.GetFillMode());
TimingParams timing =
TimingParamsFromCSSParams(aStyleDisplay.GetAnimationDuration(animIdx),
aStyleDisplay.GetAnimationDelay(animIdx),
aStyleDisplay.GetAnimationIterationCount(animIdx),
aStyleDisplay.GetAnimationDirection(animIdx),
aStyleDisplay.GetAnimationFillMode(animIdx));
bool isStylePaused =
aSrc.GetPlayState() == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
aStyleDisplay.GetAnimationPlayState(animIdx) ==
NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
// Find the matching animation with animation name in the old list
// of animations and remove the matched animation from the list.
RefPtr<CSSAnimation> oldAnim =
PopExistingAnimation(aSrc.GetName(), aCollection);
PopExistingAnimation(animationName, aCollection);
if (oldAnim) {
// Copy over the start times and (if still paused) pause starts
@ -642,8 +650,7 @@ BuildAnimation(nsPresContext* aPresContext,
aBuilder.SetKeyframes(*effect, Move(keyframes));
RefPtr<CSSAnimation> animation =
new CSSAnimation(aPresContext->Document()->GetScopeObject(),
aSrc.GetName());
new CSSAnimation(aPresContext->Document()->GetScopeObject(), animationName);
animation->SetOwningElement(
OwningElementRef(*aTarget.mElement, aTarget.mPseudoType));
@ -663,27 +670,29 @@ BuildAnimation(nsPresContext* aPresContext,
bool
GeckoCSSAnimationBuilder::BuildKeyframes(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
nsAtom* aName,
const nsTimingFunction& aTimingFunction,
nsTArray<Keyframe>& aKeyframes)
{
MOZ_ASSERT(aPresContext);
MOZ_ASSERT(aPresContext->StyleSet()->IsGecko());
nsCSSKeyframesRule* rule =
aPresContext->StyleSet()->AsGecko()->KeyframesRuleForName(aSrc.GetName());
aPresContext->StyleSet()->AsGecko()->KeyframesRuleForName(aName);
if (!rule) {
return false;
}
aKeyframes = BuildAnimationFrames(aPresContext, aSrc, rule);
aKeyframes = BuildAnimationFrames(aPresContext, aTimingFunction, rule);
return true;
}
nsTArray<Keyframe>
GeckoCSSAnimationBuilder::BuildAnimationFrames(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
const nsCSSKeyframesRule* aRule)
GeckoCSSAnimationBuilder::BuildAnimationFrames(
nsPresContext* aPresContext,
const nsTimingFunction& aTimingFunction,
const nsCSSKeyframesRule* aRule)
{
// Ideally we'd like to build up a set of Keyframe objects that more-or-less
// reflect the keyframes as-specified in the @keyframes rule(s) so that
@ -733,7 +742,7 @@ GeckoCSSAnimationBuilder::BuildAnimationFrames(nsPresContext* aPresContext,
// rules with the same name cascade but we don't support that yet.
Maybe<ComputedTimingFunction> inheritedTimingFunction =
ConvertTimingFunction(aSrc.GetTimingFunction());
ConvertTimingFunction(aTimingFunction);
// First, make up Keyframe objects for each rule
nsTArray<Keyframe> keyframes;
@ -1009,28 +1018,26 @@ template<class BuilderType>
static nsAnimationManager::OwningCSSAnimationPtrArray
BuildAnimations(nsPresContext* aPresContext,
const NonOwningAnimationTarget& aTarget,
const nsStyleAutoArray<StyleAnimation>& aStyleAnimations,
uint32_t aStyleAnimationNameCount,
const nsStyleDisplay& aStyleDisplay,
BuilderType& aBuilder,
nsAnimationManager::CSSAnimationCollection* aCollection)
{
nsAnimationManager::OwningCSSAnimationPtrArray result;
for (size_t animIdx = aStyleAnimationNameCount; animIdx-- != 0;) {
const StyleAnimation& src = aStyleAnimations[animIdx];
for (size_t animIdx = aStyleDisplay.mAnimationNameCount; animIdx-- != 0;) {
// CSS Animations whose animation-name does not match a @keyframes rule do
// not generate animation events. This includes when the animation-name is
// "none" which is represented by an empty name in the StyleAnimation.
// Since such animations neither affect style nor dispatch events, we do
// not generate a corresponding CSSAnimation for them.
if (src.GetName() == nsGkAtoms::_empty) {
if (aStyleDisplay.GetAnimationName(animIdx) == nsGkAtoms::_empty) {
continue;
}
RefPtr<CSSAnimation> dest = BuildAnimation(aPresContext,
aTarget,
src,
aStyleDisplay,
animIdx,
aBuilder,
aCollection);
if (!dest) {
@ -1126,8 +1133,7 @@ nsAnimationManager::DoUpdateAnimations(
OwningCSSAnimationPtrArray newAnimations;
newAnimations = BuildAnimations(mPresContext,
aTarget,
aStyleDisplay.mAnimations,
aStyleDisplay.mAnimationNameCount,
aStyleDisplay,
aBuilder,
collection);

View File

@ -2260,11 +2260,6 @@ struct StyleTransition
nsCSSPropertyID GetProperty() const { return mProperty; }
nsAtom* GetUnknownProperty() const { return mUnknownProperty; }
float GetCombinedDuration() const {
// http://dev.w3.org/csswg/css-transitions/#combined-duration
return std::max(mDuration, 0.0f) + mDelay;
}
void SetTimingFunction(const nsTimingFunction& aTimingFunction)
{ mTimingFunction = aTimingFunction; }
void SetDelay(float aDelay) { mDelay = aDelay; }
@ -2610,6 +2605,31 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
mTransitionDelayCount,
mTransitionPropertyCount;
nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const
{
return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
}
float GetTransitionDelay(uint32_t aIndex) const
{
return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
}
float GetTransitionDuration(uint32_t aIndex) const
{
return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
}
const nsTimingFunction& GetTransitionTimingFunction(uint32_t aIndex) const
{
return mTransitions[aIndex % mTransitionTimingFunctionCount].GetTimingFunction();
}
float GetTransitionCombinedDuration(uint32_t aIndex) const
{
// https://drafts.csswg.org/css-transitions/#transition-combined-duration
return
std::max(mTransitions[aIndex % mTransitionDurationCount].GetDuration(),
0.0f)
+ mTransitions[aIndex % mTransitionDelayCount].GetDelay();
}
nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; // [reset]
// The number of elements in mAnimations that are not from repeating
@ -2623,6 +2643,38 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
mAnimationPlayStateCount,
mAnimationIterationCountCount;
nsAtom* GetAnimationName(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationNameCount].GetName();
}
float GetAnimationDelay(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
}
float GetAnimationDuration(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
}
mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
}
mozilla::dom::FillMode GetAnimationFillMode(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
}
uint8_t GetAnimationPlayState(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
}
float GetAnimationIterationCount(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationIterationCountCount].GetIterationCount();
}
const nsTimingFunction& GetAnimationTimingFunction(uint32_t aIndex) const
{
return mAnimations[aIndex % mAnimationTimingFunctionCount].GetTimingFunction();
}
// The threshold used for extracting a shape from shape-outside: <image>.
float mShapeImageThreshold = 0.0f; // [reset]

View File

@ -522,7 +522,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
// Return sooner (before the startedAny check below) for the most
// common case: no transitions specified or running.
const nsStyleDisplay *disp = newStyleContext->StyleDisplay();
const nsStyleDisplay* disp = newStyleContext->StyleDisplay();
CSSPseudoElementType pseudoType = newStyleContext->GetPseudoType();
if (pseudoType != CSSPseudoElementType::NotPseudo) {
if (pseudoType != CSSPseudoElementType::before &&
@ -545,7 +545,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
CSSTransitionCollection::GetAnimationCollection(aElement, pseudoType);
if (!collection &&
disp->mTransitionPropertyCount == 1 &&
disp->mTransitions[0].GetCombinedDuration() <= 0.0f) {
disp->GetTransitionCombinedDuration(0) <= 0.0f) {
return;
}
@ -598,7 +598,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
// We don't have to update transitions if display:none, although we will
// cancel them after restyling.
if (!afterChangeStyle->IsInDisplayNoneSubtree()) {
startedAny = DoUpdateTransitions(disp,
startedAny = DoUpdateTransitions(*disp,
aElement,
afterChangeStyle->GetPseudoType(),
collection,
@ -647,9 +647,9 @@ nsTransitionManager::UpdateTransitions(
CSSTransitionCollection* collection =
CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
const nsStyleDisplay *disp =
const nsStyleDisplay* disp =
aNewStyle->ComputedData()->GetStyleDisplay();
return DoUpdateTransitions(disp,
return DoUpdateTransitions(*disp,
aElement, aPseudoType,
collection,
aOldStyle, aNewStyle);
@ -658,14 +658,13 @@ nsTransitionManager::UpdateTransitions(
template<typename StyleType>
bool
nsTransitionManager::DoUpdateTransitions(
const nsStyleDisplay* aDisp,
const nsStyleDisplay& aDisp,
dom::Element* aElement,
CSSPseudoElementType aPseudoType,
CSSTransitionCollection*& aElementTransitions,
StyleType aOldStyle,
StyleType aNewStyle)
{
MOZ_ASSERT(aDisp, "Null nsStyleDisplay");
MOZ_ASSERT(!aElementTransitions ||
aElementTransitions->mElement == aElement, "Element mismatch");
@ -675,17 +674,16 @@ nsTransitionManager::DoUpdateTransitions(
// ones (tracked using |whichStarted|).
bool startedAny = false;
nsCSSPropertyIDSet whichStarted;
for (uint32_t i = aDisp->mTransitionPropertyCount; i-- != 0; ) {
const StyleTransition& t = aDisp->mTransitions[i];
for (uint32_t i = aDisp.mTransitionPropertyCount; i-- != 0; ) {
// Check the combined duration (combination of delay and duration)
// first, since it defaults to zero, which means we can ignore the
// transition.
if (t.GetCombinedDuration() > 0.0f) {
if (aDisp.GetTransitionCombinedDuration(i) > 0.0f) {
// We might have something to transition. See if any of the
// properties in question changed and are animatable.
// FIXME: Would be good to find a way to share code between this
// interpretation of transition-property and the one below.
nsCSSPropertyID property = t.GetProperty();
nsCSSPropertyID property = aDisp.GetTransitionProperty(i);
if (property == eCSSPropertyExtra_no_properties ||
property == eCSSPropertyExtra_variable ||
property == eCSSProperty_UNKNOWN) {
@ -694,7 +692,7 @@ nsTransitionManager::DoUpdateTransitions(
for (nsCSSPropertyID p = nsCSSPropertyID(0);
p < eCSSProperty_COUNT_no_shorthands;
p = nsCSSPropertyID(p + 1)) {
ConsiderInitiatingTransition(p, t, aElement, aPseudoType,
ConsiderInitiatingTransition(p, aDisp, i, aElement, aPseudoType,
aElementTransitions,
aOldStyle, aNewStyle,
&startedAny, &whichStarted);
@ -703,13 +701,13 @@ nsTransitionManager::DoUpdateTransitions(
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property,
CSSEnabledState::eForAllContent)
{
ConsiderInitiatingTransition(*subprop, t, aElement, aPseudoType,
ConsiderInitiatingTransition(*subprop, aDisp, i, aElement, aPseudoType,
aElementTransitions,
aOldStyle, aNewStyle,
&startedAny, &whichStarted);
}
} else {
ConsiderInitiatingTransition(property, t, aElement, aPseudoType,
ConsiderInitiatingTransition(property, aDisp, i, aElement, aPseudoType,
aElementTransitions,
aOldStyle, aNewStyle,
&startedAny, &whichStarted);
@ -728,14 +726,13 @@ nsTransitionManager::DoUpdateTransitions(
// nsTransitionManager::PruneCompletedTransitions.
if (aElementTransitions) {
bool checkProperties =
aDisp->mTransitions[0].GetProperty() != eCSSPropertyExtra_all_properties;
aDisp.GetTransitionProperty(0) != eCSSPropertyExtra_all_properties;
nsCSSPropertyIDSet allTransitionProperties;
if (checkProperties) {
for (uint32_t i = aDisp->mTransitionPropertyCount; i-- != 0; ) {
const StyleTransition& t = aDisp->mTransitions[i];
for (uint32_t i = aDisp.mTransitionPropertyCount; i-- != 0; ) {
// FIXME: Would be good to find a way to share code between this
// interpretation of transition-property and the one above.
nsCSSPropertyID property = t.GetProperty();
nsCSSPropertyID property = aDisp.GetTransitionProperty(i);
if (property == eCSSPropertyExtra_no_properties ||
property == eCSSPropertyExtra_variable ||
property == eCSSProperty_UNKNOWN) {
@ -859,7 +856,8 @@ template<typename StyleType>
void
nsTransitionManager::ConsiderInitiatingTransition(
nsCSSPropertyID aProperty,
const StyleTransition& aTransition,
const nsStyleDisplay& aStyleDisplay,
uint32_t transitionIdx,
dom::Element* aElement,
CSSPseudoElementType aPseudoType,
CSSTransitionCollection*& aElementTransitions,
@ -972,9 +970,10 @@ nsTransitionManager::ConsiderInitiatingTransition(
return;
}
const nsTimingFunction &tf = aTransition.GetTimingFunction();
float delay = aTransition.GetDelay();
float duration = aTransition.GetDuration();
const nsTimingFunction &tf =
aStyleDisplay.GetTransitionTimingFunction(transitionIdx);
float delay = aStyleDisplay.GetTransitionDelay(transitionIdx);
float duration = aStyleDisplay.GetTransitionDuration(transitionIdx);
if (duration < 0.0) {
// The spec says a negative duration is treated as zero.
duration = 0.0;

View File

@ -430,7 +430,7 @@ protected:
// aElementTransitions is the collection of current transitions, and it
// could be a nullptr if we don't have any transitions.
template<typename StyleType> bool
DoUpdateTransitions(const nsStyleDisplay* aDisp,
DoUpdateTransitions(const nsStyleDisplay& aDisp,
mozilla::dom::Element* aElement,
mozilla::CSSPseudoElementType aPseudoType,
CSSTransitionCollection*& aElementTransitions,
@ -439,7 +439,8 @@ protected:
template<typename StyleType> void
ConsiderInitiatingTransition(nsCSSPropertyID aProperty,
const mozilla::StyleTransition& aTransition,
const nsStyleDisplay& aStyleDisplay,
uint32_t transitionIdx,
mozilla::dom::Element* aElement,
mozilla::CSSPseudoElementType aPseudoType,
CSSTransitionCollection*& aElementTransitions,

View File

@ -27,6 +27,12 @@ android {
vectorDrawables.useSupportLibrary = true
}
aaptOptions {
// The omnijar is already a compressed file itself and Gecko expects it to be
// STORED within the APK rather than DEFLATED.
noCompress 'ja'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7

View File

@ -174,9 +174,6 @@
@BINPATH@/components/jsdownloads.xpt
@BINPATH@/components/jsinspector.xpt
@BINPATH@/components/layout_base.xpt
#ifdef MOZ_DEBUG
@BINPATH@/components/layout_debug.xpt
#endif
#ifdef NS_PRINTING
@BINPATH@/components/layout_printing.xpt
#endif

View File

@ -181,16 +181,6 @@
"google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia"
]
},
"US": {
"visibleDefaultEngines": [
"yahoo", "google-nocodes", "bing", "amazondotcom", "ddg", "twitter", "wikipedia"
]
},
"CA": {
"visibleDefaultEngines": [
"google-nocodes", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia"
]
},
"experimental-hidden": {
"visibleDefaultEngines": [
"amazon-ca", "amazon-au", "google-2018", "duckduckgo"

View File

@ -1160,4 +1160,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1523486113350000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1523571010092000);

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1525905299167000);
const PRTime gPreloadListExpirationTime = INT64_C(1525990195432000);
%%
0-1.party, 1
0.me.uk, 1
@ -142,6 +142,7 @@ const PRTime gPreloadListExpirationTime = INT64_C(1525905299167000);
1600esplanade.com, 1
16164f.com, 1
1644091933.rsc.cdn77.org, 1
166166.com, 1
174.net.nz, 1
1750studios.com, 0
17hats.com, 1
@ -1212,7 +1213,6 @@ albion2.org, 1
alboweb.nl, 1
albuic.tk, 1
alca31.com, 1
alcantarafleuriste.com, 1
alcatelonetouch.us, 1
alcatraz.online, 1
alchemia.co.il, 1
@ -1225,6 +1225,7 @@ aldorr.net, 1
aldous-huxley.com, 1
aleax.me, 1
alecpap.com, 1
alecpapierniak.com, 1
alecrust.com, 1
aleksejjocic.tk, 1
aleksib.fi, 1
@ -1698,7 +1699,6 @@ angelinahair.com, 1
angeloventuri.com, 1
anginf.de, 1
anglertanke.de, 1
anglesya.win, 1
anglictina-sojcak.cz, 1
anglictinasojcak.cz, 1
anglingactive.co.uk, 1
@ -2583,6 +2583,7 @@ avid.blue, 1
avidcruiser.com, 1
aviv.nyc, 1
avmemo.com, 1
avmo.pw, 1
avmoo.com, 1
avnet.ws, 1
avocode.com, 1
@ -2590,6 +2591,7 @@ avonlearningcampus.com, 1
avotoma.com, 1
avova.de, 1
avpres.net, 1
avso.pw, 1
avsox.com, 1
avspot.net, 1
avticket.ru, 0
@ -2598,6 +2600,7 @@ avtogara-isperih.com, 1
avtosept.by, 1
avtovokzaly.ru, 1
avvcorda.com, 1
avxo.pw, 1
awan.tech, 1
awaremi-tai.com, 1
awaro.net, 0
@ -2838,6 +2841,7 @@ baptiste-destombes.fr, 1
baptiste-peugnez.fr, 1
bar-harcourt.com, 1
barans2239.com, 1
barbarafeldman.com, 1
barbarians.com, 1
barbaros.info, 1
barbate.fr, 1
@ -3296,7 +3300,6 @@ better.fyi, 1
betterbabyshop.com.au, 1
bettercrypto.org, 1
betterhelp.com, 1
betterlifemakers.com, 1
betterna.me, 1
betterscience.org, 1
bettertest.it, 1
@ -4273,6 +4276,7 @@ brava.bg, 1
brave-foods.ch, 1
brave-foods.com, 1
brave.com, 1
bravehearts.org.au, 1
braviskindenjeugd.nl, 1
bravisziekenhuis.nl, 1
brazilian.dating, 1
@ -4450,6 +4454,7 @@ btcgo.nl, 1
btcontract.com, 1
btcpop.co, 1
btcycle.org, 1
btio.pw, 1
btku.org, 1
btnissanparts.com, 1
btorrent.xyz, 1
@ -4613,6 +4618,7 @@ buyharpoon.com, 1
buyinginvestmentproperty.com, 1
buyingsellingflorida.com, 1
buymindhack.com, 1
buynowdepot.com, 0
buypapercheap.net, 1
buyseo.store, 1
buyshoe.org, 1
@ -5672,6 +5678,7 @@ cine-music.de, 1
cine.to, 1
cinefilia.tk, 1
cinefilzonen.se, 1
cinema5.ru, 0
cinemaclub.co, 1
cinemysticism.com, 1
ciner.is, 1
@ -5992,7 +5999,6 @@ cobaltlp.com, 1
cobracastles.co.uk, 1
cocaine-import.agency, 1
cocaine.ninja, 1
cocalc.com, 1
coccinellaskitchen.com, 1
coccinellaskitchen.de, 1
coccinellaskitchen.it, 1
@ -6264,7 +6270,6 @@ computersystems.guru, 0
comssa.org.au, 1
comunidadmontepinar.es, 1
comw.cc, 1
comyuno.com, 1
conalcorp.com, 1
conaudisa.com, 0
concept-web.ch, 1
@ -6602,7 +6607,6 @@ create-together.nl, 1
createursdefilms.com, 1
creation-contemporaine.com, 1
creations-edita.com, 1
creative-coder.de, 1
creative-wave.fr, 1
creativebites.de, 1
creativecaptiv.es, 1
@ -6759,7 +6763,7 @@ csfm.com, 1
csgo.help, 1
csgo.su, 1
csgo77.com, 1
csgogamers.com, 1
csgogamers.com, 0
csgohandouts.com, 1
csgotwister.com, 1
csharpmarc.net, 1
@ -7387,7 +7391,6 @@ dealbanana.ch, 1
dealbanana.co.uk, 1
dealbanana.com, 1
dealbanana.de, 1
dealbanana.fi, 1
dealbanana.fr, 1
dealbanana.it, 1
dealbanana.se, 1
@ -7823,7 +7826,6 @@ dicionarioetimologico.com.br, 1
dick.red, 1
dickieslife.com, 1
dickpics.ru, 1
dicoding.com, 1
didacte.com, 1
didche.net, 1
diddens.de, 1
@ -8625,6 +8627,7 @@ dustygroove.com, 1
dustyspokesbnb.ca, 1
dutch.desi, 1
dutch1.nl, 1
dutchessuganda.com, 1
dutchrank.nl, 1
dutchwanderers.nl, 1
dutchweballiance.nl, 1
@ -8777,6 +8780,7 @@ eatsleeprepeat.net, 1
eatson.com, 1
eattherich.us, 1
eatz.com, 1
eaucube.com, 1
eauxdespleiades.ch, 1
eb-net.de, 1
eb7.jp, 1
@ -8885,6 +8889,7 @@ edited.de, 1
edition-bambou.com, 1
edition-sonblom.de, 1
editoraacademiacrista.com.br, 1
edlinus.cn, 1
edmundcelis.com, 1
edoss.co.za, 1
edp-collaborative.com, 1
@ -8994,7 +8999,6 @@ eickhof.co, 1
eickhof.us, 1
eickhofcolumbaria.com, 1
eidolons.org, 1
eifelindex.de, 1
eiga-movie.com, 1
eigenbubi.de, 1
eighty-aid.com, 1
@ -9433,7 +9437,7 @@ epiteugma.com, 1
epizentrum.work, 1
epizentrum.works, 1
epmcentroitalia.it, 1
epoch.com, 0
epoch.com, 1
epolitiker.com, 1
epos-distributor.co.uk, 1
eposbirmingham.co.uk, 1
@ -11888,7 +11892,6 @@ glass.google.com, 1
glasschmuck-millefiori.de, 1
glavsudexpertiza.ru, 1
glazedmag.fr, 1
glbg.eu, 1
glcastlekings.co.uk, 1
gleanview.com, 1
glencarbide.com, 1
@ -12087,7 +12090,6 @@ goto.world, 1
gotomi.info, 1
gotoxy.at, 1
gottfridsberg.org, 1
gottfriedfeyen.com, 1
goubi.me, 1
goudenharynck.be, 1
gouforit.com, 1
@ -12631,7 +12633,6 @@ haozhang.org, 1
hapijs.cn, 1
hapissl.com, 1
hapivm.com, 1
happist.com, 0
happyagain.de, 1
happyagain.se, 1
happyandrelaxeddogs.eu, 0
@ -13122,6 +13123,7 @@ hilti.kz, 0
hilti.lv, 0
hiltonarubabeachservices.com, 1
hiltonhyland.com, 1
himens.com, 1
hindmanfuneralhomes.com, 1
hingle.me, 1
hinrich.de, 1
@ -13143,7 +13145,6 @@ hiqfranchise.co.uk, 1
hiqhub.co.uk, 1
hiqonline.co.uk, 1
hirake55.com, 1
hiraku.me, 1
hiratake.xyz, 1
hire-a-coder.de, 1
hireabouncycastle.net, 1
@ -13596,7 +13597,7 @@ huongquynh.com, 1
hup.hu, 1
hupp.se, 1
hurd.is, 1
huren.nl, 0
huren.nl, 1
huroji.com, 1
hurricanelabs.com, 0
husakbau.at, 1
@ -13862,6 +13863,7 @@ ifxor.com, 1
ifyou.live, 1
iga-semi.jp, 1
igamingforums.com, 1
igd.chat, 1
igglabs.com, 1
iggprivate.com, 1
iggsoft.com, 1
@ -14149,6 +14151,7 @@ inflatablesny.com, 1
inflatamania.com, 1
inflexsys.com, 1
influencerchampions.com, 1
influo.com, 1
influxus.com, 0
infmed.com, 1
info-bay.com, 1
@ -14199,7 +14202,6 @@ inheritestate.com, 1
inhive.group, 1
inhouseents.co.uk, 1
iniiter.com, 1
inima.org, 1
inios.fr, 0
inishbofin.ie, 1
initq.net, 1
@ -14215,7 +14217,6 @@ inkhor.se, 1
inkontriamoci.com, 1
inksay.com, 1
inkthemes.com, 1
inkvisual.tk, 1
inline-sport.cz, 1
inlink.ee, 1
inmaps.xyz, 1
@ -14884,6 +14885,7 @@ jamesknd.uk, 0
jamesmarsh.net, 1
jamesmcdonald.com, 0
jamesmilazzo.com, 1
jamesmorrison.me, 1
jamesrains.com, 1
jamesrussellward.co.uk, 1
jamessmith.me.uk, 1
@ -15259,6 +15261,7 @@ joespaintingpgh.com, 1
joestead.codes, 1
joetyson.io, 1
joetyson.me, 1
joeysmith.com, 1
jogi-server.de, 1
jogorama.com.br, 0
johanbissemattsson.se, 0
@ -16101,7 +16104,7 @@ kirchen-im-web.de, 1
kirchengemeinde-markt-erlbach.de, 1
kircp.com, 1
kirei.se, 1
kirig.ph, 1
kirig.ph, 0
kirill.ws, 1
kirillpokrovsky.de, 1
kirinas.com, 1
@ -16170,7 +16173,6 @@ klarika.com, 1
klarmobil-empfehlen.de, 1
klasfauseweh.de, 1
klatschreime.de, 1
klausbrinch.dk, 1
klausimas.lt, 1
klaver.it, 1
klaw.xyz, 1
@ -16450,6 +16452,7 @@ kristikala.nl, 1
kristinbailey.com, 1
kristofdv.be, 1
krizek.cc, 1
krizevci.info, 1
krk-media.pl, 0
krmeni.cz, 1
krokedil.se, 1
@ -16515,7 +16518,6 @@ kuehnel.org, 1
kuemmerlin.eu, 1
kuemmling.eu, 1
kuhn-elektrotechnik.de, 1
kujadin.de, 1
kukal.cz, 1
kuketz-blog.de, 1
kuketz-security.de, 1
@ -16659,7 +16661,6 @@ lacledeslan.com, 0
lacledor.ch, 1
laclefdor.ch, 1
lacliniquefinanciere.com, 1
lacuevadechauvet.com, 1
lacyc3.eu, 1
ladbroke.net, 1
lady-2.jp, 1
@ -17217,6 +17218,7 @@ lianye4.cc, 1
lianye5.cc, 1
lianye6.cc, 1
liaozheqi.cn, 1
liaronce.win, 1
liautard.fr, 1
lib64.net, 1
libbitcoin.org, 1
@ -17413,6 +17415,7 @@ lionlyrics.com, 1
lionsdeal.com, 1
lipartydepot.com, 1
lipex.com, 1
lipo.lol, 1
lipoabaltimore.org, 1
liqd.net, 1
liquid.cz, 1
@ -17711,6 +17714,7 @@ loritaboegl.de, 1
losebellyfat.pro, 1
losless.fr, 1
loss.no, 1
lost.host, 1
lostandcash.com, 1
lostarq.com, 1
lostingames.de, 1
@ -17860,7 +17864,6 @@ lukas2511.de, 1
lukasberan.com, 1
lukasberan.cz, 1
lukasfunk.com, 1
lukasoppermann.com, 1
lukasoppermann.de, 1
lukasschauer.de, 1
lukasschick.de, 1
@ -18153,7 +18156,6 @@ makem-bounce.co.uk, 1
makemejob.com, 1
makenaiyo-fx.com, 1
makeuplove.nl, 1
makeyourank.com, 1
makeyourlaws.org, 1
makinen.ru, 1
makino.games, 1
@ -18223,6 +18225,7 @@ management-companie.ro, 1
management-ethics.com, 1
managementboek.nl, 1
managementfeedback.com, 1
manageprojects.com, 0
manager-efficacement.com, 1
manager.linode.com, 0
managewp.org, 1
@ -18720,6 +18723,7 @@ me-center.com, 1
me-dc.com, 1
me-groups.com, 1
me.net.nz, 1
meadowfen.farm, 1
meadowviewfarms.org, 1
mealgoo.com, 1
mealz.com, 0
@ -18774,7 +18778,6 @@ medicinskavranje.edu.rs, 1
medicocompetente.it, 1
medicoresponde.com.br, 1
medifab.online, 1
medifi.com, 1
medireport.fr, 1
medium.com, 1
mediumraw.org, 1
@ -19024,7 +19027,7 @@ mexicom.org, 1
mexior.nl, 1
meyeraviation.com, 1
mf-fischer.de, 1
mfgod.com, 0
mfgod.com, 1
mfiles.pl, 1
mflodin.se, 1
mfrsgb45.org, 1
@ -19237,7 +19240,6 @@ minepay.net, 1
minepic.org, 1
minepod.fr, 1
minerstat.com, 1
minesouls.fr, 1
minez-nightswatch.com, 0
minf3-games.de, 1
mingming.info, 1
@ -19751,7 +19753,7 @@ mplusm.eu, 1
mpn.poker, 1
mpnpokertour.com, 1
mpodraza.pl, 1
mpreserver.com, 0
mpreserver.com, 1
mpserver12.org, 1
mpsgarage.com.au, 1
mpsoundcraft.com, 1
@ -20333,7 +20335,7 @@ narodsovety.ru, 1
naroska.name, 1
narrativasdigitais.pt, 1
narrenverein-wolkenschieber.de, 1
narthollis.net, 1
narthollis.net, 0
nasarawanewsonline.com, 1
nasbi.pl, 1
nasbnation.com, 1
@ -21237,7 +21239,6 @@ numwave.nl, 1
nunnenmacher.net, 1
nunnun.jp, 1
nunomoura.com, 1
nup.pw, 1
nupef.org.br, 1
nuquery.com, 1
nuriacamaras.com, 1
@ -21608,7 +21609,6 @@ onlinelegalmarketing.com, 1
onlinelegalmedia.com, 1
onlinelighting.com.au, 1
onlinemarketingtraining.co.uk, 1
onlinepokerspelen.be, 1
onlinerollout.de, 1
onlinestoreninjas.com, 1
onlineth.com, 0
@ -21700,7 +21700,6 @@ openrainbow.net, 1
openrainbow.org, 1
openrealestate.co, 1
openresty.com, 1
openrtv.com, 1
opensource-cms.nl, 1
opensourcedmind.eu, 1
openspa.webhop.info, 1
@ -21796,7 +21795,6 @@ oricejoc.com, 0
orientalart.nl, 1
origami.to, 1
origamika.com, 1
originalmockups.com, 1
originalniknihy.cz, 1
orimex-mebel.ru, 1
orion-universe.com, 1
@ -22452,7 +22450,6 @@ penrithapartments.com.au, 1
pensacolawinterfest.org, 1
pensador.com, 1
pensador.info, 1
pensanisso.com, 1
pensioenfonds-ey.nl, 1
pension-veldzigt.nl, 1
pension-waldesruh.de, 1
@ -22799,7 +22796,6 @@ pinterest.info, 1
pinterest.jp, 1
pioche.ovh, 1
pipenny.net, 1
pips.rocks, 1
piranil.com, 1
pirate.trade, 1
pirateahoy.eu, 1
@ -23013,7 +23009,6 @@ pmbc.org, 1
pmbremer.de, 1
pmconference.ch, 1
pmctire.com, 1
pmemanager.fr, 1
pmessage.ch, 1
pmg-offshore-company.com, 1
pmg-purchase.com, 1
@ -23090,6 +23085,7 @@ politeiaudesa.org, 1
politic.org.ua, 1
politik-bei-uns.de, 1
polizeiwallis.ch, 1
polkam.go.id, 0
pollet-ghijs.be, 1
pollet-ghys.be, 1
polletmera.com, 1
@ -23345,7 +23341,6 @@ present-m.com, 1
presentesdegrife.com.br, 1
president.bg, 1
prespanok.sk, 1
press-presse.ca, 1
presscenter.jp, 1
presses.ch, 1
pressography.org, 1
@ -23853,7 +23848,7 @@ qoqo.us, 1
qotw.net, 1
qq-navi.com, 1
qqj.net, 1
qqvips.com, 1
qqvips.com, 0
qrcontagion.com, 1
qrforex.com, 1
qrlfinancial.com, 1
@ -24311,7 +24306,6 @@ redlink.de, 1
redneragenturen.org, 1
rednoseday.com, 1
rednsx.org, 1
redoakmedia.net, 1
redperegrine.com, 1
redprice.by, 1
redshield.co, 1
@ -25831,7 +25825,6 @@ secomo.org, 1
seconfig.sytes.net, 1
secpatrol.de, 1
secretar.is, 1
secretnation.net, 1
secretofanah.com, 1
secretpanties.com, 1
secretsanta.fr, 1
@ -25954,7 +25947,6 @@ self-evident.org, 1
self-signed.com, 1
self.nu, 1
selfassess.govt.nz, 1
selfdefenserx.com, 1
selfdestruct.net, 1
selfhosters.com, 1
selfici.com, 1
@ -26307,6 +26299,7 @@ shirt2go.shop, 1
shirtsofholland.com, 1
shiseki.top, 1
shishamania.de, 1
shishkin.us, 1
shishlik.net, 1
shitagi-shop.com, 1
shitbeast.institute, 1
@ -26915,9 +26908,9 @@ smipty.com, 1
smit.com.ua, 1
smith.is, 1
smithandcanova.co.uk, 1
smkw.com, 0
sml.lc, 1
smm.im, 1
smol.cat, 1
smoo.st, 1
smoothgesturesplus.com, 1
smoothics.at, 1
@ -28654,7 +28647,6 @@ teloo.pl, 1
telos-analytics.com, 1
telugu4u.net, 1
tem.li, 1
temasa.net, 1
temizmama.com, 1
temp.pm, 1
tempdomain.ml, 1
@ -29105,6 +29097,7 @@ thinkcash.nl, 1
thinkheaddesign.com, 1
thinkindifferent.net, 1
thinkingandcomputing.com, 1
thinkingplanet.net, 1
thinklikeanentrepreneur.com, 1
thinkmarketing.ca, 1
thinkquality.nl, 1
@ -29304,6 +29297,7 @@ tintencenter.com, 1
tintenfix.net, 1
tintenfux.de, 1
tintenland.de, 1
tintenprofi.de, 1
tinyhousefinance.com.au, 1
tinylan.com, 1
tinyspeck.com, 1
@ -29355,6 +29349,7 @@ tkn.tokyo, 1
tkts.cl, 1
tkusano.jp, 1
tkw01536.de, 1
tlach.cz, 1
tlca.org, 1
tlcnet.info, 1
tlehseasyads.com, 1
@ -29437,6 +29432,7 @@ todocracy.com, 1
todoescine.com, 1
todoist.com, 1
todon.fr, 1
todoscomciro.com, 1
todosrv.com, 1
toeglhofer.at, 1
toeightycountries.com, 1
@ -29725,6 +29721,7 @@ trackdays4fun.com, 1
trackdomains.com, 1
trackersimulator.org, 1
trackeye.dk, 1
trackmeet.io, 1
trackrecordpro.co.uk, 1
tractorpumps.com, 1
trade.gov.uk, 1
@ -30479,6 +30476,7 @@ urbanietz-immobilien.de, 1
urbanmelbourne.info, 1
urbannewsservice.com, 1
urbansparrow.in, 1
urbanstylestaging.com, 1
urbanwildlifealliance.org, 1
urbexdk.nl, 1
urcentral.com, 1
@ -31182,7 +31180,6 @@ votoot.com, 1
votre-site-internet.ch, 1
votresiteweb.ch, 1
vow.vn, 1
vowsy.club, 1
voxfilmeonline.net, 1
voxml.com, 1
voxographe.com, 0
@ -31392,6 +31389,7 @@ waterschaplimburg.nl, 1
watertrails.io, 1
waterworkscondos.com, 1
watsonwork.me, 1
wattechweb.com, 1
wave-ola.es, 1
wavesboardshop.com, 1
wavesoftime.com, 1
@ -32055,7 +32053,7 @@ wmustore.com, 1
wnmed.com.au, 1
wnu.com, 1
wo-ist-elvira.net, 1
wo2forum.nl, 0
wo2forum.nl, 1
wobble.ninja, 1
wobblywotnotz.co.uk, 1
wochennummern.de, 1
@ -33092,7 +33090,6 @@ zaratan.fr, 1
zargaripour.com, 1
zarmarket.org, 1
zarpo.com.br, 1
zary.me, 1
zaufanatrzeciastrona.pl, 1
zavec.com.ec, 1
zavetaji.lv, 1
@ -33254,7 +33251,6 @@ zockenbiszumumfallen.de, 1
zodiacohouses.com, 1
zoeller.me, 1
zohar.shop, 1
zohar.wang, 1
zoigl.club, 1
zojadravai.com, 1
zoki.art, 1

View File

@ -14,8 +14,7 @@ XPCOMUtils.defineLazyGetter(this, "Utils", () => {
return Cu.import("resource://services-sync/util.js", {}).Utils;
});
const SYNC_PREFS_BRANCH = "services.sync.";
XPCOMUtils.defineLazyPreferenceGetter(this, "syncUsername", "services.sync.username");
/**
* Sync's XPCOM service.
@ -128,8 +127,7 @@ WeaveService.prototype = {
* For that, you'll want to check Weave.Status.checkSetup().
*/
get enabled() {
let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
return prefs.prefHasUserValue("username");
return !!syncUsername;
}
};

View File

@ -21,7 +21,6 @@
"test_bookmarks_in_same_named_folder.js",
"test_client_wipe.js",
"test_special_tabs.js",
"test_addon_sanity.js",
"test_addon_restartless_xpi.js",
"test_addon_nonrestartless_xpi.js",
"test_addon_reconciling.js",

View File

@ -30,19 +30,23 @@ const id = "unsigned-xpi@tests.mozilla.org";
Phase("phase01", [
[Addons.verifyNot, [id]],
[Addons.install, [id]],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase02", [
[Addons.verify, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase03", [
[Addons.verifyNot, [id]],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase04", [
[Addons.verify, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
// Now we disable the add-on
@ -72,19 +76,23 @@ Phase("phase08", [
Phase("phase09", [
[EnsureTracking],
[Addons.setEnabled, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase10", [
[Addons.verify, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase11", [
[Addons.verify, [id], STATE_DISABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase12", [
[Addons.verify, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
// And we uninstall it
@ -93,17 +101,21 @@ Phase("phase13", [
[EnsureTracking],
[Addons.verify, [id], STATE_ENABLED],
[Addons.uninstall, [id]],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase14", [
[Addons.verifyNot, [id]],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase15", [
[Addons.verify, [id], STATE_ENABLED],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);
Phase("phase16", [
[Addons.verifyNot, [id]],
[Sync]
[Sync],
[Addons.skipValidation] // Validation disabled due to bug 1427835
]);

View File

@ -1,30 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* The list of phases mapped to their corresponding profiles. The object
* here must be in strict JSON format, as it will get parsed by the Python
* testrunner (no single quotes, extra comma's, etc).
*/
EnableEngines(["addons"]);
var phases = { "phase1": "profile1",
"phase2": "profile1" };
const id = "unsigned-xpi@tests.mozilla.org";
Phase("phase1", [
[Addons.install, [id]],
// Non-restartless add-on shouldn't be found after install.
[Addons.verifyNot, [id]],
// But it should be marked for Sync.
[Sync]
]);
Phase("phase2", [
// Add-on should be present after restart
[Addons.verify, [id], STATE_ENABLED],
[Sync] // Sync to ensure everything is initialized enough for the addon validator to run
]);

View File

@ -11,10 +11,13 @@ tasks:
workerType: '{{ taskcluster.docker.workerType }}'
extra:
github:
events: []
events:
- pull_request.opened
- pull_request.reopened
- pull_request.synchronize
payload:
maxRunTime: 3600
image: servobrowser/servo-linux-dev
image: 'servobrowser/servo-linux-dev:servo-linux-build-deps-2017-06-30'
command:
- /bin/bash
- '--login'
@ -31,4 +34,4 @@ tasks:
description: Run Linux tests.
owner: '{{ event.head.user.email }}'
source: '{{ event.head.repo.url }}'
allowPullRequests: public

View File

@ -203,7 +203,7 @@ impl FontList {
// Only used in the unlikely case where no font xml mapping files are found.
fn fallback_font_families() -> Vec<FontFamily> {
let alternatives = [
("san-serif", "Roboto-Regular.ttf"),
("sans-serif", "Roboto-Regular.ttf"),
("Droid Sans", "DroidSans.ttf"),
];

View File

@ -2948,8 +2948,8 @@ fn static_assert() {
let count = other.gecko.m${type.capitalize()}${gecko_ffi_name}Count;
self.gecko.m${type.capitalize()}${gecko_ffi_name}Count = count;
let iter = self.gecko.m${type.capitalize()}s.iter_mut().zip(
other.gecko.m${type.capitalize()}s.iter().take(count as usize).cycle()
let iter = self.gecko.m${type.capitalize()}s.iter_mut().take(count as usize).zip(
other.gecko.m${type.capitalize()}s.iter()
);
for (ours, others) in iter {
@ -2982,7 +2982,7 @@ fn static_assert() {
self.gecko.m${type.capitalize()}s.ensure_len(input_len);
self.gecko.m${type.capitalize()}${gecko_ffi_name}Count = input_len as u32;
for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().zip(v.cycle()) {
for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().take(input_len as usize).zip(v) {
gecko.m${gecko_ffi_name} = servo.seconds() * 1000.;
}
}
@ -3007,7 +3007,7 @@ fn static_assert() {
self.gecko.m${type.capitalize()}s.ensure_len(input_len);
self.gecko.m${type.capitalize()}TimingFunctionCount = input_len as u32;
for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().zip(v.cycle()) {
for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().take(input_len as usize).zip(v) {
gecko.mTimingFunction = servo.into();
}
}
@ -3064,7 +3064,7 @@ fn static_assert() {
self.gecko.mAnimation${gecko_ffi_name}Count = input_len as u32;
for (gecko, servo) in self.gecko.mAnimations.iter_mut().zip(v.cycle()) {
for (gecko, servo) in self.gecko.mAnimations.iter_mut().take(input_len as usize).zip(v) {
let result = match servo {
% for value in keyword.gecko_values():
Keyword::${to_camel_case(value)} =>
@ -3298,7 +3298,8 @@ fn static_assert() {
pub fn transition_combined_duration_at(&self, index: usize) -> f32 {
// https://drafts.csswg.org/css-transitions/#transition-combined-duration
self.gecko.mTransitions[index].mDuration.max(0.0) + self.gecko.mTransitions[index].mDelay
self.gecko.mTransitions[index % self.gecko.mTransitionDurationCount as usize].mDuration.max(0.0)
+ self.gecko.mTransitions[index % self.gecko.mTransitionDelayCount as usize].mDelay
}
pub fn set_transition_property<I>(&mut self, v: I)
@ -3332,7 +3333,7 @@ fn static_assert() {
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties;
if self.gecko.mTransitionPropertyCount == 1 &&
self.gecko.mTransitions[0].mProperty == eCSSPropertyExtra_all_properties &&
self.gecko.mTransitions[0].mDuration.max(0.0) + self.gecko.mTransitions[0].mDelay <= 0.0f32 {
self.transition_combined_duration_at(0) <= 0.0f32 {
return false;
}
@ -3389,7 +3390,15 @@ fn static_assert() {
${impl_transition_count('property', 'Property')}
pub fn animations_equals(&self, other: &Self) -> bool {
unsafe { bindings::Gecko_StyleAnimationsEquals(&self.gecko.mAnimations, &other.gecko.mAnimations) }
return self.gecko.mAnimationNameCount == other.gecko.mAnimationNameCount
&& self.gecko.mAnimationDelayCount == other.gecko.mAnimationDelayCount
&& self.gecko.mAnimationDirectionCount == other.gecko.mAnimationDirectionCount
&& self.gecko.mAnimationDurationCount == other.gecko.mAnimationDurationCount
&& self.gecko.mAnimationFillModeCount == other.gecko.mAnimationFillModeCount
&& self.gecko.mAnimationIterationCountCount == other.gecko.mAnimationIterationCountCount
&& self.gecko.mAnimationPlayStateCount == other.gecko.mAnimationPlayStateCount
&& self.gecko.mAnimationTimingFunctionCount == other.gecko.mAnimationTimingFunctionCount
&& unsafe { bindings::Gecko_StyleAnimationsEquals(&self.gecko.mAnimations, &other.gecko.mAnimations) }
}
pub fn set_animation_name<I>(&mut self, v: I)
@ -3456,7 +3465,7 @@ fn static_assert() {
self.gecko.mAnimations.ensure_len(input_len);
self.gecko.mAnimationIterationCountCount = input_len as u32;
for (gecko, servo) in self.gecko.mAnimations.iter_mut().zip(v.cycle()) {
for (gecko, servo) in self.gecko.mAnimations.iter_mut().take(input_len as usize).zip(v) {
match servo {
AnimationIterationCount::Number(n) => gecko.mIterationCount = n,
AnimationIterationCount::Infinite => gecko.mIterationCount = f32::INFINITY,

View File

@ -687,14 +687,6 @@ impl LonghandId {
fn is_early_property(&self) -> bool {
matches!(*self,
% if product == 'gecko':
// We need to know the number of animations / transition-properties
// before setting the rest of the related longhands, see #15923.
//
// FIXME(emilio): Looks to me that we could just do this in Gecko
// instead of making them early properties. Indeed, the spec
// mentions _used_ values, not computed values, so this looks wrong.
LonghandId::AnimationName |
LonghandId::TransitionProperty |
// Needed to properly compute the writing mode, to resolve logical
// properties, and similar stuff. In this block instead of along

View File

@ -553,18 +553,8 @@ impl Parse for Contain {
"layout" => Some(Contain::LAYOUT),
"style" => Some(Contain::STYLE),
"paint" => Some(Contain::PAINT),
"strict" => {
if result.is_empty() {
return Ok(Contain::STRICT | Contain::STRICT_BITS)
}
None
},
"none" => {
if result.is_empty() {
return Ok(result)
}
None
},
"strict" if result.is_empty() => return Ok(Contain::STRICT | Contain::STRICT_BITS),
"none" if result.is_empty() => return Ok(result),
_ => None
};

View File

@ -41,6 +41,7 @@ treeherder:
'tc-rs': 'Repackage signing executed by Taskcluster'
'tc-BMcs': 'Beetmover checksums, executed by Taskcluster'
'Aries': 'Aries Device Image'
'Deb7': 'Packages for Debian 7'
'Nexus 5-L': 'Nexus 5-L Device Image'
'I': 'Docker Image Builds'
'TL': 'Toolchain builds for Linux 64-bits'

View File

@ -4,6 +4,9 @@
loader: taskgraph.loader.transform:loader
kind-dependencies:
- packages
transforms:
- taskgraph.transforms.docker_image:transforms
- taskgraph.transforms.task:transforms
@ -20,6 +23,10 @@ jobs:
symbol: I(db)
valgrind-build:
symbol: I(vb)
toolchain-build:
symbol: I(toolchain)
packages:
- deb7-python
lint:
symbol: I(lnt)
android-build:

View File

@ -0,0 +1,28 @@
# 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/.
loader: taskgraph.loader.transform:loader
transforms:
- taskgraph.transforms.try_job:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
jobs:
deb7-python:
description: "Python backport for Debian wheezy"
treeherder:
kind: build
platform: packages/opt
symbol: Deb7(python)
tier: 1
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
worker:
max-run-time: 1800
run:
using: debian-package
dsc: "http://snapshot.debian.org/archive/debian/20160813T164221Z/pool/main/p/python2.7/python2.7_2.7.9-2+deb8u1.dsc"
dsc-sha256: 274c293e7156edf59cb9f0a9d8cedcd94fa801df35adf39b8a9f3d776a250ead
patch: python-wheezy.diff
pre-build-command: debian/rules control-file

View File

@ -0,0 +1,102 @@
FROM debian:wheezy-20171210
MAINTAINER Mike Hommey <mhommey@mozilla.com>
### Add worker user and setup its workspace.
RUN mkdir /builds && \
groupadd -g 500 worker && \
useradd -u 500 -g 500 -d /builds/worker -s /bin/bash -m worker && \
mkdir -p /builds/worker/workspace && \
chown -R worker:worker /builds
# Declare default working folder
WORKDIR /builds/worker
VOLUME /builds/worker/checkouts
VOLUME /builds/worker/workspace
VOLUME /builds/worker/tooltool-cache
# Set variable normally configured at login, by the shells parent process, these
# are taken from GNU su manual
ENV HOME=/builds/worker \
SHELL=/bin/bash \
USER=worker \
LOGNAME=worker \
HOSTNAME=taskcluster-worker \
DEBIAN_FRONTEND=noninteractive
# Set a default command useful for debugging
CMD ["/bin/bash", "--login"]
# Set apt sources list to a snapshot.
RUN for s in debian_wheezy debian_wheezy-updates debian_wheezy-backports debian-security_wheezy/updates; do \
echo "deb http://snapshot.debian.org/archive/${s%_*}/20171210T214726Z/ ${s#*_} main"; \
done > /etc/apt/sources.list
RUN apt-get -o Acquire::Check-Valid-Until=false update -q && \
apt-get install -yyq --no-install-recommends \
apt-transport-https \
ca-certificates
# %ARG DOCKER_IMAGE_PACKAGES
RUN for task in $DOCKER_IMAGE_PACKAGES; do \
echo "deb [trusted=yes] https://queue.taskcluster.net/v1/task/$task/runs/0/artifacts/public/build/ debian/" >> /etc/apt/sources.list; \
done
RUN dpkg --add-architecture i386
RUN apt-get -o Acquire::Check-Valid-Until=false update -q && \
apt-get install -yyq --no-install-recommends \
autoconf \
automake \
bison \
build-essential \
curl \
flex \
gawk \
gcc-multilib \
git \
gnupg \
libtool \
make \
p7zip-full \
procps \
pxz/wheezy-backports \
python-dev \
python-pip \
python-setuptools \
python-virtualenv \
subversion \
tar \
unzip \
uuid \
wget \
xz-utils \
zip \
&& \
apt-get clean
# %include python/mozbuild/mozbuild/action/tooltool.py
COPY topsrcdir/python/mozbuild/mozbuild/action/tooltool.py /setup/tooltool.py
# %include testing/mozharness/external_tools/robustcheckout.py
COPY topsrcdir/testing/mozharness/external_tools/robustcheckout.py /usr/local/mercurial/robustcheckout.py
# %include taskcluster/docker/recipes/common.sh
COPY topsrcdir/taskcluster/docker/recipes/common.sh /setup/common.sh
# %include taskcluster/docker/recipes/install-mercurial.sh
COPY topsrcdir/taskcluster/docker/recipes/install-mercurial.sh /setup/install-mercurial.sh
# %include taskcluster/docker/recipes/debian-build-system-setup.sh
COPY topsrcdir/taskcluster/docker/recipes/debian-build-system-setup.sh /setup/system-setup.sh
RUN bash /setup/system-setup.sh
# Add pip configuration, among other things.
# %include taskcluster/docker/recipes/dot-config
COPY topsrcdir/taskcluster/docker/recipes/dot-config /builds/worker/.config
# %include taskcluster/docker/recipes/run-task
COPY topsrcdir/taskcluster/docker/recipes/run-task /builds/worker/bin/run-task
RUN chown -R worker:worker /builds/worker/bin && chmod 755 /builds/worker/bin/*

View File

@ -348,3 +348,7 @@ Dummy tasks to consolidate beetmover dependencies to avoid taskcluster limits on
post-beetmover-checksums-dummy
------------------------------
Dummy tasks to consolidate beetmover-checksums dependencies to avoid taskcluster limits on number of dependencies per task.
packages
--------
Tasks used to build packages for use in docker images.

View File

@ -144,6 +144,7 @@ following ``run-using`` are available
* ``mozharness-test``
* ``run-task``
* ``spidermonkey`` or ``spidermonkey-package`` or ``spidermonkey-mozjs-crate`` or ``spidermonkey-rust-bindings``
* ``debian-package``
* ``toolchain-script``

View File

@ -41,6 +41,9 @@ docker_image_schema = Schema({
# Name of the docker image definition under taskcluster/docker, when
# different from the docker image name.
Optional('definition'): basestring,
# List of package tasks this docker image depends on.
Optional('packages'): [basestring],
})
@ -54,11 +57,34 @@ def validate(config, tasks):
@transforms.add
def fill_template(config, tasks):
available_packages = {}
for task in config.kind_dependencies_tasks:
if task.kind != 'packages':
continue
name = task.label.replace('packages-', '')
for route in task.task.get('routes', []):
if route.startswith('index.') and '.hash.' in route:
available_packages[name] = route
break
for task in tasks:
image_name = task.pop('name')
job_symbol = task.pop('symbol')
args = task.pop('args', {})
definition = task.pop('definition', image_name)
packages = task.pop('packages', [])
for p in packages:
if p not in available_packages:
raise Exception('Missing package job for {}-{}: {}'.format(
config.kind, image_name, p))
# Generating the context hash relies on arguments being set, so we
# set this now, although it's not the final value (it's a
# task-reference value, see further below). We add the package routes
# containing a hash to get the overall docker image hash, so changes
# to packages will be reflected in the docker image hash.
args['DOCKER_IMAGE_PACKAGES'] = ' '.join('<{}>'.format(p)
for p in packages)
context_path = os.path.join('taskcluster', 'docker', definition)
context_hash = generate_context_hash(
@ -131,13 +157,25 @@ def fill_template(config, tasks):
}
for k, v in args.items():
taskdesc['worker']['env'][k] = v
if k == 'DOCKER_IMAGE_PACKAGES':
taskdesc['worker']['env'][k] = {'task-reference': v}
else:
taskdesc['worker']['env'][k] = v
if packages:
deps = taskdesc.setdefault('dependencies', {})
digest_data = [context_hash]
for p in sorted(packages):
deps[p] = 'packages-{}'.format(p)
digest_data.append(available_packages[p])
kwargs = {'digest_data': digest_data}
else:
kwargs = {'digest': context_hash}
add_optimization(
config, taskdesc,
cache_type="docker-images.v1",
cache_name=image_name,
digest=context_hash,
**kwargs
)
yield taskdesc

View File

@ -0,0 +1,138 @@
# 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/.
"""
Support for running spidermonkey jobs via dedicated scripts
"""
from __future__ import absolute_import, print_function, unicode_literals
import os
from taskgraph.util.schema import Schema
from voluptuous import Optional, Required
from taskgraph.transforms.job import run_job_using
from taskgraph.transforms.job.common import add_public_artifacts
from taskgraph.util.hash import hash_paths
from taskgraph import GECKO
from taskgraph.util.cached_tasks import add_optimization
run_schema = Schema({
Required('using'): 'debian-package',
# Debian distribution
Optional('dist'): basestring,
# Date of the snapshot (from snapshot.debian.org) to use, in the format
# YYYYMMDDTHHMMSSZ. The same date is used for the base docker-image name
# (only the YYYYMMDD part).
Optional('snapshot'): basestring,
# URL of the source control (.dsc) file to build.
Required('dsc'): basestring,
# SHA256 of the source control (.dsc) file.
Required('dsc-sha256'): basestring,
# Patch to apply to the extracted source.
Optional('patch'): basestring,
# Command to run before dpkg-buildpackage.
Optional('pre-build-command'): basestring,
})
@run_job_using("docker-worker", "debian-package", schema=run_schema)
def docker_worker_debian_package(config, job, taskdesc):
run = job['run']
run.setdefault('dist', 'wheezy')
run.setdefault('snapshot', '20171210T214726Z')
worker = taskdesc['worker']
worker['artifacts'] = []
worker['docker-image'] = 'debian:{dist}-{date}'.format(
dist=run['dist'],
date=run['snapshot'][:8])
add_public_artifacts(config, job, taskdesc, path='/tmp/artifacts')
dsc_file = os.path.basename(run['dsc'])
package = dsc_file[:dsc_file.index('_')]
adjust = ''
if 'patch' in run:
# We can't depend on docker images, so we don't have robustcheckout
# or run-task to get a checkout. So for this one file we'd need
# from a checkout, download it.
adjust += ('curl -sL {head_repo}/raw-file/{head_rev}'
'/build/debian-packages/{patch} | patch -p1 && ').format(
head_repo=config.params['head_repository'],
head_rev=config.params['head_rev'],
patch=run['patch'],
)
if 'pre-build-command' in run:
adjust += run['pre-build-command'] + ' && '
# We can't depend on docker images (since docker images depend on packages),
# so we inline the whole script here.
worker['command'] = [
'sh',
'-x',
'-c',
# Fill /etc/apt/sources.list with the relevant snapshot repository.
'echo "deb http://snapshot.debian.org/archive/debian'
'/{snapshot}/ {dist} main" > /etc/apt/sources.list && '
'echo "deb http://snapshot.debian.org/archive/debian'
'/{snapshot}/ {dist}-updates main" >> /etc/apt/sources.list && '
'echo "deb http://snapshot.debian.org/archive/debian-security'
'/{snapshot}/ {dist}/updates main" >> /etc/apt/sources.list && '
# Install the base utilities required to build debian packages.
'apt-get update -o Acquire::Check-Valid-Until=false -q && '
'apt-get install -yyq fakeroot build-essential devscripts apt-utils && '
'cd /tmp && '
# Get, validate and extract the package source.
'dget -d -u {dsc} && '
'echo "{dsc_sha256} {dsc_file}" | sha256sum -c && '
'dpkg-source -x {dsc_file} {package} && '
'cd {package} && '
# Optionally apply patch and/or pre-build command.
'{adjust}'
# Install the necessary build dependencies.
'mk-build-deps -i -r debian/control -t "apt-get -yyq --no-install-recommends" && '
# Build the package
'DEB_BUILD_OPTIONS="parallel=$(nproc) nocheck" dpkg-buildpackage && '
# Copy the artifacts
'mkdir -p {artifacts}/debian && '
'dcmd cp ../{package}_*.changes {artifacts}/debian/ && '
'cd {artifacts} && '
# Make the artifacts directory usable as an APT repository.
'apt-ftparchive sources debian | gzip -c9 > debian/Sources.gz && '
'apt-ftparchive packages debian | gzip -c9 > debian/Packages.gz && '
'apt-ftparchive release -o APT::FTPArchive::Release::Codename={dist} debian > Release && '
'mv Release debian/'
.format(
package=package,
snapshot=run['snapshot'],
dist=run['dist'],
dsc=run['dsc'],
dsc_file=dsc_file,
dsc_sha256=run['dsc-sha256'],
adjust=adjust,
artifacts='/tmp/artifacts',
)
]
name = taskdesc['label'].replace('{}-'.format(config.kind), '', 1)
files = [
# This file
'taskcluster/taskgraph/transforms/job/debian_package.py',
]
if 'patch' in run:
files.append('build/debian-packages/{}'.format(run['patch']))
data = [hash_paths(GECKO, files)]
for k in ('snapshot', 'dist', 'dsc-sha256', 'pre-build-command'):
if k in run:
data.append(run[k])
add_optimization(config, taskdesc, cache_type='packages.v1',
cache_name=name, digest_data=data)

View File

@ -1,3 +1,5 @@
../tools/mozterm
../mozbase/manifestparser
../mozbase/mozcrash
../mozbase/mozdebug
@ -15,5 +17,3 @@
../mozbase/mozscreenshot
../mozbase/moztest
../mozbase/mozversion
../tools/mozterm

View File

@ -0,0 +1,19 @@
../../python/mozterm
../mozbase/manifestparser
../mozbase/mozcrash
../mozbase/mozdebug
../mozbase/mozdevice
../mozbase/mozfile
../mozbase/mozhttpd
../mozbase/mozinfo
../mozbase/mozinstall
../mozbase/mozleak
../mozbase/mozlog
../mozbase/moznetwork
../mozbase/mozprocess
../mozbase/mozprofile
../mozbase/mozrunner
../mozbase/mozscreenshot
../mozbase/moztest
../mozbase/mozversion

View File

@ -7,7 +7,13 @@ from __future__ import absolute_import
from setuptools import setup, find_packages
PACKAGE_NAME = 'mozlog'
PACKAGE_VERSION = '3.6'
PACKAGE_VERSION = '3.7'
DEPS = [
'blessings>=1.3',
'mozterm',
'six >= 1.10.0',
]
setup(name=PACKAGE_NAME,
version=PACKAGE_VERSION,
@ -19,8 +25,7 @@ setup(name=PACKAGE_NAME,
license='MPL 1.1/GPL 2.0/LGPL 2.1',
packages=find_packages(),
zip_safe=False,
install_requires=['blessings >= 1.3',
'six >= 1.10.0'],
install_requires=DEPS,
tests_require=['mozfile'],
platforms=['Any'],
classifiers=['Development Status :: 4 - Beta',

View File

@ -371,6 +371,8 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin, TooltoolMixin,
options += args
if 'talos_extra_options' in self.config:
options += self.config['talos_extra_options']
if self.config.get('code_coverage', False):
options.extend(['--code-coverage'])
return options
def populate_webroot(self):
@ -578,7 +580,7 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin, TooltoolMixin,
mozbase_requirements = os.path.join(
os.path.dirname(self.talos_path),
'config',
'mozbase_requirements.txt'
'mozbase_source_requirements.txt'
)
self.register_virtualenv_module(
requirements=[mozbase_requirements],

View File

@ -180,6 +180,12 @@ def create_parser(mach_interface=False):
debug_options.add_argument('--debugger-args', default=None, metavar='params',
help='Command-line arguments to pass to the debugger itself; split'
'as the Bourne shell would.')
add_arg('--code-coverage', action="store_true",
dest='code_coverage',
help='Remove any existing ccov gcda output files after browser'
' initialization but before starting the tests. NOTE:'
' Currently only supported in production.')
add_logging_group(parser)
return parser

View File

@ -8,6 +8,7 @@ Set up a browser environment before running a test.
from __future__ import absolute_import, print_function
import os
import shutil
import tempfile
import mozfile
@ -185,12 +186,87 @@ class FFSetup(object):
try:
mozfile.remove(self._tmp_dir)
except Exception as e:
print("Exception while removing profile directory: %s" % self._tmp_dir)
print(e)
LOG.info("Exception while removing profile directory: %s" % self._tmp_dir)
LOG.info(e)
if self.gecko_profile:
self.gecko_profile.clean()
def collect_or_clean_ccov(self, clean=False):
# NOTE: Currently only supported when running in production
if not self.browser_config.get('develop', False):
# first see if we an find any ccov files at the ccov output dirs
if clean:
LOG.info("Cleaning ccov files before starting the talos test")
else:
LOG.info("Collecting ccov files that were generated during the talos test")
gcov_prefix = os.getenv('GCOV_PREFIX', None)
js_ccov_dir = os.getenv('JS_CODE_COVERAGE_OUTPUT_DIR', None)
gcda_archive_folder_name = 'gcda-archive'
_gcda_files_found = []
for _ccov_env in [gcov_prefix, js_ccov_dir]:
if _ccov_env is not None:
# ccov output dir env vars exist; now search for gcda files to remove
_ccov_path = os.path.abspath(_ccov_env)
if os.path.exists(_ccov_path):
# now walk through and look for gcda files
LOG.info("Recursive search for gcda files in: %s" % _ccov_path)
for root, dirs, files in os.walk(_ccov_path):
for next_file in files:
if next_file.endswith(".gcda"):
# don't want to move or delete files in our 'gcda-archive'
if root.find(gcda_archive_folder_name) == -1:
_gcda_files_found.append(os.path.join(root, next_file))
else:
LOG.info("The ccov env var path doesn't exist: %s" % str(_ccov_path))
# now clean or collect gcda files accordingly
if clean:
# remove ccov data
LOG.info("Found %d gcda files to clean. Deleting..." % (len(_gcda_files_found)))
for _gcda in _gcda_files_found:
try:
mozfile.remove(_gcda)
except Exception as e:
LOG.info("Exception while removing file: %s" % _gcda)
LOG.info(e)
LOG.info("Finished cleaning ccov gcda files")
else:
# copy gcda files to archive folder to be collected later
gcda_archive_top = os.path.join(gcov_prefix,
gcda_archive_folder_name,
self.test_config['name'])
LOG.info("Found %d gcda files to collect. Moving to gcda archive %s"
% (len(_gcda_files_found), str(gcda_archive_top)))
if not os.path.exists(gcda_archive_top):
try:
os.makedirs(gcda_archive_top)
except OSError:
LOG.critical("Unable to make gcda archive folder %s" % gcda_archive_top)
for _gcda in _gcda_files_found:
# want to copy the existing directory strucutre but put it under archive-dir
# need to remove preceeding '/' from _gcda file name so can join the path
gcda_archive_file = os.path.join(gcov_prefix,
gcda_archive_folder_name,
self.test_config['name'],
_gcda.strip(gcov_prefix + "//"))
gcda_archive_dest = os.path.dirname(gcda_archive_file)
# create archive folder, mirroring structure
if not os.path.exists(gcda_archive_dest):
try:
os.makedirs(gcda_archive_dest)
except OSError:
LOG.critical("Unable to make archive folder %s" % gcda_archive_dest)
# now copy the file there
try:
shutil.copy(_gcda, gcda_archive_dest)
except Exception as e:
LOG.info("Error copying %s to %s" % (str(_gcda), str(gcda_archive_dest)))
LOG.info(e)
LOG.info("Finished collecting ccov gcda files. Copied to: %s" % gcda_archive_top)
def __enter__(self):
LOG.info('Initialising browser for %s test...'
% self.test_config['name'])
@ -204,6 +280,13 @@ class FFSetup(object):
raise
self._init_gecko_profile()
LOG.info('Browser initialized.')
# remove ccov files before actual tests start
if self.browser_config.get('code_coverage', False):
# if the Firefox build was instrumented for ccov, initializing the browser
# will have caused ccov to output some gcda files; in order to have valid
# ccov data for the talos test we want to remove these files before starting
# the actual talos test(s)
self.collect_or_clean_ccov(clean=True)
return self
def __exit__(self, type, value, tb):

View File

@ -118,6 +118,18 @@ def run_tests(config, browser_config):
if browser_config['subtests']:
browser_config['preferences']['talos.subtests'] = browser_config['subtests']
# If --code-coverage files are expected, set flag in browser config so ffsetup knows
# that it needs to delete any ccov files resulting from browser initialization
# NOTE: This is only supported in production; local setup of ccov folders and
# data collection not supported yet, so if attempting to run with --code-coverage
# flag locally, that is not supported yet
if config.get('code_coverage', False):
if browser_config['develop']:
raise TalosError('Aborting: talos --code-coverage flag is only '
'supported in production')
else:
browser_config['code_coverage'] = True
# set defaults
testdate = config.get('testdate', '')

View File

@ -291,5 +291,10 @@ class TTest(object):
for key, value in c.items():
LOG.debug('COUNTER %r: %s' % (key, value))
# if running against a code-coverage instrumented build, move the
# produced gcda files to a folder where they will be collected later
if browser_config.get('code_coverage', False):
setup.collect_or_clean_ccov()
# return results
return test_results

View File

@ -1754,7 +1754,7 @@ DrawPaintedLayer(PaintedLayer* aLayer,
}
void
nsWebBrowser::WindowRaised(nsIWidget* aWidget)
nsWebBrowser::WindowActivated()
{
#if defined(DEBUG_smaug)
nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
@ -1767,7 +1767,7 @@ nsWebBrowser::WindowRaised(nsIWidget* aWidget)
}
void
nsWebBrowser::WindowLowered(nsIWidget* aWidget)
nsWebBrowser::WindowDeactivated()
{
#if defined(DEBUG_smaug)
nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();

View File

@ -118,8 +118,8 @@ protected:
NS_IMETHOD EnableGlobalHistory(bool aEnable);
// nsIWidgetListener
virtual void WindowRaised(nsIWidget* aWidget);
virtual void WindowLowered(nsIWidget* aWidget);
virtual void WindowActivated() override;
virtual void WindowDeactivated() override;
virtual bool PaintWindow(nsIWidget* aWidget,
mozilla::LayoutDeviceIntRegion aRegion) override;

View File

@ -41,5 +41,5 @@ interface mozIMozIntl : nsISupports
jsval getDisplayNames([optional] in jsval locales, [optional] in jsval options);
jsval getLocaleInfo([optional] in jsval locales);
jsval createDateTimeFormat([optional] in jsval locales, [optional] in jsval options);
readonly attribute jsval DateTimeFormat;
};

View File

@ -69,27 +69,31 @@ class MozIntl {
return this._cache.getLocaleInfo(getLocales(locales), ...args);
}
createDateTimeFormat(locales, options, ...args) {
get DateTimeFormat() {
if (!this._cache.hasOwnProperty("DateTimeFormat")) {
mozIntlHelper.addDateTimeFormatConstructor(this._cache);
}
let resolvedLocales =
this._cache.DateTimeFormat.supportedLocalesOf(getLocales(locales));
let DateTimeFormat = this._cache.DateTimeFormat;
if (options) {
if (options.dateStyle || options.timeStyle) {
options.pattern = osPrefs.getDateTimePattern(
getDateTimePatternStyle(options.dateStyle),
getDateTimePatternStyle(options.timeStyle),
resolvedLocales[0]);
} else {
// make sure that user doesn't pass a pattern explicitly
options.pattern = undefined;
class MozDateTimeFormat extends this._cache.DateTimeFormat {
constructor(locales, options, ...args) {
let resolvedLocales = DateTimeFormat.supportedLocalesOf(getLocales(locales));
if (options) {
if (options.dateStyle || options.timeStyle) {
options.pattern = osPrefs.getDateTimePattern(
getDateTimePatternStyle(options.dateStyle),
getDateTimePatternStyle(options.timeStyle),
resolvedLocales[0]);
} else {
// make sure that user doesn't pass a pattern explicitly
options.pattern = undefined;
}
}
super(resolvedLocales, options, ...args);
}
}
return new this._cache.DateTimeFormat(resolvedLocales, options, ...args);
return MozDateTimeFormat;
}
}

View File

@ -6,6 +6,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
function run_test() {
test_methods_presence();
test_methods_calling();
test_constructors();
ok(true);
}
@ -14,13 +15,34 @@ function test_methods_presence() {
equal(Services.intl.getCalendarInfo instanceof Function, true);
equal(Services.intl.getDisplayNames instanceof Function, true);
equal(Services.intl.getLocaleInfo instanceof Function, true);
equal(Services.intl.createDateTimeFormat instanceof Function, true);
equal(Services.intl.getLocaleInfo instanceof Object, true);
}
function test_methods_calling() {
Services.intl.getCalendarInfo("pl");
Services.intl.getDisplayNames("ar");
Services.intl.getLocaleInfo("de");
Services.intl.createDateTimeFormat("fr");
new Services.intl.DateTimeFormat("fr");
ok(true);
}
function test_constructors() {
let dtf = new Intl.DateTimeFormat();
let dtf2 = new Services.intl.DateTimeFormat();
equal(typeof dtf, typeof dtf2);
Assert.throws(() => {
// This is an observable difference between Intl and mozIntl.
//
// Old ECMA402 APIs (edition 1 and 2) allowed for constructors to be called
// as functions.
// Starting from ed.3 all new constructors are throwing when called without |new|.
//
// All MozIntl APIs do not implement the legacy behavior and throw
// when called without |new|.
//
// For more information see https://github.com/tc39/ecma402/pull/84 .
Services.intl.DateTimeFormat();
}, /class constructors must be invoked with |new|/);
}

View File

@ -474,7 +474,7 @@ var LoginManagerContent = {
* Keeps track of filled fields and values.
*/
fillsByRootElement: new WeakMap(),
loginFormRootElements: new Set(),
loginFormRootElements: new WeakSet(),
};
this.loginFormStateByDocument.set(document, loginFormState);
}
@ -491,7 +491,9 @@ var LoginManagerContent = {
// Returns true if this window or any subframes have insecure login forms.
let hasInsecureLoginForms = (thisWindow) => {
let doc = thisWindow.document;
let hasLoginForm = this.stateForDocument(doc).loginFormRootElements.size > 0;
let rootElsWeakSet = this.stateForDocument(doc).loginFormRootElements;
let hasLoginForm = ChromeUtils.nondeterministicGetWeakSetKeys(rootElsWeakSet)
.filter(el => el.isConnected).length > 0;
return (hasLoginForm && !thisWindow.isSecureContext) ||
Array.some(thisWindow.frames,
frame => hasInsecureLoginForms(frame));
@ -880,11 +882,17 @@ var LoginManagerContent = {
*/
_onNavigation(aDocument) {
let state = this.stateForDocument(aDocument);
let loginFormRootElements = state.loginFormRootElements;
log("_onNavigation: state:", state, "loginFormRootElements size:", loginFormRootElements.size,
let rootElsWeakSet = state.loginFormRootElements;
let weakLoginFormRootElements = ChromeUtils.nondeterministicGetWeakSetKeys(rootElsWeakSet);
log("_onNavigation: state:", state, "loginFormRootElements approx size:", weakLoginFormRootElements.length,
"document:", aDocument);
for (let formRoot of state.loginFormRootElements) {
for (let formRoot of weakLoginFormRootElements) {
if (!formRoot.isConnected) {
continue;
}
if (formRoot instanceof Ci.nsIDOMHTMLFormElement) {
// For now only perform capture upon navigation for FormLike's without
// a <form> to avoid capture from both an earlyformsubmit and
@ -1440,7 +1448,7 @@ function UserAutoCompleteResult(aSearchString, matchingLogins, {isSecure, messag
this.matchCount = matchingLogins.length + this._showInsecureFieldWarning;
this._messageManager = messageManager;
this._stringBundle = Services.strings.createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
this._dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined, { dateStyle: "medium" });
this._dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "medium" });
this._isPasswordField = isPasswordField;

View File

@ -191,7 +191,7 @@ XPCOMUtils.defineLazyGetter(LoginManagerContextMenu, "_stringBundle", function()
});
XPCOMUtils.defineLazyGetter(LoginManagerContextMenu, "dateAndTimeFormatter", function() {
return Services.intl.createDateTimeFormat(undefined, {
return new Services.intl.DateTimeFormat(undefined, {
dateStyle: "medium"
});
});

View File

@ -60,9 +60,9 @@ let signonReloadDisplay = {
};
// Formatter for localization.
let dateFormatter = Services.intl.createDateTimeFormat(undefined,
let dateFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium",
timeStyle: "short" });

View File

@ -134,7 +134,7 @@ async function reinitializeForm(index) {
}
function generateDateString(date) {
let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
return dateAndTimeFormatter.format(date);
}

View File

@ -102,7 +102,7 @@ function checkLoginItems(logins, items) {
}
let duplicates = findDuplicates(logins);
let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
for (let login of logins) {
if (login.username && !duplicates.has(login.username)) {

View File

@ -24,7 +24,7 @@ matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomple
"zzzuser4", "zzzpass4", "uname", "pword"));
let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo);
let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
const LABEL_NO_USERNAME = "No username (" + time + ")";

View File

@ -32,7 +32,7 @@ function ObservedPropertiesMixin(superClass) {
return this.getAttribute(name);
},
set(value) {
if (value === null || value === undefined) {
if (value === null || value === undefined || value === false) {
this.removeAttribute(name);
} else {
this.setAttribute(name, value);

View File

@ -116,8 +116,7 @@ this.PlacesRemoteTabsAutocompleteProvider = {
// a promise that resolves with an array of matching remote tabs.
getMatches(searchString) {
// If Sync isn't configured we bail early.
if (Weave === null ||
!Services.prefs.prefHasUserValue("services.sync.username")) {
if (!weaveXPCService.ready || !weaveXPCService.enabled) {
return Promise.resolve([]);
}

View File

@ -424,7 +424,7 @@ var PingPicker = {
for (let p of this._archivedPings) {
pingTypes.add(p.type);
const pingDate = new Date(p.timestampCreated);
const datetimeText = Services.intl.createDateTimeFormat(undefined, {
const datetimeText = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short",
timeStyle: "medium"
}).format(pingDate);
@ -1460,6 +1460,7 @@ var Search = {
homeSearch(text) {
changeUrlSearch(text);
removeSearchSectionTitles();
if (text === "") {
this.resetHome();
return;
@ -1475,7 +1476,13 @@ var Search = {
}
section.classList.add("active");
let sectionHidden = this.search(text, section);
if (noSearchResults && !sectionHidden) {
if (!sectionHidden) {
let sectionTitle = document.querySelector(`.category[value="${section.id}"] .category-name`).textContent;
let sectionDataDiv = document.querySelector(`#${section.id}.has-data.active .data`);
let titleDiv = document.createElement("h1");
titleDiv.classList.add("data", "search-section-title");
titleDiv.textContent = sectionTitle;
section.insertBefore(titleDiv, sectionDataDiv);
noSearchResults = false;
}
});
@ -1874,6 +1881,7 @@ function displayProcessesSelector(selectedSection) {
}
function refreshSearch() {
removeSearchSectionTitles();
let selectedSection = document.querySelector(".category.selected").getAttribute("value");
let search = document.getElementById("search");
if (!Search.blacklist.includes(selectedSection)) {
@ -1882,6 +1890,7 @@ function refreshSearch() {
}
function adjustSearchState() {
removeSearchSectionTitles();
let selectedSection = document.querySelector(".category.selected").getAttribute("value");
let search = document.getElementById("search");
search.value = "";
@ -1890,6 +1899,12 @@ function adjustSearchState() {
Search.search(""); // reinitialize search state.
}
function removeSearchSectionTitles() {
for (let sectionTitleDiv of Array.from(document.getElementsByClassName("search-section-title"))) {
sectionTitleDiv.remove();
}
}
function adjustSection() {
let selectedCategory = document.querySelector(".category.selected");
if (!selectedCategory.classList.contains("has-data")) {

View File

@ -73,8 +73,8 @@ function populateReportList() {
var dateFormatter;
var timeFormatter;
try {
dateFormatter = Services.intl.createDateTimeFormat(undefined, { dateStyle: "short" });
timeFormatter = Services.intl.createDateTimeFormat(undefined, { timeStyle: "short" });
dateFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "short" });
timeFormatter = new Services.intl.DateTimeFormat(undefined, { timeStyle: "short" });
} catch (e) {
// XXX Fallback to be removed once bug 1215247 is complete
// and the Intl API is available on all platforms.

View File

@ -349,7 +349,7 @@ this.DownloadUtils = {
// Figure out if the time is from today, yesterday, this week, etc.
if (aDate >= today) {
let dts = Services.intl.createDateTimeFormat(undefined, {
let dts = new Services.intl.DateTimeFormat(undefined, {
timeStyle: "short"
});
dateTimeCompact = dts.format(aDate);
@ -369,7 +369,7 @@ this.DownloadUtils = {
const dtOptions = { dateStyle: "long", timeStyle: "short" };
dateTimeFull =
Services.intl.createDateTimeFormat(undefined, dtOptions).format(aDate);
new Services.intl.DateTimeFormat(undefined, dtOptions).format(aDate);
return [dateTimeCompact, dateTimeFull];
},

View File

@ -78,12 +78,12 @@ function testAllGetReadableDates() {
const sixdaysago = new Date(2000, 11, 25, 11, 30, 15);
const sevendaysago = new Date(2000, 11, 24, 11, 30, 15);
let cDtf = Services.intl.createDateTimeFormat;
let cDtf = Services.intl.DateTimeFormat;
testGetReadableDates(today_11_30,
cDtf(undefined, {timeStyle: "short"}).format(today_11_30));
(new cDtf(undefined, {timeStyle: "short"})).format(today_11_30));
testGetReadableDates(today_12_30,
cDtf(undefined, {timeStyle: "short"}).format(today_12_30));
(new cDtf(undefined, {timeStyle: "short"})).format(today_12_30));
testGetReadableDates(yesterday_11_30, "Yesterday");
testGetReadableDates(yesterday_12_30, "Yesterday");
@ -98,7 +98,7 @@ function testAllGetReadableDates() {
let [, dateTimeFull] = DownloadUtils.getReadableDates(today_11_30);
const dtOptions = { dateStyle: "long", timeStyle: "short" };
Assert.equal(dateTimeFull, cDtf(undefined, dtOptions).format(today_11_30));
Assert.equal(dateTimeFull, (new cDtf(undefined, dtOptions)).format(today_11_30));
}
function run_test() {

View File

@ -40,9 +40,16 @@ IdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
return NS_OK;
}
// NS_IMPL_NAMED_* relies on the mName field, which is not present on
// release or beta. Instead, fall back to using "Runnable" for all
// runnables.
#ifdef RELEASE_OR_BETA
NS_IMPL_ISUPPORTS(Runnable, nsIRunnable, nsINamed)
#else
NS_IMPL_NAMED_ADDREF(Runnable, mName)
NS_IMPL_NAMED_RELEASE(Runnable, mName)
NS_IMPL_QUERY_INTERFACE(Runnable, nsIRunnable, nsINamed)
#endif
NS_IMETHODIMP
Runnable::Run()