mirror of https://github.com/vitalif/phantomjs
More work on "injectJs"
* "injectJs()" now supports ".coffee" input * "injectJs()" is now available for the "phantom" object as well * CSConverter is now a singleton embedded in the Utils static class * The code used by "injectJs()" is now centralised in the Utils static class1.2
parent
cc45aa7f38
commit
bd18d7c838
|
@ -35,6 +35,7 @@
|
|||
#define PHANTOMJS_VERSION_MINOR 2
|
||||
#define PHANTOMJS_VERSION_PATCH 0
|
||||
#define PHANTOMJS_VERSION_STRING "1.2.0"
|
||||
#define COFFEE_SCRIPT_EXTENSION ".coffee"
|
||||
|
||||
#define JS_ELEMENT_CLICK "(function (el) { " \
|
||||
"var ev = document.createEvent('MouseEvents');" \
|
||||
|
|
|
@ -52,8 +52,7 @@ CSConverter::CSConverter(QObject *parent)
|
|||
QString CSConverter::convert(const QString &script)
|
||||
{
|
||||
setProperty("source", script);
|
||||
QWebFrame *frame = m_webPage.mainFrame();
|
||||
QVariant result = frame->evaluateJavaScript("this.CoffeeScript.compile(converter.source)");
|
||||
QVariant result = m_webPage.mainFrame()->evaluateJavaScript("this.CoffeeScript.compile(converter.source)");
|
||||
if (result.type() == QVariant::String)
|
||||
return result.toString();
|
||||
return QString();
|
||||
|
|
|
@ -58,6 +58,8 @@ int main(int argc, char** argv)
|
|||
Phantom phantom;
|
||||
if (phantom.execute()) {
|
||||
app.exec();
|
||||
} else {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return phantom.returnValue();
|
||||
}
|
||||
|
|
|
@ -186,31 +186,9 @@ QVariantMap Phantom::defaultPageSettings() const
|
|||
|
||||
bool Phantom::execute()
|
||||
{
|
||||
if (m_scriptFile.isEmpty())
|
||||
return false;
|
||||
|
||||
QFile file;
|
||||
file.setFileName(m_scriptFile);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
std::cerr << "Can't open '" << qPrintable(m_scriptFile) << "'" << std::endl << std::endl;
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
m_script = QString::fromUtf8(file.readAll());
|
||||
file.close();
|
||||
|
||||
if (m_scriptFile.endsWith(".coffee")) {
|
||||
if (!m_converter)
|
||||
m_converter = new CSConverter(this);
|
||||
m_script = m_converter->convert(m_script);
|
||||
}
|
||||
|
||||
if (m_script.startsWith("#!")) {
|
||||
m_script.prepend("//");
|
||||
}
|
||||
|
||||
m_page->mainFrame()->evaluateJavaScript(m_script);
|
||||
return !m_terminated;
|
||||
return !m_scriptFile.isEmpty() && //< script filename provided
|
||||
Utils::injectJsInFrame(m_scriptFile, QDir::currentPath(), m_page->mainFrame()) && //< script injected
|
||||
!m_terminated; //< not terminated
|
||||
}
|
||||
|
||||
int Phantom::returnValue() const
|
||||
|
@ -243,6 +221,10 @@ void Phantom::exit(int code)
|
|||
QApplication::instance()->exit(code);
|
||||
}
|
||||
|
||||
bool Phantom::injectJs(const QString &jsFilePath) {
|
||||
return Utils::injectJsInFrame(jsFilePath, QDir::currentPath(), m_page->mainFrame());
|
||||
}
|
||||
|
||||
void Phantom::printConsoleMessage(const QString &msg)
|
||||
{
|
||||
std::cout << qPrintable(msg) << std::endl;
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
|
||||
public slots:
|
||||
QObject *createWebPage();
|
||||
bool injectJs(const QString &jsFilePath);
|
||||
void exit(int code = 0);
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
|
||||
#include "consts.h"
|
||||
#include "utils.h"
|
||||
|
||||
// public:
|
||||
|
@ -67,6 +69,50 @@ void Utils::messageHandler(QtMsgType type, const char *msg)
|
|||
}
|
||||
}
|
||||
|
||||
QString Utils::coffee2js(const QString &script)
|
||||
{
|
||||
// We need only one instance of the CSConverter to survive for the whole life of PhantomJS
|
||||
static CSConverter *coffeeScriptConverter = NULL;
|
||||
if ( !coffeeScriptConverter ) {
|
||||
coffeeScriptConverter = new CSConverter();
|
||||
}
|
||||
|
||||
return coffeeScriptConverter->convert(script);
|
||||
}
|
||||
|
||||
bool Utils::injectJsInFrame(const QString &jsFilePath, const QString &scriptLookupDir, QWebFrame *targetFrame)
|
||||
{
|
||||
// Don't do anything if an empty string is passed
|
||||
if (!jsFilePath.isEmpty()) {
|
||||
QFile jsFile;
|
||||
|
||||
// Is file in the PWD?
|
||||
jsFile.setFileName(QDir::fromNativeSeparators(jsFilePath)); //< Normalise User-provided path
|
||||
if (!jsFile.exists()) {
|
||||
// File is not in the PWD. Is it in the lookup directory?
|
||||
jsFile.setFileName( scriptLookupDir + '/' + QDir::fromNativeSeparators(jsFilePath) );
|
||||
}
|
||||
|
||||
if ( jsFile.open(QFile::ReadOnly) ) {
|
||||
QString scriptBody = QString::fromUtf8(jsFile.readAll());
|
||||
// Remove CLI script heading
|
||||
if (scriptBody.startsWith("#!")) {
|
||||
scriptBody.prepend("//");
|
||||
}
|
||||
|
||||
// Execute JS code in the context of the document
|
||||
targetFrame->evaluateJavaScript(jsFile.fileName().endsWith(COFFEE_SCRIPT_EXTENSION) ?
|
||||
Utils::coffee2js(scriptBody) : //< convert from Coffee Script
|
||||
scriptBody);
|
||||
jsFile.close();
|
||||
return true;
|
||||
} else {
|
||||
std::cerr << "Can't open '" << qPrintable(jsFilePath) << "'" << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// private:
|
||||
Utils::Utils()
|
||||
{
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#define UTILS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QWebFrame>
|
||||
|
||||
#include "csconverter.h"
|
||||
|
||||
/**
|
||||
* Aggregate common utility functions.
|
||||
|
@ -42,6 +45,8 @@ class Utils
|
|||
public:
|
||||
static void showUsage();
|
||||
static void messageHandler(QtMsgType type, const char *msg);
|
||||
static QString coffee2js(const QString &script);
|
||||
static bool injectJsInFrame(const QString &jsFilePath, const QString &scriptLookupDir, QWebFrame *targetFrame);
|
||||
|
||||
private:
|
||||
Utils(); //< This class shouldn't be instantiated
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <QWebFrame>
|
||||
#include <QWebPage>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
|
||||
#include <QWebElement>
|
||||
#endif
|
||||
|
@ -494,27 +496,7 @@ void WebPage::click(const QString &selector) {
|
|||
#endif
|
||||
|
||||
bool WebPage::injectJs(const QString &jsFilePath) {
|
||||
// Don't do anything if an empty string is passed
|
||||
if (!jsFilePath.isEmpty()) {
|
||||
QFile jsFile;
|
||||
|
||||
// Normalise User-provided path
|
||||
jsFilePath = QDir::fromNativeSeparators(jsFilePath);
|
||||
// Is file in the PWD?
|
||||
jsFile.setFileName(jsFilePath);
|
||||
if (!jsFile.exists()) {
|
||||
// File is not in the PWD. Is it in the lookup directory?
|
||||
jsFile.setFileName( m_scriptLookupDir + '/' + jsFilePath );
|
||||
}
|
||||
|
||||
if ( jsFile.open(QFile::ReadOnly) ) {
|
||||
// Execute JS code in the context of the document
|
||||
m_mainFrame->evaluateJavaScript( QString::fromUtf8(jsFile.readAll()) );
|
||||
jsFile.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return Utils::injectJsInFrame(jsFilePath, m_scriptLookupDir, m_mainFrame);
|
||||
}
|
||||
|
||||
void WebPage::_appendScriptElement(const QString &scriptUrl) {
|
||||
|
|
Loading…
Reference in New Issue