This commit is contained in:
Ryan VanderMeulen 2017-05-24 20:45:23 -04:00
Родитель 74778951f0 31beca4070
Коммит c5b2958154
106 изменённых файлов: 1212 добавлений и 1318 удалений

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

@ -4,18 +4,18 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized');
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let acc = await new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
@ -41,7 +41,7 @@ add_task(function* () {
// a reference to an accessible object.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -51,5 +51,5 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -4,13 +4,13 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized');
// Accessible document reference will live longer than the scope of this
@ -33,7 +33,7 @@ add_task(function* () {
// a reference to an accessible document.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -43,5 +43,5 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -4,13 +4,13 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized');
let docAcc = accService.getAccessibleFor(document);
@ -18,7 +18,7 @@ add_task(function* () {
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let acc = await new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
@ -44,7 +44,7 @@ add_task(function* () {
// references to accessible objects.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible object.
acc = null;
@ -53,7 +53,7 @@ add_task(function* () {
// a reference to an accessible document.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -63,5 +63,5 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -4,13 +4,13 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized');
let docAcc = accService.getAccessibleFor(document);
@ -18,7 +18,7 @@ add_task(function* () {
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let acc = await new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
@ -44,7 +44,7 @@ add_task(function* () {
// references to accessible objects.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible document.
docAcc = null;
@ -53,7 +53,7 @@ add_task(function* () {
// a reference to an accessible object.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -63,5 +63,5 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -4,9 +4,9 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
@ -14,9 +14,9 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
await a11yInit;
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -26,8 +26,8 @@ add_task(function* () {
</head>
<body id="body"><div id="div"></div></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
}, async function(browser) {
let docLoadedEvent = await docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
@ -49,7 +49,7 @@ add_task(function* () {
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible proxy.
acc = null;
@ -58,7 +58,7 @@ add_task(function* () {
// a reference to an accessible document proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -68,9 +68,9 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});

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

@ -4,9 +4,9 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
@ -14,9 +14,9 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
await a11yInit;
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -26,8 +26,8 @@ add_task(function* () {
</head>
<body id="body"><div id="div"></div></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
}, async function(browser) {
let docLoadedEvent = await docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
@ -49,7 +49,7 @@ add_task(function* () {
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible document proxy.
docAcc = null;
@ -58,7 +58,7 @@ add_task(function* () {
// a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -68,9 +68,9 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});

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

@ -4,13 +4,13 @@
'use strict';
add_task(function* () {
add_task(async function () {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();
let accService1 = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService1, 'Service initialized');
// Add another reference to a11y service. This will not trigger
@ -35,7 +35,7 @@ add_task(function* () {
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -44,5 +44,5 @@ add_task(function* () {
ok(!accService2, 'Service is removed');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -4,11 +4,11 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -18,7 +18,7 @@ add_task(function* () {
</head>
<body></body>
</html>`
}, function*(browser) {
}, async function(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
@ -28,7 +28,7 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
await Promise.all([parentA11yInit, contentA11yInit]);
info('Adding additional reference to accessibility service in content ' +
'process');
@ -52,7 +52,7 @@ add_task(function* () {
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
// Have some breathing room between a11y service shutdowns.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
info('Removing a service in parent');
// Now allow a11y service to shutdown in content.
@ -64,9 +64,9 @@ add_task(function* () {
// Force garbage collection that should trigger shutdown in both parent and
// content.
forceGC();
yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
await Promise.all([parentA11yShutdown, contentA11yShutdown]);
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});
});

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

@ -4,17 +4,17 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
await a11yInit;
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -24,10 +24,10 @@ add_task(function* () {
</head>
<body><div id="div" style="visibility: hidden;"></div></body>
</html>`
}, function*(browser) {
}, async function(browser) {
let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, 'div');
yield invokeSetStyle(browser, 'div', 'visibility', 'visible');
let showEvent = yield onShow;
await invokeSetStyle(browser, 'div', 'visibility', 'visible');
let showEvent = await onShow;
let divAcc = showEvent.accessible;
ok(divAcc, 'Accessible proxy is created');
// Remove unnecessary dangling references
@ -46,7 +46,7 @@ add_task(function* () {
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -56,9 +56,9 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});

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

@ -4,9 +4,9 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
@ -14,9 +14,9 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
await a11yInit;
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -26,8 +26,8 @@ add_task(function* () {
</head>
<body id="body"></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
}, async function(browser) {
let docLoadedEvent = await docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
@ -46,7 +46,7 @@ add_task(function* () {
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
@ -56,9 +56,9 @@ add_task(function* () {
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});

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

@ -4,11 +4,11 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -18,7 +18,7 @@ add_task(function* () {
</head>
<body></body>
</html>`
}, function*(browser) {
}, async function(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
@ -28,7 +28,7 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
await Promise.all([parentA11yInit, contentA11yInit]);
info('Removing a service in parent and waiting for service to be shut ' +
'down in content');
@ -40,9 +40,9 @@ add_task(function* () {
// Force garbage collection that should trigger shutdown in both main and
// content process.
forceGC();
yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
await Promise.all([parentA11yShutdown, contentA11yShutdown]);
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});

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

@ -4,11 +4,11 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -18,23 +18,23 @@ add_task(function* () {
</head>
<body></body>
</html>`
}, function*(browser) {
}, async function(browser) {
info('Creating a service in content');
// Create a11y service in the content process.
let a11yInit = initPromise(browser);
loadFrameScripts(browser, `let accService = Components.classes[
'@mozilla.org/accessibilityService;1'].getService(
Components.interfaces.nsIAccessibilityService);`);
yield a11yInit;
await a11yInit;
info('Removing a service in content');
// Remove a11y service reference from the content process.
let a11yShutdown = shutdownPromise(browser);
// Force garbage collection that should trigger shutdown.
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
yield a11yShutdown;
await a11yShutdown;
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});
});

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

@ -4,11 +4,11 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
await setE10sPrefs();
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
@ -18,7 +18,7 @@ add_task(function* () {
</head>
<body></body>
</html>`
}, function*(browser) {
}, async function(browser) {
info('Creating a service in parent and waiting for service to be created ' +
'in content');
// Create a11y service in the main process. This will trigger creating of
@ -28,7 +28,7 @@ add_task(function* () {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized in parent');
yield Promise.all([parentA11yInit, contentA11yInit]);
await Promise.all([parentA11yInit, contentA11yInit]);
info('Adding additional reference to accessibility service in content ' +
'process');
@ -56,10 +56,10 @@ add_task(function* () {
// is a reference in a content process.
forceGC();
loadFrameScripts(browser, `Components.utils.forceGC();`);
yield parentA11yShutdown;
await parentA11yShutdown;
// Have some breathing room between a11y service shutdowns.
yield new Promise(resolve => executeSoon(resolve));
await new Promise(resolve => executeSoon(resolve));
info('Removing a service in content');
// Now allow a11y service to shutdown in content.
@ -67,9 +67,9 @@ add_task(function* () {
// Remove last reference to a11y service in content and force garbage
// collection that should trigger shutdown.
loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
yield contentA11yShutdown;
await contentA11yShutdown;
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
await unsetE10sPrefs();
});
});

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

@ -4,7 +4,7 @@
'use strict';
add_task(function* () {
add_task(async function () {
// Create a11y service inside of the function scope. Its reference should be
// released once the anonimous function is called.
let a11yInitThenShutdown = initPromise().then(shutdownPromise);
@ -17,5 +17,5 @@ add_task(function* () {
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yInitThenShutdown;
await a11yInitThenShutdown;
});

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

@ -4,13 +4,13 @@
'use strict';
add_task(function* () {
add_task(async function () {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized');
info('Removing a service');
@ -20,14 +20,14 @@ add_task(function* () {
ok(!accService, 'Service is removed');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
info('Recreating a service');
// Re-create a11y service.
a11yInit = initPromise();
accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
await a11yInit;
ok(accService, 'Service initialized again');
info('Removing a service again');
@ -37,5 +37,5 @@ add_task(function* () {
ok(!accService, 'Service is removed again');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
await a11yShutdown;
});

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

@ -29,7 +29,7 @@ const defaultAttributes = {
* expected {Object} expected attributes for given accessibles
* unexpected {Object} unexpected attributes for given accessibles
*
* action {?Function*} an optional action that yields a change in
* action {?AsyncFunction} an optional action that awaits a change in
* attributes
* attrs {?Array} an optional list of attributes to update
* waitFor {?Number} an optional event to wait for
@ -46,8 +46,8 @@ const attributesTests = [{
}
}, {
desc: '@line-number attribute is present when textbox is focused',
action: function*(browser) {
yield invokeFocus(browser, 'textbox');
action: async function(browser) {
await invokeFocus(browser, 'textbox');
},
waitFor: EVENT_FOCUS,
expected: Object.assign({}, defaultAttributes, { 'line-number': '1' }),
@ -90,7 +90,7 @@ const attributesTests = [{
*/
addAccessibleTask(`
<input id="textbox" value="hello">`,
function* (browser, accDoc) {
async function (browser, accDoc) {
let textbox = findAccessibleChildByID(accDoc, 'textbox');
for (let { desc, action, attrs, expected, waitFor, unexpected } of attributesTests) {
info(desc);
@ -101,14 +101,14 @@ addAccessibleTask(`
}
if (action) {
yield action(browser);
await action(browser);
} else if (attrs) {
for (let { attr, value } of attrs) {
yield invokeSetAttribute(browser, 'textbox', attr, value);
await invokeSetAttribute(browser, 'textbox', attr, value);
}
}
yield onUpdate;
await onUpdate;
testAttrs(textbox, expected);
testAbsentAttrs(textbox, unexpected);
}

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

@ -137,7 +137,7 @@ addAccessibleTask(`
<p id="description">aria description</p>
<p id="description2">another description</p>
<img id="image" />`,
function*(browser, accDoc) {
async function(browser, accDoc) {
let imgAcc = findAccessibleChildByID(accDoc, 'image');
for (let { desc, waitFor, attrs, expected } of tests) {
@ -148,10 +148,10 @@ addAccessibleTask(`
}
if (attrs) {
for (let { attr, value } of attrs) {
yield invokeSetAttribute(browser, 'image', attr, value);
await invokeSetAttribute(browser, 'image', attr, value);
}
}
yield onUpdate;
await onUpdate;
// When attribute change (alt) triggers reorder event, accessible will
// become defunct.
if (isDefunct(imgAcc)) {

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

@ -318,8 +318,8 @@ const markupTests = [{
* accessible, its parent and its content element
* id.
*/
function* updateAccessibleIfNeeded(onEvent, target) {
let event = yield onEvent;
async function updateAccessibleIfNeeded(onEvent, target) {
let event = await onEvent;
if (isDefunct(target.acc)) {
target.acc = findAccessibleChildByID(event.accessible, target.id);
}
@ -338,7 +338,7 @@ function* updateAccessibleIfNeeded(onEvent, target) {
* @param {Object} rule current attr rule for name calculation
* @param {[type]} expected expected name value
*/
function* testAttrRule(browser, target, rule, expected) {
async function testAttrRule(browser, target, rule, expected) {
testName(target.acc, expected);
let onEvent;
if (rule.recreated) {
@ -346,9 +346,9 @@ function* testAttrRule(browser, target, rule, expected) {
} else if (rule.textchanged) {
onEvent = waitForEvent(EVENT_TEXT_INSERTED, target.id);
}
yield invokeSetAttribute(browser, target.id, rule.attr);
await invokeSetAttribute(browser, target.id, rule.attr);
if (onEvent) {
yield updateAccessibleIfNeeded(onEvent, target);
await updateAccessibleIfNeeded(onEvent, target);
}
}
@ -364,13 +364,13 @@ function* testAttrRule(browser, target, rule, expected) {
* @param {Object} rule current elm rule for name calculation
* @param {[type]} expected expected name value
*/
function* testElmRule(browser, target, rule, expected) {
async function testElmRule(browser, target, rule, expected) {
testName(target.acc, expected);
let onEvent = waitForEvent(EVENT_REORDER, rule.isSibling ?
target.parent : target.id);
yield ContentTask.spawn(browser, rule.elm, elm =>
await ContentTask.spawn(browser, rule.elm, elm =>
content.document.querySelector(`${elm}`).remove());
yield updateAccessibleIfNeeded(onEvent, target);
await updateAccessibleIfNeeded(onEvent, target);
}
/**
@ -385,16 +385,16 @@ function* testElmRule(browser, target, rule, expected) {
* @param {Object} rule current subtree rule for name calculation
* @param {[type]} expected expected name value
*/
function* testSubtreeRule(browser, target, rule, expected) {
async function testSubtreeRule(browser, target, rule, expected) {
testName(target.acc, expected);
let onEvent = waitForEvent(EVENT_REORDER, target.id);
yield ContentTask.spawn(browser, target.id, id => {
await ContentTask.spawn(browser, target.id, id => {
let elm = content.document.getElementById(id);
while (elm.firstChild) {
elm.firstChild.remove();
}
});
yield updateAccessibleIfNeeded(onEvent, target);
await updateAccessibleIfNeeded(onEvent, target);
}
/**
@ -407,7 +407,7 @@ function* testSubtreeRule(browser, target, rule, expected) {
* @param {Array} ruleset A list of rules to test a target with
* @param {Array} expected A list of expected name value for each rule
*/
function* testNameRule(browser, target, ruleset, expected) {
async function testNameRule(browser, target, ruleset, expected) {
for (let i = 0; i < ruleset.length; ++i) {
let rule = ruleset[i];
let testFn;
@ -418,16 +418,16 @@ function* testNameRule(browser, target, ruleset, expected) {
} else if (rule.fromsubtree) {
testFn = testSubtreeRule;
}
yield testFn(browser, target, rule, expected[i]);
await testFn(browser, target, rule, expected[i]);
}
}
markupTests.forEach(({ id, ruleset, markup, expected }) =>
addAccessibleTask(markup, function*(browser, accDoc) {
addAccessibleTask(markup, async function(browser, accDoc) {
// Find a target accessible from an accessible subtree.
let acc = findAccessibleChildByID(accDoc, id);
// Find target's parent accessible from an accessible subtree.
let parent = getAccessibleDOMNodeID(acc.parent);
let target = { id, parent, acc };
yield testNameRule(browser, target, rules[ruleset], expected);
await testNameRule(browser, target, rules[ruleset], expected);
}));

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

@ -22,7 +22,7 @@ const attrRelationsSpec = [
['aria-flowto', RELATION_FLOWS_TO, RELATION_FLOWS_FROM]
];
function* testRelated(browser, accDoc, attr, hostRelation, dependantRelation) {
async function testRelated(browser, accDoc, attr, hostRelation, dependantRelation) {
let host = findAccessibleChildByID(accDoc, 'host');
let dependant1 = findAccessibleChildByID(accDoc, 'dependant1');
let dependant2 = findAccessibleChildByID(accDoc, 'dependant2');
@ -58,7 +58,7 @@ function* testRelated(browser, accDoc, attr, hostRelation, dependantRelation) {
if (attrs) {
for (let { key, value } of attrs) {
yield invokeSetAttribute(browser, 'host', key, value);
await invokeSetAttribute(browser, 'host', key, value);
}
}
@ -75,9 +75,9 @@ addAccessibleTask(`
<div id="dependant1">label</div>
<div id="dependant2">label2</div>
<div role="checkbox" id="host"></div>`,
function* (browser, accDoc) {
async function (browser, accDoc) {
for (let spec of attrRelationsSpec) {
yield testRelated(browser, accDoc, ...spec);
await testRelated(browser, accDoc, ...spec);
}
}
);

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

@ -91,15 +91,15 @@ const extraStateTests = [{
expected: [0, EXT_STATE_ENABLED]
}];
function* runStateTests(browser, accDoc, id, tests) {
async function runStateTests(browser, accDoc, id, tests) {
let acc = findAccessibleChildByID(accDoc, id);
for (let { desc, attrs, expected } of tests) {
info(desc);
let onUpdate = waitForEvent(EVENT_STATE_CHANGE, id);
for (let { attr, value } of attrs) {
yield invokeSetAttribute(browser, id, attr, value);
await invokeSetAttribute(browser, id, attr, value);
}
yield onUpdate;
await onUpdate;
testStates(acc, ...expected);
}
}
@ -111,9 +111,9 @@ addAccessibleTask(`
<input id="checkbox" type="checkbox">
<input id="file" type="file">
<input id="text">`,
function* (browser, accDoc) {
yield runStateTests(browser, accDoc, 'checkbox', attributeTests);
yield runStateTests(browser, accDoc, 'file', ariaTests);
yield runStateTests(browser, accDoc, 'text', extraStateTests);
async function (browser, accDoc) {
await runStateTests(browser, accDoc, 'checkbox', attributeTests);
await runStateTests(browser, accDoc, 'file', ariaTests);
await runStateTests(browser, accDoc, 'text', extraStateTests);
}
);

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

@ -13,7 +13,7 @@ loadScripts({ name: 'value.js', dir: MOCHITESTS_DIR });
* desc {String} description for better logging
* id {String} given accessible DOMNode ID
* expected {String} expected value for a given accessible
* action {?Function*} an optional action that yields a value change
* action {?AsyncFunction} an optional action that awaits a value change
* attrs {?Array} an optional list of attributes to update
* waitFor {?Number} an optional value change event to wait for
* }
@ -25,9 +25,9 @@ const valueTests = [{
}, {
desc: 'Value should update to 3rd when 3 is pressed',
id: 'select',
action: function*(browser) {
yield invokeFocus(browser, 'select');
yield BrowserTestUtils.synthesizeKey('3', {}, browser);
action: async function(browser) {
await invokeFocus(browser, 'select');
await BrowserTestUtils.synthesizeKey('3', {}, browser);
},
waitFor: EVENT_TEXT_VALUE_CHANGE,
expected: '3rd'
@ -102,9 +102,9 @@ const valueTests = [{
}, {
desc: 'Value should change when slider is moved',
id: 'range',
action: function*(browser) {
yield invokeFocus(browser, 'range');
yield BrowserTestUtils.synthesizeKey('VK_LEFT', {}, browser);
action: async function(browser) {
await invokeFocus(browser, 'range');
await BrowserTestUtils.synthesizeKey('VK_LEFT', {}, browser);
},
waitFor: EVENT_VALUE_CHANGE,
expected: '5'
@ -124,7 +124,7 @@ addAccessibleTask(`
<input id="combobox" role="combobox" aria-autocomplete="inline">
<progress id="progress" value="22" max="100"></progress>
<input type="range" id="range" min="0" max="10" value="6">`,
function* (browser, accDoc) {
async function (browser, accDoc) {
for (let { desc, id, action, attrs, expected, waitFor } of valueTests) {
info(desc);
let acc = findAccessibleChildByID(accDoc, id);
@ -135,14 +135,14 @@ addAccessibleTask(`
}
if (action) {
yield action(browser);
await action(browser);
} else if (attrs) {
for (let { attr, value } of attrs) {
yield invokeSetAttribute(browser, id, attr, value);
await invokeSetAttribute(browser, id, attr, value);
}
}
yield onUpdate;
await onUpdate;
if (Array.isArray(expected)) {
acc.QueryInterface(nsIAccessibleValue);
testValue(acc, ...expected);

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

@ -8,10 +8,10 @@
* Test caret move event and its interface:
* - caretOffset
*/
addAccessibleTask('<input id="textbox" value="hello"/>', function*(browser) {
addAccessibleTask('<input id="textbox" value="hello"/>', async function(browser) {
let onCaretMoved = waitForEvent(EVENT_TEXT_CARET_MOVED, 'textbox');
yield invokeFocus(browser, 'textbox');
let event = yield onCaretMoved;
await invokeFocus(browser, 'textbox');
let event = await onCaretMoved;
let caretMovedEvent = event.QueryInterface(nsIAccessibleCaretMoveEvent);
is(caretMovedEvent.caretOffset, 5,

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

@ -16,11 +16,11 @@ addAccessibleTask(`
<div id="to-hide"></div>
<div id="next"></div>
</div>`,
function*(browser, accDoc) {
async function(browser, accDoc) {
let acc = findAccessibleChildByID(accDoc, 'to-hide');
let onHide = waitForEvent(EVENT_HIDE, acc);
yield invokeSetStyle(browser, 'to-hide', 'visibility', 'hidden');
let event = yield onHide;
await invokeSetStyle(browser, 'to-hide', 'visibility', 'hidden');
let event = await onHide;
let hideEvent = event.QueryInterface(Ci.nsIAccessibleHideEvent);
is(getAccessibleDOMNodeID(hideEvent.targetParent), 'parent',

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

@ -8,8 +8,8 @@
* Test show event
*/
addAccessibleTask('<div id="div" style="visibility: hidden;"></div>',
function*(browser) {
async function(browser) {
let onShow = waitForEvent(EVENT_SHOW, 'div');
yield invokeSetStyle(browser, 'div', 'visibility', 'visible');
yield onShow;
await invokeSetStyle(browser, 'div', 'visibility', 'visible');
await onShow;
});

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

@ -36,14 +36,14 @@ let iframeSrc = `data:text/html,
*/
addAccessibleTask(`
<iframe id="iframe" src="${iframeSrc}"></iframe>
<input id="checkbox" type="checkbox" />`, function*(browser) {
<input id="checkbox" type="checkbox" />`, async function(browser) {
// Test state change
let onStateChange = waitForEvent(EVENT_STATE_CHANGE, 'checkbox');
// Set checked for a checkbox.
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
content.document.getElementById('checkbox').checked = true;
});
let event = yield onStateChange;
let event = await onStateChange;
checkStateChangeEvent(event, STATE_CHECKED, false, true);
testStates(event.accessible, STATE_CHECKED, 0);
@ -51,10 +51,10 @@ addAccessibleTask(`
// Test extra state
onStateChange = waitForEvent(EVENT_STATE_CHANGE, 'iframe');
// Set design mode on.
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
content.document.getElementById('iframe').contentDocument.designMode = 'on';
});
event = yield onStateChange;
event = await onStateChange;
checkStateChangeEvent(event, EXT_STATE_EDITABLE, true, true);
testStates(event.accessible, 0, EXT_STATE_EDITABLE);

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

@ -15,34 +15,34 @@ function checkTextChangeEvent(event, id, text, start, end, isInserted, isFromUse
`Correct value of isFromUserInput for ${prettyName(id)}`);
}
function* changeText(browser, id, value, events) {
async function changeText(browser, id, value, events) {
let onEvents = waitForMultipleEvents(events.map(({ isInserted }) => {
let eventType = isInserted ? EVENT_TEXT_INSERTED : EVENT_TEXT_REMOVED;
return { id, eventType };
}));
// Change text in the subtree.
yield ContentTask.spawn(browser, [id, value], ([contentId, contentValue]) => {
await ContentTask.spawn(browser, [id, value], ([contentId, contentValue]) => {
content.document.getElementById(contentId).firstChild.textContent =
contentValue;
});
let resolvedEvents = yield onEvents;
let resolvedEvents = await onEvents;
events.forEach(({ isInserted, str, offset }, idx) =>
checkTextChangeEvent(resolvedEvents[idx],
id, str, offset, offset + str.length, isInserted, false));
}
function* removeTextFromInput(browser, id, value, start, end) {
async function removeTextFromInput(browser, id, value, start, end) {
let onTextRemoved = waitForEvent(EVENT_TEXT_REMOVED, id);
// Select text and delete it.
yield ContentTask.spawn(browser, [id, start, end], ([contentId, contentStart, contentEnd]) => {
await ContentTask.spawn(browser, [id, start, end], ([contentId, contentStart, contentEnd]) => {
let el = content.document.getElementById(contentId);
el.focus();
el.setSelectionRange(contentStart, contentEnd);
});
yield BrowserTestUtils.sendChar('VK_DELETE', browser);
await BrowserTestUtils.sendChar('VK_DELETE', browser);
let event = yield onTextRemoved;
let event = await onTextRemoved;
checkTextChangeEvent(event, id, value, start, end, false, true);
}
@ -56,16 +56,16 @@ function* removeTextFromInput(browser, id, value, start, end) {
*/
addAccessibleTask(`
<p id="p">abc</p>
<input id="input" value="input" />`, function*(browser) {
<input id="input" value="input" />`, async function(browser) {
let events = [
{ isInserted: false, str: 'abc', offset: 0 },
{ isInserted: true, str: 'def', offset: 0 }
];
yield changeText(browser, 'p', 'def', events);
await changeText(browser, 'p', 'def', events);
events = [{ isInserted: true, str: 'DEF', offset: 2 }];
yield changeText(browser, 'p', 'deDEFf', events);
await changeText(browser, 'p', 'deDEFf', events);
// Test isFromUserInput property.
yield removeTextFromInput(browser, 'input', 'n', 1, 2);
await removeTextFromInput(browser, 'input', 'n', 1, 2);
});

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

@ -8,7 +8,7 @@
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
// Test ARIA Dialog
addAccessibleTask('doc_treeupdate_ariadialog.html', function*(browser, accDoc) {
addAccessibleTask('doc_treeupdate_ariadialog.html', async function(browser, accDoc) {
testAccessibleTree(accDoc, {
role: ROLE_DOCUMENT,
children: [ ]
@ -16,10 +16,10 @@ addAccessibleTask('doc_treeupdate_ariadialog.html', function*(browser, accDoc) {
// Make dialog visible and update its inner content.
let onShow = waitForEvent(EVENT_SHOW, 'dialog');
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
content.document.getElementById('dialog').style.display = 'block';
});
yield onShow;
await onShow;
testAccessibleTree(accDoc, {
role: ROLE_DOCUMENT,

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

@ -7,7 +7,7 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* testContainer1(browser, accDoc) {
async function testContainer1(browser, accDoc) {
const id = 't1_container';
const docID = getAccessibleDOMNodeID(accDoc);
const acc = findAccessibleChildByID(accDoc, id);
@ -26,8 +26,8 @@ function* testContainer1(browser, accDoc) {
/* ================ Change ARIA owns ====================================== */
let onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, id, 'aria-owns', 't1_button t1_subdiv');
yield onReorder;
await invokeSetAttribute(browser, id, 'aria-owns', 't1_button t1_subdiv');
await onReorder;
// children are swapped again, button and subdiv are appended to
// the children.
@ -42,8 +42,8 @@ function* testContainer1(browser, accDoc) {
/* ================ Remove ARIA owns ====================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, id, 'aria-owns');
yield onReorder;
await invokeSetAttribute(browser, id, 'aria-owns');
await onReorder;
// children follow the DOM order
tree = {
@ -58,8 +58,8 @@ function* testContainer1(browser, accDoc) {
/* ================ Set ARIA owns ========================================= */
onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, id, 'aria-owns', 't1_button t1_subdiv');
yield onReorder;
await invokeSetAttribute(browser, id, 'aria-owns', 't1_button t1_subdiv');
await onReorder;
// children are swapped again, button and subdiv are appended to
// the children.
@ -74,9 +74,9 @@ function* testContainer1(browser, accDoc) {
/* ================ Add ID to ARIA owns =================================== */
onReorder = waitForEvent(EVENT_REORDER, docID);
yield invokeSetAttribute(browser, id, 'aria-owns',
await invokeSetAttribute(browser, id, 'aria-owns',
't1_button t1_subdiv t1_group');
yield onReorder;
await onReorder;
// children are swapped again, button and subdiv are appended to
// the children.
@ -92,13 +92,13 @@ function* testContainer1(browser, accDoc) {
/* ================ Append element ======================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let div = content.document.createElement('div');
div.setAttribute('id', 't1_child3');
div.setAttribute('role', 'radio');
content.document.getElementById(contentId).appendChild(div);
});
yield onReorder;
await onReorder;
// children are invalidated, they includes aria-owns swapped kids and
// newly inserted child.
@ -115,9 +115,9 @@ function* testContainer1(browser, accDoc) {
/* ================ Remove element ======================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () =>
await ContentTask.spawn(browser, {}, () =>
content.document.getElementById('t1_span').remove());
yield onReorder;
await onReorder;
// subdiv should go away
tree = {
@ -132,8 +132,8 @@ function* testContainer1(browser, accDoc) {
/* ================ Remove ID ============================================= */
onReorder = waitForEvent(EVENT_REORDER, docID);
yield invokeSetAttribute(browser, 't1_group', 'id');
yield onReorder;
await invokeSetAttribute(browser, 't1_group', 'id');
await onReorder;
tree = {
SECTION: [
@ -146,8 +146,8 @@ function* testContainer1(browser, accDoc) {
/* ================ Set ID ================================================ */
onReorder = waitForEvent(EVENT_REORDER, docID);
yield invokeSetAttribute(browser, 't1_grouptmp', 'id', 't1_group');
yield onReorder;
await invokeSetAttribute(browser, 't1_grouptmp', 'id', 't1_group');
await onReorder;
tree = {
SECTION: [
@ -160,7 +160,7 @@ function* testContainer1(browser, accDoc) {
testAccessibleTree(acc, tree);
}
function* removeContainer(browser, accDoc) {
async function removeContainer(browser, accDoc) {
const id = 't2_container1';
const acc = findAccessibleChildByID(accDoc, id);
@ -172,10 +172,10 @@ function* removeContainer(browser, accDoc) {
testAccessibleTree(acc, tree);
let onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () =>
await ContentTask.spawn(browser, {}, () =>
content.document.getElementById('t2_container2').removeChild(
content.document.getElementById('t2_container3')));
yield onReorder;
await onReorder;
tree = {
SECTION: [ ]
@ -183,7 +183,7 @@ function* removeContainer(browser, accDoc) {
testAccessibleTree(acc, tree);
}
function* stealAndRecacheChildren(browser, accDoc) {
async function stealAndRecacheChildren(browser, accDoc) {
const id1 = 't3_container1';
const id2 = 't3_container2';
const acc1 = findAccessibleChildByID(accDoc, id1);
@ -191,8 +191,8 @@ function* stealAndRecacheChildren(browser, accDoc) {
/* ================ Steal from other ARIA owns ============================ */
let onReorder = waitForEvent(EVENT_REORDER, id2);
yield invokeSetAttribute(browser, id2, 'aria-owns', 't3_child');
yield onReorder;
await invokeSetAttribute(browser, id2, 'aria-owns', 't3_child');
await onReorder;
let tree = {
SECTION: [ ]
@ -208,12 +208,12 @@ function* stealAndRecacheChildren(browser, accDoc) {
/* ================ Append element to recache children ==================== */
onReorder = waitForEvent(EVENT_REORDER, id2);
yield ContentTask.spawn(browser, id2, id => {
await ContentTask.spawn(browser, id2, id => {
let div = content.document.createElement('div');
div.setAttribute('role', 'radio');
content.document.getElementById(id).appendChild(div);
});
yield onReorder;
await onReorder;
tree = {
SECTION: [ ]
@ -229,7 +229,7 @@ function* stealAndRecacheChildren(browser, accDoc) {
testAccessibleTree(acc2, tree);
}
function* showHiddenElement(browser, accDoc) {
async function showHiddenElement(browser, accDoc) {
const id = 't4_container1';
const acc = findAccessibleChildByID(accDoc, id);
@ -241,8 +241,8 @@ function* showHiddenElement(browser, accDoc) {
testAccessibleTree(acc, tree);
let onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetStyle(browser, 't4_child1', 'display', 'block');
yield onReorder;
await invokeSetStyle(browser, 't4_child1', 'display', 'block');
await onReorder;
tree = {
SECTION: [
@ -253,7 +253,7 @@ function* showHiddenElement(browser, accDoc) {
testAccessibleTree(acc, tree);
}
function* rearrangeARIAOwns(browser, accDoc) {
async function rearrangeARIAOwns(browser, accDoc) {
const id = 't5_container';
const acc = findAccessibleChildByID(accDoc, id);
const tests = [{
@ -266,8 +266,8 @@ function* rearrangeARIAOwns(browser, accDoc) {
for (let { val, roleList } of tests) {
let onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, id, 'aria-owns', val);
yield onReorder;
await invokeSetAttribute(browser, id, 'aria-owns', val);
await onReorder;
let tree = { SECTION: [ ] };
for (let role of roleList) {
@ -279,7 +279,7 @@ function* rearrangeARIAOwns(browser, accDoc) {
}
}
function* removeNotARIAOwnedEl(browser, accDoc) {
async function removeNotARIAOwnedEl(browser, accDoc) {
const id = 't6_container';
const acc = findAccessibleChildByID(accDoc, id);
@ -292,11 +292,11 @@ function* removeNotARIAOwnedEl(browser, accDoc) {
testAccessibleTree(acc, tree);
let onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
content.document.getElementById(contentId).removeChild(
content.document.getElementById('t6_span'));
});
yield onReorder;
await onReorder;
tree = {
SECTION: [
@ -306,11 +306,11 @@ function* removeNotARIAOwnedEl(browser, accDoc) {
testAccessibleTree(acc, tree);
}
addAccessibleTask('doc_treeupdate_ariaowns.html', function*(browser, accDoc) {
yield testContainer1(browser, accDoc);
yield removeContainer(browser, accDoc);
yield stealAndRecacheChildren(browser, accDoc);
yield showHiddenElement(browser, accDoc);
yield rearrangeARIAOwns(browser, accDoc);
yield removeNotARIAOwnedEl(browser, accDoc);
addAccessibleTask('doc_treeupdate_ariaowns.html', async function(browser, accDoc) {
await testContainer1(browser, accDoc);
await removeContainer(browser, accDoc);
await stealAndRecacheChildren(browser, accDoc);
await showHiddenElement(browser, accDoc);
await rearrangeARIAOwns(browser, accDoc);
await removeNotARIAOwnedEl(browser, accDoc);
});

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

@ -10,15 +10,15 @@ loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask(`
<canvas id="canvas">
<div id="dialog" role="dialog" style="display: none;"></div>
</canvas>`, function*(browser, accDoc) {
</canvas>`, async function(browser, accDoc) {
let canvas = findAccessibleChildByID(accDoc, 'canvas');
let dialog = findAccessibleChildByID(accDoc, 'dialog');
testAccessibleTree(canvas, { CANVAS: [] });
let onShow = waitForEvent(EVENT_SHOW, 'dialog');
yield invokeSetStyle(browser, 'dialog', 'display', 'block');
yield onShow;
await invokeSetStyle(browser, 'dialog', 'display', 'block');
await onShow;
testAccessibleTree(dialog, { DIALOG: [] });
});

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

@ -11,7 +11,7 @@ addAccessibleTask(`
<div id="container"><div id="scrollarea" style="overflow:auto;"><input>
</div></div>
<div id="container2"><div id="scrollarea2" style="overflow:hidden;">
</div></div>`, function*(browser, accDoc) {
</div></div>`, async function(browser, accDoc) {
const id1 = 'container';
const id2 = 'container2';
const container = findAccessibleChildByID(accDoc, id1);
@ -28,12 +28,12 @@ addAccessibleTask(`
testAccessibleTree(container, tree);
let onReorder = waitForEvent(EVENT_REORDER, id1);
yield ContentTask.spawn(browser, id1, id => {
await ContentTask.spawn(browser, id1, id => {
let doc = content.document;
doc.getElementById('scrollarea').style.width = '20px';
doc.getElementById(id).appendChild(doc.createElement('input'));
});
yield onReorder;
await onReorder;
tree = {
SECTION: [ {// container
@ -51,8 +51,8 @@ addAccessibleTask(`
testAccessibleTree(container2, tree);
onReorder = waitForEvent(EVENT_REORDER, id2);
yield invokeSetStyle(browser, 'scrollarea2', 'overflow', 'auto');
yield onReorder;
await invokeSetStyle(browser, 'scrollarea2', 'overflow', 'auto');
await onReorder;
tree = {
SECTION: [ // container

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

@ -17,7 +17,7 @@ const iframeSrc = `data:text/html,
</html>`;
addAccessibleTask(`
<iframe id="iframe" src="${iframeSrc}"></iframe>`, function*(browser, accDoc) {
<iframe id="iframe" src="${iframeSrc}"></iframe>`, async function(browser, accDoc) {
// ID of the iframe that is being tested
const id = 'inner-iframe';
@ -32,7 +32,7 @@ addAccessibleTask(`
/* ================= Write iframe document ================================ */
let reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let docNode = content.document.getElementById('iframe').contentDocument;
let newHTMLNode = docNode.createElement('html');
let newBodyNode = docNode.createElement('body');
@ -42,7 +42,7 @@ addAccessibleTask(`
newHTMLNode.appendChild(newBodyNode);
docNode.replaceChild(newHTMLNode, docNode.documentElement);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -57,7 +57,7 @@ addAccessibleTask(`
/* ================= Replace iframe HTML element ========================== */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let docNode = content.document.getElementById('iframe').contentDocument;
// We can't use open/write/close outside of iframe document because of
// security error.
@ -68,7 +68,7 @@ addAccessibleTask(`
document.close();`;
docNode.body.appendChild(script);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -83,7 +83,7 @@ addAccessibleTask(`
/* ================= Replace iframe body ================================== */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let docNode = content.document.getElementById('iframe').contentDocument;
let newBodyNode = docNode.createElement('body');
let newTextNode = docNode.createTextNode('New Hello');
@ -92,7 +92,7 @@ addAccessibleTask(`
newBodyNode.setAttribute('role', 'button');
docNode.documentElement.replaceChild(newBodyNode, docNode.body);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_PUSHBUTTON,
@ -107,7 +107,7 @@ addAccessibleTask(`
/* ================= Open iframe document ================================= */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
// Open document.
let docNode = content.document.getElementById('iframe').contentDocument;
let script = docNode.createElement('script');
@ -121,7 +121,7 @@ addAccessibleTask(`
document.write('<body id="${contentId}"></body>');`;
docNode.body.appendChild(script);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -131,13 +131,13 @@ addAccessibleTask(`
/* ================= Close iframe document ================================ */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
// Write and close document.
let docNode = content.document.getElementById('iframe').contentDocument;
docNode.write('Works?');
docNode.close();
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -152,12 +152,12 @@ addAccessibleTask(`
/* ================= Remove HTML from iframe document ===================== */
reorderEventPromise = waitForEvent(EVENT_REORDER, iframe);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
// Remove HTML element.
let docNode = content.document.getElementById('iframe').contentDocument;
docNode.firstChild.remove();
});
let event = yield reorderEventPromise;
let event = await reorderEventPromise;
ok(event.accessible instanceof nsIAccessibleDocument,
'Reorder should happen on the document');
@ -169,7 +169,7 @@ addAccessibleTask(`
/* ================= Insert HTML to iframe document ======================= */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
// Insert HTML element.
let docNode = content.document.getElementById('iframe').contentDocument;
let html = docNode.createElement('html');
@ -180,7 +180,7 @@ addAccessibleTask(`
html.appendChild(body);
docNode.appendChild(html);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -195,12 +195,12 @@ addAccessibleTask(`
/* ================= Remove body from iframe document ===================== */
reorderEventPromise = waitForEvent(EVENT_REORDER, iframe);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
// Remove body element.
let docNode = content.document.getElementById('iframe').contentDocument;
docNode.documentElement.removeChild(docNode.body);
});
event = yield reorderEventPromise;
event = await reorderEventPromise;
ok(event.accessible instanceof nsIAccessibleDocument,
'Reorder should happen on the document');
@ -212,12 +212,12 @@ addAccessibleTask(`
/* ================ Insert element under document element while body missed */
reorderEventPromise = waitForEvent(EVENT_REORDER, iframe);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let docNode = content.document.getElementById('iframe').contentDocument;
let inputNode = content.window.inputNode = docNode.createElement('input');
docNode.documentElement.appendChild(inputNode);
});
event = yield reorderEventPromise;
event = await reorderEventPromise;
ok(event.accessible instanceof nsIAccessibleDocument,
'Reorder should happen on the document');
@ -229,14 +229,14 @@ addAccessibleTask(`
testAccessibleTree(iframe, tree);
reorderEventPromise = waitForEvent(EVENT_REORDER, iframe);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let docEl =
content.document.getElementById('iframe').contentDocument.documentElement;
// Remove aftermath of this test before next test starts.
docEl.firstChild.remove();
});
// Make sure reorder event was fired and that the input was removed.
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
children: [ ]
@ -245,7 +245,7 @@ addAccessibleTask(`
/* ================= Insert body to iframe document ======================= */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
// Write and close document.
let docNode = content.document.getElementById('iframe').contentDocument;
// Insert body element.
@ -255,7 +255,7 @@ addAccessibleTask(`
body.id = contentId;
docNode.documentElement.appendChild(body);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_DOCUMENT,
@ -270,9 +270,9 @@ addAccessibleTask(`
/* ================= Change source ======================================== */
reorderEventPromise = waitForEvent(EVENT_REORDER, 'iframe');
yield invokeSetAttribute(browser, 'iframe', 'src',
await invokeSetAttribute(browser, 'iframe', 'src',
`data:text/html,<html><body id="${id}"><input></body></html>`);
event = yield reorderEventPromise;
event = await reorderEventPromise;
tree = {
INTERNAL_FRAME: [
@ -286,7 +286,7 @@ addAccessibleTask(`
/* ================= Replace iframe body on ARIA role body ================ */
reorderEventPromise = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let docNode = content.document.getElementById('iframe').contentDocument;
let newBodyNode = docNode.createElement('body');
let newTextNode = docNode.createTextNode('New Hello');
@ -295,7 +295,7 @@ addAccessibleTask(`
newBodyNode.id = contentId;
docNode.documentElement.replaceChild(newBodyNode, docNode.body);
});
yield reorderEventPromise;
await reorderEventPromise;
tree = {
role: ROLE_PUSHBUTTON,

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

@ -18,7 +18,7 @@ addAccessibleTask(`
</style>
<div id="container1"></div>
<div id="container2"><div id="container2_child">text</div></div>`,
function*(browser, accDoc) {
async function(browser, accDoc) {
const id1 = 'container1';
const id2 = 'container2';
let container1 = findAccessibleChildByID(accDoc, id1);
@ -40,13 +40,13 @@ addAccessibleTask(`
let onReorder = waitForEvent(EVENT_REORDER, id1);
// Create and add an element with CSS generated content to container1
yield ContentTask.spawn(browser, id1, id => {
await ContentTask.spawn(browser, id1, id => {
let node = content.document.createElement('div');
node.textContent = 'text';
node.setAttribute('class', 'gentext');
content.document.getElementById(id).appendChild(node);
});
yield onReorder;
await onReorder;
tree = {
SECTION: [ // container
@ -61,8 +61,8 @@ addAccessibleTask(`
onReorder = waitForEvent(EVENT_REORDER, id2);
// Add CSS generated content to an element in container2's subtree
yield invokeSetAttribute(browser, 'container2_child', 'class', 'gentext');
yield onReorder;
await invokeSetAttribute(browser, 'container2_child', 'class', 'gentext');
await onReorder;
tree = {
SECTION: [ // container2

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

@ -7,23 +7,23 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* setHidden(browser, value) {
async function setHidden(browser, value) {
let onReorder = waitForEvent(EVENT_REORDER, 'container');
yield invokeSetAttribute(browser, 'child', 'hidden', value);
yield onReorder;
await invokeSetAttribute(browser, 'child', 'hidden', value);
await onReorder;
}
addAccessibleTask('<div id="container"><input id="child"></div>',
function*(browser, accDoc) {
async function(browser, accDoc) {
let container = findAccessibleChildByID(accDoc, 'container');
testAccessibleTree(container, { SECTION: [ { ENTRY: [ ] } ] });
// Set @hidden attribute
yield setHidden(browser, 'true');
await setHidden(browser, 'true');
testAccessibleTree(container, { SECTION: [ ] });
// Remove @hidden attribute
yield setHidden(browser);
await setHidden(browser);
testAccessibleTree(container, { SECTION: [ { ENTRY: [ ] } ] });
});

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

@ -7,7 +7,7 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* testImageMap(browser, accDoc) {
async function testImageMap(browser, accDoc) {
const id = 'imgmap';
const acc = findAccessibleChildByID(accDoc, id);
@ -21,7 +21,7 @@ function* testImageMap(browser, accDoc) {
/* ================= Insert area ========================================== */
let onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let areaElm = content.document.createElement('area');
let mapNode = content.document.getElementById('map');
areaElm.setAttribute('href',
@ -31,7 +31,7 @@ function* testImageMap(browser, accDoc) {
areaElm.setAttribute('shape', 'rect');
mapNode.insertBefore(areaElm, mapNode.firstChild);
});
yield onReorder;
await onReorder;
tree = {
IMAGE_MAP: [
@ -43,7 +43,7 @@ function* testImageMap(browser, accDoc) {
/* ================= Append area ========================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let areaElm = content.document.createElement('area');
let mapNode = content.document.getElementById('map');
areaElm.setAttribute('href',
@ -53,7 +53,7 @@ function* testImageMap(browser, accDoc) {
areaElm.setAttribute('shape', 'rect');
mapNode.appendChild(areaElm);
});
yield onReorder;
await onReorder;
tree = {
IMAGE_MAP: [
@ -66,11 +66,11 @@ function* testImageMap(browser, accDoc) {
/* ================= Remove area ========================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let mapNode = content.document.getElementById('map');
mapNode.removeChild(mapNode.firstElementChild);
});
yield onReorder;
await onReorder;
tree = {
IMAGE_MAP: [
@ -81,12 +81,12 @@ function* testImageMap(browser, accDoc) {
testAccessibleTree(acc, tree);
}
function* testContainer(browser) {
async function testContainer(browser) {
const id = 'container';
/* ================= Remove name on map =================================== */
let onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, 'map', 'name');
let event = yield onReorder;
await invokeSetAttribute(browser, 'map', 'name');
let event = await onReorder;
const acc = event.accessible;
let tree = {
@ -98,11 +98,11 @@ function* testContainer(browser) {
/* ================= Restore name on map ================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetAttribute(browser, 'map', 'name', 'atoz_map');
await invokeSetAttribute(browser, 'map', 'name', 'atoz_map');
// XXX: force repainting of the image (see bug 745788 for details).
yield BrowserTestUtils.synthesizeMouse('#imgmap', 10, 10,
await BrowserTestUtils.synthesizeMouse('#imgmap', 10, 10,
{ type: 'mousemove' }, browser);
yield onReorder;
await onReorder;
tree = {
SECTION: [ {
@ -116,11 +116,11 @@ function* testContainer(browser) {
/* ================= Remove map =========================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let mapNode = content.document.getElementById('map');
mapNode.remove();
});
yield onReorder;
await onReorder;
tree = {
SECTION: [
@ -131,7 +131,7 @@ function* testContainer(browser) {
/* ================= Insert map =========================================== */
onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
let map = content.document.createElement('map');
let area = content.document.createElement('area');
@ -147,7 +147,7 @@ function* testContainer(browser) {
map.appendChild(area);
content.document.getElementById(contentId).appendChild(map);
});
yield onReorder;
await onReorder;
tree = {
SECTION: [ {
@ -160,8 +160,8 @@ function* testContainer(browser) {
/* ================= Hide image map ======================================= */
onReorder = waitForEvent(EVENT_REORDER, id);
yield invokeSetStyle(browser, 'imgmap', 'display', 'none');
yield onReorder;
await invokeSetStyle(browser, 'imgmap', 'display', 'none');
await onReorder;
tree = {
SECTION: [ ]
@ -169,7 +169,7 @@ function* testContainer(browser) {
testAccessibleTree(acc, tree);
}
function* waitForImageMap(browser, accDoc) {
async function waitForImageMap(browser, accDoc) {
const id = 'imgmap';
const acc = findAccessibleChildByID(accDoc, id);
if (acc.firstChild) {
@ -178,13 +178,13 @@ function* waitForImageMap(browser, accDoc) {
const onReorder = waitForEvent(EVENT_REORDER, id);
// Wave over image map
yield BrowserTestUtils.synthesizeMouse(`#${id}`, 10, 10,
await BrowserTestUtils.synthesizeMouse(`#${id}`, 10, 10,
{ type: 'mousemove' }, browser);
yield onReorder;
await onReorder;
}
addAccessibleTask('doc_treeupdate_imagemap.html', function*(browser, accDoc) {
yield waitForImageMap(browser, accDoc);
yield testImageMap(browser, accDoc);
yield testContainer(browser);
addAccessibleTask('doc_treeupdate_imagemap.html', async function(browser, accDoc) {
await waitForImageMap(browser, accDoc);
await testImageMap(browser, accDoc);
await testContainer(browser);
});

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

@ -7,16 +7,16 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* setDisplayAndWaitForReorder(browser, value) {
async function setDisplayAndWaitForReorder(browser, value) {
let onReorder = waitForEvent(EVENT_REORDER, 'ul');
yield invokeSetStyle(browser, 'li', 'display', value);
return yield onReorder;
await invokeSetStyle(browser, 'li', 'display', value);
return await onReorder;
}
addAccessibleTask(`
<ul id="ul">
<li id="li">item1</li>
</ul>`, function*(browser, accDoc) {
</ul>`, async function(browser, accDoc) {
let li = findAccessibleChildByID(accDoc, 'li');
let bullet = li.firstChild;
let accTree = {
@ -31,12 +31,12 @@ addAccessibleTask(`
};
testAccessibleTree(li, accTree);
yield setDisplayAndWaitForReorder(browser, 'none');
await setDisplayAndWaitForReorder(browser, 'none');
ok(isDefunct(li), 'Check that li is defunct.');
ok(isDefunct(bullet), 'Check that bullet is defunct.');
let event = yield setDisplayAndWaitForReorder(browser, 'list-item');
let event = await setDisplayAndWaitForReorder(browser, 'list-item');
testAccessibleTree(findAccessibleChildByID(event.accessible, 'li'), accTree);
});

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

@ -7,7 +7,7 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask('<ol id="list"></ol>', function*(browser, accDoc) {
addAccessibleTask('<ol id="list"></ol>', async function(browser, accDoc) {
let list = findAccessibleChildByID(accDoc, 'list');
testAccessibleTree(list, {
@ -15,14 +15,14 @@ addAccessibleTask('<ol id="list"></ol>', function*(browser, accDoc) {
children: [ ]
});
yield invokeSetAttribute(browser, 'body', 'contentEditable', 'true');
await invokeSetAttribute(browser, 'body', 'contentEditable', 'true');
let onReorder = waitForEvent(EVENT_REORDER, 'list');
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let li = content.document.createElement('li');
li.textContent = 'item';
content.document.getElementById('list').appendChild(li);
});
yield onReorder;
await onReorder;
testAccessibleTree(list, {
role: ROLE_LIST,

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

@ -8,7 +8,7 @@
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask('<span id="parent"><span id="child"></span></span>',
function*(browser, accDoc) {
async function(browser, accDoc) {
is(findAccessibleChildByID(accDoc, 'parent'), null,
'Check that parent is not accessible.');
is(findAccessibleChildByID(accDoc, 'child'), null,
@ -16,12 +16,12 @@ addAccessibleTask('<span id="parent"><span id="child"></span></span>',
let onReorder = waitForEvent(EVENT_REORDER, 'body');
// Add an event listener to parent.
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
content.window.dummyListener = () => {};
content.document.getElementById('parent').addEventListener(
'click', content.window.dummyListener);
});
yield onReorder;
await onReorder;
let tree = { TEXT: [] };
testAccessibleTree(findAccessibleChildByID(accDoc, 'parent'), tree);

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

@ -7,12 +7,12 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask('<select id="select"></select>', function*(browser, accDoc) {
addAccessibleTask('<select id="select"></select>', async function(browser, accDoc) {
let select = findAccessibleChildByID(accDoc, 'select');
let onEvent = waitForEvent(EVENT_REORDER, 'select');
// Create a combobox with grouping and 2 standalone options
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let doc = content.document;
let contentSelect = doc.getElementById('select');
let optGroup = doc.createElement('optgroup');
@ -31,7 +31,7 @@ addAccessibleTask('<select id="select"></select>', function*(browser, accDoc) {
}
contentSelect.firstChild.firstChild.id = 'option1Node';
});
let event = yield onEvent;
let event = await onEvent;
let option1Node = findAccessibleChildByID(event.accessible, 'option1Node');
let tree = {
@ -53,11 +53,11 @@ addAccessibleTask('<select id="select"></select>', function*(browser, accDoc) {
onEvent = waitForEvent(EVENT_REORDER, 'select');
// Remove grouping from combobox
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let contentSelect = content.document.getElementById('select');
contentSelect.firstChild.remove();
});
yield onEvent;
await onEvent;
tree = {
COMBOBOX: [ {
@ -73,13 +73,13 @@ addAccessibleTask('<select id="select"></select>', function*(browser, accDoc) {
onEvent = waitForEvent(EVENT_REORDER, 'select');
// Remove all options from combobox
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let contentSelect = content.document.getElementById('select');
while (contentSelect.length) {
contentSelect.remove(0);
}
});
yield onEvent;
await onEvent;
tree = {
COMBOBOX: [ {

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

@ -7,16 +7,16 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask('doc_treeupdate_removal.xhtml', function*(browser, accDoc) {
addAccessibleTask('doc_treeupdate_removal.xhtml', async function(browser, accDoc) {
ok(isAccessible(findAccessibleChildByID(accDoc, 'the_table')),
'table should be accessible');
// Move the_table element into hidden subtree.
let onReorder = waitForEvent(EVENT_REORDER, 'body');
yield ContentTask.spawn(browser, {}, () => content.document.getElementById(
await ContentTask.spawn(browser, {}, () => content.document.getElementById(
'the_displaynone').appendChild(content.document.getElementById(
'the_table')));
yield onReorder;
await onReorder;
ok(!isAccessible(findAccessibleChildByID(accDoc, 'the_table')),
'table in display none tree shouldn\'t be accessible');
@ -24,7 +24,7 @@ addAccessibleTask('doc_treeupdate_removal.xhtml', function*(browser, accDoc) {
'row shouldn\'t be accessible');
// Remove the_row element (since it did not have accessible, no event needed).
yield ContentTask.spawn(browser, {}, () =>
await ContentTask.spawn(browser, {}, () =>
content.document.body.removeChild(
content.document.getElementById('the_row')));

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

@ -13,7 +13,7 @@ addAccessibleTask(`
<td>cell1</td>
<td>cell2</td>
</tr>
</table>`, function*(browser, accDoc) {
</table>`, async function(browser, accDoc) {
let table = findAccessibleChildByID(accDoc, 'table');
let tree = {
@ -27,7 +27,7 @@ addAccessibleTask(`
testAccessibleTree(table, tree);
let onReorder = waitForEvent(EVENT_REORDER, 'table');
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
// append a caption, it should appear as a first element in the
// accessible tree.
let doc = content.document;
@ -35,7 +35,7 @@ addAccessibleTask(`
caption.textContent = 'table caption';
doc.getElementById('table').appendChild(caption);
});
yield onReorder;
await onReorder;
tree = {
TABLE: [

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

@ -7,7 +7,7 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* removeTextData(browser, accessible, id, role) {
async function removeTextData(browser, accessible, id, role) {
let tree = {
role: role,
children: [ { role: ROLE_TEXT_LEAF, name: "text" } ]
@ -15,10 +15,10 @@ function* removeTextData(browser, accessible, id, role) {
testAccessibleTree(accessible, tree);
let onReorder = waitForEvent(EVENT_REORDER, id);
yield ContentTask.spawn(browser, id, contentId => {
await ContentTask.spawn(browser, id, contentId => {
content.document.getElementById(contentId).firstChild.textContent = '';
});
yield onReorder;
await onReorder;
tree = { role: role, children: [] };
testAccessibleTree(accessible, tree);
@ -26,9 +26,9 @@ function* removeTextData(browser, accessible, id, role) {
addAccessibleTask(`
<p id="p">text</p>
<pre id="pre">text</pre>`, function*(browser, accDoc) {
<pre id="pre">text</pre>`, async function(browser, accDoc) {
let p = findAccessibleChildByID(accDoc, 'p');
let pre = findAccessibleChildByID(accDoc, 'pre');
yield removeTextData(browser, p, 'p', ROLE_PARAGRAPH);
yield removeTextData(browser, pre, 'pre', ROLE_TEXT_CONTAINER);
await removeTextData(browser, p, 'p', ROLE_PARAGRAPH);
await removeTextData(browser, pre, 'pre', ROLE_TEXT_CONTAINER);
});

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

@ -7,18 +7,18 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
function* testTreeOnHide(browser, accDoc, containerID, id, before, after) {
async function testTreeOnHide(browser, accDoc, containerID, id, before, after) {
let acc = findAccessibleChildByID(accDoc, containerID);
testAccessibleTree(acc, before);
let onReorder = waitForEvent(EVENT_REORDER, containerID);
yield invokeSetStyle(browser, id, 'visibility', 'hidden');
yield onReorder;
await invokeSetStyle(browser, id, 'visibility', 'hidden');
await onReorder;
testAccessibleTree(acc, after);
}
function* test3(browser, accessible) {
async function test3(browser, accessible) {
let tree = {
SECTION: [ // container
{ SECTION: [ // parent
@ -35,13 +35,13 @@ function* test3(browser, accessible) {
testAccessibleTree(accessible, tree);
let onReorder = waitForEvent(EVENT_REORDER, 't3_container');
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let doc = content.document;
doc.getElementById('t3_container').style.color = 'red';
doc.getElementById('t3_parent').style.visibility = 'hidden';
doc.getElementById('t3_parent2').style.visibility = 'hidden';
});
yield onReorder;
await onReorder;
tree = {
SECTION: [ // container
@ -55,7 +55,7 @@ function* test3(browser, accessible) {
testAccessibleTree(accessible, tree);
}
function* test4(browser, accessible) {
async function test4(browser, accessible) {
let tree = {
SECTION: [
{ TABLE: [
@ -67,12 +67,12 @@ function* test4(browser, accessible) {
testAccessibleTree(accessible, tree);
let onReorder = waitForEvent(EVENT_REORDER, 't4_parent');
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let doc = content.document;
doc.getElementById('t4_container').style.color = 'red';
doc.getElementById('t4_child').style.visibility = 'visible';
});
yield onReorder;
await onReorder;
tree = {
SECTION: [{
@ -90,11 +90,11 @@ function* test4(browser, accessible) {
testAccessibleTree(accessible, tree);
}
addAccessibleTask('doc_treeupdate_visibility.html', function*(browser, accDoc) {
addAccessibleTask('doc_treeupdate_visibility.html', async function(browser, accDoc) {
let t3Container = findAccessibleChildByID(accDoc, 't3_container');
let t4Container = findAccessibleChildByID(accDoc, 't4_container');
yield testTreeOnHide(browser, accDoc, 't1_container', 't1_parent', {
await testTreeOnHide(browser, accDoc, 't1_container', 't1_parent', {
SECTION: [{
SECTION: [{
SECTION: [ { TEXT_LEAF: [] } ]
@ -106,7 +106,7 @@ addAccessibleTask('doc_treeupdate_visibility.html', function*(browser, accDoc) {
} ]
});
yield testTreeOnHide(browser, accDoc, 't2_container', 't2_grandparent', {
await testTreeOnHide(browser, accDoc, 't2_container', 't2_grandparent', {
SECTION: [{ // container
SECTION: [{ // grand parent
SECTION: [{
@ -132,10 +132,10 @@ addAccessibleTask('doc_treeupdate_visibility.html', function*(browser, accDoc) {
}]
});
yield test3(browser, t3Container);
yield test4(browser, t4Container);
await test3(browser, t3Container);
await test4(browser, t4Container);
yield testTreeOnHide(browser, accDoc, 't5_container', 't5_subcontainer', {
await testTreeOnHide(browser, accDoc, 't5_container', 't5_subcontainer', {
SECTION: [{ // container
SECTION: [{ // subcontainer
TABLE: [{
@ -157,7 +157,7 @@ addAccessibleTask('doc_treeupdate_visibility.html', function*(browser, accDoc) {
}]
});
yield testTreeOnHide(browser, accDoc, 't6_container', 't6_subcontainer', {
await testTreeOnHide(browser, accDoc, 't6_container', 't6_subcontainer', {
SECTION: [{ // container
SECTION: [{ // subcontainer
TABLE: [{

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

@ -7,7 +7,7 @@
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: 'role.js', dir: MOCHITESTS_DIR });
addAccessibleTask('doc_treeupdate_whitespace.html', function*(browser, accDoc) {
addAccessibleTask('doc_treeupdate_whitespace.html', async function(browser, accDoc) {
let container1 = findAccessibleChildByID(accDoc, 'container1');
let container2Parent = findAccessibleChildByID(accDoc, 'container2-parent');
@ -24,12 +24,12 @@ addAccessibleTask('doc_treeupdate_whitespace.html', function*(browser, accDoc) {
let onReorder = waitForEvent(EVENT_REORDER, 'container1');
// Remove img1 from container1
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let doc = content.document;
doc.getElementById('container1').removeChild(
doc.getElementById('img1'));
});
yield onReorder;
await onReorder;
tree = {
SECTION: [
@ -50,14 +50,14 @@ addAccessibleTask('doc_treeupdate_whitespace.html', function*(browser, accDoc) {
onReorder = waitForEvent(EVENT_REORDER, 'container2-parent');
// Append an img with valid src to container2
yield ContentTask.spawn(browser, {}, () => {
await ContentTask.spawn(browser, {}, () => {
let doc = content.document;
let img = doc.createElement('img');
img.setAttribute('src',
'http://example.com/a11y/accessible/tests/mochitest/moz.png');
doc.getElementById('container2').appendChild(img);
});
yield onReorder;
await onReorder;
tree = {
SECTION: [

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

@ -18,11 +18,11 @@ Services.scriptloader.loadSubScript(
* @param {String} doc URL (relative to current directory) or
* data URL or markup snippet that is used
* to test content with
* @param {Function|Function*} task a generator or a function with tests to
* @param {Function|AsyncFunction} task a generator or a function with tests to
* run
*/
function addAccessibleTask(doc, task) {
add_task(function*() {
add_task(async function() {
let url;
if (doc.includes('doc_')) {
url = `${CURRENT_CONTENT_DIR}e10s/${doc}`;
@ -49,10 +49,10 @@ function addAccessibleTask(doc, task) {
let onDocLoad = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
yield BrowserTestUtils.withNewTab({
await BrowserTestUtils.withNewTab({
gBrowser,
url: url
}, function*(browser) {
}, async function(browser) {
registerCleanupFunction(() => {
if (browser) {
let tab = gBrowser.getTabForBrowser(browser);
@ -62,7 +62,7 @@ function addAccessibleTask(doc, task) {
}
});
yield SimpleTest.promiseFocus(browser);
await SimpleTest.promiseFocus(browser);
loadFrameScripts(browser,
'let { document, window, navigator } = content;',
@ -72,8 +72,8 @@ function addAccessibleTask(doc, task) {
`e10s enabled: ${Services.appinfo.browserTabsRemoteAutostart}`);
Logger.log(`Actually remote browser: ${browser.isRemoteBrowser}`);
let event = yield onDocLoad;
yield task(browser, event.accessible);
let event = await onDocLoad;
await task(browser, event.accessible);
});
});
}

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

@ -130,7 +130,6 @@ marker.gcreason.label.DOM_WORKER=Periodic Worker GC
marker.gcreason.label.INTER_SLICE_GC=Periodic Incremental GC Slice
marker.gcreason.label.FULL_GC_TIMER=Periodic Full GC
marker.gcreason.label.SHUTDOWN_CC=Shutdown
marker.gcreason.label.FINISH_LARGE_EVALUATE=Large Eval
marker.gcreason.label.DOM_WINDOW_UTILS=User Inactive
marker.gcreason.label.USER_INACTIVE=User Inactive
@ -169,6 +168,5 @@ marker.gcreason.description.DOM_WORKER=The worker was idle for a relatively long
marker.gcreason.description.INTER_SLICE_GC=There has been a relatively long time since the last incremental GC slice.
marker.gcreason.description.FULL_GC_TIMER=JavaScript returned to the event loop, and it has been a relatively long time since we performed a garbage collection.
marker.gcreason.description.SHUTDOWN_CC=Firefox destroyed a JavaScript runtime or context, and this was the final garbage collection before shutting down.
marker.gcreason.description.FINISH_LARGE_EVALUATE=Firefox finished evaluating a large script, and performed a GC because the script will never be run again.
marker.gcreason.description.DOM_WINDOW_UTILS=The user was inactive for a long time. Took the opportunity to perform GC when it was unlikely to be noticed.
marker.gcreason.description.USER_INACTIVE=The user was inactive for a long time. Firefox took the opportunity to perform GC when it was unlikely to be noticed.

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

@ -2705,10 +2705,10 @@ Widgets.ObjectRenderers.add({
_onClick: function () {
let location = this.objectActor.location;
if (location && IGNORED_SOURCE_URLS.indexOf(location.url) === -1) {
let url = location && location.url;
if (url && IGNORED_SOURCE_URLS.indexOf(url) === -1) {
this.output.openLocationInDebugger(location);
}
else {
} else {
this.openObjectInVariablesView();
}
}

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

@ -40,6 +40,30 @@ add_task(function* () {
}], { webconsole: hud });
});
add_task(function* () {
yield loadTab(TEST_URI);
hud = yield openConsole();
let msg = yield hud.jsterm.execute("Function.prototype");
ok(msg, "output message found");
ok(msg.textContent.includes("function ()"),
"message text check");
executeSoon(() => {
EventUtils.synthesizeMouse(msg.querySelector("a"), 2, 2, {}, hud.iframeWindow);
});
let varView = yield hud.jsterm.once("variablesview-fetched");
ok(varView, "object inspector opened on click");
yield findVariableViewProperties(varView, [{
name: "constructor",
value: "Function()",
}], { webconsole: hud });
});
add_task(function* () {
let msg = yield hud.jsterm.execute("fooObj");

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

@ -7609,10 +7609,6 @@ nsresult
nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
nsIChannel* aChannel, nsresult aStatus)
{
// We can release any pressure we may have had on the throttling service and
// let background channels continue.
mThrottler.reset();
if (!aChannel) {
return NS_ERROR_NULL_POINTER;
}
@ -10799,16 +10795,6 @@ nsDocShell::InternalLoad(nsIURI* aURI,
net::PredictorPredict(aURI, nullptr,
nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
// Increase pressure on the throttling service so background channels will be
// appropriately de-prioritized. We need to explicitly check for http[s] here
// so that we don't throttle while loading, say, about:blank.
bool isHTTP, isHTTPS;
aURI->SchemeIs("http", &isHTTP);
aURI->SchemeIs("https", &isHTTPS);
if (isHTTP || isHTTPS) {
mThrottler.reset(new mozilla::net::Throttler());
}
nsCOMPtr<nsIRequest> req;
rv = DoURILoad(aURI, aOriginalURI, aLoadReplace, aReferrer,
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),

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

@ -60,7 +60,6 @@
#include "nsRect.h"
#include "Units.h"
#include "nsIDeprecationWarner.h"
#include "nsIThrottlingService.h"
namespace mozilla {
enum class TaskCategory;
@ -1101,9 +1100,6 @@ public:
InterfaceRequestorProxy() {}
nsWeakPtr mWeakPtr;
};
private:
mozilla::UniquePtr<mozilla::net::Throttler> mThrottler;
};
#endif /* nsDocShell_h__ */

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

@ -306,7 +306,7 @@ TimeoutManager::TimeoutManager(nsGlobalWindow& aWindow)
mRunningTimeout(nullptr),
mIdleCallbackTimeoutCounter(1),
mBackPressureDelayMS(0),
mThrottleTrackingTimeouts(gTrackingTimeoutThrottlingDelay <= 0)
mThrottleTrackingTimeouts(false)
{
MOZ_DIAGNOSTIC_ASSERT(aWindow.IsInnerWindow());

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

@ -307,7 +307,6 @@ nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
nsresult
nsJSUtils::ExecutionContext::JoinEncodeAndExec(void **aOffThreadToken,
mozilla::Vector<uint8_t>& aBytecodeBuf,
JS::MutableHandle<JSScript*> aScript)
{
MOZ_ASSERT_IF(aOffThreadToken, !mWantsReturnValue);
@ -319,7 +318,7 @@ nsJSUtils::ExecutionContext::JoinEncodeAndExec(void **aOffThreadToken,
return mRv;
}
if (!StartIncrementalEncoding(mCx, aBytecodeBuf, aScript)) {
if (!StartIncrementalEncoding(mCx, aScript)) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;

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

@ -168,7 +168,6 @@ public:
// Similar to JoinAndExec, except that in addition to fecthing the source,
// we register the fact that we plan to encode its bytecode later.
MOZ_MUST_USE nsresult JoinEncodeAndExec(void **aOffThreadToken,
mozilla::Vector<uint8_t>& aBytecodeBuf,
JS::MutableHandle<JSScript*> aScript);
};

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

@ -110,7 +110,11 @@ class HangMonitorChild
static HangMonitorChild* Get() { return sInstance; }
MessageLoop* MonitorLoop() { return mHangMonitor->MonitorLoop(); }
void Dispatch(already_AddRefed<nsIRunnable> aRunnable)
{
mHangMonitor->Dispatch(Move(aRunnable));
}
bool IsOnThread() { return mHangMonitor->IsOnThread(); }
private:
void ShutdownOnThread();
@ -234,7 +238,11 @@ public:
*/
void UpdateMinidump(uint32_t aPluginId, const nsString& aDumpId);
MessageLoop* MonitorLoop() { return mHangMonitor->MonitorLoop(); }
void Dispatch(already_AddRefed<nsIRunnable> aRunnable)
{
mHangMonitor->Dispatch(Move(aRunnable));
}
bool IsOnThread() { return mHangMonitor->IsOnThread(); }
private:
bool TakeBrowserMinidump(const PluginHangData& aPhd, nsString& aCrashId);
@ -345,7 +353,7 @@ HangMonitorChild::Shutdown()
void
HangMonitorChild::ShutdownOnThread()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
@ -355,19 +363,19 @@ HangMonitorChild::ShutdownOnThread()
void
HangMonitorChild::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
mIPCOpen = false;
// We use a task here to ensure that IPDL is finished with this
// HangMonitorChild before it gets deleted on the main thread.
MonitorLoop()->PostTask(NewNonOwningRunnableMethod(this, &HangMonitorChild::ShutdownOnThread));
Dispatch(NewNonOwningRunnableMethod(this, &HangMonitorChild::ShutdownOnThread));
}
mozilla::ipc::IPCResult
HangMonitorChild::RecvTerminateScript()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
MonitorAutoLock lock(mMonitor);
mTerminateScript = true;
@ -377,7 +385,7 @@ HangMonitorChild::RecvTerminateScript()
mozilla::ipc::IPCResult
HangMonitorChild::RecvBeginStartingDebugger()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
MonitorAutoLock lock(mMonitor);
mStartDebugger = true;
@ -387,7 +395,7 @@ HangMonitorChild::RecvBeginStartingDebugger()
mozilla::ipc::IPCResult
HangMonitorChild::RecvEndStartingDebugger()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
MonitorAutoLock lock(mMonitor);
mFinishedStartingDebugger = true;
@ -397,7 +405,7 @@ HangMonitorChild::RecvEndStartingDebugger()
mozilla::ipc::IPCResult
HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObserverEpoch)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
mForcePaintMonitor->NotifyActivity();
@ -425,7 +433,7 @@ HangMonitorChild::ClearForcePaint()
void
HangMonitorChild::Bind(Endpoint<PProcessHangMonitorChild>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
MOZ_ASSERT(!sInstance);
sInstance = this;
@ -472,7 +480,7 @@ HangMonitorChild::NotifySlowScript(nsITabChild* aTabChild,
}
nsAutoCString filename(aFileName);
MonitorLoop()->PostTask(NewNonOwningRunnableMethod
Dispatch(NewNonOwningRunnableMethod
<TabId, nsCString>(this,
&HangMonitorChild::NotifySlowScriptAsync,
id, filename));
@ -503,7 +511,7 @@ HangMonitorChild::NotifyPluginHang(uint32_t aPluginId)
mSentReport = true;
// bounce to background thread
MonitorLoop()->PostTask(NewNonOwningRunnableMethod<uint32_t>(this,
Dispatch(NewNonOwningRunnableMethod<uint32_t>(this,
&HangMonitorChild::NotifyPluginHangAsync,
aPluginId));
}
@ -511,7 +519,7 @@ HangMonitorChild::NotifyPluginHang(uint32_t aPluginId)
void
HangMonitorChild::NotifyPluginHangAsync(uint32_t aPluginId)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
// bounce back to parent on background thread
if (mIPCOpen) {
@ -527,7 +535,7 @@ HangMonitorChild::ClearHang()
if (mSentReport) {
// bounce to background thread
MonitorLoop()->PostTask(NewNonOwningRunnableMethod(this, &HangMonitorChild::ClearHangAsync));
Dispatch(NewNonOwningRunnableMethod(this, &HangMonitorChild::ClearHangAsync));
MonitorAutoLock lock(mMonitor);
mSentReport = false;
@ -540,7 +548,7 @@ HangMonitorChild::ClearHang()
void
HangMonitorChild::ClearHangAsync()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
// bounce back to parent on background thread
if (mIPCOpen) {
@ -595,7 +603,7 @@ HangMonitorParent::Shutdown()
mProcess = nullptr;
}
MonitorLoop()->PostTask(NewNonOwningRunnableMethod(this,
Dispatch(NewNonOwningRunnableMethod(this,
&HangMonitorParent::ShutdownOnThread));
while (!mShutdownDone) {
@ -606,7 +614,7 @@ HangMonitorParent::Shutdown()
void
HangMonitorParent::ShutdownOnThread()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
// mIPCOpen is only written from this thread, so need need to take the lock
// here. We'd be shooting ourselves in the foot, because ActorDestroy takes
@ -626,15 +634,15 @@ HangMonitorParent::ForcePaint(dom::TabParent* aTab, uint64_t aLayerObserverEpoch
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (sShouldForcePaint) {
TabId id = aTab->GetTabId();
MonitorLoop()->PostTask(NewNonOwningRunnableMethod<TabId, uint64_t>(
this, &HangMonitorParent::ForcePaintOnThread, id, aLayerObserverEpoch));
Dispatch(NewNonOwningRunnableMethod
<TabId, uint64_t>(this, &HangMonitorParent::ForcePaintOnThread, id, aLayerObserverEpoch));
}
}
void
HangMonitorParent::ForcePaintOnThread(TabId aTabId, uint64_t aLayerObserverEpoch)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (mIPCOpen) {
Unused << SendForcePaint(aTabId, aLayerObserverEpoch);
@ -644,14 +652,14 @@ HangMonitorParent::ForcePaintOnThread(TabId aTabId, uint64_t aLayerObserverEpoch
void
HangMonitorParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
mIPCOpen = false;
}
void
HangMonitorParent::Bind(Endpoint<PProcessHangMonitorParent>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
@ -729,7 +737,7 @@ mozilla::ipc::IPCResult
HangMonitorParent::RecvHangEvidence(const HangData& aHangData)
{
// chrome process, background thread
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (!mReportHangs) {
return IPC_OK();
@ -767,7 +775,7 @@ mozilla::ipc::IPCResult
HangMonitorParent::RecvClearHang()
{
// chrome process, background thread
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (!mReportHangs) {
return IPC_OK();
@ -787,7 +795,7 @@ HangMonitorParent::RecvClearHang()
void
HangMonitorParent::TerminateScript()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (mIPCOpen) {
Unused << SendTerminateScript();
@ -797,7 +805,7 @@ HangMonitorParent::TerminateScript()
void
HangMonitorParent::BeginStartingDebugger()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (mIPCOpen) {
Unused << SendBeginStartingDebugger();
@ -807,7 +815,7 @@ HangMonitorParent::BeginStartingDebugger()
void
HangMonitorParent::EndStartingDebugger()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
if (mIPCOpen) {
Unused << SendEndStartingDebugger();
@ -936,7 +944,7 @@ HangMonitoredProcess::TerminateScript()
return NS_ERROR_UNEXPECTED;
}
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
ProcessHangMonitor::Get()->Dispatch(NewNonOwningRunnableMethod(mActor,
&HangMonitorParent::TerminateScript));
return NS_OK;
}
@ -953,7 +961,7 @@ HangMonitoredProcess::BeginStartingDebugger()
return NS_ERROR_UNEXPECTED;
}
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
ProcessHangMonitor::Get()->Dispatch(NewNonOwningRunnableMethod(mActor,
&HangMonitorParent::BeginStartingDebugger));
return NS_OK;
}
@ -970,7 +978,7 @@ HangMonitoredProcess::EndStartingDebugger()
return NS_ERROR_UNEXPECTED;
}
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
ProcessHangMonitor::Get()->Dispatch(NewNonOwningRunnableMethod(mActor,
&HangMonitorParent::EndStartingDebugger));
return NS_OK;
}
@ -1052,9 +1060,7 @@ ProcessHangMonitor::ProcessHangMonitor()
obs->AddObserver(this, "xpcom-shutdown", false);
}
mThread = new base::Thread("ProcessHangMonitor");
if (!mThread->Start()) {
delete mThread;
if (NS_FAILED(NS_NewNamedThread("ProcessHangMon", getter_AddRefs(mThread)))) {
mThread = nullptr;
}
}
@ -1066,7 +1072,8 @@ ProcessHangMonitor::~ProcessHangMonitor()
MOZ_ASSERT(sInstance == this);
sInstance = nullptr;
delete mThread;
mThread->Shutdown();
mThread = nullptr;
}
ProcessHangMonitor*
@ -1129,7 +1136,7 @@ ProcessHangMonitor::ShouldTimeOutCPOWs()
void
ProcessHangMonitor::InitiateCPOWTimeout()
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_RELEASE_ASSERT(IsOnThread());
mCPOWTimeout = true;
}
@ -1152,7 +1159,7 @@ CreateHangMonitorParent(ContentParent* aContentParent,
auto* process = new HangMonitoredProcess(parent, aContentParent);
parent->SetProcess(process);
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
monitor->Dispatch(NewNonOwningRunnableMethod
<Endpoint<PProcessHangMonitorParent>&&>(parent,
&HangMonitorParent::Bind,
Move(aEndpoint)));
@ -1171,16 +1178,23 @@ mozilla::CreateHangMonitorChild(Endpoint<PProcessHangMonitorChild>&& aEndpoint)
ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
auto* child = new HangMonitorChild(monitor);
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
monitor->Dispatch(NewNonOwningRunnableMethod
<Endpoint<PProcessHangMonitorChild>&&>(child,
&HangMonitorChild::Bind,
Move(aEndpoint)));
}
MessageLoop*
ProcessHangMonitor::MonitorLoop()
void
ProcessHangMonitor::Dispatch(already_AddRefed<nsIRunnable> aRunnable)
{
return mThread->message_loop();
mThread->Dispatch(Move(aRunnable), nsIEventTarget::NS_DISPATCH_NORMAL);
}
bool
ProcessHangMonitor::IsOnThread()
{
bool on;
return NS_SUCCEEDED(mThread->IsOnCurrentThread(&on)) && on;
}
/* static */ PProcessHangMonitorParent*

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

@ -7,16 +7,14 @@
#ifndef mozilla_ProcessHangMonitor_h
#define mozilla_ProcessHangMonitor_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Atomics.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
class nsIRunnable;
class nsITabChild;
class MessageLoop;
namespace base {
class Thread;
} // namespace base
class nsIThread;
namespace mozilla {
@ -66,14 +64,15 @@ class ProcessHangMonitor final
void InitiateCPOWTimeout();
bool ShouldTimeOutCPOWs();
MessageLoop* MonitorLoop();
void Dispatch(already_AddRefed<nsIRunnable> aRunnable);
bool IsOnThread();
private:
static ProcessHangMonitor* sInstance;
Atomic<bool> mCPOWTimeout;
base::Thread* mThread;
nsCOMPtr<nsIThread> mThread;
};
} // namespace mozilla

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

@ -2010,7 +2010,6 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
MOZ_ASSERT(aRequest->mBytecodeOffset ==
aRequest->mScriptBytecode.length());
rv = exec.JoinEncodeAndExec(&aRequest->mOffThreadToken,
aRequest->mScriptBytecode,
&script);
// Queue the current script load request to later save the bytecode.
if (NS_SUCCEEDED(rv)) {
@ -2140,7 +2139,7 @@ ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
});
JS::RootedScript script(aCx, aRequest->mScript);
if (!JS::FinishIncrementalEncoding(aCx, script)) {
if (!JS::FinishIncrementalEncoding(aCx, script, aRequest->mScriptBytecode)) {
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode",
aRequest));
return;
@ -2188,7 +2187,8 @@ ScriptLoader::GiveUpBytecodeEncoding()
{
// Ideally we prefer to properly end the incremental encoder, such that we
// would not keep a large buffer around. If we cannot, we fallback on the
// removal of all request from the current list.
// removal of all request from the current list and these large buffers would
// be removed at the same time as the source object.
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
if (globalObject) {
nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
@ -2200,7 +2200,8 @@ ScriptLoader::GiveUpBytecodeEncoding()
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode", request.get()));
TRACE_FOR_TEST_NONE(request->mElement, "scriptloader_bytecode_failed");
script.set(request->mScript);
Unused << JS::FinishIncrementalEncoding(aes.cx(), script);
Unused << JS::FinishIncrementalEncoding(aes.cx(), script,
request->mScriptBytecode);
request->mScriptBytecode.clearAndFree();
request->DropBytecodeCacheReferences();
}
@ -2212,11 +2213,8 @@ ScriptLoader::GiveUpBytecodeEncoding()
RefPtr<ScriptLoadRequest> request = mBytecodeEncodingQueue.StealFirst();
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode", request.get()));
TRACE_FOR_TEST_NONE(request->mElement, "scriptloader_bytecode_failed");
// Note: Do not clear the mScriptBytecode buffer, because the incremental
// encoder owned by the ScriptSource object still has a reference to this
// buffer. This reference would be removed as soon as the ScriptSource
// object would be GC.
request->mCacheInfo = nullptr;
request->mScriptBytecode.clearAndFree();
request->DropBytecodeCacheReferences();
}
}

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

@ -719,7 +719,13 @@ template <bool apply_alpha> SkPMColor trunc_from_255(const Sk4f& x, const Sk4f&
Sk4f c4f255 = x;
if (apply_alpha) {
const float scale = x[SkPM4f::A] * (1 / 255.f);
c4f255 *= Sk4f(scale, scale, scale, 1);
// Multiply alpha by a number slightly greater than 1 to compensate for error
// in scaling from the 1/255 approximation. This error is less than 1e-6 for
// all alpha values. Non-integer alpha values very close to their ceiling can
// push the color values above the alpha value, which will become an invalid
// premultiplied color. So nudge alpha up slightly by this compensating scale
// to keep it above the color values.
c4f255 *= Sk4f(scale, scale, scale, 1.000001f);
}
SkNx_cast<uint8_t>(post_bias<apply_alpha>(c4f255, bias)).store(&c);

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

@ -7,6 +7,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/CheckedInt.h"
#include "imgIContainer.h"
#include "LookupResult.h"
#include "MainThreadUtils.h"
@ -14,6 +15,7 @@
#include "gfxPrefs.h"
#include "pixman.h"
#include <algorithm>
namespace mozilla {
@ -336,17 +338,32 @@ FrameAnimator::AdvanceFrame(AnimationState& aState,
// If we can get closer to the current time by a multiple of the image's loop
// time, we should. We can only do this if we're done decoding; otherwise, we
// don't know the full loop length, and LoopLength() will have to return
// FrameTimeout::Forever().
// FrameTimeout::Forever(). We also skip this for images with a finite loop
// count if we have initialized mLoopRemainingCount (it only gets initialized
// after one full loop).
FrameTimeout loopTime = aState.LoopLength();
if (loopTime != FrameTimeout::Forever()) {
if (loopTime != FrameTimeout::Forever() &&
(aState.LoopCount() < 0 || aState.mLoopRemainingCount >= 0)) {
TimeDuration delay = aTime - aState.mCurrentAnimationFrameTime;
if (delay.ToMilliseconds() > loopTime.AsMilliseconds()) {
// Explicitly use integer division to get the floor of the number of
// loops.
uint64_t loops = static_cast<uint64_t>(delay.ToMilliseconds())
/ loopTime.AsMilliseconds();
// If we have a finite loop count limit the number of loops we advance.
if (aState.mLoopRemainingCount >= 0) {
MOZ_ASSERT(aState.LoopCount() >= 0);
loops = std::min(loops, CheckedUint64(aState.mLoopRemainingCount).value());
}
aState.mCurrentAnimationFrameTime +=
TimeDuration::FromMilliseconds(loops * loopTime.AsMilliseconds());
if (aState.mLoopRemainingCount >= 0) {
MOZ_ASSERT(loops <= CheckedUint64(aState.mLoopRemainingCount).value());
aState.mLoopRemainingCount -= CheckedInt32(loops).value();
}
}
}

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

@ -108,7 +108,7 @@ namespace JS {
D(REFRESH_FRAME) \
D(FULL_GC_TIMER) \
D(SHUTDOWN_CC) \
D(FINISH_LARGE_EVALUATE) \
D(UNUSED2) \
D(USER_INACTIVE) \
D(XPCONNECT_SHUTDOWN)

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

@ -190,7 +190,6 @@ compartment.
* "REFRESH_FRAME"
* "FULL_GC_TIMER"
* "SHUTDOWN_CC"
* "FINISH_LARGE_EVALUATE"
* "USER_INACTIVE"
`nonincrementalReason`

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

@ -125,8 +125,12 @@ from its prototype:
`url`
: **If the instance refers to a `JSScript`**, the filename or URL from which
this script's code was loaded. If the `source` property is non-`null`,
then this is equal to `source.url`.
this script's code was loaded. For scripts created by `eval` or the
`Function` constructor, this may be a synthesized filename, starting with a
valid URL and followed by information tracking how the code was introduced
into the system; the entire string is not a valid URL. For
`Function.prototype`'s script, this is `null`. If this `Debugger.Script`'s
`source` property is non-`null`, then this is equal to `source.url`.
**If the instance refers to WebAssembly code**, throw a `TypeError`.

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

@ -85,9 +85,13 @@ from its prototype:
WebAssembly bytecode.
`url`
: **If the instance refers to JavaScript source**, the URL from which this
source was loaded, if this source was loaded from a URL. Otherwise, this
is `undefined`. Source may be loaded from a URL in the following ways:
: **If the instance refers to JavaScript source**, the filename or URL from
which this script's code was loaded. For scripts created by `eval` or the
`Function` constructor, this may be a synthesized filename, starting with a
valid URL and followed by information tracking how the code was introduced
into the system; the entire string is not a valid URL. For
`Function.prototype`'s script, this is `null`. Source may be loaded from a
URL in the following ways:
* The URL may appear as the `src` attribute of a `<script>` element
in markup text.

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

@ -0,0 +1,10 @@
// Source.prototype.url returns a synthesized URL for eval code.
var g = newGlobal();
g.eval('function double() { return 2*x }');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
var fw = gw.getOwnPropertyDescriptor('double').value;
assertEq(!!fw.script.source.url.match(/Source-url-01.js line [0-9]+ > eval/), true);

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

@ -0,0 +1,11 @@
// Source.prototype.url returns a synthesized URL for Function code.
var g = newGlobal();
g.eval('var double = Function("x", "return 2*x;");');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
var fw = gw.getOwnPropertyDescriptor('double').value;
print(fw.script.source.url);
assertEq(!!fw.script.source.url.match(/Source-url-02.js .* > Function/), true);

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

@ -0,0 +1,11 @@
// Source.prototype.url is null for Function.prototype.
var g = newGlobal();
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
var Fpw = gw.getOwnPropertyDescriptor('Function').value.proto;
assertEq(Fpw.script.source.url, null);

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

@ -4639,8 +4639,6 @@ JS::CloneAndExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
return ExecuteScript(cx, envChain, script, rval.address());
}
static const unsigned LARGE_SCRIPT_LENGTH = 500*1024;
static bool
Evaluate(JSContext* cx, ScopeKind scopeKind, HandleObject env,
const ReadOnlyCompileOptions& optionsArg,
@ -4664,17 +4662,6 @@ Evaluate(JSContext* cx, ScopeKind scopeKind, HandleObject env,
bool result = Execute(cx, script, *env,
options.noScriptRval ? nullptr : rval.address());
// After evaluation, the compiled script will not be run again.
// script->ensureRanAnalysis allocated 1 analyze::Bytecode for every opcode
// which for large scripts means significant memory. Perform a GC eagerly
// to clear out this analysis data before anything happens to inhibit the
// flushing of this memory (such as setting requestAnimationFrame).
if (script->length() > LARGE_SCRIPT_LENGTH) {
script = nullptr;
PrepareZoneForGC(cx->zone());
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUATE);
}
return result;
}
@ -7110,21 +7097,21 @@ JS::DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer,
}
JS_PUBLIC_API(bool)
JS::StartIncrementalEncoding(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script)
JS::StartIncrementalEncoding(JSContext* cx, JS::HandleScript script)
{
if (!script)
return false;
if (!script->scriptSource()->xdrEncodeTopLevel(cx, buffer, script))
if (!script->scriptSource()->xdrEncodeTopLevel(cx, script))
return false;
return true;
}
JS_PUBLIC_API(bool)
JS::FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script)
JS::FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer)
{
if (!script)
return false;
if (!script->scriptSource()->xdrFinalizeEncoder())
if (!script->scriptSource()->xdrFinalizeEncoder(buffer))
return false;
return true;
}

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

@ -6257,15 +6257,14 @@ DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHan
// an out-param of any of the |Compile| functions, or the result of
// |FinishOffThreadScript|.
//
// The |buffer| argument should not be used before until
// |FinishIncrementalEncoding| is called on the same script, and returns
// successfully. If any of these functions failed, the |buffer| content is
// undefined.
// The |buffer| argument of |FinishIncrementalEncoding| is used for appending
// the encoded bytecode into the buffer. If any of these functions failed, the
// content of |buffer| would be undefined.
extern JS_PUBLIC_API(bool)
StartIncrementalEncoding(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script);
StartIncrementalEncoding(JSContext* cx, JS::HandleScript script);
extern JS_PUBLIC_API(bool)
FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script);
FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer);
} /* namespace JS */

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

@ -2019,10 +2019,9 @@ ScriptSource::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
}
bool
ScriptSource::xdrEncodeTopLevel(JSContext* cx, JS::TranscodeBuffer& buffer,
HandleScript script)
ScriptSource::xdrEncodeTopLevel(JSContext* cx, HandleScript script)
{
xdrEncoder_ = js::MakeUnique<XDRIncrementalEncoder>(cx, buffer, buffer.length());
xdrEncoder_ = js::MakeUnique<XDRIncrementalEncoder>(cx);
if (!xdrEncoder_) {
ReportOutOfMemory(cx);
return false;
@ -2064,14 +2063,14 @@ ScriptSource::xdrEncodeFunction(JSContext* cx, HandleFunction fun, HandleScriptS
}
bool
ScriptSource::xdrFinalizeEncoder()
ScriptSource::xdrFinalizeEncoder(JS::TranscodeBuffer& buffer)
{
MOZ_ASSERT(hasEncoder());
auto cleanup = mozilla::MakeScopeExit([&] {
xdrEncoder_.reset(nullptr);
});
if (!xdrEncoder_->linearize())
if (!xdrEncoder_->linearize(buffer))
return false;
return true;
}

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

@ -646,7 +646,7 @@ class ScriptSource
// of the encoding would be available in the |buffer| provided as argument,
// as soon as |xdrFinalize| is called and all xdr function calls returned
// successfully.
bool xdrEncodeTopLevel(JSContext* cx, JS::TranscodeBuffer& buffer, HandleScript script);
bool xdrEncodeTopLevel(JSContext* cx, HandleScript script);
// Encode a delazified JSFunction. In case of errors, the XDR encoder is
// freed and the |buffer| provided as argument to |xdrEncodeTopLevel| is
@ -660,7 +660,7 @@ class ScriptSource
// Linearize the encoded content in the |buffer| provided as argument to
// |xdrEncodeTopLevel|, and free the XDR encoder. In case of errors, the
// |buffer| is considered undefined.
bool xdrFinalizeEncoder();
bool xdrFinalizeEncoder(JS::TranscodeBuffer& buffer);
const mozilla::TimeStamp parseEnded() const {
return parseEnded_;

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

@ -1649,7 +1649,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
// register ahead the fact that every JSFunction which is being
// delazified should be encoded at the end of the delazification.
if (saveIncrementalBytecode) {
if (!StartIncrementalEncoding(cx, saveBuffer, script))
if (!StartIncrementalEncoding(cx, script))
return false;
}
@ -1675,7 +1675,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
// Serialize the encoded bytecode, recorded before the execution, into a
// buffer which can be deserialized linearly.
if (saveIncrementalBytecode) {
if (!FinishIncrementalEncoding(cx, script))
if (!FinishIncrementalEncoding(cx, script, saveBuffer))
return false;
}
}

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

@ -322,7 +322,7 @@ XDRIncrementalEncoder::endSubTree()
}
bool
XDRIncrementalEncoder::linearize()
XDRIncrementalEncoder::linearize(JS::TranscodeBuffer& buffer)
{
if (oom_) {
ReportOutOfMemory(cx());
@ -356,7 +356,7 @@ XDRIncrementalEncoder::linearize()
// buffer which would be serialized.
MOZ_ASSERT(slice.sliceBegin <= slices_.length());
MOZ_ASSERT(slice.sliceBegin + slice.sliceLength <= slices_.length());
if (!buffer_.append(slices_.begin() + slice.sliceBegin, slice.sliceLength)) {
if (!buffer.append(slices_.begin() + slice.sliceBegin, slice.sliceLength)) {
ReportOutOfMemory(cx());
return fail(JS::TranscodeResult_Throw);
}

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

@ -448,18 +448,15 @@ class XDRIncrementalEncoder : public XDREncoder
// Tree of slices.
SlicesTree tree_;
JS::TranscodeBuffer slices_;
JS::TranscodeBuffer& buffer_;
bool oom_;
public:
XDRIncrementalEncoder(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor)
explicit XDRIncrementalEncoder(JSContext* cx)
: XDREncoder(cx, slices_, 0),
scope_(nullptr),
node_(nullptr),
buffer_(buffer),
oom_(false)
{
MOZ_ASSERT(buffer.length() == cursor, "NYI");
}
virtual ~XDRIncrementalEncoder() {}
@ -472,9 +469,9 @@ class XDRIncrementalEncoder : public XDREncoder
void createOrReplaceSubTree(AutoXDRTree* child) override;
void endSubTree() override;
// In the current XDRBuffer, move replaceable-parts to form a linear
// sequence of bytes.
MOZ_MUST_USE bool linearize();
// Append the content collected during the incremental encoding into the
// buffer given as argument.
MOZ_MUST_USE bool linearize(JS::TranscodeBuffer& buffer);
};
} /* namespace js */

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

@ -1,440 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Things to think about
// * do we need to be multithreaded, or is mt-only ok?
#include "ThrottlingService.h"
#include "nsIHttpChannel.h"
#include "nsIObserverService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/net/NeckoChild.h"
namespace mozilla {
namespace net{
static const char kEnabledPref[] = "network.throttle.enable";
static const bool kDefaultEnabled = true;
// During a page load presure, every channel that is marked as Throttleable
// is being periodically suspended and resumed for the suspend-for and
// resume-for intervals respectively. This gives more bandwidth to other
// more priority responses.
static const char kSuspendPeriodPref[] = "network.throttle.suspend-for";
static const uint32_t kDefaultSuspendPeriod = 3000;
static const char kResumePeriodPref[] = "network.throttle.resume-for";
static const uint32_t kDefaultResumePeriod = 200;
NS_IMPL_ISUPPORTS(ThrottlingService, nsIThrottlingService, nsIObserver, nsITimerCallback)
ThrottlingService::ThrottlingService()
:mEnabled(kDefaultEnabled)
,mInitCalled(false)
,mSuspended(false)
,mPressureCount(0)
,mSuspendPeriod(kDefaultSuspendPeriod)
,mResumePeriod(kDefaultResumePeriod)
,mIteratingHash(false)
{
}
ThrottlingService::~ThrottlingService()
{
Shutdown();
}
nsresult
ThrottlingService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mInitCalled);
mInitCalled = true;
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return NS_ERROR_UNEXPECTED;
}
nsresult rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
NS_ENSURE_SUCCESS(rv, rv);
mEnabled = Preferences::GetBool(kEnabledPref, kDefaultEnabled);
rv = Preferences::AddStrongObserver(this, kEnabledPref);
NS_ENSURE_SUCCESS(rv, rv);
Preferences::AddUintVarCache(&mSuspendPeriod, kSuspendPeriodPref, kDefaultSuspendPeriod);
Preferences::AddUintVarCache(&mResumePeriod, kResumePeriodPref, kDefaultResumePeriod);
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
return NS_OK;
}
void
ThrottlingService::Shutdown()
{
if (!mInitCalled) {
return;
}
if (mTimer) {
mTimer->Cancel();
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
Preferences::RemoveObserver(this, kEnabledPref);
MaybeResumeAll();
mChannelHash.Clear();
}
nsresult
ThrottlingService::Create(nsISupports *outer, const nsIID& iid, void **result)
{
MOZ_ASSERT(NS_IsMainThread());
if (outer != nullptr) {
return NS_ERROR_NO_AGGREGATION;
}
RefPtr<ThrottlingService> svc = new ThrottlingService();
if (!IsNeckoChild()) {
// We only need to do any work on the parent, so only bother initializing
// there. Child-side, we'll just error out since we only deal with parent
// channels.)
nsresult rv = svc->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
return svc->QueryInterface(iid, result);
}
// nsIThrottlingService
nsresult
ThrottlingService::AddChannel(nsIHttpChannel *channel)
{
MOZ_ASSERT(NS_IsMainThread());
// We don't check mEnabled, because we always want to put channels in the hash
// to avoid potential inconsistencies in the case where the user changes the
// enabled pref at run-time.
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
if (mChannelHash.Get(key, nullptr)) {
// We already have this channel under our control, not adding it again.
return NS_OK;
}
if (!mIteratingHash) {
// This should be the common case, and as such is easy to handle
mChannelHash.Put(key, channel);
if (mSuspended) {
channel->Suspend();
}
} else {
// This gets tricky - we've somehow re-entrantly gotten here through the
// hash iteration in one of MaybeSuspendAll or MaybeResumeAll. Keep track
// of the fact that this add came in now, and once we're done iterating, we
// can add this into the hash. This avoids unexpectedly modifying the hash
// while it's being iterated over, which could lead to inconsistencies.
mChannelsToAddRemove.AppendElement(channel);
mChannelIsAdd.AppendElement(true);
}
return NS_OK;
}
nsresult
ThrottlingService::RemoveChannel(nsIHttpChannel *channel)
{
MOZ_ASSERT(NS_IsMainThread());
// Just like above, don't worry about mEnabled to avoid inconsistencies when
// the pref changes at run-time
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
if (!mChannelHash.Get(key, nullptr)) {
// TODO - warn?
return NS_ERROR_ILLEGAL_VALUE;
}
if (!mIteratingHash) {
// This should be the common case, and easy to handle.
mChannelHash.Remove(key);
if (mSuspended) {
// This channel is no longer under our control for suspend/resume, but
// we've suspended it. Time to let it go.
channel->Resume();
}
} else {
// This gets tricky - we've somehow re-entrantly gotten here through the
// hash iteration in one of MaybeSuspendAll or MaybeResumeAll. Keep track
// of the fact that this add came in now, and once we're done iterating, we
// can add this into the hash. This avoids unexpectedly modifying the hash
// while it's being iterated over, which could lead to inconsistencies.
mChannelsToAddRemove.AppendElement(channel);
mChannelIsAdd.AppendElement(false);
}
return NS_OK;
}
nsresult
ThrottlingService::IncreasePressure()
{
MOZ_ASSERT(NS_IsMainThread());
// Just like add/removing channels, we don't check mEnabled here in order to
// avoid inconsistencies that could occur if the pref is flipped at runtime
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (mPressureCount++ == 0) {
MOZ_ASSERT(!mSuspended, "Suspended with 0 pressure?");
MaybeSuspendAll();
if (mSuspended) {
// MaybeSuspendAll() may not actually suspend things, and we only want to
// bother setting a timer to resume if we actually suspended.
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
}
return NS_OK;
}
nsresult
ThrottlingService::DecreasePressure()
{
MOZ_ASSERT(NS_IsMainThread());
// Just like add/removing channels, we don't check mEnabled here in order to
// avoid inconsistencies that could occur if the pref is flipped at runtime
if (IsNeckoChild()) {
return NS_ERROR_NOT_AVAILABLE;
}
MOZ_ASSERT(mPressureCount > 0, "Unbalanced throttle pressure");
if (--mPressureCount == 0) {
MaybeResumeAll();
mTimer->Cancel();
}
return NS_OK;
}
// nsIObserver
nsresult
ThrottlingService::Observe(nsISupports *subject, const char *topic,
const char16_t *data_unicode)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) {
Shutdown();
} else if (!strcmp("nsPref:changed", topic)) {
mEnabled = Preferences::GetBool(kEnabledPref, mEnabled);
if (mEnabled && mPressureCount) {
// We weren't enabled, but we are now, AND we're under pressure. Go ahead
// and suspend things.
MaybeSuspendAll();
if (mSuspended) {
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
} else if (!mEnabled) {
// We were enabled, but we aren't any longer. Make sure we aren't
// suspending channels and that we don't have any timer that wants to
// change things unexpectedly.
mTimer->Cancel();
MaybeResumeAll();
}
}
return NS_OK;
}
// nsITimerCallback
nsresult
ThrottlingService::Notify(nsITimer *timer)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(timer == mTimer);
if (mSuspended) {
MaybeResumeAll();
// Always try to resume if we were suspended, but only time-limit the
// resumption if we're under pressure and we're enabled. If either of those
// conditions is false, it doesn't make any sense to set a timer to suspend
// things when we don't want to be suspended anyway.
if (mPressureCount && mEnabled) {
mTimer->InitWithCallback(this, mResumePeriod, nsITimer::TYPE_ONE_SHOT);
}
} else if (mPressureCount) {
MaybeSuspendAll();
if (mSuspended) {
// MaybeSuspendAll() may not actually suspend, and it only makes sense to
// set a timer to resume if we actually suspended the channels.
mTimer->InitWithCallback(this, mSuspendPeriod, nsITimer::TYPE_ONE_SHOT);
}
}
return NS_OK;
}
// Internal methods
void
ThrottlingService::MaybeSuspendAll()
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!mEnabled) {
// We don't actually suspend when disabled, even though it's possible we get
// called in that state in order to avoid inconsistencies in the hash and
// the count if the pref changes at runtime.
return;
}
if (mSuspended) {
// Already suspended, nothing to do!
return;
}
mSuspended = true;
IterateHash([](ChannelHash::Iterator &iter) -> void {
const nsCOMPtr<nsIHttpChannel> channel = iter.UserData();
channel->Suspend();
});
}
void
ThrottlingService::MaybeResumeAll()
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(NS_IsMainThread());
if (!mSuspended) {
// Already resumed, nothing to do!
return;
}
mSuspended = false;
IterateHash([](ChannelHash::Iterator &iter) -> void {
const nsCOMPtr<nsIHttpChannel> channel = iter.UserData();
channel->Resume();
});
}
void
ThrottlingService::IterateHash(void (* callback)(ChannelHash::Iterator &iter))
{
MOZ_ASSERT(!mIteratingHash);
mIteratingHash = true;
for (ChannelHash::Iterator iter = mChannelHash.ConstIter(); !iter.Done(); iter.Next()) {
callback(iter);
}
mIteratingHash = false;
HandleExtraAddRemove();
}
void
ThrottlingService::HandleExtraAddRemove()
{
MOZ_ASSERT(!mIteratingHash);
MOZ_ASSERT(mChannelsToAddRemove.Length() == mChannelIsAdd.Length());
nsCOMArray<nsIHttpChannel> channelsToAddRemove;
channelsToAddRemove.SwapElements(mChannelsToAddRemove);
nsTArray<bool> channelIsAdd;
channelIsAdd.SwapElements(mChannelIsAdd);
for (size_t i = 0; i < channelsToAddRemove.Length(); ++i) {
if (channelIsAdd[i]) {
AddChannel(channelsToAddRemove[i]);
} else {
RemoveChannel(channelsToAddRemove[i]);
}
}
channelsToAddRemove.Clear();
channelIsAdd.Clear();
}
// The publicly available way to throttle things
Throttler::Throttler()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsNeckoChild()) {
if (gNeckoChild) {
// The child object may have already gone away, so we need to guard
// guard against deref'ing a nullptr here. If that's what happened, then
// our pageload won't be continuing anyway, so what we do is pretty much
// irrelevant.
gNeckoChild->SendIncreaseThrottlePressure();
}
} else {
mThrottlingService = do_GetService("@mozilla.org/network/throttling-service;1");
mThrottlingService->IncreasePressure();
}
}
Throttler::~Throttler()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsNeckoChild()) {
if (gNeckoChild) {
// The child object may have already gone away, so we need to guard
// guard against deref'ing a nullptr here. If that's what happened, then
// NeckoParent::ActorDestroy will take care of releasing the pressure we
// created.
gNeckoChild->SendDecreaseThrottlePressure();
}
} else {
MOZ_RELEASE_ASSERT(mThrottlingService);
mThrottlingService->DecreasePressure();
mThrottlingService = nullptr;
}
}
}
}

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

@ -1,67 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla__net__ThrottlingService_h
#define mozilla__net__ThrottlingService_h
#include "nsIThrottlingService.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsInterfaceHashtable.h"
#include "nsIObserver.h"
#include "nsITimer.h"
class nsIHttpChannel;
namespace mozilla {
namespace net {
class ThrottlingService : public nsIThrottlingService
, public nsIObserver
, public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITHROTTLINGSERVICE
NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK
ThrottlingService();
nsresult Init();
void Shutdown();
static nsresult Create(nsISupports *outer, const nsIID& iid, void **result);
private:
virtual ~ThrottlingService();
void MaybeSuspendAll();
void MaybeResumeAll();
void HandleExtraAddRemove();
bool mEnabled;
bool mInitCalled;
bool mSuspended;
uint32_t mPressureCount;
uint32_t mSuspendPeriod; // How long we should Suspend() channels for
uint32_t mResumePeriod; // How long we should Resume() channels for
nsCOMPtr<nsITimer> mTimer;
typedef nsInterfaceHashtable<nsUint64HashKey, nsIHttpChannel> ChannelHash;
ChannelHash mChannelHash;
// Used to avoid inconsistencies in the hash and the suspend/resume count of
// channels. See comments in AddChannel and RemoveChannel for details.
void IterateHash(void (* callback)(ChannelHash::Iterator &iter));
bool mIteratingHash;
nsCOMArray<nsIHttpChannel> mChannelsToAddRemove;
nsTArray<bool> mChannelIsAdd;
};
} // ::mozilla::net
} // ::mozilla
#endif // mozilla__net__ThrottlingService_h

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

@ -117,7 +117,6 @@ XPIDL_SOURCES += [
'nsIThreadRetargetableRequest.idl',
'nsIThreadRetargetableStreamListener.idl',
'nsIThrottledInputChannel.idl',
'nsIThrottlingService.idl',
'nsITimedChannel.idl',
'nsITLSServerSocket.idl',
'nsITraceableChannel.idl',
@ -250,7 +249,6 @@ UNIFIED_SOURCES += [
'StreamingProtocolService.cpp',
'TCPFastOpenLayer.cpp',
'ThrottleQueue.cpp',
'ThrottlingService.cpp',
'Tickler.cpp',
'TLSServerSocket.cpp',
]

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

@ -1,37 +0,0 @@
/* vim: set ts=2 sts=2 et sw=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIHttpChannel;
[builtinclass, uuid(c755ef98-b749-4f30-a658-1e6110013a66)]
interface nsIThrottlingService : nsISupports
{
void addChannel(in nsIHttpChannel channel);
void removeChannel(in nsIHttpChannel channel);
/* Don't call these directly, use mozilla::net::Throttler instead! */
void increasePressure();
void decreasePressure();
};
%{C++
namespace mozilla {
namespace net {
class Throttler
{
public:
Throttler();
~Throttler();
private:
nsCOMPtr<nsIThrottlingService> mThrottlingService;
};
} // ::mozilla::net
} // ::mozilla
%}

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

@ -494,17 +494,6 @@
{0x93, 0x30, 0x18, 0x58, 0xb9, 0x9a, 0xce, 0x69} \
}
// service implementing nsIThrottlingService
#define NS_THROTTLINGSERVICE_CONTRACTID \
"@mozilla.org/network/throttling-service;1"
#define NS_THROTTLINGSERVICE_CID \
{ /* c1c48f2b-cb9c-415e-b4f9-5e4c3476ca86 */ \
0xc1c48f2b, \
0xcb9c, \
0x415e, \
{0xb4, 0xf9, 0x5e, 0x4c, 0x34, 0x76, 0xca, 0x86} \
}
/******************************************************************************
* netwerk/cache/ classes
*/

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

@ -38,7 +38,6 @@
#include "nsCategoryCache.h"
#include "nsIContentSniffer.h"
#include "Predictor.h"
#include "ThrottlingService.h"
#include "nsIThreadPool.h"
#include "mozilla/net/NeckoChild.h"
@ -875,7 +874,6 @@ NS_DEFINE_NAMED_CID(NS_REQUESTCONTEXTSERVICE_CID);
#ifdef BUILD_NETWORK_INFO_SERVICE
NS_DEFINE_NAMED_CID(NETWORKINFOSERVICE_CID);
#endif // BUILD_NETWORK_INFO_SERVICE
NS_DEFINE_NAMED_CID(NS_THROTTLINGSERVICE_CID);
static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
{ &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
@ -1029,7 +1027,6 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
#ifdef BUILD_NETWORK_INFO_SERVICE
{ &kNETWORKINFOSERVICE_CID, false, nullptr, nsNetworkInfoServiceConstructor },
#endif
{ &kNS_THROTTLINGSERVICE_CID, false, nullptr, mozilla::net::ThrottlingService::Create },
{ nullptr }
};
@ -1188,7 +1185,6 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
#ifdef BUILD_NETWORK_INFO_SERVICE
{ NETWORKINFOSERVICE_CONTRACT_ID, &kNETWORKINFOSERVICE_CID },
#endif
{ NS_THROTTLINGSERVICE_CONTRACTID, &kNS_THROTTLINGSERVICE_CID },
{ nullptr }
};

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

@ -144,7 +144,8 @@ nsresult
CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
nsIChannel *aChannel,
const char *aCookieString,
const char *aServerTime)
const char *aServerTime,
bool aFromHttp)
{
NS_ENSURE_ARG(aHostURI);
NS_ENSURE_ARG_POINTER(aCookieString);
@ -179,7 +180,7 @@ CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
// Synchronously call the parent.
SendSetCookieString(uriParams, !!isForeign, cookieString, serverTime,
attrs);
attrs, aFromHttp);
return NS_OK;
}
@ -220,7 +221,8 @@ CookieServiceChild::SetCookieString(nsIURI *aHostURI,
const char *aCookieString,
nsIChannel *aChannel)
{
return SetCookieStringInternal(aHostURI, aChannel, aCookieString, nullptr);
return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
nullptr, false);
}
NS_IMETHODIMP
@ -231,7 +233,8 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI *aHostURI,
const char *aServerTime,
nsIChannel *aChannel)
{
return NS_ERROR_NOT_IMPLEMENTED;
return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
aServerTime, true);
}
} // namespace net

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

@ -47,7 +47,8 @@ protected:
nsresult SetCookieStringInternal(nsIURI *aHostURI,
nsIChannel *aChannel,
const char *aCookieString,
const char *aServerTime);
const char *aServerTime,
bool aFromHttp);
void PrefChanged(nsIPrefBranch *aPrefBranch);

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

@ -109,7 +109,8 @@ CookieServiceParent::RecvSetCookieString(const URIParams& aHost,
const bool& aIsForeign,
const nsCString& aCookieString,
const nsCString& aServerTime,
const OriginAttributes& aAttrs)
const OriginAttributes& aAttrs,
const bool& aFromHttp)
{
if (!mCookieService)
return IPC_OK();
@ -134,7 +135,7 @@ CookieServiceParent::RecvSetCookieString(const URIParams& aHost,
// NB: dummyChannel could be null if something failed in CreateDummyChannel.
nsDependentCString cookieString(aCookieString, 0);
mCookieService->SetCookieStringInternal(hostURI, aIsForeign, cookieString,
aServerTime, false, aAttrs,
aServerTime, aFromHttp, aAttrs,
dummyChannel);
return IPC_OK();
}

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

@ -32,7 +32,8 @@ protected:
const bool& aIsForeign,
const nsCString& aCookieString,
const nsCString& aServerTime,
const OriginAttributes& aAttrs) override;
const OriginAttributes& aAttrs,
const bool& aFromHttp) override;
RefPtr<nsCookieService> mCookieService;
};

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

@ -97,7 +97,8 @@ parent:
bool isForeign,
nsCString cookieString,
nsCString serverTime,
OriginAttributes attrs);
OriginAttributes attrs,
bool aFromHttp);
async __delete__();
};

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

@ -48,7 +48,6 @@
#include "nsINetworkPredictor.h"
#include "nsINetworkPredictorVerifier.h"
#include "nsISpeculativeConnect.h"
#include "nsIThrottlingService.h"
#include "nsNetUtil.h"
using mozilla::OriginAttributes;
@ -946,23 +945,6 @@ NeckoParent::RecvRemoveRequestContext(const uint64_t& rcid)
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvIncreaseThrottlePressure()
{
mThrottlers.AppendElement(mozilla::UniquePtr<mozilla::net::Throttler>(new mozilla::net::Throttler));
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvDecreaseThrottlePressure()
{
MOZ_ASSERT(!mThrottlers.IsEmpty());
// We do this because we don't actually care which throttler gets removed,
// just that one of them does.
mThrottlers.RemoveElementAt(0);
return IPC_OK();
}
mozilla::ipc::IPCResult
NeckoParent::RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId)
{

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

@ -10,7 +10,6 @@
#include "mozilla/net/NeckoCommon.h"
#include "nsIAuthPrompt2.h"
#include "nsINetworkPredictor.h"
#include "nsIThrottlingService.h"
#include "nsNetUtil.h"
#ifndef mozilla_net_NeckoParent_h
@ -236,14 +235,7 @@ protected:
virtual mozilla::ipc::IPCResult RecvRemoveRequestContext(const uint64_t& rcid) override;
/* Throttler messages */
virtual mozilla::ipc::IPCResult RecvIncreaseThrottlePressure() override;
virtual mozilla::ipc::IPCResult RecvDecreaseThrottlePressure() override;
virtual mozilla::ipc::IPCResult
RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId) override;
private:
nsTArray<mozilla::UniquePtr<mozilla::net::Throttler>> mThrottlers;
virtual mozilla::ipc::IPCResult RecvNotifyCurrentTopLevelOuterContentWindowId(const uint64_t& aWindowId) override;
};
} // namespace net

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

@ -125,12 +125,6 @@ parent:
async PStunAddrsRequest();
/**
* Throttling of channels
*/
async IncreaseThrottlePressure();
async DecreaseThrottlePressure();
prio(high) async NotifyCurrentTopLevelOuterContentWindowId(uint64_t windowId);
child:

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

@ -4248,11 +4248,5 @@ Http2Session::RealJoinConnection(const nsACString &hostname, int32_t port,
return joinedReturn;
}
void
Http2Session::ThrottleResponse(bool aThrottle)
{
// Response throttling on an h2 connection will be implemented later.
}
} // namespace net
} // namespace mozilla

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

@ -52,7 +52,6 @@ public:
uint32_t SpdyVersion() override;
bool TestJoinConnection(const nsACString &hostname, int32_t port) override;
bool JoinConnection(const nsACString &hostname, int32_t port) override;
void ThrottleResponse(bool aThrottle) override;
// When the connection is active this is called up to once every 1 second
// return the interval (in seconds) that the connection next wants to

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

@ -62,7 +62,6 @@
#include "nsIXULRuntime.h"
#include "nsICacheInfoChannel.h"
#include "nsIDOMWindowUtils.h"
#include "nsIThrottlingService.h"
#include <algorithm>
#include "HttpBaseChannel.h"
@ -3071,13 +3070,6 @@ HttpBaseChannel::ReleaseListeners()
{
MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread.");
if (mClassOfService & nsIClassOfService::Throttleable) {
nsIThrottlingService *throttler = gHttpHandler->GetThrottlingService();
if (throttler) {
throttler->RemoveChannel(this);
}
}
mListener = nullptr;
mListenerContext = nullptr;
mCallbacks = nullptr;

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

@ -146,14 +146,6 @@ public:
// nsHttp.h version
virtual uint32_t Version() = 0;
// Throttling control, can be called only on the socket thread. HTTP/1
// implementation effects whether we AsyncWait on the socket input stream
// after reading data. This doesn't have a counter-like logic, hence
// calling it with aThrottle = false will re-enable read from the socket
// immediately. Calling more than once with the same argument value has
// no effect.
virtual void ThrottleResponse(bool aThrottle) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpConnection, NS_AHTTPCONNECTION_IID)

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

@ -107,7 +107,6 @@
#include "HSTSPrimerListener.h"
#include "CacheStorageService.h"
#include "HttpChannelParent.h"
#include "nsIThrottlingService.h"
#include "nsIBufferedStreams.h"
#include "nsIFileStreams.h"
#include "nsIMIMEInputStream.h"
@ -711,7 +710,7 @@ nsHttpChannel::ContinueConnect()
while (suspendCount--)
mTransactionPump->Suspend();
if (mSuspendCount && mClassOfService & nsIClassOfService::Throttleable) {
if (mClassOfService & nsIClassOfService::Throttleable) {
gHttpHandler->ThrottleTransaction(mTransaction, true);
}
@ -6627,18 +6626,9 @@ nsHttpChannel::OnClassOfServiceUpdated()
{
bool throttleable = !!(mClassOfService & nsIClassOfService::Throttleable);
if (mSuspendCount && mTransaction) {
if (mTransaction) {
gHttpHandler->ThrottleTransaction(mTransaction, throttleable);
}
nsIThrottlingService *throttler = gHttpHandler->GetThrottlingService();
if (throttler) {
if (throttleable) {
throttler->AddChannel(this);
} else {
throttler->RemoveChannel(this);
}
}
}
NS_IMETHODIMP

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

@ -86,8 +86,6 @@ nsHttpConnection::nsHttpConnection()
, mContentBytesWritten0RTT(0)
, mEarlyDataNegotiated(false)
, mDid0RTTSpdy(false)
, mResponseThrottled(false)
, mResumeRecvOnUnthrottle(false)
, mFastOpen(false)
, mFastOpenStatus(TFO_NOT_TRIED)
, mForceSendDuringFastOpenPending(false)
@ -1471,22 +1469,6 @@ nsHttpConnection::ResumeRecv()
return NS_OK;
}
// mResponseThrottled is an indication from above layers to stop reading
// the socket.
if (mResponseThrottled) {
mResumeRecvOnUnthrottle = true;
if (mSocketIn) {
LOG((" throttled, waiting for closure only"));
return mSocketIn->AsyncWait(this,
nsIAsyncInputStream::WAIT_CLOSURE_ONLY,
0, nullptr);
}
LOG((" throttled, and no socket input stream"));
NS_NOTREACHED("no socket input stream");
return NS_OK;
}
// the mLastReadTime timestamp is used for finding slowish readers
// and can be pretty sensitive. For that reason we actually reset it
// when we ask to read (resume recv()) so that when we get called back
@ -2165,32 +2147,6 @@ nsHttpConnection::DisableTCPKeepalives()
return NS_OK;
}
void nsHttpConnection::ThrottleResponse(bool aThrottle)
{
LOG(("nsHttpConnection::ThrottleResponse this=%p, throttle=%d", this, aThrottle));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (aThrottle) {
mResponseThrottled = true;
return;
}
mResponseThrottled = false;
if (!mResumeRecvOnUnthrottle) {
// We didn't get to the point when ResumeRecv was called
// during the throttle period, nothing to do.
return;
}
mResumeRecvOnUnthrottle = false;
nsresult rv = ResumeRecv();
if (NS_FAILED(rv)) {
CloseTransaction(mTransaction, rv);
}
}
//-----------------------------------------------------------------------------
// nsHttpConnection::nsISupports
//-----------------------------------------------------------------------------

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

@ -231,8 +231,6 @@ public:
bool TestJoinConnection(const nsACString &hostname, int32_t port);
bool JoinConnection(const nsACString &hostname, int32_t port);
void ThrottleResponse(bool aThrottle);
void SetFastOpenStatus(uint8_t tfoStatus) {
mFastOpenStatus = tfoStatus;
}
@ -396,13 +394,6 @@ private:
nsCString mEarlyNegotiatedALPN;
bool mDid0RTTSpdy;
// Reflects throttling request, effects if we resume read from the socket.
// Accessed only on the socket thread.
bool mResponseThrottled;
// A read from the socket was requested while we where throttled, means
// to ResumeRecv() when untrottled again. Only accessed on the socket thread.
bool mResumeRecvOnUnthrottle;
bool mFastOpen;
uint8_t mFastOpenStatus;

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

@ -1640,7 +1640,6 @@ class ConnectionHandle : public nsAHttpConnection
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSAHTTPCONNECTION(mConn)
virtual void ThrottleResponse(bool aThrottle) override;
explicit ConnectionHandle(nsHttpConnection *conn) : mConn(conn) { }
void Reset() { mConn = nullptr; }
@ -1655,13 +1654,6 @@ nsHttpConnectionMgr::MakeConnectionHandle(nsHttpConnection *aWrapped)
return new ConnectionHandle(aWrapped);
}
void ConnectionHandle::ThrottleResponse(bool aThrottle)
{
if (mConn) {
mConn->ThrottleResponse(aThrottle);
}
}
ConnectionHandle::~ConnectionHandle()
{
if (mConn) {

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

@ -53,7 +53,6 @@
#include "nsComponentManagerUtils.h"
#include "nsSocketTransportService2.h"
#include "nsIOService.h"
#include "nsIThrottlingService.h"
#include "nsISupportsPrimitives.h"
#include "nsIXULRuntime.h"
#include "nsCharSeparatedTokenizer.h"
@ -715,17 +714,6 @@ nsHttpHandler::GetIOService(nsIIOService** result)
return NS_OK;
}
nsIThrottlingService *
nsHttpHandler::GetThrottlingService()
{
if (!mThrottlingService) {
nsCOMPtr<nsIThrottlingService> service = do_GetService(NS_THROTTLINGSERVICE_CONTRACTID);
mThrottlingService = new nsMainThreadPtrHolder<nsIThrottlingService>(service);
}
return mThrottlingService;
}
uint32_t
nsHttpHandler::Get32BitsOfPseudoRandom()
{

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

@ -27,7 +27,6 @@ class nsIIOService;
class nsIRequestContextService;
class nsISiteSecurityService;
class nsIStreamConverterService;
class nsIThrottlingService;
namespace mozilla {
@ -296,7 +295,6 @@ public:
MOZ_MUST_USE nsresult GetIOService(nsIIOService** service);
nsICookieService * GetCookieService(); // not addrefed
nsISiteSecurityService * GetSSService();
nsIThrottlingService * GetThrottlingService();
// callable from socket thread only
uint32_t Get32BitsOfPseudoRandom();
@ -412,7 +410,6 @@ private:
nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
nsMainThreadPtrHandle<nsICookieService> mCookieService;
nsMainThreadPtrHandle<nsISiteSecurityService> mSSService;
nsMainThreadPtrHandle<nsIThrottlingService> mThrottlingService;
// the authentication credentials cache
nsHttpAuthCache mAuthCache;

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

@ -159,12 +159,7 @@ void nsHttpTransaction::ThrottleResponse(bool aThrottle)
{
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
// Just in case we suspend, get a connection, release a connection, get another connection.
mThrottleResponse = aThrottle;
if (mConnection) {
mConnection->ThrottleResponse(aThrottle);
}
}
nsHttpTransaction::~nsHttpTransaction()
@ -479,10 +474,6 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
MutexAutoLock lock(mLock);
mConnection = conn;
}
if (conn && mThrottleResponse) {
gHttpHandler->ThrottleTransaction(this, true);
}
}
void

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

@ -313,6 +313,7 @@ private:
Atomic<bool, ReleaseAcquire> mResponseIsComplete;
// If true, this transaction was asked to stop receiving the response.
// NOTE: this flag is currently unused. A useful remnant of an old throttling algorithm.
bool mThrottleResponse;
// state flags, all logically boolean, but not packed together into a
@ -377,8 +378,8 @@ public:
// but later can be dispatched via spdy (not subject to rate pacing).
void CancelPacing(nsresult reason);
// Forwards to the connection's ThrottleResponse. If there is no connection
// at the time, we set a flag to do it on connection assignment.
// Called only on the socket thread. Updates the flag whether the transaction
// should make the underlying connection or session stop reading from the socket.
void ThrottleResponse(bool aThrottle);
private:

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

@ -11,7 +11,7 @@ function make_channel(url) {
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
}
var multipartBody = "--boundary\r\n\r\nSome text\r\n--boundary\r\nContent-Type: text/x-test\r\n\r\n<?xml version='1.1'?>\r\n<root/>\r\n--boundary\r\n\r\n<?xml version='1.0'?><root/>\r\n--boundary--";
var multipartBody = "--boundary\r\nSet-Cookie: foo=bar\r\n\r\nSome text\r\n--boundary\r\nContent-Type: text/x-test\r\n\r\n<?xml version='1.1'?>\r\n<root/>\r\n--boundary\r\n\r\n<?xml version='1.0'?><root/>\r\n--boundary--";
function contentHandler(metadata, response)
{

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

@ -0,0 +1,3 @@
function run_test() {
run_test_in_child("../unit/test_multipart_streamconv.js");
}

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

@ -56,6 +56,7 @@ support-files =
!/netwerk/test/unit/test_alt-data_simple.js
!/netwerk/test/unit/test_alt-data_stream.js
!/netwerk/test/unit/test_channel_priority.js
!/netwerk/test/unit/test_multipart_streamconv.js
[test_bug528292_wrap.js]
[test_bug248970_cookie_wrap.js]
@ -101,3 +102,4 @@ skip-if = true
[test_trackingProtection_annotateChannels_wrap1.js]
[test_trackingProtection_annotateChannels_wrap2.js]
[test_channel_priority_wrap.js]
[test_multipart_streamconv_wrap.js]

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