зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central r=merge a=merge
This commit is contained in:
Коммит
7df7614d04
|
@ -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,
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче