Merge autoland to mozilla-central r=merge a=merge

This commit is contained in:
Dorel Luca 2018-01-10 23:58:59 +02:00
Родитель 59fa32fd74 740dcad222
Коммит 7df7614d04
135 изменённых файлов: 2895 добавлений и 2432 удалений

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

@ -247,11 +247,12 @@ Site.prototype = {
*/
onClick: function Site_onClick(aEvent) {
let pinned = this.isPinned();
let tileIndex = this.cell.index;
let {button, target} = aEvent;
const isLinkClick = target.classList.contains("newtab-link") ||
target.parentElement.classList.contains("newtab-link");
// Only handle primary clicks for the remaining targets
if (button == 0) {
// Handle primary click for pin and block
if (button == 0 && !isLinkClick) {
aEvent.preventDefault();
if (target.classList.contains("newtab-control-block")) {
this.block();

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

@ -32,6 +32,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
ContentClick: "resource:///modules/ContentClick.jsm",
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
DateTimePickerHelper: "resource://gre/modules/DateTimePickerHelper.jsm",
DirectoryLinksProvider: "resource:///modules/DirectoryLinksProvider.jsm",
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
@ -438,6 +439,8 @@ BrowserGlue.prototype = {
if (this._placesBrowserInitComplete) {
Services.obs.notifyObservers(null, "places-browser-init-complete");
}
} else if (data == "migrateMatchBucketsPrefForUIVersion60") {
this._migrateMatchBucketsPrefForUIVersion60();
}
break;
case "initial-migration-will-import-default-bookmarks":
@ -1771,7 +1774,7 @@ BrowserGlue.prototype = {
// eslint-disable-next-line complexity
_migrateUI: function BG__migrateUI() {
const UI_VERSION = 59;
const UI_VERSION = 60;
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
let currentUIVersion;
@ -2256,6 +2259,12 @@ BrowserGlue.prototype = {
}
}
if (currentUIVersion < 60) {
// Set whether search suggestions or history results come first in the
// urlbar results.
this._migrateMatchBucketsPrefForUIVersion60();
}
// Update the migration version.
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
},
@ -2337,6 +2346,26 @@ BrowserGlue.prototype = {
}
},
_migrateMatchBucketsPrefForUIVersion60() {
let prefName = "browser.urlbar.matchBuckets";
let pref = Services.prefs.getCharPref(prefName, "");
if (!pref) {
// Set the pref based on the search bar's current placement. If it's
// placed (the urlbar and search bar are not unified), then set the pref
// (so that history results will come before search suggestions). If it's
// not placed (the urlbar and search bar are unified), then leave the pref
// cleared so that UnifiedComplete.js uses the default value (so that
// search suggestions will come before history results).
if (CustomizableUI.getPlacementOfWidget("search-container")) {
Services.prefs.setCharPref(prefName, "general:5,suggestion:Infinity");
}
}
// Else, the pref has already been set. Normally this pref does not exist.
// Either the user customized it, or they were enrolled in the Shield study
// in Firefox 57 that effectively already migrated the pref. Either way,
// leave it at its current value.
},
// ------------------------------
// public nsIBrowserGlue members
// ------------------------------

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

@ -15,6 +15,7 @@ Preferences.addAll([
{ id: "browser.urlbar.suggest.searches", type: "bool" },
{ id: "browser.search.hiddenOneOffs", type: "unichar" },
{ id: "browser.search.widget.inNavBar", type: "bool" },
{ id: "browser.urlbar.matchBuckets", type: "string" },
]);
const ENGINE_FLAVOR = "text/x-moz-search-engine";
@ -60,6 +61,47 @@ var gSearchPane = {
let suggestsPref = Preferences.get("browser.search.suggest.enabled");
suggestsPref.on("change", this.updateSuggestsCheckbox.bind(this));
this.updateSuggestsCheckbox();
this._initShowSearchSuggestionsFirst();
},
_initShowSearchSuggestionsFirst() {
let pref = Preferences.get("browser.urlbar.matchBuckets");
let checkbox =
document.getElementById("showSearchSuggestionsFirstCheckbox");
pref.on("change", () => {
this.syncFromShowSearchSuggestionsFirstPref(checkbox, pref);
});
this._syncFromShowSearchSuggestionsFirstPref(checkbox, pref);
checkbox.addEventListener("command", () => {
this._syncToShowSearchSuggestionsFirstPref(checkbox.checked, pref);
});
},
_syncFromShowSearchSuggestionsFirstPref(checkbox, pref) {
if (!pref.value) {
// The pref is cleared, meaning search suggestions are shown first.
checkbox.checked = true;
return;
}
// The pref has a value. If the first bucket in the pref is search
// suggestions, then check the checkbox.
let bucketPair = pref.value.split(",")[0];
let bucketName = bucketPair.split(":")[0];
checkbox.checked = bucketName == "suggestion";
},
_syncToShowSearchSuggestionsFirstPref(checked, pref) {
if (checked) {
// Show search suggestions first, so clear the pref since that's the
// default.
pref.reset();
return;
}
// Show history first.
pref.value = "general:5,suggestion:Infinity";
},
updateSuggestsCheckbox() {

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

@ -18,6 +18,8 @@
<radio id="searchBarShownRadio" value="true" label="&searchBar.shown.label;"/>
<image class="searchBarImage searchBarShownImage" role="presentation"/>
</radiogroup>
<checkbox id="showSearchSuggestionsFirstCheckbox"
label="&showSearchSuggestionsAboveHistory.label;"/>
</groupbox>
<!-- Default Search Engine -->

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

@ -67,6 +67,7 @@ skip-if = e10s
[browser_privacypane_5.js]
[browser_privacypane_8.js]
[browser_sanitizeOnShutdown_prefLocked.js]
[browser_searchShowSuggestionsFirst.js]
[browser_searchsuggestions.js]
[browser_security-1.js]
[browser_security-2.js]

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

@ -0,0 +1,53 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NAME = "browser.urlbar.matchBuckets";
const HISTORY_FIRST_PREF_VALUE = "general:5,suggestion:Infinity";
const CHECKBOX_ID = "showSearchSuggestionsFirstCheckbox";
// Open preferences with search suggestions shown first (the default).
add_task(async function openWithSearchSuggestionsShownFirst() {
// The pref should be cleared initially so that search suggestions are shown
// first (the default).
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
"Pref should be cleared initially");
// Open preferences. The checkbox should be checked.
await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let checkbox = doc.getElementById(CHECKBOX_ID);
Assert.equal(checkbox.checked, true, "Checkbox should be checked");
// Uncheck the checkbox.
checkbox.checked = false;
checkbox.doCommand();
// The pref should now be set so that history is shown first.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""),
HISTORY_FIRST_PREF_VALUE,
"Pref should now be set to show history first");
gBrowser.removeCurrentTab();
});
// Open preferences with history shown first.
add_task(async function openWithHistoryShownFirst() {
// Set the pref to show history first.
Services.prefs.setCharPref(PREF_NAME, HISTORY_FIRST_PREF_VALUE);
// Open preferences. The checkbox should be unchecked.
await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let checkbox = doc.getElementById(CHECKBOX_ID);
Assert.equal(checkbox.checked, false, "Checkbox should be unchecked");
// Check the checkbox.
checkbox.checked = true;
checkbox.doCommand();
// The pref should now be cleared so that search suggestions are shown first.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
"Pref should now be cleared to show search suggestions first");
gBrowser.removeCurrentTab();
});

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

@ -5,15 +5,44 @@
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
const TEST_PATH = "http://example.net/browser/browser/" +
"components/resistfingerprinting/test/browser/";
var spoofedUserAgent;
const SPOOFED_APPNAME = "Netscape";
const SPOOFED_APPVERSION = "5.0 (Windows)";
const SPOOFED_PLATFORM = "Win64";
const SPOOFED_OSCPU = "Windows NT 6.1; Win64; x64";
const SPOOFED_APPNAME = "Netscape";
const SPOOFED_APPVERSION = {
linux: "5.0 (X11)",
win: "5.0 (Windows)",
macosx: "5.0 (Macintosh)",
android: "5.0 (Android 6.0)",
other: "5.0 (X11)",
};
const SPOOFED_PLATFORM = {
linux: "Linux x86_64",
win: "Win64",
macosx: "MacIntel",
android: "Linux armv7l",
other: "Linux x86_64",
};
const SPOOFED_OSCPU = {
linux: "Linux x86_64",
win: "Windows NT 6.1; Win64; x64",
macosx: "Intel Mac OS X 10.13",
android: "Linux armv7l",
other: "Linux x86_64",
};
const SPOOFED_UA_OS = {
linux: "X11; Linux x86_64",
win: "Windows NT 6.1; Win64; x64",
macosx: "Macintosh; Intel Mac OS X 10.13",
android: "Android 6.0; Mobile",
other: "X11; Linux x86_64",
};
const SPOOFED_BUILDID = "20100101";
const SPOOFED_HW_CONCURRENCY = 2;
@ -35,12 +64,12 @@ async function testNavigator() {
result = JSON.parse(result);
is(result.appName, SPOOFED_APPNAME, "Navigator.appName is correctly spoofed.");
is(result.appVersion, SPOOFED_APPVERSION, "Navigator.appVersion is correctly spoofed.");
is(result.platform, SPOOFED_PLATFORM, "Navigator.platform is correctly spoofed.");
is(result.appVersion, SPOOFED_APPVERSION[AppConstants.platform], "Navigator.appVersion is correctly spoofed.");
is(result.platform, SPOOFED_PLATFORM[AppConstants.platform], "Navigator.platform is correctly spoofed.");
is(result.userAgent, spoofedUserAgent, "Navigator.userAgent is correctly spoofed.");
is(result.mimeTypesLength, 0, "Navigator.mimeTypes has a length of 0.");
is(result.pluginsLength, 0, "Navigator.plugins has a length of 0.");
is(result.oscpu, SPOOFED_OSCPU, "Navigator.oscpu is correctly spoofed.");
is(result.oscpu, SPOOFED_OSCPU[AppConstants.platform], "Navigator.oscpu is correctly spoofed.");
is(result.buildID, SPOOFED_BUILDID, "Navigator.buildID is correctly spoofed.");
is(result.hardwareConcurrency, SPOOFED_HW_CONCURRENCY, "Navigator.hardwareConcurrency is correctly spoofed.");
@ -73,8 +102,8 @@ async function testWorkerNavigator() {
result = JSON.parse(result);
is(result.appName, SPOOFED_APPNAME, "Navigator.appName is correctly spoofed.");
is(result.appVersion, SPOOFED_APPVERSION, "Navigator.appVersion is correctly spoofed.");
is(result.platform, SPOOFED_PLATFORM, "Navigator.platform is correctly spoofed.");
is(result.appVersion, SPOOFED_APPVERSION[AppConstants.platform], "Navigator.appVersion is correctly spoofed.");
is(result.platform, SPOOFED_PLATFORM[AppConstants.platform], "Navigator.platform is correctly spoofed.");
is(result.userAgent, spoofedUserAgent, "Navigator.userAgent is correctly spoofed.");
is(result.hardwareConcurrency, SPOOFED_HW_CONCURRENCY, "Navigator.hardwareConcurrency is correctly spoofed.");
@ -91,7 +120,7 @@ add_task(async function setup() {
let appVersion = parseInt(Services.appinfo.version);
let spoofedVersion = appVersion - ((appVersion - 3) % 7);
spoofedUserAgent = `Mozilla/5.0 (${SPOOFED_OSCPU}; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`;
spoofedUserAgent = `Mozilla/5.0 (${SPOOFED_UA_OS[AppConstants.platform]}; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`;
});
add_task(async function runNavigatorTest() {

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

@ -5,3 +5,4 @@ skip-if = !updater
reason = test depends on update channel
[browser_contentpermissionprompt.js]
[browser_default_bookmark_toolbar_visibility.js]
[browser_urlbar_matchBuckets_migration59.js]

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

@ -0,0 +1,100 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Makes sure the browser.urlbar.matchBuckets pref is set correctly starting in
// Firefox 59 (nsBrowserGlue UI version 60).
const SEARCHBAR_WIDGET_ID = "search-container";
const PREF_NAME = "browser.urlbar.matchBuckets";
const SEARCHBAR_PRESENT_PREF_VALUE = "general:5,suggestion:Infinity";
add_task(async function test() {
// Initial checks.
Assert.equal(CustomizableUI.getPlacementOfWidget(SEARCHBAR_WIDGET_ID), null,
"Searchbar should not be placed initially");
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
"Pref should be cleared initially");
// Add the searchbar.
let widgetPromise = promiseWidget("onWidgetAdded");
CustomizableUI.addWidgetToArea(SEARCHBAR_WIDGET_ID,
CustomizableUI.AREA_NAVBAR);
info("Waiting for searchbar to be added");
await widgetPromise;
// Force nsBrowserGlue to attempt update the pref again via UI version
// migration. It shouldn't actually though since the UI version has already
// been migrated. If it erroneously does, then the matchBuckets pref will be
// set since the searchbar is now placed.
messageBrowserGlue("force-ui-migration");
// The pref should remain cleared since the migration already happened even
// though the searchbar is now present.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
"Pref should remain cleared even though searchbar present");
// Force nsBrowserGlue to update the pref.
forceBrowserGlueUpdatePref();
// The pref should be set since the searchbar is present.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""),
SEARCHBAR_PRESENT_PREF_VALUE,
"Pref should be set to show history first");
// Set the pref to something custom.
let customValue = "test:Infinity";
Services.prefs.setCharPref(PREF_NAME, customValue);
// Force nsBrowserGlue to update the pref again.
forceBrowserGlueUpdatePref();
// The pref should remain the custom value.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), customValue,
"Pref should remain the custom value");
// Remove the searchbar.
widgetPromise = promiseWidget("onWidgetRemoved");
CustomizableUI.removeWidgetFromArea(SEARCHBAR_WIDGET_ID);
info("Waiting for searchbar to be removed");
await widgetPromise;
// Force nsBrowserGlue to update the pref again.
forceBrowserGlueUpdatePref();
// The pref should remain the custom value.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), customValue,
"Pref should remain the custom value");
// Clear the pref.
Services.prefs.clearUserPref(PREF_NAME);
// Force nsBrowserGlue to update the pref again.
forceBrowserGlueUpdatePref();
// The pref should remain cleared since the searchbar isn't placed.
Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
"Pref should remain cleared");
});
function promiseWidget(observerName) {
return new Promise(resolve => {
let listener = {};
listener[observerName] = widgetID => {
if (widgetID == SEARCHBAR_WIDGET_ID) {
CustomizableUI.removeListener(listener);
executeSoon(resolve);
}
};
CustomizableUI.addListener(listener);
});
}
function messageBrowserGlue(msgName) {
Cc["@mozilla.org/browser/browserglue;1"]
.getService(Ci.nsIObserver)
.observe(null, "browser-glue-test", msgName);
}
function forceBrowserGlueUpdatePref() {
messageBrowserGlue("migrateMatchBucketsPrefForUIVersion60");
}

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

@ -103,7 +103,7 @@ AutofillProfileAutoCompleteSearch.prototype = {
let isAddressField = FormAutofillUtils.isAddressField(activeFieldDetail.fieldName);
let isInputAutofilled = activeFieldDetail.state == FIELD_STATES.AUTO_FILLED;
let allFieldNames = activeSection.allFieldNames;
let filledRecordGUID = activeSection.getFilledRecordGUID();
let filledRecordGUID = activeSection.filledRecordGUID;
let searchPermitted = isAddressField ?
FormAutofillUtils.isAutofillAddressesEnabled :
FormAutofillUtils.isAutofillCreditCardsEnabled;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -149,9 +149,9 @@ class FieldScanner {
*/
getSectionFieldDetails() {
// When the section feature is disabled, `getSectionFieldDetails` should
// provide a single section result.
// provide a single address and credit card section result.
if (!this._sectionEnabled) {
return [this._getFinalDetails(this.fieldDetails)];
return this._getFinalDetails(this.fieldDetails);
}
if (this._sections.length == 0) {
return [];
@ -160,9 +160,10 @@ class FieldScanner {
this._classifySections();
}
return this._sections.map(section =>
this._getFinalDetails(section.fieldDetails)
);
return this._sections.reduce((sections, current) => {
sections.push(...this._getFinalDetails(current.fieldDetails));
return sections;
}, []);
}
/**
@ -239,6 +240,9 @@ class FieldScanner {
* the final `fieldDetails` will include the duplicated fields if
* `_allowDuplicates` is true.
*
* Each item should contain one type of fields only, and the two valid types
* are Address and CreditCard.
*
* @param {Array<Object>} fieldDetails
* The field details for trimming.
* @returns {Array<Object>}
@ -246,19 +250,40 @@ class FieldScanner {
* duplicated fields.
*/
_getFinalDetails(fieldDetails) {
if (this._allowDuplicates) {
return fieldDetails.filter(f => f.fieldName);
}
let dedupedFieldDetails = [];
let addressFieldDetails = [];
let creditCardFieldDetails = [];
for (let fieldDetail of fieldDetails) {
if (fieldDetail.fieldName && !dedupedFieldDetails.find(f => this._isSameField(fieldDetail, f))) {
dedupedFieldDetails.push(fieldDetail);
let fieldName = fieldDetail.fieldName;
if (FormAutofillUtils.isAddressField(fieldName)) {
addressFieldDetails.push(fieldDetail);
} else if (FormAutofillUtils.isCreditCardField(fieldName)) {
creditCardFieldDetails.push(fieldDetail);
} else {
log.debug("Not collecting an invalid field or matching another with the same info:", fieldDetail);
log.debug("Not collecting a field with a unknown fieldName", fieldDetail);
}
}
return dedupedFieldDetails;
return [
{
type: FormAutofillUtils.SECTION_TYPES.ADDRESS,
fieldDetails: addressFieldDetails,
},
{
type: FormAutofillUtils.SECTION_TYPES.CREDIT_CARD,
fieldDetails: creditCardFieldDetails,
},
].map(section => {
if (this._allowDuplicates) {
return section;
}
// Deduplicate each set of fieldDetails
let details = section.fieldDetails;
section.fieldDetails = details.filter((detail, index) => {
let previousFields = details.slice(0, index);
return !previousFields.find(f => this._isSameField(detail, f));
});
return section;
}).filter(section => section.fieldDetails.length > 0);
}
elementExisting(index) {

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

@ -33,6 +33,10 @@ const FIELD_STATES = {
AUTO_FILLED: "AUTO_FILLED",
PREVIEW: "PREVIEW",
};
const SECTION_TYPES = {
ADDRESS: "address",
CREDIT_CARD: "creditCard",
};
// The maximum length of data to be saved in a single field for preventing DoS
// attacks that fill the user's hard drive(s).
@ -180,6 +184,7 @@ this.FormAutofillUtils = {
EDIT_CREDITCARD_KEYWORDS,
MAX_FIELD_VALUE_LENGTH,
FIELD_STATES,
SECTION_TYPES,
_fieldNameInfo: {
"name": "name",

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

@ -2,7 +2,10 @@
<!-- 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/. -->
<!DOCTYPE html>
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml" width="620">
<head>
<title data-localization="addNewAddressTitle"/>
@ -11,7 +14,7 @@
<link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
<script src="chrome://formautofill/content/editDialog.js"></script>
</head>
<body>
<body dir="&locale.dir;">
<form id="form" autocomplete="off">
<div>
<div id="name-container">

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

@ -2,7 +2,10 @@
<!-- 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/. -->
<!DOCTYPE html>
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml" width="500" style="width: 500px">
<head>
<title data-localization="addNewCreditCardTitle"/>
@ -11,7 +14,7 @@
<link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
<script src="chrome://formautofill/content/editDialog.js"></script>
</head>
<body>
<body dir="&locale.dir;">
<form id="form" autocomplete="off">
<label>
<span data-localization="cardNumber"/>

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

@ -2,7 +2,10 @@
<!-- 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/. -->
<!DOCTYPE html>
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="manageAddressesTitle"/>
@ -10,7 +13,7 @@
<link rel="stylesheet" href="chrome://formautofill/content/manageDialog.css" />
<script src="chrome://formautofill/content/manageDialog.js"></script>
</head>
<body>
<body dir="&locale.dir;">
<fieldset>
<legend data-localization="addressesListHeader"/>
<select id="addresses" size="9" multiple="multiple"/>

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

@ -2,7 +2,10 @@
<!-- 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/. -->
<!DOCTYPE html>
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="manageCreditCardsTitle"/>
@ -10,7 +13,7 @@
<link rel="stylesheet" href="chrome://formautofill/content/manageDialog.css" />
<script src="chrome://formautofill/content/manageDialog.js"></script>
</head>
<body>
<body dir="&locale.dir;">
<fieldset>
<legend data-localization="creditCardsListHeader"/>
<select id="credit-cards" size="9" multiple="multiple"/>

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

@ -118,7 +118,10 @@ function runHeuristicsTest(patterns, fixturePathPrefix) {
forms.forEach((form, formIndex) => {
let sections = FormAutofillHeuristics.getFormInfo(form);
verifySectionFieldDetails(sections, testPattern.expectedResult[formIndex]);
verifySectionFieldDetails(
sections.map(section => section.fieldDetails),
testPattern.expectedResult[formIndex],
);
});
});
});

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

@ -27,6 +27,7 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},

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

@ -11,7 +11,6 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
]],
[[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},

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

@ -42,6 +42,7 @@ runHeuristicsTest([
// FIXME: bug 1392932 - misdetect ZIP ext string
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
], [
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},

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

@ -14,7 +14,7 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
], [
// FIXME: bug 1392944 - the uncommented cc-exp-month and cc-exp-year are
// both invisible <input> elements, and the following two <select>
// elements are the correct ones. BTW, they are both applied

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

@ -22,12 +22,6 @@ runHeuristicsTest([
fixturePath: "Checkout_Payment.html",
expectedResult: [
[[
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // ac-off
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
@ -37,6 +31,13 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
], [
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // ac-off
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
]],
[],
],

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

@ -27,11 +27,6 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
@ -39,6 +34,12 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // state
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
]],
[[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},

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

@ -29,8 +29,6 @@ runHeuristicsTest([
fixturePath: "Payment.html",
expectedResult: [
[[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "organization"},
@ -46,7 +44,9 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
// FIXME: bug 1392950 - the membership number should not be detected
// as cc-number.
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},

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

@ -12,6 +12,7 @@ runHeuristicsTest([
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, // select
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"},
], [
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
@ -32,6 +33,7 @@ runHeuristicsTest([
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, // select
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, // select
], [
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // select
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},

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

@ -75,10 +75,6 @@ runHeuristicsTest([
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
// FIXME: bug 1392950 - the bank routing number should not be detected
// as cc-number.
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
// FIXME: bug 1392934 - this should be detected as address-level1 since
// it's for Driver's license or state identification.
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
@ -86,6 +82,10 @@ runHeuristicsTest([
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"},
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"},
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"},
], [
// FIXME: bug 1392950 - the bank routing number should not be detected
// as cc-number.
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
]],
[[
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},

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

@ -30,11 +30,12 @@ runHeuristicsTest([
[
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "tel"},
], [
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
// {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "tel"},
], [
// FIXME bug 1392932 - the following field shouldn't be recognized as
// "tel-extension".

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

@ -16,7 +16,6 @@ const TESTCASES = [
<input id='email'><input id="tel"></form>`,
focusedInputId: "given-name",
profileData: {},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "",
"city": "",
@ -47,7 +46,6 @@ const TESTCASES = [
"email": "foo@mozilla.com",
"tel": "1234567",
},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "2 Harrison St line2",
"city": "San Francisco",
@ -77,7 +75,6 @@ const TESTCASES = [
"email": "foo@mozilla.com",
"tel": "1234567",
},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "2 Harrison St",
"city": "San Francisco",
@ -104,7 +101,6 @@ const TESTCASES = [
"email": "",
"tel": "",
},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "2 Harrison St",
"city": "San Francisco",
@ -131,7 +127,6 @@ const TESTCASES = [
"email": "foo@mozilla.com",
"tel": "1234567",
},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "",
"city": "",
@ -160,7 +155,6 @@ const TESTCASES = [
"country": "US",
"address-level1": "CA",
},
expectedFillingForm: "address",
expectedResult: {
"country": "US",
"state": "CA",
@ -186,7 +180,6 @@ const TESTCASES = [
"country": "United States",
"address-level1": "California",
},
expectedFillingForm: "address",
expectedResult: {
"country": "US",
"state": "CA",
@ -220,7 +213,6 @@ const TESTCASES = [
"email": "foo@mozilla.com",
"tel": "1234567",
},
expectedFillingForm: "address",
expectedResult: {
"street-addr": "2 Harrison St line2",
"city": "San Francisco",
@ -259,7 +251,6 @@ const TESTCASES = [
"cc-exp-month": "06",
"cc-exp-year": "25",
},
expectedFillingForm: "creditCard",
expectedResult: {
"street-addr": "",
"city": "",
@ -296,7 +287,6 @@ const TESTCASES_INPUT_UNCHANGED = [
"country": "US",
"address-level1": "unknown state",
},
expectedFillingForm: "address",
expectedResult: {
"country": "US",
"state": "",
@ -321,7 +311,6 @@ const TESTCASES_FILL_SELECT = [
"country": "US",
"address-level1": "CA",
},
expectedFillingForm: "address",
expectedResult: {
"state": "CA",
},
@ -341,7 +330,6 @@ const TESTCASES_FILL_SELECT = [
"country": "US",
"address-level1": "CA",
},
expectedFillingForm: "address",
expectedResult: {
"state": "ca",
},
@ -361,7 +349,6 @@ const TESTCASES_FILL_SELECT = [
"country": "US",
"address-level1": " California ",
},
expectedFillingForm: "address",
expectedResult: {
"state": "CA",
},
@ -381,7 +368,6 @@ const TESTCASES_FILL_SELECT = [
"country": "US",
"address-level1": "WA",
},
expectedFillingForm: "address",
expectedResult: {
"state": "US-WA",
},
@ -402,7 +388,6 @@ const TESTCASES_FILL_SELECT = [
"guid": "123",
"country": "US",
},
expectedFillingForm: "address",
expectedResult: {
"country": "US",
},
@ -421,7 +406,6 @@ const TESTCASES_FILL_SELECT = [
"guid": "123",
"country": "US",
},
expectedFillingForm: "address",
expectedResult: {
"country": "us",
},
@ -440,7 +424,6 @@ const TESTCASES_FILL_SELECT = [
"guid": "123",
"country": "US",
},
expectedFillingForm: "address",
expectedResult: {
"country": "XX",
},
@ -459,7 +442,6 @@ const TESTCASES_FILL_SELECT = [
"guid": "123",
"country": "US",
},
expectedFillingForm: "address",
expectedResult: {
"country": "XX",
},
@ -478,7 +460,6 @@ const TESTCASES_FILL_SELECT = [
"guid": "123",
"country": "US",
},
expectedFillingForm: "address",
expectedResult: {
"country": "XX",
},
@ -518,15 +499,15 @@ function do_test(testcases, testFn) {
};
handler.collectFormFields();
let focusedInput = doc.getElementById(testcase.focusedInputId);
handler.focusedInput = focusedInput;
for (let section of handler.sections) {
section._decrypt = decryptHelper;
}
// TODO [Bug 1415077] We can assume all test cases with only one section
// should be filled. Eventually, the test needs to verify the filling
// feature in a multiple section case.
let handlerInfo = handler.sections[0][testcase.expectedFillingForm];
handlerInfo.fieldDetails.forEach(field => {
handler.activeSection.fieldDetails.forEach(field => {
let element = field.elementWeakRef.get();
if (!testcase.profileData[field.fieldName]) {
// Avoid waiting for `change` event of a input with a blank value to
@ -536,11 +517,9 @@ function do_test(testcases, testFn) {
promises.push(...testFn(testcase, element));
});
let focusedInput = doc.getElementById(testcase.focusedInputId);
handler.focusedInput = focusedInput;
let [adaptedProfile] = handler.activeSection.getAdaptedProfiles([testcase.profileData]);
await handler.autofillFormFields(adaptedProfile, focusedInput);
Assert.equal(handlerInfo.filledRecordGUID, testcase.profileData.guid,
Assert.equal(handler.activeSection.filledRecordGUID, testcase.profileData.guid,
"Check if filledRecordGUID is set correctly");
await Promise.all(promises);
});

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

@ -12,8 +12,8 @@ const TESTCASES = [
document: `<form><input id="given-name"><input id="family-name">
<input id="street-addr"><input id="city"><select id="country"></select>
<input id='email'><input id="phone"></form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
@ -22,8 +22,7 @@ const TESTCASES = [
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
@ -50,8 +49,8 @@ const TESTCASES = [
<input id="cc-exp-month" autocomplete="cc-exp-month">
<input id="cc-exp-year" autocomplete="cc-exp-year">
</form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
@ -59,14 +58,13 @@ const TESTCASES = [
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
@ -90,8 +88,8 @@ const TESTCASES = [
<input id="country" autocomplete="shipping country">
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
@ -100,8 +98,7 @@ const TESTCASES = [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
@ -121,8 +118,8 @@ const TESTCASES = [
<select autocomplete="shipping country"></select>
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
@ -131,8 +128,7 @@ const TESTCASES = [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
@ -151,16 +147,15 @@ const TESTCASES = [
<input id="street-addr" autocomplete="shipping street-address">
<input id="cc-number" autocomplete="shipping cc-number">
</form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
],
creditCardFieldDetails: [
], [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "cc-number"},
],
}],
],
validFieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
@ -174,10 +169,7 @@ const TESTCASES = [
<input id="given-name" autocomplete="shipping given-name">
<input autocomplete="shipping address-level2">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [],
}],
sections: [[]],
validFieldDetails: [],
},
{
@ -187,10 +179,7 @@ const TESTCASES = [
<input id="cc-exp-month" autocomplete="cc-exp-month">
<input id="cc-exp-year" autocomplete="cc-exp-year">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [],
}],
sections: [[]],
validFieldDetails: [],
},
{
@ -199,10 +188,7 @@ const TESTCASES = [
<input id="cc-name" autocomplete="cc-name">
<input id="cc-number" name="card-number">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [],
}],
sections: [[]],
validFieldDetails: [],
},
{
@ -210,12 +196,11 @@ const TESTCASES = [
document: `<form>
<input id="cc-number" autocomplete="cc-number">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
],
@ -226,13 +211,12 @@ const TESTCASES = [
<input id="cc-number" name="card-number">
<input id="cc-exp" autocomplete="cc-exp">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
@ -249,14 +233,13 @@ const TESTCASES = [
<input id="cc-exp-month" autocomplete="cc-exp-month">
<input id="cc-exp-year" autocomplete="cc-exp-year">
</form>`,
sections: [{
addressFieldDetails: [],
creditCardFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
@ -286,16 +269,13 @@ const TESTCASES = [
<input id="otherSuffix" name="phone" maxlength="4">
</form>`,
allowDuplicates: true,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
],
creditCardFieldDetails: [],
}, {
addressFieldDetails: [
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
@ -304,16 +284,12 @@ const TESTCASES = [
// section. There should be a way to group the related fields during the
// parsing stage.
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-country-code"},
],
creditCardFieldDetails: [],
}, {
addressFieldDetails: [
], [
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
@ -345,16 +321,15 @@ const TESTCASES = [
<input id="mobilePhone" maxlength="10">
<input id="officePhone" maxlength="10">
</form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
@ -376,8 +351,8 @@ const TESTCASES = [
<input id="shippingPrefix" autocomplete="shipping tel-local-prefix">
<input id="shippingSuffix" autocomplete="shipping tel-local-suffix">
</form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
@ -391,8 +366,7 @@ const TESTCASES = [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-prefix"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-suffix"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
@ -415,14 +389,13 @@ const TESTCASES = [
<input id="dummyPrefix" autocomplete="shipping tel" maxlength="3">
<input id="dummySuffix" autocomplete="shipping tel" maxlength="4">
</form>`,
sections: [{
addressFieldDetails: [
sections: [
[
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
creditCardFieldDetails: [],
}],
],
validFieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
@ -464,7 +437,7 @@ for (let tc of TESTCASES) {
Assert.equal(handlerDetails, testCaseDetails);
return;
}
Assert.equal(handlerDetails.length, testCaseDetails.length);
Assert.equal(handlerDetails.length, testCaseDetails.length, "field count");
handlerDetails.forEach((detail, index) => {
Assert.equal(detail.fieldName, testCaseDetails[index].fieldName, "fieldName");
Assert.equal(detail.section, testCaseDetails[index].section, "section");
@ -474,7 +447,7 @@ for (let tc of TESTCASES) {
});
}
setElementWeakRef(testcase.sections.reduce((fieldDetails, section) => {
fieldDetails.push(...section.addressFieldDetails, ...section.creditCardFieldDetails);
fieldDetails.push(...section);
return fieldDetails;
}, []));
setElementWeakRef(testcase.validFieldDetails);
@ -482,11 +455,10 @@ for (let tc of TESTCASES) {
let handler = new FormAutofillHandler(formLike);
let validFieldDetails = handler.collectFormFields(testcase.allowDuplicates);
Assert.equal(handler.sections.length, testcase.sections.length);
Assert.equal(handler.sections.length, testcase.sections.length, "section count");
for (let i = 0; i < handler.sections.length; i++) {
let section = handler.sections[i];
verifyDetails(section.address.fieldDetails, testcase.sections[i].addressFieldDetails);
verifyDetails(section.creditCard.fieldDetails, testcase.sections[i].creditCardFieldDetails);
verifyDetails(section.fieldDetails, testcase.sections[i]);
}
verifyDetails(validFieldDetails, testcase.validFieldDetails);
});

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

@ -16,7 +16,7 @@ browser.jar:
* skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png
skin/classic/browser/searchbar.css
* skin/classic/browser/searchbar.css
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/slowStartup-16.png
skin/classic/browser/webRTC-indicator.css (../shared/webRTC-indicator.css)

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

@ -2,12 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.searchbar-engine-image {
height: 16px;
width: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
margin-inline-start: -1px;
}
%include ../shared/searchbar.inc.css
menuitem[cmd="cmd_clearhistory"] {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
@ -16,238 +11,3 @@ menuitem[cmd="cmd_clearhistory"] {
menuitem[cmd="cmd_clearhistory"][disabled] {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
}
.search-panel-current-engine {
-moz-box-align: center;
}
/**
* The borders of the various elements are specified as follows.
*
* The current engine always has a bottom border.
* The search results never have a border.
*
* When the search results are not collapsed:
* - The elements underneath the search results all have a top border.
*
* When the search results are collapsed:
* - The elements underneath the search results all have a bottom border, except
* the lowest one: search-setting-button.
*/
.search-panel-current-engine {
border-top: none !important;
border-bottom: 1px solid var(--panel-separator-color) !important;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
border-top: none !important;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
border-bottom: 1px solid var(--panel-separator-color) !important;
}
.search-panel-header {
font-weight: normal;
background-color: var(--arrowpanel-dimmed);
border: none;
border-top: 1px solid var(--panel-separator-color);
padding: 3px 5px;
color: GrayText;
}
.search-panel-header > label {
margin-top: 2px !important;
margin-bottom: 1px !important;
}
.search-panel-current-input > label {
margin: 2px 0 1px !important;
}
.search-panel-input-value {
color: -moz-fieldtext;
}
.search-panel-one-offs {
margin: 0 !important;
border-top: 1px solid var(--panel-separator-color);
background-color: var(--arrowpanel-dimmed);
}
.searchbar-engine-one-off-item {
-moz-appearance: none;
display: inline-block;
border: none;
min-width: 48px;
height: 32px;
margin: 0;
padding: 0;
background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
background-size: 1px auto;
background-repeat: no-repeat;
background-position: right center;
color: GrayText;
}
.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
background-position: left center;
}
.searchbar-engine-one-off-item:not(.last-row) {
box-sizing: content-box;
border-bottom: 1px solid var(--panel-separator-color);
}
.search-setting-button-compact {
border-bottom: none !important;
}
.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
.search-setting-button-compact {
background-image: none;
}
.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
.addengine-item:hover {
background-color: var(--arrowpanel-dimmed-further);
color: inherit;
}
.searchbar-engine-one-off-item[selected] {
background-color: Highlight;
background-image: none;
color: HighlightText;
}
.searchbar-engine-one-off-item > .button-box {
padding: 0;
}
.searchbar-engine-one-off-item > .button-box > .button-text {
display: none;
}
.searchbar-engine-one-off-item > .button-box > .button-icon {
display: -moz-box;
margin-inline-end: 0;
width: 16px;
height: 16px;
}
.search-add-engines {
background-color: var(--arrowpanel-dimmed);
}
.addengine-item {
-moz-appearance: none;
background-color: transparent;
color: inherit;
border: none;
height: 32px;
margin: 0;
padding: 0 10px;
}
.addengine-item:first-of-type {
border-top: 1px solid var(--panel-separator-color);
}
.addengine-item[selected] {
background-color: Highlight;
color: HighlightText;
}
.addengine-item[type=menu][selected] {
color: inherit;
background-color: var(--arrowpanel-dimmed-further);
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
display: -moz-box;
background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
box-shadow: none;
/* "!important" is necessary to override the rule in toolbarbutton.css */
margin: -4px 0 0 !important;
margin-inline-end: -4px !important;
width: 11px;
height: 11px;
min-width: 11px;
min-height: 11px;
}
.addengine-item > .toolbarbutton-text {
text-align: start;
padding-inline-start: 10px;
}
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
}
@media (min-resolution: 1.1dppx) {
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
}
}
.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
display: -moz-box;
-moz-appearance: menuarrow !important;
list-style-image: none;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
border-top: none !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
padding-inline-start: 4px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
padding-inline-start: 5px;
width: 14px;
height: 14px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
list-style-image: url("chrome://browser/skin/history.svg");
-moz-context-properties: fill;
fill: graytext;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
fill: HighlightText;
}
.search-setting-button {
-moz-appearance: none;
margin: 0;
min-height: 32px;
}
.search-setting-button:hover,
.search-setting-button[selected] {
background-color: var(--arrowpanel-dimmed-further);
}
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/settings.svg");
-moz-context-properties: fill;
fill: currentColor;
}

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

@ -18,7 +18,7 @@ browser.jar:
skin/classic/browser/panel-plus-sign.png
skin/classic/browser/page-livemarks.png
* skin/classic/browser/pageInfo.css
skin/classic/browser/searchbar.css
* skin/classic/browser/searchbar.css
skin/classic/browser/slowStartup-16.png
skin/classic/browser/toolbarbutton-dropmarker.png
skin/classic/browser/toolbarbutton-dropmarker@2x.png

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

@ -2,8 +2,11 @@
* 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/. */
.searchbar-textbox {
border-radius: 10000px;
%include ../shared/searchbar.inc.css
.search-panel-header,
.addengine-item {
font-size: 10px;
}
.searchbar-popup {
@ -11,237 +14,14 @@
margin-inline-start: 3px;
}
.searchbar-engine-image {
width: 16px;
height: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
#PopupSearchAutoComplete {
border-radius: 4px;
}
.search-panel-current-engine {
border-radius: 4px 4px 0 0;
}
/**
* The borders of the various elements are specified as follows.
*
* The current engine always has a bottom border.
* The search results never have a border.
*
* When the search results are not collapsed:
* - The elements underneath the search results all have a top border.
*
* When the search results are collapsed:
* - The elements underneath the search results all have a bottom border, except
* the lowest one: search-setting-button.
*/
.search-panel-current-engine {
border-top: none !important;
border-bottom: 1px solid var(--panel-separator-color);
}
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
border-top: none;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
border-bottom: 1px solid var(--panel-separator-color);
}
.search-panel-header {
font-size: 10px;
font-weight: normal;
background-color: var(--arrowpanel-dimmed);
border-top: 1px solid var(--panel-separator-color);
margin: 0;
padding: 3px 6px;
color: GrayText;
}
.search-panel-header > label {
margin-top: 2px !important;
margin-bottom: 2px !important;
}
.search-panel-current-input > label {
margin: 2px 0 !important;
}
.search-panel-input-value {
color: -moz-fieldtext;
}
.search-panel-one-offs {
margin: 0 !important;
border-top: 1px solid var(--panel-separator-color);
background-color: var(--arrowpanel-dimmed);
}
.searchbar-engine-one-off-item {
-moz-appearance: none;
display: inline-block;
min-width: 48px;
height: 32px;
margin: 0;
padding: 0;
background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
background-size: 1px auto;
background-repeat: no-repeat;
background-position: right center;
color: GrayText;
}
.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
background-position: left center;
}
.searchbar-engine-one-off-item:not(.last-row) {
box-sizing: content-box;
border-bottom: 1px solid var(--panel-separator-color);
}
.search-setting-button-compact {
border-bottom: none !important;
}
.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
.search-setting-button-compact {
background-image: none;
}
.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
.addengine-item:hover {
background-color: var(--arrowpanel-dimmed-further);
color: inherit;
}
.searchbar-engine-one-off-item[selected] {
background-color: Highlight;
background-image: none;
color: HighlightText;
}
.searchbar-engine-one-off-item > .button-box > .button-text {
display: none;
}
.searchbar-engine-one-off-item > .button-box > .button-icon {
margin-inline-start: 0;
width: 16px;
height: 16px;
}
.search-add-engines {
background-color: var(--arrowpanel-dimmed);
}
.addengine-item {
-moz-appearance: none;
font-size: 10px;
height: 32px;
margin: 0;
padding: 0 10px;
}
.addengine-item:first-of-type {
border-top: 1px solid var(--panel-separator-color);
}
.addengine-item[selected] {
background-color: Highlight;
color: HighlightText;
}
.addengine-item[type=menu][selected] {
color: inherit;
background-color: var(--arrowpanel-dimmed-further);
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
display: -moz-box;
background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
box-shadow: none;
/* "!important" is necessary to override the rule in toolbarbutton.css */
margin: -4px 0 0 !important;
margin-inline-end: -4px !important;
width: 11px;
height: 11px;
min-width: 11px;
min-height: 11px;
}
.addengine-item > .toolbarbutton-text {
text-align: start;
padding-inline-start: 10px;
}
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
}
@media (min-resolution: 2dppx) {
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
}
}
.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
display: -moz-box;
-moz-appearance: menuarrow !important;
list-style-image: none;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
border-top: none !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
padding-inline-start: 4px;
padding-inline-end: 2px;
width: 14px;
height: 14px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
list-style-image: url("chrome://browser/skin/history.svg");
-moz-context-properties: fill;
fill: graytext;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
fill: HighlightText;
}
#PopupSearchAutoComplete {
border-radius: 4px;
}
.search-setting-button {
-moz-appearance: none;
border-radius: 0 0 4px 4px;
min-height: 32px;
}
.search-setting-button:hover,
.search-setting-button[selected] {
background-color: var(--arrowpanel-dimmed-further);
}
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/settings.svg");
-moz-context-properties: fill;
fill: currentColor;
}

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

@ -12,8 +12,9 @@
list-style-image: url("chrome://browser/skin/preferences/in-content/no-search-bar.svg");
}
#searchBarShownRadio {
/* Allow a little visual space to separate the radio from the image above it. */
#searchBarShownRadio,
#showSearchSuggestionsFirstCheckbox {
/* A little space to separate these from the elements above them. */
margin-top: 10px;
}

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

@ -0,0 +1,237 @@
/* 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/. */
.searchbar-engine-image {
width: 16px;
height: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
}
/**
* The borders of the various elements are specified as follows.
*
* The current engine always has a bottom border.
* The search results never have a border.
*
* When the search results are not collapsed:
* - The elements underneath the search results all have a top border.
*
* When the search results are collapsed:
* - The elements underneath the search results all have a bottom border, except
* the lowest one: search-setting-button.
*/
.search-panel-current-engine {
-moz-box-align: center;
border-top: none !important;
border-bottom: 1px solid var(--panel-separator-color);
}
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
border-top: none;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
border-bottom: 1px solid var(--panel-separator-color);
}
.search-panel-header {
font-weight: normal;
background-color: var(--arrowpanel-dimmed);
border-top: 1px solid var(--panel-separator-color);
margin: 0;
padding: 3px 6px;
color: GrayText;
}
.search-panel-header > label {
margin-top: 2px !important;
margin-bottom: 1px !important;
}
.search-panel-current-input > label {
margin: 2px 0 !important;
}
.search-panel-input-value {
color: -moz-fieldtext;
}
.search-panel-one-offs {
margin: 0 !important;
border-top: 1px solid var(--panel-separator-color);
background-color: var(--arrowpanel-dimmed);
/* Bug 1108841: prevent font-size from affecting the layout */
line-height: 0;
}
.searchbar-engine-one-off-item {
-moz-appearance: none;
display: inline-block;
min-width: 48px;
height: 32px;
margin: 0;
padding: 0;
background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
background-size: 1px auto;
background-repeat: no-repeat;
background-position: right center;
color: GrayText;
}
.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
background-position-x: left;
}
.searchbar-engine-one-off-item:not(.last-row) {
box-sizing: content-box;
border-bottom: 1px solid var(--panel-separator-color);
}
.search-setting-button-compact {
border-bottom: none !important;
}
.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
.search-setting-button-compact {
background-image: none;
}
.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
.addengine-item:hover {
background-color: var(--arrowpanel-dimmed-further);
color: inherit;
}
.searchbar-engine-one-off-item[selected] {
background-color: Highlight;
background-image: none;
color: HighlightText;
}
.searchbar-engine-one-off-item > .button-box {
padding: 0;
}
.searchbar-engine-one-off-item > .button-box > .button-text {
display: none;
}
.searchbar-engine-one-off-item > .button-box > .button-icon {
margin-inline-start: 0;
margin-inline-end: 0;
width: 16px;
height: 16px;
}
.search-add-engines {
background-color: var(--arrowpanel-dimmed);
}
.addengine-item {
-moz-appearance: none;
color: inherit;
height: 32px;
margin: 0;
padding: 0 10px;
}
.addengine-item:first-of-type {
border-top: 1px solid var(--panel-separator-color);
}
.addengine-item[selected] {
background-color: Highlight;
color: HighlightText;
}
.addengine-item[type=menu][selected] {
color: inherit;
background-color: var(--arrowpanel-dimmed-further);
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
display: -moz-box;
background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
box-shadow: none;
/* "!important" is necessary to override the rule in toolbarbutton.css */
margin: -4px 0 0 !important;
margin-inline-end: -4px !important;
width: 11px;
height: 11px;
min-width: 11px;
min-height: 11px;
}
.addengine-item > .toolbarbutton-text {
text-align: start;
padding-inline-start: 10px;
}
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
}
@media (min-resolution: 1.1dppx) {
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
}
}
.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
display: -moz-box;
-moz-appearance: menuarrow !important;
list-style-image: none;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
border-top: none !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
padding-inline-start: 2px;
padding-inline-end: 2px;
width: 14px;
height: 14px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
list-style-image: url("chrome://browser/skin/history.svg");
-moz-context-properties: fill;
fill: graytext;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
fill: HighlightText;
}
.search-setting-button {
-moz-appearance: none;
margin: 0;
min-height: 32px;
}
.search-setting-button:hover,
.search-setting-button[selected] {
background-color: var(--arrowpanel-dimmed-further);
}
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/settings.svg");
-moz-context-properties: fill;
fill: currentColor;
}

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

@ -14,7 +14,7 @@ browser.jar:
skin/classic/browser/monitor_16-10.png
skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/searchbar.css
* skin/classic/browser/searchbar.css
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/slowStartup-16.png
skin/classic/browser/sync-desktopIcon.svg (../shared/sync-desktopIcon.svg)

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

@ -2,245 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.searchbar-engine-image {
height: 16px;
width: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
margin-inline-start: -1px;
}
.search-panel-current-engine {
-moz-box-align: center;
}
/**
* The borders of the various elements are specified as follows.
*
* The current engine always has a bottom border.
* The search results never have a border.
*
* When the search results are not collapsed:
* - The elements underneath the search results all have a top border.
*
* When the search results are collapsed:
* - The elements underneath the search results all have a bottom border, except
* the lowest one: search-setting-button.
*/
.search-panel-current-engine {
border-top: none !important;
border-bottom: 1px solid var(--panel-separator-color) !important;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
border-top: none !important;
}
.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
border-bottom: 1px solid var(--panel-separator-color) !important;
}
.search-panel-header {
font-weight: normal;
background-color: var(--arrowpanel-dimmed);
border: none;
border-top: 1px solid var(--panel-separator-color);
margin: 0;
padding: 3px 6px;
color: GrayText;
}
.search-panel-header > label {
margin-top: 2px !important;
margin-bottom: 1px !important;
}
.search-panel-current-input > label {
margin: 2px 0 1px !important;
}
.search-panel-input-value {
color: -moz-fieldtext;
}
.search-panel-one-offs {
margin: 0 !important;
border-top: 1px solid var(--panel-separator-color);
line-height: 0;
background-color: var(--arrowpanel-dimmed);
}
.searchbar-engine-one-off-item {
-moz-appearance: none;
display: inline-block;
border: none;
min-width: 48px;
height: 32px;
margin: 0;
padding: 0;
background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
background-size: 1px auto;
background-repeat: no-repeat;
background-position: right center;
color: GrayText;
}
.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
background-position: left center;
}
.searchbar-engine-one-off-item:not(.last-row) {
box-sizing: content-box;
border-bottom: 1px solid var(--panel-separator-color);
}
%include ../shared/searchbar.inc.css
.searchbar-engine-one-off-item:-moz-focusring {
outline: none;
}
.search-setting-button-compact {
border-bottom: none !important;
}
.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
.search-setting-button-compact {
background-image: none;
}
.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
.addengine-item:hover {
background-color: var(--arrowpanel-dimmed-further);
color: inherit;
}
.searchbar-engine-one-off-item[selected] {
background-color: Highlight;
background-image: none;
color: HighlightText;
}
.searchbar-engine-one-off-item > .button-box {
padding: 0;
}
.searchbar-engine-one-off-item > .button-box > .button-text {
display: none;
}
.searchbar-engine-one-off-item > .button-box > .button-icon {
width: 16px;
height: 16px;
}
.search-add-engines {
background-color: var(--arrowpanel-dimmed);
}
.addengine-item {
-moz-appearance: none;
border: none;
height: 32px;
margin: 0;
padding: 0 10px;
}
.addengine-item:first-of-type {
border-top: 1px solid var(--panel-separator-color);
}
.addengine-item[selected] {
background-color: Highlight;
color: HighlightText;
}
.addengine-item[type=menu][selected] {
color: inherit;
background-color: var(--arrowpanel-dimmed-further);
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
display: -moz-box;
background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
box-shadow: none;
/* "!important" is necessary to override the rule in toolbarbutton.css */
margin: -4px 0 0 !important;
margin-inline-end: -4px !important;
width: 11px;
height: 11px;
min-width: 11px;
min-height: 11px;
}
.addengine-item > .toolbarbutton-text {
text-align: start;
padding-inline-start: 10px;
}
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
}
@media (min-resolution: 1.1dppx) {
.addengine-item:not([image]) {
list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
}
}
.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
display: -moz-box;
-moz-appearance: menuarrow !important;
list-style-image: none;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
border-top: none !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
padding-inline-start: 4px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
padding-inline-start: 5px;
width: 14px;
height: 14px;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
list-style-image: url("chrome://browser/skin/history.svg");
-moz-context-properties: fill;
fill: graytext;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
fill: HighlightText;
}
.search-setting-button {
-moz-appearance: none;
min-height: 32px;
}
.search-setting-button:hover,
.search-setting-button[selected] {
background-color: var(--arrowpanel-dimmed-further);
}
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/settings.svg");
-moz-context-properties: fill;
fill: currentColor;
}

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

@ -0,0 +1,148 @@
diff -Nru cmake-3.7.1/debian/changelog cmake-3.7.1/debian/changelog
--- cmake-3.7.1/debian/changelog 2016-12-04 09:01:26.000000000 +0900
+++ cmake-3.7.1/debian/changelog 2017-12-21 15:46:11.000000000 +0900
@@ -1,3 +1,22 @@
+cmake (3.7.1-1.deb7moz1) wheezy; urgency=medium
+
+ * Mozilla backport for wheezy.
+ * debian/rules, debian/control:
+ - Remove versioned dependencies on dpkg/dpkg-dev/debhelper.
+ - Don't build against system libraries. libuv is missing on wheezy, there
+ are API incompatibilities with libjsoncpp, and it's just simpler to
+ disable the use of system libraries altogether.
+ - Remove Qt GUI. Build profiles are not supported on Wheezy, and Qt5 is
+ not available either. It's not like we need the feature.
+ - Don't build a dbgsym package through dh_strip, that's not supported on
+ Wheezy.
+ * debian/*.maintscript: Remove symlink_to_dir entries, they're not supported
+ on Wheezy. Ideally, we'd replace them with the proper preinst snippet, but
+ it's only needed for upgrades of the package from older versions, and we
+ don't actually care that this works properly.
+
+ -- Mike Hommey <glandium@mozilla.com> Thu, 21 Dec 2017 15:46:11 +0900
+
cmake (3.7.1-1) unstable; urgency=medium
* New upstream release.
diff -Nru cmake-3.7.1/debian/cmake-curses-gui.maintscript cmake-3.7.1/debian/cmake-curses-gui.maintscript
--- cmake-3.7.1/debian/cmake-curses-gui.maintscript 2016-10-31 02:20:34.000000000 +0900
+++ cmake-3.7.1/debian/cmake-curses-gui.maintscript 2017-12-21 15:46:11.000000000 +0900
@@ -1 +0,0 @@
-symlink_to_dir /usr/share/doc/cmake-curses-gui /usr/share/doc/cmake-data 2.8.12.2-2~
diff -Nru cmake-3.7.1/debian/cmake-dbg.maintscript cmake-3.7.1/debian/cmake-dbg.maintscript
--- cmake-3.7.1/debian/cmake-dbg.maintscript 2016-10-31 02:20:34.000000000 +0900
+++ cmake-3.7.1/debian/cmake-dbg.maintscript 2017-12-21 15:46:11.000000000 +0900
@@ -1 +0,0 @@
-symlink_to_dir /usr/share/doc/cmake-dbg /usr/share/doc/cmake-data 2.8.12.2-2~
diff -Nru cmake-3.7.1/debian/cmake-qt-gui.maintscript cmake-3.7.1/debian/cmake-qt-gui.maintscript
--- cmake-3.7.1/debian/cmake-qt-gui.maintscript 2016-10-31 02:20:34.000000000 +0900
+++ cmake-3.7.1/debian/cmake-qt-gui.maintscript 2017-12-21 15:46:11.000000000 +0900
@@ -1 +0,0 @@
-symlink_to_dir /usr/share/doc/cmake-qt-gui /usr/share/doc/cmake-data 2.8.12.2-2~
diff -Nru cmake-3.7.1/debian/cmake.maintscript cmake-3.7.1/debian/cmake.maintscript
--- cmake-3.7.1/debian/cmake.maintscript 2016-10-31 02:20:34.000000000 +0900
+++ cmake-3.7.1/debian/cmake.maintscript 2017-12-21 15:46:11.000000000 +0900
@@ -1,4 +1,3 @@
-symlink_to_dir /usr/share/doc/cmake /usr/share/doc/cmake-data 2.8.12.2-2~
rm_conffile /etc/bash_completion.d/cmake 3.2.2-3~
rm_conffile /etc/bash_completion.d/cpack 3.2.2-3~
rm_conffile /etc/bash_completion.d/ctest 3.2.2-3~
diff -Nru cmake-3.7.1/debian/control cmake-3.7.1/debian/control
--- cmake-3.7.1/debian/control 2016-11-12 19:55:11.000000000 +0900
+++ cmake-3.7.1/debian/control 2017-12-21 15:46:11.000000000 +0900
@@ -4,20 +4,12 @@
Maintainer: Debian CMake Team <pkg-cmake-team@lists.alioth.debian.org>
Uploaders: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org>,
Felix Geyer <fgeyer@debian.org>
-Build-Depends: debhelper (>= 9.20160114~),
- dpkg-dev (>= 1.17.14~),
- libarchive-dev (>= 2.8.0),
- libbz2-dev,
+Build-Depends: debhelper,
+ dpkg-dev,
libcurl4-openssl-dev | libcurl-ssl-dev,
- libexpat1-dev,
- libjsoncpp-dev,
- liblzma-dev,
libncurses5-dev,
- libuv1-dev,
procps [!hurd-any],
- python-sphinx,
- qtbase5-dev <!stage1>,
- zlib1g-dev
+ python-sphinx
Standards-Version: 3.9.6
Vcs-Git: https://anonscm.debian.org/git/pkg-cmake/cmake.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-cmake/cmake.git/
@@ -26,7 +18,6 @@
Package: cmake
Architecture: any
Multi-Arch: foreign
-Pre-Depends: dpkg (>= 1.17.5~)
Depends: cmake-data (= ${source:Version}),
procps [!hurd-any],
${misc:Depends},
@@ -59,7 +50,6 @@
Package: cmake-curses-gui
Architecture: any
-Pre-Depends: dpkg (>= 1.17.5~)
Depends: cmake (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
Description: curses based user interface for CMake (ccmake)
CMake is used to control the software compilation process using simple
@@ -72,23 +62,6 @@
are provided at the bottom of the terminal when the program is running. The
main executable file for this GUI is "ccmake".
-Package: cmake-qt-gui
-Architecture: any
-Build-Profiles: <!stage1>
-Pre-Depends: dpkg (>= 1.17.5~)
-Depends: cmake (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
-Provides: cmake-gui
-Description: Qt based user interface for CMake (cmake-gui)
- CMake is used to control the software compilation process using simple
- platform and compiler independent configuration files. CMake generates native
- makefiles and workspaces that can be used in the compiler environment of your
- choice.
- .
- This package provides the CMake Qt based GUI. Project configuration
- settings may be specified interactively. Brief instructions are provided at
- the bottom of the window when the program is running. The main executable
- file for this GUI is "cmake-gui".
-
Package: cmake-doc
Architecture: all
Section: doc
diff -Nru cmake-3.7.1/debian/rules cmake-3.7.1/debian/rules
--- cmake-3.7.1/debian/rules 2016-12-04 07:30:25.000000000 +0900
+++ cmake-3.7.1/debian/rules 2017-12-21 15:46:11.000000000 +0900
@@ -29,9 +29,6 @@
$(call $(flag_action),CMAKE_CXX_FLAGS,"$(CXXFLAGS)","C++ flags")
$(call $(flag_action),CMAKE_SKIP_BOOTSTRAP_TEST,ON,"Skip BootstrapTest")
$(call $(flag_action),BUILD_CursesDialog,ON,"Build curses GUI")
-ifeq ($(filter stage1,$(DEB_BUILD_PROFILES)),)
- $(call $(flag_action),BUILD_QtDialog,ON,"Build Qt GUI")
-endif
ifeq ($(DEB_HOST_ARCH_OS),hurd)
$(call $(flag_action),CMAKE_USE_LIBUV,0,"Do not use libuv")
endif
@@ -44,7 +41,7 @@
override_dh_auto_configure: $(BUILD_FLAGS_FILE)
rm -rf Build && mkdir -p Build
cd Build && ../bootstrap --prefix=/usr --docdir=/share/doc/cmake --mandir=/share/man \
- --init=../$(BUILD_FLAGS_FILE) --system-libs \
+ --init=../$(BUILD_FLAGS_FILE) \
--sphinx-man --sphinx-html --sphinx-flags="-D today=\"$(BUILD_DATE)\"" \
$(BOOTSTRAP_PARALLEL) --verbose
@@ -68,9 +65,6 @@
override_dh_sphinxdoc:
dh_sphinxdoc -pcmake-doc
-override_dh_strip:
- dh_strip --dbgsym-migration='cmake-dbg (<< 3.5.0-1~)'
-
%:
dh $@ --with=sphinxdoc --parallel --builddirectory=Build

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

@ -0,0 +1,13 @@
diff -Nru ninja-build-1.6.0/debian/changelog ninja-build-1.6.0/debian/changelog
--- ninja-build-1.6.0/debian/changelog 2016-02-09 04:54:03.000000000 +0900
+++ ninja-build-1.6.0/debian/changelog 2017-12-21 16:38:47.000000000 +0900
@@ -1,3 +1,9 @@
+ninja-build (1.6.0-1.deb7moz1) wheezy; urgency=medium
+
+ * Mozilla backport for wheezy.
+
+ -- Mike Hommey <glandium@mozilla.com> Thu, 21 Dec 2017 16:38:47 +0900
+
ninja-build (1.6.0-1) unstable; urgency=medium
* New maintainer. (Closes: #810025)

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

@ -1,5 +1,6 @@
#!/bin/bash
set -e
set -x
hfplus_version=540.1.linux3
@ -30,6 +31,19 @@ tar xzf $TMPDIR/${filename} -C hfsplus-source --strip-components=1
# Build
cd hfsplus-source
# We want to statically link against libcrypto. On CentOS, that requires zlib
# and libdl, because of FIPS functions pulling in more than necessary from
# libcrypto (only SHA1 functions are used), but not on Debian, thus
# --as-needed.
patch -p1 << 'EOF'
--- a/newfs_hfs.tproj/Makefile.lnx
+++ b/newfs_hfs.tproj/Makefile.lnx
@@ -6,3 +6,3 @@
newfs_hfs: $(OFILES)
- ${CC} ${CFLAGS} ${LDFLAGS} -o newfs_hfs ${OFILES} -lcrypto
+ ${CC} ${CFLAGS} ${LDFLAGS} -o newfs_hfs ${OFILES} -Wl,-Bstatic -lcrypto -Wl,-Bdynamic,--as-needed,-lz,-ldl
EOF
make $make_flags || exit 1
cd ..

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

@ -328,3 +328,4 @@ devtools.jar:
content/netmonitor/src/assets/styles/variables.css (netmonitor/src/assets/styles/variables.css)
content/netmonitor/src/assets/icons/play.svg (netmonitor/src/assets/icons/play.svg)
content/netmonitor/index.html (netmonitor/index.html)
content/netmonitor/initializer.js (netmonitor/initializer.js)

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

@ -95,7 +95,7 @@ Files used to run the Network Monitor in the browser tab
* `bin/` files to launch test server.
* `configs/` dev configs.
* `index.js` the entry point, equivalent to `index.html`.
* `launchpad.js` the entry point, equivalent to `index.html`.
* `webpack.config.js` the webpack config file, including plenty of module alias map to shims and polyfills.
* `package.json` declare every required packages and available commands.

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

@ -9,144 +9,6 @@
</head>
<body class="theme-body" role="application">
<div id="mount"></div>
<script>
"use strict";
const { BrowserLoader } = Components.utils.import(
"resource://devtools/client/shared/browser-loader.js", {});
const require = window.windowRequire = BrowserLoader({
baseURI: "resource://devtools/client/netmonitor/",
window,
}).require;
const EventEmitter = require("devtools/shared/old-event-emitter");
const { createFactory } = require("devtools/client/shared/vendor/react");
const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
const { Connector } = require("./src/connector/index");
const { configureStore } = require("./src/utils/create-store");
const App = createFactory(require("./src/components/App"));
const { getDisplayedRequestById } = require("./src/selectors/index");
const { EVENTS } = require("./src/constants");
// Inject EventEmitter into global window.
EventEmitter.decorate(window);
// Configure store/state object.
let connector = new Connector();
const store = configureStore(connector);
const actions = bindActionCreators(require("./src/actions/index"), store.dispatch);
// Inject to global window for testing
window.store = store;
window.connector = connector;
window.Netmonitor = {
bootstrap({ toolbox, panel }) {
this.mount = document.querySelector("#mount");
const connection = {
tabConnection: {
tabTarget: toolbox.target,
},
toolbox,
panel,
};
const openLink = (link) => {
let parentDoc = toolbox.doc;
let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
let top = iframe.ownerDocument.defaultView.top;
top.openUILinkIn(link, "tab");
};
// Render the root Application component.
const sourceMapService = toolbox.sourceMapURLService;
const app = App({ connector, openLink, sourceMapService });
render(Provider({ store }, app), this.mount);
// Connect to the Firefox backend by default.
return connector.connectFirefox(connection, actions, store.getState);
},
destroy() {
unmountComponentAtNode(this.mount);
return connector.disconnect();
},
/**
* Selects the specified request in the waterfall and opens the details view.
* This is a firefox toolbox specific API, which providing an ability to inspect
* a network request directly from other internal toolbox panel.
*
* @param {string} requestId The actor ID of the request to inspect.
* @return {object} A promise resolved once the task finishes.
*/
inspectRequest(requestId) {
// Look for the request in the existing ones or wait for it to appear, if
// the network monitor is still loading.
return new Promise((resolve) => {
let request = null;
let inspector = () => {
request = getDisplayedRequestById(store.getState(), requestId);
if (!request) {
// Reset filters so that the request is visible.
actions.toggleRequestFilterType("all");
request = getDisplayedRequestById(store.getState(), requestId);
}
// If the request was found, select it. Otherwise this function will be
// called again once new requests arrive.
if (request) {
window.off(EVENTS.REQUEST_ADDED, inspector);
actions.selectRequest(request.id);
resolve();
}
};
inspector();
if (!request) {
window.on(EVENTS.REQUEST_ADDED, inspector);
}
});
}
};
// Implement support for:
// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
// where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
// URL constructor doesn't support chrome: scheme
let href = window.location.href.replace(/chrome:/, "http://");
let url = new window.URL(href);
// If query parameters are given in a chrome tab, the inspector
// is running in standalone.
if (window.location.protocol === "chrome:" && url.search.length > 1) {
const { targetFromURL } = require("devtools/client/framework/target-from-url");
(async function () {
let target = await targetFromURL(url);
// Start the network event listening as it is done in the toolbox code
await target.activeConsole.startListeners([
"NetworkActivity",
]);
// Create a fake toolbox object
let toolbox = {
target,
viewSourceInDebugger() {
throw new Error("toolbox.viewSourceInDebugger is not implement from a tab");
}
};
window.Netmonitor.bootstrap({ toolbox });
})().catch(e => {
window.alert("Unable to start the network monitor:" +
e.message + "\n" + e.stack);
});
}
</script>
<script src="initializer.js"></script>
</body>
</html>

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

@ -0,0 +1,155 @@
/* 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/. */
"use strict";
/**
* This script is the entry point of Network monitor panel.
* See README.md for more information.
*/
const { BrowserLoader } = Components.utils.import(
"resource://devtools/client/shared/browser-loader.js", {});
const require = window.windowRequire = BrowserLoader({
baseURI: "resource://devtools/client/netmonitor/",
window,
}).require;
const EventEmitter = require("devtools/shared/old-event-emitter");
const { createFactory } = require("devtools/client/shared/vendor/react");
const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
const { Connector } = require("./src/connector/index");
const { configureStore } = require("./src/utils/create-store");
const App = createFactory(require("./src/components/App"));
const { getDisplayedRequestById } = require("./src/selectors/index");
const { EVENTS } = require("./src/constants");
// Inject EventEmitter into global window.
EventEmitter.decorate(window);
// Configure store/state object.
let connector = new Connector();
const store = configureStore(connector);
const actions = bindActionCreators(require("./src/actions/index"), store.dispatch);
// Inject to global window for testing
window.store = store;
window.connector = connector;
/**
* Global Netmonitor object in this panel. This object can be consumed
* by other panels (e.g. Console is using inspectRequest), by the
* Launchpad (bootstrap), etc.
*/
window.Netmonitor = {
bootstrap({ toolbox, panel }) {
this.mount = document.querySelector("#mount");
const connection = {
tabConnection: {
tabTarget: toolbox.target,
},
toolbox,
panel,
};
const openLink = (link) => {
let parentDoc = toolbox.doc;
let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
let top = iframe.ownerDocument.defaultView.top;
top.openUILinkIn(link, "tab");
};
// Render the root Application component.
const sourceMapService = toolbox.sourceMapURLService;
const app = App({ connector, openLink, sourceMapService });
render(Provider({ store }, app), this.mount);
// Connect to the Firefox backend by default.
return connector.connectFirefox(connection, actions, store.getState);
},
destroy() {
unmountComponentAtNode(this.mount);
return connector.disconnect();
},
/**
* Selects the specified request in the waterfall and opens the details view.
* This is a firefox toolbox specific API, which providing an ability to inspect
* a network request directly from other internal toolbox panel.
*
* @param {string} requestId The actor ID of the request to inspect.
* @return {object} A promise resolved once the task finishes.
*/
inspectRequest(requestId) {
// Look for the request in the existing ones or wait for it to appear, if
// the network monitor is still loading.
return new Promise((resolve) => {
let request = null;
let inspector = () => {
request = getDisplayedRequestById(store.getState(), requestId);
if (!request) {
// Reset filters so that the request is visible.
actions.toggleRequestFilterType("all");
request = getDisplayedRequestById(store.getState(), requestId);
}
// If the request was found, select it. Otherwise this function will be
// called again once new requests arrive.
if (request) {
window.off(EVENTS.REQUEST_ADDED, inspector);
actions.selectRequest(request.id);
resolve();
}
};
inspector();
if (!request) {
window.on(EVENTS.REQUEST_ADDED, inspector);
}
});
}
};
// Implement support for:
// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
// where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
// URL constructor doesn't support chrome: scheme
let href = window.location.href.replace(/chrome:/, "http://");
let url = new window.URL(href);
// If query parameters are given in a chrome tab, the inspector
// is running in standalone.
if (window.location.protocol === "chrome:" && url.search.length > 1) {
const { targetFromURL } = require("devtools/client/framework/target-from-url");
(async function () {
try {
let target = await targetFromURL(url);
// Start the network event listening as it is done in the toolbox code
await target.activeConsole.startListeners([
"NetworkActivity",
]);
// Create a fake toolbox object
let toolbox = {
target,
viewSourceInDebugger() {
throw new Error("toolbox.viewSourceInDebugger is not implement from a tab");
}
};
window.Netmonitor.bootstrap({ toolbox });
} catch (err) {
window.alert("Unable to start the network monitor:" + err);
}
})();
}

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

@ -14,7 +14,7 @@ const { getConfig } = require("./bin/configure");
let webpackConfig = {
entry: {
netmonitor: [path.join(__dirname, "index.js")]
netmonitor: [path.join(__dirname, "launchpad.js")]
},
module: {

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

@ -50,9 +50,10 @@ support-files =
sourcemaps-watching.html
test_private.css
test_private.html
doc_fetch_from_netmonitor.html
doc_long_string.css
doc_long.css
doc_uncached.css
doc_uncached.html
doc_short_string.css
doc_xulpage.xul
sync.html
utf-16.css

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

@ -3,10 +3,10 @@
"use strict";
// A test to ensure Style Editor only issues 1 request for a stylesheet (instead of 2) by
// using the network monitor's request history (bug 1306892).
// A test to ensure Style Editor only issues 1 request for each stylesheet (instead of 2)
// by using the network monitor's request history (bug 1306892).
const TEST_URL = TEST_BASE_HTTP + "doc_uncached.html";
const TEST_URL = TEST_BASE_HTTP + "doc_fetch_from_netmonitor.html";
add_task(function* () {
info("Opening netmonitor");
@ -27,18 +27,27 @@ add_task(function* () {
info("Opening Style Editor");
let styleeditor = yield toolbox.selectTool("styleeditor");
let ui = styleeditor.UI;
info("Waiting for the source to be loaded.");
yield styleeditor.UI.editors[0].getSourceEditor();
info("Waiting for the sources to be loaded.");
yield ui.editors[0].getSourceEditor();
yield ui.selectStyleSheet(ui.editors[1].styleSheet);
yield ui.editors[1].getSourceEditor();
info("Checking Netmonitor contents.");
let items = [];
let shortRequests = [];
let longRequests = [];
for (let item of getSortedRequests(store.getState())) {
if (item.url.endsWith("doc_uncached.css")) {
items.push(item);
if (item.url.endsWith("doc_short_string.css")) {
shortRequests.push(item);
}
if (item.url.endsWith("doc_long_string.css")) {
longRequests.push(item);
}
}
is(items.length, 1,
"Got one request for doc_uncached.css after Style Editor was loaded.");
is(shortRequests.length, 1,
"Got one request for doc_short_string.css after Style Editor was loaded.");
is(longRequests.length, 1,
"Got one request for doc_long_string.css after Style Editor was loaded.");
});

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

@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>Fetch from netmonitor testcase</title>
<link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_short_string.css"/>
<link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_long_string.css"/>
</head>
<body>
<div>Fetch from netmonitor</div>
</body>
</html>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1,10 +0,0 @@
<!doctype html>
<html>
<head>
<title>uncached testcase</title>
<link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_uncached.css"/>
</head>
<body>
<div>uncached <span>testcase</span></div>
</body>
</html>

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

@ -268,7 +268,6 @@ skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these o
[browser_webconsole_cspro.js]
[browser_webconsole_document_focus.js]
[browser_webconsole_duplicate_errors.js]
skip-if = true # Bug 1403907
[browser_webconsole_errors_after_page_reload.js]
[browser_webconsole_eval_in_debugger_stackframe.js]
[browser_webconsole_eval_in_debugger_stackframe2.js]

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

@ -1,5 +1,3 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
@ -10,40 +8,20 @@
const INIT_URI = "data:text/html;charset=utf8,hello world";
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
"test/test-duplicate-error.html";
add_task(function* () {
yield loadTab(INIT_URI);
let hud = yield openConsole();
"new-console-output/test/mochitest/test-duplicate-error.html";
add_task(async function () {
// On e10s, the exception is triggered in child process
// and is ignored by test harness
if (!Services.appinfo.browserTabsRemoteAutostart) {
expectUncaughtException();
}
let hud = await openNewTabAndConsole(TEST_URI);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
await waitFor(() => findMessage(hud, "fooDuplicateError1", ".message.error"));
yield waitForMessages({
webconsole: hud,
messages: [{
text: "fooDuplicateError1",
category: CATEGORY_JS,
severity: SEVERITY_ERROR,
},
{
text: "test-duplicate-error.html",
category: CATEGORY_NETWORK,
severity: SEVERITY_LOG,
}],
});
let text = hud.outputNode.textContent;
let error1pos = text.indexOf("fooDuplicateError1");
ok(error1pos > -1, "found fooDuplicateError1");
if (error1pos > -1) {
ok(text.indexOf("fooDuplicateError1", error1pos + 1) == -1,
"no duplicate for fooDuplicateError1");
}
const errorMessages = hud.outputNode.querySelectorAll(".message.error");
is(errorMessages.length, 1, "There's only one error message for fooDuplicateError1");
is(errorMessages[0].querySelector(".message-repeats"), null,
"There is no repeat bubble on the error message")
});

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

@ -494,8 +494,20 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
if (request._discardResponseBody || !content) {
return null;
}
if (content.text.type != "longString") {
// For short strings, the text is available directly.
return {
content: content.text,
contentType: content.mimeType,
};
}
// For long strings, look up the actor that holds the full text.
let longStringActor = this.conn._getOrCreateActor(content.text.actor);
if (!longStringActor) {
return null;
}
return {
content: content.text,
content: longStringActor.rawValue(),
contentType: content.mimeType,
};
},

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

@ -7,12 +7,16 @@
const URL1 = MAIN_DOMAIN + "navigate-first.html";
const URL2 = MAIN_DOMAIN + "navigate-second.html";
var EventEmitter = require("devtools/shared/event-emitter");
var client;
var isE10s = Services.appinfo.browserTabsRemoteAutostart;
SpecialPowers.pushPrefEnv(
{"set": [["dom.require_user_interaction_for_beforeunload", false]]});
var signalAllEventsReceived;
var onAllEventsReceived = new Promise(resolve => {
signalAllEventsReceived = resolve;
});
// State machine to check events order
var i = 0;
function assertEvent(event, data) {
@ -31,32 +35,29 @@ function assertEvent(event, data) {
is(event, "will-navigate", "The very first event is will-navigate on server side");
is(data.newURI, URL2, "newURI property is correct");
break;
case 4:
is(event, "request",
"RDP is async with messageManager, the request happens after will-navigate");
is(data, URL2);
break;
case 5:
case isE10s ? 4 : 5: // When e10s is disabled tabNavigated/request order is swapped
is(event, "tabNavigated", "After the request, the client receive tabNavigated");
is(data.state, "start", "state is start");
is(data.url, URL2, "url property is correct");
is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
break;
case isE10s ? 5 : 4:
is(event, "request",
"RDP is async with messageManager, the request happens after will-navigate");
is(data, URL2);
break;
case 6:
is(event, "DOMContentLoaded");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "interactive");
is(data.readyState, "interactive");
break;
case 7:
is(event, "load");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "complete");
is(data.readyState, "complete");
break;
case 8:
is(event, "navigate",
"Then once the second doc is loaded, we get the navigate event");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(content.document.readyState, "complete",
is(data.readyState, "complete",
"navigate is emitted only once the document is fully loaded");
break;
case 9:
@ -65,20 +66,18 @@ function assertEvent(event, data) {
is(data.url, URL2, "url property is correct");
is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
// End of test!
cleanup();
signalAllEventsReceived();
break;
}
}
function waitForOnBeforeUnloadDialog(browser, callback) {
browser.addEventListener("DOMWillOpenModalDialog", function () {
executeSoon(() => {
let stack = browser.parentNode;
let dialogs = stack.getElementsByTagName("tabmodalprompt");
let {button0, button1} = dialogs[0].ui;
callback(button0, button1);
});
browser.addEventListener("DOMWillOpenModalDialog", async function (event) {
let stack = browser.parentNode;
let dialogs = stack.getElementsByTagName("tabmodalprompt");
await waitUntil(() => dialogs[0]);
let {button0, button1} = dialogs[0].ui;
callback(button0, button1);
}, {capture: true, once: true});
}
@ -92,71 +91,86 @@ var httpObserver = function (subject, topic, state) {
};
Services.obs.addObserver(httpObserver, "http-on-modify-request");
function onDOMContentLoaded() {
assertEvent("DOMContentLoaded");
}
function onLoad() {
assertEvent("load");
function onMessage({ data }) {
assertEvent(data.event, data.data);
}
function getServerTabActor(callback) {
async function connectAndAttachTab() {
// Ensure having a minimal server
initDebuggerServer();
// Connect to this tab
let transport = DebuggerServer.connectPipe();
client = new DebuggerClient(transport);
connectDebuggerClient(client).then(form => {
let actorID = form.actor;
client.attachTab(actorID, function (response, tabClient) {
// !Hack! Retrieve a server side object, the BrowserTabActor instance
let tabActor = DebuggerServer.searchAllConnectionsForActor(actorID);
callback(tabActor);
});
});
let client = new DebuggerClient(transport);
client.addListener("tabNavigated", function (event, packet) {
assertEvent("tabNavigated", packet);
});
let form = await connectDebuggerClient(client);
let actorID = form.actor;
await client.attachTab(actorID);
return { client, actorID };
}
function test() {
add_task(async function () {
// Open a test tab
addTab(URL1).then(function (browser) {
getServerTabActor(function (tabActor) {
// In order to listen to internal will-navigate/navigate events
EventEmitter.on(tabActor, "will-navigate", function (data) {
assertEvent("will-navigate", data);
});
EventEmitter.on(tabActor, "navigate", function (data) {
assertEvent("navigate", data);
});
let browser = await addTab(URL1);
// Start listening for page load events
browser.addEventListener("DOMContentLoaded", onDOMContentLoaded, true);
browser.addEventListener("load", onLoad, true);
// Listen for alert() call being made in navigate-first during unload
waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
assertEvent("unload-dialog");
// accept to quit this page to another
btnLeave.click();
});
// Listen for alert() call being made in navigate-first during unload
waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
assertEvent("unload-dialog");
// accept to quit this page to another
btnLeave.click();
// Listen for messages sent by the content task
browser.messageManager.addMessageListener("devtools-test:event", onMessage);
let { client, actorID } = await connectAndAttachTab();
await ContentTask.spawn(browser, [actorID], async function (actorId) {
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { DebuggerServer } = require("devtools/server/main");
const EventEmitter = require("devtools/shared/event-emitter");
// !Hack! Retrieve a server side object, the BrowserTabActor instance
let tabActor = DebuggerServer.searchAllConnectionsForActor(actorId);
// In order to listen to internal will-navigate/navigate events
EventEmitter.on(tabActor, "will-navigate", function (data) {
sendSyncMessage("devtools-test:event", {
event: "will-navigate",
data: { newURI: data.newURI }
});
// Load another document in this doc to dispatch these events
assertEvent("load-new-document");
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, URL2);
});
EventEmitter.on(tabActor, "navigate", function (data) {
sendSyncMessage("devtools-test:event", {
event: "navigate",
data: { readyState: content.document.readyState }
});
});
// Forward DOMContentLoaded and load events
addEventListener("DOMContentLoaded", function () {
sendSyncMessage("devtools-test:event", {
event: "DOMContentLoaded",
data: { readyState: content.document.readyState }
});
}, { capture: true });
addEventListener("load", function () {
sendSyncMessage("devtools-test:event", {
event: "load",
data: { readyState: content.document.readyState }
});
}, { capture: true });
});
}
function cleanup() {
let browser = gBrowser.selectedBrowser;
browser.removeEventListener("DOMContentLoaded", onDOMContentLoaded);
browser.removeEventListener("load", onLoad);
client.close().then(function () {
Services.obs.addObserver(httpObserver, "http-on-modify-request");
DebuggerServer.destroy();
finish();
});
}
// Load another document in this doc to dispatch these events
assertEvent("load-new-document");
BrowserTestUtils.loadURI(browser, URL2);
// Wait for all events to be received
await onAllEventsReceived;
// Cleanup
browser.messageManager.removeMessageListener("devtools-test:event", onMessage);
await client.close();
Services.obs.addObserver(httpObserver, "http-on-modify-request");
DebuggerServer.destroy();
});

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

@ -1585,6 +1585,11 @@ HTMLMediaElement::MozRequestDebugInfo(ErrorResult& aRv)
nsAutoString result;
GetMozDebugReaderData(result);
if (mVideoFrameContainer) {
result.AppendPrintf("Compositor dropped frame(including when element's invisible): %u\n",
mVideoFrameContainer->GetDroppedImageCount());
}
if (mMediaKeys) {
nsString EMEInfo;
GetEMEInfo(EMEInfo);

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

@ -437,6 +437,9 @@ TabChild::TabChild(nsIContentChild* aManager,
#endif
, mPendingDocShellIsActive(false)
, mPendingDocShellReceivedMessage(false)
, mPendingRenderLayers(false)
, mPendingRenderLayersReceivedMessage(false)
, mPendingLayerObserverEpoch(0)
, mPendingDocShellBlockers(0)
, mWidgetNativeData(0)
{
@ -2663,6 +2666,10 @@ TabChild::RemovePendingDocShellBlocker()
mPendingDocShellReceivedMessage = false;
InternalSetDocShellIsActive(mPendingDocShellIsActive);
}
if (!mPendingDocShellBlockers && mPendingRenderLayersReceivedMessage) {
mPendingRenderLayersReceivedMessage = false;
RecvRenderLayers(mPendingRenderLayers, mPendingLayerObserverEpoch);
}
}
void
@ -2696,6 +2703,13 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive)
mozilla::ipc::IPCResult
TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverEpoch)
{
if (mPendingDocShellBlockers > 0) {
mPendingRenderLayersReceivedMessage = true;
mPendingRenderLayers = aEnabled;
mPendingLayerObserverEpoch = aLayerObserverEpoch;
return IPC_OK();
}
// Since requests to change the rendering state come in from both the hang
// monitor channel and the PContent channel, we have an ordering problem. This
// code ensures that we respect the order in which the requests were made and

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

@ -983,8 +983,20 @@ private:
#endif
bool mCoalesceMouseMoveEvents;
// In some circumstances, a DocShell might be in a state where it is
// "blocked", and we should not attempt to change its active state or
// the underlying PresShell state until the DocShell becomes unblocked.
// It is possible, however, for the parent process to send commands to
// change those states while the DocShell is blocked. We store those
// states temporarily as "pending", and only apply them once the DocShell
// is no longer blocked.
bool mPendingDocShellIsActive;
bool mPendingDocShellReceivedMessage;
bool mPendingRenderLayers;
bool mPendingRenderLayersReceivedMessage;
uint64_t mPendingLayerObserverEpoch;
// When mPendingDocShellBlockers is greater than 0, the DocShell is blocked,
// and once it reaches 0, it is no longer blocked.
uint32_t mPendingDocShellBlockers;
WindowsHandle mWidgetNativeData;

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

@ -157,7 +157,7 @@ TabParent::TabParent(nsIContentParent* aManager,
, mUpdatedDimensions(false)
, mSizeMode(nsSizeMode_Normal)
, mManager(aManager)
, mDocShellIsActive(false)
, mDocShellIsActive(true)
, mMarkedDestroying(false)
, mIsDestroyed(false)
, mChromeFlags(aChromeFlags)

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

@ -413,6 +413,8 @@ ChannelMediaDecoder::DownloadProgressed()
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
GetOwner()->DownloadProgressed();
using StatsPromise = MozPromise<MediaStatistics, bool, true>;
InvokeAsync(GetStateMachine()->OwnerThread(),
__func__,
@ -437,8 +439,8 @@ ChannelMediaDecoder::DownloadProgressed()
mCanPlayThrough = aStats.CanPlayThrough();
GetStateMachine()->DispatchCanPlayThrough(mCanPlayThrough);
mResource->ThrottleReadahead(ShouldThrottleDownload(aStats));
AbstractThread::AutoEnter context(AbstractMainThread());
GetOwner()->DownloadProgressed();
// Update readyState since mCanPlayThrough might have changed.
GetOwner()->UpdateReadyState();
},
[]() { MOZ_ASSERT_UNREACHABLE("Promise not resolved"); });
}

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

@ -153,27 +153,27 @@ public:
// IPC messages recevied, received on the PBackground thread
// these are the actual callbacks with data
virtual mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
mozilla::ipc::Shmem&&,
const VideoFrameProperties & prop) override;
virtual mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
const int& w, const int& h) override;
mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
mozilla::ipc::Shmem&&,
const VideoFrameProperties & prop) override;
mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
const int& w, const int& h) override;
virtual mozilla::ipc::IPCResult RecvDeviceChange() override;
virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
mozilla::ipc::IPCResult RecvDeviceChange() override;
int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
int SetFakeDeviceChangeEvents();
// these are response messages to our outgoing requests
virtual mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
virtual mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
virtual mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
virtual mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
const nsCString& device_id,
const bool& scary) override;
virtual mozilla::ipc::IPCResult RecvReplyFailure(void) override;
virtual mozilla::ipc::IPCResult RecvReplySuccess(void) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvReplyFailure(void) override;
mozilla::ipc::IPCResult RecvReplySuccess(void) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
// the webrtc.org ViECapture calls are mirrored here, but with access
// to a specific PCameras instance to communicate over. These also

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

@ -472,7 +472,7 @@ CamerasParent::RecvNumberOfCaptureDevices(const CaptureEngine& aCapEngine)
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, num]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (num < 0) {
@ -504,7 +504,7 @@ CamerasParent::RecvEnsureInitialized(const CaptureEngine& aCapEngine)
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, result]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (!result) {
@ -542,7 +542,7 @@ CamerasParent::RecvNumberOfCapabilities(const CaptureEngine& aCapEngine,
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, num]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (num < 0) {
@ -593,7 +593,7 @@ CamerasParent::RecvGetCaptureCapability(const CaptureEngine& aCapEngine,
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
VideoCaptureCapability capCap(webrtcCaps.width,
@ -653,7 +653,7 @@ CamerasParent::RecvGetCaptureDevice(const CaptureEngine& aCapEngine,
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, error, name, uniqueId, devicePid]() {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (error) {
@ -764,7 +764,7 @@ CamerasParent::RecvAllocateCaptureDevice(const CaptureEngine& aCapEngine,
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, numdev, error]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (error) {
@ -810,8 +810,7 @@ CamerasParent::RecvReleaseCaptureDevice(const CaptureEngine& aCapEngine,
int error = self->ReleaseCaptureDevice(aCapEngine, numdev);
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, error, numdev]() -> nsresult {
if (self->IsShuttingDown()) {
LOG(("In Shutdown, not Releasing"));
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (error) {
@ -933,7 +932,7 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
}
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([self, error]() -> nsresult {
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
return NS_ERROR_FAILURE;
}
if (!error) {
@ -994,7 +993,7 @@ CamerasParent::RecvStopCapture(const CaptureEngine& aCapEngine,
return NS_OK;
});
nsresult rv = DispatchToVideoCaptureThread(webrtc_runnable);
if (self->IsShuttingDown()) {
if (!self->mChildIsAlive) {
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}

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

@ -46,7 +46,7 @@ public:
// These callbacks end up running on the VideoCapture thread.
// From VideoCaptureCallback
virtual void OnFrame(const webrtc::VideoFrame& videoFrame) override;
void OnFrame(const webrtc::VideoFrame& videoFrame) override;
friend CamerasParent;
@ -83,25 +83,25 @@ public:
static already_AddRefed<CamerasParent> Create();
// Messages received form the child. These run on the IPC/PBackground thread.
virtual mozilla::ipc::IPCResult
mozilla::ipc::IPCResult
RecvAllocateCaptureDevice(const CaptureEngine& aEngine,
const nsCString& aUnique_idUTF8,
const ipc::PrincipalInfo& aPrincipalInfo) override;
virtual mozilla::ipc::IPCResult RecvReleaseCaptureDevice(const CaptureEngine&,
const int&) override;
virtual mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
virtual mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
const nsCString&) override;
virtual mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
const int&) override;
virtual mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
virtual mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
const VideoCaptureCapability&) override;
virtual mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
virtual mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
virtual mozilla::ipc::IPCResult RecvAllDone() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
mozilla::ipc::IPCResult RecvReleaseCaptureDevice(const CaptureEngine&,
const int&) override;
mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
const nsCString&) override;
mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
const int&) override;
mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
const VideoCaptureCapability&) override;
mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
mozilla::ipc::IPCResult RecvAllDone() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
nsIEventTarget* GetBackgroundEventTarget() { return mPBackgroundEventTarget; };
bool IsShuttingDown()

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

@ -15,10 +15,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=686942
<pre id="test">
<script class="testbody" type="text/javascript">
if (navigator.platform.startsWith("Win")) {
SimpleTest.expectAssertions(0, 2);
}
var manager = new MediaTestManager;
function onloaded(event) {

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

@ -10,51 +10,11 @@
<pre id="test">
<script class="testbody" type="text/javascript">
if (navigator.platform.startsWith("Win")) {
SimpleTest.expectAssertions(0, 10);
}
var manager = new MediaTestManager;
// Test if the ended event works correctly.
function startTest(e) {
var v = e.target;
checkMetadata(v._name, v, v._test);
is(v._loadedMetadata, false, "Should only receive one loadedmetadata event for " + v._name);
v._loadedMetadata = true;
v.currentTime = 3.0 * v.duration;
}
function playbackEnded(e) {
var v = e.target;
// We should have dispatched an ended event when we seeked to the end of
// media, but we want the ended event which dispatches once playback has
// completed after the seek to the beginning.
if (!v._played)
return;
ok(v.ended, "Checking ended set after seeking to EOF and playing for " + v._name);
ok(!v._finished, "Should only hit the end once for " + v._name);
v._finished = true;
removeNodeAndSource(v);
manager.finished(v.token);
}
function endSeek(e) {
var v = e.target;
if (v._seeked)
return;
v._seeked = true;
ok(Math.abs(v.duration - v.currentTime) < 0.1,
"Should be at end of media for " + v._name + " t=" + v.currentTime + " d=" + v.duration);
v.play();
}
function playing(e) {
e.target._played = true;
}
function initTest(test, token) {
async function initTest(test, token) {
var type = getMajorMimeType(test.type);
var v = document.createElement(type);
v.preload = "auto";
@ -62,16 +22,22 @@ function initTest(test, token) {
manager.started(token);
v.src = test.name;
v._name = test.name;
v._finished = false;
v._test = test;
v._loadedMetadata = false;
v._seeked = false;
v._played = false;
v.addEventListener("loadedmetadata", startTest);
v.addEventListener("playing", playing);
v.addEventListener("seeked", endSeek);
v.addEventListener("ended", playbackEnded);
document.body.appendChild(v);
await once(v, "loadedmetadata");
info(`${v._name}: seeking to the end of the media.`);
v.currentTime = 3.0 * v.duration;
// Wait for 'seeked' and 'ended' to be fired.
await Promise.all([once(v, "seeked"), once(v, "ended")]);
// Check currentTime is near the end of the media.
ok(Math.abs(v.duration - v.currentTime) < 0.1,
"Should be at end of media for " + v._name + " t=" + v.currentTime + " d=" + v.duration);
// Call play() to start playback from the beginning.
v.play();
await once(v, "ended");
ok(v.ended, "Checking ended set after seeking to EOF and playing for " + v._name);
removeNodeAndSource(v);
manager.finished(v.token);
}
manager.runTests(gSmallTests, initTest);

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

@ -7217,21 +7217,22 @@ nsCSSFrameConstructor::CheckBitsForLazyFrameConstruction(nsIContent* aParent)
//
// But we disable lazy frame construction for shadow trees... We should fix
// that, too.
//
// NOTE(emilio): The IsXULElement check is pretty unfortunate, but there's tons
// of browser chrome code that rely on XBL bindings getting synchronously loaded
// as soon as the elements get inserted in the DOM.
bool
nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
nsIContent* aContainer,
nsIContent* aChild)
{
if (mPresShell->GetPresContext()->IsChrome() || !aContainer ||
aContainer->IsInNativeAnonymousSubtree() || aContainer->IsXULElement()) {
if (!aContainer || aContainer->IsInNativeAnonymousSubtree() ||
aContainer->IsXULElement()) {
return false;
}
if (aOperation == CONTENTINSERT) {
if (aChild->IsRootOfAnonymousSubtree() ||
(aChild->HasFlag(NODE_IS_IN_SHADOW_TREE) &&
!aChild->IsInNativeAnonymousSubtree()) ||
aChild->IsXULElement()) {
if (aChild->IsRootOfAnonymousSubtree() || aChild->IsXULElement()) {
return false;
}
} else { // CONTENTAPPEND
@ -7239,7 +7240,7 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
"operation should be either insert or append");
for (nsIContent* child = aChild; child; child = child->GetNextSibling()) {
NS_ASSERTION(!child->IsRootOfAnonymousSubtree(),
"Should be coming through the CONTENTAPPEND case");
"Should be coming through the CONTENTINSERT case");
if (child->IsXULElement()) {
return false;
}

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

@ -443,14 +443,30 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
? GetOrthogonalAxis(aAbsPosCBAxis)
: aAbsPosCBAxis);
const bool placeholderContainerIsContainingBlock =
aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame;
LayoutFrameType parentType = aPlaceholderContainer->Type();
LogicalSize alignAreaSize(pcWM);
if (parentType == LayoutFrameType::FlexContainer) {
// The alignment container is the flex container's content box:
alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
LogicalMargin pcBorderPadding =
aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
alignAreaSize -= pcBorderPadding.Size(pcWM);
// We store the frame rect in FinishAndStoreOverflow, which runs _after_
// reflowing the absolute frames, so handle the special case of the frame
// being the actual containing block here, by getting the size from
// aAbsPosCBSize.
//
// The alignment container is the flex container's content box.
if (placeholderContainerIsContainingBlock) {
alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
// aAbsPosCBSize is the padding-box, so substract the padding to get the
// content box.
alignAreaSize -=
aPlaceholderContainer->GetLogicalUsedPadding(pcWM).Size(pcWM);
} else {
alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
LogicalMargin pcBorderPadding =
aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
alignAreaSize -= pcBorderPadding.Size(pcWM);
}
} else if (parentType == LayoutFrameType::GridContainer) {
// This abspos elem's parent is a grid container. Per CSS Grid 10.1 & 10.2:
// - If the grid container *also* generates the abspos containing block (a
@ -458,7 +474,7 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
// the alignment container, too. (And its size is aAbsPosCBSize.)
// - Otherwise, we use the grid's padding box as the alignment container.
// https://drafts.csswg.org/css-grid/#static-position
if (aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame) {
if (placeholderContainerIsContainingBlock) {
// The alignment container is the grid area that we're using as the
// absolute containing block.
alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);

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

@ -276,6 +276,14 @@ RemotePrintJobParent::ActorDestroy(ActorDestroyReason aWhy)
}
mIsDoingPrinting = false;
// If progress dialog is opened, notify closing it.
for (auto listener : mPrintProgressListeners) {
listener->OnStateChange(nullptr,
nullptr,
nsIWebProgressListener::STATE_STOP,
NS_OK);
}
}
} // namespace layout

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

@ -0,0 +1,25 @@
<!doctype html>
<title>CSS Test Reference</title>
<meta charset="utf-8">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<style>
.parent {
position: fixed;
top: 0;
left: 0;
display: block;
width: 200px;
height: 200px;
background: yellow;
}
.child {
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
background: green;
}
</style>
<div class="parent"><div class="child"></div></div>

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

@ -0,0 +1,28 @@
<!doctype html>
<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
<link rel="match" href="position-absolute-containing-block-001-ref.html">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<style>
.parent {
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 200px;
height: 200px;
background: yellow;
}
.child {
position: absolute;
width: 100px;
height: 100px;
background: green;
}
</style>
<div class="parent"><div class="child"></div></div>

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

@ -0,0 +1,25 @@
<!doctype html>
<title>CSS Test Reference</title>
<meta charset="utf-8">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<style>
.parent {
position: fixed;
top: 0;
left: 0;
display: block;
width: 200px;
height: 200px;
background: yellow;
}
.child {
position: absolute;
left: 60px;
top: 60px;
width: 100px;
height: 100px;
background: green;
}
</style>
<div class="parent"><div class="child"></div></div>

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

@ -0,0 +1,36 @@
<!doctype html>
<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
<link rel="match" href="position-absolute-containing-block-002-ref.html">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<style>
.parent {
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 180px;
height: 180px;
/* Expand the background area to 200px, without touching the content-box,
which is what flex absolute children should be aligned relative to. */
border-top: 5px solid yellow;
padding-top: 15px;
border-left: 5px solid yellow;
padding-left: 15px;
background: yellow;
}
.child {
position: absolute;
width: 100px;
height: 100px;
background: green;
}
</style>
<div class="parent"><div class="child"></div></div>

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

@ -213,3 +213,7 @@ fails == flexbox-min-height-auto-002b.html flexbox-min-height-auto-002-ref.html
== flexbox-single-line-clamp-1.html flexbox-single-line-clamp-1-ref.html
== flexbox-single-line-clamp-2.html flexbox-single-line-clamp-2-ref.html
== flexbox-single-line-clamp-3.html flexbox-single-line-clamp-3-ref.html
# Flexbox as an absolute containing block.
== position-absolute-containing-block-001.html position-absolute-containing-block-001-ref.html
== position-absolute-containing-block-002.html position-absolute-containing-block-002-ref.html

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

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIMemoryReporter.h"
#include "mozilla/CachedAnonBoxStyles.h"
#include "mozilla/ServoStyleContext.h"
namespace mozilla {
void
CachedAnonBoxStyles::Insert(ServoStyleContext* aStyle)
{
MOZ_ASSERT(aStyle);
MOZ_ASSERT(aStyle->IsInheritingAnonBox());
if (IsEmpty()) {
RefPtr<ServoStyleContext> s = aStyle;
mBits = reinterpret_cast<uintptr_t>(s.forget().take());
MOZ_ASSERT(!IsEmpty() && !IsIndirect());
} else if (IsIndirect()) {
AsIndirect()->AppendElement(aStyle);
} else {
IndirectCache* cache = new IndirectCache();
cache->AppendElement(dont_AddRef(AsDirect()));
cache->AppendElement(aStyle);
mBits = reinterpret_cast<uintptr_t>(cache) | 1;
MOZ_ASSERT(IsIndirect());
}
}
ServoStyleContext*
CachedAnonBoxStyles::Lookup(nsAtom* aAnonBox) const
{
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
if (IsIndirect()) {
for (auto& style : *AsIndirect()) {
if (style->GetPseudo() == aAnonBox) {
return style;
}
}
return nullptr;
}
ServoStyleContext* direct = AsDirect();
return direct && direct->GetPseudo() == aAnonBox ? direct : nullptr;
}
void
CachedAnonBoxStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
{
if (IsIndirect()) {
for (auto& style : *AsIndirect()) {
if (!aSizes.mState.HaveSeenPtr(style)) {
style->AddSizeOfIncludingThis(aSizes, aCVsSize);
}
}
return;
}
ServoStyleContext* direct = AsDirect();
if (direct && !aSizes.mState.HaveSeenPtr(direct)) {
direct->AddSizeOfIncludingThis(aSizes, aCVsSize);
}
}
} // namespace mozilla

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

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_CachedAnonBoxStyles_h
#define mozilla_CachedAnonBoxStyles_h
#include "nsAtom.h"
#include "nsTArray.h"
class nsWindowSizes;
namespace mozilla {
class ServoStyleContext;
// Cache of anonymous box styles that inherit from a given style.
//
// To minimize memory footprint, the cache is word-sized with a tagged pointer
// If there is only one entry, it's stored inline. If there are more, they're
// stored in an out-of-line buffer. See bug 1429126 comment 0 and comment 1 for
// the measurements and rationale that influenced the design.
class CachedAnonBoxStyles
{
public:
void Insert(ServoStyleContext* aStyle);
ServoStyleContext* Lookup(nsAtom* aAnonBox) const;
CachedAnonBoxStyles() : mBits(0) {}
~CachedAnonBoxStyles()
{
if (IsIndirect()) {
delete AsIndirect();
} else if (!IsEmpty()) {
RefPtr<ServoStyleContext> ref = dont_AddRef(AsDirect());
}
}
void AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const;
private:
// See bug 1429126 comment 1 for the choice of four here.
typedef AutoTArray<RefPtr<ServoStyleContext>, 4> IndirectCache;
bool IsEmpty() const { return !mBits; }
bool IsIndirect() const { return (mBits & 1); }
ServoStyleContext* AsDirect() const
{
MOZ_ASSERT(!IsIndirect());
return reinterpret_cast<ServoStyleContext*>(mBits);
}
IndirectCache* AsIndirect() const
{
MOZ_ASSERT(IsIndirect());
return reinterpret_cast<IndirectCache*>(mBits & ~1);
}
uintptr_t mBits;
};
} // namespace mozilla
#endif // mozilla_CachedAnonBoxStyles_h

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

@ -9,6 +9,7 @@
#ifndef mozilla_dom_MediaList_h
#define mozilla_dom_MediaList_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/ServoUtils.h"
#include "mozilla/StyleBackendType.h"

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

@ -33,26 +33,6 @@ ServoStyleContext::ServoStyleContext(
// producing the ServoComputedData.
}
ServoStyleContext*
ServoStyleContext::GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
{
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
// See the reasoning in SetCachedInheritingAnonBoxStyle to understand why we
// can't use the cache in this case.
if (IsInheritingAnonBox()) {
return nullptr;
}
auto* current = mNextInheritingAnonBoxStyle.get();
while (current && current->GetPseudo() != aAnonBox) {
current = current->mNextInheritingAnonBoxStyle.get();
}
return current;
}
ServoStyleContext*
ServoStyleContext::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
{

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

@ -12,6 +12,8 @@
#include "nsWindowSizes.h"
#include <algorithm>
#include "mozilla/CachedAnonBoxStyles.h"
namespace mozilla {
namespace dom {
@ -45,26 +47,16 @@ public:
!nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType());
}
ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const;
ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
{
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
return mInheritingAnonBoxStyles.Lookup(aAnonBox);
}
void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox,
ServoStyleContext* aStyle)
void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox, ServoStyleContext* aStyle)
{
MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox));
MOZ_ASSERT(!aStyle->mNextInheritingAnonBoxStyle);
// NOTE(emilio): Since we use it to cache inheriting anon boxes in a linked
// list, we can't use that cache if the style we're inheriting from is an
// inheriting anon box itself, since otherwise our parent would mistakenly
// think that the style we're caching inherits from it.
//
// See the documentation of mNextInheritingAnonBoxStyle.
if (IsInheritingAnonBox()) {
return;
}
mNextInheritingAnonBoxStyle.swap(aStyle->mNextInheritingAnonBoxStyle);
mNextInheritingAnonBoxStyle = aStyle;
mInheritingAnonBoxStyles.Insert(aStyle);
}
ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
@ -111,11 +103,7 @@ public:
// clearly identify in DMD's output the memory measured here.
*aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
mSource.AddSizeOfExcludingThis(aSizes);
if (mNextInheritingAnonBoxStyle &&
!aSizes.mState.HaveSeenPtr(mNextInheritingAnonBoxStyle)) {
mNextInheritingAnonBoxStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
}
mInheritingAnonBoxStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
if (mNextLazyPseudoStyle &&
!aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
@ -127,12 +115,9 @@ private:
nsPresContext* mPresContext;
ServoComputedData mSource;
// A linked-list cache of inheriting anon boxes inheriting from this style _if
// the style isn't an inheriting anon-box_.
//
// Otherwise it represents the next entry in the cache of the parent style
// context.
RefPtr<ServoStyleContext> mNextInheritingAnonBoxStyle;
// A cache of inheriting anon boxes inheriting from this style _if the style
// isn't an inheriting anon-box_.
CachedAnonBoxStyles mInheritingAnonBoxStyles;
// A linked-list cache of lazy pseudo styles inheriting from this style _if
// the style isn't a lazy pseudo style itself_.

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

@ -81,6 +81,7 @@ EXPORTS += [
EXPORTS.mozilla += [
'AnimationCollection.h',
'BindingStyleRule.h',
'CachedAnonBoxStyles.h',
'CSSEnabledState.h',
'CSSStyleSheet.h',
'CSSVariableDeclarations.h',
@ -179,6 +180,7 @@ EXPORTS.mozilla.css += [
UNIFIED_SOURCES += [
'AnimationCollection.cpp',
'BindingStyleRule.cpp',
'CachedAnonBoxStyles.cpp',
'CounterStyleManager.cpp',
'CSS.cpp',
'CSSFontFeatureValuesRule.cpp',

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

@ -35,6 +35,7 @@
using namespace mozilla;
using namespace mozilla::css;
using mozilla::dom::Animation;
using mozilla::dom::AnimationEffectReadOnly;
using mozilla::dom::AnimationPlayState;
using mozilla::dom::KeyframeEffectReadOnly;
using mozilla::dom::CSSAnimation;

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

@ -74,8 +74,10 @@ public:
void OnFrame(const webrtc::VideoFrame& frame) override
{
mVideoFrame = frame;
++mOnFrameCount;
}
size_t mOnFrameCount = 0;
webrtc::VideoFrame mVideoFrame;
};
@ -985,16 +987,19 @@ TEST_F(VideoConduitTest, TestReconfigureSendMediaCodec)
ASSERT_EQ(sink->mVideoFrame.width(), 1280);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
ASSERT_EQ(sink->mOnFrameCount, 1U);
SendVideoFrame(640, 360, 2);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
ASSERT_EQ(sink->mOnFrameCount, 2U);
SendVideoFrame(1920, 1280, 3);
ASSERT_EQ(sink->mVideoFrame.width(), 960);
ASSERT_EQ(sink->mVideoFrame.height(), 640);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
ASSERT_EQ(sink->mOnFrameCount, 3U);
mVideoConduit->StopTransmitting();
}
@ -1076,16 +1081,19 @@ TEST_F(VideoConduitTest, TestReconfigureSendMediaCodecWhileTransmitting)
ASSERT_EQ(sink->mVideoFrame.width(), 1280);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
ASSERT_EQ(sink->mOnFrameCount, 1U);
SendVideoFrame(640, 360, 2);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
ASSERT_EQ(sink->mOnFrameCount, 2U);
SendVideoFrame(1920, 1280, 3);
ASSERT_EQ(sink->mVideoFrame.width(), 960);
ASSERT_EQ(sink->mVideoFrame.height(), 640);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
ASSERT_EQ(sink->mOnFrameCount, 3U);
mVideoConduit->StopTransmitting();
}
@ -1111,16 +1119,19 @@ TEST_F(VideoConduitTest, TestVideoEncode)
ASSERT_EQ(sink->mVideoFrame.width(), 1280);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
ASSERT_EQ(sink->mOnFrameCount, 1U);
SendVideoFrame(640, 360, 2);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
ASSERT_EQ(sink->mOnFrameCount, 2U);
SendVideoFrame(1920, 1280, 3);
ASSERT_EQ(sink->mVideoFrame.width(), 1920);
ASSERT_EQ(sink->mVideoFrame.height(), 1280);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
ASSERT_EQ(sink->mOnFrameCount, 3U);
mVideoConduit->StopTransmitting();
mVideoConduit->RemoveSink(sink.get());
@ -1148,16 +1159,19 @@ TEST_F(VideoConduitTest, TestVideoEncodeMaxFs)
ASSERT_EQ(sink->mVideoFrame.width(), 1280);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
ASSERT_EQ(sink->mOnFrameCount, 1U);
SendVideoFrame(640, 360, 2);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
ASSERT_EQ(sink->mOnFrameCount, 2U);
SendVideoFrame(1920, 1280, 3);
ASSERT_EQ(sink->mVideoFrame.width(), 960);
ASSERT_EQ(sink->mVideoFrame.height(), 640);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
ASSERT_EQ(sink->mOnFrameCount, 3U);
// maxFs should not force pixel count above what a sink has requested.
// We set 3600 macroblocks (16x16 pixels), so we request 3500 here.
@ -1168,16 +1182,19 @@ TEST_F(VideoConduitTest, TestVideoEncodeMaxFs)
ASSERT_EQ(sink->mVideoFrame.width(), 960);
ASSERT_EQ(sink->mVideoFrame.height(), 540);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 4000U);
ASSERT_EQ(sink->mOnFrameCount, 4U);
SendVideoFrame(640, 360, 5);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 5000U);
ASSERT_EQ(sink->mOnFrameCount, 5U);
SendVideoFrame(1920, 1280, 6);
ASSERT_EQ(sink->mVideoFrame.width(), 960);
ASSERT_EQ(sink->mVideoFrame.height(), 640);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 6000U);
ASSERT_EQ(sink->mOnFrameCount, 6U);
mVideoConduit->StopTransmitting();
mVideoConduit->RemoveSink(sink.get());
@ -1207,16 +1224,19 @@ TEST_F(VideoConduitTest, DISABLED_TestVideoEncodeMaxWidthAndHeight)
ASSERT_EQ(sink->mVideoFrame.width(), 1280);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
ASSERT_EQ(sink->mOnFrameCount, 1U);
SendVideoFrame(640, 360, 2);
ASSERT_EQ(sink->mVideoFrame.width(), 640);
ASSERT_EQ(sink->mVideoFrame.height(), 360);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
ASSERT_EQ(sink->mOnFrameCount, 2U);
SendVideoFrame(1920, 1280, 3);
ASSERT_EQ(sink->mVideoFrame.width(), 1080);
ASSERT_EQ(sink->mVideoFrame.height(), 720);
ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
ASSERT_EQ(sink->mOnFrameCount, 3U);
mVideoConduit->StopTransmitting();
mVideoConduit->RemoveSink(sink.get());

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

@ -246,7 +246,6 @@ WebrtcVideoConduit::WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall,
, mEngineReceiving(false)
, mCapId(-1)
, mCodecMutex("VideoConduit codec db")
, mInReconfig(false)
, mRecvStream(nullptr)
, mSendStream(nullptr)
, mLastWidth(0)
@ -1697,12 +1696,9 @@ WebrtcVideoConduit::SelectBitrates(
// XXX we need to figure out how to feed back changes in preferred capture
// resolution to the getUserMedia source.
// Returns boolean if we've submitted an async change (and took ownership
// of *frame's data)
bool
void
WebrtcVideoConduit::SelectSendResolution(unsigned short width,
unsigned short height,
const webrtc::VideoFrame* frame) // may be null
unsigned short height)
{
mCodecMutex.AssertCurrentThreadOwns();
// XXX This will do bandwidth-resolution adaptation as well - bug 877954
@ -1731,10 +1727,8 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
}
}
// Adapt to getUserMedia resolution changes
// check if we need to reconfigure the sending resolution.
// Update on resolution changes
// NOTE: mSendingWidth != mLastWidth, because of maxwidth/height/etc above
bool changed = false;
if (mSendingWidth != width || mSendingHeight != height) {
CSFLogDebug(LOGTAG, "%s: resolution changing to %ux%u (from %ux%u)",
__FUNCTION__, width, height, mSendingWidth, mSendingHeight);
@ -1743,7 +1737,6 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
// keep using the old size in the encoder.
mSendingWidth = width;
mSendingHeight = height;
changed = true;
}
unsigned int framerate = SelectSendFrameRate(mCurSendCodecConfig,
@ -1754,72 +1747,7 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
CSFLogDebug(LOGTAG, "%s: framerate changing to %u (from %u)",
__FUNCTION__, framerate, mSendingFramerate);
mSendingFramerate = framerate;
changed = true;
}
if (changed) {
// On a resolution change, bounce this to the correct thread to
// re-configure (same as used for Init(). Do *not* block the calling
// thread since that may be the MSG thread.
// MUST run on the same thread as Init()/etc
if (!NS_IsMainThread()) {
// Note: on *initial* config (first frame), best would be to drop
// frames until the config is done, then encode the most recent frame
// provided and continue from there. We don't do this, but we do drop
// all frames while in the process of a reconfig and then encode the
// frame that started the reconfig, which is close. There may be
// barely perceptible glitch in the video due to the dropped frame(s).
mInReconfig = true;
// We can't pass a UniquePtr<> or unique_ptr<> to a lambda directly
webrtc::VideoFrame* new_frame = nullptr;
if (frame) {
// the internal buffer pointer is refcounted, so we don't have 2 copies here
new_frame = new webrtc::VideoFrame(*frame);
}
RefPtr<WebrtcVideoConduit> self(this);
RefPtr<Runnable> webrtc_runnable =
media::NewRunnableFrom([self, width, height, new_frame]() -> nsresult {
UniquePtr<webrtc::VideoFrame> local_frame(new_frame); // Simplify cleanup
MutexAutoLock lock(self->mCodecMutex);
return self->ReconfigureSendCodec(width, height, new_frame);
});
// new_frame now owned by lambda
CSFLogDebug(LOGTAG, "%s: proxying lambda to WebRTC thread for reconfig (width %u/%u, height %u/%u",
__FUNCTION__, width, mLastWidth, height, mLastHeight);
NS_DispatchToMainThread(webrtc_runnable.forget());
if (new_frame) {
return true; // queued it
}
} else {
// already on the right thread
ReconfigureSendCodec(width, height, frame);
}
}
return false;
}
nsresult
WebrtcVideoConduit::ReconfigureSendCodec(unsigned short width,
unsigned short height,
const webrtc::VideoFrame* frame)
{
mCodecMutex.AssertCurrentThreadOwns();
// Test in case the stream hasn't started yet! We could get a frame in
// before we get around to StartTransmitting(), and that would dispatch a
// runnable to call this.
mInReconfig = false;
if (mSendStream) {
mSendStream->ReconfigureVideoEncoder(mEncoderConfig.CopyConfig());
if (frame) {
mVideoBroadcaster.OnFrame(*frame);
CSFLogDebug(LOGTAG, "%s Inserted a frame from reconfig lambda", __FUNCTION__);
}
}
return NS_OK;
}
unsigned int
@ -1963,15 +1891,10 @@ WebrtcVideoConduit::SendVideoFrame(const webrtc::VideoFrame& frame)
// broken cameras, include Logitech c920's IIRC.
CSFLogVerbose(LOGTAG, "%s (send SSRC %u (0x%x))", __FUNCTION__,
mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front());
mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front());
// See if we need to recalculate what we're sending.
// Don't compute mSendingWidth/Height, since those may not be the same as the input.
{
MutexAutoLock lock(mCodecMutex);
if (mInReconfig) {
// Waiting for it to finish
return kMediaConduitNoError;
}
// mLastWidth/Height starts at 0, so we'll never call SelectSendResolution with a 0 size.
// We in some cases set them back to 0 to force SelectSendResolution to be called again.
if (frame.width() != mLastWidth || frame.height() != mLastHeight) {
@ -1979,12 +1902,11 @@ WebrtcVideoConduit::SendVideoFrame(const webrtc::VideoFrame& frame)
__FUNCTION__, frame.width(), frame.height());
MOZ_ASSERT(frame.width() != 0 && frame.height() != 0);
// Note coverity will flag this since it thinks they can be 0
if (SelectSendResolution(frame.width(), frame.height(), &frame)) {
// SelectSendResolution took ownership of the data in i420_frame.
// Submit the frame after reconfig is done
return kMediaConduitNoError;
}
MutexAutoLock lock(mCodecMutex);
SelectSendResolution(frame.width(), frame.height());
}
// adapt input video to wants of sink
if (!mVideoBroadcaster.frame_wanted()) {
return kMediaConduitNoError;

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

@ -171,19 +171,8 @@ public:
* @param width, height: dimensions of the frame
* @param frame: optional frame to submit for encoding after reconfig
*/
bool SelectSendResolution(unsigned short width,
unsigned short height,
const webrtc::VideoFrame* frame);
/**
* Function to reconfigure the current send codec for a different
* width/height/framerate/etc.
* @param width, height: dimensions of the frame
* @param frame: optional frame to submit for encoding after reconfig
*/
nsresult ReconfigureSendCodec(unsigned short width,
unsigned short height,
const webrtc::VideoFrame* frame);
void SelectSendResolution(unsigned short width,
unsigned short height);
/**
* Function to select and change the encoding frame rate based on incoming frame rate
@ -506,10 +495,9 @@ private:
//Local database of currently applied receive codecs
nsTArray<UniquePtr<VideoCodecConfig>> mRecvCodecList;
// protects mCurSendCodecConfig, mInReconfig,mVideoSend/RecvStreamStats, mSend/RecvStreams, mSendPacketCounts, mRecvPacketCounts
// protects mCurSendCodecConfig, mVideoSend/RecvStreamStats, mSend/RecvStreams, mSendPacketCounts, mRecvPacketCounts
Mutex mCodecMutex;
nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
bool mInReconfig;
SendStreamStatistics mSendStreamStats;
ReceiveStreamStatistics mRecvStreamStats;
webrtc::RtcpPacketTypeCounter mSendPacketCounts;

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

@ -15,7 +15,7 @@ import org.mozilla.gecko.mozglue.JNIObject;
public final class GeckoHLSDemuxerWrapper {
private static final String LOGTAG = "GeckoHLSDemuxerWrapper";
private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
// NOTE : These TRACK definitions should be synced with Gecko.
public enum TrackType {

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

@ -12,7 +12,7 @@ import org.mozilla.gecko.mozglue.JNIObject;
public class GeckoHLSResourceWrapper {
private static final String LOGTAG = "GeckoHLSResourceWrapper";
private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;
private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
private BaseHlsPlayer mPlayer = null;
private boolean mDestroy = false;

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

@ -28,7 +28,7 @@ public class GeckoHlsAudioRenderer extends GeckoHlsRendererBase {
super(C.TRACK_TYPE_AUDIO, eventDispatcher);
assertTrue(Build.VERSION.SDK_INT >= 16);
LOGTAG = getClass().getSimpleName();
DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
}
@Override

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

@ -50,7 +50,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
private static final String LOGTAG = "GeckoHlsPlayer";
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private static final int MAX_TIMELINE_ITEM_LINES = 3;
private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;
private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
private static final AtomicInteger sPlayerId = new AtomicInteger(0);
/*

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

@ -56,7 +56,7 @@ public class GeckoHlsVideoRenderer extends GeckoHlsRendererBase {
super(C.TRACK_TYPE_VIDEO, eventDispatcher);
assertTrue(Build.VERSION.SDK_INT >= 16);
LOGTAG = getClass().getSimpleName();
DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
}
@Override

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

@ -2165,7 +2165,7 @@ cocoa)
LDFLAGS="$LDFLAGS -framework Cocoa -lobjc"
# Use -Wl as a trick to avoid -framework and framework names from
# being separated by AC_SUBST_LIST.
TK_LIBS='-Wl,-framework,CoreLocation -Wl,-framework,QuartzCore -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,AddressBook -Wl,-framework,OpenGL -Wl,-framework,Security -Wl,-framework,ServiceManagement'
TK_LIBS='-Wl,-framework,Foundation -Wl,-framework,CoreFoundation -Wl,-framework,CoreLocation -Wl,-framework,QuartzCore -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,CoreVideo -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,AddressBook -Wl,-framework,OpenGL -Wl,-framework,Security -Wl,-framework,ServiceManagement -Wl,-framework,CoreServices -Wl,-framework,ApplicationServices -Wl,-framework,AppKit'
TK_CFLAGS=""
CFLAGS="$CFLAGS $TK_CFLAGS"
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"

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

@ -303,6 +303,16 @@ impl DOMString {
parse_week_string(&*self.0).is_ok()
}
/// A valid number is the same as what rust considers to be valid,
/// except for +1., NaN, and Infinity.
/// https://html.spec.whatwg.org/multipage/#valid-floating-point-number
pub fn is_valid_number_string(&self) -> bool {
let input = &self.0;
input.parse::<f64>().ok().map_or(false, |val| {
!(val.is_infinite() || val.is_nan() || input.ends_with(".") || input.starts_with("+"))
})
}
/// A valid normalized local date and time string should be "{date}T{time}"
/// where date and time are both valid, and the time string must be as short as possible
/// https://html.spec.whatwg.org/multipage/#valid-normalised-local-date-and-time-string

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

@ -1045,6 +1045,12 @@ impl HTMLInputElement {
textinput.single_line_content_mut().clear();
}
}
InputType::Number => {
let mut textinput = self.textinput.borrow_mut();
if !textinput.single_line_content().is_valid_number_string() {
textinput.single_line_content_mut().clear();
}
}
// TODO: Implement more value sanitization algorithms for different types of inputs
_ => ()
}

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

@ -50,7 +50,7 @@ pub struct HTMLTextAreaElement {
pub trait LayoutHTMLTextAreaElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String;
unsafe fn value_for_layout(self) -> String;
#[allow(unsafe_code)]
unsafe fn selection_for_layout(self) -> Option<Range<usize>>;
#[allow(unsafe_code)]
@ -62,13 +62,16 @@ pub trait LayoutHTMLTextAreaElementHelpers {
impl LayoutHTMLTextAreaElementHelpers for LayoutDom<HTMLTextAreaElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String {
unsafe fn value_for_layout(self) -> String {
let text = (*self.unsafe_get()).textinput.borrow_for_layout().get_content();
String::from(if text.is_empty() {
(*self.unsafe_get()).placeholder.borrow_for_layout().clone()
if text.is_empty() {
(*self.unsafe_get()).placeholder
.borrow_for_layout()
.replace("\r\n", "\n")
.replace("\r", "\n")
} else {
text
})
text.into()
}
}
#[allow(unrooted_must_root)]
@ -138,7 +141,6 @@ impl HTMLTextAreaElement {
let has_value = !self.textinput.borrow().is_empty();
let el = self.upcast::<Element>();
el.set_placeholder_shown_state(has_placeholder && !has_value);
el.set_placeholder_shown_state(has_placeholder);
}
}

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

@ -1140,7 +1140,7 @@ impl LayoutNodeHelpers for LayoutDom<Node> {
}
if let Some(area) = self.downcast::<HTMLTextAreaElement>() {
return unsafe { area.get_value_for_layout() };
return unsafe { area.value_for_layout() };
}
panic!("not text!")

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

@ -398,22 +398,20 @@ pub trait ThreadSafeLayoutElement
&style_pseudo,
Some(data.styles.primary()),
CascadeFlags::empty(),
&ServoMetricsProvider)
.clone()
&ServoMetricsProvider,
)
}
PseudoElementCascadeType::Lazy => {
context.stylist
.lazily_compute_pseudo_element_style(
&context.guards,
unsafe { &self.unsafe_get() },
&style_pseudo,
RuleInclusion::All,
data.styles.primary(),
/* is_probe = */ false,
&ServoMetricsProvider,
/* matching_func = */ None)
.unwrap()
.clone()
context.stylist.lazily_compute_pseudo_element_style(
&context.guards,
unsafe { self.unsafe_get() },
&style_pseudo,
RuleInclusion::All,
data.styles.primary(),
/* is_probe = */ false,
&ServoMetricsProvider,
/* matching_func = */ None,
).unwrap()
}
}
}
@ -424,7 +422,7 @@ pub trait ThreadSafeLayoutElement
fn selected_style(&self) -> Arc<ComputedValues> {
let data = self.style_data();
data.styles.pseudos
.get(&PseudoElement::Selection).map(|s| s)
.get(&PseudoElement::Selection)
.unwrap_or(data.styles.primary())
.clone()
}

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

@ -130,151 +130,11 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
animation_value_type="discrete",
spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}
<%helpers:longhand name="paint-order"
animation_value_type="discrete"
gecko_pref="svg.paint-order.enabled"
products="gecko"
spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder">
use std::fmt;
use style_traits::ToCss;
/// The specified value for a single CSS paint-order property.
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ToCss)]
pub enum PaintOrder {
Normal = 0,
Fill = 1,
Stroke = 2,
Markers = 3,
}
/// Number of non-normal components.
const COUNT: u8 = 3;
/// Number of bits for each component
const SHIFT: u8 = 2;
/// Mask with above bits set
const MASK: u8 = 0b11;
/// The specified value is tree `PaintOrder` values packed into the
/// bitfields below, as a six-bit field, of 3 two-bit pairs
///
/// Each pair can be set to FILL, STROKE, or MARKERS
/// Lowest significant bit pairs are highest priority.
/// `normal` is the empty bitfield. The three pairs are
/// never zero in any case other than `normal`.
///
/// Higher priority values, i.e. the values specified first,
/// will be painted first (and may be covered by paintings of lower priority)
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
pub struct SpecifiedValue(pub u8);
impl SpecifiedValue {
fn normal() -> Self {
SpecifiedValue(0)
}
}
pub mod computed_value {
pub use super::SpecifiedValue as T;
}
pub fn get_initial_value() -> SpecifiedValue {
SpecifiedValue::normal()
}
impl SpecifiedValue {
fn order_at(&self, pos: u8) -> PaintOrder {
// Safe because PaintOrder covers all possible patterns.
unsafe { ::std::mem::transmute((self.0 >> pos * SHIFT) & MASK) }
}
}
pub fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<SpecifiedValue,ParseError<'i>> {
if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
return Ok(SpecifiedValue::normal())
}
let mut value = 0;
// bitfield representing what we've seen so far
// bit 1 is fill, bit 2 is stroke, bit 3 is markers
let mut seen = 0;
let mut pos = 0;
loop {
let result: Result<_, ParseError> = input.try(|input| {
try_match_ident_ignore_ascii_case! { input,
"fill" => Ok(PaintOrder::Fill),
"stroke" => Ok(PaintOrder::Stroke),
"markers" => Ok(PaintOrder::Markers),
}
});
match result {
Ok(val) => {
if (seen & (1 << val as u8)) != 0 {
// don't parse the same ident twice
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
value |= (val as u8) << (pos * SHIFT);
seen |= 1 << (val as u8);
pos += 1;
}
Err(_) => break,
}
}
if value == 0 {
// Couldn't find any keyword
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
// fill in rest
for i in pos..COUNT {
for paint in 0..COUNT {
// if not seen, set bit at position, mark as seen
if (seen & (1 << paint)) == 0 {
seen |= 1 << paint;
value |= paint << (i * SHIFT);
break;
}
}
}
Ok(SpecifiedValue(value))
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.0 == 0 {
return dest.write_str("normal")
}
let mut last_pos_to_serialize = 0;
for i in (1..COUNT).rev() {
let component = self.order_at(i);
let earlier_component = self.order_at(i - 1);
if component < earlier_component {
last_pos_to_serialize = i - 1;
break;
}
}
for pos in 0..last_pos_to_serialize + 1 {
if pos != 0 {
dest.write_str(" ")?
}
self.order_at(pos).to_css(dest)?;
}
Ok(())
}
}
</%helpers:longhand>
${helpers.predefined_type("paint-order", "SVGPaintOrder", "computed::SVGPaintOrder::normal()",
products="gecko",
animation_value_type="discrete",
gecko_pref="svg.paint-order.enabled",
spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder")}
<%helpers:vector_longhand name="-moz-context-properties"
animation_value_type="none"

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

@ -155,8 +155,8 @@ impl SelectorMap<Rule> {
/// Sort the Rules at the end to maintain cascading order.
pub fn get_all_matching_rules<E, F>(
&self,
element: &E,
rule_hash_target: &E,
element: E,
rule_hash_target: E,
matching_rules_list: &mut ApplicableDeclarationList,
context: &mut MatchingContext<E::Impl>,
quirks_mode: QuirksMode,
@ -217,7 +217,7 @@ impl SelectorMap<Rule> {
/// Adds rules in `rules` that match `element` to the `matching_rules` list.
fn get_matching_rules<E, F>(
element: &E,
element: E,
rules: &[Rule],
matching_rules: &mut ApplicableDeclarationList,
context: &mut MatchingContext<E::Impl>,
@ -232,7 +232,7 @@ impl SelectorMap<Rule> {
if matches_selector(&rule.selector,
0,
Some(&rule.hashes),
element,
&element,
context,
flags_setter) {
matching_rules.push(

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

@ -152,24 +152,25 @@ impl ValidationData {
/// Get or compute the list of presentational attributes associated with
/// this element.
pub fn pres_hints<E>(&mut self, element: E) -> &[ApplicableDeclarationBlock]
where E: TElement,
where
E: TElement,
{
if self.pres_hints.is_none() {
self.pres_hints.get_or_insert_with(|| {
let mut pres_hints = SmallVec::new();
element.synthesize_presentational_hints_for_legacy_attributes(
VisitedHandlingMode::AllLinksUnvisited,
&mut pres_hints
);
self.pres_hints = Some(pres_hints);
}
&*self.pres_hints.as_ref().unwrap()
pres_hints
})
}
/// Get or compute the class-list associated with this element.
pub fn class_list<E>(&mut self, element: E) -> &[Atom]
where E: TElement,
where
E: TElement,
{
if self.class_list.is_none() {
self.class_list.get_or_insert_with(|| {
let mut class_list = SmallVec::<[Atom; 5]>::new();
element.each_class(|c| class_list.push(c.clone()));
// Assuming there are a reasonable number of classes (we use the
@ -179,21 +180,20 @@ impl ValidationData {
if !class_list.spilled() {
class_list.sort_by(|a, b| a.get_hash().cmp(&b.get_hash()));
}
self.class_list = Some(class_list);
}
&*self.class_list.as_ref().unwrap()
class_list
})
}
/// Get or compute the parent style identity.
pub fn parent_style_identity<E>(&mut self, el: E) -> OpaqueComputedValues
where E: TElement,
where
E: TElement,
{
if self.parent_style_identity.is_none() {
self.parent_style_identity.get_or_insert_with(|| {
let parent = el.inheritance_parent().unwrap();
self.parent_style_identity =
Some(OpaqueComputedValues::from(parent.borrow_data().unwrap().styles.primary()));
}
self.parent_style_identity.as_ref().unwrap().clone()
let values = OpaqueComputedValues::from(parent.borrow_data().unwrap().styles.primary());
values
}).clone()
}
/// Computes the revalidation results if needed, and returns it.
@ -212,7 +212,7 @@ impl ValidationData {
E: TElement,
F: FnMut(&E, ElementSelectorFlags),
{
if self.revalidation_match_results.is_none() {
self.revalidation_match_results.get_or_insert_with(|| {
// The bloom filter may already be set up for our element.
// If it is, use it. If not, we must be in a candidate
// (i.e. something in the cache), and the element is one
@ -230,16 +230,13 @@ impl ValidationData {
None
}
};
self.revalidation_match_results =
Some(stylist.match_revalidation_selectors(
element,
bloom_to_use,
nth_index_cache,
flags_setter,
));
}
self.revalidation_match_results.as_ref().unwrap()
stylist.match_revalidation_selectors(
element,
bloom_to_use,
nth_index_cache,
flags_setter,
)
})
}
}

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

@ -428,7 +428,7 @@ where
// Compute the primary rule node.
stylist.push_applicable_declarations(
&self.element,
self.element,
implemented_pseudo.as_ref(),
self.element.style_attribute(),
self.element.get_smil_override(),
@ -502,7 +502,7 @@ where
// NB: We handle animation rules for ::before and ::after when
// traversing them.
stylist.push_applicable_declarations(
&self.element,
self.element,
Some(pseudo_element),
None,
None,

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