1
1
mirror of https://github.com/ariya/phantomjs.git synced 2024-09-11 12:55:33 +03:00

Issue #13234: page.includeJs() callbacks should fire only once.

Thanks to the awkward semantics of JS 'this', callbacks registered for
page.includeJs() completion were not getting deregistered.  This was
invisible under most conditions, but: if you loaded a page, included JS
into it, loaded another page using the same webpage object, and then
included the *same* JS file into the second page, the callback you
provided for the *first* call to includeJs would get called a second
time.
This commit is contained in:
YunJu Lee 2015-12-21 10:52:13 -05:00 committed by Zack Weinberg
parent b38fd78eb1
commit 668d8a42f7
5 changed files with 55 additions and 4 deletions

View File

@ -334,7 +334,8 @@ function decorateNewPage(opts, page) {
*/
page.includeJs = function (scriptUrl, onScriptLoaded) {
// Register temporary signal handler for 'alert()'
this.javaScriptAlertSent.connect(function (msgFromAlert) {
var self = this;
function alertCallback (msgFromAlert) {
if (msgFromAlert === scriptUrl) {
// Resource loaded, time to fire the callback (if any)
if (onScriptLoaded && typeof(onScriptLoaded) === "function") {
@ -342,13 +343,14 @@ function decorateNewPage(opts, page) {
}
// And disconnect the signal handler
try {
this.javaScriptAlertSent.disconnect(arguments.callee);
self.javaScriptAlertSent.disconnect(alertCallback);
} catch (e) {}
}
});
}
self.javaScriptAlertSent.connect(alertCallback);
// Append the script tag to the body
this._appendScriptElement(scriptUrl);
self._appendScriptElement(scriptUrl);
};
/**

View File

@ -0,0 +1,42 @@
var webpage = require('webpage');
async_test(function () {
var page = webpage.create();
page.open(TEST_HTTP_BASE + 'includejs1.html',
this.step_func(function (status) {
assert_equals(status, 'success');
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
this.step_func_done(function () {
var title = page.evaluate('getTitle');
assert_equals(title, 'i am includejs one');
}));
}));
}, "including JS in a page");
async_test(function () {
var page = webpage.create();
var already = false;
page.open(TEST_HTTP_BASE + 'includejs1.html',
this.step_func(function (status) {
assert_equals(status, 'success');
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
this.step_func(function () {
assert_is_false(already);
already = true;
var title = page.evaluate('getTitle');
assert_equals(title, 'i am includejs one');
page.open(TEST_HTTP_BASE + 'includejs2.html',
this.step_func(function (status) {
assert_equals(status, 'success');
page.includeJs(TEST_HTTP_BASE + 'includejs.js',
this.step_func_done(function () {
assert_is_true(already);
var title = page.evaluate('getTitle');
assert_equals(title, 'i am includejs two');
}));
}));
}));
}));
}, "after-inclusion callbacks should fire only once");

3
test/www/includejs.js Normal file
View File

@ -0,0 +1,3 @@
function getTitle () {
return document.title;
}

2
test/www/includejs1.html Normal file
View File

@ -0,0 +1,2 @@
<!doctype html>
<title>i am includejs one</title>

2
test/www/includejs2.html Normal file
View File

@ -0,0 +1,2 @@
<!doctype html>
<title>i am includejs two</title>