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

This commit is contained in:
Dorel Luca 2017-12-06 23:57:33 +02:00
commit ada131e8c5
40 changed files with 685 additions and 5836 deletions

View File

@ -78,24 +78,24 @@ MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_A
.PHONY: repackage
tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME) features
rm -rf $(dist_dest)
$(MKDIR) -p $(dist_dest)/Contents/MacOS
$(MKDIR) -p $(dist_dest)/$(LPROJ)
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/$(LPROJ)
sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' -e 's|%MOZ_DEVELOPER_REPO_PATH%|$(topsrcdir)|' -e 's|%MOZ_DEVELOPER_OBJ_PATH%|$(topobjdir)|' $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/$(LPROJ)/InfoPlist.strings
rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ $(dist_dest)/Contents/Resources
rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ $(dist_dest)/Contents/MacOS
$(RM) $(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) $(dist_dest)/Contents/MacOS
cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
$(MKDIR) -p $(dist_dest)/Contents/Library/LaunchServices
$(MKDIR) -p '$(dist_dest)/Contents/MacOS'
$(MKDIR) -p '$(dist_dest)/$(LPROJ)'
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents '$(dist_dest)' --exclude English.lproj
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ '$(dist_dest)/$(LPROJ)'
sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' -e 's|%MOZ_DEVELOPER_REPO_PATH%|$(topsrcdir)|' -e 's|%MOZ_DEVELOPER_OBJ_PATH%|$(topobjdir)|' $(srcdir)/macbuild/Contents/Info.plist.in > '$(dist_dest)/Contents/Info.plist'
sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > '$(dist_dest)/$(LPROJ)/InfoPlist.strings'
rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ '$(dist_dest)/Contents/Resources'
rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ '$(dist_dest)/Contents/MacOS'
$(RM) '$(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)'
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) '$(dist_dest)/Contents/MacOS'
cp -RL $(DIST)/branding/firefox.icns '$(dist_dest)/Contents/Resources/firefox.icns'
cp -RL $(DIST)/branding/document.icns '$(dist_dest)/Contents/Resources/document.icns'
$(MKDIR) -p '$(dist_dest)/Contents/Library/LaunchServices'
ifdef MOZ_UPDATER
mv -f $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater $(dist_dest)/Contents/Library/LaunchServices
ln -s ../../../../Library/LaunchServices/org.mozilla.updater $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater
mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices'
ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater'
endif
printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo'
endif
.PHONY: features

View File

@ -49,6 +49,7 @@ let AddressDataLoader = {
country: false,
level1: new Set(),
},
/**
* Load address data and extension script into a sandbox from different paths.
* @param {string} path
@ -77,11 +78,38 @@ let AddressDataLoader = {
}
return sandbox;
},
/**
* Convert certain properties' string value into array. We should make sure
* the cached data is parsed.
* @param {object} data Original metadata from addressReferences.
* @returns {object} parsed metadata with property value that converts to array.
*/
_parse(data) {
if (!data) {
return null;
}
const properties = ["languages", "sub_keys", "sub_names", "sub_lnames"];
for (let key of properties) {
if (!data[key]) {
continue;
}
// No need to normalize data if the value is array already.
if (Array.isArray(data[key])) {
return data;
}
data[key] = data[key].split("~");
}
return data;
},
/**
* We'll cache addressData in the loader once the data loaded from scripts.
* It'll become the example below after loading addressReferences with extension:
* addressData: {
"data/US": {"lang": "en", ...// Data defined in libaddressinput metadata
* "data/US": {"lang": ["en"], ...// Data defined in libaddressinput metadata
* "alternative_names": ... // Data defined in extension }
* "data/CA": {} // Other supported country metadata
* "data/TW": {} // Other supported country metadata
@ -89,16 +117,16 @@ let AddressDataLoader = {
* }
* @param {string} country
* @param {string} level1
* @returns {object}
* @returns {object} Default locale metadata
*/
getData(country, level1 = null) {
_loadData(country, level1 = null) {
// Load the addressData if needed
if (!this._dataLoaded.country) {
this._addressData = this._loadScripts(ADDRESS_METADATA_PATH).addressData;
this._dataLoaded.country = true;
}
if (!level1) {
return this._addressData[`data/${country}`];
return this._parse(this._addressData[`data/${country}`]);
}
// If level1 is set, load addressReferences under country folder with specific
// country/level 1 for level 2 information.
@ -107,7 +135,30 @@ let AddressDataLoader = {
this._loadScripts(`${ADDRESS_METADATA_PATH}${country}/`).addressData);
this._dataLoaded.level1.add(country);
}
return this._addressData[`data/${country}/${level1}`];
return this._parse(this._addressData[`data/${country}/${level1}`]);
},
/**
* Return the region metadata with default locale and other locales (if exists).
* @param {string} country
* @param {string} level1
* @returns {object} Return default locale and other locales metadata.
*/
getData(country, level1) {
let defaultLocale = this._loadData(country, level1);
if (!defaultLocale) {
return null;
}
let countryData = this._parse(this._addressData[`data/${country}`]);
let locales = [];
// TODO: Should be able to support multi-locale level 1/ level 2 metadata query
// in Bug 1421886
if (countryData.languages) {
let list = countryData.languages.filter(key => key !== countryData.lang);
locales = list.map(key => this._parse(this._addressData[`${defaultLocale.id}--${key}`]));
}
return {defaultLocale, locales};
},
};
@ -289,16 +340,18 @@ this.FormAutofillUtils = {
/**
* Get country address data and fallback to US if not found.
* See AddressDataLoader.getData for more details of addressData structure.
* See AddressDataLoader._loadData for more details of addressData structure.
* @param {string} [country=FormAutofillUtils.DEFAULT_REGION]
* The country code for requesting specific country's metadata. It'll be
* default region if parameter is not set.
* @param {string} [level1=null]
* Retrun address level 1/level 2 metadata if parameter is set.
* @returns {object}
* Return the metadata of specific region.
* @returns {object|null}
* Return metadata of specific region with default locale and other supported
* locales. We need to return a deafult country metadata for layout format
* and collator, but for sub-region metadata we'll just return null if not found.
*/
getCountryAddressData(country = FormAutofillUtils.DEFAULT_REGION, level1 = null) {
getCountryAddressRawData(country = FormAutofillUtils.DEFAULT_REGION, level1 = null) {
let metadata = AddressDataLoader.getData(country, level1);
if (!metadata) {
if (level1) {
@ -310,8 +363,35 @@ this.FormAutofillUtils = {
}
}
// Fallback to US if we couldn't get data from default region.
return metadata || AddressDataLoader.getData("US");
// TODO: Now we fallback to US if we couldn't get data from default region,
// but it could be removed in bug 1423464 if it's not necessary.
if (!metadata) {
metadata = AddressDataLoader.getData("US");
}
return metadata;
},
/**
* Get country address data with default locale.
* @param {string} country
* @param {string} level1
* @returns {object|null} Return metadata of specific region with default locale.
*/
getCountryAddressData(country, level1) {
let metadata = this.getCountryAddressRawData(country, level1);
return metadata && metadata.defaultLocale;
},
/**
* Get country address data with all locales.
* @param {string} country
* @param {string} level1
* @returns {array<object>|null}
* Return metadata of specific region with all the locales.
*/
getCountryAddressDataWithLocales(country, level1) {
let metadata = this.getCountryAddressRawData(country, level1);
return metadata && [metadata.defaultLocale, ...metadata.locales];
},
/**
@ -327,7 +407,7 @@ this.FormAutofillUtils = {
if (!this._collators[country]) {
let dataset = this.getCountryAddressData(country);
let languages = dataset.languages ? dataset.languages.split("~") : [dataset.lang];
let languages = dataset.languages || [dataset.lang];
this._collators[country] = languages.map(lang => new Intl.Collator(lang, {sensitivity: "base", ignorePunctuation: true}));
}
return this._collators[country];
@ -438,33 +518,33 @@ this.FormAutofillUtils = {
let values = Array.isArray(subregionValues) ? subregionValues : [subregionValues];
let collators = this.getCollators(country);
let {sub_keys: subKeys, sub_names: subNames} = this.getCountryAddressData(country);
for (let metadata of this.getCountryAddressDataWithLocales(country)) {
let {sub_keys: subKeys, sub_names: subNames, sub_lnames: subLnames} = metadata;
// Apply sub_lnames if sub_names does not exist
subNames = subNames || subLnames;
if (!Array.isArray(subKeys)) {
subKeys = subKeys.split("~");
}
if (!Array.isArray(subNames)) {
subNames = subNames.split("~");
}
let speculatedSubIndexes = [];
for (const val of values) {
let identifiedValue = this.identifyValue(subKeys, subNames, val, collators);
if (identifiedValue) {
return identifiedValue;
}
let speculatedSubIndexes = [];
for (const val of values) {
let identifiedValue = this.identifyValue(subKeys, subNames, val, collators);
if (identifiedValue) {
return identifiedValue;
// Predict the possible state by partial-matching if no exact match.
[subKeys, subNames].forEach(sub => {
speculatedSubIndexes.push(sub.findIndex(token => {
let pattern = new RegExp("\\b" + this.escapeRegExp(token) + "\\b");
return pattern.test(val);
}));
});
}
let subKey = subKeys[speculatedSubIndexes.find(i => !!~i)];
if (subKey) {
return subKey;
}
// Predict the possible state by partial-matching if no exact match.
[subKeys, subNames].forEach(sub => {
speculatedSubIndexes.push(sub.findIndex(token => {
let pattern = new RegExp("\\b" + this.escapeRegExp(token) + "\\b");
return pattern.test(val);
}));
});
}
return subKeys[speculatedSubIndexes.find(i => !!~i)] || null;
return null;
},
/**
@ -484,7 +564,6 @@ this.FormAutofillUtils = {
return null;
}
let dataset = this.getCountryAddressData(address.country);
let collators = this.getCollators(address.country);
for (let option of selectEl.options) {
@ -496,29 +575,26 @@ this.FormAutofillUtils = {
switch (fieldName) {
case "address-level1": {
if (!Array.isArray(dataset.sub_keys)) {
dataset.sub_keys = dataset.sub_keys.split("~");
}
if (!Array.isArray(dataset.sub_names)) {
dataset.sub_names = dataset.sub_names.split("~");
}
let keys = dataset.sub_keys;
let names = dataset.sub_names;
let identifiedValue = this.identifyValue(keys, names, value, collators);
// No point going any further if we cannot identify value from address
let {country} = address;
let identifiedValue = this.getAbbreviatedSubregionName([value], country);
// No point going any further if we cannot identify value from address level 1
if (!identifiedValue) {
return null;
}
for (let dataset of this.getCountryAddressDataWithLocales(country)) {
let keys = dataset.sub_keys;
// Apply sub_lnames if sub_names does not exist
let names = dataset.sub_names || dataset.sub_lnames;
// Go through options one by one to find a match.
// Also check if any option contain the address-level1 key.
let pattern = new RegExp("\\b" + this.escapeRegExp(identifiedValue) + "\\b", "i");
for (let option of selectEl.options) {
let optionValue = this.identifyValue(keys, names, option.value, collators);
let optionText = this.identifyValue(keys, names, option.text, collators);
if (identifiedValue === optionValue || identifiedValue === optionText || pattern.test(option.value)) {
return option;
// Go through options one by one to find a match.
// Also check if any option contain the address-level1 key.
let pattern = new RegExp("\\b" + this.escapeRegExp(identifiedValue) + "\\b", "i");
for (let option of selectEl.options) {
let optionValue = this.identifyValue(keys, names, option.value, collators);
let optionText = this.identifyValue(keys, names, option.text, collators);
if (identifiedValue === optionValue || identifiedValue === optionText || pattern.test(option.value)) {
return option;
}
}
}
break;

View File

@ -16,5 +16,6 @@ scheme=https
scheme=https
[test_form_changes.html]
[test_formautofill_preview_highlight.html]
[test_multi_locale_CA_address_form.html]
[test_multiple_forms.html]
[test_on_address_submission.html]

View File

@ -0,0 +1,201 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test basic autofill</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="formautofill_common.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Form autofill test: simple form address autofill
<script>
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
/* import-globals-from formautofill_common.js */
"use strict";
let MOCK_STORAGE = [{
organization: "Mozilla Vancouver",
"street-address": "163 W Hastings St.\n#209\n3-line",
tel: "+17787851540",
country: "CA",
"address-level1": "BC",
}, {
organization: "Mozilla Toronto",
"street-address": "366 Adelaide St.\nW Suite 500\n3-line",
tel: "+14168483114",
country: "CA",
"address-level1": "ON",
}, {
organization: "Prince of Wales Northern Heritage",
"street-address": "4750 48 St.\nYellowknife\n3-line",
tel: "+18677679347",
country: "CA",
"address-level1": "Northwest Territories",
}, {
organization: "ExpoCité",
"street-address": "250 Boulevard Wilfrid-Hamel\nVille de Québec\n3-line",
tel: "+14186917110",
country: "CA",
"address-level1": "Québec",
}];
function checkElementFilled(element, expectedvalue) {
return [
new Promise(resolve => {
element.addEventListener("input", function onInput() {
ok(true, "Checking " + element.name + " field fires input event");
resolve();
}, {once: true});
}),
new Promise(resolve => {
element.addEventListener("change", function onChange() {
ok(true, "Checking " + element.name + " field fires change event");
is(element.value, expectedvalue, "Checking " + element.name + " field");
resolve();
}, {once: true});
}),
];
}
function checkAutoCompleteInputFilled(element, expectedvalue) {
return new Promise(resolve => {
element.addEventListener("DOMAutoComplete", function onChange() {
is(element.value, expectedvalue, "Checking " + element.name + " field");
resolve();
}, {once: true});
});
}
function checkFormFilled(selector, address) {
info("expecting form filled");
let promises = [];
let form = document.querySelector(selector);
for (let prop in address) {
let element = form.querySelector(`[name=${prop}]`);
if (document.activeElement == element) {
promises.push(checkAutoCompleteInputFilled(element, address[prop]));
} else {
let converted = address[prop];
if (prop == "street-address") {
converted = FormAutofillUtils.toOneLineAddress(converted);
}
promises.push(...checkElementFilled(element, converted));
}
}
doKey("return");
return Promise.all(promises);
}
async function setupAddressStorage() {
for (let address of MOCK_STORAGE) {
await addAddress(address);
}
}
initPopupListener();
// Autofill the address with address level 1 code.
add_task(async function autofill_with_level1_code() {
await setupAddressStorage();
await setInput("#organization-en", "Mozilla Toronto");
doKey("down");
await expectPopup();
doKey("down");
// Replace address level 1 code with full name in English for test result
let result = Object.assign({}, MOCK_STORAGE[1], {"address-level1": "Ontario"});
await checkFormFilled("#form-en", result);
await setInput("#organization-fr", "Mozilla Vancouver");
doKey("down");
await expectPopup();
doKey("down");
// Replace address level 1 code with full name in French for test result
result = Object.assign({}, MOCK_STORAGE[0], {"address-level1": "Colombie-Britannique"});
await checkFormFilled("#form-fr", result);
document.querySelector("#form-en").reset();
document.querySelector("#form-fr").reset();
});
// Autofill the address with address level 1 full name.
add_task(async function autofill_with_level1_full_name() {
await setInput("#organization-en", "ExpoCité");
doKey("down");
await expectPopup();
doKey("down");
// Replace address level 1 code with full name in French for test result
let result = Object.assign({}, MOCK_STORAGE[3], {"address-level1": "Quebec"});
await checkFormFilled("#form-en", result);
await setInput("#organization-fr", "Prince of Wales Northern Heritage");
doKey("down");
await expectPopup();
doKey("down");
// Replace address level 1 code with full name in English for test result
result = Object.assign({}, MOCK_STORAGE[2], {"address-level1": "Territoires du Nord-Ouest"});
await checkFormFilled("#form-fr", result);
});
</script>
<p id="display"></p>
<div id="content">
<form id="form-en">
<p>This is a basic CA form with en address level 1 select.</p>
<p><label>organization: <input id="organization-en" name="organization" autocomplete="organization" type="text"></label></p>
<p><label>streetAddress: <input id="street-address-en" name="street-address" autocomplete="street-address" type="text"></label></p>
<p><label>address-line1: <input id="address-line1-en" name="address-line1" autocomplete="address-line1" type="text"></label></p>
<p><label>tel: <input id="tel-en" name="tel" autocomplete="tel" type="text"></label></p>
<p><label>email: <input id="email-en" name="email" autocomplete="email" type="text"></label></p>
<p><label>country: <select id="country-en" name="country" autocomplete="country">
<option/>
<option value="US">United States</option>
<option value="CA">Canada</option>
</select></label></p>
<p><label>states: <select id="address-level1-en" name="address-level1" autocomplete="address-level1">
<option/>
<option value="British Columbia">British Columbia</option>
<option value="Ontario">Ontario</option>
<option value="Northwest Territories">Northwest Territories</option>
<option value="Quebec">Quebec</option>
</select></label></p>
</form>
<form id="form-fr">
<p>This is a basic CA form with fr address level 1 select.</p>
<p><label>organization: <input id="organization-fr" name="organization" autocomplete="organization" type="text"></label></p>
<p><label>streetAddress: <input id="street-address-fr" name="street-address" autocomplete="street-address" type="text"></label></p>
<p><label>address-line1: <input id="address-line1-fr" name="address-line1" autocomplete="address-line1" type="text"></label></p>
<p><label>tel: <input id="tel-fr" name="tel" autocomplete="tel" type="text"></label></p>
<p><label>email: <input id="email-fr" name="email" autocomplete="email" type="text"></label></p>
<p><label>country: <select id="country-fr" name="country" autocomplete="country">
<option/>
<option value="US">United States</option>
<option value="CA">Canada</option>
</select></label></p>
<p><label>states: <select id="address-level1-fr" name="address-level1" autocomplete="address-level1">
<option/>
<option value="Colombie-Britannique">Colombie-Britannique</option>
<option value="Ontario">Ontario</option>
<option value="Territoires du Nord-Ouest">Territoires du Nord-Ouest</option>
<option value="Québec">Québec</option>
</select></label></p>
</form>
</div>
<pre id="test"></pre>
</body>
</html>

View File

@ -69,5 +69,13 @@ SUPPORT_COUNTRIES_TESTCASES.forEach(testcase => {
let metadata = FormAutofillUtils.getCountryAddressData(testcase.country);
Assert.ok(testcase.properties.every(key => metadata[key]),
"These properties should exist: " + testcase.properties);
// Verify the multi-locale country
if (metadata.languages && metadata.languages.length > 1) {
let locales = FormAutofillUtils.getCountryAddressDataWithLocales(testcase.country);
Assert.equal(metadata.languages.length, locales.length, "Total supported locales should be matched");
metadata.languages.forEach((lang, index) => {
Assert.equal(lang, locales[index].lang, `Should support ${lang}`);
});
}
});
});

View File

@ -110,19 +110,19 @@ include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
ifeq (bundle, $(MOZ_FS_LAYOUT))
BINPATH = $(_BINPATH)
DEFINES += -DAPPNAME=$(_APPNAME)
DEFINES += -DAPPNAME='$(_APPNAME)'
else
# Every other platform just winds up in dist/bin
BINPATH = bin
endif
DEFINES += -DBINPATH=$(BINPATH)
DEFINES += -DBINPATH='$(BINPATH)'
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
RESPATH = $(_APPNAME)/Contents/Resources
else
RESPATH = $(BINPATH)
endif
DEFINES += -DRESPATH=$(RESPATH)
DEFINES += -DRESPATH="$(RESPATH)"
LPROJ_ROOT = $(firstword $(subst -, ,$(AB_CD)))
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))

View File

@ -155,10 +155,10 @@ endif
ident:
@printf 'fx_revision '
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
$(STAGEDIST)/application.ini App SourceStamp
'$(STAGEDIST)'/application.ini App SourceStamp
@printf 'buildid '
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
$(STAGEDIST)/application.ini App BuildID
'$(STAGEDIST)'/application.ini App BuildID
# test target, depends on make package
# try to repack x-test, with just toolkit/defines.inc being there

View File

@ -717,7 +717,7 @@ html|span.ac-emphasize-text-url {
:root[tabsintitlebar] > #titlebar:-moz-lwtheme {
visibility: hidden;
}
:root[tabsintitlebar] > #titlebar-content:-moz-lwtheme {
:root[tabsintitlebar] #titlebar-content:-moz-lwtheme {
visibility: visible;
}

View File

@ -13,35 +13,43 @@
* See devtools/client/framework/toolbox.js:setIframeVisible().
*/
const {
createClass,
} = require("devtools/client/shared/vendor/react");
const { Component } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const VisibilityHandler = createClass({
class VisibilityHandler extends Component {
static get propTypes() {
return {
children: PropTypes.element.isRequired
};
}
displayName: "VisiblityHandler",
constructor(props) {
super(props);
this.onVisibilityChange = this.onVisibilityChange.bind(this);
}
componentDidMount() {
window.addEventListener("visibilitychange", this.onVisibilityChange);
}
shouldComponentUpdate() {
return document.visibilityState == "visible";
},
}
componentWillUnmount() {
window.removeEventListener("visibilitychange", this.onVisibilityChange);
}
onVisibilityChange() {
if (document.visibilityState == "visible") {
this.forceUpdate();
}
},
componentDidMount() {
window.addEventListener("visibilitychange", this.onVisibilityChange);
},
componentWillUnmount() {
window.removeEventListener("visibilitychange", this.onVisibilityChange);
},
}
render() {
return this.props.children;
}
});
}
module.exports = VisibilityHandler;

View File

@ -259,8 +259,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
subsuite = clipboard
[browser_webconsole_context_menu_open_url.js]
[browser_webconsole_context_menu_store_as_global.js]
[browser_webconsole_copy_link_location.js]
skip-if = true # Bug 1401944
[browser_webconsole_csp_ignore_reflected_xss_message.js]
skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows
[browser_webconsole_cspro.js]

View File

@ -22,14 +22,15 @@ add_task(async function() {
info("Test Copy URL menu item for text log");
info("Logging a text message in the content window");
let onLogMessage = waitForMessage(hud, "simple text message");
await ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
content.wrappedJSObject.console.log("simple text message");
});
let message = await waitFor(() => findMessage(hud, "simple text message"));
let message = await onLogMessage;
ok(message, "Text log found in the console");
info("Open and check the context menu for the logged text message");
let menuPopup = await openContextMenu(hud, message);
let menuPopup = await openContextMenu(hud, message.node);
let copyURLItem = menuPopup.querySelector(CONTEXT_MENU_ID);
ok(!copyURLItem, "Copy URL menu item is hidden for a simple text message");
@ -39,15 +40,16 @@ add_task(async function() {
info("Test Copy URL menu item for network log");
info("Reload the content window to produce a network log");
let onNetworkMessage = waitForMessage(hud, "test-console.html");
await ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
content.wrappedJSObject.location.reload();
});
message = await waitFor(() => findMessage(hud, "test-console.html"));
message = await onNetworkMessage;
ok(message, "Network log found in the console");
info("Open and check the context menu for the logged network message");
menuPopup = await openContextMenu(hud, message);
menuPopup = await openContextMenu(hud, message.node);
copyURLItem = menuPopup.querySelector(CONTEXT_MENU_ID);
ok(copyURLItem, "Copy url menu item is available in context menu");

View File

@ -1,107 +0,0 @@
/* -*- 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/ */
// Test for the "Copy link location" context menu item shown when you right
// click network requests in the output. See Bug 638949.
"use strict";
add_task(function* () {
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
"test/test-console.html?_date=" + Date.now();
const COMMAND_NAME = "consoleCmd_copyURL";
const CONTEXT_MENU_ID = "#menu_copyURL";
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.webconsole.filter.networkinfo");
});
Services.prefs.setBoolPref("devtools.webconsole.filter.networkinfo", true);
yield loadTab(TEST_URI);
let hud = yield openConsole();
let output = hud.outputNode;
let menu = hud.iframeWindow.document.getElementById("output-contextmenu");
hud.jsterm.clearOutput();
content.console.log("bug 638949");
// Test that the "Copy Link Location" command is disabled for non-network
// messages.
let [result] = yield waitForMessages({
webconsole: hud,
messages: [{
text: "bug 638949",
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
});
output.focus();
let message = [...result.matched][0];
goUpdateCommand(COMMAND_NAME);
ok(!isEnabled(), COMMAND_NAME + " is disabled");
// Test that the "Copy Link Location" menu item is hidden for non-network
// messages.
yield waitForContextMenu(menu, message, () => {
let isHidden = menu.querySelector(CONTEXT_MENU_ID).hidden;
ok(isHidden, CONTEXT_MENU_ID + " is hidden");
});
hud.jsterm.clearOutput();
// Reloading will produce network logging
content.location.reload();
// Test that the "Copy Link Location" command is enabled and works
// as expected for any network-related message.
// This command should copy only the URL.
[result] = yield waitForMessages({
webconsole: hud,
messages: [{
text: "test-console.html",
category: CATEGORY_NETWORK,
severity: SEVERITY_LOG,
}],
});
output.focus();
message = [...result.matched][0];
hud.ui.output.selectMessage(message);
goUpdateCommand(COMMAND_NAME);
ok(isEnabled(), COMMAND_NAME + " is enabled");
info("expected clipboard value: " + message.url);
let deferred = defer();
waitForClipboard((aData) => {
return aData.trim() == message.url;
}, () => {
goDoCommand(COMMAND_NAME);
}, () => {
deferred.resolve(null);
}, () => {
deferred.reject(null);
});
yield deferred.promise;
// Test that the "Copy Link Location" menu item is visible for network-related
// messages.
yield waitForContextMenu(menu, message, () => {
let isVisible = !menu.querySelector(CONTEXT_MENU_ID).hidden;
ok(isVisible, CONTEXT_MENU_ID + " is visible");
});
// Return whether "Copy Link Location" command is enabled or not.
function isEnabled() {
let controller = top.document.commandDispatcher
.getControllerForCommand(COMMAND_NAME);
return controller && controller.isCommandEnabled(COMMAND_NAME);
}
});

View File

@ -2467,7 +2467,6 @@ BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun *aTextRun)
gfxSkipChars skipChars;
AutoTArray<int32_t,50> textBreakPoints;
TextRunUserData dummyData;
TextRunMappedFlow dummyMappedFlow;
TextRunMappedFlow* userMappedFlows;
@ -2488,9 +2487,6 @@ BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun *aTextRun)
userDataToDestroy = userData;
}
uint32_t nextBreakIndex = 0;
nsTextFrame* nextBreakBeforeFrame = GetNextBreakBeforeFrame(&nextBreakIndex);
const nsStyleText* textStyle = nullptr;
for (uint32_t i = 0; i < mMappedFlows.Length(); ++i) {
MappedFlow* mappedFlow = &mMappedFlows[i];
@ -2513,12 +2509,6 @@ BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun *aTextRun)
mappedFlow->mStartFrame->GetContentOffset();
newFlow->mContentLength = contentLength;
while (nextBreakBeforeFrame && nextBreakBeforeFrame->GetContent() == content) {
textBreakPoints.AppendElement(
nextBreakBeforeFrame->GetContentOffset() + newFlow->mDOMOffsetToBeforeTransformOffset);
nextBreakBeforeFrame = GetNextBreakBeforeFrame(&nextBreakIndex);
}
nsTextFrameUtils::Flags analysisFlags;
if (frag->Is2b()) {
NS_ASSERTION(mDoubleByteText, "Wrong buffer char size!");

View File

@ -59,22 +59,16 @@ MOZ_MEMORY_API char *strndup_impl(const char *, size_t);
#include <sys/types.h>
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Likely.h"
#include "mozilla/mozalloc.h"
#include "mozilla/mozalloc_oom.h" // for mozalloc_handle_oom
#ifdef __GNUC__
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#define UNLIKELY(x) (__builtin_expect(!!(x), 0))
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
void*
moz_xmalloc(size_t size)
{
void* ptr = malloc_impl(size);
if (UNLIKELY(!ptr && size)) {
if (MOZ_UNLIKELY(!ptr && size)) {
mozalloc_handle_oom(size);
return moz_xmalloc(size);
}
@ -85,8 +79,9 @@ void*
moz_xcalloc(size_t nmemb, size_t size)
{
void* ptr = calloc_impl(nmemb, size);
if (UNLIKELY(!ptr && nmemb && size)) {
mozalloc_handle_oom(size);
if (MOZ_UNLIKELY(!ptr && nmemb && size)) {
mozilla::CheckedInt<size_t> totalSize = mozilla::CheckedInt<size_t>(nmemb) * size;
mozalloc_handle_oom(totalSize.isValid() ? totalSize.value() : SIZE_MAX);
return moz_xcalloc(nmemb, size);
}
return ptr;
@ -96,7 +91,7 @@ void*
moz_xrealloc(void* ptr, size_t size)
{
void* newptr = realloc_impl(ptr, size);
if (UNLIKELY(!newptr && size)) {
if (MOZ_UNLIKELY(!newptr && size)) {
mozalloc_handle_oom(size);
return moz_xrealloc(ptr, size);
}
@ -107,7 +102,7 @@ char*
moz_xstrdup(const char* str)
{
char* dup = strdup_impl(str);
if (UNLIKELY(!dup)) {
if (MOZ_UNLIKELY(!dup)) {
mozalloc_handle_oom(0);
return moz_xstrdup(str);
}
@ -119,7 +114,7 @@ char*
moz_xstrndup(const char* str, size_t strsize)
{
char* dup = strndup_impl(str, strsize);
if (UNLIKELY(!dup)) {
if (MOZ_UNLIKELY(!dup)) {
mozalloc_handle_oom(strsize);
return moz_xstrndup(str, strsize);
}
@ -137,7 +132,7 @@ void*
moz_xmemalign(size_t boundary, size_t size)
{
void* ptr = memalign_impl(boundary, size);
if (UNLIKELY(!ptr && EINVAL != errno)) {
if (MOZ_UNLIKELY(!ptr && EINVAL != errno)) {
mozalloc_handle_oom(size);
return moz_xmemalign(boundary, size);
}

View File

@ -33,14 +33,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#if defined(MOZ_ALWAYS_INLINE_EVEN_DEBUG)
# define MOZALLOC_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG
#elif defined(HAVE_FORCEINLINE)
# define MOZALLOC_INLINE __forceinline
#else
# define MOZALLOC_INLINE inline
#endif
MOZ_BEGIN_EXTERN_C
/*
@ -133,16 +125,7 @@ MOZ_END_EXTERN_C
# define MOZALLOC_EXPORT_NEW
#endif
#if defined(ANDROID)
/*
* It's important to always specify 'throw()' in GCC because it's used to tell
* GCC that 'new' may return null. That makes GCC null-check the result before
* potentially initializing the memory to zero.
* Also, the Android minimalistic headers don't include std::bad_alloc.
*/
#define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw()
#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
#elif defined(_MSC_VER)
#if defined(_MSC_VER)
/*
* Suppress build warning spam (bug 578546).
*/
@ -166,50 +149,50 @@ MOZALLOC_EXPORT_NEW
/* gcc's asan somehow doesn't like always_inline on this function. */
__attribute__((gnu_inline)) inline
#else
MOZALLOC_INLINE
MOZ_ALWAYS_INLINE_EVEN_DEBUG
#endif
void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC
{
return moz_xmalloc(size);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void* operator new(size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return malloc_impl(size);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void* operator new[](size_t size) MOZALLOC_THROW_BAD_ALLOC
{
return moz_xmalloc(size);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void* operator new[](size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return malloc_impl(size);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete(void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return free_impl(ptr);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete(void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return free_impl(ptr);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete[](void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return free_impl(ptr);
}
MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return free_impl(ptr);
@ -235,25 +218,25 @@ void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_E
* (4) the matching system |operator delete(void*) throw(std::bad_alloc)|
*/
MOZALLOC_INLINE
MOZ_ALWAYS_INLINE_EVEN_DEBUG
void* operator new(size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return malloc_impl(size);
}
MOZALLOC_INLINE
MOZ_ALWAYS_INLINE_EVEN_DEBUG
void* operator new[](size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
return malloc_impl(size);
}
MOZALLOC_INLINE
MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete(void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
free_impl(ptr);
}
MOZALLOC_INLINE
MOZ_ALWAYS_INLINE_EVEN_DEBUG
void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
{
free_impl(ptr);

View File

@ -50,6 +50,7 @@ public final class HardwareCodecCapabilityUtils {
"SGH-I337", // S4
"SPH-L720", // S4 (Sprint)
"SAMSUNG-SGH-I337", // S4
"GT-I9195", // S4 Mini
"300E5EV/300E4EV/270E5EV/270E4EV/2470EV/2470EE",
"LG-D605" // LG Optimus L9 II
};

View File

@ -4537,13 +4537,13 @@ MOZ_ARG_WITH_STRING(macbundlename-prefix,
Prefix for MOZ_MACBUNDLE_NAME],
[ MOZ_MACBUNDLE_NAME_PREFIX="$withval"])
MOZ_MACBUNDLE_NAME=`echo $MOZ_APP_DISPLAYNAME | tr -d ' '`
MOZ_MACBUNDLE_NAME=$MOZ_APP_DISPLAYNAME
if test "$MOZ_MACBUNDLE_NAME_PREFIX"; then
MOZ_MACBUNDLE_NAME="${MOZ_MACBUNDLE_NAME_PREFIX}${MOZ_MACBUNDLE_NAME}"
MOZ_MACBUNDLE_NAME="${MOZ_MACBUNDLE_NAME_PREFIX} ${MOZ_MACBUNDLE_NAME}"
fi
if test "$MOZ_DEBUG"; then
MOZ_MACBUNDLE_NAME=${MOZ_MACBUNDLE_NAME}Debug.app
MOZ_MACBUNDLE_NAME="${MOZ_MACBUNDLE_NAME} Debug.app"
else
MOZ_MACBUNDLE_NAME=${MOZ_MACBUNDLE_NAME}.app
fi

View File

@ -7,40 +7,60 @@ CertPassPrompt=Please enter the master password for the %S.
CertPassPromptDefault=Please enter your master password.
# the following strings have special requirements:
# they must fit in a 32 or 64 byte buffer after being translated
# to UTF8. Note to translator. It's not easy for you to figure
# whether the escaped unicode string you produce will fit in
# the space allocated.
# The following strings have special requirements: they must fit in a 32 or 64
# bytes buffer after being encoded to UTF-8.
#
# 64 bytes long after conversion to UTF8
# It's possible to verify the length of a translation using the Browser Console
# in Firefox and evaluating the following code:
#
# (new TextEncoder('utf-8').encode('YOURSTRING')).length
#
# Simply replace YOURSTRING with your translation.
#
# If it's not possible to produce an understandable translation withing these
# limits, keeping the English text is an acceptable workaround.
# LOCALIZATION NOTE (RootCertModuleName): string limit is 64 bytes after
# conversion to UTF-8.
# length_limit = 64 bytes
RootCertModuleName=Builtin Roots Module
#
# 32 bytes long after conversion to UTF8
# LOCALIZATION NOTE (ManufacturerID): string limit is 32 bytes after conversion
# to UTF-8.
# length_limit = 32 bytes
ManufacturerID=Mozilla.org
#
# 32 bytes long after conversion to UTF8
# LOCALIZATION NOTE (LibraryDescription): string limit is 32 bytes after
# conversion to UTF-8.
# length_limit = 32 bytes
LibraryDescription=PSM Internal Crypto Services
#
# 32 bytes long after conversion to UTF8
# LOCALIZATION NOTE (TokenDescription): string limit is 32 bytes after
# conversion to UTF-8.
# length_limit = 32 bytes
TokenDescription=Generic Crypto Services
#
# 32 bytes long after conversion to UTF8
# LOCALIZATION NOTE (PrivateTokenDescription): string limit is 32 bytes after
# conversion to UTF-8.
# length_limit = 32 bytes
PrivateTokenDescription=Software Security Device
#
# 64 bytes long after conversion to UTF8
# LOCALIZATION NOTE (SlotDescription): string limit is 64 bytes after conversion
# to UTF-8.
# length_limit = 64 bytes
SlotDescription=PSM Internal Cryptographic Services
#
# 64 bytes long after conversion to UTF8
# LOCALIZATION NOTE (PrivateSlotDescription): string limit is 64 bytes after
# conversion to UTF-8.
# length_limit = 64 bytes
PrivateSlotDescription=PSM Private Keys
#
# 32
# LOCALIZATION NOTE (Fips140TokenDescription): string limit is 32 bytes after
# conversion to UTF-8.
# length_limit = 32 bytes
Fips140TokenDescription=Software Security Device (FIPS)
# 64
# LOCALIZATION NOTE (Fips140SlotDescription): string limit is 64 bytes after
# conversion to UTF-8.
# length_limit = 64 bytes
Fips140SlotDescription=FIPS 140 Cryptographic, Key and Certificate Services
# 32
# LOCALIZATION NOTE (InternalToken): string limit is 32 bytes after conversion
# to UTF-8.
# length_limit = 32 bytes
InternalToken=Software Security Device
# End of size restriction.
VerifySSLClient=SSL Client Certificate
VerifySSLServer=SSL Server Certificate
VerifySSLCA=SSL Certificate Authority

View File

@ -29,12 +29,14 @@ trait Recover<Q: ?Sized> {
#[derive(Debug)]
pub struct FailedAllocationError {
reason: &'static str,
/// The size we are allocating, if needed.
allocation_size: Option<usize>,
}
impl FailedAllocationError {
#[inline]
pub fn new(reason: &'static str) -> Self {
Self { reason }
Self { reason, allocation_size: None }
}
}
@ -46,6 +48,9 @@ impl error::Error for FailedAllocationError {
impl fmt::Display for FailedAllocationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.reason.fmt(f)
match self.allocation_size {
Some(size) => write!(f, "{}, allocation size: {}", self.reason, size),
None => self.reason.fmt(f),
}
}
}

View File

@ -757,7 +757,7 @@ impl<K, V> RawTable<K, V> {
align_of::<(K, V)>());
if oflo {
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
return Err(FailedAllocationError::new("capacity overflow when allocating RawTable" ));
}
// One check for overflow that covers calculation and rounding of size.
@ -767,21 +767,21 @@ impl<K, V> RawTable<K, V> {
if let Some(cap_bytes) = cap_bytes {
if size < cap_bytes {
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
return Err(FailedAllocationError::new("capacity overflow when allocating RawTable"));
}
} else {
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
return Err(FailedAllocationError::new("capacity overflow when allocating RawTable"));
}
// FORK NOTE: Uses alloc shim instead of Heap.alloc
let buffer = alloc(size, alignment);
if buffer.is_null() {
return Err(FailedAllocationError { reason: "out of memory when allocating RawTable" });
return Err(FailedAllocationError {
reason: "out of memory when allocating RawTable",
allocation_size: Some(size),
});
}
let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;

View File

@ -150,11 +150,6 @@ this.GeckoDriver = function(appId, server) {
this.sandboxes = new Sandboxes(() => this.getCurrentWindow());
this.legacyactions = new legacyaction.Chain();
this.timer = null;
this.inactivityTimer = null;
this.testName = null;
this.capabilities = new session.Capabilities();
this.mm = globalMessageManager;
@ -298,24 +293,6 @@ GeckoDriver.prototype.globalModalDialogHandler = function(subject, topic) {
this.dialog = new modal.Dialog(() => this.curBrowser, winr);
};
/**
* Switches to the global ChromeMessageBroadcaster, potentially replacing
* a frame-specific ChromeMessageSender. Has no effect if the global
* ChromeMessageBroadcaster is already in use. If this replaces a
* frame-specific ChromeMessageSender, it removes the message listeners
* from that sender, and then puts the corresponding frame script "to
* sleep", which removes most of the message listeners from it as well.
*/
GeckoDriver.prototype.switchToGlobalMessageManager = function() {
if (this.curBrowser &&
this.curBrowser.frameManager.currentRemoteFrame !== null) {
this.curBrowser.frameManager.removeMessageManagerListeners(this.mm);
this.sendAsync("sleepSession");
this.curBrowser.frameManager.currentRemoteFrame = null;
}
this.mm = globalMessageManager;
};
/**
* Helper method to send async messages to the content listener.
* Correct usage is to pass in the name of a function in listener.js,
@ -433,7 +410,6 @@ GeckoDriver.prototype.addFrameCloseListener = function(action) {
this.mozBrowserClose = e => {
if (e.target.id == this.oopFrameId) {
win.removeEventListener("mozbrowserclose", this.mozBrowserClose, true);
this.switchToGlobalMessageManager();
throw new NoSuchWindowError("The window closed during action: " + action);
}
};
@ -815,11 +791,9 @@ GeckoDriver.prototype.newSession = async function(cmd) {
let win = this.getCurrentWindow();
this.addBrowser(win);
this.whenBrowserStarted(win, false);
this.mm.broadcastAsyncMessage("Marionette:restart", {});
} else {
throw new WebDriverError("Session already running");
}
this.switchToGlobalMessageManager();
await registerBrowsers;
await browserListening;
@ -1886,15 +1860,6 @@ GeckoDriver.prototype.switchToFrame = async function(cmd) {
}
} else if (this.context == Context.Content) {
if (!id && !byFrame &&
this.curBrowser.frameManager.currentRemoteFrame !== null) {
// We're currently using a ChromeMessageSender for a remote frame,
// so this request indicates we need to switch back to the top-level
// (parent) frame. We'll first switch to the parent's (global)
// ChromeMessageBroadcaster, so we send the message to the right
// listener.
this.switchToGlobalMessageManager();
}
cmd.commandID = cmd.id;
let res = await this.listener.switchToFrame(cmd.parameters);
@ -2829,10 +2794,6 @@ GeckoDriver.prototype.close = async function() {
return [];
}
if (this.mm != globalMessageManager) {
this.mm.removeDelayedFrameScript(FRAME_SCRIPT);
}
await this.curBrowser.closeTab();
return this.windowHandles.map(String);
};
@ -2868,10 +2829,6 @@ GeckoDriver.prototype.closeChromeWindow = async function() {
// reset frame to the top-most frame
this.curFrame = null;
if (this.mm != globalMessageManager) {
this.mm.removeDelayedFrameScript(FRAME_SCRIPT);
}
await this.curBrowser.closeWindow();
return this.chromeWindowHandles.map(String);
};
@ -2904,8 +2861,6 @@ GeckoDriver.prototype.deleteSession = function() {
globalMessageManager);
}
this.switchToGlobalMessageManager();
// reset frame to the top-most frame
this.curFrame = null;
if (this.mainFrame) {

View File

@ -164,7 +164,6 @@ frame.Manager = class {
this.currentRemoteFrame = f;
this.addMessageManagerListeners(mm);
mm.sendAsyncMessage("Marionette:restart");
return oopFrame.id;
}
}

View File

@ -2,36 +2,42 @@
# 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/.
import urllib
from marionette_driver.by import By
from marionette_driver.errors import MoveTargetOutOfBoundsException
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
from marionette_harness import MarionetteTestCase, skip_if_mobile
def inline(doc):
return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
class TestClickScrolling(MarionetteTestCase):
def test_clicking_on_anchor_scrolls_page(self):
scrollScript = """
var pageY;
if (typeof(window.pageYOffset) == 'number') {
pageY = window.pageYOffset;
} else {
pageY = document.documentElement.scrollTop;
}
return pageY;"""
test_html = self.marionette.absolute_url("macbeth.html")
self.marionette.navigate(test_html)
self.marionette.find_element(By.PARTIAL_LINK_TEXT, "last speech").click()
y_offset = self.marionette.execute_script(scrollScript)
self.marionette.navigate(inline("""
<a href="#content">Link to content</a>
<div id="content" style="margin-top: 205vh;">Text</div>
"""))
# Focusing on to click, but not actually following,
# the link will scroll it in to view, which is a few
# pixels further than 0
self.marionette.find_element(By.CSS_SELECTOR, "a").click()
self.assertTrue(y_offset > 300)
y_offset = self.marionette.execute_script("""
var pageY;
if (typeof(window.pageYOffset) == 'number') {
pageY = window.pageYOffset;
} else {
pageY = document.documentElement.scrollTop;
}
return pageY;
""")
self.assertGreater(y_offset, 300)
def test_should_scroll_to_click_on_an_element_hidden_by_overflow(self):
test_html = self.marionette.absolute_url("click_out_of_bounds_overflow.html")
@ -43,45 +49,6 @@ class TestClickScrolling(MarionetteTestCase):
except MoveTargetOutOfBoundsException:
self.fail("Should not be out of bounds")
@skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll")
def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self):
test_html = self.marionette.absolute_url("scroll.html")
self.marionette.navigate(test_html)
link = self.marionette.find_element(By.ID, "line8")
link.click()
self.assertEqual("line8", self.marionette.find_element(By.ID, "clicked").text)
def test_should_not_scroll_overflow_elements_which_are_visible(self):
test_html = self.marionette.absolute_url("scroll2.html")
self.marionette.navigate(test_html)
list_el = self.marionette.find_element(By.TAG_NAME, "ul")
item = list_el.find_element(By.ID, "desired")
item.click()
y_offset = self.marionette.execute_script("return arguments[0].scrollTop;", script_args=[list_el])
self.assertEqual(0, y_offset)
def test_should_not_scroll_if_already_scrolled_and_element_is_in_view(self):
test_html = self.marionette.absolute_url("scroll3.html")
self.marionette.navigate(test_html)
button1 = self.marionette.find_element(By.ID, "button1")
button2 = self.marionette.find_element(By.ID, "button2")
button2.click()
scroll_top = self.marionette.execute_script("return document.body.scrollTop;")
button1.click()
self.assertEqual(scroll_top, self.marionette.execute_script("return document.body.scrollTop;"))
def test_should_be_able_to_click_radio_button_scrolled_into_view(self):
test_html = self.marionette.absolute_url("scroll4.html")
self.marionette.navigate(test_html)
# If we dont throw we are good
self.marionette.find_element(By.ID, "radio").click()
@skip_if_mobile("Bug 1293855 - Lists differ: [70, 70] != [70, 120]")
def test_should_not_scroll_elements_if_click_point_is_in_view(self):
test_html = self.marionette.absolute_url("element_outside_viewport.html")
@ -91,12 +58,76 @@ class TestClickScrolling(MarionetteTestCase):
self.marionette.navigate(test_html)
scroll = self.marionette.execute_script("return [window.scrollX, window.scrollY];")
self.marionette.find_element(By.ID, "{0}-{1}".format(s, p)).click()
self.assertEqual(scroll, self.marionette.execute_script("return [window.scrollX, window.scrollY];"))
self.assertEqual(scroll, self.marionette.execute_script(
"return [window.scrollX, window.scrollY];"))
@skip("Bug 1003687")
def test_should_scroll_overflow_elements_if_click_point_is_out_of_view_but_element_is_in_view(self):
test_html = self.marionette.absolute_url("scroll5.html")
self.marionette.navigate(test_html)
def test_do_not_scroll_again_if_element_is_already_in_view(self):
self.marionette.navigate(inline("""
<div style="height: 200vh;">
<button id="button1" style="margin-top: 105vh">Button1</button>
<button id="button2" style="position: relative; top: 5em">Button2</button>
</div>
"""))
button1 = self.marionette.find_element(By.ID, "button1")
button2 = self.marionette.find_element(By.ID, "button2")
button2.click()
scroll_top = self.marionette.execute_script("return document.body.scrollTop;")
button1.click()
self.assertEqual(scroll_top, self.marionette.execute_script(
"return document.body.scrollTop;"))
def test_scroll_radio_button_into_view(self):
self.marionette.navigate(inline("""
<input type="radio" id="radio" style="margin-top: 105vh;">
"""))
self.marionette.find_element(By.ID, "radio").click()
def test_overflow_scroll_do_not_scroll_elements_which_are_visible(self):
self.marionette.navigate(inline("""
<ul style='overflow: scroll; height: 8em; line-height: 3em'>
<li></li>
<li id="desired">Text</li>
<li></li>
<li></li>
</ul>
"""))
list_el = self.marionette.find_element(By.TAG_NAME, "ul")
expected_y_offset = self.marionette.execute_script(
"return arguments[0].scrollTop;", script_args=(list_el,))
item = list_el.find_element(By.ID, "desired")
item.click()
y_offset = self.marionette.execute_script("return arguments[0].scrollTop;",
script_args=(list_el,))
self.assertEqual(expected_y_offset, y_offset)
def test_overflow_scroll_click_on_hidden_element(self):
self.marionette.navigate(inline("""
Result: <span id="result"></span>
<ul style='overflow: scroll; width: 150px; height: 8em; line-height: 4em'
onclick="document.getElementById('result').innerText = event.target.id;">
<li>line1</li>
<li>line2</li>
<li>line3</li>
<li id="line4">line4</li>
</ul>
"""))
self.marionette.find_element(By.ID, "line4").click()
self.assertEqual("line4", self.marionette.find_element(By.ID, "result").text)
def test_overflow_scroll_vertically_for_click_point_outside_of_viewport(self):
self.marionette.navigate(inline("""
Result: <span id="result"></span>
<div style='overflow: scroll; width: 100px; height: 100px; background-color: yellow;'>
<div id="inner" style="width: 100px; height: 300px; background-color: green;"
onclick="document.getElementById('result').innerText = event.type" ></div>
</div>
"""))
self.marionette.find_element(By.ID, "inner").click()
self.assertEqual("clicked", self.marionette.find_element(By.ID, "clicked").text)
self.assertEqual("click", self.marionette.find_element(By.ID, "result").text)

View File

@ -26,13 +26,8 @@ class MockMozCrash(object):
with self.marionette.using_context('chrome'):
self.crash_reporter_enabled = self.marionette.execute_script("""
try {
Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
getService(Components.interfaces.nsICrashReporter);
return true;
} catch (exc) {
return false;
}
Cu.import("resource://gre/modules/AppConstants.jsm");
return AppConstants.MOZ_CRASHREPORTER;
""")
def check_for_crashes(self, dump_directory, *args, **kwargs):

View File

@ -755,6 +755,7 @@ class TestPageLoadStrategy(BaseNavigationTestCase):
self.assertEqual("complete", self.ready_state)
self.marionette.find_element(By.ID, "slow")
@skip("Bug 1422741 - Causes following tests to fail in loading remote browser")
@run_if_e10s("Requires e10s mode enabled")
def test_strategy_after_remoteness_change(self):
"""Bug 1378191 - Reset of capabilities after listener reload"""

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
<!-- 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/. -->
<html>
<head></head>
<body>
<script>
function dump(event) {
var elt = event.target || event.srcElement;
document.getElementById('clicked').innerHTML = elt.innerHTML;
}
</script>
<div style='height: 150px'></div>
<ul style='overflow: scroll; width: 150px; height: 80px; background-color: yellow' onclick="dump(event)">
<li id='line1'>line1</li>
<li id='line2'>line2</li>
<li id='line3'>line3</li>
<li id='line4'>line4</li>
<li id='line5'>line5</li>
<li id='line6'>line6</li>
<li id='line7'>line7</li>
<li id='line8'>line8</li>
<li id='line9'>line9</li>
</ul>
<div>
Clicked: <span id='clicked'></span>
</div>
</body>
</html>

View File

@ -1,24 +0,0 @@
<!-- 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/. -->
<html>
<head></head>
<body>
<ul style='overflow: scroll; height: 100px;'>
<li></li>
<li></li>
<li id="desired">Text</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>

View File

@ -1,18 +0,0 @@
<!-- 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/. -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<style type="text/css"></style>
</head>
<body>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="button1">Button1</button>
<br><br><br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button2">Button2</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>

View File

@ -1,15 +0,0 @@
<!-- 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/. -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<style type="text/css"></style>
</head>
<body>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<input type="radio" id="radio">
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>

View File

@ -1,20 +0,0 @@
<!-- 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/. -->
<html>
<head></head>
<body>
<script>
function dump(text) {
document.getElementById('clicked').innerHTML = text;
}
</script>
<div style='overflow: scroll; width: 150px; height: 200px; background-color: yellow' id="outer">
<div style="width: 150px; height: 5000px; background-color: red;" onclick="dump('clicked')" id="inner"></div>
</div>
<div>
Clicked: <span id='clicked'></span>
</div>
</body>
</html>

View File

@ -574,7 +574,6 @@ function startListeners() {
addMessageListenerId("Marionette:switchToParentFrame", switchToParentFrame);
addMessageListenerId("Marionette:switchToShadowRoot", switchToShadowRootFn);
addMessageListenerId("Marionette:deleteSession", deleteSession);
addMessageListenerId("Marionette:sleepSession", sleepSession);
addMessageListenerId("Marionette:takeScreenshot", takeScreenshotFn);
addMessageListenerId("Marionette:reftestWait", reftestWaitFn);
addMessageListener("Marionette:DOM:AddEventListener", domAddEventListener);
@ -590,23 +589,6 @@ function newSession(msg) {
resetValues();
}
/**
* Puts the current session to sleep, so all listeners are removed except
* for the 'restart' listener.
*/
function sleepSession() {
deleteSession();
addMessageListener("Marionette:restart", restart);
}
/**
* Restarts all our listeners after this listener was put to sleep
*/
function restart() {
removeMessageListener("Marionette:restart", restart);
registerSelf();
}
/**
* Removes all listeners
*/
@ -658,7 +640,6 @@ function deleteSession() {
removeMessageListenerId(
"Marionette:switchToShadowRoot", switchToShadowRootFn);
removeMessageListenerId("Marionette:deleteSession", deleteSession);
removeMessageListenerId("Marionette:sleepSession", sleepSession);
removeMessageListenerId("Marionette:takeScreenshot", takeScreenshotFn);
seenEls.clear();

View File

@ -273,6 +273,16 @@ config = {
'halt_on_failure': True,
'enabled': ADJUST_MOUSE_AND_SCREEN
},
{
'name': 'disable windows security and maintenance notifications',
'cmd': [
'powershell', '-command',
'"&{$p=\'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.SecurityAndMaintenance\';if(!(Test-Path -Path $p)){&New-Item -Path $p -Force}&Set-ItemProperty -Path $p -Name Enabled -Value 0}"'
],
'architectures': ['32bit', '64bit'],
'halt_on_failure': True,
'enabled': (platform.release() == 10)
},
{
'name': 'set windows VisualFX',
'cmd': [

View File

@ -113,21 +113,21 @@ MOZDEPTH ?= $(DEPTH)
repackage-zip: UNPACKAGE='$(ZIP_IN)'
repackage-zip:
$(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/l10n-repack.py $(STAGEDIST) $(DIST)/xpi-stage/locale-$(AB_CD) \
$(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/l10n-repack.py '$(STAGEDIST)' $(DIST)/xpi-stage/locale-$(AB_CD) \
$(MOZ_PKG_EXTRAL10N) \
$(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES)))
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
ifneq (en,$(LPROJ_ROOT))
mv $(STAGEDIST)/en.lproj $(STAGEDIST)/$(LPROJ_ROOT).lproj
mv '$(STAGEDIST)'/en.lproj '$(STAGEDIST)'/$(LPROJ_ROOT).lproj
endif
ifdef MOZ_CRASHREPORTER
# On Mac OS X, the crashreporter.ini file needs to be moved from under the
# application bundle's Resources directory where all other l10n files are
# located to the crash reporter bundle's Resources directory.
mv $(STAGEDIST)/crashreporter.app/Contents/Resources/crashreporter.ini \
$(STAGEDIST)/../MacOS/crashreporter.app/Contents/Resources/crashreporter.ini
$(RM) -rf $(STAGEDIST)/crashreporter.app
mv '$(STAGEDIST)'/crashreporter.app/Contents/Resources/crashreporter.ini \
'$(STAGEDIST)'/../MacOS/crashreporter.app/Contents/Resources/crashreporter.ini
$(RM) -rf '$(STAGEDIST)'/crashreporter.app
endif
endif
@ -141,7 +141,7 @@ endif
# packaging done, undo l10n stuff
ifneq (en,$(LPROJ_ROOT))
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
mv $(STAGEDIST)/$(LPROJ_ROOT).lproj $(STAGEDIST)/en.lproj
mv '$(STAGEDIST)'/$(LPROJ_ROOT).lproj '$(STAGEDIST)'/en.lproj
endif
endif
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
@ -247,7 +247,7 @@ endif
generate-snippet-%:
$(PYTHON) $(MOZILLA_DIR)/tools/update-packaging/generatesnippet.py \
--mar-path=$(ABS_DIST)/update \
--application-ini-file=$(STAGEDIST)/application.ini \
--application-ini-file='$(STAGEDIST)'/application.ini \
--locale=$* \
--product=$(MOZ_PKG_APPNAME) \
--platform=$(MOZ_PKG_PLATFORM) \

View File

@ -46,7 +46,7 @@ stage-package: multilocale.json locale-manifest.in $(MOZ_PKG_MANIFEST) $(MOZ_PKG
$(if $(JARLOG_DIR),$(addprefix --jarlog ,$(wildcard $(JARLOG_FILE_AB_CD)))) \
$(if $(OPTIMIZEJARS),--optimizejars) \
$(addprefix --compress ,$(JAR_COMPRESSION)) \
$(MOZ_PKG_MANIFEST) $(DIST) $(DIST)/$(MOZ_PKG_DIR)$(if $(MOZ_PKG_MANIFEST),,$(_BINPATH)) \
$(MOZ_PKG_MANIFEST) '$(DIST)' '$(DIST)'/$(MOZ_PKG_DIR)$(if $(MOZ_PKG_MANIFEST),,$(_BINPATH)) \
$(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES)))
$(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/find-dupes.py $(DEFINES) $(ACDEFINES) $(MOZ_PKG_DUPEFLAGS) $(DIST)/$(MOZ_PKG_DIR)
ifndef MOZ_IS_COMM_TOPDIR

View File

@ -83,15 +83,15 @@ make_add_instruction() {
# before performing this add instruction.
testdir=$(echo "$f" | sed 's/\(.*distribution\/extensions\/[^\/]*\)\/.*/\1/')
notice " add-if \"$testdir\" \"$f\""
echo "add-if \"$testdir\" \"$f\"" >> $filev2
echo "add-if \"$testdir\" \"$f\"" >> "$filev2"
if [ ! $filev3 = "" ]; then
echo "add-if \"$testdir\" \"$f\"" >> $filev3
echo "add-if \"$testdir\" \"$f\"" >> "$filev3"
fi
else
notice " add \"$f\"$forced"
echo "add \"$f\"" >> $filev2
echo "add \"$f\"" >> "$filev2"
if [ ! $filev3 = "" ]; then
echo "add \"$f\"" >> $filev3
echo "add \"$f\"" >> "$filev3"
fi
fi
}
@ -138,12 +138,12 @@ make_patch_instruction() {
# before performing this add instruction.
testdir=$(echo "$f" | sed 's/\(.*distribution\/extensions\/[^\/]*\)\/.*/\1/')
notice " patch-if \"$testdir\" \"$f.patch\" \"$f\""
echo "patch-if \"$testdir\" \"$f.patch\" \"$f\"" >> $filev2
echo "patch-if \"$testdir\" \"$f.patch\" \"$f\"" >> $filev3
echo "patch-if \"$testdir\" \"$f.patch\" \"$f\"" >> "$filev2"
echo "patch-if \"$testdir\" \"$f.patch\" \"$f\"" >> "$filev3"
else
notice " patch \"$f.patch\" \"$f\""
echo "patch \"$f.patch\" \"$f\"" >> $filev2
echo "patch \"$f.patch\" \"$f\"" >> $filev3
echo "patch \"$f.patch\" \"$f\"" >> "$filev2"
echo "patch \"$f.patch\" \"$f\"" >> "$filev3"
fi
}
@ -172,18 +172,18 @@ append_remove_instructions() {
if [ ! $(echo "$f" | grep -c '^#') = 1 ]; then
if [ $(echo "$f" | grep -c '\/$') = 1 ]; then
notice " rmdir \"$f\""
echo "rmdir \"$f\"" >> $filev2
echo "rmdir \"$f\"" >> $filev3
echo "rmdir \"$f\"" >> "$filev2"
echo "rmdir \"$f\"" >> "$filev3"
elif [ $(echo "$f" | grep -c '\/\*$') = 1 ]; then
# Remove the *
f=$(echo "$f" | sed -e 's:\*$::')
notice " rmrfdir \"$f\""
echo "rmrfdir \"$f\"" >> $filev2
echo "rmrfdir \"$f\"" >> $filev3
echo "rmrfdir \"$f\"" >> "$filev2"
echo "rmrfdir \"$f\"" >> "$filev3"
else
notice " remove \"$f\""
echo "remove \"$f\"" >> $filev2
echo "remove \"$f\"" >> $filev3
echo "remove \"$f\"" >> "$filev2"
echo "remove \"$f\"" >> "$filev3"
fi
fi
fi

View File

@ -67,13 +67,13 @@ list_files files
popd
# Add the type of update to the beginning of the update manifests.
> $updatemanifestv2
> $updatemanifestv3
> "$updatemanifestv2"
> "$updatemanifestv3"
notice ""
notice "Adding type instruction to update manifests"
notice " type complete"
echo "type \"complete\"" >> $updatemanifestv2
echo "type \"complete\"" >> $updatemanifestv3
echo "type \"complete\"" >> "$updatemanifestv2"
echo "type \"complete\"" >> "$updatemanifestv3"
notice ""
notice "Adding file add instructions to update manifests"

View File

@ -438,6 +438,8 @@ STUB(gtk_widget_get_has_window)
STUB(gtk_widget_get_mapped)
STUB(gtk_widget_get_parent)
STUB(gtk_widget_get_parent_window)
STUB(gtk_widget_get_preferred_width)
STUB(gtk_widget_get_preferred_height)
STUB(gtk_widget_get_realized)
STUB(gtk_widget_get_screen)
STUB(gtk_widget_get_settings)
@ -479,6 +481,7 @@ STUB(gtk_widget_show_all)
STUB(gtk_widget_size_allocate)
STUB(gtk_widget_style_get)
STUB(gtk_widget_unparent)
STUB(gtk_widget_unrealize)
STUB(gtk_window_deiconify)
STUB(gtk_window_fullscreen)
STUB(gtk_window_get_group)

View File

@ -3790,12 +3790,13 @@ nsWindow::Create(nsIWidget* aParent,
* 1) We're running on Gtk+ without client side decorations.
* Content is rendered to mShell window and we listen
* to the Gtk+ events on mShell
* 2) We're running on Gtk+ > 3.20 and client side decorations
* 2) We're running on Gtk+ and client side decorations
* are drawn by Gtk+ to mShell. Content is rendered to mContainer
* and we listen to the Gtk+ events on mContainer.
*/
GtkStyleContext* style = gtk_widget_get_style_context(mShell);
drawToContainer = gtk_style_context_has_class(style, "csd");
drawToContainer = mIsCSDAvailable ||
gtk_style_context_has_class(style, "csd");
#endif
eventWidget = (drawToContainer) ? container : mShell;
@ -5077,7 +5078,7 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)
}
void
nsWindow::HideWindowChrome(bool aShouldHide)
nsWindow::SetWindowDecoration(nsBorderStyle aStyle)
{
if (!mShell) {
// Pass the request to the toplevel window
@ -5089,7 +5090,7 @@ nsWindow::HideWindowChrome(bool aShouldHide)
if (!topWindow)
return;
topWindow->HideWindowChrome(aShouldHide);
topWindow->SetWindowDecoration(aStyle);
return;
}
@ -5102,12 +5103,7 @@ nsWindow::HideWindowChrome(bool aShouldHide)
wasVisible = true;
}
gint wmd;
if (aShouldHide)
wmd = 0;
else
wmd = ConvertBorderStyles(mBorderStyle);
gint wmd = ConvertBorderStyles(aStyle);
if (wmd != -1)
gdk_window_set_decorations(mGdkWindow, (GdkWMDecoration) wmd);
@ -5126,6 +5122,12 @@ nsWindow::HideWindowChrome(bool aShouldHide)
#endif /* MOZ_X11 */
}
void
nsWindow::HideWindowChrome(bool aShouldHide)
{
SetWindowDecoration(aShouldHide ? eBorderStyle_none : mBorderStyle);
}
bool
nsWindow::CheckForRollup(gdouble aMouseX, gdouble aMouseY,
bool aIsWheel, bool aAlwaysRollup)
@ -6646,14 +6648,66 @@ nsWindow::SetDrawsInTitlebar(bool aState)
return;
if (mShell) {
gint wmd;
if (aState) {
wmd = GetCSDSupportLevel() == CSD_SUPPORT_FULL ? GDK_DECOR_BORDER : 0;
} else {
wmd = ConvertBorderStyles(mBorderStyle);
if (GetCSDSupportLevel() == CSD_SUPPORT_FULL) {
SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle);
}
else {
/* Window manager does not support GDK_DECOR_BORDER,
* emulate it by CSD.
*
* gtk_window_set_titlebar() works on unrealized widgets only,
* we need to handle mShell carefully here.
* When CSD is enabled mGdkWindow is owned by mContainer which is good
* as we can't delete our mGdkWindow. To make mShell unrealized while
* mContainer is preserved we temporary reparent mContainer to an
* invisible GtkWindow.
*/
NativeShow(false);
// Using GTK_WINDOW_POPUP rather than
// GTK_WINDOW_TOPLEVEL in the hope that POPUP results in less
// initialization and window manager interaction.
GtkWidget* tmpWindow = gtk_window_new(GTK_WINDOW_POPUP);
gtk_widget_realize(tmpWindow);
gtk_widget_reparent(GTK_WIDGET(mContainer), tmpWindow);
gtk_widget_unrealize(GTK_WIDGET(mShell));
// Available as of GTK 3.10+
static auto sGtkWindowSetTitlebar = (void (*)(GtkWindow*, GtkWidget*))
dlsym(RTLD_DEFAULT, "gtk_window_set_titlebar");
MOZ_ASSERT(sGtkWindowSetTitlebar,
"Missing gtk_window_set_titlebar(), old Gtk+ library?");
if (aState) {
// Add a hidden titlebar widget to trigger CSD, but disable the default
// titlebar. GtkFixed is a somewhat random choice for a simple unused
// widget. gtk_window_set_titlebar() takes ownership of the titlebar
// widget.
sGtkWindowSetTitlebar(GTK_WINDOW(mShell), gtk_fixed_new());
} else {
sGtkWindowSetTitlebar(GTK_WINDOW(mShell), nullptr);
}
/* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=791081
* gtk_widget_realize() throws:
* "In pixman_region32_init_rect: Invalid rectangle passed"
* when mShell has default 1x1 size.
*/
GtkAllocation allocation = {0, 0, 0, 0};
gtk_widget_get_preferred_width(GTK_WIDGET(mShell), nullptr,
&allocation.width);
gtk_widget_get_preferred_height(GTK_WIDGET(mShell), nullptr,
&allocation.height);
gtk_widget_size_allocate(GTK_WIDGET(mShell), &allocation);
gtk_widget_realize(GTK_WIDGET(mShell));
gtk_widget_reparent(GTK_WIDGET(mContainer), GTK_WIDGET(mShell));
mNeedsShow = true;
NativeResize();
gtk_widget_destroy(tmpWindow);
}
gdk_window_set_decorations(gtk_widget_get_window(mShell),
(GdkWMDecoration) wmd);
}
mIsCSDEnabled = aState;

View File

@ -435,6 +435,7 @@ private:
nsWindow *GetContainerWindow();
void SetUrgencyHint(GtkWidget *top_window, bool state);
void SetDefaultIcon(void);
void SetWindowDecoration(nsBorderStyle aStyle);
void InitButtonEvent(mozilla::WidgetMouseEvent& aEvent,
GdkEventButton* aGdkEvent);
bool DispatchCommandEvent(nsAtom* aCommand);
@ -453,7 +454,6 @@ private:
nsIWidgetListener* GetListener();
bool IsComposited() const;
GtkWidget *mShell;
MozContainer *mContainer;
GdkWindow *mGdkWindow;