Merge mozilla-central to mozilla-inbound. a=merge

This commit is contained in:
Cosmin Sabou 2018-10-19 00:59:32 +03:00
Родитель 31aa4651c5 5115d61980
Коммит a833a61a1b
4956 изменённых файлов: 317502 добавлений и 8067 удалений

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

@ -6,6 +6,7 @@
#include "AccessibleWrap.h"
#include "Accessible-inl.h"
#include "AndroidInputType.h"
#include "DocAccessibleWrap.h"
#include "IDSet.h"
#include "JavaBuiltins.h"
@ -286,10 +287,11 @@ AccessibleWrap::CreateBundle(int32_t aParentID,
GECKOBUNDLE_PUT(nodeInfo, "rangeInfo", rangeInfo);
}
nsString inputType;
nsAccUtils::GetAccAttr(aAttributes, nsGkAtoms::textInputType, inputType);
if (!inputType.IsEmpty()) {
GECKOBUNDLE_PUT(nodeInfo, "inputType", jni::StringParam(inputType));
nsString inputTypeAttr;
nsAccUtils::GetAccAttr(aAttributes, nsGkAtoms::textInputType, inputTypeAttr);
int32_t inputType = GetInputType(inputTypeAttr);
if (inputType) {
GECKOBUNDLE_PUT(nodeInfo, "inputType", java::sdk::Integer::ValueOf(inputType));
}
nsString posinset;
@ -462,6 +464,36 @@ AccessibleWrap::GetAndroidClass(role aRole)
#undef ROLE
}
int32_t
AccessibleWrap::GetInputType(const nsString& aInputTypeAttr)
{
if (aInputTypeAttr.EqualsIgnoreCase("email")) {
return java::sdk::InputType::TYPE_CLASS_TEXT | java::sdk::InputType::TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
}
if (aInputTypeAttr.EqualsIgnoreCase("number")) {
return java::sdk::InputType::TYPE_CLASS_NUMBER;
}
if (aInputTypeAttr.EqualsIgnoreCase("password")) {
return java::sdk::InputType::TYPE_CLASS_TEXT | java::sdk::InputType::TYPE_TEXT_VARIATION_WEB_PASSWORD;
}
if (aInputTypeAttr.EqualsIgnoreCase("tel")) {
return java::sdk::InputType::TYPE_CLASS_PHONE;
}
if (aInputTypeAttr.EqualsIgnoreCase("text")) {
return java::sdk::InputType::TYPE_CLASS_TEXT | java::sdk::InputType::TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
}
if (aInputTypeAttr.EqualsIgnoreCase("url")) {
return java::sdk::InputType::TYPE_CLASS_TEXT | java::sdk::InputType::TYPE_TEXT_VARIATION_URI;
}
return 0;
}
void
AccessibleWrap::DOMNodeID(nsString& aDOMNodeID)
{

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

@ -57,6 +57,8 @@ protected:
static int32_t GetAndroidClass(role aRole);
static int32_t GetInputType(const nsString& aInputTypeAttr);
int32_t mID;
private:

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

@ -126,7 +126,6 @@ var TrackingProtection = {
};
var ThirdPartyCookies = {
reportBreakageLabel: "cookierestrictions",
telemetryIdentifier: "cr",
PREF_ENABLED: "network.cookie.cookieBehavior",
PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.rejecttrackers.reportBreakage.enabled",
@ -144,12 +143,49 @@ var ThirdPartyCookies = {
document.getElementById("identity-popup-content-blocking-category-3rdpartycookies");
},
get reportBreakageLabel() {
switch (this.behaviorPref) {
case Ci.nsICookieService.BEHAVIOR_ACCEPT:
return "nocookiesblocked";
case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
return "allthirdpartycookiesblocked";
case Ci.nsICookieService.BEHAVIOR_REJECT:
return "allcookiesblocked";
case Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN:
return "cookiesfromunvisitedsitesblocked";
default:
Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
// fall through
case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
return "cookierestrictions";
}
},
get categoryLabelDefault() {
delete this.categoryLabelDefault;
return this.categoryLabelDefault =
document.getElementById("identity-popup-content-blocking-category-label-default");
},
get categoryLabelTrackers() {
delete this.categoryLabelTrackers;
return this.categoryLabelTrackers =
document.getElementById("identity-popup-content-blocking-category-label-trackers");
},
updateCategoryLabel() {
let rejectTrackers = this.behaviorPref == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
this.categoryLabelDefault.hidden = rejectTrackers;
this.categoryLabelTrackers.hidden = !rejectTrackers;
},
init() {
XPCOMUtils.defineLazyPreferenceGetter(this, "behaviorPref", this.PREF_ENABLED,
Ci.nsICookieService.BEHAVIOR_ACCEPT);
Ci.nsICookieService.BEHAVIOR_ACCEPT, this.updateCategoryLabel.bind(this));
XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
this.PREF_REPORT_BREAKAGE_ENABLED, false);
this.updateCategoryLabel();
},
get enabled() {
return this.PREF_ENABLED_VALUES.includes(this.behaviorPref);

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

@ -177,6 +177,18 @@ function testTrackingPage(window) {
is(hidden(category + " > .identity-popup-content-blocking-category-state-label"), !blockedByTP,
"Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
}
if (Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER) {
ok(hidden("#identity-popup-content-blocking-category-label-default"),
"Not showing default cookie restrictions label.");
ok(!hidden("#identity-popup-content-blocking-category-label-trackers"),
"Showing trackers cookie restrictions label.");
} else {
ok(hidden("#identity-popup-content-blocking-category-label-trackers"),
"Not showing trackers cookie restrictions label.");
ok(!hidden("#identity-popup-content-blocking-category-label-default"),
"Showing default cookie restrictions label.");
}
}
function testTrackingPageUnblocked(blockedByTP, window) {

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

@ -105,7 +105,10 @@
<hbox id="identity-popup-content-blocking-category-3rdpartycookies"
class="identity-popup-content-blocking-category" align="center" role="group">
<image class="identity-popup-content-blocking-category-icon thirdpartycookies-icon"/>
<label flex="1" class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.label;</label>
<label flex="1" id="identity-popup-content-blocking-category-label-default"
class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.label;</label>
<label flex="1" id="identity-popup-content-blocking-category-label-trackers"
hidden="true" class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.trackers.label;</label>
<label flex="1" class="identity-popup-content-blocking-category-state-label">&contentBlocking.3rdPartyCookies.blocking.label;</label>
<label flex="1" class="identity-popup-content-blocking-category-add-blocking text-link"
id="identity-popup-3rdpartycookies-add-blocking"

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

@ -10,6 +10,24 @@ ChromeUtils.defineModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
ChromeUtils.defineModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm");
ChromeUtils.defineModuleGetter(this, "RemoteSettings",
"resource://services-settings/remote-settings.js");
async function installFromUrl(url, hash) {
let install = await AddonManager.getInstallForURL(
url, "application/x-xpinstall", hash);
return install.install();
}
async function dictionaryIdsForLocale(locale) {
let entries = await RemoteSettings("language-dictionaries").get({
filters: {id: locale},
});
if (entries.length > 0) {
return entries[0].dictionaries;
}
return [];
}
class OrderedListBox {
constructor({richlistbox, upButton, downButton, removeButton, onRemove}) {
@ -394,24 +412,34 @@ var gBrowserLanguagesDialog = {
},
async availableLanguageSelected(item) {
let available = new Set(Services.locale.availableLocales);
if (Services.locale.availableLocales.includes(item.value)) {
this.requestLocalLanguage(item);
} else if (this.availableLangpacks.has(item.value)) {
await this.requestRemoteLanguage(item);
} else {
this.showError();
}
},
if (available.has(item.value)) {
requestLocalLanguage(item, available) {
this._requestedLocales.addItem(item);
if (available.size == this._requestedLocales.items.length) {
let requestedCount = this._requestedLocales.items.length;
let availableCount = Services.locale.availableLocales.length;
if (requestedCount == availableCount) {
// Remove the installed label, they're all installed.
this._availableLocales.items.shift();
this._availableLocales.setItems(this._availableLocales.items);
}
} else if (this.availableLangpacks.has(item.value)) {
this._availableLocales.disableWithMessageId("browser-languages-downloading");
},
async requestRemoteLanguage(item) {
this._availableLocales.disableWithMessageId(
"browser-languages-downloading");
let {url, hash} = this.availableLangpacks.get(item.value);
let install = await AddonManager.getInstallForURL(
url, "application/x-xpinstall", hash);
try {
await install.install();
await installFromUrl(url, hash);
} catch (e) {
this.showError();
return;
@ -419,9 +447,23 @@ var gBrowserLanguagesDialog = {
item.installed = true;
this._requestedLocales.addItem(item);
this._availableLocales.enableWithMessageId("browser-languages-select-language");
} else {
this.showError();
this._availableLocales.enableWithMessageId(
"browser-languages-select-language");
// This is an async task that will install the recommended dictionaries for
// this locale. This will fail silently at least until a management UI is
// added in bug 1493705.
this.installDictionariesForLanguage(item.value);
},
async installDictionariesForLanguage(locale) {
try {
let ids = await dictionaryIdsForLocale(locale);
let addonInfos = await AddonRepository.getAddonsByIDs(ids);
await Promise.all(addonInfos.map(
info => installFromUrl(info.sourceURI.spec)));
} catch (e) {
Cu.reportError(e);
}
},

Двоичный файл не отображается.

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

@ -5,6 +5,7 @@ prefs =
support-files =
head.js
privacypane_tests_perwindow.js
addons/pl-dictionary.xpi
addons/set_homepage.xpi
addons/set_newtab.xpi

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

@ -4,9 +4,11 @@
ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", this);
ChromeUtils.import("resource://gre/modules/Services.jsm");
AddonTestUtils.initMochitest(this);
const BROWSER_LANGUAGES_URL = "chrome://browser/content/preferences/browserLanguages.xul";
const DICTIONARY_ID_PL = "pl@dictionaries.addons.mozilla.org";
function getManifestData(locale) {
return {
@ -79,6 +81,45 @@ async function createLanguageToolsFile() {
return dir;
}
async function createDictionaryBrowseResults() {
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
let dictionaryPath = testDir + "/addons/pl-dictionary.xpi";
let filename = "dictionaries.json";
let response = {
page_size: 25,
page_count: 1,
count: 1,
results: [{
current_version: {
id: 1823648,
compatibility: {
firefox: {max: "9999", min: "4.0"},
},
files: [{
platform: "all",
url: dictionaryPath,
}],
version: "1.0.20160228",
},
default_locale: "pl",
description: "Polish spell-check",
guid: DICTIONARY_ID_PL,
name: "Polish Dictionary",
slug: "polish-spellchecker-dictionary",
status: "public",
summary: "Polish dictionary",
type: "dictionary",
}],
};
let files = {[filename]: response};
let dir = await AddonTestUtils.promiseWriteFilesToDir(
AddonTestUtils.tempDir.path, files);
dir.append(filename);
return dir;
}
function assertLocaleOrder(list, locales) {
is(list.itemCount, locales.split(",").length,
"The right number of locales are requested");
@ -245,12 +286,16 @@ add_task(async function testInstallFromAMO() {
let langpacksFile = await createLanguageToolsFile();
let langpacksUrl = Services.io.newFileURI(langpacksFile).spec;
let dictionaryBrowseFile = await createDictionaryBrowseResults();
let browseApiEndpoint = Services.io.newFileURI(dictionaryBrowseFile).spec;
await SpecialPowers.pushPrefEnv({
set: [
["intl.multilingual.enabled", true],
["intl.locale.requested", "en-US"],
["extensions.getAddons.langpacks.url", langpacksUrl],
["extensions.langpacks.signatures.required", false],
["extensions.getAddons.get.url", browseApiEndpoint],
],
});
@ -277,6 +322,10 @@ add_task(async function testInstallFromAMO() {
is(Services.locale.availableLocales.join(","),
"en-US", "There is only one installed locale");
// Verify that there are no extra dictionaries.
let dicts = await AddonManager.getAddonsByTypes(["dictionary"]);
is(dicts.length, 0, "There are no installed dictionaries");
// Add Polish, this will install the langpack.
requestLocale("pl", available, dialogDoc);
@ -293,10 +342,21 @@ add_task(async function testInstallFromAMO() {
is(Services.locale.availableLocales.sort().join(","),
"en-US,pl", "Polish is now installed");
// Uninstall the langpack.
langpacks = await AddonManager.getAddonsByTypes(["locale"]);
is(langpacks.length, 1, "There is one langpacks installed");
await Promise.all(langpacks.map(pack => pack.uninstall()));
await BrowserTestUtils.waitForCondition(async () => {
let newDicts = await AddonManager.getAddonsByTypes(["dictionary"]);
let done = newDicts.length != 0;
if (done) {
is(newDicts[0].id, DICTIONARY_ID_PL, "The polish dictionary was installed");
}
return done;
});
// Uninstall the langpack and dictionary.
let installs = await AddonManager.getAddonsByTypes(["locale", "dictionary"]);
is(installs.length, 2, "There is one langpack and one dictionary installed");
await Promise.all(installs.map(item => item.uninstall()));
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

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

@ -1002,6 +1002,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY contentBlocking.trackingProtection.add.label "Add Blocking…">
<!ENTITY contentBlocking.3rdPartyCookies.label "Third-Party Cookies">
<!ENTITY contentBlocking.3rdPartyCookies.trackers.label "Tracking Cookies">
<!-- LOCALIZATION NOTE (contentBlocking.3rdPartyCookies.blocked.label):
This label signals that this type of content blocking is turned
ON and is successfully blocking third-party cookies, so this is

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

@ -6,6 +6,7 @@
@import "resource://devtools/client/themes/variables.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/ConnectSteps.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsList.css";

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

@ -5,6 +5,12 @@
"use strict";
const {
ADB_ADDON_INSTALL_START,
ADB_ADDON_INSTALL_SUCCESS,
ADB_ADDON_INSTALL_FAILURE,
ADB_ADDON_UNINSTALL_START,
ADB_ADDON_UNINSTALL_SUCCESS,
ADB_ADDON_UNINSTALL_FAILURE,
ADB_ADDON_STATUS_UPDATED,
DEBUG_TARGET_COLLAPSIBILITY_UPDATED,
NETWORK_LOCATIONS_UPDATED,
@ -13,6 +19,7 @@ const {
} = require("../constants");
const NetworkLocationsModule = require("../modules/network-locations");
const { adbAddon } = require("devtools/shared/adb/adb-addon");
const Actions = require("./index");
@ -69,10 +76,38 @@ function updateNetworkLocations(locations) {
return { type: NETWORK_LOCATIONS_UPDATED, locations };
}
function installAdbAddon() {
return async (dispatch, getState) => {
dispatch({ type: ADB_ADDON_INSTALL_START });
try {
await adbAddon.install();
dispatch({ type: ADB_ADDON_INSTALL_SUCCESS });
} catch (e) {
dispatch({ type: ADB_ADDON_INSTALL_FAILURE, error: e.message });
}
};
}
function uninstallAdbAddon() {
return async (dispatch, getState) => {
dispatch({ type: ADB_ADDON_UNINSTALL_START });
try {
await adbAddon.uninstall();
dispatch({ type: ADB_ADDON_UNINSTALL_SUCCESS });
} catch (e) {
dispatch({ type: ADB_ADDON_UNINSTALL_FAILURE, error: e.message });
}
};
}
module.exports = {
addNetworkLocation,
installAdbAddon,
removeNetworkLocation,
selectPage,
uninstallAdbAddon,
updateAdbAddonStatus,
updateDebugTargetCollapsibility,
updateNetworkLocations,

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

@ -36,7 +36,12 @@ class App extends PureComponent {
}
getSelectedPageComponent() {
const { dispatch, networkLocations, selectedPage } = this.props;
const {
adbAddonStatus,
dispatch,
networkLocations,
selectedPage
} = this.props;
if (!selectedPage) {
// No page selected.
@ -45,7 +50,11 @@ class App extends PureComponent {
switch (selectedPage) {
case PAGES.CONNECT:
return ConnectPage({ dispatch, networkLocations });
return ConnectPage({
adbAddonStatus,
dispatch,
networkLocations
});
default:
// All pages except for the CONNECT page are RUNTIME pages.
return RuntimePage({ dispatch });

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

@ -0,0 +1,7 @@
/* 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/. */
.connect-page__usb__toggle-button {
margin-top: calc(var(--base-distance) * 4);
}

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

@ -11,6 +11,14 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized);
const {
USB_STATES,
} = require("../../constants");
const Actions = require("../../actions/index");
loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true);
const ConnectSection = createFactory(require("./ConnectSection"));
const ConnectSteps = createFactory(require("./ConnectSteps"));
const NetworkLocationsForm = createFactory(require("./NetworkLocationsForm"));
@ -23,6 +31,7 @@ const GLOBE_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-globe-icon.
class ConnectPage extends PureComponent {
static get propTypes() {
return {
adbAddonStatus: PropTypes.string,
dispatch: PropTypes.func.isRequired,
// Provided by wrapping the component with FluentReact.withLocalization.
getString: PropTypes.func.isRequired,
@ -54,8 +63,59 @@ class ConnectPage extends PureComponent {
);
}
onToggleUSBClick() {
const { adbAddonStatus } = this.props;
const isAddonInstalled = adbAddonStatus === ADB_ADDON_STATES.INSTALLED;
if (isAddonInstalled) {
this.props.dispatch(Actions.uninstallAdbAddon());
} else {
this.props.dispatch(Actions.installAdbAddon());
}
}
getUsbStatus() {
switch (this.props.adbAddonStatus) {
case ADB_ADDON_STATES.INSTALLED:
return USB_STATES.ENABLED_USB;
case ADB_ADDON_STATES.UNINSTALLED:
return USB_STATES.DISABLED_USB;
default:
return USB_STATES.UPDATING_USB;
}
}
renderUsbToggleButton() {
const usbStatus = this.getUsbStatus();
const localizedStates = {
[USB_STATES.ENABLED_USB]: "about-debugging-connect-usb-disable-button",
[USB_STATES.DISABLED_USB]: "about-debugging-connect-usb-enable-button",
[USB_STATES.UPDATING_USB]: "about-debugging-connect-usb-updating-button",
};
const localizedState = localizedStates[usbStatus];
// Disable the button while the USB status is updating.
const disabled = usbStatus === USB_STATES.UPDATING_USB;
return Localized(
{
id: localizedState
},
dom.button(
{
className: "std-button connect-page__usb__toggle-button " +
"js-connect-usb-toggle-button",
disabled,
onClick: () => this.onToggleUSBClick(),
},
localizedState
)
);
}
renderUsb() {
const { getString } = this.props;
const { adbAddonStatus, getString } = this.props;
const isAddonInstalled = adbAddonStatus === ADB_ADDON_STATES.INSTALLED;
return Localized(
{
id: "about-debugging-connect-usb",
@ -66,13 +126,28 @@ class ConnectPage extends PureComponent {
icon: USB_ICON_SRC,
title: "Via USB",
},
(isAddonInstalled ?
ConnectSteps({
steps: [
getString("about-debugging-connect-usb-step-enable-dev-menu"),
getString("about-debugging-connect-usb-step-enable-debug"),
getString("about-debugging-connect-usb-step-plug-device"),
]
})
}) :
Localized(
{
id: "about-debugging-connect-usb-disabled",
},
dom.aside(
{
className: "js-connect-usb-disabled-message"
},
"Enabling this will download and add the required Android USB debugging " +
"components to Firefox."
)
)
),
this.renderUsbToggleButton()
)
);
}

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

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'ConnectPage.css',
'ConnectPage.js',
'ConnectSection.js',
'ConnectSteps.css',

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

@ -5,6 +5,12 @@
"use strict";
const actionTypes = {
ADB_ADDON_INSTALL_START: "ADB_ADDON_INSTALL_START",
ADB_ADDON_INSTALL_SUCCESS: "ADB_ADDON_INSTALL_SUCCESS",
ADB_ADDON_INSTALL_FAILURE: "ADB_ADDON_INSTALL_FAILURE",
ADB_ADDON_UNINSTALL_START: "ADB_ADDON_UNINSTALL_START",
ADB_ADDON_UNINSTALL_SUCCESS: "ADB_ADDON_UNINSTALL_SUCCESS",
ADB_ADDON_UNINSTALL_FAILURE: "ADB_ADDON_UNINSTALL_FAILURE",
ADB_ADDON_STATUS_UPDATED: "ADB_ADDON_STATUS_UPDATED",
CONNECT_RUNTIME_FAILURE: "CONNECT_RUNTIME_FAILURE",
CONNECT_RUNTIME_START: "CONNECT_RUNTIME_START",
@ -70,6 +76,12 @@ const SERVICE_WORKER_STATUSES = {
STOPPED: "STOPPED",
};
const USB_STATES = {
DISABLED_USB: "DISABLED_USB",
ENABLED_USB: "ENABLED_USB",
UPDATING_USB: "UPDATING_USB",
};
// flatten constants
module.exports = Object.assign({}, {
DEBUG_TARGETS,
@ -78,4 +90,5 @@ module.exports = Object.assign({}, {
RUNTIMES,
SERVICE_WORKER_FETCH_STATES,
SERVICE_WORKER_STATUSES,
USB_STATES,
}, actionTypes);

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

@ -11,6 +11,8 @@ support-files =
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_aboutdebugging_connect_networklocations.js]
[browser_aboutdebugging_connect_toggle_usb_devices.js]
skip-if = (os == 'linux' && bits == 32) # ADB start() fails on linux 32, see Bug 1499638
[browser_aboutdebugging_debug-target-pane_collapsibilities_interaction.js]
[browser_aboutdebugging_debug-target-pane_collapsibilities_preference.js]
[browser_aboutdebugging_debug-target-pane_empty.js]

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

@ -13,17 +13,7 @@ const TEST_NETWORK_LOCATION = "localhost:1111";
add_task(async function() {
const { document, tab } = await openAboutDebugging();
const sidebarItems = document.querySelectorAll(".js-sidebar-item");
const connectSidebarItem = [...sidebarItems].find(element => {
return element.textContent === "Connect";
});
ok(connectSidebarItem, "Sidebar contains a Connect item");
info("Click on the Connect item in the sidebar");
connectSidebarItem.click();
info("Wait until Connect page is displayed");
await waitUntil(() => document.querySelector(".js-connect-page"));
await selectConnectPage(document);
let networkLocations = document.querySelectorAll(".js-network-location");
is(networkLocations.length, 0, "By default, no network locations are displayed");

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

@ -0,0 +1,55 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { ADB } = require("devtools/shared/adb/adb");
/**
* Check that USB Devices scanning can be enabled and disabled from the connect page.
*/
add_task(async function() {
await pushPref("devtools.remote.adb.extensionURL",
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi");
const { document, tab } = await openAboutDebugging();
await selectConnectPage(document);
info("Wait until Connect page is displayed");
await waitUntil(() => document.querySelector(".js-connect-page"));
info("Check that by default USB devices are disabled");
const usbDisabledMessage = document.querySelector(".js-connect-usb-disabled-message");
ok(usbDisabledMessage, "A message about enabling USB devices is rendered");
const usbToggleButton = document.querySelector(".js-connect-usb-toggle-button");
ok(usbToggleButton, "The button to toggle USB devices debugging is rendered");
ok(usbToggleButton.textContent.includes("Enable"),
"The text of the toggle USB button is correct");
info("Click on the toggle button");
usbToggleButton.click();
info("Wait until the toggle button text is updated");
await waitUntil(() => usbToggleButton.textContent.includes("Disable"));
ok(!document.querySelector(".js-connect-usb-disabled-message"),
"The message about enabling USB devices is no longer rendered");
// Right now we are resuming as soon as "USB devices enabled" is displayed, but ADB
// might still be starting up. If we move to uninstall directly, the ADB startup will
// fail and we will have an unhandled promise rejection.
// See Bug 1498469.
info("Wait until ADB has started.");
await waitUntil(() => ADB.ready);
info("Click on the toggle button");
usbToggleButton.click();
info("Wait until the toggle button text is updated");
await waitUntil(() => usbToggleButton.textContent.includes("Enable"));
ok(document.querySelector(".js-connect-usb-disabled-message"),
"The message about enabling USB devices is rendered again");
await removeTab(tab);
});

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

@ -11,17 +11,6 @@ const { ADB } = require("devtools/shared/adb/adb");
* devices scanning.
*/
add_task(async function() {
// Make sure the ADB addon is removed and ADB is stopped when the test ends.
registerCleanupFunction(async function() {
try {
await adbAddon.uninstall();
} catch (e) {
// Will throw if the addon is already uninstalled, ignore exceptions here.
}
await ADB.kill();
});
await pushPref("devtools.remote.adb.extensionURL",
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi");

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

@ -17,6 +17,18 @@ Services.scriptloader.loadSubScript(
Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "debug-target-pane_collapsibilities_head.js", this);
// Make sure the ADB addon is removed and ADB is stopped when the test ends.
registerCleanupFunction(async function() {
try {
const { adbAddon } = require("devtools/shared/adb/adb-addon");
await adbAddon.uninstall();
} catch (e) {
// Will throw if the addon is already uninstalled, ignore exceptions here.
}
const { ADB } = require("devtools/shared/adb/adb");
await ADB.kill();
});
/**
* Enable the new about:debugging panel.
*/
@ -42,6 +54,23 @@ async function openAboutDebugging(page, win) {
return { tab, document, window };
}
/**
* Navigate to the Connect page. Resolves when the Connect page is rendered.
*/
async function selectConnectPage(doc) {
const sidebarItems = doc.querySelectorAll(".js-sidebar-item");
const connectSidebarItem = [...sidebarItems].find(element => {
return element.textContent === "Connect";
});
ok(connectSidebarItem, "Sidebar contains a Connect item");
info("Click on the Connect item in the sidebar");
connectSidebarItem.click();
info("Wait until Connect page is displayed");
await waitUntil(() => doc.querySelector(".js-connect-page"));
}
function findSidebarItemByText(text, document) {
const sidebarItems = document.querySelectorAll(".js-sidebar-item");
return [...sidebarItems].find(element => {

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

@ -59,6 +59,11 @@ about-debugging-connect-wifi-step-enable-debug = Enable Remote Debugging via WiF
about-debugging-connect-usb
.title = Via USB
about-debugging-connect-usb-disabled = Enabling this will download and add the required Android USB debugging components to Firefox.
about-debugging-connect-usb-enable-button = Enable USB Devices
about-debugging-connect-usb-disable-button = Disable USB Devices
about-debugging-connect-usb-updating-button = Updating…
# USB section step by step guide
about-debugging-connect-usb-step-enable-dev-menu = Enable Developer menu on your Android device

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

@ -1,10 +0,0 @@
{
"manifest_version": 2,
"name": "test-devtools-webextension-nobg",
"version": "1.0",
"applications": {
"gecko": {
"id": "test-devtools-webextension-nobg@mozilla.org"
}
}
}

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

@ -1,5 +0,0 @@
{
"manifest_version": 2,
"name": "test-devtools-webextension-noid",
"version": "1.0"
}

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

@ -1,14 +0,0 @@
{
"manifest_version": 2,
"name": "test-devtools-webextension-unknown-prop",
"version": "1.0",
"applications": {
"gecko": {
"id": "test-devtools-webextension-unknown-prop@mozilla.org"
}
},
"browser_actions": {
"default_title": "WebExtension Popup Debugging",
"default_popup": "popup.html"
}
}

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

@ -1,23 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env browser */
/* global browser */
"use strict";
document.body.innerText = "Background Page Body Test Content";
// These functions are called from the following about:debugging tests:
// - browser_addons_debug_webextension.js
// - browser_addons_debug_webextension_popup.js
// eslint-disable-next-line no-unused-vars
function myWebExtensionAddonFunction() {
console.log("Background page function called", browser.runtime.getManifest());
}
// eslint-disable-next-line no-unused-vars
function myWebExtensionShowPopup() {
browser.test.sendMessage("readyForOpenPopup");
}

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

@ -1,17 +0,0 @@
{
"manifest_version": 2,
"name": "test-devtools-webextension",
"version": "1.0",
"applications": {
"gecko": {
"id": "test-devtools-webextension@mozilla.org"
}
},
"background": {
"scripts": ["bg.js"]
},
"browser_action": {
"default_title": "WebExtension Popup Debugging",
"default_popup": "popup.html"
}
}

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

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="popup.js"></script>
</head>
<body>
Background Page Body Test Content
</body>
</html>

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

@ -1,15 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env browser */
/* global browser */
"use strict";
// This function is called from the following about:debugging test:
// browser_addons_debug_webextension.js
//
// eslint-disable-next-line no-unused-vars
function myWebExtensionPopupAddonFunction() {
browser.test.sendMessage("popupPageFunctionCalled", browser.runtime.getManifest());
}

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

@ -39,15 +39,27 @@ add_task(async function testWebExtension() {
const { tab, document } = await openAboutDebugging("addons");
await waitForInitialAddonList(document);
const addonFile = ExtensionTestCommon.generateXPI({
manifest: {
name: addonName,
applications: {
gecko: {id: addonId},
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
await installAddon({
document,
path: "addons/test-devtools-webextension-nobg/manifest.json",
file: addonFile,
name: addonName,
isWebExtension: true
});
const container = document.querySelector(`[data-addon-id="${addonId}"]`);
testFilePath(container, "/test/addons/test-devtools-webextension-nobg/");
testFilePath(container, addonFile.leafName);
const extensionID = container.querySelector(".extension-id span");
ok(extensionID.textContent === "test-devtools-webextension-nobg@mozilla.org");
@ -68,9 +80,17 @@ add_task(async function testTemporaryWebExtension() {
const { tab, document } = await openAboutDebugging("addons");
await waitForInitialAddonList(document);
const addonFile = ExtensionTestCommon.generateXPI({
manifest: {
name: addonName,
},
});
registerCleanupFunction(() => addonFile.remove(false));
await installAddon({
document,
path: "addons/test-devtools-webextension-noid/manifest.json",
file: addonFile,
name: addonName,
isWebExtension: true
});
@ -98,9 +118,22 @@ add_task(async function testUnknownManifestProperty() {
const { tab, document } = await openAboutDebugging("addons");
await waitForInitialAddonList(document);
const addonFile = ExtensionTestCommon.generateXPI({
manifest: {
name: addonName,
applications: {
gecko: {id: addonId},
},
wrong_manifest_property_name: {
}
},
});
registerCleanupFunction(() => addonFile.remove(false));
await installAddon({
document,
path: "addons/test-devtools-webextension-unknown-prop/manifest.json",
file: addonFile,
name: addonName,
isWebExtension: true
});
@ -113,7 +146,7 @@ add_task(async function testUnknownManifestProperty() {
const messages = container.querySelectorAll(".addon-target-message");
ok(messages.length === 1, "there is one message");
ok(messages[0].textContent.match(/Error processing browser_actions/),
ok(messages[0].textContent.match(/Error processing wrong_manifest_property_name/),
"the message is helpful");
ok(messages[0].classList.contains("addon-target-warning-message"),
"the message is a warning");

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

@ -13,7 +13,6 @@ requestLongerTimeout(2);
const ADDON_ID = "test-devtools-webextension@mozilla.org";
const ADDON_NAME = "test-devtools-webextension";
const ADDON_MANIFEST_PATH = "addons/test-devtools-webextension/manifest.json";
const {
BrowserToolboxProcess
@ -25,9 +24,25 @@ const {
* has a working webconsole with the background page as default target;
*/
add_task(async function testWebExtensionsToolboxWebConsole() {
const addonFile = ExtensionTestCommon.generateXPI({
background: function() {
window.myWebExtensionAddonFunction = function() {
console.log("Background page function called",
this.browser.runtime.getManifest());
};
},
manifest: {
name: ADDON_NAME,
applications: {
gecko: {id: ADDON_ID},
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
const {
tab, document, debugBtn,
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, ADDON_MANIFEST_PATH);
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, addonFile);
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!

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

@ -12,7 +12,6 @@ requestLongerTimeout(2);
const ADDON_ID = "test-devtools-webextension@mozilla.org";
const ADDON_NAME = "test-devtools-webextension";
const ADDON_PATH = "addons/test-devtools-webextension/manifest.json";
const {
BrowserToolboxProcess
@ -24,9 +23,22 @@ const {
* background page as default target;
*/
add_task(async function testWebExtensionsToolboxInspector() {
const addonFile = ExtensionTestCommon.generateXPI({
background: function() {
document.body.innerText = "Background Page Body Test Content";
},
manifest: {
name: ADDON_NAME,
applications: {
gecko: {id: ADDON_ID},
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
const {
tab, document, debugBtn,
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, ADDON_PATH);
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, addonFile);
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!

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

@ -12,7 +12,6 @@ requestLongerTimeout(2);
const ADDON_NOBG_ID = "test-devtools-webextension-nobg@mozilla.org";
const ADDON_NOBG_NAME = "test-devtools-webextension-nobg";
const ADDON_NOBG_PATH = "addons/test-devtools-webextension-nobg/manifest.json";
const {
BrowserToolboxProcess
@ -26,9 +25,19 @@ const {
* webextension context);
*/
add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
const addonFile = ExtensionTestCommon.generateXPI({
manifest: {
name: ADDON_NOBG_NAME,
applications: {
gecko: {id: ADDON_NOBG_ID},
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
const {
tab, document, debugBtn,
} = await setupTestAboutDebuggingWebExtension(ADDON_NOBG_NAME, ADDON_NOBG_PATH);
} = await setupTestAboutDebuggingWebExtension(ADDON_NOBG_NAME, addonFile);
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!
@ -36,17 +45,14 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
.getService(Ci.nsIEnvironment);
const testScript = function() {
/* eslint-disable no-undef */
toolbox.selectTool("inspector")
.then(inspector => {
return inspector.walker.querySelector(inspector.walker.rootNode, "body");
})
.then((nodeActor) => {
toolbox.selectTool("inspector").then(async inspector => {
const nodeActor = await inspector.walker.querySelector(
inspector.walker.rootNode, "body");
if (!nodeActor) {
throw new Error("nodeActor not found");
}
dump("Got a nodeActor\n");
if (!(nodeActor.inlineTextChild)) {
throw new Error("inlineTextChild not found");
}
@ -63,10 +69,9 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
}
dump("Got the expected inline text content in the selected node\n");
return Promise.resolve();
})
.then(() => toolbox.destroy())
.catch((error) => {
await toolbox.destroy();
}).catch((error) => {
dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n");
dump("stack:\n" + error.stack + "\n");

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

@ -12,7 +12,6 @@ requestLongerTimeout(2);
const ADDON_ID = "test-devtools-webextension@mozilla.org";
const ADDON_NAME = "test-devtools-webextension";
const ADDON_MANIFEST_PATH = "addons/test-devtools-webextension/manifest.json";
const {
BrowserToolboxProcess
@ -42,6 +41,46 @@ function makeWidgetId(id) {
}
add_task(async function testWebExtensionsToolboxSwitchToPopup() {
const addonFile = ExtensionTestCommon.generateXPI({
background: function() {
const {browser} = this;
window.myWebExtensionShowPopup = function() {
browser.test.sendMessage("readyForOpenPopup");
};
},
manifest: {
name: ADDON_NAME,
applications: {
gecko: {id: ADDON_ID},
},
browser_action: {
default_title: "WebExtension Popup Debugging",
default_popup: "popup.html",
},
},
files: {
"popup.html": `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="popup.js"></script>
</head>
<body>
Background Page Body Test Content
</body>
</html>
`,
"popup.js": function() {
const {browser} = this;
window.myWebExtensionPopupAddonFunction = function() {
browser.test.sendMessage("popupPageFunctionCalled",
browser.runtime.getManifest());
};
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
let onReadyForOpenPopup;
let onPopupCustomMessage;
@ -81,7 +120,7 @@ add_task(async function testWebExtensionsToolboxSwitchToPopup() {
const {
tab, document, debugBtn,
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, ADDON_MANIFEST_PATH);
} = await setupTestAboutDebuggingWebExtension(ADDON_NAME, addonFile);
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!

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

@ -44,10 +44,20 @@ add_task(async function removeWebextension() {
const { tab, document } = await openAboutDebugging("addons");
await waitForInitialAddonList(document);
const addonFile = ExtensionTestCommon.generateXPI({
manifest: {
name: addonName,
applications: {
gecko: {id: addonID},
},
},
});
registerCleanupFunction(() => addonFile.remove(false));
// Install this add-on, and verify that it appears in the about:debugging UI
await installAddon({
document,
path: "addons/test-devtools-webextension/manifest.json",
file: addonFile,
name: addonName,
isWebExtension: true,
});

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

@ -14,6 +14,7 @@ Services.scriptloader.loadSubScript(
const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
const { Management } = ChromeUtils.import("resource://gre/modules/Extension.jsm", {});
const { ExtensionTestCommon } = ChromeUtils.import("resource://testing-common/ExtensionTestCommon.jsm", {});
async function openAboutDebugging(page, win) {
info("opening about:debugging");
@ -165,12 +166,16 @@ function getTabList(document) {
document.querySelector("#tabs.targets");
}
async function installAddon({document, path, name, isWebExtension}) {
async function installAddon({document, path, file, name, isWebExtension}) {
// Mock the file picker to select a test addon
const MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
const file = getSupportsFile(path);
if (path) {
file = getSupportsFile(path);
MockFilePicker.setFiles([file.file]);
} else {
MockFilePicker.setFiles([file]);
}
let onAddonInstalled;
@ -341,7 +346,7 @@ function waitForDelayedStartupFinished(win) {
/**
* open the about:debugging page and install an addon
*/
async function setupTestAboutDebuggingWebExtension(name, path) {
async function setupTestAboutDebuggingWebExtension(name, file) {
await new Promise(resolve => {
const options = {"set": [
// Force enabling of addons debugging
@ -360,7 +365,7 @@ async function setupTestAboutDebuggingWebExtension(name, path) {
await installAddon({
document,
path,
file,
name,
isWebExtension: true,
});

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

@ -479,8 +479,8 @@ Workers.prototype = {
this._updateWorkerList();
// `_targetFront` can be BrowsingContextTargetFront (protocol.js front) or
// WorkerClient/DebuggerClient (old fashion client)
// `_targetFront` can be BrowsingContextTargetFront/WorkerTargetFront (protocol.js
// front) or DebuggerClient (old fashion client)
if (typeof(this._targetFront.on) == "function") {
this._targetFront.on("workerListChanged", this._onWorkerListChanged);
} else {
@ -529,8 +529,8 @@ Workers.prototype = {
},
_onWorkerSelect: function (workerForm) {
DebuggerController.client.attachWorker(workerForm.actor).then(([response, workerClient]) => {
let toolbox = gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
DebuggerController.client.attachWorker(workerForm.actor).then(([response, workerTargetFront]) => {
let toolbox = gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
"jsdebugger", Toolbox.HostType.WINDOW);
window.emit(EVENTS.WORKER_SELECTED, toolbox);
});

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

@ -64,11 +64,11 @@ DebuggerPanel.prototype = {
},
openWorkerToolbox: async function(worker) {
const [response, workerClient] =
const [response, workerTargetFront] =
await this.toolbox.target.client.attachWorker(worker.actor);
const workerTarget = TargetFactory.forWorker(workerClient);
const workerTarget = TargetFactory.forWorker(workerTargetFront);
const toolbox = await gDevTools.showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW);
toolbox.once("destroy", () => workerClient.detach());
toolbox.once("destroy", () => workerTargetFront.detach());
},
getFrames: function() {

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

@ -41,8 +41,8 @@ function setupEvents(dependencies) {
});
if (threadClient._parent) {
// Parent may be BrowsingContextTargetFront and be protocol.js.
// Or DebuggerClient/WorkerClient and still be old fashion actor.
// Parent may be BrowsingContextTargetFront/WorkerTargetFront and be protocol.js.
// Or DebuggerClient and still be old fashion actor.
if (threadClient._parent.on) {
threadClient._parent.on("workerListChanged", workerListChanged);
} else {

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

@ -28,10 +28,10 @@ add_task(async function() {
await createWorkerInTab(tab, WORKER_URL);
let { workers } = await listWorkers(targetFront);
let [, workerClient] = await attachWorker(targetFront,
let [, workerTargetFront] = await attachWorker(targetFront,
findWorker(workers, WORKER_URL));
let toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
let toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
"jsdebugger",
Toolbox.HostType.WINDOW);
@ -55,7 +55,7 @@ add_task(async function() {
"Correct set of tools supported by worker");
terminateWorkerInTab(tab, WORKER_URL);
await waitForWorkerClose(workerClient);
await waitForWorkerClose(workerTargetFront);
await close(client);
await toolbox.destroy();

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

@ -1114,14 +1114,14 @@ function waitForWorkerListChanged(targetFront) {
return targetFront.once("workerListChanged");
}
function attachThread(workerClient, options) {
function attachThread(workerTargetFront, options) {
info("Attaching to thread.");
return workerClient.attachThread(options);
return workerTargetFront.attachThread(options);
}
async function waitForWorkerClose(workerClient) {
async function waitForWorkerClose(workerTargetFront) {
info("Waiting for worker to close.");
await workerClient.once("close");
await workerTargetFront.once("close");
info("Worker did close.");
}
@ -1288,15 +1288,15 @@ async function initWorkerDebugger(TAB_URL, WORKER_URL) {
await createWorkerInTab(tab, WORKER_URL);
let { workers } = await listWorkers(targetFront);
let [, workerClient] = await attachWorker(targetFront,
let [, workerTargetFront] = await attachWorker(targetFront,
findWorker(workers, WORKER_URL));
let toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
let toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
"jsdebugger",
Toolbox.HostType.WINDOW);
let debuggerPanel = toolbox.getCurrentPanel();
let gDebugger = debuggerPanel.panelWin;
return {client, tab, targetFront, workerClient, toolbox, gDebugger};
return {client, tab, targetFront, workerTargetFront, toolbox, gDebugger};
}

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

@ -375,10 +375,10 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
* worker actor form to debug
*/
async openWorkerToolbox(client, workerTargetActor) {
const [, workerClient] = await client.attachWorker(workerTargetActor);
const workerTarget = TargetFactory.forWorker(workerClient);
const [, workerTargetFront] = await client.attachWorker(workerTargetActor);
const workerTarget = TargetFactory.forWorker(workerTargetFront);
const toolbox = await gDevTools.showToolbox(workerTarget, null, Toolbox.HostType.WINDOW);
toolbox.once("destroy", () => workerClient.detach());
toolbox.once("destroy", () => workerTargetFront.detach());
},
/**

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

@ -120,11 +120,11 @@ const TargetFactory = exports.TargetFactory = {
return targetPromise;
},
forWorker: function(workerClient) {
let target = targets.get(workerClient);
forWorker: function(workerTargetFront) {
let target = targets.get(workerTargetFront);
if (target == null) {
target = new WorkerTarget(workerClient);
targets.set(workerClient, target);
target = new WorkerTarget(workerTargetFront);
targets.set(workerTargetFront, target);
}
return target;
},
@ -848,9 +848,9 @@ TabTarget.prototype = {
},
};
function WorkerTarget(workerClient) {
function WorkerTarget(workerTargetFront) {
EventEmitter.decorate(this);
this._workerClient = workerClient;
this._workerTargetFront = workerTargetFront;
}
/**
@ -858,9 +858,9 @@ function WorkerTarget(workerClient) {
* either a local or remote tab, WorkerTarget always represents a remote worker.
* Moreover, unlike TabTarget, which is constructed with a placeholder object
* for remote tabs (from which a TargetFront can then be lazily obtained),
* WorkerTarget is constructed with a WorkerClient directly.
* WorkerTarget is constructed with a WorkerTargetFront directly.
*
* WorkerClient is designed to mimic the interface of TargetFront as closely as
* WorkerTargetFront is designed to mimic the interface of TargetFront as closely as
* possible. This allows us to debug workers as if they were ordinary tabs,
* requiring only minimal changes to the rest of the frontend.
*/
@ -878,7 +878,7 @@ WorkerTarget.prototype = {
},
get url() {
return this._workerClient.url;
return this._workerTargetFront.url;
},
get isWorkerTarget() {
@ -887,12 +887,12 @@ WorkerTarget.prototype = {
get form() {
return {
consoleActor: this._workerClient.consoleActor
consoleActor: this._workerTargetFront.consoleActor
};
},
get activeTab() {
return this._workerClient;
return this._workerTargetFront;
},
get activeConsole() {
@ -900,7 +900,7 @@ WorkerTarget.prototype = {
},
get client() {
return this._workerClient.client;
return this._workerTargetFront.client;
},
get canRewind() {
@ -908,7 +908,7 @@ WorkerTarget.prototype = {
},
destroy: function() {
this._workerClient.detach();
this._workerTargetFront.detach();
},
hasActor: function(name) {

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

@ -28,16 +28,13 @@ const flags = require("devtools/shared/flags");
* @return {Object} the highlighterUtils public API
*/
exports.getHighlighterUtils = function(toolbox) {
if (!toolbox || !toolbox.target) {
if (!toolbox) {
throw new Error("Missing or invalid toolbox passed to getHighlighterUtils");
}
// Exported API properties will go here
const exported = {};
// The current toolbox target
let target = toolbox.target;
// Is the highlighter currently in pick mode
let isPicking = false;
@ -49,17 +46,7 @@ exports.getHighlighterUtils = function(toolbox) {
* Release this utils, nullifying the references to the toolbox
*/
exported.release = function() {
toolbox = target = null;
};
/**
* Does the target have the highlighter actor.
* The devtools must be backwards compatible with at least B2G 1.3 (28),
* which doesn't have the highlighter actor. This can be removed as soon as
* the minimal supported version becomes 1.4 (29)
*/
const isRemoteHighlightable = exported.isRemoteHighlightable = function() {
return target.client.traits.highlightable;
toolbox = null;
};
/**
@ -115,7 +102,6 @@ exports.getHighlighterUtils = function(toolbox) {
await toolbox.selectTool("inspector", "inspect_dom");
toolbox.on("select", cancelPicker);
if (isRemoteHighlightable()) {
toolbox.walker.on("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.on("picker-node-picked", onPickerNodePicked);
toolbox.walker.on("picker-node-previewed", onPickerNodePreviewed);
@ -123,14 +109,6 @@ exports.getHighlighterUtils = function(toolbox) {
await toolbox.highlighter.pick(doFocus);
toolbox.emit("picker-started");
} else {
// If the target doesn't have the highlighter actor, we can use the
// walker's pick method instead, knowing that it only responds when a node
// is picked (instead of emitting events)
toolbox.emit("picker-started");
const node = await toolbox.walker.pick();
onPickerNodePicked({node: node});
}
});
/**
@ -147,17 +125,11 @@ exports.getHighlighterUtils = function(toolbox) {
toolbox.pickerButton.isChecked = false;
if (isRemoteHighlightable()) {
await toolbox.highlighter.cancelPick();
toolbox.walker.off("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.off("picker-node-picked", onPickerNodePicked);
toolbox.walker.off("picker-node-previewed", onPickerNodePreviewed);
toolbox.walker.off("picker-node-canceled", onPickerNodeCanceled);
} else {
// If the target doesn't have the highlighter actor, use the walker's
// cancelPick method instead
await toolbox.walker.cancelPick();
}
toolbox.off("select", cancelPicker);
toolbox.emit("picker-stopped");
@ -221,13 +193,7 @@ exports.getHighlighterUtils = function(toolbox) {
}
isNodeFrontHighlighted = true;
if (isRemoteHighlightable()) {
await toolbox.highlighter.showBoxModel(nodeFront, options);
} else {
// If the target doesn't have the highlighter actor, revert to the
// walker's highlight method, which draws a simple outline
await toolbox.walker.highlight(nodeFront);
}
toolbox.emit("node-highlight", nodeFront);
});
@ -271,10 +237,7 @@ exports.getHighlighterUtils = function(toolbox) {
exported.unhighlight = async function(forceHide = false) {
forceHide = forceHide || !flags.testing;
// Note that if isRemoteHighlightable is true, there's no need to hide the
// highlighter as the walker uses setTimeout to hide it after some time
if (isNodeFrontHighlighted && forceHide && toolbox.highlighter &&
isRemoteHighlightable()) {
if (isNodeFrontHighlighted && forceHide && toolbox.highlighter) {
isNodeFrontHighlighted = false;
await toolbox.highlighter.hideBoxModel();
}

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

@ -2345,7 +2345,7 @@ Toolbox.prototype = {
await this.initInspector();
// Only enable frame highlighting when the top level document is targeted
if (this._supportsFrameHighlight && this.rootFrameSelected) {
if (this.rootFrameSelected) {
const frameActor = await this.walker.getNodeActorFromWindowID(frameId);
this.highlighterUtils.highlightNodeFront(frameActor);
}
@ -2680,18 +2680,11 @@ Toolbox.prototype = {
this._selection = new Selection(this._walker);
this._selection.on("new-node-front", this._onNewSelectedNodeFront);
if (this.highlighterUtils.isRemoteHighlightable()) {
this.walker.on("highlighter-ready", this._highlighterReady);
this.walker.on("highlighter-hide", this._highlighterHidden);
const autohide = !flags.testing;
this._highlighter = await this._inspector.getHighlighter(autohide);
}
if (!("_supportsFrameHighlight" in this)) {
// Only works with FF58+ targets
this._supportsFrameHighlight =
await this.target.actorHasMethod("domwalker", "getNodeActorFromWindowID");
}
}.bind(this))();
}
return this._initInspector;
@ -2769,14 +2762,6 @@ Toolbox.prototype = {
this._inspector.destroy();
if (this._highlighter) {
// Note that if the toolbox is closed, this will work fine, but will fail
// in case the browser is closed and will trigger a noSuchActor message.
// We ignore the promise that |_hideBoxModel| returns, since we should still
// proceed with the rest of destruction if it fails.
// FF42+ now does the cleanup from the actor.
if (!this.highlighter.traits.autoHideOnDestroy) {
this.highlighterUtils.unhighlight();
}
await this._highlighter.destroy();
}
if (this._selection) {

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

@ -4,6 +4,7 @@ subsuite = devtools
support-files =
doc_flexbox_simple.html
doc_flexbox_pseudos.html
doc_flexbox_text_nodes.html
head.js
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
@ -20,4 +21,6 @@ support-files =
[browser_flexbox_pseudo_elements_are_listed.js]
[browser_flexbox_sizing_info_exists.js]
[browser_flexbox_sizing_info_for_pseudos.js]
[browser_flexbox_sizing_info_for_text_nodes.js]
[browser_flexbox_sizing_info_has_correct_sections.js]
[browser_flexbox_text_nodes_are_listed.js]

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

@ -0,0 +1,38 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the flex item sizing UI also appears for text nodes.
const TEST_URI = URL_ROOT + "doc_flexbox_text_nodes.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
info("Select the first text node in the flex container");
const containerNode = await getNodeFront(".container", inspector);
const { nodes } = await inspector.walker.children(containerNode);
const firstTextNode = nodes[0];
const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing");
const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container");
await selectNode(firstTextNode, inspector);
const [flexSizingContainer] = await onFlexItemSizingRendered;
const [flexOutlineContainer] = await onFlexItemOutlineRendered;
ok(flexSizingContainer, "The flex sizing exists in the DOM");
ok(flexOutlineContainer, "The flex outline exists in the DOM");
info("Check that the various sizing sections are displayed");
const allSections = [...flexSizingContainer.querySelectorAll(".section")];
ok(allSections.length, "Sizing sections are displayed");
info("Check that the various parts of the outline are displayed");
const [basis, final] = [...flexOutlineContainer.querySelectorAll(
".flex-outline-basis, .flex-outline-final")];
ok(basis && final, "The final and basis parts of the outline exist");
});

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

@ -0,0 +1,27 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that text nodes that are flex items do appear in the list of items.
const TEST_URI = URL_ROOT + "doc_flexbox_text_nodes.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
// Select the flex container in the inspector.
const onItemsListRendered = waitForDOM(doc,
"#layout-flexbox-container .flex-item-list");
await selectNode(".container", inspector);
const [flexItemList] = await onItemsListRendered;
const items = [...flexItemList.querySelectorAll("li")];
is(items.length, 3, "There are 3 items displayed in the list");
is(items[0].textContent, "#text", "The first item is a text node");
is(items[2].textContent, "#text", "The third item is a text node");
});

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

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.container {
width: 400px;
display: flex;
}
.container div {
flex-basis: 100px;
flex-shrink: 0;
background: #f06;
align-self: stretch;
}
</style>
<div class="container">
A text node will be wrapped into an anonymous block container
<div></div>
Here is yet another text node
</div>

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

@ -268,7 +268,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
[browser_rules_strict-search-filter_02.js]
[browser_rules_strict-search-filter_03.js]
[browser_rules_style-editor-link.js]
skip-if = true # Bug 1309759
[browser_rules_url-click-opens-new-tab.js]
[browser_rules_urls-clickable.js]
[browser_rules_user-agent-styles.js]

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

@ -11,7 +11,6 @@ const STYLESHEET_DATA_URL_CONTENTS = ["#first {",
"}"].join("\n");
const STYLESHEET_DATA_URL =
`data:text/css,${encodeURIComponent(STYLESHEET_DATA_URL_CONTENTS)}`;
const STYLESHEET_DECODED_DATA_URL = `data:text/css,${STYLESHEET_DATA_URL_CONTENTS}`;
const EXTERNAL_STYLESHEET_FILE_NAME = "doc_style_editor_link.css";
const EXTERNAL_STYLESHEET_URL = URL_ROOT + EXTERNAL_STYLESHEET_FILE_NAME;
@ -55,28 +54,13 @@ add_task(async function() {
const {toolbox, inspector, view, testActor} = await openRuleView();
await selectNode("div", inspector);
await testInlineStyle(view);
testRuleViewLinkLabel(view);
await testFirstInlineStyleSheet(view, toolbox, testActor);
await testSecondInlineStyleSheet(view, toolbox, testActor);
await testExternalStyleSheet(view, toolbox, testActor);
await testDisabledStyleEditor(view, toolbox);
});
async function testInlineStyle(view) {
info("Testing inline style");
const onTab = waitForTab();
info("Clicking on the first link in the rule-view");
clickLinkByIndex(view, 0);
const tab = await onTab;
const tabURI = tab.linkedBrowser.documentURI.spec;
ok(tabURI.startsWith("view-source:"), "View source tab is open");
info("Closing tab");
gBrowser.removeTab(tab);
}
async function testFirstInlineStyleSheet(view, toolbox, testActor) {
info("Testing inline stylesheet");
@ -103,7 +87,6 @@ async function testSecondInlineStyleSheet(view, toolbox, testActor) {
await toolbox.selectTool("inspector");
info("Clicking on second inline stylesheet link");
testRuleViewLinkLabel(view);
clickLinkByIndex(view, 3);
const editor = await onSelected;
@ -123,7 +106,6 @@ async function testExternalStyleSheet(view, toolbox, testActor) {
await toolbox.selectTool("inspector");
info("Clicking on an external stylesheet link");
testRuleViewLinkLabel(view);
clickLinkByIndex(view, 1);
const editor = await onSelected;
@ -140,8 +122,8 @@ async function validateStyleEditorSheet(editor, expectedSheetIndex, testActor) {
const href = editor.styleSheet.href || editor.styleSheet.nodeHref;
const expectedHref = await testActor.eval(
`content.document.styleSheets[${expectedSheetIndex}].href ||
content.document.location.href`);
`document.styleSheets[${expectedSheetIndex}].href ||
document.location.href`);
is(href, expectedHref, "loaded stylesheet href matches document stylesheet");
}
@ -183,9 +165,9 @@ function testRuleViewLinkLabel(view) {
let value = labelElem.textContent;
let tooltipText = labelElem.getAttribute("title");
is(value, `${STYLESHEET_DATA_URL_CONTENTS}:1`,
is(value, encodeURIComponent(STYLESHEET_DATA_URL_CONTENTS) + ":1",
"Rule view data URL stylesheet display value matches contents");
is(tooltipText, `${STYLESHEET_DECODED_DATA_URL}:1`,
is(tooltipText, STYLESHEET_DATA_URL + ":1",
"Rule view data URL stylesheet tooltip text matches the full URI path");
info("Checking the external link label");

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

@ -283,7 +283,12 @@ RuleEditor.prototype = {
if (Tools.styleEditor.isTargetSupported(target)) {
gDevTools.showToolbox(target, "styleeditor").then(toolbox => {
const {url, line, column} = this._currentLocation;
if (!this.rule.sheet.href && this.rule.sheet.nodeHref) {
toolbox.getCurrentPanel().selectStyleSheet(this.rule.sheet, line, column);
} else {
toolbox.getCurrentPanel().selectStyleSheet(url, line, column);
}
});
}
},

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

@ -44,32 +44,32 @@ function test() {
// createWorker in the tab to be resolved.
yield createWorkerInTab(tab, WORKER1_URL);
let { workers } = yield listWorkers(targetFront);
let [, workerClient1] = yield attachWorker(targetFront,
let [, workerTargetFront1] = yield attachWorker(targetFront,
findWorker(workers, WORKER1_URL));
is(workerClient1.isClosed, false, "worker in tab 1 should not be closed");
is(workerTargetFront1.isClosed, false, "worker in tab 1 should not be closed");
executeSoon(() => {
BrowserTestUtils.loadURI(tab.linkedBrowser, TAB2_URL);
});
yield waitForWorkerClose(workerClient1);
is(workerClient1.isClosed, true, "worker in tab 1 should be closed");
yield waitForWorkerClose(workerTargetFront1);
is(workerTargetFront1.isClosed, true, "worker in tab 1 should be closed");
yield createWorkerInTab(tab, WORKER2_URL);
({ workers } = yield listWorkers(targetFront));
const [, workerClient2] = yield attachWorker(targetFront,
const [, workerTargetFront2] = yield attachWorker(targetFront,
findWorker(workers, WORKER2_URL));
is(workerClient2.isClosed, false, "worker in tab 2 should not be closed");
is(workerTargetFront2.isClosed, false, "worker in tab 2 should not be closed");
executeSoon(() => {
tab.linkedBrowser.goBack();
});
yield waitForWorkerClose(workerClient2);
is(workerClient2.isClosed, true, "worker in tab 2 should be closed");
yield waitForWorkerClose(workerTargetFront2);
is(workerTargetFront2.isClosed, true, "worker in tab 2 should be closed");
({ workers } = yield listWorkers(targetFront));
[, workerClient1] = yield attachWorker(targetFront,
[, workerTargetFront1] = yield attachWorker(targetFront,
findWorker(workers, WORKER1_URL));
is(workerClient1.isClosed, false, "worker in tab 1 should not be closed");
is(workerTargetFront1.isClosed, false, "worker in tab 1 should not be closed");
yield close(client);
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);

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

@ -18,7 +18,7 @@ var TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
add_task(async function testNormalExecution() {
const {client, tab, workerClient, toolbox} =
const {client, tab, workerTargetFront, toolbox} =
await initWorkerDebugger(TAB_URL, WORKER_URL);
const jsterm = await getSplitConsole(toolbox);
@ -27,8 +27,8 @@ add_task(async function testNormalExecution() {
"Evaluating the global's location works");
terminateWorkerInTab(tab, WORKER_URL);
await waitForWorkerClose(workerClient);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
await waitForWorkerClose(workerTargetFront);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerTargetFront));
await close(client);
await removeTab(tab);
});

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

@ -19,7 +19,7 @@ var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
add_task(async function testWhilePaused() {
const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
const {client, tab, workerClient, toolbox} = dbg;
const {client, tab, workerTargetFront, toolbox} = dbg;
// Execute some basic math to make sure evaluations are working.
const jsterm = await getSplitConsole(toolbox);
@ -55,8 +55,8 @@ add_task(async function testWhilePaused() {
await resume(dbg);
terminateWorkerInTab(tab, WORKER_URL);
await waitForWorkerClose(workerClient);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
await waitForWorkerClose(workerTargetFront);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerTargetFront));
await close(client);
await removeTab(tab);
});

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

@ -20,7 +20,7 @@ var WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
// Test to see if creating the pause from the console works.
add_task(async function testPausedByConsole() {
const dbg = await initWorkerDebugger(TAB_URL, WORKER_URL);
const {client, tab, workerClient, toolbox} = dbg;
const {client, tab, workerTargetFront, toolbox} = dbg;
const jsterm = await getSplitConsole(toolbox);
let executed = await jsterm.execute("10000+1");
@ -46,8 +46,8 @@ add_task(async function testPausedByConsole() {
"Text for message appeared correct");
terminateWorkerInTab(tab, WORKER_URL);
await waitForWorkerClose(workerClient);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
await waitForWorkerClose(workerTargetFront);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerTargetFront));
await close(client);
await removeTab(tab);
});

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

@ -27,7 +27,7 @@ const TAB_URL = EXAMPLE_URL + "doc_WorkerTargetActor.attachThread-tab.html";
const WORKER_URL = "code_WorkerTargetActor.attachThread-worker.js";
add_task(async function testPausedByConsole() {
const {client, tab, workerClient, toolbox} =
const {client, tab, workerTargetFront, toolbox} =
await initWorkerDebugger(TAB_URL, WORKER_URL);
info("Check Date objects can be used in the console");
@ -42,8 +42,8 @@ add_task(async function testPausedByConsole() {
"Text for message appeared correct");
terminateWorkerInTab(tab, WORKER_URL);
await waitForWorkerClose(workerClient);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
await waitForWorkerClose(workerTargetFront);
await gDevTools.closeToolbox(TargetFactory.forWorker(workerTargetFront));
await close(client);
await removeTab(tab);
});

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

@ -118,14 +118,14 @@ function attachWorker(targetFront, worker) {
return targetFront.attachWorker(worker.actor);
}
function attachThread(workerClient, options) {
function attachThread(workerTargetFront, options) {
info("Attaching to thread.");
return workerClient.attachThread(options);
return workerTargetFront.attachThread(options);
}
async function waitForWorkerClose(workerClient) {
async function waitForWorkerClose(workerTargetFront) {
info("Waiting for worker to close.");
await workerClient.once("close");
await workerTargetFront.once("close");
info("Worker did close.");
}
@ -164,10 +164,10 @@ async function initWorkerDebugger(TAB_URL, WORKER_URL) {
await createWorkerInTab(tab, WORKER_URL);
const { workers } = await listWorkers(targetFront);
const [, workerClient] = await attachWorker(targetFront,
const [, workerTargetFront] = await attachWorker(targetFront,
findWorker(workers, WORKER_URL));
const toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
const toolbox = await gDevTools.showToolbox(TargetFactory.forWorker(workerTargetFront),
"jsdebugger",
Toolbox.HostType.WINDOW);
@ -177,7 +177,7 @@ async function initWorkerDebugger(TAB_URL, WORKER_URL) {
const context = createDebuggerContext(toolbox);
return { ...context, client, tab, targetFront, workerClient, toolbox, gDebugger};
return { ...context, client, tab, targetFront, workerTargetFront, toolbox, gDebugger};
}
// Override addTab/removeTab as defined by shared-head, since these have

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

@ -113,9 +113,6 @@ exports.HighlighterActor = protocol.ActorClassWithSpec(highlighterSpec, {
form: function() {
return {
actor: this.actorID,
traits: {
autoHideOnDestroy: true
}
};
},

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

@ -315,6 +315,8 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
let currentNode = treeWalker.currentNode;
let displayType = this.walker.getNode(currentNode).displayType;
// If the node is an element, check first if it is itself a flex or a grid.
if (currentNode.nodeType === currentNode.ELEMENT_NODE) {
if (!displayType) {
return null;
}
@ -329,9 +331,13 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
(displayType == "inline-grid" || displayType == "grid")) {
return new GridActor(this, currentNode);
}
}
// Otherwise, check if this is a flex/grid item or the parent node is a flex/grid
// container.
// Note that text nodes that are children of flex/grid containers are wrapped in
// anonymous containers, so even if their displayType getter returns null we still
// want to walk up the chain to find their container.
while ((currentNode = treeWalker.parentNode())) {
if (!currentNode) {
break;

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

@ -116,9 +116,6 @@ RootActor.prototype = {
traits: {
sources: true,
// Whether the server-side highlighter actor exists and can be used to
// remotely highlight nodes (see server/actors/highlighters.js)
highlightable: true,
networkMonitor: true,
// Whether the storage inspector actor to inspect cookies, etc.
storageInspector: true,

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

@ -96,7 +96,6 @@ AddonTargetActor.prototype = {
consoleActor: this._consoleActor.actorID,
traits: {
highlightable: false,
networkMonitor: false,
},
};

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

@ -119,7 +119,6 @@ ContentProcessTargetActor.prototype = {
promisesActor: this._promisesActor.actorID,
traits: {
highlightable: false,
networkMonitor: false,
},
};

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

@ -25,7 +25,7 @@ const noop = () => {};
* is a front to the thread actor created in the server side, hiding the
* protocol details in a traditional JavaScript API.
*
* @param client DebuggerClient, WorkerClient or BrowsingContextFront
* @param client DebuggerClient, WorkerTargetFront or BrowsingContextFront
* The parent of the thread (tab for target-scoped debuggers,
* DebuggerClient for chrome debuggers).
* @param actor string

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

@ -1604,7 +1604,13 @@ var FrontClassWithSpec = function(actorSpec, frontProto) {
// Existing Fronts are relying on the initialize instead of constructor methods.
const cls = function() {
const instance = Object.create(cls.prototype);
instance.initialize.apply(instance, arguments);
const initializer = instance.initialize.apply(instance, arguments);
// Async Initialization
// return a promise that resolves with the instance if the initializer is async
if (initializer && typeof initializer.then === "function") {
return initializer.then(resolve => instance);
}
return instance;
};
cls.prototype = extend(Front.prototype, generateRequestMethods(actorSpec, frontProto));

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

@ -111,16 +111,16 @@ var _attachConsole = async function(
"worker actor\n");
return;
}
const [workerResponse, workerClient] =
const [workerResponse, workerTargetFront] =
await targetFront.attachWorker(workerTargetActor);
if (!workerClient || workerResponse.error) {
console.error("attachWorker failed. No worker client or " +
if (!workerTargetFront || workerResponse.error) {
console.error("attachWorker failed. No worker target front or " +
" error: " + workerResponse.error);
return;
}
await workerClient.attachThread({});
state.actor = workerClient.consoleActor;
state.dbgClient.attachConsole(workerClient.consoleActor, listeners)
await workerTargetFront.attachThread({});
state.actor = workerTargetFront.consoleActor;
state.dbgClient.attachConsole(workerTargetFront.consoleActor, listeners)
.then(_onAttachConsole.bind(null, state), _onAttachError.bind(null, state));
} else {
state.actor = tab.consoleActor;

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

@ -9,10 +9,33 @@
* dev tools.
*/
/**
* A flex container's main and cross axes are either horizontal or
* vertical, each with two possible directions.
*/
enum FlexPhysicalDirection {
"horizontal-lr",
"horizontal-rl",
"vertical-tb",
"vertical-bt",
};
[ChromeOnly]
interface Flex
{
sequence<FlexLine> getLines();
sequence<FlexLineValues> getLines();
/**
* The physical direction in which successive flex items are placed,
* within a flex line in this flex container.
*/
readonly attribute FlexPhysicalDirection mainAxisDirection;
/**
* The physical direction in which successive flex lines are placed
* in this flex container (if it is or were multi-line).
*/
readonly attribute FlexPhysicalDirection crossAxisDirection;
};
/**
@ -22,7 +45,7 @@ interface Flex
enum FlexLineGrowthState { "unchanged", "shrinking", "growing" };
[ChromeOnly]
interface FlexLine
interface FlexLineValues
{
readonly attribute FlexLineGrowthState growthState;
readonly attribute double crossStart;
@ -35,14 +58,14 @@ interface FlexLine
readonly attribute double lastBaselineOffset;
/**
* getItems() returns FlexItems only for the Elements in this Flex
* container -- ignoring struts and abs-pos Elements.
* getItems() returns FlexItemValues only for the Elements in
* this Flex container -- ignoring struts and abs-pos Elements.
*/
sequence<FlexItem> getItems();
sequence<FlexItemValues> getItems();
};
[ChromeOnly]
interface FlexItem
interface FlexItemValues
{
readonly attribute Node? node;
readonly attribute double mainBaseSize;

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

@ -10,6 +10,9 @@ with Files("**"):
with Files("ChannelWrapper.webidl"):
BUG_COMPONENT = ("WebExtensions", "Request Handling")
with Files("Flex.webidl"):
BUG_COMPONENT = ("Core", "CSS Parsing and Computation")
with Files("HeapSnapshot.webidl"):
BUG_COMPONENT = ("DevTools", "Memory")
@ -33,6 +36,7 @@ WEBIDL_FILES = [
'BrowsingContext.webidl',
'ChannelWrapper.webidl',
'DominatorTree.webidl',
'Flex.webidl',
'HeapSnapshot.webidl',
'InspectorUtils.webidl',
'IteratorResult.webidl',

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

@ -6,7 +6,7 @@
#include "Flex.h"
#include "FlexLine.h"
#include "FlexLineValues.h"
#include "mozilla/dom/FlexBinding.h"
#include "nsFlexContainerFrame.h"
@ -37,10 +37,13 @@ Flex::Flex(Element* aParent,
mLines.SetLength(containerInfo->mLines.Length());
uint32_t index = 0;
for (auto&& l : containerInfo->mLines) {
FlexLine* line = new FlexLine(this, &l);
FlexLineValues* line = new FlexLineValues(this, &l);
mLines.ElementAt(index) = line;
index++;
}
mMainAxisDirection = containerInfo->mMainAxisDirection;
mCrossAxisDirection = containerInfo->mCrossAxisDirection;
}
JSObject*
@ -50,10 +53,22 @@ Flex::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
}
void
Flex::GetLines(nsTArray<RefPtr<FlexLine>>& aResult)
Flex::GetLines(nsTArray<RefPtr<FlexLineValues>>& aResult)
{
aResult.AppendElements(mLines);
}
FlexPhysicalDirection
Flex::MainAxisDirection() const
{
return mMainAxisDirection;
}
FlexPhysicalDirection
Flex::CrossAxisDirection() const
{
return mCrossAxisDirection;
}
} // namespace dom
} // namespace mozilla

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

@ -8,6 +8,7 @@
#define mozilla_dom_Flex_h
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FlexBinding.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
@ -16,7 +17,7 @@ class nsFlexContainerFrame;
namespace mozilla {
namespace dom {
class FlexLine;
class FlexLineValues;
class Flex : public nsISupports
, public nsWrapperCache
@ -37,11 +38,15 @@ public:
return mParent;
}
void GetLines(nsTArray<RefPtr<FlexLine>>& aResult);
void GetLines(nsTArray<RefPtr<FlexLineValues>>& aResult);
FlexPhysicalDirection MainAxisDirection() const;
FlexPhysicalDirection CrossAxisDirection() const;
protected:
nsCOMPtr<Element> mParent;
nsTArray<RefPtr<FlexLine>> mLines;
nsTArray<RefPtr<FlexLineValues>> mLines;
FlexPhysicalDirection mMainAxisDirection;
FlexPhysicalDirection mCrossAxisDirection;
};
} // namespace dom

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

@ -4,7 +4,7 @@
* 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 "FlexItem.h"
#include "FlexItemValues.h"
#include "mozilla/dom/FlexBinding.h"
#include "nsFlexContainerFrame.h"
@ -12,10 +12,10 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FlexItem, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FlexItem)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FlexItem)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlexItem)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FlexItemValues, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FlexItemValues)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FlexItemValues)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlexItemValues)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
@ -38,7 +38,7 @@ ToPossiblyUnconstrainedPixels(nscoord aSize)
return nsPresContext::AppUnitsToDoubleCSSPixels(aSize);
}
FlexItem::FlexItem(FlexLine* aParent,
FlexItemValues::FlexItemValues(FlexLineValues* aParent,
const ComputedFlexItemInfo* aItem)
: mParent(aParent)
{
@ -63,49 +63,49 @@ FlexItem::FlexItem(FlexLine* aParent,
}
JSObject*
FlexItem::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
FlexItemValues::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return FlexItem_Binding::Wrap(aCx, this, aGivenProto);
return FlexItemValues_Binding::Wrap(aCx, this, aGivenProto);
}
nsINode*
FlexItem::GetNode() const
FlexItemValues::GetNode() const
{
return mNode;
}
double
FlexItem::MainBaseSize() const
FlexItemValues::MainBaseSize() const
{
return mMainBaseSize;
}
double
FlexItem::MainDeltaSize() const
FlexItemValues::MainDeltaSize() const
{
return mMainDeltaSize;
}
double
FlexItem::MainMinSize() const
FlexItemValues::MainMinSize() const
{
return mMainMinSize;
}
double
FlexItem::MainMaxSize() const
FlexItemValues::MainMaxSize() const
{
return mMainMaxSize;
}
double
FlexItem::CrossMinSize() const
FlexItemValues::CrossMinSize() const
{
return mCrossMinSize;
}
double
FlexItem::CrossMaxSize() const
FlexItemValues::CrossMaxSize() const
{
return mCrossMaxSize;
}

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

@ -4,8 +4,8 @@
* 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_FlexItem_h
#define mozilla_dom_FlexItem_h
#ifndef mozilla_dom_FlexItemValues_h
#define mozilla_dom_FlexItemValues_h
#include "mozilla/dom/FlexBinding.h"
#include "nsISupports.h"
@ -16,24 +16,24 @@ struct ComputedFlexItemInfo;
namespace mozilla {
namespace dom {
class FlexLine;
class FlexLineValues;
class FlexItem : public nsISupports
class FlexItemValues : public nsISupports
, public nsWrapperCache
{
public:
explicit FlexItem(FlexLine* aParent,
explicit FlexItemValues(FlexLineValues* aParent,
const ComputedFlexItemInfo* aItem);
protected:
virtual ~FlexItem() = default;
virtual ~FlexItemValues() = default;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlexItem)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlexItemValues)
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
FlexLine* GetParentObject()
FlexLineValues* GetParentObject()
{
return mParent;
}
@ -47,7 +47,7 @@ public:
double CrossMaxSize() const;
protected:
RefPtr<FlexLine> mParent;
RefPtr<FlexLineValues> mParent;
RefPtr<nsINode> mNode;
// These sizes are all CSS pixel units.
@ -62,4 +62,4 @@ protected:
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_FlexItem_h */
#endif /* mozilla_dom_FlexItemValues_h */

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

@ -4,24 +4,24 @@
* 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 "FlexLine.h"
#include "FlexLineValues.h"
#include "FlexItem.h"
#include "FlexItemValues.h"
#include "mozilla/dom/FlexBinding.h"
#include "nsFlexContainerFrame.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FlexLine, mParent, mItems)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FlexLine)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FlexLine)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlexLine)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FlexLineValues, mParent, mItems)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FlexLineValues)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FlexLineValues)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlexLineValues)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
FlexLine::FlexLine(Flex* aParent,
FlexLineValues::FlexLineValues(Flex* aParent,
const ComputedFlexLineInfo* aLine)
: mParent(aParent)
{
@ -56,50 +56,50 @@ FlexLine::FlexLine(Flex* aParent,
mItems.SetLength(aLine->mItems.Length());
uint32_t index = 0;
for (auto&& i : aLine->mItems) {
FlexItem* item = new FlexItem(this, &i);
FlexItemValues* item = new FlexItemValues(this, &i);
mItems.ElementAt(index) = item;
index++;
}
}
JSObject*
FlexLine::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
FlexLineValues::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return FlexLine_Binding::Wrap(aCx, this, aGivenProto);
return FlexLineValues_Binding::Wrap(aCx, this, aGivenProto);
}
FlexLineGrowthState
FlexLine::GrowthState() const
FlexLineValues::GrowthState() const
{
return mGrowthState;
}
double
FlexLine::CrossStart() const
FlexLineValues::CrossStart() const
{
return mCrossStart;
}
double
FlexLine::CrossSize() const
FlexLineValues::CrossSize() const
{
return mCrossSize;
}
double
FlexLine::FirstBaselineOffset() const
FlexLineValues::FirstBaselineOffset() const
{
return mFirstBaselineOffset;
}
double
FlexLine::LastBaselineOffset() const
FlexLineValues::LastBaselineOffset() const
{
return mLastBaselineOffset;
}
void
FlexLine::GetItems(nsTArray<RefPtr<FlexItem>>& aResult)
FlexLineValues::GetItems(nsTArray<RefPtr<FlexItemValues>>& aResult)
{
aResult.AppendElements(mItems);
}

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

@ -4,8 +4,8 @@
* 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_FlexLine_h
#define mozilla_dom_FlexLine_h
#ifndef mozilla_dom_FlexLineValues_h
#define mozilla_dom_FlexLineValues_h
#include "mozilla/dom/FlexBinding.h"
#include "nsISupports.h"
@ -17,21 +17,21 @@ namespace mozilla {
namespace dom {
class Flex;
class FlexItem;
class FlexItemValues;
class FlexLine : public nsISupports
class FlexLineValues : public nsISupports
, public nsWrapperCache
{
public:
explicit FlexLine(Flex* aParent,
explicit FlexLineValues(Flex* aParent,
const ComputedFlexLineInfo* aLine);
protected:
virtual ~FlexLine() = default;
virtual ~FlexLineValues() = default;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlexLine)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlexLineValues)
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
Flex* GetParentObject()
@ -45,7 +45,7 @@ public:
double FirstBaselineOffset() const;
double LastBaselineOffset() const;
void GetItems(nsTArray<RefPtr<FlexItem>>& aResult);
void GetItems(nsTArray<RefPtr<FlexItemValues>>& aResult);
protected:
RefPtr<Flex> mParent;
@ -56,10 +56,10 @@ protected:
double mFirstBaselineOffset;
double mLastBaselineOffset;
nsTArray<RefPtr<FlexItem>> mItems;
nsTArray<RefPtr<FlexItemValues>> mItems;
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_FlexLine_h */
#endif /* mozilla_dom_FlexLineValues_h */

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

@ -11,14 +11,14 @@ MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
EXPORTS.mozilla.dom += [
'Flex.h',
'FlexItem.h',
'FlexLine.h',
'FlexItemValues.h',
'FlexLineValues.h',
]
UNIFIED_SOURCES += [
'Flex.cpp',
'FlexItem.cpp',
'FlexLine.cpp',
'FlexItemValues.cpp',
'FlexLineValues.cpp',
]
LOCAL_INCLUDES += [

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

@ -1,2 +1,3 @@
[chrome/test_flex_axis_directions.html]
[chrome/test_flex_items.html]
[chrome/test_flex_lines.html]

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

@ -0,0 +1,204 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
f {
display: flex;
width: 400px;
height: 50px;
margin-bottom: 2px;
}
b {
background-color: gold;
width: 100px;
height: 15px;
}
b::after {
content: "B";
}
c {
background-color: yellow;
width: 100px;
height: 15px;
}
c::after {
content: "C";
}
d {
background-color: orange;
width: 100px;
height: 15px;
}
d::after {
content: "D";
}
.fdR {
flex-direction: row;
background-color: lightgrey;
}
.fdRR {
flex-direction: row-reverse;
background-color: lightgreen;
}
.fdC {
flex-direction: column;
background-color: lightblue;
}
.fdCR {
flex-direction: column-reverse;
background-color: lavender;
}
.wmHTB {
writing-mode: horizontal-tb;
}
.wmVLR {
writing-mode: vertical-lr;
}
.wmVRL {
writing-mode: vertical-rl;
}
.wmSLR {
writing-mode: sideways-lr;
}
.wmSRL {
writing-mode: sideways-rl;
}
.dLR {
direction: ltr;
}
.dRL {
direction: rtl;
}
</style>
<script>
"use strict";
SimpleTest.waitForExplicitFinish();
function testContainerMatchesExpectedValues(flex, values, flexIndex) {
is(flex.mainAxisDirection, values.m, "Flex index " + flexIndex + " should have expected mainAxisDirection.");
is(flex.crossAxisDirection, values.c, "Flex index " + flexIndex + " should have expected crossAxisDirection.");
}
function runTests() {
const expectedValues = [
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "vertical-tb", c: "horizontal-lr" },
{ m: "vertical-bt", c: "horizontal-lr" },
{ m: "vertical-tb", c: "horizontal-rl" },
{ m: "vertical-bt", c: "horizontal-rl" },
{ m: "vertical-bt", c: "horizontal-lr" },
{ m: "vertical-tb", c: "horizontal-lr" },
{ m: "vertical-tb", c: "horizontal-rl" },
{ m: "vertical-bt", c: "horizontal-rl" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "vertical-bt", c: "horizontal-lr" },
{ m: "vertical-tb", c: "horizontal-lr" },
{ m: "vertical-bt", c: "horizontal-rl" },
{ m: "vertical-tb", c: "horizontal-rl" },
{ m: "vertical-tb", c: "horizontal-lr" },
{ m: "vertical-bt", c: "horizontal-lr" },
{ m: "vertical-bt", c: "horizontal-rl" },
{ m: "vertical-tb", c: "horizontal-rl" },
{ m: "vertical-tb", c: "horizontal-lr" },
{ m: "vertical-tb", c: "horizontal-rl" },
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "horizontal-lr", c: "vertical-bt" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "horizontal-rl", c: "vertical-bt" },
{ m: "horizontal-lr", c: "vertical-bt" },
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "horizontal-rl", c: "vertical-bt" },
{ m: "vertical-bt", c: "horizontal-lr" },
{ m: "vertical-bt", c: "horizontal-rl" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "horizontal-rl", c: "vertical-bt" },
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "horizontal-lr", c: "vertical-bt" },
{ m: "horizontal-rl", c: "vertical-bt" },
{ m: "horizontal-rl", c: "vertical-tb" },
{ m: "horizontal-lr", c: "vertical-tb" },
{ m: "horizontal-lr", c: "vertical-bt" },
];
const children = document.body.children;
is(children.length, expectedValues.length, "Document should have expected number of flex containers.");
for (let i = 0; i < children.length; ++i) {
const flex = children.item(i).getAsFlexContainer();
ok(flex, "Document child index " + i + " should be a flex container.");
if (flex) {
const values = expectedValues[i];
testContainerMatchesExpectedValues(flex, values, i);
}
}
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<f class="fdR wmHTB dLR"><b></b><c></c><d></d></f>
<f class="fdR wmHTB dRL"><b></b><c></c><d></d></f>
<f class="fdR wmVLR dLR"><b></b><c></c><d></d></f>
<f class="fdR wmVLR dRL"><b></b><c></c><d></d></f>
<f class="fdR wmVRL dLR"><b></b><c></c><d></d></f>
<f class="fdR wmVRL dRL"><b></b><c></c><d></d></f>
<f class="fdR wmSLR dLR"><b></b><c></c><d></d></f>
<f class="fdR wmSLR dRL"><b></b><c></c><d></d></f>
<f class="fdR wmSRL dLR"><b></b><c></c><d></d></f>
<f class="fdR wmSRL dRL"><b></b><c></c><d></d></f>
<f class="fdRR wmHTB dLR"><b></b><c></c><d></d></f>
<f class="fdRR wmHTB dRL"><b></b><c></c><d></d></f>
<f class="fdRR wmVLR dLR"><b></b><c></c><d></d></f>
<f class="fdRR wmVLR dRL"><b></b><c></c><d></d></f>
<f class="fdRR wmVRL dLR"><b></b><c></c><d></d></f>
<f class="fdRR wmVRL dRL"><b></b><c></c><d></d></f>
<f class="fdRR wmSLR dLR"><b></b><c></c><d></d></f>
<f class="fdRR wmSLR dRL"><b></b><c></c><d></d></f>
<f class="fdRR wmSRL dLR"><b></b><c></c><d></d></f>
<f class="fdRR wmSRL dRL"><b></b><c></c><d></d></f>
<f class="fdC wmHTB dLR"><b></b><c></c><d></d></f>
<f class="fdC wmHTB dRL"><b></b><c></c><d></d></f>
<f class="fdC wmVLR dLR"><b></b><c></c><d></d></f>
<f class="fdC wmVLR dRL"><b></b><c></c><d></d></f>
<f class="fdC wmVRL dLR"><b></b><c></c><d></d></f>
<f class="fdC wmVRL dRL"><b></b><c></c><d></d></f>
<f class="fdC wmSLR dLR"><b></b><c></c><d></d></f>
<f class="fdC wmSLR dRL"><b></b><c></c><d></d></f>
<f class="fdC wmSRL dLR"><b></b><c></c><d></d></f>
<f class="fdC wmSRL dRL"><b></b><c></c><d></d></f>
<f class="fdCR wmHTB dLR"><b></b><c></c><d></d></f>
<f class="fdCR wmHTB dRL"><b></b><c></c><d></d></f>
<f class="fdCR wmVLR dLR"><b></b><c></c><d></d></f>
<f class="fdCR wmVLR dRL"><b></b><c></c><d></d></f>
<f class="fdCR wmVRL dLR"><b></b><c></c><d></d></f>
<f class="fdCR wmVRL dRL"><b></b><c></c><d></d></f>
<f class="fdCR wmSLR dLR"><b></b><c></c><d></d></f>
<f class="fdCR wmSLR dRL"><b></b><c></c><d></d></f>
<f class="fdCR wmSRL dLR"><b></b><c></c><d></d></f>
<f class="fdCR wmSRL dRL"><b></b><c></c><d></d></f>
</body>
</html>

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

@ -2715,7 +2715,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
INIT_MIRROR(mMediaPrincipalHandle, PRINCIPAL_HANDLE_NONE),
INIT_CANONICAL(mDuration, NullableTimeUnit()),
INIT_CANONICAL(mCurrentPosition, TimeUnit::Zero()),
INIT_CANONICAL(mIsAudioDataAudible, false)
INIT_CANONICAL(mIsAudioDataAudible, false),
mSetSinkRequestsCount(0)
{
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@ -3674,7 +3675,7 @@ MediaDecoderStateMachine::InvokeSetSink(RefPtr<AudioDeviceInfo> aSink)
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSink);
++mSetSinkRequestsCount;
Unused << ++mSetSinkRequestsCount;
return InvokeAsync(
OwnerThread(), this, __func__,
&MediaDecoderStateMachine::SetSink, aSink);

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

@ -103,9 +103,6 @@ with Files("FakePluginTagInit.webidl"):
with Files("FeaturePolicy.webidl"):
BUG_COMPONENT = ("Core", "DOM: Security")
with Files("Flex.webidl"):
BUG_COMPONENT = ("Core", "CSS Parsing and Computation")
with Files("FocusEvent.webidl"):
BUG_COMPONENT = ("Core", "DOM: Events")
@ -507,7 +504,6 @@ WEBIDL_FILES = [
'FileSystemDirectoryReader.webidl',
'FileSystemEntry.webidl',
'FileSystemFileEntry.webidl',
'Flex.webidl',
'FocusEvent.webidl',
'FontFace.webidl',
'FontFaceSet.webidl',

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

@ -398,7 +398,9 @@ skip-if(!xulRuntime.shell) script test262/built-ins/Atomics/wake/wake-all-on-loc
# https://bugzilla.mozilla.org/show_bug.cgi?id=1346081
skip script test262/intl402/NumberFormat/prototype/format/format-fraction-digits.js
skip script test262/intl402/NumberFormat/prototype/format/format-fraction-digits-precision.js
skip script test262/intl402/NumberFormat/prototype/format/format-significant-digits.js
skip script test262/intl402/NumberFormat/prototype/format/format-significant-digits-precision.js
# Hoisted block-level function named "arguments" not initialized with undefined per B.3.3.1
# https://bugzilla.mozilla.org/show_bug.cgi?id=1339123
@ -408,6 +410,12 @@ skip script test262/annexB/language/function-code/block-decl-func-skip-arguments
skip script test262/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order.js
skip script test262/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1495072
skip script test262/language/expressions/await/await-monkey-patched-promise.js
skip script test262/language/expressions/await/async-await-interleaved.js
skip script test262/language/expressions/await/for-await-of-interleaved.js
skip script test262/language/expressions/await/async-generator-interleaved.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1321616
skip script test262/annexB/built-ins/Function/createdynfn-html-close-comment-params.js
@ -450,6 +458,11 @@ skip script test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-shor
# https://bugzilla.mozilla.org/show_bug.cgi?id=1483548
skip script test262/intl402/RelativeTimeFormat/prototype/format/value-non-finite.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1499933
skip script test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js
skip script test262/intl402/PluralRules/prototype/resolvedOptions/order.js
skip script test262/intl402/NumberFormat/prototype/resolvedOptions/order.js
###########################################################
# Tests disabled due to issues in test262 importer script #

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

@ -21,7 +21,12 @@ from itertools import chain
UNSUPPORTED_FEATURES = set([
"tail-call-optimization",
"class-fields-public",
"class-static-fields-public",
"class-fields-private",
"class-static-fields-private",
"class-methods-private",
"class-static-methods-private",
"dynamic-import",
"regexp-dotall",
"regexp-lookbehind",
"regexp-named-groups",
@ -37,6 +42,8 @@ FEATURE_CHECK_NEEDED = {
"Atomics": "!this.hasOwnProperty('Atomics')",
"BigInt": "!this.hasOwnProperty('BigInt')",
"SharedArrayBuffer": "!this.hasOwnProperty('SharedArrayBuffer')",
"Intl.ListFormat": "!Intl.hasOwnProperty('ListFormat')",
"Intl.Segmenter": "!Intl.hasOwnProperty('Segmenter')",
}
RELEASE_OR_BETA = set()

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

@ -1,7 +1,36 @@
commit ab436c465106be86719c4849c9cedecd7b570ff9
Author: Leo Balter <leonardo.balter@gmail.com>
Date: Fri Aug 17 18:06:19 2018 -0400
commit b98c45ca5a46966bce1ac691d5f608beb36d5db7
Author: Maya Lekova <apokalyptra@gmail.com>
Date: Wed Oct 17 22:10:09 2018 +0200
Merge pull request #1677 from tc39/ofe-use-verifyproperty
AsyncFunction: Add tests ensuring the new 1-tick await behaviour (#1843)
Object.fromEntries: use verifyProperty; add specification details
* AsyncFunction: Add tests ensuring the new 1-tick await behaviour
This commit adds 3 tests ensuring the optimized behaviour of await
(see https://github.com/tc39/ecma262/pull/1250) in the following cases:
- async functions
- yielding from async generator functions
- for-await-of loops
* AsyncFunction: Add tests ensuring the monkey-patched promises behaviour
This commit adds 2 more tests ensuring the optimized behaviour of await
(see tc39/ecma262#1250) in the following cases:
- awaiting on a native promise with monkey-patched "then"
- awaiting on a non-native promise (a "thenable" object)
* AsyncFunction: Add tests ensuring the non-native promises behaviour
This commit adds 1 more tests ensuring the optimized behaviour of await
(see tc39/ecma262#1250) in the following cases:
- awaiting on a non-promise, non-thenable object
It also renames the previous test for non-promise (a "thenable" object)
to distinguish from the new case.
The commit adds checks for proper await/promises interleaving in the
aforementioned cases and includes a small code clean-up.
* AsyncFunction: Refactor tests ensuring the new 1-tick await behaviour
Gather all the tests to their appropriate folder and update copyright header.

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

@ -16,18 +16,18 @@ var a = getArgumentsObject([1], [2]);
var actual = [].flat.call(a);
assert.compareArray(actual, [1, 2], 'arguments objects');
var a = {
a = {
length: 1,
0: [1],
};
var actual = [].flat.call(a);
actual = [].flat.call(a);
assert.compareArray(actual, [1], 'array-like objects');
var a = {
a = {
length: undefined,
0: [1],
};
var actual = [].flat.call(a);
actual = [].flat.call(a);
assert.compareArray(actual, [], 'array-like objects; undefined length');
reportCompare(0, 0);

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

@ -14,8 +14,10 @@ assert.sameValue(
'The value of `Array.prototype.flat.length` is `0`'
);
verifyNotEnumerable(Array.prototype.flat, 'length');
verifyNotWritable(Array.prototype.flat, 'length');
verifyConfigurable(Array.prototype.flat, 'length');
verifyProperty(Array.prototype.flat, 'length', {
enumerable: false,
writable: false,
configurable: true,
});
reportCompare(0, 0);

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

@ -15,8 +15,10 @@ assert.sameValue(
'The value of `Array.prototype.flat.name` is `"flat"`'
);
verifyNotEnumerable(Array.prototype.flat, 'name');
verifyNotWritable(Array.prototype.flat, 'name');
verifyConfigurable(Array.prototype.flat, 'name');
verifyProperty(Array.prototype.flat, 'name', {
enumerable: false,
writable: false,
configurable: true,
});
reportCompare(0, 0);

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

@ -17,29 +17,29 @@ var actual = a.flat(depthNum);
assert(compareArray(actual, expected), 'non integral string depthNum');
// object type depthNum is converted to 0
var depthNum = {};
var actual = a.flat(depthNum);
depthNum = {};
actual = a.flat(depthNum);
assert(compareArray(actual, expected), 'object type depthNum');
// negative infinity depthNum is converted to 0
var depthNum = Number.NEGATIVE_INFINITY;
var actual = a.flat(depthNum);
depthNum = Number.NEGATIVE_INFINITY;
actual = a.flat(depthNum);
assert(compareArray(actual, expected), 'negative infinity depthNum');
// positive zero depthNum is converted to 0
var depthNum = +0;
var actual = a.flat(depthNum);
depthNum = +0;
actual = a.flat(depthNum);
assert(compareArray(actual, expected), 'positive zero depthNum');
// negative zero depthNum is converted to 0
var depthNum = -0;
var actual = a.flat(depthNum);
depthNum = -0;
actual = a.flat(depthNum);
assert(compareArray(actual, expected), 'negative zero depthNum');
// integral string depthNum is converted to an integer
var depthNum = '1';
var actual = a.flat(depthNum);
var expected = [1, 2]
depthNum = '1';
actual = a.flat(depthNum);
expected = [1, 2]
assert(compareArray(actual, expected), 'integral string depthNum');
reportCompare(0, 0);

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

@ -14,19 +14,19 @@ assert.throws(TypeError, function() {
a.flat();
}, 'null value');
var a = [];
a = [];
a.constructor = 1;
assert.throws(TypeError, function() {
a.flat();
}, 'number value');
var a = [];
a = [];
a.constructor = 'string';
assert.throws(TypeError, function() {
a.flat();
}, 'string value');
var a = [];
a = [];
a.constructor = true;
assert.throws(TypeError, function() {
a.flat();

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

@ -2,7 +2,6 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-array.prototype.flat
es6id: 22.1.3
description: Property type and descriptor.
info: >
17 ECMAScript Standard Built-in Objects
@ -16,8 +15,10 @@ assert.sameValue(
'`typeof Array.prototype.flat` is `function`'
);
verifyNotEnumerable(Array.prototype, 'flat');
verifyWritable(Array.prototype, 'flat');
verifyConfigurable(Array.prototype, 'flat');
verifyProperty(Array.prototype, 'flat', {
enumerable: false,
writable: true,
configurable: true,
});
reportCompare(0, 0);

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

@ -0,0 +1,38 @@
// Copyright (C) 2018 Richard Lawrence. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-array.prototype.flat
description: >
properties are accessed correct number of times by .flat
info: |
Array.prototype.flat( [ depth ] )
...
6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
FlattenIntoArray (target, source, sourceLen, start, depth [ , mapperFunction, thisArg ])
3. Repeat, while sourceIndex < sourceLen
a. Let P be ! ToString(sourceIndex).
b. Let exists be ? HasProperty(source, P).
c. If exists is true, then
i. Let element be ? Get(source, P).
features: [Array.prototype.flat]
includes: [compareArray.js]
---*/
const getCalls = [], hasCalls = [];
const handler = {
get : function (t, p, r) { getCalls.push(p); return Reflect.get(t, p, r); },
has : function (t, p, r) { hasCalls.push(p); return Reflect.has(t, p, r); }
}
const tier2 = new Proxy([4, 3], handler);
const tier1 = new Proxy([2, [3, [4, 2], 2], 5, tier2, 6], handler);
Array.prototype.flat.call(tier1, 3);
assert.compareArray(getCalls, ["length", "constructor", "0", "1", "2", "3", "length", "0", "1", "4"], 'getProperty by .flat should occur exactly once per property and once for length and constructor');
assert.compareArray(hasCalls, ["0", "1", "2", "3", "0", "1", "4"], 'hasProperty by .flat should occur exactly once per property');
reportCompare(0, 0);

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

@ -20,18 +20,18 @@ var a = getArgumentsObject(1, 2);
var actual = [].flatMap.call(a, double);
assert.compareArray(actual, [2, 4], 'arguments objects');
var a = {
a = {
length: 1,
0: 1,
};
var actual = [].flatMap.call(a, double);
actual = [].flatMap.call(a, double);
assert.compareArray(actual, [2], 'array-like objects');
var a = {
a = {
length: void 0,
0: 1,
};
var actual = [].flatMap.call(a, double);
actual = [].flatMap.call(a, double);
assert.compareArray(actual, [], 'array-like objects; undefined length');
reportCompare(0, 0);

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

@ -14,8 +14,10 @@ assert.sameValue(
'The value of `Array.prototype.flatmap.length` is `1`'
);
verifyNotEnumerable(Array.prototype.flatMap, 'length');
verifyNotWritable(Array.prototype.flatMap, 'length');
verifyConfigurable(Array.prototype.flatMap, 'length');
verifyProperty(Array.prototype.flatMap, 'length', {
enumerable: false,
writable: false,
configurable: true,
});
reportCompare(0, 0);

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

@ -14,8 +14,10 @@ assert.sameValue(
'The value of `Array.prototype.flatMap.name` is `"flatMap"`'
);
verifyNotEnumerable(Array.prototype.flatMap, 'name');
verifyNotWritable(Array.prototype.flatMap, 'name');
verifyConfigurable(Array.prototype.flatMap, 'name');
verifyProperty(Array.prototype.flatMap, 'name', {
enumerable: false,
writable: false,
configurable: true,
});
reportCompare(0, 0);

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

@ -14,19 +14,19 @@ assert.throws(TypeError, function() {
a.flatMap();
}, 'null value');
var a = [];
a = [];
a.constructor = 1;
assert.throws(TypeError, function() {
a.flatMap();
}, 'number value');
var a = [];
a = [];
a.constructor = 'string';
assert.throws(TypeError, function() {
a.flatMap();
}, 'string value');
var a = [];
a = [];
a.constructor = true;
assert.throws(TypeError, function() {
a.flatMap();

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

@ -0,0 +1,29 @@
// Copyright (C) 2018 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-array.prototype.flatMap
description: Property type and descriptor.
info: >
17 ECMAScript Standard Built-in Objects
Every other data property described in clauses 18 through 26 and in Annex B.2
has the attributes { [[Writable]]: true, [[Enumerable]]: false,
[[Configurable]]: true } unless otherwise specified.
includes: [propertyHelper.js]
features: [Array.prototype.flatMap]
---*/
assert.sameValue(
typeof Array.prototype.flatMap,
'function',
'`typeof Array.prototype.flatMap` is `function`'
);
verifyProperty(Array.prototype, 'flatMap', {
enumerable: false,
writable: true,
configurable: true,
});
reportCompare(0, 0);

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

@ -0,0 +1,38 @@
// Copyright (C) 2018 Richard Lawrence. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-array.prototype.flatMap
description: >
properties are accessed correct number of times by .flatMap
info: |
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
...
6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T).
FlattenIntoArray (target, source, sourceLen, start, depth [ , mapperFunction, thisArg ])
3. Repeat, while sourceIndex < sourceLen
a. Let P be ! ToString(sourceIndex).
b. Let exists be ? HasProperty(source, P).
c. If exists is true, then
i. Let element be ? Get(source, P).
features: [Array.prototype.flat]
includes: [compareArray.js]
---*/
const getCalls = [], hasCalls = [];
const handler = {
get : function (t, p, r) { getCalls.push(p); return Reflect.get(t, p, r); },
has : function (t, p, r) { hasCalls.push(p); return Reflect.has(t, p, r); }
}
const tier2 = new Proxy([4, 3], handler);
const tier1 = new Proxy([2, [3, 4, 2, 2], 5, tier2, 6], handler);
Array.prototype.flatMap.call(tier1, function(a){ return a; });
assert.compareArray(getCalls, ["length", "constructor", "0", "1", "2", "3", "length", "0", "1", "4"], 'getProperty by .flatMap should occur exactly once per property and once for length and constructor');
assert.compareArray(hasCalls, ["0", "1", "2", "3", "0", "1", "4"], 'hasProperty by .flatMap should occur exactly once per property');
reportCompare(0, 0);

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

@ -6,13 +6,6 @@ description: >
Collection of functions used to interact with Atomics.* operations across agent boundaries.
---*/
/**
* The amount of slack allowed for testing time-related Atomics methods (i.e. wait and notify).
* The absolute value of the difference of the observed time and the expected time must
* be epsilon-close.
*/
$262.agent.MAX_TIME_EPSILON = 100;
/**
* @return {String} A report sent from an agent.
*/

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

@ -68,7 +68,7 @@ assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "
// Notify again at index 0, default => 0.
var woken = 0;
while ((woken = Atomics.notify(i32a, /*, default values used */)) === 0) ;
while ((woken = Atomics.notify(i32a /*, default values used */)) === 0) ;
assert.sameValue(woken, 1, 'Atomics.notify(i32a /*, default values used */) returns 1');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');

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

@ -36,16 +36,13 @@ $262.agent.start(`
const i64a = new BigInt64Array(sab);
Atomics.add(i64a, ${RUNNING}, 1n);
const before = $262.agent.monotonicNow();
const status1 = Atomics.wait(i64a, 0, 0n, false);
const status2 = Atomics.wait(i64a, 0, 0n, valueOf);
const status3 = Atomics.wait(i64a, 0, 0n, toPrimitive);
const duration = $262.agent.monotonicNow() - before;
$262.agent.report(status1);
$262.agent.report(status2);
$262.agent.report(status3);
$262.agent.report(duration);
$262.agent.leaving();
});
`);
@ -76,12 +73,6 @@ assert.sameValue(
'$262.agent.getReport() returns "timed-out"'
);
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'The result of `(lapse >= 0)` is true (timeout should be a min of 0ms)');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'The result of `(lapse <= $262.agent.MAX_TIME_EPSILON)` is true');
assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0');
reportCompare(0, 0);

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

@ -36,16 +36,13 @@ $262.agent.start(`
const i32a = new Int32Array(sab);
Atomics.add(i32a, ${RUNNING}, 1);
const before = $262.agent.monotonicNow();
const status1 = Atomics.wait(i32a, 0, 0, false);
const status2 = Atomics.wait(i32a, 0, 0, valueOf);
const status3 = Atomics.wait(i32a, 0, 0, toPrimitive);
const duration = $262.agent.monotonicNow() - before;
$262.agent.report(status1);
$262.agent.report(status2);
$262.agent.report(status3);
$262.agent.report(duration);
$262.agent.leaving();
});
`);
@ -76,12 +73,6 @@ assert.sameValue(
'$262.agent.getReport() returns "timed-out"'
);
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'The result of `(lapse >= 0)` is true (timeout should be a min of 0ms)');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'The result of `(lapse <= $262.agent.MAX_TIME_EPSILON)` is true');
assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
reportCompare(0, 0);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше