Implement require('webpage').

This is mostly based on Ivan's work, see
https://github.com/ariya/phantomjs/pull/153

window.WebPage still works, it is not recommended and will be
deprecated.

http://code.google.com/p/phantomjs/issues/detail?id=47
1.3
Ariya Hidayat 2011-09-08 17:32:31 -07:00
parent b412aba06d
commit 2b83a52251
5 changed files with 158 additions and 154 deletions

View File

@ -4,7 +4,10 @@
/*
This file is part of the PhantomJS project from Ofi Labs.
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
Copyright (C) 2011 James Roe <roejames12@hotmail.com>
Copyright (C) 2011 execjosh, http://execjosh.blogspot.com
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@ -30,10 +33,159 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function require (name) {
function require(name) {
var exports;
if (name === 'webpage') {
exports = function (opts) {
var page = phantom.createWebPage(),
handlers = {};
function checkType(o, type) {
return typeof o === type;
}
function isObject(o) {
return checkType(o, 'object');
}
function isUndefined(o) {
return checkType(o, 'undefined');
}
function isUndefinedOrNull(o) {
return isUndefined(o) || null === o;
}
function copyInto(target, source) {
if (target === source || isUndefinedOrNull(source)) {
return target;
}
target = target || {};
// Copy into objects only
if (isObject(target)) {
// Make sure source exists
source = source || {};
if (isObject(source)) {
var i, newTarget, newSource;
for (i in source) {
if (source.hasOwnProperty(i)) {
newTarget = target[i];
newSource = source[i];
if (newTarget && isObject(newSource)) {
// Deep copy
newTarget = copyInto(target[i], newSource);
} else {
newTarget = newSource;
}
if (!isUndefined(newTarget)) {
target[i] = newTarget;
}
}
}
} else {
target = source;
}
}
return target;
}
function defineSetter(handlerName, signalName) {
page.__defineSetter__(handlerName, function (f) {
if (handlers && typeof handlers[signalName] === 'function') {
try {
this[signalName].disconnect(handlers[signalName]);
} catch (e) {}
}
handlers[signalName] = f;
this[signalName].connect(handlers[signalName]);
});
}
// deep copy
page.settings = JSON.parse(JSON.stringify(phantom.defaultPageSettings));
defineSetter("onInitialized", "initialized");
defineSetter("onLoadStarted", "loadStarted");
defineSetter("onLoadFinished", "loadFinished");
defineSetter("onResourceRequested", "resourceRequested");
defineSetter("onResourceReceived", "resourceReceived");
defineSetter("onAlert", "javaScriptAlertSent");
defineSetter("onConsoleMessage", "javaScriptConsoleMessageSent");
page.open = function (url, arg1, arg2, arg3, arg4) {
if (arguments.length === 1) {
this.openUrl(url, 'get', this.settings);
return;
}
if (arguments.length === 2 && typeof arg1 === 'function') {
this.onLoadFinished = arg1;
this.openUrl(url, 'get', this.settings);
return;
} else if (arguments.length === 2) {
this.openUrl(url, arg1, this.settings);
return;
} else if (arguments.length === 3 && typeof arg2 === 'function') {
this.onLoadFinished = arg2;
this.openUrl(url, arg1, this.settings);
return;
} else if (arguments.length === 3) {
this.openUrl(url, {
operation: arg1,
data: arg2
}, this.settings);
return;
} else if (arguments.length === 4) {
this.onLoadFinished = arg3;
this.openUrl(url, {
operation: arg1,
data: arg2
}, this.settings);
return;
}
throw "Wrong use of WebPage#open";
};
page.includeJs = function (scriptUrl, onScriptLoaded) {
// Register temporary signal handler for 'alert()'
this.javaScriptAlertSent.connect(function (msgFromAlert) {
if (msgFromAlert === scriptUrl) {
// Resource loaded, time to fire the callback
onScriptLoaded(scriptUrl);
// And disconnect the signal handler
try {
this.javaScriptAlertSent.disconnect(arguments.callee);
} catch (e) {}
}
});
// Append the script tag to the body
this._appendScriptElement(scriptUrl);
};
// Copy options into page
if (opts) {
page = copyInto(page, opts);
}
return page;
};
}
if (name === 'fs') {
exports = phantom.createFilesystem();
@ -178,3 +330,5 @@ function require (name) {
return exports;
}
// Legacy way to use WebPage
window.WebPage = require('webpage');

View File

@ -112,11 +112,10 @@ Phantom::Phantom(QObject *parent)
m_page->mainFrame()->addToJavaScriptWindowObject("phantom", this);
// Load all the required JavaScript 'shims'
QString jsShims[2] = {
":/bootstrap.js",
":/webpage-shim.js"
QString jsShims[1] = {
":/bootstrap.js"
};
for (int i = 0, len = 2; i < len; ++i) {
for (int i = 0, len = 1; i < len; ++i) {
QFile f(jsShims[i]);
f.open(QFile::ReadOnly); //< It's OK to assume this succeed. If it doesn't, we have a bigger problem.
m_page->mainFrame()->evaluateJavaScript(QString::fromUtf8(f.readAll()));

View File

@ -36,7 +36,6 @@ SOURCES += phantom.cpp \
config.cpp
OTHER_FILES += usage.txt \
webpage-shim.js \
bootstrap.js \
configurator.js

View File

@ -3,7 +3,6 @@
<file>phantomjs-icon.png</file>
<file>coffee-script.js</file>
<file>usage.txt</file>
<file>webpage-shim.js</file>
<file>bootstrap.js</file>
<file>configurator.js</file>
</qresource>

View File

@ -33,150 +33,3 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This allows creating a new web page using the construct "new WebPage",
// which feels more natural than "phantom.createWebPage()".
window.WebPage = function (opts) {
var page = phantom.createWebPage(),
handlers = {};
function checkType(o, type) {
return typeof o === type;
}
function isObject(o) {
return checkType(o, 'object');
}
function isUndefined(o) {
return checkType(o, 'undefined');
}
function isUndefinedOrNull(o) {
return isUndefined(o) || null === o;
}
function copyInto(target, source) {
if (target === source || isUndefinedOrNull(source)) {
return target;
}
target = target || {};
// Copy into objects only
if (isObject(target)) {
// Make sure source exists
source = source || {};
if (isObject(source)) {
var i, newTarget, newSource;
for (i in source) {
if (source.hasOwnProperty(i)) {
newTarget = target[i];
newSource = source[i];
if (newTarget && isObject(newSource)) {
// Deep copy
newTarget = copyInto(target[i], newSource);
} else {
newTarget = newSource;
}
if (!isUndefined(newTarget)) {
target[i] = newTarget;
}
}
}
} else {
target = source;
}
}
return target;
}
function defineSetter(handlerName, signalName) {
page.__defineSetter__(handlerName, function (f) {
if (handlers && typeof handlers[signalName] === 'function') {
try {
this[signalName].disconnect(handlers[signalName]);
} catch (e) {}
}
handlers[signalName] = f;
this[signalName].connect(handlers[signalName]);
});
}
// deep copy
page.settings = JSON.parse(JSON.stringify(phantom.defaultPageSettings));
defineSetter("onInitialized", "initialized");
defineSetter("onLoadStarted", "loadStarted");
defineSetter("onLoadFinished", "loadFinished");
defineSetter("onResourceRequested", "resourceRequested");
defineSetter("onResourceReceived", "resourceReceived");
defineSetter("onAlert", "javaScriptAlertSent");
defineSetter("onConsoleMessage", "javaScriptConsoleMessageSent");
page.open = function (url, arg1, arg2, arg3, arg4) {
if (arguments.length === 1) {
this.openUrl(url, 'get', this.settings);
return;
}
if (arguments.length === 2 && typeof arg1 === 'function') {
this.onLoadFinished = arg1;
this.openUrl(url, 'get', this.settings);
return;
} else if (arguments.length === 2) {
this.openUrl(url, arg1, this.settings);
return;
} else if (arguments.length === 3 && typeof arg2 === 'function') {
this.onLoadFinished = arg2;
this.openUrl(url, arg1, this.settings);
return;
} else if (arguments.length === 3) {
this.openUrl(url, {
operation: arg1,
data: arg2
}, this.settings);
return;
} else if (arguments.length === 4) {
this.onLoadFinished = arg3;
this.openUrl(url, {
operation: arg1,
data: arg2
}, this.settings);
return;
}
throw "Wrong use of WebPage#open";
};
page.includeJs = function (scriptUrl, onScriptLoaded) {
// Register temporary signal handler for 'alert()'
this.javaScriptAlertSent.connect(function (msgFromAlert) {
if (msgFromAlert === scriptUrl) {
// Resource loaded, time to fire the callback
onScriptLoaded(scriptUrl);
// And disconnect the signal handler
try {
this.javaScriptAlertSent.disconnect(arguments.callee);
} catch (e) {}
}
});
// Append the script tag to the body
this._appendScriptElement(scriptUrl);
};
// Copy options into page
if (opts) {
page = copyInto(page, opts);
}
return page;
};