Merge mozilla-central to mozilla-inbound.

--HG--
rename : toolkit/modules/Task.jsm => toolkit/modules/tests/modules/Task.jsm
extra : rebase_source : 52141f691cc72d4a80c7c5d4d35aad67a51b660d
This commit is contained in:
Cosmin Sabou 2019-01-04 18:38:34 +02:00
Родитель 626a5211e9 c32eaed37e
Коммит 3b1edf526b
65 изменённых файлов: 829 добавлений и 608 удалений

Просмотреть файл

@ -114,7 +114,6 @@ const startupPhases = {
modules: new Set([
"resource://gre/modules/AsyncPrefs.jsm",
"resource://gre/modules/LoginManagerContextMenu.jsm",
"resource://gre/modules/Task.jsm",
"resource://pdf.js/PdfStreamConverter.jsm",
]),
}},

Просмотреть файл

@ -2128,9 +2128,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
return;
}
// Set the direction of the popup based on the textbox (bug 649840).
let popupDirection = this.style.direction = (RTL_UI ? "rtl" : "ltr");
// Make the popup span the width of the window. First, set its width.
let documentRect =
window.windowUtils
@ -2142,7 +2139,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// aligns with the window border.
let elementRect =
window.windowUtils.getBoundsWithoutFlushing(aElement);
if (popupDirection == "rtl") {
if (RTL_UI) {
let offset = elementRect.right - documentRect.right;
this.style.marginRight = offset + "px";
} else {
@ -2157,13 +2154,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// value of the margins are different from the previous value, over-
// and underflow must be handled for each item already in the popup.
let needsHandleOverUnderflow = false;
let boundToCheck = popupDirection == "rtl" ? "right" : "left";
let boundToCheck = RTL_UI ? "right" : "left";
let inputRect = window.windowUtils.getBoundsWithoutFlushing(aInput);
let startOffset = Math.abs(inputRect[boundToCheck] - documentRect[boundToCheck]);
let alignSiteIcons = startOffset / width <= 0.3 || startOffset <= 250;
if (alignSiteIcons) {
// Calculate the end margin if we have a start margin.
let boundToCheckEnd = popupDirection == "rtl" ? "left" : "right";
let boundToCheckEnd = RTL_UI ? "left" : "right";
let endOffset = Math.abs(inputRect[boundToCheckEnd] -
documentRect[boundToCheckEnd]);
if (endOffset > startOffset * 2) {
@ -2175,7 +2172,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let identityIcon = document.getElementById("identity-icon");
let identityRect =
window.windowUtils.getBoundsWithoutFlushing(identityIcon);
let start = popupDirection == "rtl" ?
let start = RTL_UI ?
documentRect.right - identityRect.right :
identityRect.left;
if (!this.margins || start != this.margins.start ||
@ -2209,7 +2206,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
if (this._searchSuggestionsImpressionId == impressionId)
aInput.updateSearchSuggestionsNotificationImpressions(whichNotification);
}, {once: true});
this._showSearchSuggestionsNotification(whichNotification, popupDirection);
this._showSearchSuggestionsNotification(whichNotification);
} else if (this.classList.contains("showSearchSuggestionsNotification")) {
this._hideSearchSuggestionsNotification();
}
@ -2325,7 +2322,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="_showSearchSuggestionsNotification">
<parameter name="whichNotification"/>
<parameter name="popupDirection"/>
<body>
<![CDATA[
if (whichNotification == "opt-out") {

Просмотреть файл

@ -165,6 +165,10 @@ class UrlbarController {
}
switch (event.keyCode) {
case KeyEvent.DOM_VK_ESCAPE:
this.input.handleRevert();
event.preventDefault();
break;
case KeyEvent.DOM_VK_RETURN:
if (AppConstants.platform == "macosx" &&
event.metaKey) {
@ -175,7 +179,7 @@ class UrlbarController {
// TODO: We should have an input bufferrer so that we can use search results
// if appropriate.
this.input.handleCommand(event);
return;
break;
case KeyEvent.DOM_VK_TAB:
if (this.view.isOpen) {
this.view.selectNextItem({ reverse: event.shiftKey });

Просмотреть файл

@ -251,6 +251,14 @@ class UrlbarInput {
this._loadURL(url, where, openParams);
}
handleRevert() {
this.window.gBrowser.userTypedValue = null;
this.window.URLBarSetURI(null, true);
if (this.value && this.focused) {
this.select();
}
}
/**
* Called by the view when a result is picked.
*
@ -273,8 +281,7 @@ class UrlbarInput {
switch (result.type) {
case UrlbarUtils.MATCH_TYPE.TAB_SWITCH: {
// TODO: Implement handleRevert or equivalent on the input.
// this.input.handleRevert();
this.handleRevert();
let prevTab = this.window.gBrowser.selectedTab;
let loadOpts = {
adoptIntoActiveWindow: UrlbarPrefs.get("switchTabs.adoptIntoActiveWindow"),
@ -590,8 +597,7 @@ class UrlbarInput {
browser.focus();
if (openUILinkWhere != "current") {
// TODO: Implement handleRevert or equivalent on the input.
// this.input.handleRevert();
this.handleRevert();
}
try {
@ -600,8 +606,7 @@ class UrlbarInput {
// This load can throw an exception in certain cases, which means
// we'll want to replace the URL with the loaded URL:
if (ex.result != Cr.NS_ERROR_LOAD_SHOWED_ERRORPAGE) {
// TODO: Implement handleRevert or equivalent on the input.
// this.input.handleRevert();
this.handleRevert();
}
}

Просмотреть файл

@ -78,13 +78,12 @@ const AboutDebugging = {
this.mount
);
this.actions.updateNetworkLocations(getNetworkLocations());
this.onNetworkLocationsUpdated();
addNetworkLocationsObserver(this.onNetworkLocationsUpdated);
// Listen to USB runtime updates and retrieve the initial list of runtimes.
this.onUSBRuntimesUpdated();
addUSBRuntimesObserver(this.onUSBRuntimesUpdated);
getUSBRuntimes();
adbAddon.on("update", this.onAdbAddonUpdated);
this.onAdbAddonUpdated();

Просмотреть файл

@ -7,6 +7,7 @@
const Actions = require("./index");
const {
getAllRuntimes,
getCurrentRuntime,
findRuntimeById,
} = require("../modules/runtimes-state-helper");
@ -25,6 +26,7 @@ const {
DISCONNECT_RUNTIME_FAILURE,
DISCONNECT_RUNTIME_START,
DISCONNECT_RUNTIME_SUCCESS,
REMOTE_RUNTIMES_UPDATED,
RUNTIME_PREFERENCE,
RUNTIMES,
UNWATCH_RUNTIME_FAILURE,
@ -33,7 +35,6 @@ const {
UPDATE_CONNECTION_PROMPT_SETTING_FAILURE,
UPDATE_CONNECTION_PROMPT_SETTING_START,
UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS,
USB_RUNTIMES_UPDATED,
WATCH_RUNTIME_FAILURE,
WATCH_RUNTIME_START,
WATCH_RUNTIME_SUCCESS,
@ -195,12 +196,48 @@ function unwatchRuntime(id) {
};
}
function updateUSBRuntimes(runtimes) {
function updateNetworkRuntimes(locations) {
const runtimes = locations.map(location => {
const [ host, port ] = location.split(":");
return {
id: location,
extra: {
connectionParameters: { host, port: parseInt(port, 10) },
},
isUnknown: false,
name: location,
type: RUNTIMES.NETWORK,
};
});
return updateRemoteRuntimes(runtimes, RUNTIMES.NETWORK);
}
function updateUSBRuntimes(adbRuntimes) {
const runtimes = adbRuntimes.map(adbRuntime => {
// Set connectionParameters only for known runtimes.
const socketPath = adbRuntime._socketPath;
const deviceId = adbRuntime.deviceId;
const connectionParameters = adbRuntime.isUnknown() ? null : { deviceId, socketPath };
return {
id: adbRuntime.id,
extra: {
connectionParameters,
deviceName: adbRuntime.deviceName,
},
isUnknown: adbRuntime.isUnknown(),
name: adbRuntime.shortName,
type: RUNTIMES.USB,
};
});
return updateRemoteRuntimes(runtimes, RUNTIMES.USB);
}
function updateRemoteRuntimes(runtimes, type) {
return async (dispatch, getState) => {
const currentRuntime = getCurrentRuntime(getState().runtimes);
if (currentRuntime &&
currentRuntime.type === RUNTIMES.USB &&
currentRuntime.type === type &&
!runtimes.find(runtime => currentRuntime.id === runtime.id)) {
// Since current USB runtime was invalid, move to this firefox page.
// This case is considered as followings and so on:
@ -215,18 +252,33 @@ function updateUSBRuntimes(runtimes) {
await dispatch(Actions.selectPage(RUNTIMES.THIS_FIREFOX, RUNTIMES.THIS_FIREFOX));
}
// Retrieve runtimeDetails from existing runtimes.
runtimes.forEach(runtime => {
const existingRuntime = findRuntimeById(runtime.id, getState().runtimes);
runtime.runtimeDetails = existingRuntime ? existingRuntime.runtimeDetails : null;
});
// Disconnect runtimes that were no longer valid
const validIds = runtimes.map(r => r.id);
const existingRuntimes = getState().runtimes.usbRuntimes;
const invalidRuntimes = existingRuntimes.filter(r => !validIds.includes(r.id));
const existingRuntimes = getAllRuntimes(getState().runtimes);
const invalidRuntimes = existingRuntimes.filter(r => {
return r.type === type && !validIds.includes(r.id);
});
for (const invalidRuntime of invalidRuntimes) {
await dispatch(disconnectRuntime(invalidRuntime.id));
const isConnected = !!invalidRuntime.runtimeDetails;
if (isConnected) {
await dispatch(disconnectRuntime(invalidRuntime.id));
}
}
dispatch({ type: USB_RUNTIMES_UPDATED, runtimes });
dispatch({ type: REMOTE_RUNTIMES_UPDATED, runtimes, runtimeType: type });
for (const runtime of getAllRuntimes(getState().runtimes)) {
if (runtime.type !== type) {
continue;
}
for (const runtime of getState().runtimes.usbRuntimes) {
const isConnected = !!runtime.runtimeDetails;
const hasConnectedClient = remoteClientManager.hasClient(runtime.id, runtime.type);
if (!isConnected && hasConnectedClient) {
@ -259,6 +311,7 @@ module.exports = {
removeRuntimeListeners,
unwatchRuntime,
updateConnectionPromptSetting,
updateNetworkRuntimes,
updateUSBRuntimes,
watchRuntime,
};

Просмотреть файл

@ -80,7 +80,10 @@ function updateAdbAddonStatus(adbAddonStatus) {
}
function updateNetworkLocations(locations) {
return { type: NETWORK_LOCATIONS_UPDATED, locations };
return (dispatch, getState) => {
dispatch(Actions.updateNetworkRuntimes(locations));
dispatch({ type: NETWORK_LOCATIONS_UPDATED, locations });
};
}
function installAdbAddon() {

Просмотреть файл

@ -22,6 +22,7 @@ const actionTypes = {
MULTI_E10S_UPDATED: "MULTI_E10S_UPDATED",
NETWORK_LOCATIONS_UPDATED: "NETWORK_LOCATIONS_UPDATED",
PAGE_SELECTED: "PAGE_SELECTED",
REMOTE_RUNTIMES_UPDATED: "REMOTE_RUNTIMES_UPDATED",
REQUEST_EXTENSIONS_FAILURE: "REQUEST_EXTENSIONS_FAILURE",
REQUEST_EXTENSIONS_START: "REQUEST_EXTENSIONS_START",
REQUEST_EXTENSIONS_SUCCESS: "REQUEST_EXTENSIONS_SUCCESS",
@ -42,7 +43,6 @@ const actionTypes = {
UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS: "UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS",
USB_RUNTIMES_SCAN_START: "USB_RUNTIMES_SCAN_START",
USB_RUNTIMES_SCAN_SUCCESS: "USB_RUNTIMES_SCAN_SUCCESS",
USB_RUNTIMES_UPDATED: "USB_RUNTIMES_UPDATED",
WATCH_RUNTIME_FAILURE: "WATCH_RUNTIME_FAILURE",
WATCH_RUNTIME_START: "WATCH_RUNTIME_START",
WATCH_RUNTIME_SUCCESS: "WATCH_RUNTIME_SUCCESS",

Просмотреть файл

@ -29,14 +29,18 @@ function getCurrentConnectionPromptSetting(runtimesState) {
exports.getCurrentConnectionPromptSetting = getCurrentConnectionPromptSetting;
function findRuntimeById(id, runtimesState) {
const allRuntimes = [
return getAllRuntimes(runtimesState).find(r => r.id === id);
}
exports.findRuntimeById = findRuntimeById;
function getAllRuntimes(runtimesState) {
return [
...runtimesState.networkRuntimes,
...runtimesState.thisFirefoxRuntimes,
...runtimesState.usbRuntimes,
];
return allRuntimes.find(r => r.id === id);
}
exports.findRuntimeById = findRuntimeById;
exports.getAllRuntimes = getAllRuntimes;
function getCurrentRuntimeDetails(runtimesState) {
const runtime = getCurrentRuntime(runtimesState);

Просмотреть файл

@ -7,11 +7,10 @@
const {
CONNECT_RUNTIME_SUCCESS,
DISCONNECT_RUNTIME_SUCCESS,
NETWORK_LOCATIONS_UPDATED,
RUNTIMES,
UNWATCH_RUNTIME_SUCCESS,
UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS,
USB_RUNTIMES_UPDATED,
REMOTE_RUNTIMES_UPDATED,
WATCH_RUNTIME_SUCCESS,
} = require("../constants");
@ -85,23 +84,6 @@ function runtimesReducer(state = RuntimesState(), action) {
return _updateRuntimeById(id, { runtimeDetails: null }, state);
}
case NETWORK_LOCATIONS_UPDATED: {
const { locations } = action;
const networkRuntimes = locations.map(location => {
const [ host, port ] = location.split(":");
return {
id: location,
extra: {
connectionParameters: { host, port: parseInt(port, 10) },
},
isUnknown: false,
name: location,
type: RUNTIMES.NETWORK,
};
});
return Object.assign({}, state, { networkRuntimes });
}
case UNWATCH_RUNTIME_SUCCESS: {
return Object.assign({}, state, { selectedRuntimeId: null });
}
@ -115,32 +97,12 @@ function runtimesReducer(state = RuntimesState(), action) {
return _updateRuntimeById(runtimeId, { runtimeDetails }, state);
}
case USB_RUNTIMES_UPDATED: {
const { runtimes } = action;
const usbRuntimes = runtimes.map(runtime => {
// Retrieve runtimeDetails from existing runtimes.
const existingRuntime = findRuntimeById(runtime.id, state);
const runtimeDetails = existingRuntime ? existingRuntime.runtimeDetails : null;
// Set connectionParameters only for known runtimes.
const socketPath = runtime._socketPath;
const deviceId = runtime.deviceId;
const connectionParameters =
runtime.isUnknown() ? null : { deviceId, socketPath };
return {
id: runtime.id,
extra: {
connectionParameters,
deviceName: runtime.deviceName,
},
isUnknown: runtime.isUnknown(),
name: runtime.shortName,
runtimeDetails,
type: RUNTIMES.USB,
};
case REMOTE_RUNTIMES_UPDATED: {
const { runtimes, runtimeType } = action;
const key = TYPE_TO_RUNTIMES_KEY[runtimeType];
return Object.assign({}, state, {
[key]: runtimes,
});
return Object.assign({}, state, { usbRuntimes });
}
case WATCH_RUNTIME_SUCCESS: {

Просмотреть файл

@ -3,9 +3,11 @@
"use strict";
const RUNTIME_ID = "test-runtime-id";
const RUNTIME_DEVICE_NAME = "test device name";
const RUNTIME_APP_NAME = "TestApp";
const NETWORK_RUNTIME_HOST = "localhost:6080";
const NETWORK_RUNTIME_APP_NAME = "TestNetworkApp";
const USB_RUNTIME_ID = "test-runtime-id";
const USB_DEVICE_NAME = "test device name";
const USB_APP_NAME = "TestApp";
/* import-globals-from head-mocks.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "head-mocks.js", this);
@ -14,36 +16,57 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "head-mocks.js", this);
add_task(async function() {
const mocks = new Mocks();
let { document, tab } = await openAboutDebugging();
const usbClient = mocks.createUSBRuntime(RUNTIME_ID, {
name: RUNTIME_APP_NAME,
deviceName: RUNTIME_DEVICE_NAME,
info("Test with a USB runtime");
const usbClient = mocks.createUSBRuntime(USB_RUNTIME_ID, {
name: USB_APP_NAME,
deviceName: USB_DEVICE_NAME,
});
mocks.emitUSBUpdate();
await connectToRuntime(RUNTIME_DEVICE_NAME, document);
await selectRuntime(RUNTIME_DEVICE_NAME, RUNTIME_APP_NAME, document);
await testRemoteClientPersistConnection(mocks, {
client: usbClient,
id: USB_RUNTIME_ID,
runtimeName: USB_APP_NAME,
sidebarName: USB_DEVICE_NAME,
});
info("Test with a network runtime");
const networkClient = mocks.createNetworkRuntime(NETWORK_RUNTIME_HOST, {
name: NETWORK_RUNTIME_APP_NAME,
});
await testRemoteClientPersistConnection(mocks, {
client: networkClient,
id: NETWORK_RUNTIME_HOST,
runtimeName: NETWORK_RUNTIME_APP_NAME,
sidebarName: NETWORK_RUNTIME_HOST,
});
});
async function testRemoteClientPersistConnection(mocks,
{ client, id, runtimeName, sidebarName }) {
info("Open about:debugging and connect to the test runtime");
let { document, tab } = await openAboutDebugging();
await connectToRuntime(sidebarName, document);
await selectRuntime(sidebarName, runtimeName, document);
info("Reload about:debugging");
document = await reloadAboutDebugging(tab);
mocks.emitUSBUpdate();
info("Wait until the remote runtime appears as connected");
await waitUntil(() => {
const sidebarItem = findSidebarItemByText(RUNTIME_DEVICE_NAME, document);
const sidebarItem = findSidebarItemByText(sidebarName, document);
return sidebarItem && !sidebarItem.querySelector(".js-connect-button");
});
// Remove the runtime without emitting an update.
// This is what happens today when we simply close Firefox for Android.
info("Remove the runtime from the list of USB runtimes");
mocks.removeUSBRuntime(RUNTIME_ID);
info("Remove the runtime from the list of remote runtimes");
mocks.removeRuntime(id);
info("Emit 'closed' on the client and wait for the sidebar item to disappear");
usbClient._eventEmitter.emit("closed");
await waitUntil(() => !findSidebarItemByText(RUNTIME_DEVICE_NAME, document));
client._eventEmitter.emit("closed");
await waitUntil(() => !findSidebarItemByText(sidebarName, document));
info("Remove the tab");
await removeTab(tab);
});
}

Просмотреть файл

@ -151,4 +151,12 @@ class Mocks {
this._usbRuntimes = this._usbRuntimes.filter(runtime => runtime.id !== id);
delete this._clients[RUNTIMES.USB][id];
}
removeRuntime(id) {
if (this._clients[RUNTIMES.USB][id]) {
this.removeUSBRuntime(id);
} else if (this._clients[RUNTIMES.NETWORK][id]) {
this.removeNetworkRuntime(id);
}
}
}

Просмотреть файл

@ -9356,14 +9356,6 @@ exports.PSEUDO_ELEMENTS = [
* exposed for testing purposes.
*/
exports.PREFERENCES = [
[
"box-decoration-break",
"layout.css.box-decoration-break.enabled"
],
[
"color-adjust",
"layout.css.color-adjust.enabled"
],
[
"column-span",
"layout.css.column-span.enabled"
@ -9376,30 +9368,14 @@ exports.PREFERENCES = [
"font-optical-sizing",
"layout.css.font-variations.enabled"
],
[
"image-orientation",
"layout.css.image-orientation.enabled"
],
[
"initial-letter",
"layout.css.initial-letter.enabled"
],
[
"isolation",
"layout.css.isolation.enabled"
],
[
"mix-blend-mode",
"layout.css.mix-blend-mode.enabled"
],
[
"-moz-osx-font-smoothing",
"layout.css.osx-font-smoothing.enabled"
],
[
"scroll-behavior",
"layout.css.scroll-behavior.property-enabled"
],
[
"scrollbar-width",
"layout.css.scrollbar-width.enabled"
@ -9440,10 +9416,6 @@ exports.PREFERENCES = [
"scroll-snap-type-y",
"layout.css.scroll-snap.enabled"
],
[
"background-blend-mode",
"layout.css.background-blend-mode.enabled"
],
[
"font-variation-settings",
"layout.css.font-variations.enabled"

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/IdleDeadline.h"
#include "mozilla/dom/JSWindowActorService.h"
#include "mozilla/dom/ReportingHeader.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
@ -797,6 +798,14 @@ constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude;
/* static */ bool ChromeUtils::IsPopupTokenUnused(GlobalObject& aGlobal) {
return PopupBlocker::IsPopupOpeningTokenUnused();
/* static */ void ChromeUtils::RegisterWindowActor(
const GlobalObject& aGlobal, const nsAString& aName,
const WindowActorOptions& aOptions, ErrorResult& aRv) {
MOZ_ASSERT(XRE_IsParentProcess());
RefPtr<JSWindowActorService> service = JSWindowActorService::GetSingleton();
service->RegisterWindowActor(aName, aOptions, aRv);
}
} // namespace dom

Просмотреть файл

@ -27,6 +27,7 @@ struct IdleRequestOptions;
class MozQueryInterface;
class PrecompiledScript;
class Promise;
struct WindowActorOptions;
class ChromeUtils {
private:
@ -176,6 +177,11 @@ class ChromeUtils {
static PopupBlockerState GetPopupControlState(GlobalObject& aGlobal);
static bool IsPopupTokenUnused(GlobalObject& aGlobal);
static void RegisterWindowActor(const GlobalObject& aGlobal,
const nsAString& aName,
const WindowActorOptions& aOptions,
ErrorResult& aRv);
};
} // namespace dom

Просмотреть файл

@ -385,6 +385,9 @@ partial namespace ChromeUtils {
[ChromeOnly]
boolean isPopupTokenUnused();
[ChromeOnly, Throws]
void registerWindowActor(DOMString aName, WindowActorOptions aOptions);
};
/**
@ -521,6 +524,17 @@ dictionary Base64URLEncodeOptions {
required boolean pad;
};
dictionary WindowActorOptions {
/** This fields are used for configuring individual sides of the actor. */
required WindowActorSidedOptions parent;
required WindowActorSidedOptions child;
};
dictionary WindowActorSidedOptions {
/** The module path which should be loaded for the actor on this side. */
required DOMString moduleURI;
};
enum Base64URLDecodePadding {
/**
* Fails decoding if the input is unpadded. RFC 4648, section 3.2 requires

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "mozilla/dom/JSWindowActorService.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace dom {
struct WindowActorOptions;
namespace {
StaticRefPtr<JSWindowActorService> gJSWindowActorService;
}
JSWindowActorService::JSWindowActorService() {
MOZ_ASSERT(XRE_IsParentProcess());
}
JSWindowActorService::~JSWindowActorService() {
MOZ_ASSERT(XRE_IsParentProcess());
}
/* static */ already_AddRefed<JSWindowActorService>
JSWindowActorService::GetSingleton() {
if (!gJSWindowActorService) {
gJSWindowActorService = new JSWindowActorService();
ClearOnShutdown(&gJSWindowActorService);
}
RefPtr<JSWindowActorService> service = gJSWindowActorService.get();
return service.forget();
}
void JSWindowActorService::RegisterWindowActor(
const nsAString& aName, const WindowActorOptions& aOptions,
ErrorResult& aRv) {
MOZ_ASSERT(XRE_IsParentProcess());
auto entry = mDescriptors.LookupForAdd(aName);
if (entry) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
entry.OrInsert([&] { return &aOptions; });
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_JSWindowActorService_h
#define mozilla_dom_JSWindowActorService_h
#include "nsDataHashtable.h"
namespace mozilla {
namespace dom {
struct WindowActorOptions;
class JSWindowActorService final {
public:
NS_INLINE_DECL_REFCOUNTING(JSWindowActorService)
static already_AddRefed<JSWindowActorService> GetSingleton();
void RegisterWindowActor(const nsAString& aName,
const WindowActorOptions& aOptions,
ErrorResult& aRv);
private:
JSWindowActorService();
~JSWindowActorService();
nsDataHashtable<nsStringHashKey, const WindowActorOptions*> mDescriptors;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_JSWindowActorService_h

Просмотреть файл

@ -40,6 +40,7 @@ EXPORTS.mozilla.dom += [
'CPOWManagerGetter.h',
'DocShellMessageUtils.h',
'FilePickerParent.h',
'JSWindowActorService.h',
'MemoryReportRequest.h',
'nsIContentChild.h',
'nsIContentParent.h',
@ -72,6 +73,7 @@ UNIFIED_SOURCES += [
'ContentProcessManager.cpp',
'DocShellMessageUtils.cpp',
'FilePickerParent.cpp',
'JSWindowActorService.cpp',
'MemMapSnapshot.cpp',
'MemoryReportRequest.cpp',
'MMPrinter.cpp',

Просмотреть файл

@ -0,0 +1,23 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(function test_registerWindowActor() {
let windowActorOptions = {
parent: {
moduleURI: "resource:///actors/TestParent.jsm",
},
child: {
moduleURI: "resource:///actors/TestChild.jsm",
},
};
Assert.ok(ChromeUtils, "Should be able to get the ChromeUtils interface");
ChromeUtils.registerWindowActor("Test", windowActorOptions);
Assert.ok(true);
Assert.throws(() =>
ChromeUtils.registerWindowActor("Test", windowActorOptions),
/NotSupportedError/,
"Should throw if register duplicate name.");
});

Просмотреть файл

@ -1,2 +1,2 @@
[test_registerWindowActor.js]
[test_sharedMap.js]

Просмотреть файл

@ -1 +1 @@
a5b036eced81dcfc012f1335277af595f931fb11
da88c56f2448e66421fe8e2cab386a61e8b956b5

Просмотреть файл

@ -115,9 +115,9 @@ impl ClipScrollTree {
}
}
/// Calculate the relative transform from `ref_node_index`
/// to `target_node_index`. It's assumed that `ref_node_index`
/// is a parent of `target_node_index`. This method will
/// Calculate the relative transform from `from_node_index`
/// to `to_node_index`. It's assumed that `from_node_index`
/// is an ancestor or a descendant of `to_node_index`. This method will
/// panic if that invariant isn't true!
pub fn get_relative_transform(
&self,

Просмотреть файл

@ -103,12 +103,12 @@ fuzzy-if(OSX,0-1,0-324) == background-layers-1b.html background-layers-1-ref.htm
# box-decoration-break's effect on backgrounds is touchy and hard to test due to stretching
# artifacts and the difficulty of covering exact lines, so just make sure
# background-size results in a different rendering when present.
pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-slice.html
pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-clone.html background-size-clone.html
!= background-size-cover-slice.html background-size-slice.html
!= background-size-cover-clone.html background-size-clone.html
# ...and make sure each rendering with background-size is different from the
# other
pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-cover-clone.html
!= background-size-cover-slice.html background-size-cover-clone.html
random-if(OSX==1010) == background-size-monster-ch.html background-size-monster-ref.html # bug 1129300
random-if(OSX==1010) == background-size-monster-cm.html background-size-monster-ref.html # bug 1129300

Просмотреть файл

@ -601,7 +601,7 @@ fails-if(Android&&!asyncPan) != 367247-l-hidden.html 367247-l-scroll.html
fuzzy-if(skiaContent,0-32,0-33) fuzzy-if(d2d,0-5,0-2) == 368020-1.html 368020-1-ref.html
== 368020-2.html 368020-2-ref.html
== 368020-3.html 368020-3-ref.html
pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020-5-ref.html
== 368020-5.html 368020-5-ref.html
== 368155-1.xhtml 368155-1-ref.xhtml
asserts(4) == 368155-negative-margins-1.html 368155-negative-margins-1-ref.html # bug 387205 / bug 457397
# we can't test this because there's antialiasing involved, and our comparison

Просмотреть файл

@ -1,100 +1,100 @@
pref(layout.css.mix-blend-mode.enabled,true) == blend-canvas.html blend-canvas-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == blend-constant-background-color.html blend-constant-background-color-ref.html
pref(layout.css.mix-blend-mode.enabled,true) fuzzy-if(webrender,1-3,1313-7888) == blend-gradient-background-color.html blend-gradient-background-color-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == blend-image.html blend-image-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == blend-difference-stacking.html blend-difference-stacking-ref.html
== blend-canvas.html blend-canvas-ref.html
== blend-constant-background-color.html blend-constant-background-color-ref.html
fuzzy-if(webrender,1-3,1313-7888) == blend-gradient-background-color.html blend-gradient-background-color-ref.html
== blend-image.html blend-image-ref.html
== blend-difference-stacking.html blend-difference-stacking-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-10000) fuzzy-if(skiaContent,0-1,0-30000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-alpha.html background-blending-alpha-ref.html
pref(layout.css.background-blend-mode.enabled,true) fuzzy-if(webrender,1-3,1313-7888) == background-blending-gradient-color.html background-blending-gradient-color-ref.html
fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender,1-5,3938-23663) pref(layout.css.background-blend-mode.enabled,true) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-1,1288-7887) pref(layout.css.background-blend-mode.enabled,true) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-10000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-jpg.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-png.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-svg.html background-blending-image-color-ref.html
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-3,1313-7888) pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-image.html background-blending-image-color-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation.html background-blending-isolation-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-list-repeat.html background-blending-list-repeat-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-multiple-images.html background-blending-multiple-images-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-10000) fuzzy-if(skiaContent,0-1,0-30000) == background-blending-alpha.html background-blending-alpha-ref.html
fuzzy-if(webrender,1-3,1313-7888) == background-blending-gradient-color.html background-blending-gradient-color-ref.html
fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender,1-5,3938-23663) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-1,1288-7887) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-10000) == background-blending-image-color-jpg.html background-blending-image-color-ref.html
== background-blending-image-color-png.html background-blending-image-color-ref.html
== background-blending-image-color-svg.html background-blending-image-color-ref.html
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-3,1313-7888) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
== background-blending-image-image.html background-blending-image-color-ref.html
== background-blending-isolation.html background-blending-isolation-ref.html
== background-blending-list-repeat.html background-blending-list-repeat-ref.html
== background-blending-multiple-images.html background-blending-multiple-images-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-color-burn.html background-blending-color-burn-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-color-dodge.html background-blending-color-dodge-ref.svg
== background-blending-color-burn.html background-blending-color-burn-ref.svg
== background-blending-color-dodge.html background-blending-color-dodge-ref.svg
# need to investigate why these tests are fuzzy - first suspect is a possible color space conversion on some platforms; same for mix-blend-mode tests
fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) fuzzy-if(d2d,0-1,0-8000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-color.html background-blending-color-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-darken.html background-blending-darken-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-difference.html background-blending-difference-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||skiaContent,0-1,0-1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-exclusion.html background-blending-exclusion-ref.svg
fuzzy-if(cocoaWidget||d2d,0-1,0-1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-hard-light.html background-blending-hard-light-ref.svg
fuzzy-if(d2d,0-1,0-9600) fuzzy-if(azureSkia||gtkWidget,0-1,0-11200) fuzzy-if(webrender,1-1,9600-11200) pref(layout.css.background-blend-mode.enabled,true) == background-blending-hue.html background-blending-hue-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-lighten.html background-blending-lighten-ref.svg
fuzzy-if(d2d,0-1,0-8000) fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-luminosity.html background-blending-luminosity-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-multiply.html background-blending-multiply-ref.svg
pref(layout.css.background-blend-mode.enabled,true) == background-blending-normal.html background-blending-normal-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||azureSkia||gtkWidget,0-1,0-1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-overlay.html background-blending-overlay-ref.svg
fuzzy-if(d2d,0-1,0-3200) fuzzy-if(azureSkia||gtkWidget,0-2,0-12800) pref(layout.css.background-blend-mode.enabled,true) == background-blending-saturation.html background-blending-saturation-ref.svg
fuzzy-if(d2d||azureSkia||gtkWidget,0-1,0-1600) pref(layout.css.background-blend-mode.enabled,true) == background-blending-screen.html background-blending-screen-ref.svg
fuzzy-if(d2d||azureSkia||gtkWidget,0-10,0-4800) pref(layout.css.background-blend-mode.enabled,true) == background-blending-soft-light.html background-blending-soft-light-ref.svg
fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) fuzzy-if(d2d,0-1,0-8000) == background-blending-color.html background-blending-color-ref.svg
== background-blending-darken.html background-blending-darken-ref.svg
== background-blending-difference.html background-blending-difference-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||skiaContent,0-1,0-1600) == background-blending-exclusion.html background-blending-exclusion-ref.svg
fuzzy-if(cocoaWidget||d2d,0-1,0-1600) == background-blending-hard-light.html background-blending-hard-light-ref.svg
fuzzy-if(d2d,0-1,0-9600) fuzzy-if(azureSkia||gtkWidget,0-1,0-11200) fuzzy-if(webrender,1-1,9600-11200) == background-blending-hue.html background-blending-hue-ref.svg
== background-blending-lighten.html background-blending-lighten-ref.svg
fuzzy-if(d2d,0-1,0-8000) fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) == background-blending-luminosity.html background-blending-luminosity-ref.svg
== background-blending-multiply.html background-blending-multiply-ref.svg
== background-blending-normal.html background-blending-normal-ref.svg
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||azureSkia||gtkWidget,0-1,0-1600) == background-blending-overlay.html background-blending-overlay-ref.svg
fuzzy-if(d2d,0-1,0-3200) fuzzy-if(azureSkia||gtkWidget,0-2,0-12800) == background-blending-saturation.html background-blending-saturation-ref.svg
fuzzy-if(d2d||azureSkia||gtkWidget,0-1,0-1600) == background-blending-screen.html background-blending-screen-ref.svg
fuzzy-if(d2d||azureSkia||gtkWidget,0-10,0-4800) == background-blending-soft-light.html background-blending-soft-light-ref.svg
fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-40000) pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html
fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-40000) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html
#fuzzy due to inconsistencies in rounded rect cliping between parent and child; may be related to antialiasing. Between platforms, the max difference is the same, and the number of different pixels is either 36 or 37. (Win, Mac and Lin)
fuzzy(0-65,0-53) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
fuzzy(0-65,0-53) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
fuzzy-if(d3d11,0-49,0-200) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-and-filter.html mix-blend-mode-and-filter-ref.html
fuzzy-if(d3d11,0-1,0-5) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
fuzzy-if(d3d11,0-49,0-200) == mix-blend-mode-and-filter.html mix-blend-mode-and-filter-ref.html
fuzzy-if(d3d11,0-1,0-5) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
fuzzy(0-2,0-14400) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
fuzzy(0-2,0-14400) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-culling-1207041.html mix-blend-mode-culling-1207041-ref.html
pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-dest-alpha-1135271.html mix-blend-mode-dest-alpha-1135271-ref.html
== mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html
== mix-blend-mode-culling-1207041.html mix-blend-mode-culling-1207041-ref.html
== mix-blend-mode-dest-alpha-1135271.html mix-blend-mode-dest-alpha-1135271-ref.html
== clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html
fuzzy(0-1,0-6800) == clipped-opacity-containing-unclipped-mixblendmode.html clipped-opacity-containing-unclipped-mixblendmode-ref.html
# Test plan 5.3.1 Blending between the background layers and the background color for an element with background-blend-mode
# Test 9
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-svg-as-data-uri.html background-blending-image-color-ref.html
== background-blending-image-color-svg-as-data-uri.html background-blending-image-color-ref.html
# Test 10
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-gif.html background-blending-image-color-gif-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-image-color-transform3d.html background-blending-image-color-ref.html
== background-blending-image-color-gif.html background-blending-image-color-gif-ref.html
== background-blending-image-color-transform3d.html background-blending-image-color-ref.html
# Test plan 5.3.2 Background layers do not blend with content outside the background (or behind the element) - tests 2 and 3
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation-parent-child-color.html background-blending-isolation-parent-child-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-isolation-parent-child-image.html background-blending-isolation-parent-child-ref.html
== background-blending-isolation-parent-child-color.html background-blending-isolation-parent-child-ref.html
== background-blending-isolation-parent-child-image.html background-blending-isolation-parent-child-ref.html
# Test plan 5.3.6 background-blend-mode for an element with background-position
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-position-percentage.html background-blending-background-position-percentage-ref.html
== background-blending-background-position-percentage.html background-blending-background-position-percentage-ref.html
# Test plan 5.3.7 background-blend-mode for an element with background-size
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-size-contain.html background-blending-background-size-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-size-cover.html background-blending-background-size-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-size-percentage.html background-blending-background-size-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-size-pixels.html background-blending-background-size-ref.html
== background-blending-background-size-contain.html background-blending-background-size-ref.html
== background-blending-background-size-cover.html background-blending-background-size-ref.html
== background-blending-background-size-percentage.html background-blending-background-size-ref.html
== background-blending-background-size-pixels.html background-blending-background-size-ref.html
# Test plan 5.3.8 background-blend-mode for an element with background-repeat
# Tests 2 and 3 are not added because space and round are not currently supported
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-repeat-no-repeat.html background-blending-background-repeat-no-repeat-ref.html
== background-blending-background-repeat-no-repeat.html background-blending-background-repeat-no-repeat-ref.html
# Test plan 5.3.9 background-blend-mode for an element with background-clip
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-clip-content-box.html background-blending-background-clip-content-box-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-clip-padding-box.html background-blending-background-clip-padding-box-ref.html
== background-blending-background-clip-content-box.html background-blending-background-clip-content-box-ref.html
== background-blending-background-clip-padding-box.html background-blending-background-clip-padding-box-ref.html
# Test plan 5.3.10 background-blend-mode for an element with background-origin
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-origin-border-box.html background-blending-background-origin-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-origin-content-box.html background-blending-background-origin-ref.html
== background-blending-background-origin-border-box.html background-blending-background-origin-ref.html
== background-blending-background-origin-content-box.html background-blending-background-origin-ref.html
# Test plan 5.3.11 background-blend-mode for an element with background-attachement
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed.html background-blending-background-attachement-fixed-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html
== background-blending-background-attachement-fixed.html background-blending-background-attachement-fixed-ref.html
== background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html
pref(layout.css.background-blend-mode.enabled,true) fuzzy-if(webrender,0-1,0-49710) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-16408) fuzzy-if(Android,0-4,0-768) fuzzy-if(gtkWidget,0-1,0-132) fuzzy-if(skiaContent,0-1,0-800) fuzzy-if(d2d,0-1,0-33208) pref(layout.css.background-blend-mode.enabled,true) fuzzy-if(webrender,0-1,0-78472) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
fuzzy-if(webrender,0-1,0-49710) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-16408) fuzzy-if(Android,0-4,0-768) fuzzy-if(gtkWidget,0-1,0-132) fuzzy-if(skiaContent,0-1,0-800) fuzzy-if(d2d,0-1,0-33208) fuzzy-if(webrender,0-1,0-78472) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html
pref(layout.css.background-blend-mode.enabled,true) == background-blending-moz-element.html background-blending-moz-element-ref.html
== background-blending-moz-element.html background-blending-moz-element-ref.html
fuzzy(0-1,0-40000) pref(layout.css.background-blend-mode.enabled,true) == mix-blend-mode-soft-light.html mix-blend-mode-soft-light-ref.html
fuzzy(0-1,0-40000) == mix-blend-mode-soft-light.html mix-blend-mode-soft-light-ref.html
# Test plan 4.4.2 element with isolation:isolate creates an isolated group for blended children
pref(layout.css.isolation.enabled,true) == blend-isolation.html blend-isolation-ref.html
== blend-isolation.html blend-isolation-ref.html
pref(layout.css.background-blend-mode.enabled,true) == bug1281593.html bug1281593-ref.html
== bug1281593.html bug1281593-ref.html

Просмотреть файл

@ -1,5 +1,3 @@
default-preferences pref(layout.css.box-decoration-break.enabled,true)
== box-decoration-break-1.html box-decoration-break-1-ref.html
fuzzy(0-1,0-20) fuzzy-if(skiaContent,0-1,0-700) fuzzy-if(webrender,21-26,8908-12681) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
skip-if(verify) fuzzy(0-45,0-460) fuzzy-if(skiaContent,0-57,0-439) fuzzy-if(Android,0-57,0-1330) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543, bug 1392106

Просмотреть файл

@ -8,10 +8,10 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-003.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-004.html abspos-breaking-004-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-005.html abspos-breaking-005-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-006.html abspos-breaking-006-ref.html # Bug 1392106
pref(layout.css.box-decoration-break.enabled,true) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-007.html abspos-breaking-007-ref.html # Bug 1392106
pref(layout.css.box-decoration-break.enabled,true) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-008.html abspos-breaking-008-ref.html # Bug 1392106
pref(layout.css.box-decoration-break.enabled,true) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-009.html abspos-breaking-009-ref.html # Bug 1392106
pref(layout.css.box-decoration-break.enabled,true) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-010.html abspos-breaking-010-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-007.html abspos-breaking-007-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-008.html abspos-breaking-008-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-009.html abspos-breaking-009-ref.html # Bug 1392106
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == abspos-breaking-010.html abspos-breaking-010-ref.html # Bug 1392106
== abspos-breaking-011.html abspos-breaking-011-ref.html # Bug 1392106
== abspos-breaking-dynamic-001.html abspos-breaking-dynamic-001-ref.html
== abspos-breaking-dynamic-002.html abspos-breaking-dynamic-002-ref.html

Просмотреть файл

@ -12,17 +12,17 @@ random-if(Android) HTTP == opacity-mixed-scrolling-1.html opacity-mixed-scrollin
random-if(cocoaWidget) HTTP == opacity-mixed-scrolling-2.html opacity-mixed-scrolling-2.html?ref # see bug 625357
fails-if(Android) == percent-height-overflowing-image-1.html percent-height-overflowing-image-1-ref.html # bug 1494132
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-1.html scroll-behavior-1.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-2.html scroll-behavior-2.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-3.html scroll-behavior-3.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-4.html scroll-behavior-4.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-5.html scroll-behavior-5.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-6.html scroll-behavior-6.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-7.html scroll-behavior-7.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-8.html scroll-behavior-8.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-9.html scroll-behavior-9.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-10.html scroll-behavior-10.html?ref
pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-textarea.html scroll-behavior-textarea.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-1.html scroll-behavior-1.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-2.html scroll-behavior-2.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-3.html scroll-behavior-3.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-4.html scroll-behavior-4.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-5.html scroll-behavior-5.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-6.html scroll-behavior-6.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-7.html scroll-behavior-7.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-8.html scroll-behavior-8.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-9.html scroll-behavior-9.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-10.html scroll-behavior-10.html?ref
pref(layout.css.scroll-behavior.enabled,true) == scroll-behavior-textarea.html scroll-behavior-textarea.html?ref
HTTP == simple-1.html simple-1.html?ref
HTTP == subpixel-1.html#d subpixel-1-ref.html#d
fuzzy-if(Android,0-4,0-120) HTTP == text-1.html text-1.html?ref

Просмотреть файл

@ -31,28 +31,28 @@ include svg-integration/reftest.list
== baseline-middle-01.svg pass.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-color-burn.svg blend-color-burn-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-color-dodge.svg blend-color-dodge-ref.svg
# pref(layout.css.mix-blend-mode.enabled,true) == blend-color.svg blend-color-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-darken.svg blend-darken-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-difference.svg blend-difference-ref.svg
skip-if(Android) fuzzy-if(skiaContent,0-1,0-1600) pref(layout.css.mix-blend-mode.enabled,true) == blend-exclusion.svg blend-exclusion-ref.svg
# pref(layout.css.mix-blend-mode.enabled,true) == blend-hard-light.svg blend-hard-light-ref.svg
# pref(layout.css.mix-blend-mode.enabled,true) == blend-hue.svg blend-hue-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-layer-blend.svg blend-layer-blend-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-layer-filter.svg blend-layer-filter-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-layer-mask.svg blend-layer-mask-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-layer-opacity.svg blend-layer-opacity-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-lighten.svg blend-lighten-ref.svg
# pref(layout.css.mix-blend-mode.enabled,true) == blend-luminosity.svg blend-luminosity-ref.svg
#skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-multiply-alpha.svg blend-multiply-alpha-ref.svg
skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-multiply.svg blend-multiply-ref.svg
pref(layout.css.mix-blend-mode.enabled,true) == blend-normal.svg blend-normal-ref.svg
#skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-overlay.svg blend-overlay-ref.svg
#skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-saturation.svg blend-saturation-ref.svg
#skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-screen.svg blend-screen-ref.svg
#skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-soft-light.svg blend-soft-light-ref.svg
skip pref(layout.css.mix-blend-mode.enabled,true) == blend-difference-stacking.html blend-difference-stacking-ref.html # bug 1458353
skip-if(Android) == blend-color-burn.svg blend-color-burn-ref.svg
skip-if(Android) == blend-color-dodge.svg blend-color-dodge-ref.svg
# == blend-color.svg blend-color-ref.svg
skip-if(Android) == blend-darken.svg blend-darken-ref.svg
skip-if(Android) == blend-difference.svg blend-difference-ref.svg
skip-if(Android) fuzzy-if(skiaContent,0-1,0-1600) == blend-exclusion.svg blend-exclusion-ref.svg
# == blend-hard-light.svg blend-hard-light-ref.svg
# == blend-hue.svg blend-hue-ref.svg
skip-if(Android) == blend-layer-blend.svg blend-layer-blend-ref.svg
skip-if(Android) == blend-layer-filter.svg blend-layer-filter-ref.svg
skip-if(Android) == blend-layer-mask.svg blend-layer-mask-ref.svg
skip-if(Android) == blend-layer-opacity.svg blend-layer-opacity-ref.svg
skip-if(Android) == blend-lighten.svg blend-lighten-ref.svg
# == blend-luminosity.svg blend-luminosity-ref.svg
#skip-if(Android) == blend-multiply-alpha.svg blend-multiply-alpha-ref.svg
skip-if(Android) == blend-multiply.svg blend-multiply-ref.svg
== blend-normal.svg blend-normal-ref.svg
#skip-if(Android) == blend-overlay.svg blend-overlay-ref.svg
#skip-if(Android) == blend-saturation.svg blend-saturation-ref.svg
#skip-if(Android) == blend-screen.svg blend-screen-ref.svg
#skip-if(Android) == blend-soft-light.svg blend-soft-light-ref.svg
skip == blend-difference-stacking.html blend-difference-stacking-ref.html # bug 1458353
fuzzy(0-11,0-7155) == blur-inside-clipPath.svg blur-inside-clipPath-ref.svg

Просмотреть файл

@ -1638,6 +1638,14 @@ var gCSSProperties = {
other_values: [ "center", "end", "justify" ],
invalid_values: []
},
"box-decoration-break": {
domProp: "boxDecorationBreak",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "slice" ],
other_values: [ "clone" ],
invalid_values: [ "auto", "none", "1px" ],
},
"box-sizing": {
domProp: "boxSizing",
inherited: false,
@ -2738,6 +2746,18 @@ var gCSSProperties = {
other_values: [ "fixed", "local", "scroll,scroll", "fixed, scroll", "scroll, fixed, local, scroll", "fixed, fixed" ],
invalid_values: []
},
"background-blend-mode": {
domProp: "backgroundBlendMode",
inherited: false,
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_placeholder: true,
initial_values: [ "normal" ],
other_values: [ "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn",
"hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity" ],
invalid_values: ["none", "10px", "multiply multiply"],
},
"background-clip": {
/*
* When we rename this to 'background-clip', we also
@ -4443,6 +4463,14 @@ var gCSSProperties = {
"over left", "right under", "0", "100px", "50%"
]
},
"scroll-behavior": {
domProp: "scrollBehavior",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
other_values: [ "smooth" ],
invalid_values: [ "none", "1px" ],
},
"table-layout": {
domProp: "tableLayout",
inherited: false,
@ -5198,6 +5226,14 @@ var gCSSProperties = {
other_values: [ "0", "0.3", "-7.3" ],
invalid_values: []
},
"image-orientation": {
domProp: "imageOrientation",
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "from-image" ],
invalid_values: [ "0", "0deg" ],
},
"image-rendering": {
domProp: "imageRendering",
inherited: true,
@ -5206,6 +5242,14 @@ var gCSSProperties = {
other_values: [ "optimizeSpeed", "optimizeQuality", "-moz-crisp-edges" ],
invalid_values: []
},
"isolation": {
domProp: "isolation",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
other_values: ["isolate"],
invalid_values: [],
},
"lighting-color": {
domProp: "lightingColor",
inherited: false,
@ -5248,6 +5292,15 @@ var gCSSProperties = {
other_values: [ "url(#mysym)" ],
invalid_values: []
},
"mix-blend-mode": {
domProp: "mixBlendMode",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "normal" ],
other_values: ["multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn",
"hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"],
invalid_values: [],
},
"shape-image-threshold": {
domProp: "shapeImageThreshold",
inherited: false,
@ -7188,16 +7241,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.contain.enabled")) {
};
}
if (IsCSSPropertyPrefEnabled("layout.css.image-orientation.enabled")) {
gCSSProperties["image-orientation"] = {
domProp: "imageOrientation",
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "from-image" ],
invalid_values: [ "0", "0deg" ]
};
}
if (IsCSSPropertyPrefEnabled("layout.css.initial-letter.enabled")) {
gCSSProperties["initial-letter"] = {
@ -7225,44 +7268,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.osx-font-smoothing.enabled")) {
};
}
if (IsCSSPropertyPrefEnabled("layout.css.mix-blend-mode.enabled")) {
gCSSProperties["mix-blend-mode"] = {
domProp: "mixBlendMode",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "normal" ],
other_values: ["multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn",
"hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"],
invalid_values: []
};
}
if (IsCSSPropertyPrefEnabled("layout.css.isolation.enabled")) {
gCSSProperties["isolation"] = {
domProp: "isolation",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
other_values: ["isolate"],
invalid_values: []
};
}
if (IsCSSPropertyPrefEnabled("layout.css.background-blend-mode.enabled")) {
gCSSProperties["background-blend-mode"] = {
domProp: "backgroundBlendMode",
inherited: false,
type: CSS_TYPE_LONGHAND,
applies_to_first_letter: true,
applies_to_first_line: true,
applies_to_placeholder: true,
initial_values: [ "normal" ],
other_values: [ "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn",
"hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity" ],
invalid_values: ["none", "10px", "multiply multiply"]
};
}
if (IsCSSPropertyPrefEnabled("layout.css.overflow-clip-box.enabled")) {
gCSSProperties["overflow-clip-box-block"] = {
domProp: "overflowClipBoxBlock",
@ -7295,28 +7300,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.overflow-clip-box.enabled")) {
};
}
if (IsCSSPropertyPrefEnabled("layout.css.box-decoration-break.enabled")) {
gCSSProperties["box-decoration-break"] = {
domProp: "boxDecorationBreak",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "slice" ],
other_values: [ "clone" ],
invalid_values: [ "auto", "none", "1px" ]
};
}
if (IsCSSPropertyPrefEnabled("layout.css.scroll-behavior.property-enabled")) {
gCSSProperties["scroll-behavior"] = {
domProp: "scrollBehavior",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
other_values: [ "smooth" ],
invalid_values: [ "none", "1px" ]
};
}
if (IsCSSPropertyPrefEnabled("layout.css.overscroll-behavior.enabled")) {
gCSSProperties["overscroll-behavior-x"] = {
domProp: "overscrollBehaviorX",

Просмотреть файл

@ -49,8 +49,7 @@ function test_bug_841601() {
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({ "set": [["layout.css.background-blend-mode.enabled", true]] },
test_bug_841601);
test_bug_841601();
</script>
</pre>

Просмотреть файл

@ -68,9 +68,6 @@ function step() {
// ----
var gProps = {
"layout.css.image-orientation.enabled": ["image-orientation"],
"layout.css.mix-blend-mode.enabled": ["mix-blend-mode"],
"layout.css.isolation.enabled": [ "isolation"],
"layout.css.touch_action.enabled": ["touch-action"],
"svg.transform-box.enabled": ["transform-box"]
};

Просмотреть файл

@ -201,6 +201,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment {
// Rebuild the list to reflect the current locale.
getPreferenceScreen().removeAll();
addPreferencesFromResource(getResource());
syncPreference = (SyncPreference) findPreference(GeckoPreferences.PREFS_SYNC);
}
// Fix the parent title regardless.

Просмотреть файл

@ -1,7 +1,7 @@
// Bits and pieces copied from toolkit/components/search/tests/xpcshell/head_search.js
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Task.jsm");
ChromeUtils.import("resource://testing-common/Task.jsm");
/**
* Adds test engines and returns a promise resolved when they are installed.

Просмотреть файл

@ -19,7 +19,7 @@ Migrated from Robocop: https://bugzilla.mozilla.org/show_bug.cgi?id=1184186
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Task.jsm");
ChromeUtils.import("resource://testing-common/Task.jsm");
let gChromeWin;
let gBrowserApp;

Просмотреть файл

@ -24,7 +24,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1498892
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Messaging.jsm");
ChromeUtils.import("resource://gre/modules/Task.jsm");
ChromeUtils.import("resource://testing-common/Task.jsm");
// The chrome window and friends.
let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");

Просмотреть файл

@ -705,7 +705,7 @@ var _Task;
function add_task(func) {
if (!_Task) {
let ns = {};
_Task = Components.utils.import("resource://gre/modules/Task.jsm", ns).Task;
_Task = Components.utils.import("resource://testing-common/Task.jsm", ns).Task;
}
_gTests.push([true, func]);

Просмотреть файл

@ -3023,12 +3023,6 @@ pref("layout.css.individual-transform.enabled", false);
// Is support for CSS initial-letter property enabled?
pref("layout.css.initial-letter.enabled", false);
// Is support for mix-blend-mode enabled?
pref("layout.css.mix-blend-mode.enabled", true);
// Is support for isolation enabled?
pref("layout.css.isolation.enabled", true);
// Is support for scrollbar-color property enabled?
pref("layout.css.scrollbar-color.enabled", true);
@ -3075,9 +3069,6 @@ pref("layout.css.convertFromNode.enabled", true);
// Is support for CSS text-justify property enabled?
pref("layout.css.text-justify.enabled", true);
// Is support for the CSS image-orientation property enabled?
pref("layout.css.image-orientation.enabled", true);
// Is the paint-order property supported for HTML text?
// (It is always supported for SVG.)
pref("layout.css.paint-order.enabled", true);
@ -3090,9 +3081,6 @@ pref("layout.css.prefixes.animations", true);
pref("layout.css.prefixes.box-sizing", true);
pref("layout.css.prefixes.font-features", true);
// Is support for background-blend-mode enabled?
pref("layout.css.background-blend-mode.enabled", true);
// Is -moz-osx-font-smoothing enabled?
// Only supported in OSX builds
#ifdef XP_MACOSX
@ -3107,18 +3095,12 @@ pref("layout.css.overflow-clip-box.enabled", false);
// Is support for CSS contain enabled?
pref("layout.css.contain.enabled", false);
// Is support for CSS box-decoration-break enabled?
pref("layout.css.box-decoration-break.enabled", true);
// Is layout of CSS outline-style:auto enabled?
pref("layout.css.outline-style-auto.enabled", false);
// Is CSSOM-View scroll-behavior and its MSD smooth scrolling enabled?
pref("layout.css.scroll-behavior.enabled", true);
// Is the CSSOM-View scroll-behavior CSS property enabled?
pref("layout.css.scroll-behavior.property-enabled", true);
// Tuning of the smooth scroll motion used by CSSOM-View scroll-behavior.
// Spring-constant controls the strength of the simulated MSD
// (Mass-Spring-Damper)
@ -5842,9 +5824,6 @@ pref("plugins.rewrite_youtube_embeds", true);
// Disable browser frames by default
pref("dom.mozBrowserFramesEnabled", false);
// Is support for 'color-adjust' CSS property enabled?
pref("layout.css.color-adjust.enabled", true);
pref("dom.audiochannel.audioCompeting", false);
pref("dom.audiochannel.audioCompeting.allAgents", false);

Просмотреть файл

@ -108,7 +108,6 @@ ${helpers.single_keyword(
color-burn hard-light soft-light difference exclusion hue
saturation color luminosity""",
gecko_constant_prefix="NS_STYLE_BLEND",
gecko_pref="layout.css.background-blend-mode.enabled",
vector=True, products="gecko", animation_value_type="discrete",
spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",

Просмотреть файл

@ -88,7 +88,6 @@ ${helpers.single_keyword(
"box-decoration-break",
"slice clone",
gecko_enum_prefix="StyleBoxDecorationBreak",
gecko_pref="layout.css.box-decoration-break.enabled",
spec="https://drafts.csswg.org/css-break/#propdef-box-decoration-break",
products="gecko",
animation_value_type="discrete",

Просмотреть файл

@ -389,7 +389,6 @@ ${helpers.predefined_type(
${helpers.single_keyword(
"scroll-behavior",
"auto smooth",
gecko_pref="layout.css.scroll-behavior.property-enabled",
products="gecko",
spec="https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior",
animation_value_type="discrete",
@ -427,7 +426,6 @@ ${helpers.single_keyword(
"isolation",
"auto isolate",
products="gecko",
gecko_pref="layout.css.isolation.enabled",
spec="https://drafts.fxtf.org/compositing/#isolation",
flags="CREATES_STACKING_CONTEXT",
animation_value_type="discrete",

Просмотреть файл

@ -62,6 +62,5 @@ ${helpers.single_keyword(
gecko_constant_prefix="NS_STYLE_BLEND",
animation_value_type="discrete",
flags="CREATES_STACKING_CONTEXT",
gecko_pref="layout.css.mix-blend-mode.enabled",
spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode",
)}

Просмотреть файл

@ -55,7 +55,6 @@ ${helpers.single_keyword(
"color-adjust",
"economy exact", products="gecko",
gecko_enum_prefix="StyleColorAdjust",
gecko_pref="layout.css.color-adjust.enabled",
animation_value_type="discrete",
spec="https://drafts.csswg.org/css-color/#propdef-color-adjust",
)}
@ -78,6 +77,5 @@ ${helpers.single_keyword(
products="gecko",
gecko_enum_prefix="StyleImageOrientation",
animation_value_type="discrete",
gecko_pref="layout.css.image-orientation.enabled",
spec="https://drafts.csswg.org/css-images/#propdef-image-orientation",
)}

Просмотреть файл

@ -6,7 +6,7 @@
"use strict";
ChromeUtils.import("resource://gre/modules/Task.jsm", this);
ChromeUtils.import("resource://testing-common/Task.jsm", this);
ChromeUtils.import("resource://testing-common/ContentTaskUtils.jsm", this);
const AssertCls = ChromeUtils.import("resource://testing-common/Assert.jsm", null).Assert;

Просмотреть файл

@ -603,14 +603,22 @@ class Raptor(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidMixin):
if not self.run_local:
# copy results to upload dir so they are included as an artifact
self.info("copying raptor results to upload dir:")
src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor.json')
dest = os.path.join(env['MOZ_UPLOAD_DIR'], 'perfherder-data.json')
self.info(str(dest))
src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor.json')
self._artifact_perf_data(src, dest)
if self.power_test:
src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor-power.json')
self._artifact_perf_data(src, dest)
src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'screenshots.html')
if os.path.exists(src):
dest = os.path.join(env['MOZ_UPLOAD_DIR'], 'screenshots.html')
self.info(str(dest))
self._artifact_perf_data(src, dest)
class RaptorOutputParser(OutputParser):
minidump_regex = re.compile(r'''raptorError: "error executing: '(\S+) (\S+) (\S+)'"''')

Просмотреть файл

@ -68,17 +68,25 @@ def MakeCustomHandlerClass(results_handler, shutdown_browser, write_raw_gecko_pr
_raw_profile = data['data'][2]
LOG.info("received gecko profile for test %s pagecycle %s" % (_test, _pagecycle))
self.write_raw_gecko_profile(_test, _pagecycle, _raw_profile)
elif data['type'] == 'webext_results':
LOG.info("received " + data['type'] + ": " + str(data['data']))
self.results_handler.add(data['data'])
elif data['type'] == "webext_raptor-page-timeout":
LOG.info("received " + data['type'] + ": " + str(data['data']))
# pageload test has timed out; record it as a failure
self.results_handler.add_page_timeout(str(data['data'][0]),
str(data['data'][1]))
elif data['data'] == "__raptor_shutdownBrowser":
LOG.info("received " + data['type'] + ": " + str(data['data']))
# webext is telling us it's done, and time to shutdown the browser
self.shutdown_browser()
elif data['type'] == 'webext_screenshot':
LOG.info("received " + data['type'])
self.results_handler.add_image(str(data['data'][0]),
str(data['data'][1]),
str(data['data'][2]))
else:
LOG.info("received " + data['type'] + ": " + str(data['data']))
if data['type'] == 'webext_results':
self.results_handler.add(data['data'])
elif data['type'] == "webext_raptor-page-timeout":
# pageload test has timed out; record it as a failure
self.results_handler.add_page_timeout(str(data['data'][0]),
str(data['data'][1]))
elif data['data'] == "__raptor_shutdownBrowser":
# webext is telling us it's done, and time to shutdown the browser
self.shutdown_browser()
def do_OPTIONS(self):
self.send_response(200, "ok")

Просмотреть файл

@ -111,6 +111,9 @@ def write_test_settings_json(args, test_details, oskey):
if test_details.get("alert_threshold", None) is not None:
test_settings['raptor-options']['alert_threshold'] = float(test_details['alert_threshold'])
if test_details.get("screen_capture", None) is not None:
test_settings['raptor-options']['screen_capture'] = test_details.get("screen_capture")
# if gecko profiling is enabled, write profiling settings for webext
if test_details.get("gecko_profile", False):
test_settings['raptor-options']['gecko_profile'] = True

Просмотреть файл

@ -29,6 +29,7 @@ class Output(object):
self.summarized_results = {}
self.supporting_data = supporting_data
self.summarized_supporting_data = []
self.summarized_screenshots = []
def summarize(self):
suites = []
@ -555,6 +556,43 @@ class Output(object):
return subtests, vals
def summarize_screenshots(self, screenshots):
if len(screenshots) == 0:
return
self.summarized_screenshots.append("""<!DOCTYPE html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
</head>
<html> <body>
<h1>Captured screenshots!</h1>
<table style="width:100%">
<tr>
<th>Test Name</th>
<th>Pagecycle</th>
<th>Screenshot</th>
</tr>""")
for screenshot in screenshots:
self.summarized_screenshots.append("""<tr>
<th>%s</th>
<th> %s</th>
<th>
<img src="%s" alt="%s %s" width="320" height="240">
</th>
</tr>""" % (screenshot['test_name'],
screenshot['page_cycle'],
screenshot['screenshot'],
screenshot['test_name'],
screenshot['page_cycle']))
self.summarized_screenshots.append("""</table></body> </html>""")
def output(self):
"""output to file and perfherder data json """
if self.summarized_results == {}:
@ -567,13 +605,22 @@ class Output(object):
# and made into a tc artifact accessible in treeherder as perfherder-data.json)
results_path = os.path.join(os.path.dirname(os.environ['MOZ_UPLOAD_DIR']),
'raptor.json')
screenshot_path = os.path.join(os.path.dirname(os.environ['MOZ_UPLOAD_DIR']),
'screenshots.html')
else:
results_path = os.path.join(os.getcwd(), 'raptor.json')
screenshot_path = os.path.join(os.getcwd(), 'screenshots.html')
with open(results_path, 'w') as f:
for result in self.summarized_results:
f.write("%s\n" % result)
if len(self.summarized_screenshots) > 0:
with open(screenshot_path, 'w') as f:
for result in self.summarized_screenshots:
f.write("%s\n" % result)
LOG.info("screen captures can be found locally at: %s" % screenshot_path)
# when gecko_profiling, we don't want results ingested by Perfherder
extra_opts = self.summarized_results['suites'][0].get('extraOptions', [])
if 'gecko_profile' not in extra_opts:

Просмотреть файл

@ -19,6 +19,7 @@ class RaptorResultsHandler():
def __init__(self):
self.results = []
self.page_timeout_list = []
self.images = []
self.supporting_data = None
def add(self, new_result_json):
@ -27,6 +28,13 @@ class RaptorResultsHandler():
new_result = RaptorTestResult(new_result_json)
self.results.append(new_result)
def add_image(self, screenshot, test_name, page_cycle):
# add to results
LOG.info("received screenshot")
self.images.append({'screenshot': screenshot,
'test_name': test_name,
'page_cycle': page_cycle})
def add_page_timeout(self, test_name, page_url):
self.page_timeout_list.append({'test_name': test_name, 'url': page_url})
@ -63,6 +71,7 @@ class RaptorResultsHandler():
LOG.info("summarizing raptor test results")
output = Output(self.results, self.supporting_data)
output.summarize()
output.summarize_screenshots(self.images)
if self.supporting_data is not None:
output.summarize_supporting_data()
output.output_supporting_data()

Просмотреть файл

@ -58,6 +58,7 @@ var geckoInterval = 1;
var geckoEntries = 1000000;
var webRenderEnabled = false;
var debugMode = 0;
var screenCapture = false;
var results = {"name": "",
"page": "",
@ -121,6 +122,10 @@ function getTestSettings() {
}
}
if (settings.screen_capture !== undefined) {
screenCapture = settings.screen_capture;
}
if (settings.newtab_per_cycle !== undefined) {
reuseTab = settings.newtab_per_cycle;
}
@ -240,6 +245,10 @@ function waitForResult() {
if (geckoProfiling) {
await getGeckoProfile();
}
if (screenCapture) {
await getScreenCapture();
}
resolve();
} else {
setTimeout(checkForResult, 5);
@ -252,6 +261,9 @@ function waitForResult() {
await getGeckoProfile();
}
resolve();
if (screenCapture) {
await getScreenCapture();
}
} else {
setTimeout(checkForResult, 5);
}
@ -261,6 +273,36 @@ function waitForResult() {
});
}
async function getScreenCapture() {
console.log("Capturing screenshot...");
var capturing;
if (["firefox", "geckoview"].includes(browserName)) {
capturing = ext.tabs.captureVisibleTab();
capturing.then(onCaptured, onError);
await capturing;
} else {
// create capturing promise
capturing = new Promise(function(resolve, reject) {
ext.tabs.captureVisibleTab(resolve);
});
// capture and wait for promise to end
capturing.then(onCaptured, onError);
await capturing;
}
}
function onCaptured(screenshotUri) {
console.log("Screenshot capured!");
postToControlServer("screenshot", [screenshotUri, testName, pageCycle]);
}
function onError(error) {
console.log("Screenshot captured failed!");
console.log(`Error: ${error}`);
}
async function startGeckoProfiling() {
var _threads;
if (webRenderEnabled) {
@ -476,6 +518,7 @@ function postToControlServer(msgType, msgData) {
client.setRequestHeader("Content-Type", "application/json");
if (client.readyState == 1) {
console.log("posting to control server");
console.log(msgData);
var data = { "type": "webext_" + msgType, "data": msgData};
client.send(JSON.stringify(data));
}

Просмотреть файл

@ -40,7 +40,7 @@ var _Services = ChromeUtils.import("resource://gre/modules/Services.jsm", null).
_register_modules_protocol_handler();
var _PromiseTestUtils = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", null).PromiseTestUtils;
var _Task = ChromeUtils.import("resource://gre/modules/Task.jsm", null).Task;
var _Task = ChromeUtils.import("resource://testing-common/Task.jsm", null).Task;
let _NetUtil = ChromeUtils.import("resource://gre/modules/NetUtil.jsm", null).NetUtil;

Просмотреть файл

@ -43,8 +43,6 @@ ChromeUtils.import("resource://gre/modules/Services.jsm", this);
ChromeUtils.defineModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gDebug",
"@mozilla.org/xpcom/debug;1", "nsIDebug2");
Object.defineProperty(this, "gCrashReporter", {
@ -313,17 +311,11 @@ function getOrigin(topFrame, filename = null, lineNumber = null, stack = null) {
if (stack == null) {
// Now build the rest of the stack as a string, using Task.jsm's rewriting
// to ensure that we do not lose information at each call to `Task.spawn`.
let frames = [];
stack = [];
while (frame != null) {
frames.push(frame.filename + ":" + frame.name + ":" + frame.lineNumber);
stack.push(frame.filename + ":" + frame.name + ":" + frame.lineNumber);
frame = frame.caller;
}
stack = frames.join("\n");
// Avoid loading Task.jsm if there's no task on the stack.
if (stack.includes("/Task.jsm:")) {
stack = Task.Debugging.generateReadableStack(stack);
}
stack = stack.split("\n");
}
return {

Просмотреть файл

@ -48,8 +48,6 @@ ChromeUtils.import("resource://gre/modules/osfile/ospath.jsm", Path);
// The library of promises.
ChromeUtils.defineModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
// The implementation of communications
ChromeUtils.import("resource://gre/modules/PromiseWorker.jsm", this);
@ -313,9 +311,6 @@ var Scheduler = this.Scheduler = {
Scheduler.latestReceived = [];
let stack = new Error().stack;
// Avoid loading Task.jsm if there's no task on the stack.
if (stack.includes("/Task.jsm:"))
stack = Task.Debugging.generateReadableStack(stack);
Scheduler.latestSent = [Date.now(), stack, ...message];
// Wait for result

Просмотреть файл

@ -47,7 +47,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "PageThumbsStorageService",
"@mozilla.org/thumbnails/pagethumbs-service;1", "nsIPageThumbsStorageService");
/**
* Utilities for dealing with promises and Task.jsm
* Utilities for dealing with promises.
*/
const TaskUtils = {
/**

Просмотреть файл

@ -7,10 +7,8 @@
var EXPORTED_SYMBOLS = ["Log"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
Services: "resource://gre/modules/Services.jsm",
Task: "resource://gre/modules/Task.jsm",
});
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
const INTERNAL_FIELDS = new Set(["_level", "_message", "_time", "_namespace"]);
@ -129,9 +127,6 @@ var Log = {
// Standard JS exception
if (e.stack) {
let stack = e.stack;
// Avoid loading Task.jsm if there's no task on the stack.
if (stack.includes("/Task.jsm:"))
stack = Task.Debugging.generateReadableStack(stack);
return "JS Stack trace: " + stack.trim()
.replace(/@[^@]*?([^\/\.]+\.\w+:)/g, "@$1");
}

Просмотреть файл

@ -22,7 +22,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
OS: "resource://gre/modules/osfile.jsm",
Log: "resource://gre/modules/Log.jsm",
FileUtils: "resource://gre/modules/FileUtils.jsm",
Task: "resource://gre/modules/Task.jsm",
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
});
@ -302,14 +301,14 @@ ConnectionData.prototype = Object.freeze({
* any write operation, as follows:
*
* myConnection.executeBeforeShutdown("Bookmarks: Removing a bookmark",
* Task.async(function*(db) {
* async function(db) {
* // The connection will not be closed and shutdown will not proceed
* // until this task has completed.
*
* // `db` exposes the same API as `myConnection` but provides additional
* // logging support to help debug hard-to-catch shutdown timeouts.
*
* yield db.execute(...);
* await db.execute(...);
* }));
*
* @param {string} name A human-readable name for the ongoing operation, used
@ -599,13 +598,7 @@ ConnectionData.prototype = Object.freeze({
let result;
try {
// Keep Task.spawn here to preserve API compat; unfortunately
// func was a generator rather than a task here.
result = func();
if (Object.prototype.toString.call(result) == "[object Generator]")
result = await Task.spawn(func); // eslint-disable-line mozilla/no-task
else
result = await result;
result = await func();
} catch (ex) {
// It's possible that the exception has been caused by trying to
// close the connection in the middle of a transaction.
@ -1406,22 +1399,21 @@ OpenedConnection.prototype = Object.freeze({
* YOU SHOULD _NEVER_ NEST executeTransaction CALLS FOR ANY REASON, NOR
* DIRECTLY, NOR THROUGH OTHER PROMISES.
* FOR EXAMPLE, NEVER DO SOMETHING LIKE:
* yield executeTransaction(function* () {
* await executeTransaction(async function () {
* ...some_code...
* yield executeTransaction(function* () { // WRONG!
* await executeTransaction(async function () { // WRONG!
* ...some_code...
* })
* yield someCodeThatExecuteTransaction(); // WRONG!
* yield neverResolvedPromise; // WRONG!
* await someCodeThatExecuteTransaction(); // WRONG!
* await neverResolvedPromise; // WRONG!
* });
* NESTING CALLS WILL BLOCK ANY FUTURE TRANSACTION UNTIL A TIMEOUT KICKS IN.
* *****************************************************************************
*
* A transaction is specified by a user-supplied function that is a
* generator function which can be used by Task.jsm's Task.spawn(). The
* function receives this connection instance as its argument.
* A transaction is specified by a user-supplied function that is an
* async function. The function receives this connection instance as its argument.
*
* The supplied function is expected to yield promises. These are often
* The supplied function is expected to return promises. These are often
* promises created by calling `execute` and `executeCached`. If the
* generator is exhausted without any errors being thrown, the
* transaction is committed. If an error occurs, the transaction is

Просмотреть файл

@ -75,7 +75,6 @@ outstanding operations before FooService shuts down.
// Module FooService
Components.utils.import("resource://gre/modules/AsyncShutdown.jsm", this);
Components.utils.import("resource://gre/modules/Task.jsm", this);
this.exports = ["FooService"];
@ -84,12 +83,12 @@ outstanding operations before FooService shuts down.
// Export the `client` capability, to let clients register shutdown blockers
FooService.shutdown = shutdown.client;
// This Task should be triggered at some point during shutdown, generally
// as a client to another Barrier or Phase. Triggering this Task is not covered
// This function should be triggered at some point during shutdown, generally
// as a client to another Barrier or Phase. Triggering this function is not covered
// in this snippet.
let onshutdown = Task.async(function*() {
let onshutdown = async function() {
// Wait for all registered clients to have lifted the barrier
yield shutdown.wait();
await shutdown.wait();
// Now deactivate FooService itself.
// ...
@ -121,7 +120,7 @@ The following snippet presents FooClient2, a more sophisticated client of FooSer
// It can be any JSON serializable object.
state: "Not started",
wait: Task.async(function*() {
async wait() {
// This method is called once FooService starts informing its clients that
// FooService wishes to shut down.
@ -130,19 +129,19 @@ The following snippet presents FooClient2, a more sophisticated client of FooSer
// to shutdown properly.
this.state = "Starting";
let data = yield collectSomeData();
let data = await collectSomeData();
this.state = "Data collection complete";
try {
yield writeSomeDataToDisk(data);
await writeSomeDataToDisk(data);
this.state = "Data successfully written to disk";
} catch (ex) {
this.state = "Writing data to disk failed, proceeding with shutdown: " + ex;
}
yield FooService.oneLastCall();
await FooService.oneLastCall();
this.state = "Ready";
}.bind(this)
}
};
@ -154,7 +153,6 @@ Example 4: A service with both internal and external dependencies
// Module FooService2
Components.utils.import("resource://gre/modules/AsyncShutdown.jsm", this);
Components.utils.import("resource://gre/modules/Task.jsm", this);
Components.utils.import("resource://gre/modules/Promise.jsm", this);
this.exports = ["FooService2"];
@ -199,19 +197,19 @@ Example 4: A service with both internal and external dependencies
};
// This Task should be triggered at some point during shutdown, generally
// as a client to another Barrier. Triggering this Task is not covered
// This function should be triggered at some point during shutdown, generally
// as a client to another Barrier. Triggering this function is not covered
// in this snippet.
let onshutdown = Task.async(function*() {
let onshutdown = async function() {
// Wait for all registered clients to have lifted the barrier.
// These clients may open instances of FooConnection if they need to.
yield shutdown.wait();
await shutdown.wait();
// Now stop accepting any other connection request.
isClosed = true;
// Wait for all instances of FooConnection to be closed.
yield connections.wait();
await connections.wait();
// Now finish shutting down FooService2
// ...

Просмотреть файл

@ -157,6 +157,7 @@ TESTING_JS_MODULES += [
'HiddenFrame.jsm',
'tests/modules/MockDocument.jsm',
'tests/modules/PromiseTestUtils.jsm',
'tests/modules/Task.jsm',
'tests/xpcshell/TestIntegration.jsm',
]
@ -243,7 +244,6 @@ EXTRA_JS_MODULES += [
'sessionstore/FormData.jsm',
'ShortcutUtils.jsm',
'Sqlite.jsm',
'Task.jsm',
'Timer.jsm',
'Troubleshoot.jsm',
'UpdateUtils.jsm',

Просмотреть файл

Просмотреть файл

@ -4,7 +4,7 @@
ChromeUtils.import("resource://gre/modules/Promise.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Task.jsm");
ChromeUtils.import("resource://testing-common/Task.jsm");
ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm");
// Prevent test failures due to the unhandled rejections in this test file.

Просмотреть файл

@ -13,7 +13,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
"resource://testing-common/Task.jsm");
/**
* Returns a promise that will be resolved with the given value, when an event
@ -581,4 +581,3 @@ add_test(function exit_stack_tests() {
Task.Debugging.maintainStack = maintainStack;
run_next_test();
});

Просмотреть файл

@ -1526,8 +1526,7 @@ var AddonTestUtils = {
*
* @param {function} task
* The task to run while monitoring console output. May be
* either a generator function, per Task.jsm, or an ordinary
* function which returns promose.
* an async function, or an ordinary function which returns a promose.
* @return {Promise<[Array<nsIConsoleMessage>, *]>}
* Resolves to an object containing a `messages` property, with
* the array of console messages emitted during the execution

Просмотреть файл

@ -13,16 +13,6 @@ ChromeUtils.import("resource://gre/modules/UpdateTelemetry.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "XMLHttpRequest"]);
XPCOMUtils.defineLazyModuleGetters(this, {
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
CertUtils: "resource://gre/modules/CertUtils.jsm",
ctypes: "resource://gre/modules/ctypes.jsm",
DeferredTask: "resource://gre/modules/DeferredTask.jsm",
OS: "resource://gre/modules/osfile.jsm",
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm",
});
const UPDATESERVICE_CID = Components.ID("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}");
const PREF_APP_UPDATE_ALTWINDOWTYPE = "app.update.altwindowtype";
@ -201,6 +191,16 @@ var gUpdateMutexHandle = null;
// session
var gUpdateDirPermissionFixAttempted = false;
XPCOMUtils.defineLazyModuleGetters(this, {
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
CertUtils: "resource://gre/modules/CertUtils.jsm",
ctypes: "resource://gre/modules/ctypes.jsm",
DeferredTask: "resource://gre/modules/DeferredTask.jsm",
OS: "resource://gre/modules/osfile.jsm",
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm",
});
XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() {
return Services.prefs.getBoolPref(PREF_APP_UPDATE_LOG, false);
});
@ -1186,16 +1186,8 @@ function handleCriticalWriteResult(wroteSuccessfully, path) {
*/
function UpdatePatch(patch) {
this._properties = {};
this.errorCode = 0;
this.state = STATE_NONE;
for (let i = 0; i < patch.attributes.length; ++i) {
for (var i = 0; i < patch.attributes.length; ++i) {
var attr = patch.attributes.item(i);
// If an undefined value is saved to the xml file it will be a string when
// it is read from the xml file.
if (attr.value == "undefined") {
continue;
}
switch (attr.name) {
case "xmlns":
// Don't save the XML namespace.
@ -1208,26 +1200,19 @@ function UpdatePatch(patch) {
LOG("UpdatePatch:init - 0-sized patch!");
throw Cr.NS_ERROR_ILLEGAL_VALUE;
}
this[attr.name] = attr.value;
break;
case "errorCode":
if (attr.value) {
let val = parseInt(attr.value);
// This will evaluate to false if the value is 0 but that's ok since
// this.errorCode is set to the default of 0 above.
if (val) {
this.errorCode = val;
}
}
break;
case "finalURL":
case "state":
// fall through
case "type":
case "URL":
case "finalURL":
case "state":
case "errorCode":
this[attr.name] = attr.value;
break;
default:
// Set nsIPropertyBag properties that were read from the xml file.
this[attr.name] = attr.value;
// Save custom attributes when serializing to the local xml file but
// don't use this method for the expected attributes which are already
// handled in serialize.
this.setProperty(attr.name, attr.value);
break;
}
@ -1239,9 +1224,6 @@ UpdatePatch.prototype = {
*/
serialize: function UpdatePatch_serialize(updates) {
var patch = updates.createElementNS(URI_UPDATE_NS, "patch");
patch.setAttribute("size", this.size);
patch.setAttribute("type", this.type);
patch.setAttribute("URL", this.URL);
// Don't write an errorCode if it evaluates to false since 0 is the same as
// no error code.
if (this.errorCode) {
@ -1251,22 +1233,28 @@ UpdatePatch.prototype = {
if (this.finalURL) {
patch.setAttribute("finalURL", this.finalURL);
}
// The selected patch is the only patch that should have this attribute.
if (this.selected) {
patch.setAttribute("selected", this.selected);
}
if (this.state != STATE_NONE) {
patch.setAttribute("state", this.state);
}
patch.setAttribute("size", this.size);
patch.setAttribute("state", this.state);
patch.setAttribute("type", this.type);
patch.setAttribute("URL", this.URL);
for (let [name, value] of Object.entries(this._properties)) {
if (value.present) {
patch.setAttribute(name, value.data);
for (let p in this._properties) {
if (this._properties[p].present) {
patch.setAttribute(p, this._properties[p].data);
}
}
return patch;
},
/**
* A hash of custom properties
*/
_properties: null,
/**
* See nsIWritablePropertyBag.idl
*/
@ -1278,11 +1266,10 @@ UpdatePatch.prototype = {
* See nsIWritablePropertyBag.idl
*/
deleteProperty: function UpdatePatch_deleteProperty(name) {
if (name in this._properties) {
if (name in this._properties)
this._properties[name].present = false;
} else {
else
throw Cr.NS_ERROR_FAILURE;
}
},
/**
@ -1296,37 +1283,50 @@ UpdatePatch.prototype = {
},
* enumerate() {
// An nsISupportsInterfacePointer is used so creating an array using
// Array.from will retain the QueryInterface for nsIProperty.
let ip = Cc["@mozilla.org/supports-interface-pointer;1"].
createInstance(Ci.nsISupportsInterfacePointer);
let qi = ChromeUtils.generateQI([Ci.nsIProperty]);
for (let [name, value] of Object.entries(this._properties)) {
if (value.present) {
for (let propName in this._properties) {
if (this._properties[propName].present) {
// The nsIPropertyBag enumerator returns a nsISimpleEnumerator whose
// elements are nsIProperty objects. Calling QueryInterface for
// nsIProperty on the object doesn't return to the caller an object that
// is already queried to nsIProperty but do it just in case it is fixed
// at some point.
ip.data = {name, value: value.data, QueryInterface: qi};
yield ip.data.QueryInterface(Ci.nsIProperty);
// elements are nsIProperty objects.
yield { name: propName,
value: this._properties[propName].data,
QueryInterface: ChromeUtils.generateQI([Ci.nsIProperty])};
}
}
},
/**
* See nsIPropertyBag.idl
*
* Note: returns null instead of throwing when the property doesn't exist to
* simplify code and to silence warnings in debug builds.
*/
getProperty: function UpdatePatch_getProperty(name) {
if (name in this._properties && this._properties[name].present) {
if (name in this._properties &&
this._properties[name].present) {
return this._properties[name].data;
}
return null;
},
/**
* See nsIUpdateService.idl
*/
get errorCode() {
return this._properties.errorCode || 0;
},
set errorCode(val) {
this._properties.errorCode = val;
},
/**
* See nsIUpdateService.idl
*/
get state() {
return this._properties.state || STATE_NONE;
},
set state(val) {
this._properties.state = val;
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIUpdatePatch,
Ci.nsIPropertyBag,
Ci.nsIWritablePropertyBag]),
@ -1341,12 +1341,12 @@ UpdatePatch.prototype = {
* @constructor
*/
function Update(update) {
this._patches = [];
this._properties = {};
this._patches = [];
this.isCompleteUpdate = false;
this.unsupported = false;
this.channel = "default";
this.promptWaitTime = Services.prefs.getIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 43200);
this.unsupported = false;
// Null <update>, assume this is a message container and do no
// further initialization
@ -1354,6 +1354,7 @@ function Update(update) {
return;
}
let patch;
for (let i = 0; i < update.childNodes.length; ++i) {
let patchElement = update.childNodes.item(i);
if (patchElement.nodeType != patchElement.ELEMENT_NODE ||
@ -1361,7 +1362,6 @@ function Update(update) {
continue;
}
let patch;
try {
patch = new UpdatePatch(patchElement);
} catch (e) {
@ -1378,17 +1378,14 @@ function Update(update) {
// installDate attribute this will be replaced with that value if it doesn't
// equal 0.
this.installDate = (new Date()).getTime();
this.patchCount = update.childNodes.length;
for (let i = 0; i < update.attributes.length; ++i) {
let attr = update.attributes.item(i);
var attr = update.attributes.item(i);
if (attr.name == "xmlns" || attr.value == "undefined") {
// Don't save the XML namespace or undefined values.
// If an undefined value is saved to the xml file it will be a string when
// it is read from the xml file.
continue;
} else if (attr.name == "detailsURL") {
this.detailsURL = attr.value;
this._detailsURL = attr.value;
} else if (attr.name == "installDate" && attr.value) {
let val = parseInt(attr.value);
if (val) {
@ -1397,10 +1394,7 @@ function Update(update) {
} else if (attr.name == "errorCode" && attr.value) {
let val = parseInt(attr.value);
if (val) {
// Set the value of |_errorCode| instead of |errorCode| since
// selectedPatch won't be available at this point and normally the
// nsIUpdatePatch will provide the errorCode.
this._errorCode = val;
this.errorCode = val;
}
} else if (attr.name == "isCompleteUpdate") {
this.isCompleteUpdate = attr.value == "true";
@ -1411,59 +1405,54 @@ function Update(update) {
} else if (attr.name == "unsupported") {
this.unsupported = attr.value == "true";
} else {
this[attr.name] = attr.value;
switch (attr.name) {
case "appVersion":
case "buildID":
case "channel":
case "displayVersion":
case "elevationFailure":
case "name":
case "previousAppVersion":
case "serviceURL":
case "statusText":
case "type":
this[attr.name] = attr.value;
break;
default:
// Set nsIPropertyBag properties that were read from the xml file.
// Save custom attributes when serializing to the local xml file but
// don't use this method for the expected attributes which are already
// handled in serialize.
this.setProperty(attr.name, attr.value);
break;
}
}
}
if (!this.previousAppVersion) {
this.previousAppVersion = Services.appinfo.version;
}
if (!this.elevationFailure) {
this.elevationFailure = false;
}
if (!this.detailsURL) {
try {
// Try using a default details URL supplied by the distribution
// if the update XML does not supply one.
this.detailsURL = Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_URL_DETAILS);
} catch (e) {
this.detailsURL = "";
}
}
if (!this.displayVersion) {
this.displayVersion = this.appVersion;
}
if (!this.name) {
// When the update doesn't provide a name fallback to using
// "<App Name> <Update App Version>"
let brandBundle = Services.strings.createBundle(URI_BRAND_PROPERTIES);
let appName = brandBundle.GetStringFromName("brandShortName");
this.name = gUpdateBundle.formatStringFromName("updateName",
[appName, this.displayVersion], 2);
// The Update Name is either the string provided by the <update> element, or
// the string: "<App Name> <Update App Version>"
var name = "";
if (update.hasAttribute("name")) {
name = update.getAttribute("name");
} else {
var brandBundle = Services.strings.createBundle(URI_BRAND_PROPERTIES);
var appName = brandBundle.GetStringFromName("brandShortName");
name = gUpdateBundle.formatStringFromName("updateName",
[appName, this.displayVersion], 2);
}
this.name = name;
}
Update.prototype = {
/**
* See nsIUpdateService.idl
*/
get patchCount() {
return this._patches.length;
},
/**
* See nsIUpdateService.idl
*/
@ -1515,14 +1504,28 @@ Update.prototype = {
* See nsIUpdateService.idl
*/
get selectedPatch() {
for (let i = 0; i < this.patchCount; ++i) {
if (this._patches[i].selected) {
for (var i = 0; i < this.patchCount; ++i) {
if (this._patches[i].selected)
return this._patches[i];
}
}
return null;
},
/**
* See nsIUpdateService.idl
*/
get detailsURL() {
if (!this._detailsURL) {
try {
// Try using a default details URL supplied by the distribution
// if the update XML does not supply one.
return Services.urlFormatter.formatURLPref(PREF_APP_UPDATE_URL_DETAILS);
} catch (e) {
}
}
return this._detailsURL || "";
},
/**
* See nsIUpdateService.idl
*/
@ -1532,33 +1535,35 @@ Update.prototype = {
if (!this.appVersion) {
return null;
}
let update = updates.createElementNS(URI_UPDATE_NS, "update");
var update = updates.createElementNS(URI_UPDATE_NS, "update");
update.setAttribute("appVersion", this.appVersion);
update.setAttribute("buildID", this.buildID);
update.setAttribute("channel", this.channel);
update.setAttribute("detailsURL", this.detailsURL);
update.setAttribute("displayVersion", this.displayVersion);
update.setAttribute("installDate", this.installDate);
update.setAttribute("isCompleteUpdate", this.isCompleteUpdate);
update.setAttribute("name", this.name);
update.setAttribute("previousAppVersion", this.previousAppVersion);
update.setAttribute("promptWaitTime", this.promptWaitTime);
update.setAttribute("serviceURL", this.serviceURL);
update.setAttribute("type", this.type);
if (this.detailsURL) {
update.setAttribute("detailsURL", this.detailsURL);
}
if (this.previousAppVersion) {
update.setAttribute("previousAppVersion", this.previousAppVersion);
}
if (this.statusText) {
update.setAttribute("statusText", this.statusText);
}
if (this.unsupported) {
update.setAttribute("unsupported", this.unsupported);
}
if (this.elevationFailure) {
update.setAttribute("elevationFailure", this.elevationFailure);
}
updates.documentElement.appendChild(update);
for (let [name, value] of Object.entries(this._properties)) {
if (value.present) {
update.setAttribute(name, value.data);
for (let p in this._properties) {
if (this._properties[p].present) {
update.setAttribute(p, this._properties[p].data);
}
}
@ -1566,10 +1571,14 @@ Update.prototype = {
update.appendChild(this.getPatchAt(i).serialize(updates));
}
updates.documentElement.appendChild(update);
return update;
},
/**
* A hash of custom properties
*/
_properties: null,
/**
* See nsIWritablePropertyBag.idl
*/
@ -1581,11 +1590,10 @@ Update.prototype = {
* See nsIWritablePropertyBag.idl
*/
deleteProperty: function Update_deleteProperty(name) {
if (name in this._properties) {
if (name in this._properties)
this._properties[name].present = false;
} else {
else
throw Cr.NS_ERROR_FAILURE;
}
},
/**
@ -1599,20 +1607,13 @@ Update.prototype = {
},
* enumerate() {
// An nsISupportsInterfacePointer is used so creating an array using
// Array.from will retain the QueryInterface for nsIProperty.
let ip = Cc["@mozilla.org/supports-interface-pointer;1"].
createInstance(Ci.nsISupportsInterfacePointer);
let qi = ChromeUtils.generateQI([Ci.nsIProperty]);
for (let [name, value] of Object.entries(this._properties)) {
if (value.present) {
for (let propName in this._properties) {
if (this._properties[propName].present) {
// The nsIPropertyBag enumerator returns a nsISimpleEnumerator whose
// elements are nsIProperty objects. Calling QueryInterface for
// nsIProperty on the object doesn't return to the caller an object that
// is already queried to nsIProperty but do it just in case it is fixed
// at some point.
ip.data = {name, value: value.data, QueryInterface: qi};
yield ip.data.QueryInterface(Ci.nsIProperty);
// elements are nsIProperty objects.
yield { name: propName,
value: this._properties[propName].data,
QueryInterface: ChromeUtils.generateQI([Ci.nsIProperty])};
}
}
},
@ -1637,9 +1638,8 @@ Update.prototype = {
const UpdateServiceFactory = {
_instance: null,
createInstance(outer, iid) {
if (outer != null) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return this._instance == null ? this._instance = new UpdateService() :
this._instance;
},
@ -2582,6 +2582,8 @@ UpdateService.prototype = {
}
this._downloader.cancel();
}
// Set the previous application version prior to downloading the update.
update.previousAppVersion = Services.appinfo.version;
this._downloader = new Downloader(background, this);
return this._downloader.downloadUpdate(update);
},

Просмотреть файл

@ -108,27 +108,30 @@ function run_test() {
"the update custom2_attr property" + MSG_SHOULD_EQUAL);
// nsIPropertyBag enumerator
debugDump("checking the first update enumerator");
Assert.ok(update.enumerator instanceof Ci.nsISimpleEnumerator,
"update enumerator should be an instance of nsISimpleEnumerator");
let results = Array.from(update.enumerator);
Assert.equal(results.length, 3,
"the length of the array created from the update enumerator" +
MSG_SHOULD_EQUAL);
Assert.ok(results.every(prop => prop instanceof Ci.nsIProperty),
"the objects in the array created from the update enumerator " +
"should all be an instance of nsIProperty");
Assert.equal(results[0].name, "custom1_attr",
let e = update.enumerator;
Assert.ok(e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
let prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom1_attr",
"the first property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[0].value, "custom1 value",
Assert.equal(prop.value, "custom1 value",
"the first property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].name, "custom2_attr",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom2_attr",
"the second property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].value, "custom2 value",
Assert.equal(prop.value, "custom2 value",
"the second property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[2].name, "foregroundDownload",
"the second property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[2].value, "true",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.equal(prop.name, "foregroundDownload",
"the third property name" + MSG_SHOULD_EQUAL);
Assert.equal(prop.value, "true",
"the third property value" + MSG_SHOULD_EQUAL);
Assert.ok(!e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
debugDump("checking the first update patch properties");
let patch = update.selectedPatch.QueryInterface(Ci.nsIWritablePropertyBag);
@ -148,23 +151,25 @@ function run_test() {
"the update patch custom2_attr property" + MSG_SHOULD_EQUAL);
// nsIPropertyBag enumerator
debugDump("checking the first update patch enumerator");
Assert.ok(patch.enumerator instanceof Ci.nsISimpleEnumerator,
"patch enumerator should be an instance of nsISimpleEnumerator");
results = Array.from(patch.enumerator);
Assert.equal(results.length, 2,
"the length of the array created from the patch enumerator" +
MSG_SHOULD_EQUAL);
Assert.ok(results.every(prop => prop instanceof Ci.nsIProperty),
"the objects in the array created from the patch enumerator " +
"should all be an instance of nsIProperty");
Assert.equal(results[0].name, "custom1_attr",
e = patch.enumerator;
Assert.ok(e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom1_attr",
"the first property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[0].value, "custom1 patch value",
Assert.equal(prop.value, "custom1 patch value",
"the first property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].name, "custom2_attr",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom2_attr",
"the second property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].value, "custom2 patch value",
Assert.equal(prop.value, "custom2 patch value",
"the second property value" + MSG_SHOULD_EQUAL);
Assert.ok(!e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
debugDump("checking the second update properties");
update = gUpdateManager.getUpdateAt(1).QueryInterface(Ci.nsIWritablePropertyBag);
@ -194,7 +199,7 @@ function run_test() {
"the update channel attribute" + MSG_SHOULD_EQUAL);
Assert.equal(update.promptWaitTime, "691200",
"the update promptWaitTime attribute" + MSG_SHOULD_EQUAL);
Assert.equal(update.previousAppVersion, "1.0",
Assert.equal(update.previousAppVersion, null,
"the update previousAppVersion attribute" + MSG_SHOULD_EQUAL);
// Custom attributes
Assert.equal(update.getProperty("custom3_attr"), "custom3 value",
@ -203,27 +208,30 @@ function run_test() {
"the update custom4_attr property" + MSG_SHOULD_EQUAL);
// nsIPropertyBag enumerator
debugDump("checking the second update enumerator");
Assert.ok(update.enumerator instanceof Ci.nsISimpleEnumerator,
"update enumerator should be an instance of nsISimpleEnumerator");
results = Array.from(update.enumerator);
Assert.equal(results.length, 3,
"the length of the array created from the update enumerator" +
MSG_SHOULD_EQUAL);
Assert.ok(results.every(prop => prop instanceof Ci.nsIProperty),
"the objects in the array created from the update enumerator " +
"should all be an instance of nsIProperty");
Assert.equal(results[0].name, "custom3_attr",
e = update.enumerator;
Assert.ok(e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom3_attr",
"the first property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[0].value, "custom3 value",
Assert.equal(prop.value, "custom3 value",
"the first property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].name, "custom4_attr",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom4_attr",
"the second property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].value, "custom4 value",
Assert.equal(prop.value, "custom4 value",
"the second property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[2].name, "foregroundDownload",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.equal(prop.name, "foregroundDownload",
"the third property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[2].value, "false",
Assert.equal(prop.value, "false",
"the third property value" + MSG_SHOULD_EQUAL);
Assert.ok(!e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
debugDump("checking the second update patch properties");
patch = update.selectedPatch.QueryInterface(Ci.nsIWritablePropertyBag);
@ -243,23 +251,25 @@ function run_test() {
"the update patch custom4_attr property" + MSG_SHOULD_EQUAL);
// nsIPropertyBag enumerator
debugDump("checking the second update patch enumerator");
Assert.ok(patch.enumerator instanceof Ci.nsISimpleEnumerator,
"patch enumerator should be an instance of nsISimpleEnumerator");
results = Array.from(patch.enumerator);
Assert.equal(results.length, 2,
"the length of the array created from the patch enumerator" +
MSG_SHOULD_EQUAL);
Assert.ok(results.every(prop => prop instanceof Ci.nsIProperty),
"the objects in the array created from the patch enumerator " +
"should all be an instance of nsIProperty");
Assert.equal(results[0].name, "custom3_attr",
e = patch.enumerator;
Assert.ok(e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom3_attr",
"the first property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[0].value, "custom3 patch value",
Assert.equal(prop.value, "custom3 patch value",
"the first property value" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].name, "custom4_attr",
prop = e.getNext().QueryInterface(Ci.nsIProperty);
Assert.ok(!!prop,
"the enumerator.getNext()" + MSG_SHOULD_EQUAL);
Assert.equal(prop.name, "custom4_attr",
"the second property name" + MSG_SHOULD_EQUAL);
Assert.equal(results[1].value, "custom4 patch value",
Assert.equal(prop.value, "custom4 patch value",
"the second property value" + MSG_SHOULD_EQUAL);
Assert.ok(!e.hasMoreElements(),
"the enumerator.hasMoreElements()" + MSG_SHOULD_EQUAL);
// Cleaning up the active update along with reloading the update manager
// in doTestFinish will prevent writing the update xml files during