зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
c5b2958154
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -25,14 +25,14 @@ const defaultAttributes = {
|
|||
/**
|
||||
* Test data has the format of:
|
||||
* {
|
||||
* desc {String} description for better logging
|
||||
* expected {Object} expected attributes for given accessibles
|
||||
* unexpected {Object} unexpected attributes for given accessibles
|
||||
* desc {String} description for better logging
|
||||
* expected {Object} expected attributes for given accessibles
|
||||
* unexpected {Object} unexpected attributes for given accessibles
|
||||
*
|
||||
* action {?Function*} an optional action that yields a change in
|
||||
* attributes
|
||||
* attrs {?Array} an optional list of attributes to update
|
||||
* waitFor {?Number} an optional event to wait for
|
||||
* 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
|
||||
* }
|
||||
*/
|
||||
const attributesTests = [{
|
||||
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -10,12 +10,12 @@ loadScripts({ name: 'value.js', dir: MOCHITESTS_DIR });
|
|||
/**
|
||||
* Test data has the format of:
|
||||
* {
|
||||
* 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
|
||||
* attrs {?Array} an optional list of attributes to update
|
||||
* waitFor {?Number} an optional value change event to wait for
|
||||
* desc {String} description for better logging
|
||||
* id {String} given accessible DOMNode ID
|
||||
* expected {String} expected value for a given accessible
|
||||
* 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
|
||||
* }
|
||||
*/
|
||||
const valueTests = [{
|
||||
|
@ -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: [
|
||||
|
|
|
@ -15,14 +15,14 @@ Services.scriptloader.loadSubScript(
|
|||
/**
|
||||
* A wrapper around browser test add_task that triggers an accessible test task
|
||||
* as a new browser test task with given document, data URL or markup snippet.
|
||||
* @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
|
||||
* run
|
||||
* @param {String} doc URL (relative to current directory) or
|
||||
* data URL or markup snippet that is used
|
||||
* to test content with
|
||||
* @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,10 +480,10 @@ HangMonitorChild::NotifySlowScript(nsITabChild* aTabChild,
|
|||
}
|
||||
nsAutoCString filename(aFileName);
|
||||
|
||||
MonitorLoop()->PostTask(NewNonOwningRunnableMethod
|
||||
<TabId, nsCString>(this,
|
||||
&HangMonitorChild::NotifySlowScriptAsync,
|
||||
id, filename));
|
||||
Dispatch(NewNonOwningRunnableMethod
|
||||
<TabId, nsCString>(this,
|
||||
&HangMonitorChild::NotifySlowScriptAsync,
|
||||
id, filename));
|
||||
return SlowScriptAction::Continue;
|
||||
}
|
||||
|
||||
|
@ -503,15 +511,15 @@ HangMonitorChild::NotifyPluginHang(uint32_t aPluginId)
|
|||
mSentReport = true;
|
||||
|
||||
// bounce to background thread
|
||||
MonitorLoop()->PostTask(NewNonOwningRunnableMethod<uint32_t>(this,
|
||||
&HangMonitorChild::NotifyPluginHangAsync,
|
||||
aPluginId));
|
||||
Dispatch(NewNonOwningRunnableMethod<uint32_t>(this,
|
||||
&HangMonitorChild::NotifyPluginHangAsync,
|
||||
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,8 +603,8 @@ HangMonitorParent::Shutdown()
|
|||
mProcess = nullptr;
|
||||
}
|
||||
|
||||
MonitorLoop()->PostTask(NewNonOwningRunnableMethod(this,
|
||||
&HangMonitorParent::ShutdownOnThread));
|
||||
Dispatch(NewNonOwningRunnableMethod(this,
|
||||
&HangMonitorParent::ShutdownOnThread));
|
||||
|
||||
while (!mShutdownDone) {
|
||||
mMonitor.Wait();
|
||||
|
@ -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,8 +944,8 @@ HangMonitoredProcess::TerminateScript()
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
|
||||
&HangMonitorParent::TerminateScript));
|
||||
ProcessHangMonitor::Get()->Dispatch(NewNonOwningRunnableMethod(mActor,
|
||||
&HangMonitorParent::TerminateScript));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -953,8 +961,8 @@ HangMonitoredProcess::BeginStartingDebugger()
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
|
||||
&HangMonitorParent::BeginStartingDebugger));
|
||||
ProcessHangMonitor::Get()->Dispatch(NewNonOwningRunnableMethod(mActor,
|
||||
&HangMonitorParent::BeginStartingDebugger));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -970,8 +978,8 @@ HangMonitoredProcess::EndStartingDebugger()
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ProcessHangMonitor::Get()->MonitorLoop()->PostTask(NewNonOwningRunnableMethod(mActor,
|
||||
&HangMonitorParent::EndStartingDebugger));
|
||||
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,10 +1159,10 @@ CreateHangMonitorParent(ContentParent* aContentParent,
|
|||
auto* process = new HangMonitoredProcess(parent, aContentParent);
|
||||
parent->SetProcess(process);
|
||||
|
||||
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
|
||||
<Endpoint<PProcessHangMonitorParent>&&>(parent,
|
||||
&HangMonitorParent::Bind,
|
||||
Move(aEndpoint)));
|
||||
monitor->Dispatch(NewNonOwningRunnableMethod
|
||||
<Endpoint<PProcessHangMonitorParent>&&>(parent,
|
||||
&HangMonitorParent::Bind,
|
||||
Move(aEndpoint)));
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
@ -1171,16 +1178,23 @@ mozilla::CreateHangMonitorChild(Endpoint<PProcessHangMonitorChild>&& aEndpoint)
|
|||
ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
|
||||
auto* child = new HangMonitorChild(monitor);
|
||||
|
||||
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
|
||||
<Endpoint<PProcessHangMonitorChild>&&>(child,
|
||||
&HangMonitorChild::Bind,
|
||||
Move(aEndpoint)));
|
||||
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]
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче