Merge mozilla-central to mozilla-inboud

--HG--
rename : security/certverifier/TrustOverride-AppleGoogleData.inc => security/certverifier/TrustOverride-AppleGoogleDigiCertData.inc
rename : security/manager/tools/crtshToDNStruct/crtshToDNStruct.py => security/manager/tools/crtshToIdentifyingStruct/crtshToIdentifyingStruct.py
rename : security/manager/tools/crtshToDNStruct/requirements.txt => security/manager/tools/crtshToIdentifyingStruct/requirements.txt
extra : rebase_source : 6bcbd2a80706f4f4b36bbb1e53c260ea495babf8
This commit is contained in:
Dorel Luca 2018-02-22 12:10:42 +02:00
commit ce3c40d6ba
241 changed files with 3705 additions and 2594 deletions

View File

@ -24,7 +24,6 @@ gfx/tests/chrome/**
gfx/tests/mochitest/**
gfx/tests/unit/**
image/**
intl/**
layout/**
memory/replace/dmd/test/**
modules/**
@ -303,6 +302,12 @@ dom/media/webvtt/**
gfx/ots/**
gfx/skia/**
# intl/ exclusions
intl/icu/**
intl/locale/**
intl/strres/**
intl/uconv/**
# Exclude everything but self-hosted JS
js/ductwork/**
js/examples/**

View File

@ -8009,7 +8009,9 @@ var gIdentityHandler = {
nameLabel.setAttribute("class", "identity-popup-permission-label");
nameLabel.textContent = SitePermissions.getPermissionLabel(aPermission.id);
if (aPermission.id == "popup") {
let isPolicyPermission = aPermission.scope == SitePermissions.SCOPE_POLICY;
if (aPermission.id == "popup" && !isPolicyPermission) {
let menulist = document.createElement("menulist");
let menupopup = document.createElement("menupopup");
let block = document.createElement("vbox");
@ -8064,6 +8066,17 @@ var gIdentityHandler = {
}
stateLabel.textContent = SitePermissions.getCurrentStateLabel(state, scope);
container.appendChild(img);
container.appendChild(nameLabel);
container.appendChild(stateLabel);
/* We return the permission item here without a remove button if the permission is a
SCOPE_POLICY permission. Policy permissions cannot be removed/changed for the duration
of the browser session. */
if (isPolicyPermission) {
return container;
}
let button = document.createElement("button");
button.setAttribute("class", "identity-popup-permission-remove-button");
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
@ -8128,9 +8141,6 @@ var gIdentityHandler = {
histogram.add(aPermission.id, permissionType);
});
container.appendChild(img);
container.appendChild(nameLabel);
container.appendChild(stateLabel);
container.appendChild(button);
return container;

View File

@ -69,7 +69,7 @@ function initRow(aPartId) {
var checkbox = document.getElementById(aPartId + "Def");
var command = document.getElementById("cmd_" + aPartId + "Toggle");
var {state} = SitePermissions.get(gPermURI, aPartId);
var {state, scope} = SitePermissions.get(gPermURI, aPartId);
let defaultState = SitePermissions.getDefault(aPartId);
if (state != defaultState) {
@ -79,6 +79,12 @@ function initRow(aPartId) {
checkbox.checked = true;
command.setAttribute("disabled", "true");
}
if (scope == SitePermissions.SCOPE_POLICY) {
checkbox.setAttribute("disabled", "true");
command.setAttribute("disabled", "true");
}
setRadioState(aPartId, state);
}

View File

@ -224,3 +224,45 @@ add_task(async function testPermissionShortcuts() {
SitePermissions.remove(gBrowser.currentURI, "shortcuts");
});
});
// Test the control center UI when policy permissions are set.
add_task(async function testPolicyPermission() {
await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function() {
await SpecialPowers.pushPrefEnv({set: [
["dom.disable_open_during_load", true],
]});
let permissionsList = document.getElementById("identity-popup-permission-list");
SitePermissions.set(gBrowser.currentURI, "popup", SitePermissions.ALLOW, SitePermissions.SCOPE_POLICY);
await openIdentityPopup();
// Check if the icon, nameLabel and stateLabel are visible.
let img, labelText, labels;
img = permissionsList.querySelector("image.identity-popup-permission-icon");
ok(img, "There is an image for the popup permission");
ok(img.classList.contains("popup-icon"), "proper class is in image class");
labelText = SitePermissions.getPermissionLabel("popup");
labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
is(labels.length, 1, "One permission visible in main view");
is(labels[0].textContent, labelText, "Correct name label value");
labelText = SitePermissions.getCurrentStateLabel(SitePermissions.ALLOW, SitePermissions.SCOPE_POLICY);
labels = permissionsList.querySelectorAll(".identity-popup-permission-state-label");
is(labels[0].textContent, labelText, "Correct state label value");
// Check if the menulist and the remove button are hidden.
// The menulist is specific to the "popup" permission.
let menulist = document.getElementById("identity-popup-popup-menulist");
ok(menulist == null, "The popup permission menulist is not visible");
let removeButton = permissionsList.querySelector(".identity-popup-permission-remove-button");
ok(removeButton == null, "The permission remove button is not visible");
Services.perms.removeAll();
await closeIdentityPopup();
});
});

View File

@ -27,7 +27,6 @@ support-files =
file_inspectedwindow_reload_target.sjs
file_indexedDB.html
file_serviceWorker.html
locale/chrome.manifest
webNav_createdTarget.html
webNav_createdTargetSource.html
webNav_createdTargetSource_subframe.html

View File

@ -7,14 +7,17 @@
/* import-globals-from head.js */
{
const chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
// At the moment extension language negotiation is tied to Firefox language
// negotiation result. That means that to test an extension in `es-ES`, we need
// to mock `es-ES` being available in Firefox and then request it.
//
// In the future, we should provide some way for tests to decouple their
// language selection from that of Firefox.
const avLocales = Services.locale.getAvailableLocales();
let localeDir = new URL("locale/", gTestPath).href;
let {file} = chromeRegistry.convertChromeURL(Services.io.newURI(localeDir)).QueryInterface(Ci.nsIFileURL);
Components.manager.addBootstrappedManifestLocation(file);
Services.locale.setAvailableLocales(["en-US", "es-ES"]);
registerCleanupFunction(() => {
Components.manager.removeBootstrappedManifestLocation(file);
Services.locale.setAvailableLocales(avLocales);
});
}

View File

@ -1 +0,0 @@
locale global es-ES resource://gre/chrome/en-US/locale/en-US/global/

View File

@ -716,15 +716,9 @@ BrowserGlue.prototype = {
// Initialize the default l10n resource sources for L10nRegistry.
const multilocalePath = "resource://gre/res/multilocale.json";
L10nRegistry.bootstrap = fetch(multilocalePath).then(d => d.json()).then(({ locales }) => {
const toolkitSource = new FileSource("toolkit", locales, "resource://gre/localization/{locale}/");
L10nRegistry.registerSource(toolkitSource);
const appSource = new FileSource("app", locales, "resource://app/localization/{locale}/");
L10nRegistry.registerSource(appSource);
}).catch(e => {
Services.console.logStringMessage(`Could not load multilocale.json. Error: ${e}`);
});
let locales = Services.locale.getPackagedLocales();
const appSource = new FileSource("app", locales, "resource://app/localization/{locale}/");
L10nRegistry.registerSource(appSource);
Services.obs.notifyObservers(null, "browser-ui-startup-complete");
},

View File

@ -1382,11 +1382,12 @@ var PlacesControllerDragHelper = {
unwrappedNode.id <= 0 || PlacesUtils.isRootItem(unwrappedNode.id)) {
return false;
}
let parentId = unwrappedNode.parent;
if (parentId <= 0 ||
parentId == PlacesUtils.placesRootId ||
parentId == PlacesUtils.tagsFolderId ||
unwrappedNode.grandParentId == PlacesUtils.tagsFolderId) {
let parentGuid = unwrappedNode.parentGuid;
// If there's no parent Guid, this was likely a virtual query that returns
// bookmarks, such as a tags query.
if (!parentGuid ||
parentGuid == PlacesUtils.bookmarks.rootGuid) {
return false;
}
// leftPaneFolderId and allBookmarksFolderId are lazy getters running
@ -1394,7 +1395,7 @@ var PlacesControllerDragHelper = {
// them first, especially because isCommandEnabled may be called way
// before the left pane folder is even necessary.
if (typeof Object.getOwnPropertyDescriptor(PlacesUIUtils, "leftPaneFolderId").get != "function" &&
(parentId == PlacesUIUtils.leftPaneFolderId)) {
(unwrappedNode.parent == PlacesUIUtils.leftPaneFolderId)) {
return false;
}
return true;

View File

@ -50,6 +50,8 @@ skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_check_correct_controllers.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_click_bookmarks_on_toolbar.js]
[browser_controller_onDrop_sidebar.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_controller_onDrop_tagFolder.js]
skip-if = (os == 'win' && ccov) # Bug 1423667
[browser_controller_onDrop.js]

View File

@ -0,0 +1,157 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URL = "about:buildconfig";
add_task(async function setup() {
// Clean before and after so we don't have anything in the folders.
await PlacesUtils.bookmarks.eraseEverything();
registerCleanupFunction(async function() {
await PlacesUtils.bookmarks.eraseEverything();
});
});
// Simulating actual drag and drop is hard for a xul tree as we can't get the
// required source elements, so we have to do a lot more work by hand.
async function simulateDrop(selectTargets, sourceBm, dropEffect, targetGuid,
isVirtualRoot = false) {
await withSidebarTree("bookmarks", async function(tree) {
for (let target of selectTargets) {
tree.selectItems([target]);
if (tree.selectedNode instanceof Ci.nsINavHistoryContainerResultNode) {
tree.selectedNode.containerOpen = true;
}
}
let dataTransfer = {
_data: [],
dropEffect,
mozCursor: "auto",
mozItemCount: 1,
types: [ PlacesUtils.TYPE_X_MOZ_PLACE ],
mozTypesAt(i) {
return [this._data[0].type];
},
mozGetDataAt(i) {
return this._data[0].data;
},
mozSetDataAt(type, data, index) {
this._data.push({
type,
data,
index
});
},
};
let event = {
dataTransfer,
preventDefault() {},
stopPropagation() {},
};
tree._controller.setDataTransfer(event);
Assert.equal(dataTransfer.mozTypesAt(0), PlacesUtils.TYPE_X_MOZ_PLACE,
"Should have x-moz-place as the first data type.");
let dataObject = JSON.parse(dataTransfer.mozGetDataAt(0));
let guid = isVirtualRoot ? dataObject.concreteGuid : dataObject.itemGuid;
Assert.equal(guid, sourceBm.guid,
"Should have the correct guid.");
Assert.equal(dataObject.title, PlacesUtils.bookmarks.getLocalizedTitle(sourceBm),
"Should have the correct title.");
Assert.equal(dataTransfer.dropEffect, dropEffect);
let ip = new InsertionPoint({
parentId: await PlacesUtils.promiseItemId(targetGuid),
parentGuid: targetGuid,
index: 0,
orientation: Ci.nsITreeView.DROP_ON
});
await PlacesControllerDragHelper.onDrop(ip, dataTransfer);
});
}
add_task(async function test_move_normal_bm_in_sidebar() {
let bm = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
title: "Fake",
url: TEST_URL
});
await simulateDrop([bm.guid], bm, "move", PlacesUtils.bookmarks.unfiledGuid);
let newBm = await PlacesUtils.bookmarks.fetch(bm.guid);
Assert.equal(newBm.parentGuid, PlacesUtils.bookmarks.unfiledGuid,
"Should have moved to the new parent.");
let oldLocationBm = await PlacesUtils.bookmarks.fetch({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
index: 0
});
Assert.ok(!oldLocationBm,
"Should not have a bookmark at the old location.");
});
add_task(async function test_try_move_root_in_sidebar() {
let menuFolder = await PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.menuGuid);
await simulateDrop([menuFolder.guid], menuFolder, "move",
PlacesUtils.bookmarks.toolbarGuid, true);
menuFolder = await PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.menuGuid);
Assert.equal(menuFolder.parentGuid, PlacesUtils.bookmarks.rootGuid,
"Should have remained in the root");
let newFolder = await PlacesUtils.bookmarks.fetch({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
index: 0,
});
Assert.notEqual(newFolder.guid, menuFolder.guid,
"Should have created a different folder");
Assert.equal(newFolder.title, PlacesUtils.bookmarks.getLocalizedTitle(menuFolder),
"Should have copied the folder title.");
Assert.equal(newFolder.type, PlacesUtils.bookmarks.TYPE_BOOKMARK,
"Should have a bookmark type (for a folder shortcut).");
Assert.equal(newFolder.url, "place:folder=BOOKMARKS_MENU",
"Should have the correct url for the folder shortcut.");
});
add_task(async function test_try_move_bm_within_two_root_folder_queries() {
await PlacesUtils.bookmarks.eraseEverything();
let bookmark = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
title: "Fake",
url: TEST_URL
});
let queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
let queries = await PlacesUtils.bookmarks.insertTree({
guid: PlacesUtils.bookmarks.toolbarGuid,
children: [{
title: "Query",
url: `place:queryType=${queryType}&terms=Fake`
}]
});
await simulateDrop([queries[0].guid, bookmark.guid],
bookmark, "move", PlacesUtils.bookmarks.toolbarGuid);
let newBm = await PlacesUtils.bookmarks.fetch(bookmark.guid);
Assert.equal(newBm.parentGuid, PlacesUtils.bookmarks.toolbarGuid,
"should have moved the bookmark to a new folder.");
});

View File

@ -80,6 +80,7 @@ this.SiteDataManager = {
cookies: [],
persisted: false,
quotaUsage: 0,
lastAccessed: 0,
principals: [],
appCacheList: [],
};
@ -153,6 +154,9 @@ this.SiteDataManager = {
if (item.persisted) {
site.persisted = true;
}
if (site.lastAccessed < item.lastAccessed) {
site.lastAccessed = item.lastAccessed;
}
site.principals.push(principal);
site.quotaUsage += item.usage;
}
@ -174,6 +178,9 @@ this.SiteDataManager = {
let cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
let site = this._getOrInsertSite(cookie.rawHost);
site.cookies.push(cookie);
if (site.lastAccessed < cookie.lastAccessed) {
site.lastAccessed = cookie.lastAccessed;
}
}
},
@ -228,7 +235,8 @@ this.SiteDataManager = {
cookies: site.cookies,
host,
usage,
persisted: site.persisted
persisted: site.persisted,
lastAccessed: new Date(site.lastAccessed / 1000),
});
}
return list;

View File

@ -576,8 +576,8 @@
<checkbox id="automaticallySubmitCrashesBox"
class="tail-with-learn-more"
preference="browser.crashReports.unsubmittedCheck.autoSubmit2"
label="&alwaysSubmitCrashReports1.label;"
accesskey="&alwaysSubmitCrashReports1.accesskey;"/>
label="&sendBackloggedCrashReports.label;"
accesskey="&sendBackloggedCrashReports.accesskey;"/>
<label id="crashReporterLearnMore"
class="learnMore text-link">&crashReporterLearnMore.label;</label>
</hbox>

View File

@ -64,6 +64,8 @@ add_task(async function() {
let request = Services.qms.clearStoragesForPrincipal(principal, null, true);
request.callback = resolve;
});
await SiteDataManager.removeAll();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
}).skip(); // Bug 1414751
@ -144,13 +146,12 @@ add_task(async function() {
await acceptRemovePromise;
await updatePromise;
await promiseServiceWorkersCleared();
await SiteDataManager.removeAll();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
// Test showing and removing sites with cookies.
add_task(async function() {
SiteDataManager.removeAll();
// Add some test cookies.
let uri = Services.io.newURI("https://example.com");
let uri2 = Services.io.newURI("https://example.org");
@ -165,12 +166,28 @@ add_task(async function() {
Services.cookies.add(uri.host, uri.pathQueryRef, "test3", "3",
false, false, false, Date.now() + 1000 * 60 * 60, { privateBrowsingId: 1 });
// Get the exact creation date from the cookies (to avoid intermittents
// from minimal time differences, since we round up to minutes).
let cookiesEnum1 = Services.cookies.getCookiesFromHost(uri.host);
// We made two valid cookies for example.com.
cookiesEnum1.getNext();
let cookiesEnum2 = Services.cookies.getCookiesFromHost(uri2.host);
let cookie1 = cookiesEnum1.getNext().QueryInterface(Ci.nsICookie2);
let cookie2 = cookiesEnum2.getNext().QueryInterface(Ci.nsICookie2);
let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short", timeStyle: "short",
});
let creationDate1 = formatter.format(new Date(cookie1.lastAccessed / 1000));
let creationDate2 = formatter.format(new Date(cookie2.lastAccessed / 1000));
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
// Open the site data manager and remove one site.
await openSiteDataSettingsDialog();
let removeDialogOpenPromise = promiseWindowDialogOpen("accept", REMOVE_DIALOG_URL);
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
await ContentTask.spawn(gBrowser.selectedBrowser, {creationDate1, creationDate2}, function(args) {
let frameDoc = content.gSubDialog._topDialog._frame.contentDocument;
let siteItems = frameDoc.getElementsByTagName("richlistitem");
@ -183,11 +200,13 @@ add_task(async function() {
is(columns[0].value, "example.com", "Should show the correct host.");
is(columns[2].value, "2", "Should show the correct number of cookies.");
is(columns[3].value, "", "Should show no site data.");
is(columns[4].value, args.creationDate1, "Should show the correct date.");
columns = site2.querySelectorAll(".item-box > label");
is(columns[0].value, "example.org", "Should show the correct host.");
is(columns[2].value, "1", "Should show the correct number of cookies.");
is(columns[3].value, "", "Should show no site data.");
is(columns[4].value, args.creationDate2, "Should show the correct date.");
let removeBtn = frameDoc.getElementById("removeSelected");
let saveBtn = frameDoc.getElementById("save");
@ -203,7 +222,7 @@ add_task(async function() {
// Open the site data manager and remove another site.
await openSiteDataSettingsDialog();
let acceptRemovePromise = promiseAlertDialogOpen("accept");
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
await ContentTask.spawn(gBrowser.selectedBrowser, {creationDate1}, function(args) {
let frameDoc = content.gSubDialog._topDialog._frame.contentDocument;
let siteItems = frameDoc.getElementsByTagName("richlistitem");
@ -215,6 +234,7 @@ add_task(async function() {
is(columns[0].value, "example.com", "Should show the correct host.");
is(columns[2].value, "2", "Should show the correct number of cookies.");
is(columns[3].value, "", "Should show no site data.");
is(columns[4].value, args.creationDate1, "Should show the correct date.");
let removeBtn = frameDoc.getElementById("removeSelected");
let saveBtn = frameDoc.getElementById("save");

View File

@ -112,7 +112,7 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertAllSitesNotListed(win);
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
function removeAllSitesOneByOne() {
@ -224,7 +224,7 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertSitesListed(doc, fakeHosts.slice(2));
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
function removeSelectedSite(hosts) {
@ -300,7 +300,7 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertSitesListed(doc, fakeHosts.filter(host => !host.includes("xyz")));
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
@ -358,6 +358,6 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertAllSitesNotListed(win);
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

View File

@ -42,7 +42,7 @@ add_task(async function() {
await openSiteDataSettingsDialog();
assertSitesListed(doc, fakeHosts.filter(host => host != "shopping.xyz.com"));
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
@ -104,7 +104,7 @@ add_task(async function() {
DownloadUtils.convertByteUnits(quotaUsage * mockSiteDataManager.fakeSites.length));
is(columns[3].value, expected, "Should sum up usages across scheme, port and origin attributes");
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
@ -116,19 +116,19 @@ add_task(async function() {
usage: 1024,
origin: "https://account.xyz.com",
cookies: 6,
persisted: true
persisted: true,
},
{
usage: 1024 * 2,
origin: "https://books.foo.com",
cookies: 0,
persisted: false
persisted: false,
},
{
usage: 1024 * 3,
origin: "http://cinema.bar.com",
cookies: 3,
persisted: true
persisted: true,
},
]);
@ -174,7 +174,7 @@ add_task(async function() {
statusCol.click();
assertSortByStatus("descending");
mockSiteDataManager.unregister();
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
function assertSortByBaseDomain(order) {
@ -250,3 +250,69 @@ add_task(async function() {
return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
}
});
// Test sorting based on access date (separate from cookies for simplicity,
// since cookies access date affects this as well, but we don't mock our cookies)
add_task(async function() {
mockSiteDataManager.register(SiteDataManager, [
{
usage: 1024,
origin: "https://account.xyz.com",
persisted: true,
lastAccessed: (Date.now() - 120 * 1000) * 1000,
},
{
usage: 1024 * 2,
origin: "https://books.foo.com",
persisted: false,
lastAccessed: (Date.now() - 240 * 1000) * 1000,
},
{
usage: 1024 * 3,
origin: "http://cinema.bar.com",
persisted: true,
lastAccessed: Date.now() * 1000,
},
]);
let updatePromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatePromise;
await openSiteDataSettingsDialog();
// eslint-disable-next-line mozilla/no-cpows-in-tests
let dialog = content.gSubDialog._topDialog;
let dialogFrame = dialog._frame;
let frameDoc = dialogFrame.contentDocument;
let lastAccessedCol = frameDoc.getElementById("lastAccessedCol");
let sitesList = frameDoc.getElementById("sitesList");
// Test sorting on the date column
lastAccessedCol.click();
assertSortByDate("ascending");
lastAccessedCol.click();
assertSortByDate("descending");
await mockSiteDataManager.unregister();
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
function assertSortByDate(order) {
let siteItems = sitesList.getElementsByTagName("richlistitem");
for (let i = 0; i < siteItems.length - 1; ++i) {
let aHost = siteItems[i].getAttribute("host");
let bHost = siteItems[i + 1].getAttribute("host");
let a = findSiteByHost(aHost);
let b = findSiteByHost(bHost);
let result = a.lastAccessed - b.lastAccessed;
if (order == "ascending") {
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by date");
} else {
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order date");
}
}
}
function findSiteByHost(host) {
return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
}
});

View File

@ -229,7 +229,8 @@ const mockSiteDataManager = {
let result = this.fakeSites.map(site => ({
origin: site.principal.origin,
usage: site.usage,
persisted: site.persisted
persisted: site.persisted,
lastAccessed: site.lastAccessed,
}));
onUsageResult({ result, resultCode: Components.results.NS_OK });
},
@ -270,9 +271,9 @@ const mockSiteDataManager = {
}
},
unregister() {
async unregister() {
await this._SiteDataManager.removeAll();
this.fakeSites = null;
this._SiteDataManager.removeAll();
this._SiteDataManager._qms = this._originalQMS;
this._SiteDataManager._removeQuotaUsage = this._originalRemoveQuotaUsage;
}

View File

@ -67,6 +67,10 @@ let gSiteDataSettings = {
addColumnItem(null, "1");
}
// Add "Last Used" column.
addColumnItem(site.lastAccessed > 0 ?
this._formatter.format(site.lastAccessed) : null, "2");
item.appendChild(container);
return item;
},
@ -77,6 +81,10 @@ let gSiteDataSettings = {
.addEventListener(eventType, callback.bind(gSiteDataSettings));
}
this._formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short", timeStyle: "short",
});
this._list = document.getElementById("sitesList");
this._searchBox = document.getElementById("searchBox");
this._prefStrBundle = document.getElementById("bundlePreferences");
@ -95,6 +103,7 @@ let gSiteDataSettings = {
setEventListener("sitesList", "select", this.onSelect);
setEventListener("hostCol", "click", this.onClickTreeCol);
setEventListener("usageCol", "click", this.onClickTreeCol);
setEventListener("lastAccessedCol", "click", this.onClickTreeCol);
setEventListener("cookiesCol", "click", this.onClickTreeCol);
setEventListener("statusCol", "click", this.onClickTreeCol);
setEventListener("cancel", "command", this.close);
@ -161,6 +170,10 @@ let gSiteDataSettings = {
case "usageCol":
sortFunc = (a, b) => a.usage - b.usage;
break;
case "lastAccessedCol":
sortFunc = (a, b) => a.lastAccessed - b.lastAccessed;
break;
}
if (sortDirection === "descending") {
sites.sort((a, b) => sortFunc(b, a));

View File

@ -42,6 +42,7 @@
<treecol flex="1" width="50" label="&cookiesCol.label;" id="cookiesCol"/>
<!-- Sorted by usage so the user can quickly see which sites use the most data. -->
<treecol flex="1" width="50" label="&usageCol.label;" id="usageCol" data-isCurrentSortCol="true"/>
<treecol flex="2" width="50" label="&lastAccessedCol.label;" id="lastAccessedCol" />
</listheader>
</richlistbox>
</vbox>

View File

@ -10,7 +10,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
OnboardingTourType: "resource://onboarding/modules/OnboardingTourType.jsm",
OnboardingTelemetry: "resource://onboarding/modules/OnboardingTelemetry.jsm",
Services: "resource://gre/modules/Services.jsm",
fxAccounts: "resource://gre/modules/FxAccounts.jsm",
UIState: "resource://services-sync/UIState.jsm",
});
const {PREF_STRING, PREF_BOOL, PREF_INT} = Ci.nsIPrefBranch;
@ -89,33 +89,28 @@ let syncTourChecker = {
},
observe(subject, topic) {
switch (topic) {
case "fxaccounts:onlogin":
this.setComplete();
break;
case "fxaccounts:onlogout":
this._loggedIn = false;
break;
const state = UIState.get();
if (state.status == UIState.STATUS_NOT_CONFIGURED) {
this._loggedIn = false;
} else {
this.setComplete();
}
},
init() {
// Check if we've already logged in at startup.
fxAccounts.getSignedInUser().then(user => {
if (user) {
this.setComplete();
}
// Observe for login action if we haven't logged in yet.
this.register();
});
const state = UIState.get();
if (state.status != UIState.STATUS_NOT_CONFIGURED) {
this.setComplete();
}
this.register();
},
register() {
if (this._registered) {
return;
}
Services.obs.addObserver(this, "fxaccounts:onlogin");
Services.obs.addObserver(this, "fxaccounts:onlogout");
Services.obs.addObserver(this, "sync-ui-state:update");
this._registered = true;
},
@ -128,8 +123,7 @@ let syncTourChecker = {
if (!this._registered) {
return;
}
Services.obs.removeObserver(this, "fxaccounts:onlogin");
Services.obs.removeObserver(this, "fxaccounts:onlogout");
Services.obs.removeObserver(this, "sync-ui-state:update");
this._registered = false;
},

View File

@ -145,6 +145,8 @@ res/table-remove-column.gif
res/table-remove-row-active.gif
res/table-remove-row-hover.gif
res/table-remove-row.gif
res/multilocale.txt
update.locale
# Aurora branding
browser/chrome/browser/content/branding/icon64.png
browser/chrome/devtools/content/framework/dev-edition-promo/dev-edition-logo.png

View File

@ -86,7 +86,7 @@ endif
@$(MAKE) -C ../../devtools/shim/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
@$(MAKE) multilocale.json-$* AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) multilocale.txt-$* AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$*
chrome-%: AB_CD=$*

View File

@ -41,8 +41,8 @@ available. -->
<!ENTITY collectBrowserErrors.accesskey "b">
<!ENTITY collectBrowserErrorsLearnMore.label "Learn more">
<!ENTITY alwaysSubmitCrashReports1.label "Allow &brandShortName; to send crash reports to Mozilla">
<!ENTITY alwaysSubmitCrashReports1.accesskey "c">
<!ENTITY sendBackloggedCrashReports.label "Allow &brandShortName; to send backlogged crash reports on your behalf">
<!ENTITY sendBackloggedCrashReports.accesskey "c">
<!ENTITY crashReporterLearnMore.label "Learn more">
<!ENTITY networkTab.label "Network">

View File

@ -7,6 +7,7 @@
<!ENTITY statusCol.label "Status">
<!ENTITY cookiesCol.label "Cookies">
<!ENTITY usageCol.label "Storage">
<!ENTITY lastAccessedCol.label "Last Used">
<!ENTITY searchTextboxPlaceHolder "Search websites">
<!ENTITY searchTextboxPlaceHolder.accesskey "S">
<!ENTITY removeSelected.label "Remove Selected">

View File

@ -149,6 +149,7 @@ this.SitePermissions = {
SCOPE_TEMPORARY: "{SitePermissions.SCOPE_TEMPORARY}",
SCOPE_SESSION: "{SitePermissions.SCOPE_SESSION}",
SCOPE_PERSISTENT: "{SitePermissions.SCOPE_PERSISTENT}",
SCOPE_POLICY: "{SitePermissions.SCOPE_POLICY}",
_defaultPrefBranch: Services.prefs.getBranch("permissions.default."),
@ -188,7 +189,10 @@ this.SitePermissions = {
let scope = this.SCOPE_PERSISTENT;
if (permission.expireType == Services.perms.EXPIRE_SESSION) {
scope = this.SCOPE_SESSION;
} else if (permission.expireType == Services.perms.EXPIRE_POLICY) {
scope = this.SCOPE_POLICY;
}
result.push({
id: permission.type,
scope,
@ -358,6 +362,8 @@ this.SitePermissions = {
result.state = permission.capability;
if (permission.expireType == Services.perms.EXPIRE_SESSION) {
result.scope = this.SCOPE_SESSION;
} else if (permission.expireType == Services.perms.EXPIRE_POLICY) {
result.scope = this.SCOPE_POLICY;
}
}
}
@ -430,6 +436,8 @@ this.SitePermissions = {
let perms_scope = Services.perms.EXPIRE_NEVER;
if (scope == this.SCOPE_SESSION) {
perms_scope = Services.perms.EXPIRE_SESSION;
} else if (scope == this.SCOPE_POLICY) {
perms_scope = Services.perms.EXPIRE_POLICY;
}
Services.perms.add(uri, permissionID, state, perms_scope);
@ -541,13 +549,13 @@ this.SitePermissions = {
case this.PROMPT:
return gStringBundle.GetStringFromName("state.current.prompt");
case this.ALLOW:
if (scope && scope != this.SCOPE_PERSISTENT)
if (scope && scope != this.SCOPE_PERSISTENT && scope != this.SCOPE_POLICY)
return gStringBundle.GetStringFromName("state.current.allowedTemporarily");
return gStringBundle.GetStringFromName("state.current.allowed");
case this.ALLOW_COOKIES_FOR_SESSION:
return gStringBundle.GetStringFromName("state.current.allowedForSession");
case this.BLOCK:
if (scope && scope != this.SCOPE_PERSISTENT)
if (scope && scope != this.SCOPE_PERSISTENT && scope != this.SCOPE_POLICY)
return gStringBundle.GetStringFromName("state.current.blockedTemporarily");
return gStringBundle.GetStringFromName("state.current.blocked");
default:

View File

@ -343,15 +343,6 @@ PreviewController.prototype = {
}
};
XPCOMUtils.defineLazyGetter(PreviewController.prototype, "canvasPreviewFlags",
function() {
let canvasInterface = Ci.nsIDOMCanvasRenderingContext2D;
return canvasInterface.DRAWWINDOW_DRAW_VIEW
| canvasInterface.DRAWWINDOW_DRAW_CARET
| canvasInterface.DRAWWINDOW_ASYNC_DECODE_IMAGES
| canvasInterface.DRAWWINDOW_DO_NOT_FLUSH;
});
// TabWindow
/*

View File

@ -173,9 +173,8 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
bool exists = false;
file->Exists(&exists);
if (!exists) {
nsAutoCString path;
file->GetNativePath(path);
printf("Chrome file doesn't exist: %s\n", path.get());
printf("Chrome file doesn't exist: %s\n",
file->HumanReadablePath().get());
}
}
#endif

View File

@ -735,12 +735,6 @@ nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno
if (NS_FAILED(rv)) {
return;
}
if (mainPackage.Equals(package)) {
// We should refresh the LocaleService, since the available
// locales changed.
LocaleService::GetInstance()->AvailableLocalesChanged();
}
}
void

View File

@ -44,6 +44,7 @@ registerCleanupFunction(function() {
add_task(async function() {
// Windows XP and 8.1 test slaves are terribly slow at this test.
requestLongerTimeout(5);
await pushPref("devtools.chrome.enabled", true);
await pushPref("devtools.debugger.remote-enabled", true);
gProcess = await initChromeDebugger();

View File

@ -12,6 +12,7 @@ var gProcess;
function test() {
// Windows XP and 8.1 test slaves are terribly slow at this test.
requestLongerTimeout(5);
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
initChromeDebugger(aOnClose).then(aProcess => {
@ -57,6 +58,7 @@ function aOnClose() {
}
registerCleanupFunction(function () {
Services.prefs.clearUserPref("devtools.chrome.enabled");
Services.prefs.clearUserPref("devtools.debugger.remote-enabled");
gProcess = null;
});

View File

@ -91,9 +91,28 @@ EventEmitter.decorate(BrowserToolboxProcess);
* @return object
*/
BrowserToolboxProcess.init = function (onClose, onRun, options) {
if (!Services.prefs.getBoolPref("devtools.chrome.enabled") ||
!Services.prefs.getBoolPref("devtools.debugger.remote-enabled")) {
console.error("Could not start Browser Toolbox, you need to enable it.");
return null;
}
return new BrowserToolboxProcess(onClose, onRun, options);
};
/**
* Figure out if there are any open Browser Toolboxes that'll need to be restored.
* @return bool
*/
BrowserToolboxProcess.getBrowserToolboxSessionState = function () {
for (let process of processes.values()) {
// Don't worry about addon toolboxes, we only want to restore the Browser Toolbox.
if (!process._options || !process._options.addonID) {
return true;
}
}
return false;
};
/**
* Passes a set of options to the BrowserAddonActors for the given ID.
*

View File

@ -17,6 +17,7 @@ loader.lazyRequireGetter(this, "ToolboxHostManager", "devtools/client/framework/
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
loader.lazyRequireGetter(this, "HUDService", "devtools/client/webconsole/hudservice", true);
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
loader.lazyRequireGetter(this, "WebExtensionInspectedWindowFront",
"devtools/shared/fronts/webextension-inspected-window", true);
@ -397,6 +398,7 @@ DevTools.prototype = {
*/
saveDevToolsSession: function (state) {
state.browserConsole = HUDService.getBrowserConsoleSessionState();
state.browserToolbox = BrowserToolboxProcess.getBrowserToolboxSessionState();
// Check if the module is loaded to avoid loading ScratchpadManager for no reason.
state.scratchpads = [];
@ -408,11 +410,15 @@ DevTools.prototype = {
/**
* Restore the devtools session state as provided by SessionStore.
*/
restoreDevToolsSession: function ({scratchpads, browserConsole}) {
restoreDevToolsSession: function ({scratchpads, browserConsole, browserToolbox}) {
if (scratchpads) {
ScratchpadManager.restoreSession(scratchpads);
}
if (browserToolbox) {
BrowserToolboxProcess.init();
}
if (browserConsole && !HUDService.getBrowserConsole()) {
HUDService.toggleBrowserConsole();
}

View File

@ -5,8 +5,8 @@
// On debug test slave, it takes about 50s to run the test.
requestLongerTimeout(4);
add_task(function* runTest() {
yield new Promise(done => {
add_task(async function() {
await new Promise(done => {
let options = {"set": [
["devtools.debugger.prompt-connection", false],
["devtools.debugger.remote-enabled", true],
@ -48,18 +48,22 @@ add_task(function* runTest() {
});
let { BrowserToolboxProcess } = ChromeUtils.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
is(BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state initially");
let closePromise;
yield new Promise(onRun => {
await new Promise(onRun => {
closePromise = new Promise(onClose => {
info("Opening the browser toolbox\n");
BrowserToolboxProcess.init(onClose, onRun);
});
});
ok(true, "Browser toolbox started\n");
is(BrowserToolboxProcess.getBrowserToolboxSessionState(), true, "Has session state");
yield onCustomMessage;
await onCustomMessage;
ok(true, "Received the custom message");
yield closePromise;
await closePromise;
ok(true, "Browser toolbox process just closed");
is(BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state after closing");
});

View File

@ -16,7 +16,8 @@ var { Toolbox } = require("devtools/client/framework/toolbox");
var Services = require("Services");
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
var { PrefsHelper } = require("devtools/client/shared/prefs");
var { Task } = require("devtools/shared/task");
const STATUS_REVEAL_TIME = 5000;
/**
* Shortcuts for accessing various debugger preferences.
@ -28,9 +29,20 @@ var Prefs = new PrefsHelper("devtools.debugger", {
var gToolbox, gClient;
var connect = Task.async(function* () {
window.removeEventListener("load", connect);
function appendStatusMessage(msg) {
let statusMessage = document.getElementById("status-message");
statusMessage.value += msg + "\n";
if (msg.stack) {
statusMessage.value += msg.stack + "\n";
}
}
function revealStatusMessage() {
let statusMessageContainer = document.getElementById("status-message-container");
statusMessageContainer.hidden = false;
}
var connect = async function () {
// Initiate the connection
let env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
@ -44,24 +56,29 @@ var connect = Task.async(function* () {
throw new Error("Must pass a port in an env variable with MOZ_BROWSER_TOOLBOX_PORT");
}
let transport = yield DebuggerClient.socketConnect({
host: Prefs.chromeDebuggingHost,
let host = Prefs.chromeDebuggingHost;
let webSocket = Prefs.chromeDebuggingWebSocket;
appendStatusMessage(`Connecting to ${host}:${port}, ws: ${webSocket}`);
let transport = await DebuggerClient.socketConnect({
host,
port,
webSocket: Prefs.chromeDebuggingWebSocket,
webSocket,
});
gClient = new DebuggerClient(transport);
yield gClient.connect();
appendStatusMessage("Start protocol client for connection");
await gClient.connect();
appendStatusMessage("Get root form for toolbox");
if (addonID) {
let { addons } = yield gClient.listAddons();
let { addons } = await gClient.listAddons();
let addonActor = addons.filter(addon => addon.id === addonID).pop();
let isTabActor = addonActor.isWebExtension;
openToolbox({form: addonActor, chrome: true, isTabActor});
await openToolbox({form: addonActor, chrome: true, isTabActor});
} else {
let response = yield gClient.getProcess();
openToolbox({form: response.form, chrome: true});
let response = await gClient.getProcess();
await openToolbox({form: response.form, chrome: true});
}
});
};
// Certain options should be toggled since we can assume chrome debugging here
function setPrefDefaults() {
@ -78,47 +95,55 @@ function setPrefDefaults() {
Services.prefs.setBoolPref("devtools.preference.new-panel-enabled", false);
Services.prefs.setBoolPref("layout.css.emulate-moz-box-with-flex", false);
}
window.addEventListener("load", function () {
window.addEventListener("load", async function () {
let cmdClose = document.getElementById("toolbox-cmd-close");
cmdClose.addEventListener("command", onCloseCommand);
setPrefDefaults();
connect().catch(e => {
let errorMessageContainer = document.getElementById("error-message-container");
let errorMessage = document.getElementById("error-message");
errorMessage.value = e.message || e;
errorMessageContainer.hidden = false;
// Reveal status message if connecting is slow or if an error occurs
let delayedStatusReveal = setTimeout(() => {
revealStatusMessage();
}, STATUS_REVEAL_TIME);
try {
await connect();
clearTimeout(delayedStatusReveal);
} catch (e) {
appendStatusMessage(e);
revealStatusMessage();
console.error(e);
});
});
}
}, { once: true });
function onCloseCommand(event) {
window.close();
}
function openToolbox({ form, chrome, isTabActor }) {
async function openToolbox({ form, chrome, isTabActor }) {
let options = {
form: form,
client: gClient,
chrome: chrome,
isTabActor: isTabActor
};
TargetFactory.forRemoteTab(options).then(target => {
let frame = document.getElementById("toolbox-iframe");
appendStatusMessage(`Create toolbox target: ${JSON.stringify(arguments, null, 2)}`);
let target = await TargetFactory.forRemoteTab(options);
let frame = document.getElementById("toolbox-iframe");
// Remember the last panel that was used inside of this profile.
// But if we are testing, then it should always open the debugger panel.
let selectedTool =
Services.prefs.getCharPref("devtools.browsertoolbox.panel",
Services.prefs.getCharPref("devtools.toolbox.selectedTool",
"jsdebugger"));
// Remember the last panel that was used inside of this profile.
// But if we are testing, then it should always open the debugger panel.
let selectedTool =
Services.prefs.getCharPref("devtools.browsertoolbox.panel",
Services.prefs.getCharPref("devtools.toolbox.selectedTool",
"jsdebugger"));
options = { customIframe: frame };
gDevTools.showToolbox(target,
selectedTool,
Toolbox.HostType.CUSTOM,
options)
.then(onNewToolbox);
});
options = { customIframe: frame };
appendStatusMessage(`Show toolbox with ${selectedTool} selected`);
let toolbox = await gDevTools.showToolbox(
target,
selectedTool,
Toolbox.HostType.CUSTOM,
options
);
onNewToolbox(toolbox);
}
function onNewToolbox(toolbox) {
@ -147,7 +172,7 @@ function evaluateTestScript(script, toolbox) {
Cu.evalInSandbox(script, sandbox);
}
function bindToolboxHandlers() {
async function bindToolboxHandlers() {
gToolbox.once("destroyed", quitApp);
window.addEventListener("unload", onUnload);
@ -157,9 +182,8 @@ function bindToolboxHandlers() {
updateBadgeText(false);
// Once the debugger panel opens listen for thread pause / resume.
gToolbox.getPanelWhenReady("jsdebugger").then(panel => {
setupThreadListeners(panel);
});
let panel = await gToolbox.getPanelWhenReady("jsdebugger");
setupThreadListeners(panel);
}
}

View File

@ -37,9 +37,9 @@
for example when viewing network request details. -->
<popupset id="mainPopupSet"></popupset>
<vbox id="error-message-container" hidden="true" flex="1">
<box>&browserToolboxErrorMessage;</box>
<textbox multiline="true" id="error-message" flex="1"></textbox>
<vbox id="status-message-container" hidden="true" flex="1">
<box>&browserToolboxStatusMessage;</box>
<textbox multiline="true" id="status-message" flex="1"></textbox>
</vbox>
<tooltip id="aHTMLTooltip" page="true"/>

View File

@ -307,27 +307,34 @@ class BoxModelMain extends PureComponent {
switch (keyCode) {
case KeyCodes.DOM_VK_RETURN:
if (!isEditable) {
this.setState({ focusable: true });
let editableBox = this.layouts[level].get(keyCode);
if (editableBox) {
editableBox.boxModelEditable.focus();
}
this.setState({ focusable: true }, () => {
let editableBox = this.layouts[level].get(keyCode);
if (editableBox) {
editableBox.boxModelEditable.focus();
}
});
}
break;
case KeyCodes.DOM_VK_DOWN:
case KeyCodes.DOM_VK_UP:
if (!editingMode) {
event.preventDefault();
this.setState({ focusable: false });
event.stopPropagation();
this.setState({ focusable: false }, () => {
let nextLayout = this.layouts[level].get(keyCode);
let nextLayout = this.layouts[level].get(keyCode);
this.setAriaActive(nextLayout);
if (!nextLayout) {
return;
}
if (target && target._editable) {
target.blur();
}
this.setAriaActive(nextLayout);
this.props.boxModelContainer.focus();
if (target && target._editable) {
target.blur();
}
this.props.boxModelContainer.focus();
});
}
break;
case KeyCodes.DOM_VK_TAB:
@ -340,8 +347,9 @@ class BoxModelMain extends PureComponent {
if (target._editable) {
event.preventDefault();
event.stopPropagation();
this.setState({ focusable: false });
this.props.boxModelContainer.focus();
this.setState({ focusable: false }, () => {
this.props.boxModelContainer.focus();
});
}
break;
default:

View File

@ -45,16 +45,18 @@ class Font extends PureComponent {
});
}
onFontToggle() {
onFontToggle(event) {
this.setState({
isFontExpanded: !this.state.isFontExpanded
});
event.stopPropagation();
}
onFontFaceRuleToggle() {
onFontFaceRuleToggle(event) {
this.setState({
isFontFaceRuleExpanded: !this.state.isFontFaceRuleExpanded
});
event.stopPropagation();
}
renderFontCSS(cssFamilyName) {

View File

@ -44,8 +44,9 @@ class FontPreview extends PureComponent {
this.setState({ isFocused: false });
}
onClick() {
onClick(event) {
this.setState({ isFocused: true });
event.stopPropagation();
}
onChange(event) {

View File

@ -34,11 +34,13 @@ class Accordion extends PureComponent {
this.renderContainer = this.renderContainer.bind(this);
}
handleHeaderClick(i) {
handleHeaderClick(i, event) {
const opened = [...this.state.opened];
const created = [...this.state.created];
const item = this.props.items[i];
event.stopPropagation();
opened[i] = !opened[i];
created[i] = true;
@ -67,7 +69,7 @@ class Accordion extends PureComponent {
div(
{ className: "_header",
onClick: () => this.handleHeaderClick(i) },
onClick: event => this.handleHeaderClick(i, event) },
span({ className: arrowClassName }),
item.header
),

View File

@ -10,9 +10,10 @@
<!ENTITY toggleToolboxF12.keycode "VK_F12">
<!ENTITY toggleToolboxF12.keytext "F12">
<!-- LOCALIZATION NOTE (browserToolboxErrorMessage): This is the label
- shown next to error details when the Browser Toolbox is unable to open. -->
<!ENTITY browserToolboxErrorMessage "Error opening Browser Toolbox:">
<!-- LOCALIZATION NOTE (browserToolboxStatusMessage): This is the label
- shown next to status details when the Browser Toolbox fails to connect or
- appears to be taking a while to do so. -->
<!ENTITY browserToolboxStatusMessage "Browser Toolbox connection status:">
<!-- LOCALIZATION NOTE (options.context.advancedSettings): This is the label for
- the heading of the advanced settings group in the options panel. -->

View File

@ -28,11 +28,14 @@ We need to disable minification and tree shaking as they overcomplicate the upgr
- Find a method called `function getRollupOutputOptions()`
- After `sourcemap: false` add `treeshake: false` and `freeze: false`
- Change this:
```js
// Apply dead code elimination and/or minification.
isProduction &&
```
To this:
```js
{
transformBundle(source) {
@ -78,6 +81,7 @@ if (process.env.NODE_ENV === 'production') {
```
To this:
```js
module.exports = require('./cjs/react-test-renderer-shallow.development.js');
```
@ -112,192 +116,3 @@ cp build/packages/react-test-renderer/react-test-renderer-shallow.js <gecko-dev>
```
From this point we will no longer need your react repository so feel free to delete it.
## Patching
### Patching react-dom
Open `devtools/client/shared/vendor/react-dom.js` and `devtools/client/shared/vendor/react-dom-dev.js`.
The following change should be made to **BOTH** files.
To have React's event system working correctly in certain XUL situations, ReactDOM must be monkey patched with a fix.
Turn this:
```js
var ReactDOM$2 = Object.freeze({
default: ReactDOM
});
```
Into this:
```js
//--------------------------------------------------------------------------------------
// START MONKEY PATCH
/**
* This section contains a monkey patch for React DOM, so that it functions correctly in
* certain XUL situations. React centralizes events to specific DOM nodes by only
* binding a single listener to the document of the page. It then captures these events,
* and then uses a SyntheticEvent system to dispatch these throughout the page.
*
* In privileged XUL with a XUL iframe, and React in both documents, this system breaks.
* By design, these XUL frames can still talk to each other, while in a normal HTML
* situation, they would not be able to. The events from the XUL iframe propagate to the
* parent document as well. This leads to the React event system incorrectly dispatching
* TWO SyntheticEvents for for every ONE action.
*
* The fix here is trick React into thinking that the owning document for every node in
* a XUL iframe to be the toolbox.xul. This is done by creating a Proxy object that
* captures any usage of HTMLElement.ownerDocument, and then passing in the toolbox.xul
* document rather than (for example) the netmonitor.xul document. React will then hook
* up the event system correctly on the top level controlling document.
*
* @return {object} The proxied and monkey patched ReactDOM
*/
function monkeyPatchReactDOM(ReactDOM) {
// This is the actual monkey patched function.
const reactDomRender = monkeyPatchRender(ReactDOM);
// Proxied method calls might need to be bound, but do this lazily with caching.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy, but the render property is not writable on the ReactDOM object, so
// a direct proxy will fail with an error. Instead, create a proxy on a a blank object.
// Pass on getting and setting behaviors.
return new Proxy({}, {
get: (target, name) => {
if (name === "render") {
return reactDomRender;
}
return lazyFunctionBinding(ReactDOM, name);
},
set: (target, name, value) => {
ReactDOM[name] = value;
return true;
}
});
};
/**
* Creates a function that replaces the ReactDOM.render method. It does this by
* creating a proxy for the dom node being mounted. This proxy rewrites the
* "ownerDocument" property to point to the toolbox.xul document. This function
* is only used for XUL iframes inside of a XUL document.
*
* @param {object} ReactDOM
* @return {function} The patched ReactDOM.render function.
*/
function monkeyPatchRender(ReactDOM) {
const elementProxyCache = new WeakMap();
return (...args) => {
const container = args[1];
const toolboxDoc = getToolboxDocIfXulOnly(container);
if (toolboxDoc) {
// Re-use any existing cached HTMLElement proxies.
let proxy = elementProxyCache.get(container);
if (!proxy) {
// Proxied method calls need to be bound, but do this lazily.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy to the container HTMLElement. If React tries to access the
// ownerDocument, pass in the toolbox's document, as the event dispatching system
// is rooted from the toolbox document.
proxy = new Proxy(container, {
get: function (target, name) {
if (name === "ownerDocument") {
return toolboxDoc;
}
return lazyFunctionBinding(target, name);
}
});
elementProxyCache.set(container, proxy);
}
// Update the args passed to ReactDOM.render.
args[1] = proxy;
}
return ReactDOM.render.apply(this, args);
};
}
/**
* Try to access the containing toolbox XUL document, but only if all of the iframes
* in the heirarchy are XUL documents. Events dispatch differently in the case of all
* privileged XUL documents. Events that fire in an iframe propagate up to the parent
* frame. This does not happen when HTML is in the mix. Only return the toolbox if
* it matches the proper case of a XUL iframe inside of a XUL document.
*
* In addition to the XUL case, if the panel uses the toolbox's ReactDOM instance,
* this patch needs to be applied as well. This is the case for the inspector.
*
* @param {HTMLElement} node - The DOM node inside of an iframe.
* @return {XULDocument|null} The toolbox.xul document, or null.
*/
function getToolboxDocIfXulOnly(node) {
// This execution context doesn't know about XULDocuments, so don't get the toolbox.
if (typeof XULDocument !== "function") {
return null;
}
let doc = node.ownerDocument;
const inspectorUrl = "chrome://devtools/content/inspector/inspector.xhtml";
const netMonitorUrl = "chrome://devtools/content/netmonitor/netmonitor.xhtml";
const webConsoleUrl = "chrome://devtools/content/webconsole/webconsole.xhtml";
while (doc instanceof XULDocument ||
doc.location.href === inspectorUrl ||
doc.location.href === netMonitorUrl ||
doc.location.href === webConsoleUrl) {
const {frameElement} = doc.defaultView;
if (!frameElement) {
// We're at the root element, and no toolbox was found.
return null;
}
doc = frameElement.parentElement.ownerDocument;
if (doc.documentURI === "about:devtools-toolbox") {
return doc;
}
}
return null;
}
/**
* When accessing proxied functions, the instance becomes unbound to the method. This
* utility either passes a value through if it's not a function, or automatically binds a
* function and caches that bound function for repeated calls.
*/
function functionLazyBinder() {
const boundFunctions = {};
return (target, name) => {
if (typeof target[name] === "function") {
// Lazily cache function bindings.
if (boundFunctions[name]) {
return boundFunctions[name];
}
boundFunctions[name] = target[name].bind(target);
return boundFunctions[name];
}
return target[name];
};
}
// END MONKEY PATCH
//--------------------------------------------------------------------------------------
ReactDOM = monkeyPatchReactDOM(ReactDOM);
var ReactDOM$2 = Object.freeze({
default: ReactDOM
});
```

View File

@ -16051,169 +16051,6 @@ var foundDevTools = DOMRenderer.injectIntoDevTools({
}
}
//--------------------------------------------------------------------------------------
// START MONKEY PATCH
/**
* This section contains a monkey patch for React DOM, so that it functions correctly in
* certain XUL situations. React centralizes events to specific DOM nodes by only
* binding a single listener to the document of the page. It then captures these events,
* and then uses a SyntheticEvent system to dispatch these throughout the page.
*
* In privileged XUL with a XUL iframe, and React in both documents, this system breaks.
* By design, these XUL frames can still talk to each other, while in a normal HTML
* situation, they would not be able to. The events from the XUL iframe propagate to the
* parent document as well. This leads to the React event system incorrectly dispatching
* TWO SyntheticEvents for for every ONE action.
*
* The fix here is trick React into thinking that the owning document for every node in
* a XUL iframe to be the toolbox.xul. This is done by creating a Proxy object that
* captures any usage of HTMLElement.ownerDocument, and then passing in the toolbox.xul
* document rather than (for example) the netmonitor.xul document. React will then hook
* up the event system correctly on the top level controlling document.
*
* @return {object} The proxied and monkey patched ReactDOM
*/
function monkeyPatchReactDOM(ReactDOM) {
// This is the actual monkey patched function.
const reactDomRender = monkeyPatchRender(ReactDOM);
// Proxied method calls might need to be bound, but do this lazily with caching.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy, but the render property is not writable on the ReactDOM object, so
// a direct proxy will fail with an error. Instead, create a proxy on a a blank object.
// Pass on getting and setting behaviors.
return new Proxy({}, {
get: (target, name) => {
if (name === "render") {
return reactDomRender;
}
return lazyFunctionBinding(ReactDOM, name);
},
set: (target, name, value) => {
ReactDOM[name] = value;
return true;
}
});
};
/**
* Creates a function that replaces the ReactDOM.render method. It does this by
* creating a proxy for the dom node being mounted. This proxy rewrites the
* "ownerDocument" property to point to the toolbox.xul document. This function
* is only used for XUL iframes inside of a XUL document.
*
* @param {object} ReactDOM
* @return {function} The patched ReactDOM.render function.
*/
function monkeyPatchRender(ReactDOM) {
const elementProxyCache = new WeakMap();
return (...args) => {
const container = args[1];
const toolboxDoc = getToolboxDocIfXulOnly(container);
if (toolboxDoc) {
// Re-use any existing cached HTMLElement proxies.
let proxy = elementProxyCache.get(container);
if (!proxy) {
// Proxied method calls need to be bound, but do this lazily.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy to the container HTMLElement. If React tries to access the
// ownerDocument, pass in the toolbox's document, as the event dispatching system
// is rooted from the toolbox document.
proxy = new Proxy(container, {
get: function (target, name) {
if (name === "ownerDocument") {
return toolboxDoc;
}
return lazyFunctionBinding(target, name);
}
});
elementProxyCache.set(container, proxy);
}
// Update the args passed to ReactDOM.render.
args[1] = proxy;
}
return ReactDOM.render.apply(this, args);
};
}
/**
* Try to access the containing toolbox XUL document, but only if all of the iframes
* in the heirarchy are XUL documents. Events dispatch differently in the case of all
* privileged XUL documents. Events that fire in an iframe propagate up to the parent
* frame. This does not happen when HTML is in the mix. Only return the toolbox if
* it matches the proper case of a XUL iframe inside of a XUL document.
*
* In addition to the XUL case, if the panel uses the toolbox's ReactDOM instance,
* this patch needs to be applied as well. This is the case for the inspector.
*
* @param {HTMLElement} node - The DOM node inside of an iframe.
* @return {XULDocument|null} The toolbox.xul document, or null.
*/
function getToolboxDocIfXulOnly(node) {
// This execution context doesn't know about XULDocuments, so don't get the toolbox.
if (typeof XULDocument !== "function") {
return null;
}
let doc = node.ownerDocument;
const inspectorUrl = "chrome://devtools/content/inspector/inspector.xhtml";
const netMonitorUrl = "chrome://devtools/content/netmonitor/netmonitor.xhtml";
const webConsoleUrl = "chrome://devtools/content/webconsole/webconsole.xhtml";
while (doc instanceof XULDocument ||
doc.location.href === inspectorUrl ||
doc.location.href === netMonitorUrl ||
doc.location.href === webConsoleUrl) {
const {frameElement} = doc.defaultView;
if (!frameElement) {
// We're at the root element, and no toolbox was found.
return null;
}
doc = frameElement.parentElement.ownerDocument;
if (doc.documentURI === "about:devtools-toolbox") {
return doc;
}
}
return null;
}
/**
* When accessing proxied functions, the instance becomes unbound to the method. This
* utility either passes a value through if it's not a function, or automatically binds a
* function and caches that bound function for repeated calls.
*/
function functionLazyBinder() {
const boundFunctions = {};
return (target, name) => {
if (typeof target[name] === "function") {
// Lazily cache function bindings.
if (boundFunctions[name]) {
return boundFunctions[name];
}
boundFunctions[name] = target[name].bind(target);
return boundFunctions[name];
}
return target[name];
};
}
// END MONKEY PATCH
//--------------------------------------------------------------------------------------
ReactDOM = monkeyPatchReactDOM(ReactDOM);
var ReactDOM$2 = Object.freeze({
default: ReactDOM
});

View File

@ -12918,169 +12918,6 @@ var foundDevTools = DOMRenderer.injectIntoDevTools({
rendererPackageName: 'react-dom'
});
//--------------------------------------------------------------------------------------
// START MONKEY PATCH
/**
* This section contains a monkey patch for React DOM, so that it functions correctly in
* certain XUL situations. React centralizes events to specific DOM nodes by only
* binding a single listener to the document of the page. It then captures these events,
* and then uses a SyntheticEvent system to dispatch these throughout the page.
*
* In privileged XUL with a XUL iframe, and React in both documents, this system breaks.
* By design, these XUL frames can still talk to each other, while in a normal HTML
* situation, they would not be able to. The events from the XUL iframe propagate to the
* parent document as well. This leads to the React event system incorrectly dispatching
* TWO SyntheticEvents for for every ONE action.
*
* The fix here is trick React into thinking that the owning document for every node in
* a XUL iframe to be the toolbox.xul. This is done by creating a Proxy object that
* captures any usage of HTMLElement.ownerDocument, and then passing in the toolbox.xul
* document rather than (for example) the netmonitor.xul document. React will then hook
* up the event system correctly on the top level controlling document.
*
* @return {object} The proxied and monkey patched ReactDOM
*/
function monkeyPatchReactDOM(ReactDOM) {
// This is the actual monkey patched function.
const reactDomRender = monkeyPatchRender(ReactDOM);
// Proxied method calls might need to be bound, but do this lazily with caching.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy, but the render property is not writable on the ReactDOM object, so
// a direct proxy will fail with an error. Instead, create a proxy on a a blank object.
// Pass on getting and setting behaviors.
return new Proxy({}, {
get: (target, name) => {
if (name === "render") {
return reactDomRender;
}
return lazyFunctionBinding(ReactDOM, name);
},
set: (target, name, value) => {
ReactDOM[name] = value;
return true;
}
});
};
/**
* Creates a function that replaces the ReactDOM.render method. It does this by
* creating a proxy for the dom node being mounted. This proxy rewrites the
* "ownerDocument" property to point to the toolbox.xul document. This function
* is only used for XUL iframes inside of a XUL document.
*
* @param {object} ReactDOM
* @return {function} The patched ReactDOM.render function.
*/
function monkeyPatchRender(ReactDOM) {
const elementProxyCache = new WeakMap();
return (...args) => {
const container = args[1];
const toolboxDoc = getToolboxDocIfXulOnly(container);
if (toolboxDoc) {
// Re-use any existing cached HTMLElement proxies.
let proxy = elementProxyCache.get(container);
if (!proxy) {
// Proxied method calls need to be bound, but do this lazily.
const lazyFunctionBinding = functionLazyBinder();
// Create a proxy to the container HTMLElement. If React tries to access the
// ownerDocument, pass in the toolbox's document, as the event dispatching system
// is rooted from the toolbox document.
proxy = new Proxy(container, {
get: function (target, name) {
if (name === "ownerDocument") {
return toolboxDoc;
}
return lazyFunctionBinding(target, name);
}
});
elementProxyCache.set(container, proxy);
}
// Update the args passed to ReactDOM.render.
args[1] = proxy;
}
return ReactDOM.render.apply(this, args);
};
}
/**
* Try to access the containing toolbox XUL document, but only if all of the iframes
* in the heirarchy are XUL documents. Events dispatch differently in the case of all
* privileged XUL documents. Events that fire in an iframe propagate up to the parent
* frame. This does not happen when HTML is in the mix. Only return the toolbox if
* it matches the proper case of a XUL iframe inside of a XUL document.
*
* In addition to the XUL case, if the panel uses the toolbox's ReactDOM instance,
* this patch needs to be applied as well. This is the case for the inspector.
*
* @param {HTMLElement} node - The DOM node inside of an iframe.
* @return {XULDocument|null} The toolbox.xul document, or null.
*/
function getToolboxDocIfXulOnly(node) {
// This execution context doesn't know about XULDocuments, so don't get the toolbox.
if (typeof XULDocument !== "function") {
return null;
}
let doc = node.ownerDocument;
const inspectorUrl = "chrome://devtools/content/inspector/inspector.xhtml";
const netMonitorUrl = "chrome://devtools/content/netmonitor/netmonitor.xhtml";
const webConsoleUrl = "chrome://devtools/content/webconsole/webconsole.xhtml";
while (doc instanceof XULDocument ||
doc.location.href === inspectorUrl ||
doc.location.href === netMonitorUrl ||
doc.location.href === webConsoleUrl) {
const {frameElement} = doc.defaultView;
if (!frameElement) {
// We're at the root element, and no toolbox was found.
return null;
}
doc = frameElement.parentElement.ownerDocument;
if (doc.documentURI === "about:devtools-toolbox") {
return doc;
}
}
return null;
}
/**
* When accessing proxied functions, the instance becomes unbound to the method. This
* utility either passes a value through if it's not a function, or automatically binds a
* function and caches that bound function for repeated calls.
*/
function functionLazyBinder() {
const boundFunctions = {};
return (target, name) => {
if (typeof target[name] === "function") {
// Lazily cache function bindings.
if (boundFunctions[name]) {
return boundFunctions[name];
}
boundFunctions[name] = target[name].bind(target);
return boundFunctions[name];
}
return target[name];
};
}
// END MONKEY PATCH
//--------------------------------------------------------------------------------------
ReactDOM = monkeyPatchReactDOM(ReactDOM);
var ReactDOM$2 = Object.freeze({
default: ReactDOM
});

View File

@ -162,6 +162,7 @@ skip-if = (e10s && (os == 'win' || os == 'mac')) # Bug 1243976
[browser_console.js]
[browser_console_addonsdk_loader_exception.js]
[browser_console_certificate_imminent_distrust.js]
disabled=bug 1439378 to re-enable due to nss cert/key db upgrade issue
[browser_console_clear_method.js]
[browser_console_clear_on_reload.js]
[browser_console_click_focus.js]

View File

@ -152,8 +152,9 @@ this.DevToolsShim = {
return;
}
let {scratchpads, browserConsole} = session;
let hasDevToolsData = browserConsole || (scratchpads && scratchpads.length);
let {scratchpads, browserConsole, browserToolbox} = session;
let hasDevToolsData = browserConsole || browserToolbox ||
(scratchpads && scratchpads.length);
if (!hasDevToolsData) {
// Do not initialize DevTools unless there is DevTools specific data in the session.
return;

View File

@ -35,7 +35,6 @@
#include "nsIDOMFileList.h"
#include "nsIDOMMouseEvent.h"
#include "nsIFormControl.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIImageLoadingContent.h"
#include "nsIWebNavigation.h"
#include "nsIPresShell.h"

View File

@ -1126,9 +1126,6 @@ waitForAllPaints(() => {
div.style.display = '';
// We need to wait a frame to unapply display:none style.
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Script animations restored from "display: none" state should update ' +
@ -1163,12 +1160,14 @@ waitForAllPaints(() => {
div.style.display = '';
// We need to wait a frame to unapply display:none style.
await waitForNextFrame();
var markers = await observeStyling(1);
is(markers.length, 1,
'Script animations restored from "display: none" state should update ' +
'styles soon');
ok(SpecialPowers.wrap(animation).isRunningOnCompositor,
'Opacity script animations restored from "display: none" should be ' +
'run on the compositor');
'run on the compositor in the next frame');
await ensureElementRemoval(div);
});

View File

@ -135,7 +135,6 @@
#include "nsIDOMDocumentType.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMWindowUtils.h"
@ -1060,7 +1059,7 @@ nsContentUtils::Atob(const nsAString& aAsciiBase64String,
}
bool
nsContentUtils::IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput)
nsContentUtils::IsAutocompleteEnabled(mozilla::dom::HTMLInputElement* aInput)
{
NS_PRECONDITION(aInput, "aInput should not be null!");
@ -1068,8 +1067,7 @@ nsContentUtils::IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput)
aInput->GetAutocomplete(autocomplete);
if (autocomplete.IsEmpty()) {
nsCOMPtr<nsIDOMHTMLFormElement> form;
aInput->GetForm(getter_AddRefs(form));
auto* form = aInput->GetForm();
if (!form) {
return true;
}

View File

@ -73,7 +73,6 @@ class nsIDocumentLoaderFactory;
class nsIDOMDocument;
class nsIDOMDocumentFragment;
class nsIDOMEvent;
class nsIDOMHTMLInputElement;
class nsIDOMNode;
class nsIDragSession;
class nsIEventTarget;
@ -135,6 +134,7 @@ struct CustomElementDefinition;
class DocumentFragment;
class Element;
class EventTarget;
class HTMLInputElement;
class IPCDataTransfer;
class IPCDataTransferItem;
struct LifecycleCallbackArgs;
@ -2634,7 +2634,7 @@ public:
* @param aInput the input element to check. NOTE: aInput can't be null.
* @return whether the input element has autocomplete enabled.
*/
static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
static bool IsAutocompleteEnabled(mozilla::dom::HTMLInputElement* aInput);
enum AutocompleteAttrState : uint8_t
{

View File

@ -115,7 +115,6 @@
#include "nsFocusManager.h"
// for radio group stuff
#include "nsIDOMHTMLInputElement.h"
#include "nsIRadioVisitor.h"
#include "nsIFormControl.h"

View File

@ -18,13 +18,13 @@
#include "nsGlobalWindow.h"
#include "nsFocusManager.h"
#include "nsIContent.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIControllers.h"
#include "nsIController.h"
#include "xpcpublic.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/HTMLTextAreaElement.h"
#include "mozilla/dom/HTMLInputElement.h"
#ifdef MOZ_XUL
#include "nsXULElement.h"
@ -238,8 +238,8 @@ nsWindowRoot::GetControllers(bool aForVisibleWindow,
if (htmlTextArea)
return htmlTextArea->GetControllers(aResult);
nsCOMPtr<nsIDOMHTMLInputElement> htmlInputElement =
do_QueryInterface(focusedContent);
HTMLInputElement* htmlInputElement =
HTMLInputElement::FromContent(focusedContent);
if (htmlInputElement)
return htmlInputElement->GetControllers(aResult);

View File

@ -5562,7 +5562,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, double aX,
}
// Flush layout updates
if (!(aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH)) {
if (!(aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_DO_NOT_FLUSH)) {
nsContentUtils::FlushLayoutForTree(aWindow.AsInner()->GetOuterWindow());
}
@ -5597,20 +5597,20 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, double aX,
nsPresContext::CSSPixelsToAppUnits((float)aH));
uint32_t renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
nsIPresShell::RENDER_DOCUMENT_RELATIVE);
if (aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
if (aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_DRAW_CARET) {
renderDocFlags |= nsIPresShell::RENDER_CARET;
}
if (aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
if (aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_DRAW_VIEW) {
renderDocFlags &= ~(nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
nsIPresShell::RENDER_DOCUMENT_RELATIVE);
}
if (aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_USE_WIDGET_LAYERS) {
if (aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_USE_WIDGET_LAYERS) {
renderDocFlags |= nsIPresShell::RENDER_USE_WIDGET_LAYERS;
}
if (aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_ASYNC_DECODE_IMAGES) {
if (aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_ASYNC_DECODE_IMAGES) {
renderDocFlags |= nsIPresShell::RENDER_ASYNC_DECODE_IMAGES;
}
if (aFlags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) {
if (aFlags & CanvasRenderingContext2DBinding::DRAWWINDOW_DO_NOT_FLUSH) {
renderDocFlags |= nsIPresShell::RENDER_DRAWWINDOW_NOT_FLUSHING;
}

View File

@ -7,7 +7,6 @@
#include "mozilla/Attributes.h"
#include <vector>
#include "nsIDOMCanvasRenderingContext2D.h"
#include "nsICanvasRenderingContextInternal.h"
#include "mozilla/RefPtr.h"
#include "nsColor.h"

View File

@ -9,7 +9,6 @@
#include "nsIServiceManager.h"
#include "nsIConsoleService.h"
#include "nsIDOMCanvasRenderingContext2D.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsIHTMLCollection.h"
#include "mozilla/dom/HTMLCanvasElement.h"

View File

@ -7,8 +7,6 @@
#ifndef mozilla_dom_ImageData_h
#define mozilla_dom_ImageData_h
#include "nsIDOMCanvasRenderingContext2D.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/TypedArray.h"

View File

@ -1637,7 +1637,7 @@ HTMLFormElement::GetActionURL(nsIURI** aActionURL,
"The originating element must be a submit form control!");
#endif // DEBUG
nsCOMPtr<nsIDOMHTMLInputElement> inputElement = do_QueryInterface(aOriginatingElement);
HTMLInputElement* inputElement = HTMLInputElement::FromContent(aOriginatingElement);
if (inputElement) {
inputElement->GetFormAction(action);
} else {

View File

@ -18,7 +18,6 @@
#include "nsAttrValueInlines.h"
#include "nsCRTGlue.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsITextControlElement.h"
#include "nsIDOMNSEditableElement.h"
#include "nsIRadioVisitor.h"
@ -258,13 +257,13 @@ public:
{
nsresult rv = NS_OK;
rv = nsContentUtils::DispatchTrustedEvent(mInputElement->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInputElement.get()),
static_cast<Element*>(mInputElement.get()),
NS_LITERAL_STRING("input"), true,
false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed");
rv = nsContentUtils::DispatchTrustedEvent(mInputElement->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInputElement.get()),
static_cast<Element*>(mInputElement.get()),
NS_LITERAL_STRING("change"), true,
false);
@ -760,7 +759,7 @@ nsColorPickerShownCallback::UpdateInternal(const nsAString& aColor,
if (valueChanged) {
mValueChanged = true;
return nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
static_cast<Element*>(mInput.get()),
NS_LITERAL_STRING("input"), true,
false);
}
@ -794,7 +793,7 @@ nsColorPickerShownCallback::Done(const nsAString& aColor)
if (mValueChanged) {
rv = nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
static_cast<Element*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
}
@ -1086,7 +1085,7 @@ UploadLastDir::Observe(nsISupports* aSubject, char const* aTopic, char16_t const
#ifdef ACCESSIBILITY
//Helper method
static nsresult FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
static nsresult FireEventForAccessibility(HTMLInputElement* aTarget,
nsPresContext* aPresContext,
EventMessage aEventMessage);
#endif
@ -1548,23 +1547,11 @@ HTMLInputElement::AfterClearForm(bool aUnbindOrDelete)
}
}
// nsIDOMHTMLInputElement
NS_IMETHODIMP
HTMLInputElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
return nsGenericHTMLFormElementWithState::GetForm(aForm);
}
NS_IMPL_ACTION_ATTR(HTMLInputElement, FormAction, formaction)
NS_IMPL_STRING_ATTR(HTMLInputElement, Name, name)
NS_IMPL_BOOL_ATTR(HTMLInputElement, ReadOnly, readonly)
NS_IMETHODIMP
void
HTMLInputElement::GetAutocomplete(nsAString& aValue)
{
if (!DoesAutocompleteApply()) {
return NS_OK;
return;
}
aValue.Truncate();
@ -1573,7 +1560,6 @@ HTMLInputElement::GetAutocomplete(nsAString& aValue)
mAutocompleteAttrState =
nsContentUtils::SerializeAutocompleteAttribute(attributeVal, aValue,
mAutocompleteAttrState);
return NS_OK;
}
void
@ -1630,13 +1616,6 @@ HTMLInputElement::Height()
return GetWidthHeightForImage(mCurrentRequest).height;
}
NS_IMETHODIMP
HTMLInputElement::GetIndeterminate(bool* aValue)
{
*aValue = Indeterminate();
return NS_OK;
}
void
HTMLInputElement::SetIndeterminateInternal(bool aValue,
bool aShouldInvalidate)
@ -1653,11 +1632,10 @@ HTMLInputElement::SetIndeterminateInternal(bool aValue,
UpdateState(true);
}
NS_IMETHODIMP
void
HTMLInputElement::SetIndeterminate(bool aValue)
{
SetIndeterminateInternal(aValue, true);
return NS_OK;
}
uint32_t
@ -2408,7 +2386,7 @@ HTMLInputElement::OpenDateTimePicker(const DateTimeValue& aInitialValue)
mDateTimeInputBoxValue = new DateTimeValue(aInitialValue);
nsContentUtils::DispatchChromeEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("MozOpenDateTimePicker"),
true, true);
}
@ -2422,7 +2400,7 @@ HTMLInputElement::UpdateDateTimePicker(const DateTimeValue& aValue)
mDateTimeInputBoxValue = new DateTimeValue(aValue);
nsContentUtils::DispatchChromeEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("MozUpdateDateTimePicker"),
true, true);
}
@ -2435,7 +2413,7 @@ HTMLInputElement::CloseDateTimePicker()
}
nsContentUtils::DispatchChromeEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("MozCloseDateTimePicker"),
true, true);
}
@ -2529,7 +2507,7 @@ HTMLInputElement::SetUserInput(const nsAString& aValue)
}
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("input"), true,
true);
@ -3110,13 +3088,6 @@ HTMLInputElement::SetValueChanged(bool aValueChanged)
return NS_OK;
}
NS_IMETHODIMP
HTMLInputElement::GetChecked(bool* aChecked)
{
*aChecked = Checked();
return NS_OK;
}
void
HTMLInputElement::SetCheckedChanged(bool aCheckedChanged)
{
@ -3152,11 +3123,10 @@ HTMLInputElement::SetCheckedChangedInternal(bool aCheckedChanged)
}
}
NS_IMETHODIMP
void
HTMLInputElement::SetChecked(bool aChecked)
{
DoSetChecked(aChecked, true, true);
return NS_OK;
}
void
@ -3205,14 +3175,13 @@ void
HTMLInputElement::RadioSetChecked(bool aNotify)
{
// Find the selected radio button so we can deselect it
nsCOMPtr<nsIDOMHTMLInputElement> currentlySelected = GetSelectedRadioButton();
HTMLInputElement* currentlySelected = GetSelectedRadioButton();
// Deselect the currently selected radio button
if (currentlySelected) {
// Pass true for the aNotify parameter since the currently selected
// button is already in the document.
static_cast<HTMLInputElement*>(currentlySelected.get())
->SetCheckedInternal(false, true);
currentlySelected->SetCheckedInternal(false, true);
}
// Let the group know that we are now the One True Radio Button
@ -3249,7 +3218,7 @@ HTMLInputElement::GetRadioGroupContainer() const
return static_cast<nsDocument*>(GetUncomposedDoc());
}
already_AddRefed<nsIDOMHTMLInputElement>
HTMLInputElement*
HTMLInputElement::GetSelectedRadioButton() const
{
nsIRadioGroupContainer* container = GetRadioGroupContainer();
@ -3260,8 +3229,8 @@ HTMLInputElement::GetSelectedRadioButton() const
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMHTMLInputElement> selected = container->GetCurrentRadioButton(name);
return selected.forget();
HTMLInputElement* selected = container->GetCurrentRadioButton(name);
return selected;
}
nsresult
@ -3628,7 +3597,7 @@ HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
aVisitor.mItemFlags |= NS_ORIGINAL_INDETERMINATE_VALUE;
}
GetChecked(&originalCheckedValue);
originalCheckedValue = Checked();
DoSetChecked(!originalCheckedValue, true, true);
mCheckedIsToggled = true;
}
@ -3636,8 +3605,8 @@ HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
case NS_FORM_INPUT_RADIO:
{
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton = GetSelectedRadioButton();
aVisitor.mItemData = selectedRadioButton;
HTMLInputElement* selectedRadioButton = GetSelectedRadioButton();
aVisitor.mItemData = static_cast<Element*>(selectedRadioButton);
originalCheckedValue = mChecked;
if (!originalCheckedValue) {
@ -3982,7 +3951,7 @@ HTMLInputElement::SetValueOfRangeForUserEvent(Decimal aValue)
if (GetValueAsDecimal() != oldValue) {
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("input"), true,
false);
}
@ -4080,7 +4049,7 @@ HTMLInputElement::StepNumberControlForUserEvent(int32_t aDirection)
nsTextEditorState::eSetValue_Notify);
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
static_cast<Element*>(this),
NS_LITERAL_STRING("input"), true,
false);
}
@ -4271,8 +4240,9 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
// selected btn to TRUE. if it is a checkbox then set it to its
// original value
if (oldType == NS_FORM_INPUT_RADIO) {
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton =
do_QueryInterface(aVisitor.mItemData);
nsCOMPtr<nsIContent> content = do_QueryInterface(aVisitor.mItemData);
HTMLInputElement* selectedRadioButton =
HTMLInputElement::FromContentOrNull(content);
if (selectedRadioButton) {
selectedRadioButton->SetChecked(true);
}
@ -4291,11 +4261,11 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
} else {
// Fire input event and then change event.
nsContentUtils::DispatchTrustedEvent<InternalEditorInputEvent>
(OwnerDoc(), static_cast<nsIDOMHTMLInputElement*>(this),
(OwnerDoc(), static_cast<Element*>(this),
eEditorInput, true, false);
nsContentUtils::DispatchTrustedEvent<WidgetEvent>
(OwnerDoc(), static_cast<nsIDOMHTMLInputElement*>(this),
(OwnerDoc(), static_cast<Element*>(this),
eFormChange, true, false);
#ifdef ACCESSIBILITY
// Fire an event to notify accessibility
@ -4306,8 +4276,9 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
FireEventForAccessibility(this, aVisitor.mPresContext,
eFormRadioStateChange);
// Fire event for the previous selected radio.
nsCOMPtr<nsIDOMHTMLInputElement> previous =
do_QueryInterface(aVisitor.mItemData);
nsCOMPtr<nsIContent> content = do_QueryInterface(aVisitor.mItemData);
HTMLInputElement* previous =
HTMLInputElement::FromContentOrNull(content);
if (previous) {
FireEventForAccessibility(previous, aVisitor.mPresContext,
eFormRadioStateChange);
@ -6022,7 +5993,7 @@ HTMLInputElement::GetControllers(ErrorResult& aRv)
return mControllers;
}
NS_IMETHODIMP
nsresult
HTMLInputElement::GetControllers(nsIControllers** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
@ -6216,13 +6187,13 @@ HTMLInputElement::SetSelectionDirection(const nsAString& aDirection, ErrorResult
#ifdef ACCESSIBILITY
/*static*/ nsresult
FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
FireEventForAccessibility(HTMLInputElement* aTarget,
nsPresContext* aPresContext,
EventMessage aEventMessage)
{
nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aTarget);
Element* element = static_cast<Element*>(aTarget);
return nsContentUtils::DispatchTrustedEvent<WidgetEvent>
(element->OwnerDoc(), aTarget, aEventMessage, true, true);
(element->OwnerDoc(), element, aEventMessage, true, true);
}
#endif
@ -6526,7 +6497,7 @@ HTMLInputElement::IntrinsicState() const
}
if (mType == NS_FORM_INPUT_RADIO) {
nsCOMPtr<nsIDOMHTMLInputElement> selected = GetSelectedRadioButton();
HTMLInputElement* selected = GetSelectedRadioButton();
bool indeterminate = !selected && !mChecked;
if (indeterminate) {
@ -7235,7 +7206,7 @@ HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
"This should be called only for radio input types");
bool notify = mDoneCreating;
nsCOMPtr<nsIDOMHTMLInputElement> selection = GetSelectedRadioButton();
HTMLInputElement* selection = GetSelectedRadioButton();
aIgnoreSelf = aIgnoreSelf || !IsMutable();

View File

@ -297,7 +297,7 @@ public:
*
* @return the selected button (or null).
*/
already_AddRefed<nsIDOMHTMLInputElement> GetSelectedRadioButton() const;
HTMLInputElement* GetSelectedRadioButton() const;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
@ -482,7 +482,7 @@ public:
SetHTMLAttr(nsGkAtoms::alt, aValue, aRv);
}
// XPCOM GetAutocomplete() is OK
void GetAutocomplete(nsAString& aValue);
void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv)
{
SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
@ -514,7 +514,7 @@ public:
{
return mChecked;
}
// XPCOM SetChecked() is OK
void SetChecked(bool aChecked);
bool Disabled() const
{
@ -526,12 +526,9 @@ public:
SetHTMLBoolAttr(nsGkAtoms::disabled, aValue, aRv);
}
// XPCOM GetForm() is OK
FileList* GetFiles();
void SetFiles(FileList* aFiles);
// XPCOM GetFormAction() is OK
void SetFormAction(const nsAString& aValue, ErrorResult& aRv)
{
SetHTMLAttr(nsGkAtoms::formaction, aValue, aRv);
@ -584,8 +581,7 @@ public:
{
return mIsDraggingRange;
}
// XPCOM SetIndeterminate() is OK
void SetIndeterminate(bool aValue);
void GetInputMode(nsAString& aValue);
void SetInputMode(const nsAString& aValue, ErrorResult& aRv)
@ -655,7 +651,10 @@ public:
SetHTMLBoolAttr(nsGkAtoms::multiple, aValue, aRv);
}
// XPCOM GetName() is OK
void GetName(nsAString& aValue)
{
GetHTMLAttr(nsGkAtoms::name, aValue);
}
void SetName(const nsAString& aValue, ErrorResult& aRv)
{
SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
@ -860,6 +859,8 @@ public:
}
nsIControllers* GetControllers(ErrorResult& aRv);
// XPCOM adapter function widely used throughout code, leaving it as is.
nsresult GetControllers(nsIControllers** aResult);
int32_t InputTextLength(CallerType aCallerType);

View File

@ -19,7 +19,6 @@
#include "nsContentCreatorFunctions.h"
#include "nsTextControlFrame.h"
#include "nsIControllers.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsITransactionManager.h"
#include "nsIControllerContext.h"
#include "nsAttrValue.h"
@ -884,7 +883,7 @@ DoCommandCallback(Command aCommand, void* aData)
nsIContent *content = frame->GetContent();
nsCOMPtr<nsIControllers> controllers;
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(content);
HTMLInputElement* input = HTMLInputElement::FromContent(content);
if (input) {
input->GetControllers(getter_AddRefs(controllers));
} else {
@ -1414,12 +1413,12 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
if (!SuppressEventHandlers(presContext)) {
nsCOMPtr<nsIControllers> controllers;
nsCOMPtr<nsIDOMHTMLInputElement> inputElement =
do_QueryInterface(mTextCtrlElement);
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
HTMLInputElement* inputElement =
HTMLInputElement::FromContentOrNull(content);
if (inputElement) {
rv = inputElement->GetControllers(getter_AddRefs(controllers));
} else {
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
HTMLTextAreaElement* textAreaElement =
HTMLTextAreaElement::FromContentOrNull(content);
@ -2073,13 +2072,13 @@ nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame)
if (!SuppressEventHandlers(mBoundFrame->PresContext()))
{
nsCOMPtr<nsIControllers> controllers;
nsCOMPtr<nsIDOMHTMLInputElement> inputElement =
do_QueryInterface(mTextCtrlElement);
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
HTMLInputElement* inputElement =
HTMLInputElement::FromContentOrNull(content);
if (inputElement)
inputElement->GetControllers(getter_AddRefs(controllers));
else
{
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
HTMLTextAreaElement* textAreaElement =
HTMLTextAreaElement::FromContentOrNull(content);
if (textAreaElement) {

View File

@ -11,7 +11,6 @@ with Files("nsIDOMWebGLRenderingContext.idl"):
BUG_COMPONENT = ("Core", "Canvas: WebGL")
XPIDL_SOURCES += [
'nsIDOMCanvasRenderingContext2D.idl',
'nsIDOMWebGLRenderingContext.idl',
]

View File

@ -1,33 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
/**
* This interface remains only for the constants, for a context, use the
* WebIDL/Paris bindings instead (CanvasRenderingContext2D.webidl).
* The constants are used by CanvasRenderingContext2D::DrawWindow and are
* used in WindowsPreviewPerTab.jsm and some extensions. The constants can
* be referenced directly via a canvas context 2d rather than this interface,
* and that should be preferred in new code.
*/
[uuid(4417cab7-c7eb-4e0c-b00a-c43842f0cba8)]
interface nsIDOMCanvasRenderingContext2D : nsISupports
{
// Show the caret if appropriate when drawing
const unsigned long DRAWWINDOW_DRAW_CARET = 0x01;
// Don't flush pending layout notifications that could otherwise
// be batched up
const unsigned long DRAWWINDOW_DO_NOT_FLUSH = 0x02;
// Draw scrollbars and scroll the viewport if they are present
const unsigned long DRAWWINDOW_DRAW_VIEW = 0x04;
// Use the widget layer manager if available. This means hardware
// acceleration may be used, but it might actually be slower or
// lower quality than normal. It will however more accurately reflect
// the pixels rendered to the screen.
const unsigned long DRAWWINDOW_USE_WIDGET_LAYERS = 0x08;
// Don't synchronously decode images - draw what we have
const unsigned long DRAWWINDOW_ASYNC_DECODE_IMAGES = 0x10;
};

View File

@ -23,16 +23,4 @@ interface nsIDOMHTMLFormElement;
[uuid(64aeda0b-e9b5-4868-a4f9-e4776e32e733)]
interface nsIDOMHTMLInputElement : nsISupports
{
readonly attribute DOMString autocomplete;
attribute boolean checked;
readonly attribute nsIDOMHTMLFormElement form;
attribute DOMString formAction;
attribute boolean indeterminate;
attribute DOMString name;
attribute boolean readOnly;
readonly attribute nsIControllers controllers;
};

View File

@ -2072,9 +2072,7 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
Unused << SendShareCodeCoverageMutex(CodeCoverageHandler::Get()->GetMutexHandle(procId));
#endif
InitInternal(aInitialPriority,
true, /* Setup off-main thread compositing */
true /* Send registered chrome */);
InitInternal(aInitialPriority);
ContentProcessManager::GetSingleton()->AddContentProcess(this);
@ -2168,9 +2166,7 @@ ContentParent::~ContentParent()
}
void
ContentParent::InitInternal(ProcessPriority aInitialPriority,
bool aSetupOffMainThreadCompositing,
bool aSendRegisteredChrome)
ContentParent::InitInternal(ProcessPriority aInitialPriority)
{
Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS,
static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS)
@ -2298,12 +2294,10 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache,
fontList);
if (aSendRegisteredChrome) {
nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
nsChromeRegistryChrome* chromeRegistry =
static_cast<nsChromeRegistryChrome*>(registrySvc.get());
chromeRegistry->SendRegisteredChrome(this);
}
nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
nsChromeRegistryChrome* chromeRegistry =
static_cast<nsChromeRegistryChrome*>(registrySvc.get());
chromeRegistry->SendRegisteredChrome(this);
if (gAppData) {
nsCString version(gAppData->version);
@ -2336,41 +2330,37 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
// must come after the Open() call above.
ProcessPriorityManager::SetProcessPriority(this, aInitialPriority);
if (aSetupOffMainThreadCompositing) {
// NB: internally, this will send an IPC message to the child
// process to get it to create the CompositorBridgeChild. This
// message goes through the regular IPC queue for this
// channel, so delivery will happen-before any other messages
// we send. The CompositorBridgeChild must be created before any
// PBrowsers are created, because they rely on the Compositor
// already being around. (Creation is async, so can't happen
// on demand.)
GPUProcessManager* gpm = GPUProcessManager::Get();
// NB: internally, this will send an IPC message to the child
// process to get it to create the CompositorBridgeChild. This
// message goes through the regular IPC queue for this
// channel, so delivery will happen-before any other messages
// we send. The CompositorBridgeChild must be created before any
// PBrowsers are created, because they rely on the Compositor
// already being around. (Creation is async, so can't happen
// on demand.)
GPUProcessManager* gpm = GPUProcessManager::Get();
Endpoint<PCompositorManagerChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
AutoTArray<uint32_t, 3> namespaces;
Endpoint<PCompositorManagerChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
AutoTArray<uint32_t, 3> namespaces;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
&vrBridge,
&videoManager,
&namespaces);
MOZ_ASSERT(opened);
DebugOnly<bool> opened = gpm->CreateContentBridges(OtherPid(),
&compositor,
&imageBridge,
&vrBridge,
&videoManager,
&namespaces);
MOZ_ASSERT(opened);
Unused << SendInitRendering(
Move(compositor),
Move(imageBridge),
Move(vrBridge),
Move(videoManager),
namespaces);
Unused << SendInitRendering(Move(compositor),
Move(imageBridge),
Move(vrBridge),
Move(videoManager),
namespaces);
gpm->AddListener(this);
}
gpm->AddListener(this);
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {

View File

@ -751,9 +751,7 @@ private:
bool LaunchSubprocess(hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND);
// Common initialization after sub process launch or adoption.
void InitInternal(ProcessPriority aPriority,
bool aSetupOffMainThreadCompositing,
bool aSendRegisteredChrome);
void InitInternal(ProcessPriority aPriority);
virtual ~ContentParent();

View File

@ -0,0 +1,39 @@
function playAndPostResult(test_case, parent_window) {
log("runTest " + test_case.name);
let element = document.createElement("video");
element.preload = "auto";
element.muted = test_case.muted;
element.src = "short.mp4";
element.id = "video";
document.body.appendChild(element);
element.play().then(
() => {
parent_window.postMessage({played: true}, "*");
},
() => {
parent_window.postMessage({played: false}, "*");
}
);
}
function nextEvent(eventTarget, eventName) {
return new Promise(function(resolve, reject) {
let f = function(event) {
eventTarget.removeEventListener(eventName, f, false);
resolve(event);
};
eventTarget.addEventListener(eventName, f, false);
});
}
function nextWindowMessage() {
return nextEvent(window, "message");
}
function log(msg) {
var log_pane = document.body;
log_pane.appendChild(document.createTextNode(msg));
log_pane.appendChild(document.createElement("br"));
}

View File

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Autoplay policy frame</title>
<script type="text/javascript" src="AutoplayTestUtils.js"></script>
<style>
video {
width: 50%;
height: 50%;
}
</style>
</head>
<body>
<script>
nextWindowMessage().then(
(event) => {
playAndPostResult(event.data, event.source);
});
</script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Autoplay policy window</title>
<style>
video {
width: 50%;
height: 50%;
}
</style>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="manifest.js"></script>
<script type="text/javascript" src="AutoplayTestUtils.js"></script>
</head>
<body>
<pre id="test">
<script>
function testAutoplayInWindow(test_case, parent_window) {
log("testAutoplayInWindow: " + test_case.name);
playAndPostResult(test_case, parent_window);
}
async function testAutoplayInChildFrame(test_case, parent_window) {
log("testAutoplayInChildFrame: " + test_case.name);
// Create a child iframe...
var frame = document.createElement("iframe");
var origin = test_case.same_origin_child
? "http://mochi.test:8888" : "http://example.org";
frame.src = origin + "/tests/dom/media/test/file_autoplay_policy_activation_frame.html";
// Wait for it to load...
document.body.appendChild(frame);
await once(frame, "load");
// Click the iframe to activate if appropriate.
if (test_case.activated_child) {
synthesizeMouseAtCenter(frame, {});
}
// Ask the child iframe to try to play video.
frame.contentWindow.postMessage(test_case, "*");
// Wait for the iframe to tell us whether it could play video.
let result = await nextWindowMessage();
// Report whether the iframe could play to the parent.
parent_window.postMessage(result.data, "*");
}
nextWindowMessage().then(
(event) => {
let test_case = event.data;
// Click the window to activate if appropriate.
if (test_case.activated_parent) {
synthesizeMouseAtCenter(document.body, {});
}
let parent_window = event.source;
if (test_case.same_origin_child === undefined) {
testAutoplayInWindow(test_case, parent_window);
} else {
testAutoplayInChildFrame(test_case, parent_window);
}
});
</script>
</pre>
</body>
</html>

View File

@ -31,6 +31,7 @@ support-files =
320x240.ogv^headers^
448636.ogv
448636.ogv^headers^
AutoplayTestUtils.js
A4.ogv
A4.ogv^headers^
VID_0001.ogg
@ -437,6 +438,8 @@ support-files =
dynamic_resource.sjs
eme.js
file_access_controls.html
file_autoplay_policy_activation_window.html
file_autoplay_policy_activation_frame.html
flac-s24.flac
flac-s24.flac^headers^
flac-noheader-s16.flac
@ -684,6 +687,8 @@ skip-if = true # bug 475110 - disabled since we don't play Wave files standalone
skip-if = android_version == '15' || android_version == '17' || android_version == '22' # android(bug 1232305, bug 1232318, bug 1372457)
[test_autoplay_policy.html]
skip-if = android_version == '23' # bug 1424903
[test_autoplay_policy_activation.html]
skip-if = android_version == '23' # bug 1424903
[test_buffered.html]
skip-if = android_version == '15' || android_version == '22' # bug 1308388, android(bug 1232305)
[test_bug448534.html]

View File

@ -0,0 +1,158 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Autoplay policy test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
<script type="text/javascript" src="AutoplayTestUtils.js"></script>
</head>
<body>
<pre id="test">
<script>
// Tests that videos can only play audibly in windows/frames
// which have been activated by same-origin user gesture.
gTestPrefs.push(["media.autoplay.enabled", false],
["media.autoplay.enabled.user-gestures-needed", true]);
SpecialPowers.pushPrefEnv({'set': gTestPrefs}, () => {
runTest();
});
let test_cases = [
{
name: "inaudible playback in unactivated same-origin iframe in activated parent allowed",
muted: true,
same_origin_child: true,
activated_child: false,
activated_parent: true,
should_play: true,
},
{
name: "inaudible playback in unactivated same-origin iframe in unactivated parent allowed",
muted: true,
same_origin_child: true,
activated_child: false,
activated_parent: false,
should_play: true,
},
{
name: "audible playback in unactivated same-origin iframe in activated parent allowed",
muted: false,
same_origin_child: true,
activated_child: false,
activated_parent: true,
should_play: true,
},
{
name: "audible playback in unactivated same-origin iframe in unactivated parent blocked",
muted: false,
same_origin_child: true,
activated_child: false,
activated_parent: false,
should_play: false,
},
{
name: "inaudible playback in unactivated cross-origin iframe in activated parent allowed",
muted: true,
same_origin_child: false,
activated_child: false,
activated_parent: true,
should_play: true,
},
{
name: "inaudible playback in unactivated cross-origin iframe in unactivated parent allowed",
muted: true,
same_origin_child: false,
activated_child: false,
activated_parent: false,
should_play: true,
},
// TODO: This case fails, Firefox's behaviour needs to be fixed.
// {
// name: "audible playback in unactivated cross-origin iframe in activated parent blocked",
// muted: false,
// same_origin_child: false,
// activated_child: false,
// activated_parent: true,
// should_play: false,
// },
{
name: "audible playback in unactivated cross-origin iframe in unactivated parent blocked",
muted: false,
same_origin_child: false,
activated_child: false,
activated_parent: false,
should_play: false,
},
{
name: "audible playback in activated cross-origin iframe allowed",
muted: false,
same_origin_child: false,
activated_child: true,
activated_parent: false,
should_play: true,
},
{
name: "audible playback in activated document allowed",
muted: false,
activated_parent: true,
should_play: true,
},
{
name: "audible playback in unactivated document blocked",
muted: false,
activated_parent: false,
should_play: false,
},
{
name: "inaudible playback in activated document allowed",
muted: true,
activated_parent: true,
should_play: true,
},
{
name: "inaudible playback in unactivated document allowed",
muted: true,
activated_parent: false,
should_play: true,
},
];
let child_url = "file_autoplay_policy_activation_window.html";
async function runTest() {
for (test_case of test_cases) {
// Run each test in a new window, to ensure its user gesture
// activation state isn't tainted by preceeding tests.
let child = window.open(child_url, "", "width=500,height=500");
await once(child, "load");
child.postMessage(test_case, window.origin);
let result = await nextWindowMessage();
SimpleTest.is(result.data.played, test_case.should_play, test_case.name);
child.close();
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -106,6 +106,8 @@ skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emula
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_audioSynchronizationSources.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_audioSynchronizationSourcesUnidirectional.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_audioContributingSources.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_checkPacketDumpHook.html]

View File

@ -29,16 +29,20 @@
await waitForSyncSources(test);
let receivers = [...test.pcRemote.getReceivers(),
...test.pcLocal.getReceivers()];
is(receivers.length, 2,
`Expected number of receivers is 2. (${receivers.length})`);
for (let recv of receivers) {
let syncSources = recv.getSynchronizationSources();
ok(syncSources,
"Receiver has Synchronization sources " + JSON.stringify(syncSources));
is(syncSources.length, 1, "Each receiver has only a single sync source");
let source = recv.getSynchronizationSources()[0];
ok(source.audioLevel,
ok(source.audioLevel !== null,
`Synchronization source has audio level. (${source.audioLevel})`);
ok(source.audioLevel < 128,
`Synchronization source audio level < 128. (${source.audioLevel})`);
ok(source.audioLevel >= 0.0,
`Synchronization source audio level >= 0.0 (${source.audioLevel})`);
ok(source.audioLevel <= 1.0,
`Synchronization source audio level <= 1.0 (${source.audioLevel})`);
ok(source.timestamp,
`Synchronization source has timestamp (${source.timestamp})`);
ok(window.performance.now() + window.performance.timeOrigin -
@ -54,12 +58,22 @@
await waitForSyncSources(test);
let receivers = [...test.pcRemote.getReceivers(),
...test.pcLocal.getReceivers()];
is(receivers.length, 2, "Expected number of receivers");
for (let recv of receivers) {
is(JSON.stringify(recv.getSynchronizationSources()),
JSON.stringify(recv.getSynchronizationSources()),
"Subsequent getSynchronizationSources calls are cached.");
is(receivers.length, 2,
`Expected number of receivers is 2. (${receivers.length})`);
let sourceSets = [[],[]];
for (let sourceSet of sourceSets) {
for (let recv of receivers) {
let sources = recv.getSynchronizationSources();
ok(sources.length, 1,
`Expected number of sources is 1. (${sources.length})`);
sourceSet.push(sources);
}
// Busy wait 1s before trying again
let endTime = performance.now() + 1000;
while (performance.now() < endTime) {};
}
is(JSON.stringify(sourceSets[0]), JSON.stringify(sourceSets[1]),
"Subsequent getSynchronizationSources calls are cached.");
};
var test;

View File

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1439001",
title: "Test audio unidirectional getSynchronizationSources"
});
var waitForSyncSources = async (test) => {
let receiver = test.pcRemote.getReceivers()[0];
ok(receiver, "Remote has a receiver");
// Wait for remote sync source
while (receiver.getSynchronizationSources().length == 0) {
await wait(250);
}
is(receiver.getSynchronizationSources().length, 1,
"Remote receiver has a synchronization source");
// Make sure local has no sync source
is(test.pcLocal.getReceivers()[0].getSynchronizationSources().length, 0,
"Local receiver has no synchronization source");
};
/*
* Test to make sure that in unidirectional calls, the receiving end has
* synchronization sources with audio levels, and the sending end has none.
*/
var testGetSynchronizationSourcesUnidirectional = async (test) => {
await waitForSyncSources(test);
let receiver = test.pcRemote.getReceivers()[0];
let syncSources = receiver.getSynchronizationSources();
ok(syncSources.length > 0,
"Receiver has Synchronization sources " + JSON.stringify(syncSources));
is(syncSources.length, 1, "Receiver has only a single sync source");
let syncSource = syncSources[0];
ok(syncSource.audioLevel !== undefined, "SynchronizationSource has audioLevel");
};
var test;
runNetworkTest(function(options) {
test = new PeerConnectionTest(options);
test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
[testGetSynchronizationSourcesUnidirectional]);
test.setMediaConstraints([{audio: true}], []);
test.pcLocal.audioElementsOnly = true;
test.run();
});
</script>
</pre>
</body>
</html>

View File

@ -163,7 +163,8 @@ QuotaUsageRequestChild::HandleResponse(const nsTArray<OriginUsage>& aResponse)
RefPtr<UsageResult> usageResult = new UsageResult(originUsage.origin(),
originUsage.persisted(),
originUsage.usage());
originUsage.usage(),
originUsage.lastAccessed());
usageResults.AppendElement(usageResult.forget());
}

View File

@ -6979,6 +6979,8 @@ GetUsageOp::TraverseRepository(QuotaManager* aQuotaManager,
originUsage->persisted() = persisted;
}
originUsage->lastAccessed() = timestamp;
UsageInfo usageInfo;
rv = GetUsageForOrigin(aQuotaManager,
aPersistenceType,

View File

@ -13,6 +13,7 @@ struct OriginUsage
nsCString origin;
bool persisted;
uint64_t usage;
uint64_t lastAccessed;
};
struct AllUsageResponse

View File

@ -12,10 +12,12 @@ namespace quota {
UsageResult::UsageResult(const nsACString& aOrigin,
bool aPersisted,
uint64_t aUsage)
uint64_t aUsage,
uint64_t aLastAccessed)
: mOrigin(aOrigin)
, mUsage(aUsage)
, mPersisted(aPersisted)
, mLastAccessed(aLastAccessed)
{
}
@ -47,6 +49,15 @@ UsageResult::GetUsage(uint64_t* aUsage)
return NS_OK;
}
NS_IMETHODIMP
UsageResult::GetLastAccessed(uint64_t* aLastAccessed)
{
MOZ_ASSERT(aLastAccessed);
*aLastAccessed = mLastAccessed;
return NS_OK;
}
OriginUsageResult::OriginUsageResult(uint64_t aUsage,
uint64_t aFileUsage,
uint64_t aLimit)

View File

@ -19,11 +19,13 @@ class UsageResult
nsCString mOrigin;
uint64_t mUsage;
bool mPersisted;
uint64_t mLastAccessed;
public:
UsageResult(const nsACString& aOrigin,
bool aPersisted,
uint64_t aUsage);
uint64_t aUsage,
uint64_t aLastAccessed);
private:
virtual ~UsageResult()

View File

@ -14,6 +14,8 @@ interface nsIQuotaUsageResult : nsISupports
readonly attribute boolean persisted;
readonly attribute unsigned long long usage;
readonly attribute unsigned long long lastAccessed;
};
[scriptable, function, uuid(96df03d2-116a-493f-bb0b-118c212a6b32)]

View File

@ -30,7 +30,6 @@
#include "nsIContent.h"
#include "nsIDOMComment.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMProcessingInstruction.h"
@ -564,7 +563,7 @@ ResourceReader::OnWalkDOMNode(nsIDOMNode* aNode)
return OnWalkSubframe(aNode);
}
nsCOMPtr<nsIDOMHTMLInputElement> nodeAsInput = do_QueryInterface(aNode);
auto nodeAsInput = dom::HTMLInputElement::FromContent(content);
if (nodeAsInput) {
return OnWalkAttribute(aNode, "src");
}

View File

@ -22,7 +22,6 @@
#include "nsIControllers.h"
#include "nsXULElement.h"
#include "nsIURI.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsFocusManager.h"
#include "nsIFormControl.h"
#include "nsIDOMEventListener.h"
@ -48,6 +47,7 @@
#include "mozilla/TextEvents.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/EventHandlerBinding.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/HTMLTextAreaElement.h"
#include "mozilla/dom/KeyboardEvent.h"
#include "mozilla/dom/KeyboardEventBinding.h"
@ -682,7 +682,7 @@ nsXBLPrototypeHandler::GetController(EventTarget* aTarget)
}
if (!controllers) {
nsCOMPtr<nsIDOMHTMLInputElement> htmlInputElement(do_QueryInterface(aTarget));
HTMLInputElement* htmlInputElement = HTMLInputElement::FromContent(targetContent);
if (htmlInputElement)
htmlInputElement->GetControllers(getter_AddRefs(controllers));
}

View File

@ -42,7 +42,6 @@
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMNode.h"
#include "nsIDocument.h"
#include "nsIFile.h"

View File

@ -22,6 +22,7 @@
// to be able to hold on to a GLContext.
#include "mozilla/GenericRefCounted.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Path.h"
// This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
// outparams using the &-operator. But it will have to do as there's no easy
@ -1534,6 +1535,7 @@ struct Config {
class GFX2D_API Factory
{
using char_type = filesystem::Path::value_type;
public:
static void Init(const Config& aConfig);
static void ShutDown();
@ -1698,7 +1700,7 @@ public:
static already_AddRefed<DrawEventRecorder>
CreateEventRecorderForFile(const char *aFilename);
CreateEventRecorderForFile(const char_type* aFilename);
static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);

View File

@ -35,7 +35,7 @@ DrawEventRecorderMemory::RecordEvent(const RecordedEvent &aEvent)
aEvent.RecordToStream(mOutputStream);
}
DrawEventRecorderFile::DrawEventRecorderFile(const char *aFilename)
DrawEventRecorderFile::DrawEventRecorderFile(const char_type* aFilename)
: mOutputStream(aFilename, ofstream::binary)
{
WriteHeader(mOutputStream);
@ -59,7 +59,7 @@ DrawEventRecorderFile::IsOpen()
}
void
DrawEventRecorderFile::OpenNew(const char *aFilename)
DrawEventRecorderFile::OpenNew(const char_type* aFilename)
{
MOZ_ASSERT(!mOutputStream.is_open());

View File

@ -10,8 +10,7 @@
#include "2D.h"
#include "RecordedEvent.h"
#include "RecordingTypes.h"
#include <ostream>
#include <fstream>
#include "mozilla/FStream.h"
#include <unordered_set>
#include <unordered_map>
@ -129,9 +128,10 @@ protected:
class DrawEventRecorderFile : public DrawEventRecorderPrivate
{
using char_type = filesystem::Path::value_type;
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile, override)
explicit DrawEventRecorderFile(const char *aFilename);
explicit DrawEventRecorderFile(const char_type* aFilename);
~DrawEventRecorderFile();
void RecordEvent(const RecordedEvent &aEvent) override;
@ -146,7 +146,7 @@ public:
* objects it has recorded. This can be used with Close, so that a recording
* can be processed in chunks. The file must not already be open.
*/
void OpenNew(const char *aFilename);
void OpenNew(const char_type* aFilename);
/**
* Closes the file so that it can be processed. The recorder does NOT forget
@ -158,7 +158,7 @@ public:
private:
void Flush() override;
std::ofstream mOutputStream;
mozilla::OFStream mOutputStream;
};
typedef std::function<void(MemStream &aStream, std::vector<RefPtr<UnscaledFont>> &aUnscaledFonts)> SerializeResourcesFn;

View File

@ -1140,7 +1140,7 @@ Factory::CopyDataSourceSurface(DataSourceSurface* aSource,
}
already_AddRefed<DrawEventRecorder>
Factory::CreateEventRecorderForFile(const char *aFilename)
Factory::CreateEventRecorderForFile(const char_type* aFilename)
{
return MakeAndAddRef<DrawEventRecorderFile>(aFilename);
}

View File

@ -39,7 +39,7 @@ class gfxVarReceiver;
_(UseWebRenderProgramBinary, bool, false) \
_(WebRenderDebugFlags, int32_t, 0) \
_(ScreenDepth, int32_t, 0) \
_(GREDirectory, nsCString, nsCString()) \
_(GREDirectory, nsString, nsString()) \
_(UseOMTP, bool, false) \
_(AllowD3D11KeyedMutex, bool, false) \

View File

@ -109,13 +109,13 @@ static PRLibrary* LoadApitraceLibrary()
static PRLibrary*
LoadLibraryForEGLOnWindows(const nsAString& filename)
{
nsAutoCString path(gfx::gfxVars::GREDirectory());
nsAutoString path(gfx::gfxVars::GREDirectory());
path.Append(PR_GetDirectorySeparator());
path.Append(ToNewUTF8String(filename));
path.Append(filename);
PRLibSpec lspec;
lspec.type = PR_LibSpec_Pathname;
lspec.value.pathname = path.get();
lspec.type = PR_LibSpec_PathnameU;
lspec.value.pathname_u = path.get();
return PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
}

View File

@ -77,6 +77,7 @@ union GfxVarValue
gfxImageFormat;
IntSize;
nsCString;
nsString;
int32_t;
};

View File

@ -1139,18 +1139,16 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
});
}
bool targetConfirmed = (hitResult != CompositorHitTestInfo::eInvisibleToHitTest)
&& !(hitResult & CompositorHitTestInfo::eDispatchToContent);
TargetConfirmationFlags confFlags{hitResult};
bool apzDragEnabled = gfxPrefs::APZDragEnabled();
if (apzDragEnabled && hitScrollbar) {
// If scrollbar dragging is enabled and we hit a scrollbar, wait
// for the main-thread confirmation because it contains drag metrics
// that we need.
targetConfirmed = false;
confFlags.mTargetConfirmed = false;
}
result = mInputQueue->ReceiveInputEvent(
apzc, targetConfirmed,
mouseInput, aOutInputBlockId);
apzc, confFlags, mouseInput, aOutInputBlockId);
// If we're starting an async scrollbar drag
if (apzDragEnabled && startsDrag && hitScrollbarNode &&
@ -1223,7 +1221,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
TargetConfirmationFlags{hitResult},
wheelInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -1275,7 +1273,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
TargetConfirmationFlags{hitResult},
panInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -1305,7 +1303,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
TargetConfirmationFlags{hitResult},
pinchInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -1331,7 +1329,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
TargetConfirmationFlags{hitResult},
tapInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
@ -1415,7 +1413,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
// Dispatch the event to the input queue.
result = mInputQueue->ReceiveInputEvent(
targetApzc,
/* aTargetConfirmed = */ true,
TargetConfirmationFlags{true},
keyInput, aOutInputBlockId);
// Any keyboard event that is dispatched to the input queue at this point
@ -1589,7 +1587,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
mApzcForInputBlock->GetGuid(aOutTargetGuid);
uint64_t inputBlockId = 0;
result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
/* aTargetConfirmed = */ !(mHitResultForInputBlock & CompositorHitTestInfo::eDispatchToContent),
TargetConfirmationFlags{mHitResultForInputBlock},
aInput, &inputBlockId);
if (aOutInputBlockId) {
*aOutInputBlockId = inputBlockId;
@ -1674,7 +1672,7 @@ APZCTreeManager::ProcessTouchInputForScrollbarDrag(MultiTouchInput& aTouchInput,
// only matters for the first event, which creates the drag block. For
// that event, the correct value is false, since the drag block will, at the
// earliest, be confirmed in the subsequent SetupScrollbarDrag() call.
bool targetConfirmed = false;
TargetConfirmationFlags targetConfirmed{false};
nsEventStatus result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
targetConfirmed, mouseInput, aOutInputBlockId);

View File

@ -10,6 +10,7 @@
#include <stdint.h> // for uint32_t
#include "LayersTypes.h"
#include "UnitTransforms.h"
#include "mozilla/gfx/CompositorHitTestInfo.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/EnumSet.h"
#include "mozilla/FloatingPoint.h"
@ -76,6 +77,22 @@ CompleteAsyncTransform(const AsyncTransformComponentMatrix& aMatrix)
PixelCastJustification::MultipleAsyncTransforms);
}
struct TargetConfirmationFlags {
explicit TargetConfirmationFlags(bool aTargetConfirmed)
: mTargetConfirmed(aTargetConfirmed)
, mRequiresTargetConfirmation(false)
{}
explicit TargetConfirmationFlags(gfx::CompositorHitTestInfo aHitTestInfo)
: mTargetConfirmed(aHitTestInfo != gfx::CompositorHitTestInfo::eInvisibleToHitTest &&
!(aHitTestInfo & gfx::CompositorHitTestInfo::eDispatchToContent))
, mRequiresTargetConfirmation(aHitTestInfo & gfx::CompositorHitTestInfo::eRequiresTargetConfirmation)
{}
bool mTargetConfirmed : 1;
bool mRequiresTargetConfirmation : 1;
};
} // namespace layers
} // namespace mozilla

View File

@ -23,10 +23,11 @@ namespace layers {
static uint64_t sBlockCounter = InputBlockState::NO_BLOCK_ID + 1;
InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed)
TargetConfirmationFlags aFlags)
: mTargetApzc(aTargetApzc)
, mTargetConfirmed(aTargetConfirmed ? TargetConfirmationState::eConfirmed
: TargetConfirmationState::eUnconfirmed)
, mTargetConfirmed(aFlags.mTargetConfirmed ? TargetConfirmationState::eConfirmed
: TargetConfirmationState::eUnconfirmed)
, mRequiresTargetConfirmation(aFlags.mRequiresTargetConfirmation)
, mBlockId(sBlockCounter++)
, mTransformToApzc(aTargetApzc->GetTransformToThis())
{
@ -108,6 +109,12 @@ InputBlockState::HasReceivedRealConfirmedTarget() const
mTargetConfirmed == TargetConfirmationState::eTimedOutAndMainThreadResponded;
}
bool
InputBlockState::ShouldDropEvents() const
{
return mRequiresTargetConfirmation && (mTargetConfirmed != TargetConfirmationState::eConfirmed);
}
bool
InputBlockState::IsDownchainOf(AsyncPanZoomController* aA, AsyncPanZoomController* aB) const
{
@ -159,8 +166,8 @@ InputBlockState::DispatchEvent(const InputData& aEvent) const
}
CancelableBlockState::CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed)
: InputBlockState(aTargetApzc, aTargetConfirmed)
TargetConfirmationFlags aFlags)
: InputBlockState(aTargetApzc, aFlags)
, mPreventDefault(false)
, mContentResponded(false)
, mContentResponseTimerExpired(false)
@ -230,6 +237,12 @@ CancelableBlockState::IsReadyForHandling() const
return mContentResponded || mContentResponseTimerExpired;
}
bool
CancelableBlockState::ShouldDropEvents() const
{
return InputBlockState::ShouldDropEvents() || IsDefaultPrevented();
}
void
CancelableBlockState::RecordContentResponseTime()
{
@ -251,9 +264,9 @@ CancelableBlockState::RecordContentResponseTime()
}
DragBlockState::DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MouseInput& aInitialEvent)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
: CancelableBlockState(aTargetApzc, aFlags)
, mReceivedMouseUp(false)
{
}
@ -308,15 +321,15 @@ DragBlockState::Type()
static uint64_t sLastWheelBlockId = InputBlockState::NO_BLOCK_ID;
WheelBlockState::WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const ScrollWheelInput& aInitialEvent)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
: CancelableBlockState(aTargetApzc, aFlags)
, mScrollSeriesCounter(0)
, mTransactionEnded(false)
{
sLastWheelBlockId = GetBlockId();
if (aTargetConfirmed) {
if (aFlags.mTargetConfirmed) {
// Find the nearest APZC in the overscroll handoff chain that is scrollable.
// If we get a content confirmation later that the apzc is different, then
// content should have found a scrollable apzc, so we don't need to handle
@ -543,13 +556,13 @@ WheelBlockState::EndTransaction()
}
PanGestureBlockState::PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const PanGestureInput& aInitialEvent)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
: CancelableBlockState(aTargetApzc, aFlags)
, mInterrupted(false)
, mWaitingForContentResponse(false)
{
if (aTargetConfirmed) {
if (aFlags.mTargetConfirmed) {
// Find the nearest APZC in the overscroll handoff chain that is scrollable.
// If we get a content confirmation later that the apzc is different, then
// content should have found a scrollable apzc, so we don't need to handle
@ -643,8 +656,9 @@ PanGestureBlockState::SetNeedsToWaitForContentResponse(bool aWaitForContentRespo
}
TouchBlockState::TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed, TouchCounter& aCounter)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
TargetConfirmationFlags aFlags,
TouchCounter& aCounter)
: CancelableBlockState(aTargetApzc, aFlags)
, mAllowedTouchBehaviorSet(false)
, mDuringFastFling(false)
, mSingleTapOccurred(false)
@ -874,7 +888,7 @@ TouchBlockState::GetActiveTouchCount() const
}
KeyboardBlockState::KeyboardBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc)
: InputBlockState(aTargetApzc, true)
: InputBlockState(aTargetApzc, TargetConfirmationFlags{true})
{
}

View File

@ -42,7 +42,7 @@ public:
static const uint64_t NO_BLOCK_ID = 0;
enum class TargetConfirmationState {
enum class TargetConfirmationState : uint8_t {
eUnconfirmed,
eTimedOut,
eTimedOutAndMainThreadResponded,
@ -50,7 +50,7 @@ public:
};
explicit InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed);
TargetConfirmationFlags aFlags);
virtual ~InputBlockState()
{}
@ -83,6 +83,8 @@ public:
bool IsTargetConfirmed() const;
bool HasReceivedRealConfirmedTarget() const;
virtual bool ShouldDropEvents() const;
void SetScrolledApzc(AsyncPanZoomController* aApzc);
AsyncPanZoomController* GetScrolledApzc() const;
bool IsDownchainOfScrolledApzc(AsyncPanZoomController* aApzc) const;
@ -110,6 +112,7 @@ private:
private:
RefPtr<AsyncPanZoomController> mTargetApzc;
TargetConfirmationState mTargetConfirmed;
bool mRequiresTargetConfirmation;
const uint64_t mBlockId;
// The APZC that was actually scrolled by events in this input block.
@ -143,7 +146,7 @@ class CancelableBlockState : public InputBlockState
{
public:
CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed);
TargetConfirmationFlags aFlags);
CancelableBlockState* AsCancelableBlock() override {
return this;
@ -204,6 +207,7 @@ public:
*/
virtual const char* Type() = 0;
bool ShouldDropEvents() const override;
private:
TimeStamp mContentResponseTimer;
bool mPreventDefault;
@ -218,7 +222,7 @@ class WheelBlockState : public CancelableBlockState
{
public:
WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const ScrollWheelInput& aEvent);
bool SetContentResponse(bool aPreventDefault) override;
@ -302,7 +306,7 @@ class DragBlockState : public CancelableBlockState
{
public:
DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MouseInput& aEvent);
bool MustStayActive() override;
@ -332,7 +336,7 @@ class PanGestureBlockState : public CancelableBlockState
{
public:
PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const PanGestureInput& aEvent);
bool SetContentResponse(bool aPreventDefault) override;
@ -392,7 +396,8 @@ class TouchBlockState : public CancelableBlockState
{
public:
explicit TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed, TouchCounter& aTouchCounter);
TargetConfirmationFlags aFlags,
TouchCounter& aTouchCounter);
TouchBlockState *AsTouchBlock() override {
return this;

View File

@ -30,7 +30,7 @@ InputQueue::~InputQueue() {
nsEventStatus
InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const InputData& aEvent,
uint64_t* aOutInputBlockId) {
APZThreadUtils::AssertOnControllerThread();
@ -38,27 +38,27 @@ InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
const MultiTouchInput& event = aEvent.AsMultiTouchInput();
return ReceiveTouchInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
return ReceiveTouchInput(aTarget, aFlags, event, aOutInputBlockId);
}
case SCROLLWHEEL_INPUT: {
const ScrollWheelInput& event = aEvent.AsScrollWheelInput();
return ReceiveScrollWheelInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
return ReceiveScrollWheelInput(aTarget, aFlags, event, aOutInputBlockId);
}
case PANGESTURE_INPUT: {
const PanGestureInput& event = aEvent.AsPanGestureInput();
return ReceivePanGestureInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
return ReceivePanGestureInput(aTarget, aFlags, event, aOutInputBlockId);
}
case MOUSE_INPUT: {
const MouseInput& event = aEvent.AsMouseInput();
return ReceiveMouseInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
return ReceiveMouseInput(aTarget, aFlags, event, aOutInputBlockId);
}
case KEYBOARD_INPUT: {
// Every keyboard input must have a confirmed target
MOZ_ASSERT(aTarget && aTargetConfirmed);
MOZ_ASSERT(aTarget && aFlags.mTargetConfirmed);
const KeyboardInput& event = aEvent.AsKeyboardInput();
return ReceiveKeyboardInput(aTarget, event, aOutInputBlockId);
@ -75,7 +75,7 @@ InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
nsEventStatus
InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MultiTouchInput& aEvent,
uint64_t* aOutInputBlockId) {
TouchBlockState* block = nullptr;
@ -93,7 +93,7 @@ InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
haveBehaviors |= mActiveTouchBlock->IsContentResponseTimerExpired();
}
block = StartNewTouchBlock(aTarget, aTargetConfirmed, false);
block = StartNewTouchBlock(aTarget, aFlags, false);
INPQ_LOG("started new touch block %p id %" PRIu64 " for target %p\n",
block, block->GetBlockId(), aTarget.get());
@ -168,7 +168,7 @@ InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
nsEventStatus
InputQueue::ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MouseInput& aEvent,
uint64_t* aOutInputBlockId) {
// On a new mouse down we can have a new target so we must force a new block
@ -198,7 +198,7 @@ InputQueue::ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
if (!block) {
MOZ_ASSERT(newBlock);
block = new DragBlockState(aTarget, aTargetConfirmed, aEvent);
block = new DragBlockState(aTarget, aFlags, aEvent);
INPQ_LOG("started new drag block %p id %" PRIu64 " for %sconfirmed target %p\n",
block, block->GetBlockId(), aTargetConfirmed ? "" : "un", aTarget.get());
@ -227,7 +227,7 @@ InputQueue::ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
nsEventStatus
InputQueue::ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const ScrollWheelInput& aEvent,
uint64_t* aOutInputBlockId) {
WheelBlockState* block = mActiveWheelBlock.get();
@ -243,7 +243,7 @@ InputQueue::ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarge
MOZ_ASSERT(!block || block->InTransaction());
if (!block) {
block = new WheelBlockState(aTarget, aTargetConfirmed, aEvent);
block = new WheelBlockState(aTarget, aFlags, aEvent);
INPQ_LOG("started new scroll wheel block %p id %" PRIu64 " for target %p\n",
block, block->GetBlockId(), aTarget.get());
@ -329,7 +329,7 @@ CanScrollTargetHorizontally(const PanGestureInput& aInitialEvent,
nsEventStatus
InputQueue::ReceivePanGestureInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const PanGestureInput& aEvent,
uint64_t* aOutInputBlockId) {
if (aEvent.mType == PanGestureInput::PANGESTURE_MAYSTART ||
@ -355,11 +355,11 @@ InputQueue::ReceivePanGestureInput(const RefPtr<AsyncPanZoomController>& aTarget
event.mType);
event.mType = PanGestureInput::PANGESTURE_START;
}
block = new PanGestureBlockState(aTarget, aTargetConfirmed, event);
block = new PanGestureBlockState(aTarget, aFlags, event);
INPQ_LOG("started new pan gesture block %p id %" PRIu64 " for target %p\n",
block, block->GetBlockId(), aTarget.get());
if (aTargetConfirmed &&
if (aFlags.mTargetConfirmed &&
event.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection &&
!CanScrollTargetHorizontally(event, block)) {
// This event may trigger a swipe gesture, depending on what our caller
@ -446,7 +446,7 @@ uint64_t
InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget)
{
TouchBlockState* block = StartNewTouchBlock(aTarget,
/* aTargetConfirmed = */ true,
TargetConfirmationFlags{true},
/* aCopyPropertiesFromCurrent = */ true);
INPQ_LOG("injecting new touch block %p with id %" PRIu64 " and target %p\n",
block, block->GetBlockId(), aTarget);
@ -456,10 +456,10 @@ InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget)
TouchBlockState*
InputQueue::StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
bool aCopyPropertiesFromCurrent)
{
TouchBlockState* newBlock = new TouchBlockState(aTarget, aTargetConfirmed,
TouchBlockState* newBlock = new TouchBlockState(aTarget, aFlags,
mTouchCounter);
if (aCopyPropertiesFromCurrent) {
// We should never enter here without a current touch block, because this
@ -730,14 +730,14 @@ InputQueue::ProcessQueue() {
break;
}
INPQ_LOG("processing input from block %p; preventDefault %d target %p\n",
INPQ_LOG("processing input from block %p; preventDefault %d shouldDropEvents %d target %p\n",
curBlock, cancelable && cancelable->IsDefaultPrevented(),
curBlock->GetTargetApzc().get());
curBlock->ShouldDropEvents(), curBlock->GetTargetApzc().get());
RefPtr<AsyncPanZoomController> target = curBlock->GetTargetApzc();
// target may be null here if the initial target was unconfirmed and then
// we later got a confirmed null target. in that case drop the events.
if (target) {
if (cancelable && cancelable->IsDefaultPrevented()) {
if (curBlock->ShouldDropEvents()) {
if (curBlock->AsTouchBlock()) {
target->ResetTouchInputState();
}

View File

@ -52,7 +52,7 @@ public:
* return values from this function, including |aOutInputBlockId|.
*/
nsEventStatus ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const InputData& aEvent,
uint64_t* aOutInputBlockId);
/**
@ -140,7 +140,7 @@ private:
~InputQueue();
TouchBlockState* StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
bool aCopyPropertiesFromCurrent);
/**
@ -157,21 +157,21 @@ private:
CancelableBlockState* aBlock);
nsEventStatus ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MultiTouchInput& aEvent,
uint64_t* aOutInputBlockId);
nsEventStatus ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const MouseInput& aEvent,
uint64_t* aOutInputBlockId);
nsEventStatus ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
TargetConfirmationFlags aFlags,
const ScrollWheelInput& aEvent,
uint64_t* aOutInputBlockId);
nsEventStatus ReceivePanGestureInput(const RefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
const PanGestureInput& aEvent,
uint64_t* aOutInputBlockId);
TargetConfirmationFlags aFlags,
const PanGestureInput& aEvent,
uint64_t* aOutInputBlockId);
nsEventStatus ReceiveKeyboardInput(const RefPtr<AsyncPanZoomController>& aTarget,
const KeyboardInput& aEvent,
uint64_t* aOutInputBlockId);

View File

@ -217,7 +217,7 @@ public:
}
nsEventStatus ReceiveInputEvent(const InputData& aEvent, uint64_t* aOutInputBlockId) {
return GetInputQueue()->ReceiveInputEvent(this, !mWaitForMainThread, aEvent, aOutInputBlockId);
return GetInputQueue()->ReceiveInputEvent(this, TargetConfirmationFlags{!mWaitForMainThread}, aEvent, aOutInputBlockId);
}
void ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault) {

View File

@ -364,11 +364,8 @@ FPSCounter::WriteFrameTimeStamps()
WriteFrameTimeStamps(fd);
PR_Close(fd);
nsAutoCString path;
rv = resultFile->GetNativePath(path);
NS_ENSURE_SUCCESS(rv, rv);
printf_stderr("Wrote FPS data to file: %s\n", path.get());
printf_stderr("Wrote FPS data to file: %s\n",
resultFile->HumanReadablePath().get());
return NS_OK;
}

View File

@ -46,9 +46,15 @@ enum class CompositorHitTestInfo : uint16_t {
// one (if set) or a horizontal one (if not set)
eScrollbarVertical = 1 << 8,
// Events targeting this frame should only be processed if a target
// confirmation is received from the main thread. If no such confirmation
// is received within a timeout period, the event may be dropped.
// Only meaningful in combination with eDispatchToContent.
eRequiresTargetConfirmation = 1 << 9,
// Used for IPDL serialization. This bitmask should include all the bits
// that are defined in the enum.
ALL_BITS = (1 << 9) - 1,
ALL_BITS = (1 << 10) - 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorHitTestInfo)

View File

@ -566,7 +566,7 @@ void RecordingPrefChanged(const char *aPrefName, void *aClosure)
nsAutoString prefFileName;
nsresult rv = Preferences::GetString("gfx.2d.recordingfile", prefFileName);
if (NS_SUCCEEDED(rv)) {
fileName.Append(NS_ConvertUTF16toUTF8(prefFileName));
CopyUTF16toUTF8(prefFileName, fileName);
} else {
nsCOMPtr<nsIFile> tmpFile;
if (NS_FAILED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile)))) {
@ -578,12 +578,21 @@ void RecordingPrefChanged(const char *aPrefName, void *aClosure)
if (NS_FAILED(rv))
return;
#ifdef XP_WIN
rv = tmpFile->GetPath(prefFileName);
CopyUTF16toUTF8(prefFileName, fileName);
#else
rv = tmpFile->GetNativePath(fileName);
#endif
if (NS_FAILED(rv))
return;
}
#ifdef XP_WIN
gPlatform->mRecorder = Factory::CreateEventRecorderForFile(prefFileName.BeginReading());
#else
gPlatform->mRecorder = Factory::CreateEventRecorderForFile(fileName.BeginReading());
#endif
printf_stderr("Recording to %s\n", fileName.get());
Factory::SetGlobalEventRecorder(gPlatform->mRecorder);
} else {
@ -675,11 +684,11 @@ gfxPlatform::Init()
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
if (NS_FAILED(rv)) {
gfxVars::SetGREDirectory(nsCString());
gfxVars::SetGREDirectory(nsString());
} else {
nsAutoCString nativePath;
file->GetNativePath(nativePath);
gfxVars::SetGREDirectory(nsCString(nativePath));
nsAutoString path;
file->GetPath(path);
gfxVars::SetGREDirectory(nsString(path));
}
}

View File

@ -16,7 +16,7 @@
*/
/* fluent@0.6.0 */
/* fluent@0.6.3 */
const { Localization } =
ChromeUtils.import("resource://gre/modules/Localization.jsm", {});
@ -31,36 +31,36 @@ const reOverlay = /<|&#?\w+;/;
* Source: https://www.w3.org/TR/html5/text-level-semantics.html
*/
const LOCALIZABLE_ELEMENTS = {
'http://www.w3.org/1999/xhtml': [
'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data',
'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u',
'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr'
"http://www.w3.org/1999/xhtml": [
"a", "em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data",
"time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u",
"mark", "ruby", "rt", "rp", "bdi", "bdo", "span", "br", "wbr"
],
};
const LOCALIZABLE_ATTRIBUTES = {
'http://www.w3.org/1999/xhtml': {
global: ['title', 'aria-label', 'aria-valuetext', 'aria-moz-hint'],
a: ['download'],
area: ['download', 'alt'],
"http://www.w3.org/1999/xhtml": {
global: ["title", "aria-label", "aria-valuetext", "aria-moz-hint"],
a: ["download"],
area: ["download", "alt"],
// value is special-cased in isAttrNameLocalizable
input: ['alt', 'placeholder'],
menuitem: ['label'],
menu: ['label'],
optgroup: ['label'],
option: ['label'],
track: ['label'],
img: ['alt'],
textarea: ['placeholder'],
th: ['abbr']
input: ["alt", "placeholder"],
menuitem: ["label"],
menu: ["label"],
optgroup: ["label"],
option: ["label"],
track: ["label"],
img: ["alt"],
textarea: ["placeholder"],
th: ["abbr"]
},
'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul': {
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": {
global: [
'accesskey', 'aria-label', 'aria-valuetext', 'aria-moz-hint', 'label'
"accesskey", "aria-label", "aria-valuetext", "aria-moz-hint", "label"
],
key: ['key', 'keycode'],
textbox: ['placeholder'],
toolbarbutton: ['tooltiptext'],
key: ["key", "keycode"],
textbox: ["placeholder"],
toolbarbutton: ["tooltiptext"],
}
};
@ -75,7 +75,7 @@ const LOCALIZABLE_ATTRIBUTES = {
function overlayElement(targetElement, translation) {
const value = translation.value;
if (typeof value === 'string') {
if (typeof value === "string") {
if (!reOverlay.test(value)) {
// If the translation doesn't contain any markup skip the overlay logic.
targetElement.textContent = value;
@ -83,7 +83,8 @@ function overlayElement(targetElement, translation) {
// Else parse the translation's HTML using an inert template element,
// sanitize it and replace the targetElement's content.
const templateElement = targetElement.ownerDocument.createElementNS(
'http://www.w3.org/1999/xhtml', 'template');
"http://www.w3.org/1999/xhtml", "template");
// eslint-disable-next-line no-unsanitized/property
templateElement.innerHTML = value;
targetElement.appendChild(
// The targetElement will be cleared at the end of sanitization.
@ -92,9 +93,9 @@ function overlayElement(targetElement, translation) {
}
}
const explicitlyAllowed = targetElement.hasAttribute('data-l10n-attrs')
? targetElement.getAttribute('data-l10n-attrs')
.split(',').map(i => i.trim())
const explicitlyAllowed = targetElement.hasAttribute("data-l10n-attrs")
? targetElement.getAttribute("data-l10n-attrs")
.split(",").map(i => i.trim())
: null;
// Remove localizable attributes which may have been set by a previous
@ -182,7 +183,7 @@ function sanitizeUsing(translationFragment, sourceElement) {
// SourceElement might have been already modified by shiftNamedElement.
// Let's clear it to make sure other code doesn't rely on random leftovers.
sourceElement.textContent = '';
sourceElement.textContent = "";
return translationFragment;
}
@ -274,10 +275,10 @@ function isAttrNameLocalizable(name, element, explicitlyAllowed = null) {
}
// Special case for value on HTML inputs with type button, reset, submit
if (element.namespaceURI === 'http://www.w3.org/1999/xhtml' &&
elemName === 'input' && attrName === 'value') {
if (element.namespaceURI === "http://www.w3.org/1999/xhtml" &&
elemName === "input" && attrName === "value") {
const type = element.type.toLowerCase();
if (type === 'submit' || type === 'button' || type === 'reset') {
if (type === "submit" || type === "button" || type === "reset") {
return true;
}
}
@ -303,8 +304,8 @@ function shiftNamedElement(element, localName) {
return null;
}
const L10NID_ATTR_NAME = 'data-l10n-id';
const L10NARGS_ATTR_NAME = 'data-l10n-args';
const L10NID_ATTR_NAME = "data-l10n-id";
const L10NARGS_ATTR_NAME = "data-l10n-args";
const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`;
@ -430,7 +431,7 @@ class DOMLocalization extends Localization {
if (root === newRoot ||
root.contains(newRoot) ||
newRoot.contains(root)) {
throw new Error('Cannot add a root that overlaps with existing root.');
throw new Error("Cannot add a root that overlaps with existing root.");
}
}
@ -500,10 +501,10 @@ class DOMLocalization extends Localization {
translateMutations(mutations) {
for (const mutation of mutations) {
switch (mutation.type) {
case 'attributes':
case "attributes":
this.pendingElements.add(mutation.target);
break;
case 'childList':
case "childList":
for (const addedNode of mutation.addedNodes) {
if (addedNode.nodeType === addedNode.ELEMENT_NODE) {
if (addedNode.childElementCount) {
@ -600,7 +601,7 @@ class DOMLocalization extends Localization {
getTranslatables(element) {
const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));
if (typeof element.hasAttribute === 'function' &&
if (typeof element.hasAttribute === "function" &&
element.hasAttribute(L10NID_ATTR_NAME)) {
nodes.push(element);
}
@ -625,4 +626,4 @@ class DOMLocalization extends Localization {
}
this.DOMLocalization = DOMLocalization;
this.EXPORTED_SYMBOLS = ['DOMLocalization'];
this.EXPORTED_SYMBOLS = ["DOMLocalization"];

View File

@ -1,7 +1,7 @@
const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
const { Services } = ChromeUtils.import('resource://gre/modules/Services.jsm', {});
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
const { MessageContext } = ChromeUtils.import("resource://gre/modules/MessageContext.jsm", {});
Components.utils.importGlobalProperties(["fetch"]); /* globals fetch */
Cu.importGlobalProperties(["fetch"]);
/**
* L10nRegistry is a localization resource management system for Gecko.
@ -89,7 +89,7 @@ const L10nRegistry = {
* @param {Array} resourceIds
* @returns {AsyncIterator<MessageContext>}
*/
async * generateContexts(requestedLangs, resourceIds) {
async* generateContexts(requestedLangs, resourceIds) {
if (this.bootstrap !== null) {
await this.bootstrap;
}
@ -109,7 +109,7 @@ const L10nRegistry = {
throw new Error(`Source with name "${source.name}" already registered.`);
}
this.sources.set(source.name, source);
Services.obs.notifyObservers(null, 'l10n:available-locales-changed', null);
Services.locale.setAvailableLocales(this.getAvailableLocales());
},
/**
@ -126,7 +126,7 @@ const L10nRegistry = {
}
this.sources.set(source.name, source);
this.ctxCache.clear();
Services.obs.notifyObservers(null, 'l10n:available-locales-changed', null);
Services.locale.setAvailableLocales(this.getAvailableLocales());
},
/**
@ -136,7 +136,7 @@ const L10nRegistry = {
*/
removeSource(sourceName) {
this.sources.delete(sourceName);
Services.obs.notifyObservers(null, 'l10n:available-locales-changed', null);
Services.locale.setAvailableLocales(this.getAvailableLocales());
},
/**
@ -167,8 +167,8 @@ const L10nRegistry = {
* @returns {String}
*/
function generateContextID(locale, sourcesOrder, resourceIds) {
const sources = sourcesOrder.join(',');
const ids = resourceIds.join(',');
const sources = sourcesOrder.join(",");
const ids = resourceIds.join(",");
return `${locale}|${sources}|${ids}`;
}
@ -219,7 +219,7 @@ async function* generateContextsForLocale(locale, sourcesOrder, resourceIds, res
}
}
const MSG_CONTEXT_OPTIONS = {
const MSG_CONTEXT_OPTIONS = {
// Temporarily disable bidi isolation due to Microsoft not supporting FSI/PDI.
// See bug 1439018 for details.
useIsolating: Services.prefs.getBoolPref("intl.l10n.enable-bidi-marks", false),
@ -242,7 +242,7 @@ const MSG_CONTEXT_OPTIONS = {
}
}
}
}
};
/**
* Generates a single MessageContext by loading all resources
@ -360,11 +360,9 @@ class FileSource {
if (this.cache[fullPath].then) {
return this.cache[fullPath];
}
} else {
if (this.indexed) {
} else if (this.indexed) {
return Promise.reject(`The source has no resources for path "${fullPath}"`);
}
}
return this.cache[fullPath] = L10nRegistry.load(fullPath).then(
data => {
return this.cache[fullPath] = data;
@ -417,7 +415,7 @@ L10nRegistry.load = function(url) {
if (!response.ok) {
return Promise.reject(response.statusText);
}
return response.text()
return response.text();
});
};
@ -425,4 +423,4 @@ this.L10nRegistry = L10nRegistry;
this.FileSource = FileSource;
this.IndexedFileSource = IndexedFileSource;
this.EXPORTED_SYMBOLS = ['L10nRegistry', 'FileSource', 'IndexedFileSource'];
this.EXPORTED_SYMBOLS = ["L10nRegistry", "FileSource", "IndexedFileSource"];

Some files were not shown because too many files have changed in this diff Show More