зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland
--HG-- extra : rebase_source : dcccfd463c74743c692814695c9a7f0cba61e3ee
This commit is contained in:
Коммит
45b510057b
|
@ -76,6 +76,7 @@ FormAutofillParent.prototype = {
|
||||||
this._profileStore.initialize();
|
this._profileStore.initialize();
|
||||||
|
|
||||||
Services.obs.addObserver(this, "advanced-pane-loaded", false);
|
Services.obs.addObserver(this, "advanced-pane-loaded", false);
|
||||||
|
Services.ppmm.addMessageListener("FormAutofill:SaveProfile", this);
|
||||||
|
|
||||||
// Observing the pref and storage changes
|
// Observing the pref and storage changes
|
||||||
Services.prefs.addObserver(ENABLED_PREF, this, false);
|
Services.prefs.addObserver(ENABLED_PREF, this, false);
|
||||||
|
@ -178,10 +179,19 @@ FormAutofillParent.prototype = {
|
||||||
*/
|
*/
|
||||||
receiveMessage({name, data, target}) {
|
receiveMessage({name, data, target}) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "FormAutofill:GetProfiles":
|
case "FormAutofill:GetProfiles": {
|
||||||
this._getProfiles(data, target);
|
this._getProfiles(data, target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "FormAutofill:SaveProfile": {
|
||||||
|
if (data.guid) {
|
||||||
|
this.getProfileStore().update(data.guid, data.profile);
|
||||||
|
} else {
|
||||||
|
this.getProfileStore().add(data.profile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,6 +217,7 @@ FormAutofillParent.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.ppmm.removeMessageListener("FormAutofill:GetProfiles", this);
|
Services.ppmm.removeMessageListener("FormAutofill:GetProfiles", this);
|
||||||
|
Services.ppmm.removeMessageListener("FormAutofill:SaveProfile", this);
|
||||||
Services.obs.removeObserver(this, "advanced-pane-loaded");
|
Services.obs.removeObserver(this, "advanced-pane-loaded");
|
||||||
Services.prefs.removeObserver(ENABLED_PREF, this);
|
Services.prefs.removeObserver(ENABLED_PREF, this);
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,6 +15,11 @@ const PREF_AUTOFILL_ENABLED = "browser.formautofill.enabled";
|
||||||
const BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
|
const BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
|
||||||
|
|
||||||
|
this.log = null;
|
||||||
|
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
|
||||||
|
|
||||||
function FormAutofillPreferences() {
|
function FormAutofillPreferences() {
|
||||||
this.bundle = Services.strings.createBundle(BUNDLE_URI);
|
this.bundle = Services.strings.createBundle(BUNDLE_URI);
|
||||||
|
@ -46,6 +51,26 @@ FormAutofillPreferences.prototype = {
|
||||||
* @returns {XULElement}
|
* @returns {XULElement}
|
||||||
*/
|
*/
|
||||||
init(document) {
|
init(document) {
|
||||||
|
this.createPreferenceGroup(document);
|
||||||
|
this.attachEventListeners();
|
||||||
|
|
||||||
|
return this.refs.formAutofillGroup;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove event listeners and the preference group.
|
||||||
|
*/
|
||||||
|
uninit() {
|
||||||
|
this.detachEventListeners();
|
||||||
|
this.refs.formAutofillGroup.remove();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Form Autofill preference group
|
||||||
|
*
|
||||||
|
* @param {XULDocument} document
|
||||||
|
*/
|
||||||
|
createPreferenceGroup(document) {
|
||||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||||
|
|
||||||
let formAutofillGroup = document.createElementNS(XUL_NS, "groupbox");
|
let formAutofillGroup = document.createElementNS(XUL_NS, "groupbox");
|
||||||
|
@ -85,18 +110,6 @@ FormAutofillPreferences.prototype = {
|
||||||
hbox.appendChild(enabledCheckbox);
|
hbox.appendChild(enabledCheckbox);
|
||||||
hbox.appendChild(spacer);
|
hbox.appendChild(spacer);
|
||||||
hbox.appendChild(savedProfilesBtn);
|
hbox.appendChild(savedProfilesBtn);
|
||||||
|
|
||||||
this.attachEventListeners();
|
|
||||||
|
|
||||||
return formAutofillGroup;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove event listeners and the preference group.
|
|
||||||
*/
|
|
||||||
uninit() {
|
|
||||||
this.detachEventListeners();
|
|
||||||
this.refs.formAutofillGroup.remove();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,8 +31,8 @@ function insertStyleSheet(domWindow, url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let windowListener = {
|
let windowListener = {
|
||||||
onOpenWindow(aWindow) {
|
onOpenWindow(window) {
|
||||||
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
let domWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||||
|
|
||||||
domWindow.addEventListener("load", function onWindowLoaded() {
|
domWindow.addEventListener("load", function onWindowLoaded() {
|
||||||
insertStyleSheet(domWindow, STYLESHEET_URI);
|
insertStyleSheet(domWindow, STYLESHEET_URI);
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
form,
|
||||||
|
label,
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin: 0 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label > span {
|
||||||
|
flex: 0 0 8em;
|
||||||
|
padding-inline-end: 0.5em;
|
||||||
|
align-self: center;
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
width: 9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
option {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 3px 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#country-container {
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#first-name-container,
|
||||||
|
#middle-name-container,
|
||||||
|
#address-level1-container,
|
||||||
|
#postal-code-container,
|
||||||
|
#country-container {
|
||||||
|
flex: 0 1 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#last-name-container,
|
||||||
|
#organization-container,
|
||||||
|
#street-address-container,
|
||||||
|
#address-level2-container,
|
||||||
|
#email-container,
|
||||||
|
#tel-container,
|
||||||
|
#controls-container {
|
||||||
|
flex: 0 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controls-container {
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#last-name,
|
||||||
|
#organization,
|
||||||
|
#address-level2,
|
||||||
|
#tel{
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: calc(50% - 10em);
|
||||||
|
}
|
||||||
|
|
||||||
|
#street-address,
|
||||||
|
#email {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#first-name-container,
|
||||||
|
#middle-name-container,
|
||||||
|
#last-name-container {
|
||||||
|
/* Hide until we support names */
|
||||||
|
display: none;
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* 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";
|
||||||
|
|
||||||
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
|
||||||
|
|
||||||
|
function EditDialog(profile) {
|
||||||
|
this._profile = profile;
|
||||||
|
window.addEventListener("DOMContentLoaded", this, {once: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
EditDialog.prototype = {
|
||||||
|
init() {
|
||||||
|
this.refs = {
|
||||||
|
controlsContainer: document.getElementById("controls-container"),
|
||||||
|
cancel: document.getElementById("cancel"),
|
||||||
|
save: document.getElementById("save"),
|
||||||
|
};
|
||||||
|
this.attachEventListeners();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks FormAutofillParent to save or update a profile.
|
||||||
|
* @param {object} data
|
||||||
|
* {
|
||||||
|
* {string} guid [optional]
|
||||||
|
* {object} profile
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
saveProfile(data) {
|
||||||
|
Services.cpmm.sendAsyncMessage("FormAutofill:SaveProfile", data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill the form with a profile object.
|
||||||
|
* @param {object} profile
|
||||||
|
*/
|
||||||
|
loadInitialValues(profile) {
|
||||||
|
for (let field in profile) {
|
||||||
|
let input = document.getElementById(field);
|
||||||
|
if (input) {
|
||||||
|
input.value = profile[field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get inputs from the form.
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
buildProfileObject() {
|
||||||
|
return Array.from(document.forms[0].elements).reduce((obj, input) => {
|
||||||
|
if (input.value) {
|
||||||
|
obj[input.id] = input.value;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle events
|
||||||
|
*
|
||||||
|
* @param {DOMEvent} event
|
||||||
|
*/
|
||||||
|
handleEvent(event) {
|
||||||
|
switch (event.type) {
|
||||||
|
case "DOMContentLoaded": {
|
||||||
|
this.init();
|
||||||
|
if (this._profile) {
|
||||||
|
this.loadInitialValues(this._profile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "click": {
|
||||||
|
this.handleClick(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "input": {
|
||||||
|
// Toggle disabled attribute on the save button based on
|
||||||
|
// whether the form is filled or empty.
|
||||||
|
if (Object.keys(this.buildProfileObject()).length == 0) {
|
||||||
|
this.refs.save.setAttribute("disabled", true);
|
||||||
|
} else {
|
||||||
|
this.refs.save.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle click events
|
||||||
|
*
|
||||||
|
* @param {DOMEvent} event
|
||||||
|
*/
|
||||||
|
handleClick(event) {
|
||||||
|
if (event.target == this.refs.cancel) {
|
||||||
|
this.detachEventListeners();
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
if (event.target == this.refs.save) {
|
||||||
|
if (this._profile) {
|
||||||
|
this.saveProfile({
|
||||||
|
guid: this._profile.guid,
|
||||||
|
profile: this.buildProfileObject(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.saveProfile({
|
||||||
|
profile: this.buildProfileObject(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.detachEventListeners();
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach event listener
|
||||||
|
*/
|
||||||
|
attachEventListeners() {
|
||||||
|
this.refs.controlsContainer.addEventListener("click", this);
|
||||||
|
document.addEventListener("input", this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove event listener
|
||||||
|
*/
|
||||||
|
detachEventListeners() {
|
||||||
|
this.refs.controlsContainer.removeEventListener("click", this);
|
||||||
|
document.removeEventListener("input", this);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pass in argument from openDialog
|
||||||
|
new EditDialog(window.arguments[0]);
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- 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>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Profile Autofill - Edit Profile</title>
|
||||||
|
<link rel="stylesheet" href="chrome://formautofill/content/editProfile.css" />
|
||||||
|
<script src="chrome://formautofill/content/editProfile.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form>
|
||||||
|
<label id="first-name-container">
|
||||||
|
<span>First Name</span>
|
||||||
|
<input id="first-name" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="middle-name-container">
|
||||||
|
<span>Middle Name</span>
|
||||||
|
<input id="middle-name" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="last-name-container">
|
||||||
|
<span>Last Name</span>
|
||||||
|
<input id="last-name" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="organization-container">
|
||||||
|
<span>Company</span>
|
||||||
|
<input id="organization" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="street-address-container">
|
||||||
|
<span>Street Address</span>
|
||||||
|
<textarea id="street-address"/>
|
||||||
|
</label>
|
||||||
|
<label id="address-level2-container">
|
||||||
|
<span>City/Town</span>
|
||||||
|
<input id="address-level2" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="address-level1-container">
|
||||||
|
<span>State/Province</span>
|
||||||
|
<input id="address-level1" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="postal-code-container">
|
||||||
|
<span>Zip/Postal</span>
|
||||||
|
<input id="postal-code" type="text"/>
|
||||||
|
</label>
|
||||||
|
<label id="country-container">
|
||||||
|
<span>Country</span>
|
||||||
|
<select id="country">
|
||||||
|
<option/>
|
||||||
|
<option value="US">United States</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label id="email-container">
|
||||||
|
<span>Email</span>
|
||||||
|
<input id="email" type="email"/>
|
||||||
|
</label>
|
||||||
|
<label id="tel-container">
|
||||||
|
<span>Phone</span>
|
||||||
|
<input id="tel" type="tel"/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<div id="controls-container">
|
||||||
|
<button id="cancel">Cancel</button>
|
||||||
|
<button id="save" disabled="disabled">Save</button>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -89,15 +89,28 @@ option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
|
||||||
option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project')
|
option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project')
|
||||||
option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
|
option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
|
||||||
|
|
||||||
|
option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1,
|
||||||
|
help='External directory containing additional build files')
|
||||||
|
|
||||||
|
@depends('--with-external-source-dir')
|
||||||
|
def external_source_dir(value):
|
||||||
|
if value:
|
||||||
|
return value[0]
|
||||||
|
|
||||||
|
set_config('EXTERNAL_SOURCE_DIR', external_source_dir)
|
||||||
|
add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
|
||||||
|
|
||||||
# Read user mozconfig
|
# Read user mozconfig
|
||||||
# ==============================================================
|
# ==============================================================
|
||||||
# Note: the dependency on --help is only there to always read the mozconfig,
|
# Note: the dependency on --help is only there to always read the mozconfig,
|
||||||
# even when --help is passed. Without this dependency, the function wouldn't
|
# even when --help is passed. Without this dependency, the function wouldn't
|
||||||
# be called when --help is passed, and the mozconfig wouldn't be read.
|
# be called when --help is passed, and the mozconfig wouldn't be read.
|
||||||
@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', 'OLD_CONFIGURE',
|
@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', 'OLD_CONFIGURE',
|
||||||
check_build_environment, '--help')
|
check_build_environment, '--with-external-source-dir',
|
||||||
|
'--help')
|
||||||
@imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
|
@imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
|
||||||
def mozconfig(current_project, mozconfig, old_configure, build_env, help):
|
def mozconfig(current_project, mozconfig, old_configure, build_env,
|
||||||
|
external_source_dir, help):
|
||||||
if not old_configure:
|
if not old_configure:
|
||||||
die('The OLD_CONFIGURE environment variable must be set')
|
die('The OLD_CONFIGURE environment variable must be set')
|
||||||
|
|
||||||
|
@ -120,7 +133,10 @@ def mozconfig(current_project, mozconfig, old_configure, build_env, help):
|
||||||
if os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'):
|
if os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'):
|
||||||
return {'path': None}
|
return {'path': None}
|
||||||
|
|
||||||
loader = MozconfigLoader(build_env.topsrcdir)
|
topsrcdir = build_env.topsrcdir
|
||||||
|
if external_source_dir:
|
||||||
|
topsrcdir = external_source_dir[0]
|
||||||
|
loader = MozconfigLoader(topsrcdir)
|
||||||
current_project = current_project[0] if current_project else None
|
current_project = current_project[0] if current_project else None
|
||||||
mozconfig = mozconfig[0] if mozconfig else None
|
mozconfig = mozconfig[0] if mozconfig else None
|
||||||
mozconfig = loader.find_mozconfig(env={'MOZCONFIG': mozconfig})
|
mozconfig = loader.find_mozconfig(env={'MOZCONFIG': mozconfig})
|
||||||
|
@ -632,9 +648,6 @@ def default_project(build_env, help):
|
||||||
option('--enable-project', nargs=1, default=default_project,
|
option('--enable-project', nargs=1, default=default_project,
|
||||||
help='Project to build')
|
help='Project to build')
|
||||||
|
|
||||||
option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1,
|
|
||||||
help='External directory containing additional build files')
|
|
||||||
|
|
||||||
@depends('--enable-project', '--with-external-source-dir',
|
@depends('--enable-project', '--with-external-source-dir',
|
||||||
check_build_environment, '--help')
|
check_build_environment, '--help')
|
||||||
@imports(_from='os.path', _import='exists')
|
@imports(_from='os.path', _import='exists')
|
||||||
|
@ -651,14 +664,6 @@ def include_project_configure(project, external_source_dir, build_env, help):
|
||||||
die('Cannot find project %s', project[0])
|
die('Cannot find project %s', project[0])
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@depends('--with-external-source-dir')
|
|
||||||
def external_source_dir(value):
|
|
||||||
if value:
|
|
||||||
return value[0]
|
|
||||||
|
|
||||||
set_config('EXTERNAL_SOURCE_DIR', external_source_dir)
|
|
||||||
add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
|
|
||||||
|
|
||||||
|
|
||||||
@depends(include_project_configure, check_build_environment, '--help')
|
@depends(include_project_configure, check_build_environment, '--help')
|
||||||
def build_project(include_project_configure, build_env, help):
|
def build_project(include_project_configure, build_env, help):
|
||||||
|
|
|
@ -151,6 +151,8 @@ for f in files:
|
||||||
log(3, ' pretty printed code:')
|
log(3, ' pretty printed code:')
|
||||||
ipdl.genipdl(ast, codedir)
|
ipdl.genipdl(ast, codedir)
|
||||||
|
|
||||||
|
ipdl.checkFixedSyncMessages(parser)
|
||||||
|
|
||||||
# Second pass: generate code
|
# Second pass: generate code
|
||||||
for f in files:
|
for f in files:
|
||||||
# Read from parser cache
|
# Read from parser cache
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified', 'checkSyncMessage' ]
|
__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified',
|
||||||
|
'checkSyncMessage', 'checkFixedSyncMessages' ]
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
@ -11,7 +12,7 @@ from ipdl.cgen import IPDLCodeGen
|
||||||
from ipdl.lower import LowerToCxx, msgenums
|
from ipdl.lower import LowerToCxx, msgenums
|
||||||
from ipdl.parser import Parser, ParseError
|
from ipdl.parser import Parser, ParseError
|
||||||
from ipdl.type import TypeCheck
|
from ipdl.type import TypeCheck
|
||||||
from ipdl.checker import checkSyncMessage
|
from ipdl.checker import checkSyncMessage, checkFixedSyncMessages
|
||||||
|
|
||||||
from ipdl.cxx.cgen import CxxCodeGen
|
from ipdl.cxx.cgen import CxxCodeGen
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,11 @@ import sys
|
||||||
from ipdl.ast import Visitor, ASYNC
|
from ipdl.ast import Visitor, ASYNC
|
||||||
|
|
||||||
class SyncMessageChecker(Visitor):
|
class SyncMessageChecker(Visitor):
|
||||||
|
syncMsgList = []
|
||||||
|
seenProtocols = []
|
||||||
|
seenSyncMessages = []
|
||||||
def __init__(self, syncMsgList):
|
def __init__(self, syncMsgList):
|
||||||
self.syncMsgList = syncMsgList
|
SyncMessageChecker.syncMsgList = syncMsgList
|
||||||
self.errors = []
|
self.errors = []
|
||||||
|
|
||||||
def prettyMsgName(self, msg):
|
def prettyMsgName(self, msg):
|
||||||
|
@ -23,16 +26,24 @@ class SyncMessageChecker(Visitor):
|
||||||
(str(loc), msg))
|
(str(loc), msg))
|
||||||
|
|
||||||
def visitProtocol(self, p):
|
def visitProtocol(self, p):
|
||||||
|
self.errors = []
|
||||||
self.currentProtocol = p.name
|
self.currentProtocol = p.name
|
||||||
|
SyncMessageChecker.seenProtocols.append(p.name)
|
||||||
Visitor.visitProtocol(self, p)
|
Visitor.visitProtocol(self, p)
|
||||||
|
|
||||||
def visitMessageDecl(self, md):
|
def visitMessageDecl(self, md):
|
||||||
pn = self.prettyMsgName(md.name)
|
pn = self.prettyMsgName(md.name)
|
||||||
if md.sendSemantics is not ASYNC and pn not in self.syncMsgList:
|
if md.sendSemantics is not ASYNC:
|
||||||
|
if pn not in SyncMessageChecker.syncMsgList:
|
||||||
self.errorUnknownSyncMessage(md.loc, pn)
|
self.errorUnknownSyncMessage(md.loc, pn)
|
||||||
if md.sendSemantics is ASYNC and pn in self.syncMsgList:
|
SyncMessageChecker.seenSyncMessages.append(pn)
|
||||||
|
elif pn in SyncMessageChecker.syncMsgList:
|
||||||
self.errorAsyncMessageCanRemove(md.loc, pn)
|
self.errorAsyncMessageCanRemove(md.loc, pn)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getFixedSyncMessages():
|
||||||
|
return set(SyncMessageChecker.syncMsgList) - set(SyncMessageChecker.seenSyncMessages)
|
||||||
|
|
||||||
def checkSyncMessage(tu, syncMsgList, errout=sys.stderr):
|
def checkSyncMessage(tu, syncMsgList, errout=sys.stderr):
|
||||||
checker = SyncMessageChecker(syncMsgList)
|
checker = SyncMessageChecker(syncMsgList)
|
||||||
tu.accept(checker)
|
tu.accept(checker)
|
||||||
|
@ -41,3 +52,14 @@ def checkSyncMessage(tu, syncMsgList, errout=sys.stderr):
|
||||||
print >>errout, error
|
print >>errout, error
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def checkFixedSyncMessages(config, errout=sys.stderr):
|
||||||
|
fixed = SyncMessageChecker.getFixedSyncMessages()
|
||||||
|
for item in fixed:
|
||||||
|
protocol = item.split('::')[0]
|
||||||
|
# Ignore things like sync messages in test protocols we didn't compile.
|
||||||
|
# Also, ignore platform-specific IPC messages.
|
||||||
|
if protocol in SyncMessageChecker.seenProtocols and \
|
||||||
|
'platform' not in config.options(item):
|
||||||
|
print >>errout, 'Error: Sync IPC message %s not found, it appears to be fixed.\n' \
|
||||||
|
'Please remove it from sync-messages.ini.' % item
|
||||||
|
|
|
@ -473,6 +473,7 @@ description =
|
||||||
description =
|
description =
|
||||||
[PDocAccessible::GetWindowedPluginIAccessible]
|
[PDocAccessible::GetWindowedPluginIAccessible]
|
||||||
description =
|
description =
|
||||||
|
platform = win
|
||||||
|
|
||||||
# CPOWs
|
# CPOWs
|
||||||
[PBrowser::RpcMessage]
|
[PBrowser::RpcMessage]
|
||||||
|
@ -537,8 +538,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NPP_GetValue_NPPVpluginWantsAllNetworkStreams]
|
[PPluginInstance::NPP_GetValue_NPPVpluginWantsAllNetworkStreams]
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NPP_GetValue_NPPVpluginNeedsXEmbed]
|
|
||||||
description =
|
|
||||||
[PPluginInstance::NPP_GetValue_NPPVpluginScriptableNPObject]
|
[PPluginInstance::NPP_GetValue_NPPVpluginScriptableNPObject]
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NPP_SetValue_NPNVprivateModeBool]
|
[PPluginInstance::NPP_SetValue_NPNVprivateModeBool]
|
||||||
|
@ -619,8 +618,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NPN_ConvertPoint]
|
[PPluginInstance::NPN_ConvertPoint]
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NegotiatedCarbon]
|
|
||||||
description =
|
|
||||||
[PPluginInstance::GetCompositionString]
|
[PPluginInstance::GetCompositionString]
|
||||||
description =
|
description =
|
||||||
[PPluginInstance::NPP_NewStream]
|
[PPluginInstance::NPP_NewStream]
|
||||||
|
@ -645,8 +642,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PPluginModule::OptionalFunctionsSupported]
|
[PPluginModule::OptionalFunctionsSupported]
|
||||||
description =
|
description =
|
||||||
[PPluginModule::PCrashReporter]
|
|
||||||
description =
|
|
||||||
[PPluginModule::ProcessSomeEvents]
|
[PPluginModule::ProcessSomeEvents]
|
||||||
description =
|
description =
|
||||||
[PPluginModule::NPN_SetException]
|
[PPluginModule::NPN_SetException]
|
||||||
|
@ -759,8 +754,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PContent::FindPlugins]
|
[PContent::FindPlugins]
|
||||||
description =
|
description =
|
||||||
[PContent::PCrashReporter]
|
|
||||||
description =
|
|
||||||
[PContent::NSSU2FTokenIsCompatibleVersion]
|
[PContent::NSSU2FTokenIsCompatibleVersion]
|
||||||
description =
|
description =
|
||||||
[PContent::NSSU2FTokenIsRegistered]
|
[PContent::NSSU2FTokenIsRegistered]
|
||||||
|
@ -801,8 +794,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PContent::AllocateLayerTreeId]
|
[PContent::AllocateLayerTreeId]
|
||||||
description =
|
description =
|
||||||
[PContent::GetGfxInfoFeatureStatus]
|
|
||||||
description =
|
|
||||||
[PContent::BeginDriverCrashGuard]
|
[PContent::BeginDriverCrashGuard]
|
||||||
description =
|
description =
|
||||||
[PContent::EndDriverCrashGuard]
|
[PContent::EndDriverCrashGuard]
|
||||||
|
@ -915,10 +906,13 @@ description =
|
||||||
description =
|
description =
|
||||||
[PCompositorWidget::EnterPresentLock]
|
[PCompositorWidget::EnterPresentLock]
|
||||||
description =
|
description =
|
||||||
|
platform = win
|
||||||
[PCompositorWidget::LeavePresentLock]
|
[PCompositorWidget::LeavePresentLock]
|
||||||
description =
|
description =
|
||||||
|
platform = win
|
||||||
[PCompositorWidget::ClearTransparentWindow]
|
[PCompositorWidget::ClearTransparentWindow]
|
||||||
description =
|
description =
|
||||||
|
platform = win
|
||||||
[PImageBridge::WillClose]
|
[PImageBridge::WillClose]
|
||||||
description =
|
description =
|
||||||
[PImageBridge::NewCompositable]
|
[PImageBridge::NewCompositable]
|
||||||
|
@ -939,8 +933,6 @@ description =
|
||||||
description =
|
description =
|
||||||
[PLayerTransaction::RequestProperty]
|
[PLayerTransaction::RequestProperty]
|
||||||
description =
|
description =
|
||||||
[PTexture::DestroySync]
|
|
||||||
description =
|
|
||||||
[PUiCompositorController::Pause]
|
[PUiCompositorController::Pause]
|
||||||
description =
|
description =
|
||||||
[PUiCompositorController::Resume]
|
[PUiCompositorController::Resume]
|
||||||
|
|
|
@ -15,10 +15,14 @@ template <typename T> class WeakCache;
|
||||||
namespace shadow {
|
namespace shadow {
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
RegisterWeakCache(JS::Zone* zone, JS::WeakCache<void*>* cachep);
|
RegisterWeakCache(JS::Zone* zone, JS::WeakCache<void*>* cachep);
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
RegisterWeakCache(JSRuntime* rt, JS::WeakCache<void*>* cachep);
|
||||||
} // namespace shadow
|
} // namespace shadow
|
||||||
|
|
||||||
// A WeakCache stores the given Sweepable container and links itself into a
|
// A WeakCache stores the given Sweepable container and links itself into a
|
||||||
// list of such caches that are swept during each GC.
|
// list of such caches that are swept during each GC. A WeakCache can be
|
||||||
|
// specific to a zone, or across a whole runtime, depending on which
|
||||||
|
// constructor is used.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class WeakCache : public js::MutableWrappedPtrOperations<T, WeakCache<T>>,
|
class WeakCache : public js::MutableWrappedPtrOperations<T, WeakCache<T>>,
|
||||||
private mozilla::LinkedListElement<WeakCache<T>>
|
private mozilla::LinkedListElement<WeakCache<T>>
|
||||||
|
@ -43,6 +47,13 @@ class WeakCache : public js::MutableWrappedPtrOperations<T, WeakCache<T>>,
|
||||||
sweeper = GCPolicy<T>::sweep;
|
sweeper = GCPolicy<T>::sweep;
|
||||||
shadow::RegisterWeakCache(zone, reinterpret_cast<WeakCache<void*>*>(this));
|
shadow::RegisterWeakCache(zone, reinterpret_cast<WeakCache<void*>*>(this));
|
||||||
}
|
}
|
||||||
|
template <typename U>
|
||||||
|
WeakCache(JSRuntime* rt, U&& initial)
|
||||||
|
: cache(mozilla::Forward<U>(initial))
|
||||||
|
{
|
||||||
|
sweeper = GCPolicy<T>::sweep;
|
||||||
|
shadow::RegisterWeakCache(rt, reinterpret_cast<WeakCache<void*>*>(this));
|
||||||
|
}
|
||||||
WeakCache(WeakCache&& other)
|
WeakCache(WeakCache&& other)
|
||||||
: sweeper(other.sweeper),
|
: sweeper(other.sweeper),
|
||||||
cache(mozilla::Move(other.cache))
|
cache(mozilla::Move(other.cache))
|
||||||
|
|
|
@ -533,6 +533,8 @@ class OrderedHashTable
|
||||||
return offsetof(OrderedHashTable, data);
|
return offsetof(OrderedHashTable, data);
|
||||||
}
|
}
|
||||||
static constexpr size_t offsetOfDataElement() {
|
static constexpr size_t offsetOfDataElement() {
|
||||||
|
static_assert(offsetof(Data, element) == 0,
|
||||||
|
"RangeFront and RangePopFront depend on offsetof(Data, element) being 0");
|
||||||
return offsetof(Data, element);
|
return offsetof(Data, element);
|
||||||
}
|
}
|
||||||
static constexpr size_t sizeofData() {
|
static constexpr size_t sizeofData() {
|
||||||
|
|
|
@ -6465,7 +6465,7 @@ RangeFront<ValueMap>(MacroAssembler& masm, Register range, Register i, Register
|
||||||
masm.loadPtr(Address(range, ValueMap::Range::offsetOfHashTable()), front);
|
masm.loadPtr(Address(range, ValueMap::Range::offsetOfHashTable()), front);
|
||||||
masm.loadPtr(Address(front, ValueMap::offsetOfImplData()), front);
|
masm.loadPtr(Address(front, ValueMap::offsetOfImplData()), front);
|
||||||
|
|
||||||
static_assert(ValueMap::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
MOZ_ASSERT(ValueMap::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
||||||
static_assert(ValueMap::sizeofImplData() == 24, "sizeof(Data) is 24");
|
static_assert(ValueMap::sizeofImplData() == 24, "sizeof(Data) is 24");
|
||||||
masm.mulBy3(i, i);
|
masm.mulBy3(i, i);
|
||||||
masm.lshiftPtr(Imm32(3), i);
|
masm.lshiftPtr(Imm32(3), i);
|
||||||
|
@ -6479,7 +6479,7 @@ RangeFront<ValueSet>(MacroAssembler& masm, Register range, Register i, Register
|
||||||
masm.loadPtr(Address(range, ValueSet::Range::offsetOfHashTable()), front);
|
masm.loadPtr(Address(range, ValueSet::Range::offsetOfHashTable()), front);
|
||||||
masm.loadPtr(Address(front, ValueSet::offsetOfImplData()), front);
|
masm.loadPtr(Address(front, ValueSet::offsetOfImplData()), front);
|
||||||
|
|
||||||
static_assert(ValueSet::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
MOZ_ASSERT(ValueSet::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
||||||
static_assert(ValueSet::sizeofImplData() == 16, "sizeof(Data) is 16");
|
static_assert(ValueSet::sizeofImplData() == 16, "sizeof(Data) is 16");
|
||||||
masm.lshiftPtr(Imm32(4), i);
|
masm.lshiftPtr(Imm32(4), i);
|
||||||
masm.addPtr(i, front);
|
masm.addPtr(i, front);
|
||||||
|
@ -6503,7 +6503,7 @@ RangePopFront(MacroAssembler& masm, Register range, Register front, Register dat
|
||||||
|
|
||||||
// We can add sizeof(Data) to |front| to select the next element, because
|
// We can add sizeof(Data) to |front| to select the next element, because
|
||||||
// |front| and |range.ht.data[i]| point to the same location.
|
// |front| and |range.ht.data[i]| point to the same location.
|
||||||
static_assert(OrderedHashTable::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
MOZ_ASSERT(OrderedHashTable::offsetOfImplDataElement() == 0, "offsetof(Data, element) is 0");
|
||||||
masm.addPtr(Imm32(OrderedHashTable::sizeofImplData()), front);
|
masm.addPtr(Imm32(OrderedHashTable::sizeofImplData()), front);
|
||||||
|
|
||||||
masm.branchTestMagic(Assembler::NotEqual, Address(front, OrderedHashTable::offsetOfEntryKey()),
|
masm.branchTestMagic(Assembler::NotEqual, Address(front, OrderedHashTable::offsetOfEntryKey()),
|
||||||
|
|
|
@ -126,6 +126,7 @@ MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare glo
|
||||||
// Date
|
// Date
|
||||||
MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date")
|
MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date")
|
||||||
MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable")
|
MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable")
|
||||||
|
MSG_DEF(JSMSG_DEPRECATED_TOLOCALEFORMAT, 0, JSEXN_WARN, "Date.prototype.toLocaleFormat is deprecated; consider using Intl.DateTimeFormat instead")
|
||||||
|
|
||||||
// String
|
// String
|
||||||
MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence")
|
MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence")
|
||||||
|
|
|
@ -54,6 +54,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
|
||||||
isAtomsCompartment_(false),
|
isAtomsCompartment_(false),
|
||||||
isSelfHosting(false),
|
isSelfHosting(false),
|
||||||
marked(true),
|
marked(true),
|
||||||
|
warnedAboutDateToLocaleFormat(false),
|
||||||
warnedAboutExprClosure(false),
|
warnedAboutExprClosure(false),
|
||||||
warnedAboutForEach(false),
|
warnedAboutForEach(false),
|
||||||
warnedAboutStringGenericsMethods(0),
|
warnedAboutStringGenericsMethods(0),
|
||||||
|
|
|
@ -406,6 +406,7 @@ struct JSCompartment
|
||||||
public:
|
public:
|
||||||
bool isSelfHosting;
|
bool isSelfHosting;
|
||||||
bool marked;
|
bool marked;
|
||||||
|
bool warnedAboutDateToLocaleFormat;
|
||||||
bool warnedAboutExprClosure;
|
bool warnedAboutExprClosure;
|
||||||
bool warnedAboutForEach;
|
bool warnedAboutForEach;
|
||||||
uint32_t warnedAboutStringGenericsMethods;
|
uint32_t warnedAboutStringGenericsMethods;
|
||||||
|
|
|
@ -2822,6 +2822,17 @@ date_toLocaleFormat_impl(JSContext* cx, const CallArgs& args)
|
||||||
{
|
{
|
||||||
Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
|
Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
|
||||||
|
|
||||||
|
#if EXPOSE_INTL_API
|
||||||
|
if (!cx->compartment()->warnedAboutDateToLocaleFormat) {
|
||||||
|
if (!JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
|
||||||
|
JSMSG_DEPRECATED_TOLOCALEFORMAT))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cx->compartment()->warnedAboutDateToLocaleFormat = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (args.length() == 0) {
|
if (args.length() == 0) {
|
||||||
/*
|
/*
|
||||||
* Use '%#c' for windows, because '%c' is backward-compatible and non-y2k
|
* Use '%#c' for windows, because '%c' is backward-compatible and non-y2k
|
||||||
|
|
|
@ -2554,6 +2554,8 @@ GCRuntime::updateRuntimePointersToRelocatedCells(AutoLockForExclusiveAccess& loc
|
||||||
WatchpointMap::sweepAll(rt);
|
WatchpointMap::sweepAll(rt);
|
||||||
Debugger::sweepAll(rt->defaultFreeOp());
|
Debugger::sweepAll(rt->defaultFreeOp());
|
||||||
jit::JitRuntime::SweepJitcodeGlobalTable(rt);
|
jit::JitRuntime::SweepJitcodeGlobalTable(rt);
|
||||||
|
for (JS::WeakCache<void*>* cache : rt->weakCaches())
|
||||||
|
cache->sweep();
|
||||||
|
|
||||||
// Type inference may put more blocks here to free.
|
// Type inference may put more blocks here to free.
|
||||||
blocksToFreeAfterSweeping.ref().freeAll();
|
blocksToFreeAfterSweeping.ref().freeAll();
|
||||||
|
@ -5149,6 +5151,10 @@ GCRuntime::beginSweepingZoneGroup(AutoLockForExclusiveAccess& lock)
|
||||||
// Sweep entries containing about-to-be-finalized JitCode and
|
// Sweep entries containing about-to-be-finalized JitCode and
|
||||||
// update relocated TypeSet::Types inside the JitcodeGlobalTable.
|
// update relocated TypeSet::Types inside the JitcodeGlobalTable.
|
||||||
jit::JitRuntime::SweepJitcodeGlobalTable(rt);
|
jit::JitRuntime::SweepJitcodeGlobalTable(rt);
|
||||||
|
|
||||||
|
// Sweep runtime-wide weak caches.
|
||||||
|
for (JS::WeakCache<void*>* cache : rt->weakCaches())
|
||||||
|
cache->sweep();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// |reftest| skip-if(!xulRuntime.shell||this.hasOwnProperty("Intl"))
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
// Don't warn about Date.prototype.toLocaleFormat() when Intl isn't supported.
|
||||||
|
|
||||||
|
enableLastWarning();
|
||||||
|
|
||||||
|
new Date().toLocaleFormat("%Y");
|
||||||
|
|
||||||
|
var warning = getLastWarning();
|
||||||
|
assertEq(warning, null, "warning shouldn't be emitted for toLocaleFormat");
|
||||||
|
|
||||||
|
disableLastWarning();
|
||||||
|
|
||||||
|
if (typeof reportCompare === 'function')
|
||||||
|
reportCompare(0, 0);
|
|
@ -0,0 +1,28 @@
|
||||||
|
// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty("Intl"))
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
// Warn once about Date.prototype.toLocaleFormat().
|
||||||
|
|
||||||
|
enableLastWarning();
|
||||||
|
|
||||||
|
new Date().toLocaleFormat("%Y");
|
||||||
|
|
||||||
|
var warning = getLastWarning();
|
||||||
|
assertEq(warning !== null, true, "warning should be emitted for toLocaleFormat");
|
||||||
|
assertEq(warning.name, "Warning");
|
||||||
|
assertEq(warning.message.indexOf("toLocaleFormat") !== -1, true,
|
||||||
|
"warning should mention toLocaleFormat");
|
||||||
|
|
||||||
|
clearLastWarning();
|
||||||
|
|
||||||
|
new Date().toLocaleFormat("%Y");
|
||||||
|
|
||||||
|
warning = getLastWarning();
|
||||||
|
assertEq(warning, null, "warning shouldn't be emitted for 2nd call to toLocaleFormat");
|
||||||
|
|
||||||
|
disableLastWarning();
|
||||||
|
|
||||||
|
if (typeof reportCompare === 'function')
|
||||||
|
reportCompare(0, 0);
|
|
@ -915,3 +915,9 @@ JSRuntime::ionLazyLinkListAdd(jit::IonBuilder* builder)
|
||||||
ionLazyLinkList().insertFront(builder);
|
ionLazyLinkList().insertFront(builder);
|
||||||
ionLazyLinkListSize_++;
|
ionLazyLinkListSize_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS::shadow::RegisterWeakCache(JSRuntime* rt, WeakCache<void*>* cachep)
|
||||||
|
{
|
||||||
|
rt->registerWeakCache(cachep);
|
||||||
|
}
|
||||||
|
|
|
@ -560,6 +560,15 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
||||||
windowProxyClass_ = clasp;
|
windowProxyClass_ = clasp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// List of non-ephemeron weak containers to sweep during beginSweepingZoneGroup.
|
||||||
|
js::ActiveThreadData<mozilla::LinkedList<JS::WeakCache<void*>>> weakCaches_;
|
||||||
|
public:
|
||||||
|
mozilla::LinkedList<JS::WeakCache<void*>>& weakCaches() { return weakCaches_.ref(); }
|
||||||
|
void registerWeakCache(JS::WeakCache<void*>* cachep) {
|
||||||
|
weakCaches().insertBack(cachep);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* Head of circular list of all enabled Debuggers that have
|
* Head of circular list of all enabled Debuggers that have
|
||||||
|
|
|
@ -64,6 +64,17 @@ class DebugFrame
|
||||||
|
|
||||||
explicit DebugFrame() {}
|
explicit DebugFrame() {}
|
||||||
|
|
||||||
|
void StaticAsserts() {
|
||||||
|
// VS2017 doesn't consider offsetOfResults() etc. to be constexpr, so we have to use
|
||||||
|
// offsetof directly. These asserts can't be at class-level because the type is incomplete.
|
||||||
|
static_assert(offsetof(DebugFrame, resultI32_) == 0, "results shall be at offset 0");
|
||||||
|
static_assert(offsetof(DebugFrame, tlsData_) + sizeof(TlsData*) ==
|
||||||
|
offsetof(DebugFrame, frame_),
|
||||||
|
"TLS pointer must be a field just before the wasm frame");
|
||||||
|
static_assert(sizeof(DebugFrame) % 8 == 0 && offsetof(DebugFrame, frame_) % 8 == 0,
|
||||||
|
"DebugFrame and its portion is 8-bytes aligned for AbstractFramePtr");
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline uint32_t funcIndex() const { return funcIndex_; }
|
inline uint32_t funcIndex() const { return funcIndex_; }
|
||||||
inline TlsData* tlsData() const { return tlsData_; }
|
inline TlsData* tlsData() const { return tlsData_; }
|
||||||
|
@ -110,12 +121,6 @@ class DebugFrame
|
||||||
static constexpr size_t offsetOfFrame() { return offsetof(DebugFrame, frame_); }
|
static constexpr size_t offsetOfFrame() { return offsetof(DebugFrame, frame_); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(DebugFrame::offsetOfResults() == 0, "results shall be at offset 0");
|
|
||||||
static_assert(DebugFrame::offsetOfTlsData() + sizeof(TlsData*) == DebugFrame::offsetOfFrame(),
|
|
||||||
"TLS pointer must be a field just before the wasm frame");
|
|
||||||
static_assert(sizeof(DebugFrame) % 8 == 0 && DebugFrame::offsetOfFrame() % 8 == 0,
|
|
||||||
"DebugFrame and its portion is 8-bytes aligned for AbstractFramePtr");
|
|
||||||
|
|
||||||
} // namespace wasm
|
} // namespace wasm
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
|
|
|
@ -593,10 +593,6 @@ GeckoRestyleManager::UpdateOnlyAnimationStyles()
|
||||||
tracker.Init(this);
|
tracker.Init(this);
|
||||||
|
|
||||||
if (doCSS) {
|
if (doCSS) {
|
||||||
// FIXME: We should have the transition manager and animation manager
|
|
||||||
// add only the elements for which animations are currently throttled
|
|
||||||
// (i.e., animating on the compositor with main-thread style updates
|
|
||||||
// suppressed).
|
|
||||||
PresContext()->EffectCompositor()->AddStyleUpdatesTo(tracker);
|
PresContext()->EffectCompositor()->AddStyleUpdatesTo(tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1575,7 +1575,8 @@ nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aParameters)
|
const ContainerLayerParameters& aParameters)
|
||||||
{
|
{
|
||||||
if (!nsDisplayItem::ForceActiveLayers()) {
|
if (!nsDisplayItem::ForceActiveLayers() &&
|
||||||
|
aManager->GetBackendType() != layers::LayersBackend::LAYERS_WR) {
|
||||||
bool animated = false;
|
bool animated = false;
|
||||||
if (!nsLayoutUtils::AnimatedImageLayersEnabled() ||
|
if (!nsLayoutUtils::AnimatedImageLayersEnabled() ||
|
||||||
mImage->GetType() != imgIContainer::TYPE_RASTER ||
|
mImage->GetType() != imgIContainer::TYPE_RASTER ||
|
||||||
|
|
|
@ -306,7 +306,8 @@ fails == 280708-1b.html 280708-1b.html
|
||||||
== 283686-2.html 283686-2.html
|
== 283686-2.html 283686-2.html
|
||||||
== 283686-3.html 283686-3.html
|
== 283686-3.html 283686-3.html
|
||||||
fails == 289384-1.xhtml 289384-1.xhtml
|
fails == 289384-1.xhtml 289384-1.xhtml
|
||||||
skip-if(stylo) == 289480.html#top 289480.html#top # Bug 1341705
|
fails == 289480.html#top 289480-ref.html
|
||||||
|
fails == 289480-ref.html 289480-ref.html
|
||||||
fails == 290129-1.html 290129-1.html
|
fails == 290129-1.html 290129-1.html
|
||||||
fails == 291078-1.html 291078-1.html
|
fails == 291078-1.html 291078-1.html
|
||||||
== 291078-2.html 291078-2.html
|
== 291078-2.html 291078-2.html
|
||||||
|
@ -1475,7 +1476,7 @@ fails == 538909-1.html 538909-1.html
|
||||||
== 539323-3.html 539323-3.html
|
== 539323-3.html 539323-3.html
|
||||||
fails == 539880-1.html 539880-1.html
|
fails == 539880-1.html 539880-1.html
|
||||||
fails == 539880-1-dynamic.html 539880-1-dynamic.html
|
fails == 539880-1-dynamic.html 539880-1-dynamic.html
|
||||||
skip-if(stylo) == 539949-1.html#test2 539949-1.html#test2 # load fails???
|
fails == 539949-1.html#test2 539949-1-ref.html#test2
|
||||||
fails == 541382-1.html 541382-1.html
|
fails == 541382-1.html 541382-1.html
|
||||||
== 541406-1.html 541406-1.html
|
== 541406-1.html 541406-1.html
|
||||||
fails needs-focus == 542116-1.html 542116-1.html
|
fails needs-focus == 542116-1.html 542116-1.html
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
|
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
|
||||||
skip-if(stylo) HTTP == deferred-anchor.xhtml#d deferred-anchor.xhtml#d # Fails to load?
|
HTTP == deferred-anchor.xhtml#d deferred-anchor-ref.xhtml#d
|
||||||
fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,23) == deferred-anchor2.xhtml deferred-anchor2.xhtml
|
fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,23) == deferred-anchor2.xhtml deferred-anchor2.xhtml
|
||||||
fails HTTP == fixed-1.html fixed-1.html
|
fails HTTP == fixed-1.html fixed-1.html
|
||||||
fails == fixed-table-1.html fixed-table-1.html
|
fails == fixed-table-1.html fixed-table-1.html
|
||||||
|
@ -23,7 +23,7 @@ fails == scroll-behavior-9.html scroll-behavior-9.html
|
||||||
skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-10.html scroll-behavior-10.html
|
skip-if(Android) pref(layout.css.scroll-behavior.enabled,true) pref(layout.css.scroll-behavior.property-enabled,true) == scroll-behavior-10.html scroll-behavior-10.html
|
||||||
fails == scroll-behavior-textarea.html scroll-behavior-textarea.html
|
fails == scroll-behavior-textarea.html scroll-behavior-textarea.html
|
||||||
fails HTTP == simple-1.html simple-1.html
|
fails HTTP == simple-1.html simple-1.html
|
||||||
skip-if(stylo) HTTP == subpixel-1.html#d subpixel-1.html#d # Fails to load?
|
fails HTTP == subpixel-1.html#d subpixel-1-ref.html#d
|
||||||
== text-1.html text-1.html
|
== text-1.html text-1.html
|
||||||
== text-2.html?up text-2.html?up
|
== text-2.html?up text-2.html?up
|
||||||
== transformed-1.html transformed-1.html
|
== transformed-1.html transformed-1.html
|
||||||
|
|
|
@ -1728,10 +1728,10 @@ nsStyleSet::ResolveStyleWithReplacement(Element* aElement,
|
||||||
// because at this point the parameter is more than just the element
|
// because at this point the parameter is more than just the element
|
||||||
// for animation; it's also used for the SetBodyTextColor call when
|
// for animation; it's also used for the SetBodyTextColor call when
|
||||||
// it's the body element.
|
// it's the body element.
|
||||||
// However, we only want to set the flag to call CheckAnimationRule
|
// However, we only want to set the flag to call UpdateAnimations
|
||||||
// if we're dealing with a replacement (such as style attribute
|
// if we're dealing with a replacement (such as style attribute
|
||||||
// replacement) that could lead to the animation property changing,
|
// replacement) that could lead to the animation property changing,
|
||||||
// and we explicitly do NOT want to call CheckAnimationRule when
|
// and we explicitly do NOT want to call UpdateAnimations when
|
||||||
// we're trying to do an animation-only update.
|
// we're trying to do an animation-only update.
|
||||||
if (aReplacements & ~(eRestyle_CSSTransitions | eRestyle_CSSAnimations)) {
|
if (aReplacements & ~(eRestyle_CSSTransitions | eRestyle_CSSAnimations)) {
|
||||||
flags |= eDoAnimation;
|
flags |= eDoAnimation;
|
||||||
|
|
|
@ -516,30 +516,49 @@ nsTableFrame::ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude)
|
||||||
{
|
{
|
||||||
// Iterate over the row groups and adjust the row indices of all rows
|
// Iterate over the row groups and adjust the row indices of all rows
|
||||||
// omit the rowgroups that will be inserted later
|
// omit the rowgroups that will be inserted later
|
||||||
|
mDeletedRowIndexRanges.clear();
|
||||||
|
|
||||||
RowGroupArray rowGroups;
|
RowGroupArray rowGroups;
|
||||||
OrderRowGroups(rowGroups);
|
OrderRowGroups(rowGroups);
|
||||||
|
|
||||||
int32_t rowIndex = 0;
|
|
||||||
nsTHashtable<nsPtrHashKey<nsTableRowGroupFrame> > excludeRowGroups;
|
nsTHashtable<nsPtrHashKey<nsTableRowGroupFrame> > excludeRowGroups;
|
||||||
nsFrameList::Enumerator excludeRowGroupsEnumerator(aRowGroupsToExclude);
|
nsFrameList::Enumerator excludeRowGroupsEnumerator(aRowGroupsToExclude);
|
||||||
while (!excludeRowGroupsEnumerator.AtEnd()) {
|
while (!excludeRowGroupsEnumerator.AtEnd()) {
|
||||||
excludeRowGroups.PutEntry(static_cast<nsTableRowGroupFrame*>(excludeRowGroupsEnumerator.get()));
|
excludeRowGroups.PutEntry(static_cast<nsTableRowGroupFrame*>(excludeRowGroupsEnumerator.get()));
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
// Check to make sure that the row indices of all rows in excluded row
|
||||||
|
// groups are '0' (i.e. the initial value since they haven't been added yet)
|
||||||
|
const nsFrameList& rowFrames =
|
||||||
|
excludeRowGroupsEnumerator.get()->PrincipalChildList();
|
||||||
|
for (nsFrameList::Enumerator rows(rowFrames); !rows.AtEnd(); rows.Next()) {
|
||||||
|
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(rows.get());
|
||||||
|
MOZ_ASSERT(row->GetRowIndex() == 0,
|
||||||
|
"exclusions cannot be used for rows that were already added,"
|
||||||
|
"because we'd need to process mDeletedRowIndexRanges");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
excludeRowGroupsEnumerator.Next();
|
excludeRowGroupsEnumerator.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t rowIndex = 0;
|
||||||
for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) {
|
for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) {
|
||||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx];
|
nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx];
|
||||||
if (!excludeRowGroups.GetEntry(rgFrame)) {
|
if (!excludeRowGroups.GetEntry(rgFrame)) {
|
||||||
const nsFrameList& rowFrames = rgFrame->PrincipalChildList();
|
const nsFrameList& rowFrames = rgFrame->PrincipalChildList();
|
||||||
for (nsFrameList::Enumerator rows(rowFrames); !rows.AtEnd(); rows.Next()) {
|
for (nsFrameList::Enumerator rows(rowFrames); !rows.AtEnd(); rows.Next()) {
|
||||||
if (mozilla::StyleDisplay::TableRow == rows.get()->StyleDisplay()->mDisplay) {
|
if (mozilla::StyleDisplay::TableRow ==
|
||||||
((nsTableRowFrame *)rows.get())->SetRowIndex(rowIndex);
|
rows.get()->StyleDisplay()->mDisplay) {
|
||||||
|
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(rows.get());
|
||||||
|
row->SetRowIndex(rowIndex);
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTableFrame::InsertColGroups(int32_t aStartColIndex,
|
nsTableFrame::InsertColGroups(int32_t aStartColIndex,
|
||||||
const nsFrameList::Slice& aColGroups)
|
const nsFrameList::Slice& aColGroups)
|
||||||
|
@ -920,13 +939,18 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
|
||||||
nsTableCellMap* cellMap = GetCellMap();
|
nsTableCellMap* cellMap = GetCellMap();
|
||||||
if (cellMap) {
|
if (cellMap) {
|
||||||
TableArea damageArea(0, 0, 0, 0);
|
TableArea damageArea(0, 0, 0, 0);
|
||||||
bool didRecalculate = RecalculateRowIndices();
|
bool shouldRecalculateIndex = !IsDeletedRowIndexRangesEmpty();
|
||||||
|
if (shouldRecalculateIndex) {
|
||||||
|
ResetRowIndices(nsFrameList::Slice(mFrames, nullptr, nullptr));
|
||||||
|
}
|
||||||
int32_t origNumRows = cellMap->GetRowCount();
|
int32_t origNumRows = cellMap->GetRowCount();
|
||||||
int32_t numNewRows = aRowFrames.Length();
|
int32_t numNewRows = aRowFrames.Length();
|
||||||
cellMap->InsertRows(aRowGroupFrame, aRowFrames, aRowIndex, aConsiderSpans, damageArea);
|
cellMap->InsertRows(aRowGroupFrame, aRowFrames, aRowIndex, aConsiderSpans, damageArea);
|
||||||
MatchCellMapToColCache(cellMap);
|
MatchCellMapToColCache(cellMap);
|
||||||
|
|
||||||
if (!didRecalculate) {
|
// Perform row index adjustment only if row indices were not
|
||||||
|
// reset above
|
||||||
|
if (!shouldRecalculateIndex) {
|
||||||
if (aRowIndex < origNumRows) {
|
if (aRowIndex < origNumRows) {
|
||||||
AdjustRowIndices(aRowIndex, numNewRows);
|
AdjustRowIndices(aRowIndex, numNewRows);
|
||||||
}
|
}
|
||||||
|
@ -952,32 +976,6 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
|
||||||
return numColsToAdd;
|
return numColsToAdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
nsTableFrame::RecalculateRowIndices()
|
|
||||||
{
|
|
||||||
if (mDeletedRowIndexRanges.size() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mDeletedRowIndexRanges.clear();
|
|
||||||
|
|
||||||
RowGroupArray rowGroups;
|
|
||||||
OrderRowGroups(rowGroups);
|
|
||||||
|
|
||||||
int32_t rowIndex = 0;
|
|
||||||
for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) {
|
|
||||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx];
|
|
||||||
const nsFrameList& rowFrames = rgFrame->PrincipalChildList();
|
|
||||||
for (nsFrameList::Enumerator rEnum(rowFrames); !rEnum.AtEnd(); rEnum.Next()) {
|
|
||||||
if (mozilla::StyleDisplay::TableRow == rEnum.get()->StyleDisplay()->mDisplay) {
|
|
||||||
nsTableRowFrame *row = static_cast<nsTableRowFrame*>(rEnum.get());
|
|
||||||
row->SetRowIndex(rowIndex);
|
|
||||||
rowIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTableFrame::AddDeletedRowIndex(int32_t aDeletedRowStoredIndex)
|
nsTableFrame::AddDeletedRowIndex(int32_t aDeletedRowStoredIndex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -872,12 +872,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex);
|
int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex);
|
||||||
|
|
||||||
/** Recalculate the row indices of all rows (if needed) and overwrite
|
|
||||||
* the value of the stored index with this newly calculated index.
|
|
||||||
* Returns whether recalculation was performed.
|
|
||||||
*/
|
|
||||||
bool RecalculateRowIndices();
|
|
||||||
|
|
||||||
/** Returns whether mDeletedRowIndexRanges is empty
|
/** Returns whether mDeletedRowIndexRanges is empty
|
||||||
*/
|
*/
|
||||||
bool IsDeletedRowIndexRangesEmpty() const {
|
bool IsDeletedRowIndexRangesEmpty() const {
|
||||||
|
|
|
@ -12,6 +12,15 @@
|
||||||
// corecrt_memory.h.
|
// corecrt_memory.h.
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// Because we wrap lz4.c in an anonymous namespace, all of its #includes
|
||||||
|
// go in the anonymous namespace too. This would create conflicting
|
||||||
|
// declarations for intrinsic functions that are internally defined
|
||||||
|
// at top-level. Including intrin.h here prevents it from being included
|
||||||
|
// later within the anonymous namespace.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace mozilla::Compression;
|
using namespace mozilla::Compression;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -287,6 +287,7 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
|
||||||
'gfx/VsyncSource.java',
|
'gfx/VsyncSource.java',
|
||||||
'InputConnectionListener.java',
|
'InputConnectionListener.java',
|
||||||
'InputMethods.java',
|
'InputMethods.java',
|
||||||
|
'NativeQueue.java',
|
||||||
'NotificationListener.java',
|
'NotificationListener.java',
|
||||||
'NSSBridge.java',
|
'NSSBridge.java',
|
||||||
'permissions/PermissionBlock.java',
|
'permissions/PermissionBlock.java',
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.mozilla.gecko.annotation.RobocopTarget;
|
||||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||||
import org.mozilla.gecko.GeckoAppShell;
|
import org.mozilla.gecko.GeckoAppShell;
|
||||||
import org.mozilla.gecko.mozglue.JNIObject;
|
import org.mozilla.gecko.mozglue.JNIObject;
|
||||||
|
import org.mozilla.gecko.NativeQueue.StateHolder;
|
||||||
import org.mozilla.gecko.util.BundleEventListener;
|
import org.mozilla.gecko.util.BundleEventListener;
|
||||||
import org.mozilla.gecko.util.EventCallback;
|
import org.mozilla.gecko.util.EventCallback;
|
||||||
import org.mozilla.gecko.util.GeckoBundle;
|
import org.mozilla.gecko.util.GeckoBundle;
|
||||||
|
@ -57,6 +58,7 @@ public final class EventDispatcher extends JNIObject {
|
||||||
new HashMap<String, List<BundleEventListener>>(DEFAULT_BACKGROUND_EVENTS_COUNT);
|
new HashMap<String, List<BundleEventListener>>(DEFAULT_BACKGROUND_EVENTS_COUNT);
|
||||||
|
|
||||||
private boolean mAttachedToGecko;
|
private boolean mAttachedToGecko;
|
||||||
|
private final StateHolder mStateHolder;
|
||||||
|
|
||||||
@ReflectionTarget
|
@ReflectionTarget
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
@WrapForJNI(calledFrom = "gecko")
|
||||||
|
@ -65,6 +67,15 @@ public final class EventDispatcher extends JNIObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ EventDispatcher() {
|
/* package */ EventDispatcher() {
|
||||||
|
mStateHolder = GeckoThread.getStateHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ EventDispatcher(final NativeQueue.StateHolder stateHolder) {
|
||||||
|
mStateHolder = stateHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isReadyForDispatchingToGecko() {
|
||||||
|
return mStateHolder.isReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapForJNI(dispatchTo = "gecko") @Override // JNIObject
|
@WrapForJNI(dispatchTo = "gecko") @Override // JNIObject
|
||||||
|
@ -228,7 +239,7 @@ public final class EventDispatcher extends JNIObject {
|
||||||
public void dispatch(final String type, final GeckoBundle message,
|
public void dispatch(final String type, final GeckoBundle message,
|
||||||
final EventCallback callback) {
|
final EventCallback callback) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mAttachedToGecko && hasGeckoListener(type)) {
|
if (isReadyForDispatchingToGecko() && hasGeckoListener(type)) {
|
||||||
dispatchToGecko(type, message, JavaCallbackDelegate.wrap(callback));
|
dispatchToGecko(type, message, JavaCallbackDelegate.wrap(callback));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -279,14 +290,17 @@ public final class EventDispatcher extends JNIObject {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GeckoThread.isRunning()) {
|
if (!isReadyForDispatchingToGecko()) {
|
||||||
// Usually, we discard an event if there is no listeners for it by the time of
|
// Usually, we discard an event if there is no listeners for it by
|
||||||
// the dispatch. However, if Gecko is not ready and there is no listener for
|
// the time of the dispatch. However, if Gecko(View) is not ready and
|
||||||
// this event that's possibly headed to Gecko, we make a special exception to
|
// there is no listener for this event that's possibly headed to
|
||||||
// queue this event until Gecko is ready. This way, Gecko can first register
|
// Gecko, we make a special exception to queue this event until
|
||||||
// its listeners, and accept the event when it is ready.
|
// Gecko(View) is ready. This way, Gecko can first register its
|
||||||
GeckoThread.queueNativeCall(this, "dispatchToGecko",
|
// listeners, and accept the event when it is ready.
|
||||||
String.class, type, GeckoBundle.class, message,
|
NativeQueue.queueUntil(mStateHolder,
|
||||||
|
mStateHolder.getReadyState(), this, "dispatchToGecko",
|
||||||
|
String.class, type,
|
||||||
|
GeckoBundle.class, message,
|
||||||
EventCallback.class, JavaCallbackDelegate.wrap(callback));
|
EventCallback.class, JavaCallbackDelegate.wrap(callback));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,10 @@ package org.mozilla.gecko;
|
||||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||||
|
import org.mozilla.gecko.NativeQueue.StateHolder;
|
||||||
import org.mozilla.gecko.util.FileUtils;
|
import org.mozilla.gecko.util.FileUtils;
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
@ -28,19 +26,14 @@ import android.util.Log;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
public class GeckoThread extends Thread {
|
public class GeckoThread extends Thread {
|
||||||
private static final String LOGTAG = "GeckoThread";
|
private static final String LOGTAG = "GeckoThread";
|
||||||
|
|
||||||
public enum State {
|
public enum State implements NativeQueue.State {
|
||||||
// After being loaded by class loader.
|
// After being loaded by class loader.
|
||||||
@WrapForJNI INITIAL(0),
|
@WrapForJNI INITIAL(0),
|
||||||
// After launching Gecko thread
|
// After launching Gecko thread
|
||||||
|
@ -73,47 +66,30 @@ public class GeckoThread extends Thread {
|
||||||
this.rank = rank;
|
this.rank = rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean is(final State other) {
|
@Override
|
||||||
|
public boolean is(final NativeQueue.State other) {
|
||||||
return this == other;
|
return this == other;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAtLeast(final State other) {
|
@Override
|
||||||
return this.rank >= other.rank;
|
public boolean isAtLeast(final NativeQueue.State other) {
|
||||||
|
if (other instanceof State) {
|
||||||
|
return this.rank >= ((State) other).rank;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAtMost(final State other) {
|
private static final StateHolder sStateHolder =
|
||||||
return this.rank <= other.rank;
|
new StateHolder(State.INITIAL, State.RUNNING);
|
||||||
}
|
|
||||||
|
|
||||||
// Inclusive
|
/* package */ static StateHolder getStateHolder() {
|
||||||
public boolean isBetween(final State min, final State max) {
|
return sStateHolder;
|
||||||
return this.rank >= min.rank && this.rank <= max.rank;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final State MIN_STATE = State.INITIAL;
|
public static final State MIN_STATE = State.INITIAL;
|
||||||
public static final State MAX_STATE = State.EXITED;
|
public static final State MAX_STATE = State.EXITED;
|
||||||
|
|
||||||
private static volatile State sState = State.INITIAL;
|
|
||||||
|
|
||||||
private static class QueuedCall {
|
|
||||||
public Method method;
|
|
||||||
public Object target;
|
|
||||||
public Object[] args;
|
|
||||||
public State state;
|
|
||||||
|
|
||||||
public QueuedCall(final Method method, final Object target,
|
|
||||||
final Object[] args, final State state) {
|
|
||||||
this.method = method;
|
|
||||||
this.target = target;
|
|
||||||
this.args = args;
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int QUEUED_CALLS_COUNT = 16;
|
|
||||||
private static final ArrayList<QueuedCall> QUEUED_CALLS = new ArrayList<>(QUEUED_CALLS_COUNT);
|
|
||||||
|
|
||||||
private static final Runnable UI_THREAD_CALLBACK = new Runnable() {
|
private static final Runnable UI_THREAD_CALLBACK = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -259,153 +235,6 @@ public class GeckoThread extends Thread {
|
||||||
return isState(State.RUNNING);
|
return isState(State.RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the given Method and handle checked Exceptions.
|
|
||||||
private static void invokeMethod(final Method method, final Object obj, final Object[] args) {
|
|
||||||
try {
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(obj, args);
|
|
||||||
} catch (final IllegalAccessException e) {
|
|
||||||
throw new IllegalStateException("Unexpected exception", e);
|
|
||||||
} catch (final InvocationTargetException e) {
|
|
||||||
throw new UnsupportedOperationException("Cannot make call", e.getCause());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue a call to the given method.
|
|
||||||
private static void queueNativeCallLocked(final Class<?> cls, final String methodName,
|
|
||||||
final Object obj, final Object[] args,
|
|
||||||
final State state) {
|
|
||||||
final ArrayList<Class<?>> argTypes = new ArrayList<>(args.length);
|
|
||||||
final ArrayList<Object> argValues = new ArrayList<>(args.length);
|
|
||||||
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
if (args[i] instanceof Class) {
|
|
||||||
argTypes.add((Class<?>) args[i]);
|
|
||||||
argValues.add(args[++i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Class<?> argType = args[i].getClass();
|
|
||||||
if (argType == Boolean.class) argType = Boolean.TYPE;
|
|
||||||
else if (argType == Byte.class) argType = Byte.TYPE;
|
|
||||||
else if (argType == Character.class) argType = Character.TYPE;
|
|
||||||
else if (argType == Double.class) argType = Double.TYPE;
|
|
||||||
else if (argType == Float.class) argType = Float.TYPE;
|
|
||||||
else if (argType == Integer.class) argType = Integer.TYPE;
|
|
||||||
else if (argType == Long.class) argType = Long.TYPE;
|
|
||||||
else if (argType == Short.class) argType = Short.TYPE;
|
|
||||||
argTypes.add(argType);
|
|
||||||
argValues.add(args[i]);
|
|
||||||
}
|
|
||||||
final Method method;
|
|
||||||
try {
|
|
||||||
method = cls.getDeclaredMethod(
|
|
||||||
methodName, argTypes.toArray(new Class<?>[argTypes.size()]));
|
|
||||||
} catch (final NoSuchMethodException e) {
|
|
||||||
throw new IllegalArgumentException("Cannot find method", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Modifier.isNative(method.getModifiers())) {
|
|
||||||
// As a precaution, we disallow queuing non-native methods. Queuing non-native
|
|
||||||
// methods is dangerous because the method could end up being called on either
|
|
||||||
// the original thread or the Gecko thread depending on timing. Native methods
|
|
||||||
// usually handle this by posting an event to the Gecko thread automatically,
|
|
||||||
// but there is no automatic mechanism for non-native methods.
|
|
||||||
throw new UnsupportedOperationException("Not allowed to queue non-native methods");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isStateAtLeast(state)) {
|
|
||||||
invokeMethod(method, obj, argValues.toArray());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QUEUED_CALLS.add(new QueuedCall(
|
|
||||||
method, obj, argValues.toArray(), state));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue a call to the given static method until Gecko is in the given state.
|
|
||||||
*
|
|
||||||
* @param state The Gecko state in which the native call could be executed.
|
|
||||||
* Default is State.RUNNING, which means this queued call will
|
|
||||||
* run when Gecko is at or after RUNNING state.
|
|
||||||
* @param cls Class that declares the static method.
|
|
||||||
* @param methodName Name of the static method.
|
|
||||||
* @param args Args to call the static method with; to specify a parameter type,
|
|
||||||
* pass in a Class instance first, followed by the value.
|
|
||||||
*/
|
|
||||||
public static void queueNativeCallUntil(final State state, final Class<?> cls,
|
|
||||||
final String methodName, final Object... args) {
|
|
||||||
synchronized (QUEUED_CALLS) {
|
|
||||||
queueNativeCallLocked(cls, methodName, null, args, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue a call to the given static method until Gecko is in the RUNNING state.
|
|
||||||
*/
|
|
||||||
public static void queueNativeCall(final Class<?> cls, final String methodName,
|
|
||||||
final Object... args) {
|
|
||||||
synchronized (QUEUED_CALLS) {
|
|
||||||
queueNativeCallLocked(cls, methodName, null, args, State.RUNNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue a call to the given instance method until Gecko is in the given state.
|
|
||||||
*
|
|
||||||
* @param state The Gecko state in which the native call could be executed.
|
|
||||||
* @param obj Object that declares the instance method.
|
|
||||||
* @param methodName Name of the instance method.
|
|
||||||
* @param args Args to call the instance method with; to specify a parameter type,
|
|
||||||
* pass in a Class instance first, followed by the value.
|
|
||||||
*/
|
|
||||||
public static void queueNativeCallUntil(final State state, final Object obj,
|
|
||||||
final String methodName, final Object... args) {
|
|
||||||
synchronized (QUEUED_CALLS) {
|
|
||||||
queueNativeCallLocked(obj.getClass(), methodName, obj, args, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue a call to the given instance method until Gecko is in the RUNNING state.
|
|
||||||
*/
|
|
||||||
public static void queueNativeCall(final Object obj, final String methodName,
|
|
||||||
final Object... args) {
|
|
||||||
synchronized (QUEUED_CALLS) {
|
|
||||||
queueNativeCallLocked(obj.getClass(), methodName, obj, args, State.RUNNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run all queued methods
|
|
||||||
private static void flushQueuedNativeCallsLocked(final State state) {
|
|
||||||
int lastSkipped = -1;
|
|
||||||
for (int i = 0; i < QUEUED_CALLS.size(); i++) {
|
|
||||||
final QueuedCall call = QUEUED_CALLS.get(i);
|
|
||||||
if (call == null) {
|
|
||||||
// We already handled the call.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!state.isAtLeast(call.state)) {
|
|
||||||
// The call is not ready yet; skip it.
|
|
||||||
lastSkipped = i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Mark as handled.
|
|
||||||
QUEUED_CALLS.set(i, null);
|
|
||||||
|
|
||||||
invokeMethod(call.method, call.target, call.args);
|
|
||||||
}
|
|
||||||
if (lastSkipped < 0) {
|
|
||||||
// We're done here; release the memory
|
|
||||||
QUEUED_CALLS.clear();
|
|
||||||
QUEUED_CALLS.trimToSize();
|
|
||||||
} else if (lastSkipped < QUEUED_CALLS.size() - 1) {
|
|
||||||
// We skipped some; free up null entries at the end,
|
|
||||||
// but keep all the previous entries for later.
|
|
||||||
QUEUED_CALLS.subList(lastSkipped + 1, QUEUED_CALLS.size()).clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadGeckoLibs(final Context context, final String resourcePath) {
|
private static void loadGeckoLibs(final Context context, final String resourcePath) {
|
||||||
GeckoLoader.loadSQLiteLibs(context, resourcePath);
|
GeckoLoader.loadSQLiteLibs(context, resourcePath);
|
||||||
GeckoLoader.loadNSSLibs(context, resourcePath);
|
GeckoLoader.loadNSSLibs(context, resourcePath);
|
||||||
|
@ -617,7 +446,7 @@ public class GeckoThread extends Thread {
|
||||||
* @return True if the current Gecko thread state matches
|
* @return True if the current Gecko thread state matches
|
||||||
*/
|
*/
|
||||||
public static boolean isState(final State state) {
|
public static boolean isState(final State state) {
|
||||||
return sState.is(state);
|
return sStateHolder.getState().is(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -628,7 +457,7 @@ public class GeckoThread extends Thread {
|
||||||
* @return True if the current Gecko thread state matches
|
* @return True if the current Gecko thread state matches
|
||||||
*/
|
*/
|
||||||
public static boolean isStateAtLeast(final State state) {
|
public static boolean isStateAtLeast(final State state) {
|
||||||
return sState.isAtLeast(state);
|
return sStateHolder.getState().isAtLeast(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -639,7 +468,7 @@ public class GeckoThread extends Thread {
|
||||||
* @return True if the current Gecko thread state matches
|
* @return True if the current Gecko thread state matches
|
||||||
*/
|
*/
|
||||||
public static boolean isStateAtMost(final State state) {
|
public static boolean isStateAtMost(final State state) {
|
||||||
return sState.isAtMost(state);
|
return state.isAtLeast(sStateHolder.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -651,28 +480,18 @@ public class GeckoThread extends Thread {
|
||||||
* @return True if the current Gecko thread state matches
|
* @return True if the current Gecko thread state matches
|
||||||
*/
|
*/
|
||||||
public static boolean isStateBetween(final State minState, final State maxState) {
|
public static boolean isStateBetween(final State minState, final State maxState) {
|
||||||
return sState.isBetween(minState, maxState);
|
return isStateAtLeast(minState) && isStateAtMost(maxState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
@WrapForJNI(calledFrom = "gecko")
|
||||||
private static void setState(final State newState) {
|
private static void setState(final State newState) {
|
||||||
ThreadUtils.assertOnGeckoThread();
|
sStateHolder.setState(newState);
|
||||||
synchronized (QUEUED_CALLS) {
|
|
||||||
flushQueuedNativeCallsLocked(newState);
|
|
||||||
sState = newState;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
@WrapForJNI(calledFrom = "gecko")
|
||||||
private static boolean checkAndSetState(final State currentState, final State newState) {
|
private static boolean checkAndSetState(final State expectedState,
|
||||||
synchronized (QUEUED_CALLS) {
|
final State newState) {
|
||||||
if (sState == currentState) {
|
return sStateHolder.checkAndSetState(expectedState, newState);
|
||||||
flushQueuedNativeCallsLocked(newState);
|
|
||||||
sState = newState;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapForJNI(stubName = "SpeculativeConnect")
|
@WrapForJNI(stubName = "SpeculativeConnect")
|
||||||
|
@ -736,4 +555,36 @@ public class GeckoThread extends Thread {
|
||||||
private static void requestUiThreadCallback(long delay) {
|
private static void requestUiThreadCallback(long delay) {
|
||||||
ThreadUtils.getUiHandler().postDelayed(UI_THREAD_CALLBACK, delay);
|
ThreadUtils.getUiHandler().postDelayed(UI_THREAD_CALLBACK, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given static method until Gecko is in the RUNNING state.
|
||||||
|
*/
|
||||||
|
public static void queueNativeCall(final Class<?> cls, final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, cls, methodName, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given instance method until Gecko is in the RUNNING state.
|
||||||
|
*/
|
||||||
|
public static void queueNativeCall(final Object obj, final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, obj, methodName, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given instance method until Gecko is in the RUNNING state.
|
||||||
|
*/
|
||||||
|
public static void queueNativeCallUntil(final State state, final Object obj, final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
NativeQueue.queueUntil(getStateHolder(), state, obj, methodName, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given static method until Gecko is in the RUNNING state.
|
||||||
|
*/
|
||||||
|
public static void queueNativeCallUntil(final State state, final Class<?> cls, final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
NativeQueue.queueUntil(getStateHolder(), state, cls, methodName, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.mozilla.gecko.annotation.ReflectionTarget;
|
||||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||||
import org.mozilla.gecko.gfx.LayerView;
|
import org.mozilla.gecko.gfx.LayerView;
|
||||||
import org.mozilla.gecko.mozglue.JNIObject;
|
import org.mozilla.gecko.mozglue.JNIObject;
|
||||||
|
import org.mozilla.gecko.NativeQueue.StateHolder;
|
||||||
import org.mozilla.gecko.util.BundleEventListener;
|
import org.mozilla.gecko.util.BundleEventListener;
|
||||||
import org.mozilla.gecko.util.EventCallback;
|
import org.mozilla.gecko.util.EventCallback;
|
||||||
import org.mozilla.gecko.util.GeckoBundle;
|
import org.mozilla.gecko.util.GeckoBundle;
|
||||||
|
@ -41,7 +42,40 @@ public class GeckoView extends LayerView
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private final EventDispatcher mEventDispatcher = new EventDispatcher();
|
/* package */ enum State implements NativeQueue.State {
|
||||||
|
@WrapForJNI INITIAL(0),
|
||||||
|
@WrapForJNI READY(1);
|
||||||
|
|
||||||
|
private int rank;
|
||||||
|
|
||||||
|
private State(int rank) {
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean is(final NativeQueue.State other) {
|
||||||
|
return this == other;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAtLeast(final NativeQueue.State other) {
|
||||||
|
if (other instanceof State) {
|
||||||
|
return this.rank >= ((State) other).rank;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final StateHolder mStateHolder =
|
||||||
|
new StateHolder(State.INITIAL, State.READY);
|
||||||
|
|
||||||
|
@WrapForJNI(calledFrom = "gecko")
|
||||||
|
private void setState(final State newState) {
|
||||||
|
mStateHolder.setState(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final EventDispatcher mEventDispatcher =
|
||||||
|
new EventDispatcher(mStateHolder);
|
||||||
|
|
||||||
private ChromeDelegate mChromeDelegate;
|
private ChromeDelegate mChromeDelegate;
|
||||||
/* package */ ContentListener mContentListener;
|
/* package */ ContentListener mContentListener;
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||||
|
* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class NativeQueue {
|
||||||
|
private static final String LOGTAG = "GeckoNativeQueue";
|
||||||
|
|
||||||
|
public interface State {
|
||||||
|
boolean is(final State other);
|
||||||
|
boolean isAtLeast(final State other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StateHolder {
|
||||||
|
private volatile State mState;
|
||||||
|
private final State mReadyState;
|
||||||
|
|
||||||
|
public StateHolder(final State initial, final State ready) {
|
||||||
|
this.mState = initial;
|
||||||
|
this.mReadyState = ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReady() {
|
||||||
|
return getState().isAtLeast(mReadyState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getReadyState() {
|
||||||
|
return mReadyState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setState(final State newState) {
|
||||||
|
return checkAndSetState(null, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkAndSetState(final State expectedState,
|
||||||
|
final State newState) {
|
||||||
|
synchronized (NativeQueue.sQueue) {
|
||||||
|
if (expectedState != null && !mState.is(expectedState)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NativeQueue.flushQueuedLocked(newState);
|
||||||
|
mState = newState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class QueuedCall {
|
||||||
|
public Method method;
|
||||||
|
public Object target;
|
||||||
|
public Object[] args;
|
||||||
|
public State state;
|
||||||
|
|
||||||
|
public QueuedCall(final Method method, final Object target,
|
||||||
|
final Object[] args, final State state) {
|
||||||
|
this.method = method;
|
||||||
|
this.target = target;
|
||||||
|
this.args = args;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int QUEUED_CALLS_COUNT = 16;
|
||||||
|
/* package */ static final ArrayList<QueuedCall> sQueue =
|
||||||
|
new ArrayList<>(QUEUED_CALLS_COUNT);
|
||||||
|
|
||||||
|
// Invoke the given Method and handle checked Exceptions.
|
||||||
|
private static void invokeMethod(final Method method, final Object obj,
|
||||||
|
final Object[] args) {
|
||||||
|
try {
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(obj, args);
|
||||||
|
} catch (final IllegalAccessException e) {
|
||||||
|
throw new IllegalStateException("Unexpected exception", e);
|
||||||
|
} catch (final InvocationTargetException e) {
|
||||||
|
throw new UnsupportedOperationException("Cannot make call", e.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue a call to the given method.
|
||||||
|
private static void queueNativeCallLocked(final StateHolder stateHolder,
|
||||||
|
final Class<?> cls,
|
||||||
|
final String methodName,
|
||||||
|
final Object obj,
|
||||||
|
final Object[] args,
|
||||||
|
final State state) {
|
||||||
|
final ArrayList<Class<?>> argTypes = new ArrayList<>(args.length);
|
||||||
|
final ArrayList<Object> argValues = new ArrayList<>(args.length);
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] instanceof Class) {
|
||||||
|
argTypes.add((Class<?>) args[i]);
|
||||||
|
argValues.add(args[++i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Class<?> argType = args[i].getClass();
|
||||||
|
if (argType == Boolean.class) argType = Boolean.TYPE;
|
||||||
|
else if (argType == Byte.class) argType = Byte.TYPE;
|
||||||
|
else if (argType == Character.class) argType = Character.TYPE;
|
||||||
|
else if (argType == Double.class) argType = Double.TYPE;
|
||||||
|
else if (argType == Float.class) argType = Float.TYPE;
|
||||||
|
else if (argType == Integer.class) argType = Integer.TYPE;
|
||||||
|
else if (argType == Long.class) argType = Long.TYPE;
|
||||||
|
else if (argType == Short.class) argType = Short.TYPE;
|
||||||
|
argTypes.add(argType);
|
||||||
|
argValues.add(args[i]);
|
||||||
|
}
|
||||||
|
final Method method;
|
||||||
|
try {
|
||||||
|
method = cls.getDeclaredMethod(
|
||||||
|
methodName, argTypes.toArray(new Class<?>[argTypes.size()]));
|
||||||
|
} catch (final NoSuchMethodException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot find method", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Modifier.isNative(method.getModifiers())) {
|
||||||
|
// As a precaution, we disallow queuing non-native methods. Queuing non-native
|
||||||
|
// methods is dangerous because the method could end up being called on either
|
||||||
|
// the original thread or the Gecko thread depending on timing. Native methods
|
||||||
|
// usually handle this by posting an event to the Gecko thread automatically,
|
||||||
|
// but there is no automatic mechanism for non-native methods.
|
||||||
|
throw new UnsupportedOperationException("Not allowed to queue non-native methods");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateHolder.getState().isAtLeast(state)) {
|
||||||
|
invokeMethod(method, obj, argValues.toArray());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sQueue.add(new QueuedCall(
|
||||||
|
method, obj, argValues.toArray(), state));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given instance method if the given current state does
|
||||||
|
* not satisfy the given state.
|
||||||
|
*
|
||||||
|
* @param stateHolder The state holder used to query the current state.
|
||||||
|
* @param state The state in which the native call could be executed.
|
||||||
|
* @param obj Object that declares the instance method.
|
||||||
|
* @param methodName Name of the instance method.
|
||||||
|
* @param args Args to call the instance method with; to specify a parameter
|
||||||
|
* type, pass in a Class instance first, followed by the value.
|
||||||
|
*/
|
||||||
|
public static void queueUntil(final StateHolder stateHolder,
|
||||||
|
final State state,
|
||||||
|
final Object obj,
|
||||||
|
final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
synchronized (sQueue) {
|
||||||
|
queueNativeCallLocked(stateHolder, obj.getClass(), methodName, obj,
|
||||||
|
args, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a call to the given static method if the given current state does
|
||||||
|
* not satisfy the given state.
|
||||||
|
*
|
||||||
|
* @param stateHolder The state holder used to query the current state.
|
||||||
|
* @param state The state in which the native call could be executed.
|
||||||
|
* @param cls Class that declares the static method.
|
||||||
|
* @param methodName Name of the instance method.
|
||||||
|
* @param args Args to call the instance method with; to specify a parameter
|
||||||
|
* type, pass in a Class instance first, followed by the value.
|
||||||
|
*/
|
||||||
|
public static void queueUntil(final StateHolder stateHolder,
|
||||||
|
final State state,
|
||||||
|
final Class<?> cls,
|
||||||
|
final String methodName,
|
||||||
|
final Object... args) {
|
||||||
|
synchronized (sQueue) {
|
||||||
|
queueNativeCallLocked(stateHolder, cls, methodName, null, args, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run all queued methods
|
||||||
|
private static void flushQueuedLocked(final State state) {
|
||||||
|
int lastSkipped = -1;
|
||||||
|
for (int i = 0; i < sQueue.size(); i++) {
|
||||||
|
final QueuedCall call = sQueue.get(i);
|
||||||
|
if (call == null) {
|
||||||
|
// We already handled the call.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!state.isAtLeast(call.state)) {
|
||||||
|
// The call is not ready yet; skip it.
|
||||||
|
lastSkipped = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Mark as handled.
|
||||||
|
sQueue.set(i, null);
|
||||||
|
|
||||||
|
invokeMethod(call.method, call.target, call.args);
|
||||||
|
}
|
||||||
|
if (lastSkipped < 0) {
|
||||||
|
// We're done here; release the memory
|
||||||
|
sQueue.clear();
|
||||||
|
sQueue.trimToSize();
|
||||||
|
} else if (lastSkipped < sQueue.size() - 1) {
|
||||||
|
// We skipped some; free up null entries at the end,
|
||||||
|
// but keep all the previous entries for later.
|
||||||
|
sQueue.subList(lastSkipped + 1, sQueue.size()).clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2163,6 +2163,7 @@ nsHttpTransaction::Do0RTT()
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpTransaction::Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */)
|
nsHttpTransaction::Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */)
|
||||||
{
|
{
|
||||||
|
LOG(("nsHttpTransaction::Finish0RTT %p %d %d\n", this, aRestart, aAlpnChanged));
|
||||||
MOZ_ASSERT(m0RTTInProgress);
|
MOZ_ASSERT(m0RTTInProgress);
|
||||||
m0RTTInProgress = false;
|
m0RTTInProgress = false;
|
||||||
if (aRestart) {
|
if (aRestart) {
|
||||||
|
@ -2174,6 +2175,10 @@ nsHttpTransaction::Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */)
|
||||||
} else {
|
} else {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
} else if (!mConnected) {
|
||||||
|
// this is code that was skipped in ::ReadSegments while in 0RTT
|
||||||
|
mConnected = true;
|
||||||
|
mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -899,6 +899,8 @@ class TestInfoCommand(MachCommandBase):
|
||||||
@CommandArgument('--end',
|
@CommandArgument('--end',
|
||||||
default=date.today().strftime("%Y-%m-%d"),
|
default=date.today().strftime("%Y-%m-%d"),
|
||||||
help='End date (YYYY-MM-DD)')
|
help='End date (YYYY-MM-DD)')
|
||||||
|
@CommandArgument('--verbose', action='store_true',
|
||||||
|
help='Enable debug logging.')
|
||||||
|
|
||||||
def test_info(self, **params):
|
def test_info(self, **params):
|
||||||
|
|
||||||
|
@ -909,6 +911,7 @@ class TestInfoCommand(MachCommandBase):
|
||||||
self.branches = params['branches']
|
self.branches = params['branches']
|
||||||
self.start = params['start']
|
self.start = params['start']
|
||||||
self.end = params['end']
|
self.end = params['end']
|
||||||
|
self.verbose = params['verbose']
|
||||||
|
|
||||||
if len(self.test_name) < 6:
|
if len(self.test_name) < 6:
|
||||||
print("'%s' is too short for a test name!" % self.test_name)
|
print("'%s' is too short for a test name!" % self.test_name)
|
||||||
|
@ -1055,9 +1058,16 @@ class TestInfoCommand(MachCommandBase):
|
||||||
|
|
||||||
def submit(self, query):
|
def submit(self, query):
|
||||||
import requests
|
import requests
|
||||||
|
import datetime
|
||||||
|
if self.verbose:
|
||||||
|
print(datetime.datetime.now())
|
||||||
|
print(json.dumps(query))
|
||||||
response = requests.post("http://activedata.allizom.org/query",
|
response = requests.post("http://activedata.allizom.org/query",
|
||||||
data=json.dumps(query),
|
data=json.dumps(query),
|
||||||
stream=True)
|
stream=True)
|
||||||
|
if self.verbose:
|
||||||
|
print(datetime.datetime.now())
|
||||||
|
print(response)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
data = response.json()["data"]
|
data = response.json()["data"]
|
||||||
return data
|
return data
|
||||||
|
@ -1092,12 +1102,29 @@ class TestInfoCommand(MachCommandBase):
|
||||||
data = self.submit(query)
|
data = self.submit(query)
|
||||||
if data and len(data) > 0:
|
if data and len(data) > 0:
|
||||||
data.sort(key=self.get_platform)
|
data.sort(key=self.get_platform)
|
||||||
|
worst_rate = 0.0
|
||||||
|
worst_platform = None
|
||||||
|
total_runs = 0
|
||||||
|
total_failures = 0
|
||||||
for record in data:
|
for record in data:
|
||||||
platform = self.get_platform(record)
|
platform = self.get_platform(record)
|
||||||
runs = record['count']
|
runs = record['count']
|
||||||
|
total_runs = total_runs + runs
|
||||||
failures = record['failures']
|
failures = record['failures']
|
||||||
|
total_failures = total_failures + failures
|
||||||
|
rate = (float)(failures) / runs
|
||||||
|
if rate >= worst_rate:
|
||||||
|
worst_rate = rate
|
||||||
|
worst_platform = platform
|
||||||
|
worst_failures = failures
|
||||||
|
worst_runs = runs
|
||||||
print("%-30s %6d failures in %6d runs" % (
|
print("%-30s %6d failures in %6d runs" % (
|
||||||
platform, failures, runs))
|
platform, failures, runs))
|
||||||
|
print("\nTotal: %d failures in %d runs or %.3f failures/run" %
|
||||||
|
(total_failures, total_runs, (float)(total_failures) / total_runs))
|
||||||
|
if worst_failures > 0:
|
||||||
|
print("Worst rate on %s %d failures in %d runs or %.3f failures/run" %
|
||||||
|
(worst_platform, worst_failures, worst_runs, worst_rate))
|
||||||
else:
|
else:
|
||||||
print("No test result data found.")
|
print("No test result data found.")
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ addTest(function(exception_t) {
|
||||||
if (Reflect.setPrototypeOf) {
|
if (Reflect.setPrototypeOf) {
|
||||||
assert_false(Reflect.setPrototypeOf(C, new Object()),
|
assert_false(Reflect.setPrototypeOf(C, new Object()),
|
||||||
"Reflect.setPrototypeOf on cross-origin Window");
|
"Reflect.setPrototypeOf on cross-origin Window");
|
||||||
assert_false(Reflect.setPrototypeOf(C, new Object()),
|
assert_false(Reflect.setPrototypeOf(C.location, new Object()),
|
||||||
"Reflect.setPrototypeOf on cross-origin Location");
|
"Reflect.setPrototypeOf on cross-origin Location");
|
||||||
}
|
}
|
||||||
}, "[[SetPrototypeOf]] should return false");
|
}, "[[SetPrototypeOf]] should return false");
|
||||||
|
|
|
@ -267,6 +267,7 @@ fail-if = os == "android"
|
||||||
fail-if = os == "android"
|
fail-if = os == "android"
|
||||||
[test_types.js]
|
[test_types.js]
|
||||||
[test_undothemeuninstall.js]
|
[test_undothemeuninstall.js]
|
||||||
|
skip-if = appname == "thunderbird"
|
||||||
[test_undouninstall.js]
|
[test_undouninstall.js]
|
||||||
[test_uninstall.js]
|
[test_uninstall.js]
|
||||||
[test_update.js]
|
[test_update.js]
|
||||||
|
|
|
@ -11,98 +11,76 @@ tags = appupdate
|
||||||
head = head_update.js
|
head = head_update.js
|
||||||
|
|
||||||
[marSuccessComplete.js]
|
[marSuccessComplete.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marSuccessPartial.js]
|
[marSuccessPartial.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marFailurePartial.js]
|
[marFailurePartial.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marStageSuccessComplete.js]
|
[marStageSuccessComplete.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marStageSuccessPartial.js]
|
[marStageSuccessPartial.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marVersionDowngrade.js]
|
[marVersionDowngrade.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985 and mar signing
|
|
||||||
[marWrongChannel.js]
|
[marWrongChannel.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985 and mar signing
|
|
||||||
[marStageFailurePartial.js]
|
[marStageFailurePartial.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
[marCallbackAppSuccessComplete_win.js]
|
[marCallbackAppSuccessComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marCallbackAppSuccessPartial_win.js]
|
[marCallbackAppSuccessPartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marCallbackAppStageSuccessComplete_win.js]
|
[marCallbackAppStageSuccessComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marCallbackAppStageSuccessPartial_win.js]
|
[marCallbackAppStageSuccessPartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marAppInUseSuccessComplete.js]
|
[marAppInUseSuccessComplete.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985 and bug 1164150
|
|
||||||
[marAppInUseStageSuccessComplete_unix.js]
|
[marAppInUseStageSuccessComplete_unix.js]
|
||||||
skip-if = os == 'win'
|
skip-if = os == 'win'
|
||||||
reason = not a Windows test and bug 1164150
|
reason = not a Windows test
|
||||||
[marAppInUseStageFailureComplete_win.js]
|
[marAppInUseStageFailureComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileLockedFailureComplete_win.js]
|
[marFileLockedFailureComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileLockedFailurePartial_win.js]
|
[marFileLockedFailurePartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileLockedStageFailureComplete_win.js]
|
[marFileLockedStageFailureComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileLockedStageFailurePartial_win.js]
|
[marFileLockedStageFailurePartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileInUseSuccessComplete_win.js]
|
[marFileInUseSuccessComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileInUseSuccessPartial_win.js]
|
[marFileInUseSuccessPartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marRMRFDirFileInUseSuccessComplete_win.js]
|
[marRMRFDirFileInUseSuccessComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marRMRFDirFileInUseSuccessPartial_win.js]
|
[marRMRFDirFileInUseSuccessPartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileInUseStageFailureComplete_win.js]
|
[marFileInUseStageFailureComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marFileInUseStageFailurePartial_win.js]
|
[marFileInUseStageFailurePartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marRMRFDirFileInUseStageFailureComplete_win.js]
|
[marRMRFDirFileInUseStageFailureComplete_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marRMRFDirFileInUseStageFailurePartial_win.js]
|
[marRMRFDirFileInUseStageFailurePartial_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marAppApplyDirLockedStageFailure_win.js]
|
[marAppApplyDirLockedStageFailure_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marAppApplyUpdateAppBinInUseStageSuccess_win.js]
|
[marAppApplyUpdateAppBinInUseStageSuccess_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
[marAppApplyUpdateSuccess.js]
|
[marAppApplyUpdateSuccess.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985 and bug 1164150
|
|
||||||
[marAppApplyUpdateStageSuccess.js]
|
[marAppApplyUpdateStageSuccess.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985 and bug 1164150
|
|
||||||
[marWrongApplyToDirFailure_win.js]
|
[marWrongApplyToDirFailure_win.js]
|
||||||
skip-if = os != 'win' || debug && (os_version == '5.1' || os_version == '5.2')
|
skip-if = os != 'win'
|
||||||
reason = Windows only test and bug 1291985
|
reason = Windows only test
|
||||||
|
|
|
@ -9,119 +9,61 @@ tags = appupdate
|
||||||
head = head_update.js
|
head = head_update.js
|
||||||
|
|
||||||
[bootstrapSvc.js]
|
[bootstrapSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marSuccessCompleteSvc.js]
|
[marSuccessCompleteSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marSuccessPartialSvc.js]
|
[marSuccessPartialSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFailurePartialSvc.js]
|
[marFailurePartialSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marStageSuccessCompleteSvc.js]
|
[marStageSuccessCompleteSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marStageSuccessPartialSvc.js]
|
[marStageSuccessPartialSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marStageFailurePartialSvc.js]
|
[marStageFailurePartialSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marCallbackAppSuccessCompleteSvc_win.js]
|
[marCallbackAppSuccessCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marCallbackAppSuccessPartialSvc_win.js]
|
[marCallbackAppSuccessPartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marCallbackAppStageSuccessCompleteSvc_win.js]
|
[marCallbackAppStageSuccessCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marCallbackAppStageSuccessPartialSvc_win.js]
|
[marCallbackAppStageSuccessPartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppInUseSuccessCompleteSvc.js]
|
[marAppInUseSuccessCompleteSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppInUseStageFailureCompleteSvc_win.js]
|
[marAppInUseStageFailureCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileLockedFailureCompleteSvc_win.js]
|
[marFileLockedFailureCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileLockedFailurePartialSvc_win.js]
|
[marFileLockedFailurePartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileLockedStageFailureCompleteSvc_win.js]
|
[marFileLockedStageFailureCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileLockedStageFailurePartialSvc_win.js]
|
[marFileLockedStageFailurePartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileInUseSuccessCompleteSvc_win.js]
|
[marFileInUseSuccessCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileInUseSuccessPartialSvc_win.js]
|
[marFileInUseSuccessPartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marRMRFDirFileInUseSuccessCompleteSvc_win.js]
|
[marRMRFDirFileInUseSuccessCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marRMRFDirFileInUseSuccessPartialSvc_win.js]
|
[marRMRFDirFileInUseSuccessPartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileInUseStageFailureCompleteSvc_win.js]
|
[marFileInUseStageFailureCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marFileInUseStageFailurePartialSvc_win.js]
|
[marFileInUseStageFailurePartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marRMRFDirFileInUseStageFailureCompleteSvc_win.js]
|
[marRMRFDirFileInUseStageFailureCompleteSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marRMRFDirFileInUseStageFailurePartialSvc_win.js]
|
[marRMRFDirFileInUseStageFailurePartialSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppApplyDirLockedStageFailureSvc_win.js]
|
[marAppApplyDirLockedStageFailureSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js]
|
[marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppApplyUpdateSuccessSvc.js]
|
[marAppApplyUpdateSuccessSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[marAppApplyUpdateStageSuccessSvc.js]
|
[marAppApplyUpdateStageSuccessSvc.js]
|
||||||
skip-if = os == 'win' && debug && (os_version == '5.1' || os_version == '5.2')
|
|
||||||
reason = bug 1291985
|
|
||||||
run-sequentially = Uses the Mozilla Maintenance Service.
|
run-sequentially = Uses the Mozilla Maintenance Service.
|
||||||
[checkUpdaterSigSvc.js]
|
[checkUpdaterSigSvc.js]
|
||||||
|
|
|
@ -434,6 +434,8 @@ xul|button[type="menu"] > xul|menupopup xul|menuseparator {
|
||||||
|
|
||||||
/* textboxes */
|
/* textboxes */
|
||||||
|
|
||||||
|
html|input[type="email"],
|
||||||
|
html|input[type="tel"],
|
||||||
html|input[type="text"],
|
html|input[type="text"],
|
||||||
html|textarea,
|
html|textarea,
|
||||||
xul|textbox {
|
xul|textbox {
|
||||||
|
@ -462,6 +464,8 @@ xul|textbox.tree-input {
|
||||||
padding-left: unset;
|
padding-left: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|input[type="email"],
|
||||||
|
html|input[type="tel"],
|
||||||
html|input[type="text"],
|
html|input[type="text"],
|
||||||
html|textarea {
|
html|textarea {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
@ -469,12 +473,16 @@ html|textarea {
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|input[type="email"]:focus,
|
||||||
|
html|input[type="tel"]:focus,
|
||||||
html|input[type="text"]:focus,
|
html|input[type="text"]:focus,
|
||||||
html|textarea:focus,
|
html|textarea:focus,
|
||||||
xul|textbox[focused] {
|
xul|textbox[focused] {
|
||||||
border-color: var(--in-content-border-focus);
|
border-color: var(--in-content-border-focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html|input[type="email"]:disabled,
|
||||||
|
html|input[type="tel"]:disabled,
|
||||||
html|input[type="text"]:disabled,
|
html|input[type="text"]:disabled,
|
||||||
html|textarea:disabled,
|
html|textarea:disabled,
|
||||||
xul|textbox[disabled="true"] {
|
xul|textbox[disabled="true"] {
|
||||||
|
|
|
@ -1000,6 +1000,33 @@ auto GeckoThread::State::RUNNING() -> State::LocalRef
|
||||||
const char GeckoView::name[] =
|
const char GeckoView::name[] =
|
||||||
"org/mozilla/gecko/GeckoView";
|
"org/mozilla/gecko/GeckoView";
|
||||||
|
|
||||||
|
constexpr char GeckoView::SetState_t::name[];
|
||||||
|
constexpr char GeckoView::SetState_t::signature[];
|
||||||
|
|
||||||
|
auto GeckoView::SetState(mozilla::jni::Object::Param a0) const -> void
|
||||||
|
{
|
||||||
|
return mozilla::jni::Method<SetState_t>::Call(GeckoView::mCtx, nullptr, a0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char GeckoView::State::name[] =
|
||||||
|
"org/mozilla/gecko/GeckoView$State";
|
||||||
|
|
||||||
|
constexpr char GeckoView::State::INITIAL_t::name[];
|
||||||
|
constexpr char GeckoView::State::INITIAL_t::signature[];
|
||||||
|
|
||||||
|
auto GeckoView::State::INITIAL() -> State::LocalRef
|
||||||
|
{
|
||||||
|
return mozilla::jni::Field<INITIAL_t>::Get(State::Context(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr char GeckoView::State::READY_t::name[];
|
||||||
|
constexpr char GeckoView::State::READY_t::signature[];
|
||||||
|
|
||||||
|
auto GeckoView::State::READY() -> State::LocalRef
|
||||||
|
{
|
||||||
|
return mozilla::jni::Field<READY_t>::Get(State::Context(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
const char GeckoView::Window::name[] =
|
const char GeckoView::Window::name[] =
|
||||||
"org/mozilla/gecko/GeckoView$Window";
|
"org/mozilla/gecko/GeckoView$Window";
|
||||||
|
|
||||||
|
|
|
@ -2989,14 +2989,85 @@ public:
|
||||||
|
|
||||||
explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {}
|
explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {}
|
||||||
|
|
||||||
|
class State;
|
||||||
class Window;
|
class Window;
|
||||||
|
|
||||||
|
struct SetState_t {
|
||||||
|
typedef GeckoView Owner;
|
||||||
|
typedef void ReturnType;
|
||||||
|
typedef void SetterType;
|
||||||
|
typedef mozilla::jni::Args<
|
||||||
|
mozilla::jni::Object::Param> Args;
|
||||||
|
static constexpr char name[] = "setState";
|
||||||
|
static constexpr char signature[] =
|
||||||
|
"(Lorg/mozilla/gecko/GeckoView$State;)V";
|
||||||
|
static const bool isStatic = false;
|
||||||
|
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||||
|
mozilla::jni::ExceptionMode::ABORT;
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::GECKO;
|
||||||
|
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||||
|
mozilla::jni::DispatchTarget::CURRENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto SetState(mozilla::jni::Object::Param) const -> void;
|
||||||
|
|
||||||
static const int32_t LOAD_DEFAULT = 0;
|
static const int32_t LOAD_DEFAULT = 0;
|
||||||
|
|
||||||
static const int32_t LOAD_NEW_TAB = 1;
|
static const int32_t LOAD_NEW_TAB = 1;
|
||||||
|
|
||||||
static const int32_t LOAD_SWITCH_TAB = 2;
|
static const int32_t LOAD_SWITCH_TAB = 2;
|
||||||
|
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::GECKO;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeckoView::State : public mozilla::jni::ObjectBase<State>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char name[];
|
||||||
|
|
||||||
|
explicit State(const Context& ctx) : ObjectBase<State>(ctx) {}
|
||||||
|
|
||||||
|
struct INITIAL_t {
|
||||||
|
typedef State Owner;
|
||||||
|
typedef State::LocalRef ReturnType;
|
||||||
|
typedef State::Param SetterType;
|
||||||
|
typedef mozilla::jni::Args<> Args;
|
||||||
|
static constexpr char name[] = "INITIAL";
|
||||||
|
static constexpr char signature[] =
|
||||||
|
"Lorg/mozilla/gecko/GeckoView$State;";
|
||||||
|
static const bool isStatic = true;
|
||||||
|
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||||
|
mozilla::jni::ExceptionMode::ABORT;
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::ANY;
|
||||||
|
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||||
|
mozilla::jni::DispatchTarget::CURRENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto INITIAL() -> State::LocalRef;
|
||||||
|
|
||||||
|
struct READY_t {
|
||||||
|
typedef State Owner;
|
||||||
|
typedef State::LocalRef ReturnType;
|
||||||
|
typedef State::Param SetterType;
|
||||||
|
typedef mozilla::jni::Args<> Args;
|
||||||
|
static constexpr char name[] = "READY";
|
||||||
|
static constexpr char signature[] =
|
||||||
|
"Lorg/mozilla/gecko/GeckoView$State;";
|
||||||
|
static const bool isStatic = true;
|
||||||
|
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||||
|
mozilla::jni::ExceptionMode::ABORT;
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::ANY;
|
||||||
|
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||||
|
mozilla::jni::DispatchTarget::CURRENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto READY() -> State::LocalRef;
|
||||||
|
|
||||||
static const mozilla::jni::CallingThread callingThread =
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
mozilla::jni::CallingThread::ANY;
|
mozilla::jni::CallingThread::ANY;
|
||||||
|
|
||||||
|
|
|
@ -509,10 +509,13 @@ nsAppShell::Init()
|
||||||
if (obsServ) {
|
if (obsServ) {
|
||||||
obsServ->AddObserver(this, "browser-delayed-startup-finished", false);
|
obsServ->AddObserver(this, "browser-delayed-startup-finished", false);
|
||||||
obsServ->AddObserver(this, "profile-after-change", false);
|
obsServ->AddObserver(this, "profile-after-change", false);
|
||||||
obsServ->AddObserver(this, "chrome-document-loaded", false);
|
|
||||||
obsServ->AddObserver(this, "tab-child-created", false);
|
obsServ->AddObserver(this, "tab-child-created", false);
|
||||||
obsServ->AddObserver(this, "quit-application-granted", false);
|
obsServ->AddObserver(this, "quit-application-granted", false);
|
||||||
obsServ->AddObserver(this, "xpcom-shutdown", false);
|
obsServ->AddObserver(this, "xpcom-shutdown", false);
|
||||||
|
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
obsServ->AddObserver(this, "chrome-document-loaded", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sPowerManagerService)
|
if (sPowerManagerService)
|
||||||
|
@ -582,8 +585,18 @@ nsAppShell::Observe(nsISupports* aSubject,
|
||||||
java::GeckoThread::State::PROFILE_READY(),
|
java::GeckoThread::State::PROFILE_READY(),
|
||||||
java::GeckoThread::State::RUNNING());
|
java::GeckoThread::State::RUNNING());
|
||||||
}
|
}
|
||||||
removeObserver = true;
|
|
||||||
|
|
||||||
|
// Enable the window event dispatcher for the given GeckoView.
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aSubject);
|
||||||
|
MOZ_ASSERT(doc);
|
||||||
|
nsCOMPtr<nsIWidget> widget =
|
||||||
|
WidgetUtils::DOMWindowToWidget(doc->GetWindow());
|
||||||
|
MOZ_ASSERT(widget);
|
||||||
|
if (widget->WindowType() == nsWindowType::eWindowType_toplevel) {
|
||||||
|
// Make sure to call this only on top level nsWindow.
|
||||||
|
const auto window = static_cast<nsWindow*>(widget.get());
|
||||||
|
window->EnableEventDispatcher();
|
||||||
|
}
|
||||||
} else if (!strcmp(aTopic, "quit-application-granted")) {
|
} else if (!strcmp(aTopic, "quit-application-granted")) {
|
||||||
if (jni::IsAvailable()) {
|
if (jni::IsAvailable()) {
|
||||||
java::GeckoThread::SetState(
|
java::GeckoThread::SetState(
|
||||||
|
|
|
@ -237,12 +237,12 @@ public:
|
||||||
Impl* operator->() const { return mImpl; }
|
Impl* operator->() const { return mImpl; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class nsWindow::GeckoViewSupport final
|
class nsWindow::GeckoViewSupport final
|
||||||
: public GeckoView::Window::Natives<GeckoViewSupport>
|
: public GeckoView::Window::Natives<GeckoViewSupport>
|
||||||
, public SupportsWeakPtr<GeckoViewSupport>
|
, public SupportsWeakPtr<GeckoViewSupport>
|
||||||
{
|
{
|
||||||
nsWindow& window;
|
nsWindow& window;
|
||||||
|
GeckoView::GlobalRef mView;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef GeckoView::Window::Natives<GeckoViewSupport> Base;
|
typedef GeckoView::Window::Natives<GeckoViewSupport> Base;
|
||||||
|
@ -268,6 +268,7 @@ public:
|
||||||
const GeckoView::Window::LocalRef& aInstance,
|
const GeckoView::Window::LocalRef& aInstance,
|
||||||
GeckoView::Param aView)
|
GeckoView::Param aView)
|
||||||
: window(*aWindow)
|
: window(*aWindow)
|
||||||
|
, mView(aView)
|
||||||
{
|
{
|
||||||
Base::AttachNative(aInstance, static_cast<SupportsWeakPtr*>(this));
|
Base::AttachNative(aInstance, static_cast<SupportsWeakPtr*>(this));
|
||||||
}
|
}
|
||||||
|
@ -301,6 +302,8 @@ public:
|
||||||
jni::Object::Param aDispatcher);
|
jni::Object::Param aDispatcher);
|
||||||
|
|
||||||
void LoadUri(jni::String::Param aUri, int32_t aFlags);
|
void LoadUri(jni::String::Param aUri, int32_t aFlags);
|
||||||
|
|
||||||
|
void EnableEventDispatcher();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1535,6 +1538,15 @@ nsWindow::GetRootLayerId() const
|
||||||
return mCompositorSession ? mCompositorSession->RootLayerTreeId() : 0;
|
return mCompositorSession ? mCompositorSession->RootLayerTreeId() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::EnableEventDispatcher()
|
||||||
|
{
|
||||||
|
if (!mGeckoViewSupport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mGeckoViewSupport->EnableEventDispatcher();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsWindow::SetParent(nsIWidget *aNewParent)
|
nsWindow::SetParent(nsIWidget *aNewParent)
|
||||||
{
|
{
|
||||||
|
@ -2061,6 +2073,13 @@ nsWindow::GetEventTimeStamp(int64_t aEventTime)
|
||||||
return TimeStamp::FromSystemTime(tick);
|
return TimeStamp::FromSystemTime(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWindow::GeckoViewSupport::EnableEventDispatcher()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mView);
|
||||||
|
mView->SetState(GeckoView::State::READY());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsWindow::UserActivity()
|
nsWindow::UserActivity()
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
|
|
||||||
static void InitNatives();
|
static void InitNatives();
|
||||||
void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
|
void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
|
||||||
|
void EnableEventDispatcher();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t mScreenId;
|
uint32_t mScreenId;
|
||||||
|
|
|
@ -38,24 +38,6 @@
|
||||||
#include "nsTraceRefcnt.h"
|
#include "nsTraceRefcnt.h"
|
||||||
#include "nsErrorService.h"
|
#include "nsErrorService.h"
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsSupportsArray.h"
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsArray.h"
|
#include "nsArray.h"
|
||||||
#include "nsINIParserImpl.h"
|
#include "nsINIParserImpl.h"
|
||||||
#include "nsSupportsPrimitives.h"
|
#include "nsSupportsPrimitives.h"
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create)
|
COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create)
|
||||||
|
|
||||||
COMPONENT(SUPPORTSARRAY, nsSupportsArray::Create)
|
|
||||||
COMPONENT(ARRAY, nsArrayBase::XPCOMConstructor)
|
COMPONENT(ARRAY, nsArrayBase::XPCOMConstructor)
|
||||||
COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor)
|
COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor)
|
||||||
COMPONENT(ATOMSERVICE, nsAtomServiceConstructor)
|
COMPONENT(ATOMSERVICE, nsAtomServiceConstructor)
|
||||||
|
|
|
@ -9,8 +9,6 @@ XPIDL_SOURCES += [
|
||||||
'nsIArrayExtensions.idl',
|
'nsIArrayExtensions.idl',
|
||||||
'nsIAtom.idl',
|
'nsIAtom.idl',
|
||||||
'nsIAtomService.idl',
|
'nsIAtomService.idl',
|
||||||
'nsICollection.idl',
|
|
||||||
'nsIEnumerator.idl',
|
|
||||||
'nsIHashable.idl',
|
'nsIHashable.idl',
|
||||||
'nsIINIParser.idl',
|
'nsIINIParser.idl',
|
||||||
'nsIMutableArray.idl',
|
'nsIMutableArray.idl',
|
||||||
|
@ -24,7 +22,6 @@ XPIDL_SOURCES += [
|
||||||
'nsISerializable.idl',
|
'nsISerializable.idl',
|
||||||
'nsISimpleEnumerator.idl',
|
'nsISimpleEnumerator.idl',
|
||||||
'nsIStringEnumerator.idl',
|
'nsIStringEnumerator.idl',
|
||||||
'nsISupportsArray.idl',
|
|
||||||
'nsISupportsIterators.idl',
|
'nsISupportsIterators.idl',
|
||||||
'nsISupportsPrimitives.idl',
|
'nsISupportsPrimitives.idl',
|
||||||
'nsIVariant.idl',
|
'nsIVariant.idl',
|
||||||
|
@ -69,7 +66,6 @@ EXPORTS += [
|
||||||
'nsStaticAtom.h',
|
'nsStaticAtom.h',
|
||||||
'nsStaticNameTable.h',
|
'nsStaticNameTable.h',
|
||||||
'nsStringEnumerator.h',
|
'nsStringEnumerator.h',
|
||||||
'nsSupportsArray.h',
|
|
||||||
'nsSupportsPrimitives.h',
|
'nsSupportsPrimitives.h',
|
||||||
'nsTArray-inl.h',
|
'nsTArray-inl.h',
|
||||||
'nsTArray.h',
|
'nsTArray.h',
|
||||||
|
@ -108,8 +104,6 @@ UNIFIED_SOURCES += [
|
||||||
'nsProperties.cpp',
|
'nsProperties.cpp',
|
||||||
'nsQuickSort.cpp',
|
'nsQuickSort.cpp',
|
||||||
'nsStringEnumerator.cpp',
|
'nsStringEnumerator.cpp',
|
||||||
'nsSupportsArray.cpp',
|
|
||||||
'nsSupportsArrayEnumerator.cpp',
|
|
||||||
'nsSupportsPrimitives.cpp',
|
'nsSupportsPrimitives.cpp',
|
||||||
'nsTArray.cpp',
|
'nsTArray.cpp',
|
||||||
'nsTObserverArray.cpp',
|
'nsTObserverArray.cpp',
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* 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 "nsISerializable.idl"
|
|
||||||
|
|
||||||
interface nsIEnumerator;
|
|
||||||
|
|
||||||
[deprecated, scriptable, uuid(83b6019c-cbc4-11d2-8cca-0060b0fc14a3)]
|
|
||||||
interface nsICollection : nsISerializable
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t Count();
|
|
||||||
nsISupports GetElementAt(in uint32_t index);
|
|
||||||
void QueryElementAt(in uint32_t index, in nsIIDRef uuid,
|
|
||||||
[iid_is(uuid),retval] out nsQIResult result);
|
|
||||||
void SetElementAt(in uint32_t index, in nsISupports item);
|
|
||||||
void AppendElement(in nsISupports item);
|
|
||||||
void RemoveElement(in nsISupports item);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This clashes with |nsISimpleEnumerator nsIArray.enumerate()| (only on the
|
|
||||||
* binary side), so it is renamed with a 'Deprecated' prefix in favor of the
|
|
||||||
* non-deprecated |nsIArray.enumerate|.
|
|
||||||
*/
|
|
||||||
[binaryname(DeprecatedEnumerate)]
|
|
||||||
nsIEnumerator Enumerate();
|
|
||||||
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
%{C++
|
|
||||||
|
|
||||||
#ifndef nsCOMPtr_h__
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS nsQueryElementAt : public nsCOMPtr_helper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
nsQueryElementAt( nsICollection* aCollection, uint32_t aIndex, nsresult* aErrorPtr )
|
|
||||||
: mCollection(aCollection),
|
|
||||||
mIndex(aIndex),
|
|
||||||
mErrorPtr(aErrorPtr)
|
|
||||||
{
|
|
||||||
// nothing else to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** )
|
|
||||||
const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsICollection* MOZ_NON_OWNING_REF mCollection;
|
|
||||||
uint32_t mIndex;
|
|
||||||
nsresult* mErrorPtr;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline
|
|
||||||
const nsQueryElementAt
|
|
||||||
do_QueryElementAt( nsICollection* aCollection, uint32_t aIndex, nsresult* aErrorPtr = 0 )
|
|
||||||
{
|
|
||||||
return nsQueryElementAt(aCollection, aIndex, aErrorPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "nsISupports.idl"
|
|
||||||
|
|
||||||
%{C++
|
|
||||||
#define NS_ENUMERATOR_FALSE 1
|
|
||||||
%}
|
|
||||||
/*
|
|
||||||
* DO NOT USE THIS INTERFACE. IT IS HORRIBLY BROKEN, USES NS_COMFALSE
|
|
||||||
* AND IS BASICALLY IMPOSSIBLE TO USE CORRECTLY THROUGH PROXIES OR
|
|
||||||
* XPCONNECT. IF YOU SEE NEW USES OF THIS INTERFACE IN CODE YOU ARE
|
|
||||||
* REVIEWING, YOU SHOULD INSIST ON nsISimpleEnumerator.
|
|
||||||
*
|
|
||||||
* DON'T MAKE ME COME OVER THERE.
|
|
||||||
*/
|
|
||||||
[deprecated, scriptable, uuid(ad385286-cbc4-11d2-8cca-0060b0fc14a3)]
|
|
||||||
interface nsIEnumerator : nsISupports {
|
|
||||||
/** First will reset the list. will return NS_FAILED if no items
|
|
||||||
*/
|
|
||||||
void first();
|
|
||||||
|
|
||||||
/** Next will advance the list. will return failed if already at end
|
|
||||||
*/
|
|
||||||
void next();
|
|
||||||
|
|
||||||
/** CurrentItem will return the CurrentItem item it will fail if the
|
|
||||||
* list is empty
|
|
||||||
*/
|
|
||||||
nsISupports currentItem();
|
|
||||||
|
|
||||||
/** return if the collection is at the end. that is the beginning following
|
|
||||||
* a call to Prev and it is the end of the list following a call to next
|
|
||||||
*/
|
|
||||||
void isDone();
|
|
||||||
};
|
|
||||||
|
|
||||||
[deprecated, uuid(75f158a0-cadd-11d2-8cca-0060b0fc14a3)]
|
|
||||||
interface nsIBidirectionalEnumerator : nsIEnumerator {
|
|
||||||
|
|
||||||
/** Last will reset the list to the end. will return NS_FAILED if no items
|
|
||||||
*/
|
|
||||||
void last();
|
|
||||||
|
|
||||||
/** Prev will decrement the list. will return failed if already at beginning
|
|
||||||
*/
|
|
||||||
void prev();
|
|
||||||
};
|
|
|
@ -1,60 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* 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 "nsICollection.idl"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This entire interface is deprecated and should not be used.
|
|
||||||
* See nsIArray and nsIMutableArray for the new implementations.
|
|
||||||
*
|
|
||||||
* http://groups.google.com/groups?q=nsisupportsarray+group:netscape.public.mozilla.xpcom&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=3D779491.3050506%40netscape.com&rnum=2
|
|
||||||
* http://groups.google.com/groups?q=nsisupportsarray+group:netscape.public.mozilla.xpcom&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=al8412%245ab2%40ripley.netscape.com&rnum=8
|
|
||||||
*/
|
|
||||||
|
|
||||||
%{C++
|
|
||||||
|
|
||||||
class nsIBidirectionalEnumerator;
|
|
||||||
class nsISupportsArray;
|
|
||||||
|
|
||||||
#define NS_SUPPORTSARRAY_CID \
|
|
||||||
{ /* bda17d50-0d6b-11d3-9331-00104ba0fd40 */ \
|
|
||||||
0xbda17d50, \
|
|
||||||
0x0d6b, \
|
|
||||||
0x11d3, \
|
|
||||||
{0x93, 0x31, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
|
|
||||||
}
|
|
||||||
#define NS_SUPPORTSARRAY_CONTRACTID "@mozilla.org/supports-array;1"
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
[deprecated, scriptable, uuid(241addc8-3608-4e73-8083-2fd6fa09eba2)]
|
|
||||||
interface nsISupportsArray : nsICollection {
|
|
||||||
|
|
||||||
[notxpcom] long IndexOf([const] in nsISupports aPossibleElement);
|
|
||||||
|
|
||||||
// xpcom-compatible versions
|
|
||||||
long GetIndexOf(in nsISupports aPossibleElement);
|
|
||||||
|
|
||||||
[notxpcom] boolean InsertElementAt(in nsISupports aElement,
|
|
||||||
in unsigned long aIndex);
|
|
||||||
[notxpcom] boolean ReplaceElementAt(in nsISupports aElement,
|
|
||||||
in unsigned long aIndex);
|
|
||||||
|
|
||||||
[notxpcom] boolean RemoveElementAt(in unsigned long aIndex);
|
|
||||||
|
|
||||||
// xpcom-compatible versions
|
|
||||||
void DeleteElementAt(in unsigned long aIndex);
|
|
||||||
|
|
||||||
nsISupportsArray clone();
|
|
||||||
};
|
|
||||||
|
|
||||||
%{C++
|
|
||||||
|
|
||||||
// Construct and return a default implementation of nsISupportsArray:
|
|
||||||
extern MOZ_MUST_USE nsresult
|
|
||||||
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult);
|
|
||||||
|
|
||||||
%}
|
|
|
@ -1,264 +0,0 @@
|
||||||
/* -*- 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 <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "nsArrayEnumerator.h"
|
|
||||||
#include "nsIObjectInputStream.h"
|
|
||||||
#include "nsIObjectOutputStream.h"
|
|
||||||
#include "nsSupportsArray.h"
|
|
||||||
#include "nsSupportsArrayEnumerator.h"
|
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsQueryElementAt::operator()(const nsIID& aIID, void** aResult) const
|
|
||||||
{
|
|
||||||
nsresult status =
|
|
||||||
mCollection ? mCollection->QueryElementAt(mIndex, aIID, aResult) :
|
|
||||||
NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
if (mErrorPtr) {
|
|
||||||
*mErrorPtr = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsSupportsArray::nsSupportsArray()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nsSupportsArray::~nsSupportsArray()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsSupportsArray::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|
||||||
{
|
|
||||||
if (aOuter) {
|
|
||||||
return NS_ERROR_NO_AGGREGATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsArray> it = new nsSupportsArray();
|
|
||||||
|
|
||||||
return it->QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsSupportsArray, nsIArray, nsISupportsArray, nsICollection,
|
|
||||||
nsISerializable)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::Read(nsIObjectInputStream* aStream)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
uint32_t newArraySize;
|
|
||||||
rv = aStream->Read32(&newArraySize);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t count;
|
|
||||||
rv = aStream->Read32(&count);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(count <= newArraySize, "overlarge mCount!");
|
|
||||||
if (count > newArraySize) {
|
|
||||||
count = newArraySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't clear out our array until we know we have enough space for the new
|
|
||||||
// one and have successfully copied everything out of the stream.
|
|
||||||
nsCOMArray<nsISupports> tmp;
|
|
||||||
tmp.SetCapacity(newArraySize);
|
|
||||||
tmp.SetCount(count);
|
|
||||||
|
|
||||||
auto elems = tmp.Elements();
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
rv = aStream->ReadObject(true, &elems[i]);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now clear out existing refs and replace with the new array.
|
|
||||||
mArray.Clear();
|
|
||||||
mArray.SwapElements(tmp);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::Write(nsIObjectOutputStream* aStream)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
rv = aStream->Write32(mArray.Capacity());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = aStream->Write32(mArray.Length());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < mArray.Length(); i++) {
|
|
||||||
rv = aStream->WriteObject(mArray[i], true);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::GetElementAt(uint32_t aIndex, nsISupports** aOutPtr)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsISupports> elm = mArray.SafeElementAt(aIndex);
|
|
||||||
elm.forget(aOutPtr);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(int32_t)
|
|
||||||
nsSupportsArray::IndexOf(const nsISupports* aPossibleElement)
|
|
||||||
{
|
|
||||||
// nsCOMArray takes a non-const param, but it just passes through to
|
|
||||||
// nsTArray which takes a const param.
|
|
||||||
return mArray.IndexOf(const_cast<nsISupports*>(aPossibleElement));
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(bool)
|
|
||||||
nsSupportsArray::InsertElementAt(nsISupports* aElement, uint32_t aIndex)
|
|
||||||
{
|
|
||||||
return mArray.InsertObjectAt(aElement, aIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(bool)
|
|
||||||
nsSupportsArray::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex)
|
|
||||||
{
|
|
||||||
// nsCOMArray::ReplaceObjectAt will grow the array if necessary. Instead
|
|
||||||
// we do the bounds check and only replace if it's in range.
|
|
||||||
if (aIndex < mArray.Length()) {
|
|
||||||
mArray.ReplaceElementAt(aIndex, aElement);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(bool)
|
|
||||||
nsSupportsArray::RemoveElementAt(uint32_t aIndex)
|
|
||||||
{
|
|
||||||
return mArray.RemoveObjectAt(aIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::RemoveElement(nsISupports* aElement)
|
|
||||||
{
|
|
||||||
return mArray.RemoveObject(aElement) ? NS_OK : NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::Clear(void)
|
|
||||||
{
|
|
||||||
mArray.Clear();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::DeprecatedEnumerate(nsIEnumerator** aResult)
|
|
||||||
{
|
|
||||||
RefPtr<nsSupportsArrayEnumerator> e = new nsSupportsArrayEnumerator(this);
|
|
||||||
e.forget(aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::Clone(nsISupportsArray** aResult)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsISupportsArray> newArray;
|
|
||||||
nsresult rv = NS_NewISupportsArray(getter_AddRefs(newArray));
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < mArray.Length(); i++) {
|
|
||||||
// AppendElement does an odd cast of bool to nsresult, we just cast back
|
|
||||||
// here.
|
|
||||||
if (!(bool)newArray->AppendElement(mArray[i])) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newArray.forget(aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
rv = nsSupportsArray::Create(nullptr, NS_GET_IID(nsISupportsArray),
|
|
||||||
(void**)aInstancePtrResult);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIArray adapters.
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::GetLength(uint32_t* aLength) {
|
|
||||||
return Count(aLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::QueryElementAt(uint32_t aIndex, const nsIID& aIID, void** aResult)
|
|
||||||
{
|
|
||||||
nsISupports* element = mArray.SafeElementAt(aIndex);
|
|
||||||
if (element) {
|
|
||||||
return element->QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::IndexOf(uint32_t aStartIndex, nsISupports* aElement, uint32_t* aResult)
|
|
||||||
{
|
|
||||||
int32_t idx = mArray.IndexOf(aElement, aStartIndex);
|
|
||||||
if (idx < 0) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aResult = static_cast<uint32_t>(idx);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArray::Enumerate(nsISimpleEnumerator** aResult)
|
|
||||||
{
|
|
||||||
return NS_NewArrayEnumerator(aResult, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
/* -*- 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 nsSupportsArray_h__
|
|
||||||
#define nsSupportsArray_h__
|
|
||||||
|
|
||||||
#include "nsIArray.h"
|
|
||||||
#include "nsCOMArray.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsISupportsArray.h"
|
|
||||||
|
|
||||||
class nsSupportsArray final : public nsISupportsArray,
|
|
||||||
public nsIArray
|
|
||||||
{
|
|
||||||
~nsSupportsArray(void); // nonvirtual since we're not subclassed
|
|
||||||
|
|
||||||
public:
|
|
||||||
nsSupportsArray(void);
|
|
||||||
|
|
||||||
static MOZ_MUST_USE nsresult
|
|
||||||
Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
|
|
||||||
NS_DECL_NSISERIALIZABLE
|
|
||||||
|
|
||||||
// nsICollection methods:
|
|
||||||
NS_IMETHOD Count(uint32_t* aResult) override
|
|
||||||
{
|
|
||||||
*aResult = mArray.Length();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
NS_IMETHOD GetElementAt(uint32_t aIndex, nsISupports** aResult) override;
|
|
||||||
MOZ_MUST_USE NS_IMETHOD
|
|
||||||
SetElementAt(uint32_t aIndex, nsISupports* aValue) override
|
|
||||||
{
|
|
||||||
return ReplaceElementAt(aValue, aIndex) ? NS_OK : NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
MOZ_MUST_USE NS_IMETHOD AppendElement(nsISupports* aElement) override
|
|
||||||
{
|
|
||||||
// XXX Invalid cast of bool to nsresult (bug 778110)
|
|
||||||
return (nsresult)InsertElementAt(aElement, mArray.Length())/* ? NS_OK : NS_ERROR_FAILURE*/;
|
|
||||||
}
|
|
||||||
// XXX this is badly named - should be RemoveFirstElement
|
|
||||||
MOZ_MUST_USE NS_IMETHOD RemoveElement(nsISupports* aElement) override;
|
|
||||||
NS_IMETHOD DeprecatedEnumerate(nsIEnumerator** aResult) override;
|
|
||||||
NS_IMETHOD Clear(void) override;
|
|
||||||
|
|
||||||
// nsISupportsArray methods:
|
|
||||||
NS_IMETHOD_(int32_t) IndexOf(const nsISupports* aPossibleElement) override;
|
|
||||||
|
|
||||||
NS_IMETHOD GetIndexOf(nsISupports* aPossibleElement, int32_t* aResult) override
|
|
||||||
{
|
|
||||||
*aResult = IndexOf(aPossibleElement);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_MUST_USE NS_IMETHOD_(bool)
|
|
||||||
InsertElementAt(nsISupports* aElement, uint32_t aIndex) override;
|
|
||||||
|
|
||||||
MOZ_MUST_USE NS_IMETHOD_(bool)
|
|
||||||
ReplaceElementAt(nsISupports* aElement, uint32_t aIndex) override;
|
|
||||||
|
|
||||||
MOZ_MUST_USE NS_IMETHOD_(bool)
|
|
||||||
RemoveElementAt(uint32_t aIndex) override;
|
|
||||||
|
|
||||||
MOZ_MUST_USE NS_IMETHOD DeleteElementAt(uint32_t aIndex) override
|
|
||||||
{
|
|
||||||
return (RemoveElementAt(aIndex) ? NS_OK : NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_MUST_USE NS_IMETHOD Clone(nsISupportsArray** aResult) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIArray adapters.
|
|
||||||
*/
|
|
||||||
NS_DECL_NSIARRAY
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Copy constructors are not allowed
|
|
||||||
explicit nsSupportsArray(const nsISupportsArray& aOther);
|
|
||||||
|
|
||||||
nsCOMArray<nsISupports> mArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // nsSupportsArray_h__
|
|
|
@ -1,131 +0,0 @@
|
||||||
/* -*- 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 "nsSupportsArrayEnumerator.h"
|
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsISupportsArray.h"
|
|
||||||
|
|
||||||
nsSupportsArrayEnumerator::nsSupportsArrayEnumerator(nsISupportsArray* array)
|
|
||||||
: mArray(array)
|
|
||||||
, mCursor(0)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(array, "null array");
|
|
||||||
}
|
|
||||||
|
|
||||||
nsSupportsArrayEnumerator::~nsSupportsArrayEnumerator()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsSupportsArrayEnumerator, nsIBidirectionalEnumerator,
|
|
||||||
nsIEnumerator)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::First()
|
|
||||||
{
|
|
||||||
mCursor = 0;
|
|
||||||
uint32_t cnt;
|
|
||||||
nsresult rv = mArray->Count(&cnt);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
int32_t end = (int32_t)cnt;
|
|
||||||
if (mCursor < end) {
|
|
||||||
return NS_OK;
|
|
||||||
} else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::Next()
|
|
||||||
{
|
|
||||||
uint32_t cnt;
|
|
||||||
nsresult rv = mArray->Count(&cnt);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
int32_t end = (int32_t)cnt;
|
|
||||||
if (mCursor < end) { // don't count upward forever
|
|
||||||
mCursor++;
|
|
||||||
}
|
|
||||||
if (mCursor < end) {
|
|
||||||
return NS_OK;
|
|
||||||
} else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::CurrentItem(nsISupports** aItem)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aItem, "null out parameter");
|
|
||||||
uint32_t cnt;
|
|
||||||
nsresult rv = mArray->Count(&cnt);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
if (mCursor >= 0 && mCursor < (int32_t)cnt) {
|
|
||||||
return mArray->GetElementAt(mCursor, aItem);
|
|
||||||
}
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::IsDone()
|
|
||||||
{
|
|
||||||
uint32_t cnt;
|
|
||||||
nsresult rv = mArray->Count(&cnt);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
// XXX This is completely incompatible with the meaning of nsresult.
|
|
||||||
// NS_ENUMERATOR_FALSE is defined to be 1. (bug 778111)
|
|
||||||
return (mCursor >= 0 && mCursor < (int32_t)cnt)
|
|
||||||
? (nsresult)NS_ENUMERATOR_FALSE : NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::Last()
|
|
||||||
{
|
|
||||||
uint32_t cnt;
|
|
||||||
nsresult rv = mArray->Count(&cnt);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
mCursor = cnt - 1;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsSupportsArrayEnumerator::Prev()
|
|
||||||
{
|
|
||||||
if (mCursor >= 0) {
|
|
||||||
--mCursor;
|
|
||||||
}
|
|
||||||
if (mCursor >= 0) {
|
|
||||||
return NS_OK;
|
|
||||||
} else {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* -*- 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 nsSupportsArrayEnumerator_h___
|
|
||||||
#define nsSupportsArrayEnumerator_h___
|
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsIEnumerator.h"
|
|
||||||
|
|
||||||
class nsISupportsArray;
|
|
||||||
|
|
||||||
class nsSupportsArrayEnumerator final : public nsIBidirectionalEnumerator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
explicit nsSupportsArrayEnumerator(nsISupportsArray* aArray);
|
|
||||||
|
|
||||||
// nsIEnumerator methods:
|
|
||||||
NS_DECL_NSIENUMERATOR
|
|
||||||
|
|
||||||
// nsIBidirectionalEnumerator methods:
|
|
||||||
NS_DECL_NSIBIDIRECTIONALENUMERATOR
|
|
||||||
|
|
||||||
private:
|
|
||||||
~nsSupportsArrayEnumerator();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsCOMPtr<nsISupportsArray> mArray;
|
|
||||||
int32_t mCursor;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __nsSupportsArrayEnumerator_h
|
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
/* -*- 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
||||||
// classes.
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsISupportsArray.h"
|
|
||||||
|
|
||||||
// {9e70a320-be02-11d1-8031-006008159b5a}
|
|
||||||
#define NS_IFOO_IID \
|
|
||||||
{0x9e70a320, 0xbe02, 0x11d1, \
|
|
||||||
{0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
|
|
||||||
|
|
||||||
namespace TestArray {
|
|
||||||
|
|
||||||
class IFoo : public nsISupports {
|
|
||||||
public:
|
|
||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
|
|
||||||
|
|
||||||
NS_IMETHOD_(nsrefcnt) RefCnt() = 0;
|
|
||||||
NS_IMETHOD_(int32_t) ID() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
|
|
||||||
|
|
||||||
class Foo final : public IFoo {
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit Foo(int32_t aID);
|
|
||||||
|
|
||||||
// nsISupports implementation
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
// IFoo implementation
|
|
||||||
NS_IMETHOD_(nsrefcnt) RefCnt() override { return mRefCnt; }
|
|
||||||
NS_IMETHOD_(int32_t) ID() override { return mID; }
|
|
||||||
|
|
||||||
static int32_t gCount;
|
|
||||||
|
|
||||||
int32_t mID;
|
|
||||||
|
|
||||||
private:
|
|
||||||
~Foo();
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t Foo::gCount;
|
|
||||||
|
|
||||||
Foo::Foo(int32_t aID)
|
|
||||||
{
|
|
||||||
mID = aID;
|
|
||||||
++gCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
Foo::~Foo()
|
|
||||||
{
|
|
||||||
--gCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(Foo, IFoo)
|
|
||||||
|
|
||||||
void CheckArray(nsISupportsArray* aArray, int32_t aExpectedCount, int32_t aElementIDs[], int32_t aExpectedTotal)
|
|
||||||
{
|
|
||||||
uint32_t cnt = 0;
|
|
||||||
#ifdef DEBUG
|
|
||||||
nsresult rv =
|
|
||||||
#endif
|
|
||||||
aArray->Count(&cnt);
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
||||||
int32_t count = cnt;
|
|
||||||
int32_t index;
|
|
||||||
|
|
||||||
EXPECT_EQ(Foo::gCount, aExpectedTotal);
|
|
||||||
EXPECT_EQ(count, aExpectedCount);
|
|
||||||
|
|
||||||
for (index = 0; (index < count) && (index < aExpectedCount); index++) {
|
|
||||||
nsCOMPtr<IFoo> foo = do_QueryElementAt(aArray, index);
|
|
||||||
EXPECT_EQ(foo->ID(), aElementIDs[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillArray(nsISupportsArray* aArray, int32_t aCount)
|
|
||||||
{
|
|
||||||
int32_t index;
|
|
||||||
for (index = 0; index < aCount; index++) {
|
|
||||||
nsCOMPtr<IFoo> foo = new Foo(index);
|
|
||||||
aArray->AppendElement(foo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace TestArray
|
|
||||||
|
|
||||||
using namespace TestArray;
|
|
||||||
|
|
||||||
TEST(Array, main)
|
|
||||||
{
|
|
||||||
nsISupportsArray* array;
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (NS_OK == (rv = NS_NewISupportsArray(&array))) {
|
|
||||||
FillArray(array, 10);
|
|
||||||
int32_t fillResult[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
||||||
CheckArray(array, 10, fillResult, 10);
|
|
||||||
|
|
||||||
// test insert
|
|
||||||
nsCOMPtr<IFoo> foo = do_QueryElementAt(array, 3);
|
|
||||||
array->InsertElementAt(foo, 5);
|
|
||||||
int32_t insertResult[11] = {0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9};
|
|
||||||
CheckArray(array, 11, insertResult, 10);
|
|
||||||
array->InsertElementAt(foo, 0);
|
|
||||||
int32_t insertResult2[12] = {3, 0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9};
|
|
||||||
CheckArray(array, 12, insertResult2, 10);
|
|
||||||
array->AppendElement(foo);
|
|
||||||
int32_t appendResult[13] = {3, 0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9, 3};
|
|
||||||
CheckArray(array, 13, appendResult, 10);
|
|
||||||
|
|
||||||
|
|
||||||
// test IndexOf
|
|
||||||
int32_t expectedIndex = 0;
|
|
||||||
int32_t index = array->IndexOf(foo);
|
|
||||||
EXPECT_EQ(index, expectedIndex);
|
|
||||||
|
|
||||||
// test ReplaceElementAt
|
|
||||||
array->ReplaceElementAt(foo, 8);
|
|
||||||
int32_t replaceResult[13] = {3, 0, 1, 2, 3, 4, 3, 5, 3, 7, 8, 9, 3};
|
|
||||||
CheckArray(array, 13, replaceResult, 9);
|
|
||||||
|
|
||||||
// test RemoveElementAt, RemoveElement
|
|
||||||
array->RemoveElementAt(0);
|
|
||||||
int32_t removeResult[12] = {0, 1, 2, 3, 4, 3, 5, 3, 7, 8, 9, 3};
|
|
||||||
CheckArray(array, 12, removeResult, 9);
|
|
||||||
array->RemoveElementAt(7);
|
|
||||||
int32_t removeResult2[11] = {0, 1, 2, 3, 4, 3, 5, 7, 8, 9, 3};
|
|
||||||
CheckArray(array, 11, removeResult2, 9);
|
|
||||||
array->RemoveElement(foo);
|
|
||||||
int32_t removeResult3[10] = {0, 1, 2, 4, 3, 5, 7, 8, 9, 3};
|
|
||||||
CheckArray(array, 10, removeResult3, 9);
|
|
||||||
|
|
||||||
foo = nullptr;
|
|
||||||
|
|
||||||
// test clear
|
|
||||||
array->Clear();
|
|
||||||
FillArray(array, 4);
|
|
||||||
CheckArray(array, 4, fillResult, 4);
|
|
||||||
|
|
||||||
// test delete
|
|
||||||
NS_RELEASE(array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "mozilla/TypeTraits.h"
|
#include "mozilla/TypeTraits.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
using mozilla::IsSame;
|
||||||
|
using mozilla::DeclVal;
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
Now define the token deallocator class...
|
Now define the token deallocator class...
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'Helpers.cpp',
|
'Helpers.cpp',
|
||||||
'TestArray.cpp',
|
|
||||||
'TestAtoms.cpp',
|
'TestAtoms.cpp',
|
||||||
'TestAutoPtr.cpp',
|
'TestAutoPtr.cpp',
|
||||||
'TestAutoRef.cpp',
|
'TestAutoRef.cpp',
|
||||||
|
|
|
@ -107,45 +107,6 @@ function test_enumerate()
|
||||||
do_check_eq(arr.length, i);
|
do_check_eq(arr.length, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_nssupportsarray_interop() {
|
|
||||||
// Tests to check that an nsSupportsArray instance can behave like an
|
|
||||||
// nsIArray.
|
|
||||||
let test = Components.classes["@mozilla.org/supports-array;1"]
|
|
||||||
.createInstance(Ci.nsISupportsArray);
|
|
||||||
|
|
||||||
let str = new SupportsString();
|
|
||||||
str.data = "element";
|
|
||||||
test.AppendElement(str);
|
|
||||||
|
|
||||||
// Now query to an nsIArray.
|
|
||||||
let iarray = test.QueryInterface(Ci.nsIArray);
|
|
||||||
do_check_neq(iarray, null);
|
|
||||||
|
|
||||||
// Make sure |nsIArray.length| works.
|
|
||||||
do_check_eq(iarray.length, 1);
|
|
||||||
|
|
||||||
// Make sure |nsIArray.queryElementAt| works.
|
|
||||||
let elm = iarray.queryElementAt(0, Ci.nsISupportsString);
|
|
||||||
do_check_eq(elm.data, "element");
|
|
||||||
|
|
||||||
// Make sure |nsIArray.indexOf| works.
|
|
||||||
let idx = iarray.indexOf(0, str);
|
|
||||||
do_check_eq(idx, 0);
|
|
||||||
|
|
||||||
// Make sure |nsIArray.enumerate| works.
|
|
||||||
let en = iarray.enumerate();
|
|
||||||
do_check_neq(en, null);
|
|
||||||
let i = 0;
|
|
||||||
while (en.hasMoreElements()) {
|
|
||||||
let str = en.getNext();
|
|
||||||
do_check_true(str instanceof Ci.nsISupportsString);
|
|
||||||
do_check_eq(str.data, "element");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
do_check_eq(iarray.length, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_nsiarrayextensions() {
|
function test_nsiarrayextensions() {
|
||||||
// Tests to check that the extensions that make an nsArray act like an
|
// Tests to check that the extensions that make an nsArray act like an
|
||||||
// nsISupportsArray for iteration purposes works.
|
// nsISupportsArray for iteration purposes works.
|
||||||
|
@ -174,7 +135,6 @@ var tests = [
|
||||||
test_replace_element,
|
test_replace_element,
|
||||||
test_clear,
|
test_clear,
|
||||||
test_enumerate,
|
test_enumerate,
|
||||||
test_nssupportsarray_interop,
|
|
||||||
test_nsiarrayextensions,
|
test_nsiarrayextensions,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче