mirror of https://github.com/vitalif/phantomjs
Import the old, working prototype.
parent
ec321505c4
commit
f0deb971a0
|
@ -0,0 +1,3 @@
|
|||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
SUBDIRS += src/phantomjs.pro
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2010 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtWebKit>
|
||||
#include <iostream>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
||||
#error Use Qt 4.7 or later version
|
||||
#endif
|
||||
|
||||
class WebPage: public QWebPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WebPage(QObject *parent = 0);
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
|
||||
protected:
|
||||
QString userAgentForUrl(const QUrl &url) const;
|
||||
|
||||
private:
|
||||
QString m_userAgent;
|
||||
friend class Phantom;
|
||||
};
|
||||
|
||||
WebPage::WebPage(QObject *parent)
|
||||
: QWebPage(parent)
|
||||
{
|
||||
m_userAgent = QWebPage::userAgentForUrl(QUrl());
|
||||
}
|
||||
|
||||
bool WebPage::shouldInterruptJavaScript()
|
||||
{
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 42);
|
||||
return false;
|
||||
}
|
||||
|
||||
QString WebPage::userAgentForUrl(const QUrl &url) const
|
||||
{
|
||||
Q_UNUSED(url);
|
||||
return m_userAgent;
|
||||
}
|
||||
|
||||
class Phantom: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QStringList arguments READ arguments)
|
||||
Q_PROPERTY(QString content READ content WRITE setContent)
|
||||
Q_PROPERTY(bool inspectorEnabled READ isInspectorEnabled WRITE setInspectorEnabled)
|
||||
Q_PROPERTY(bool inspectorVisible READ isInspectorVisible WRITE setInspectorVisible)
|
||||
Q_PROPERTY(QString loadStatus READ loadStatus)
|
||||
Q_PROPERTY(QString storage READ storage WRITE setStorage)
|
||||
Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent)
|
||||
|
||||
public:
|
||||
Phantom(QObject *parent = 0);
|
||||
|
||||
QStringList arguments() const;
|
||||
|
||||
QString content() const;
|
||||
void setContent(const QString &content);
|
||||
|
||||
void execute(const QString &fileName);
|
||||
int returnValue() const;
|
||||
|
||||
QString loadStatus() const;
|
||||
|
||||
bool isInspectorEnabled() const;
|
||||
void setInspectorEnabled(bool enable);
|
||||
|
||||
bool isInspectorVisible() const;
|
||||
void setInspectorVisible(bool visible);
|
||||
|
||||
void setStorage(const QString &value);
|
||||
QString storage() const;
|
||||
|
||||
void setUserAgent(const QString &ua);
|
||||
QString userAgent() const;
|
||||
|
||||
public slots:
|
||||
void exit(int code = 0);
|
||||
void log(const QString &msg);
|
||||
void open(const QString &address);
|
||||
void sleep(int ms);
|
||||
|
||||
private slots:
|
||||
void inject();
|
||||
void finish(bool);
|
||||
|
||||
private:
|
||||
QStringList m_arguments;
|
||||
QWebInspector m_inspector;
|
||||
QString m_loadStatus;
|
||||
WebPage m_page;
|
||||
int m_returnValue;
|
||||
QString m_script;
|
||||
QString m_storage;
|
||||
};
|
||||
|
||||
Phantom::Phantom(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_returnValue(0)
|
||||
{
|
||||
QPalette palette = m_page.palette();
|
||||
palette.setBrush(QPalette::Base, Qt::transparent);
|
||||
m_page.setPalette(palette);
|
||||
|
||||
// first argument: program name (phantomjs)
|
||||
// second argument: script name
|
||||
m_arguments = QApplication::arguments();
|
||||
m_arguments.removeFirst();
|
||||
m_arguments.removeFirst();
|
||||
|
||||
m_inspector.setPage(&m_page);
|
||||
|
||||
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), SLOT(inject()));
|
||||
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(finish(bool)));
|
||||
|
||||
m_page.settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
|
||||
m_page.settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
|
||||
m_page.settings()->setLocalStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||
m_page.settings()->setOfflineStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||
}
|
||||
|
||||
QStringList Phantom::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
QString Phantom::content() const
|
||||
{
|
||||
return m_page.mainFrame()->toHtml();
|
||||
}
|
||||
|
||||
void Phantom::setContent(const QString &content)
|
||||
{
|
||||
m_page.mainFrame()->setHtml(content);
|
||||
}
|
||||
|
||||
void Phantom::execute(const QString &fileName)
|
||||
{
|
||||
QFile file;
|
||||
file.setFileName(fileName);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
std::cerr << "Can't open " << qPrintable(fileName) << std::endl << std::endl;
|
||||
QApplication::instance()->exit(1);
|
||||
return;
|
||||
}
|
||||
m_script = file.readAll();
|
||||
file.close();
|
||||
|
||||
m_page.mainFrame()->evaluateJavaScript(m_script);
|
||||
}
|
||||
|
||||
void Phantom::exit(int code)
|
||||
{
|
||||
m_returnValue = code;
|
||||
QTimer::singleShot(0, qApp, SLOT(quit()));
|
||||
}
|
||||
|
||||
void Phantom::finish(bool success)
|
||||
{
|
||||
m_loadStatus = success ? "success" : "fail";
|
||||
m_page.mainFrame()->evaluateJavaScript(m_script);
|
||||
}
|
||||
|
||||
void Phantom::inject()
|
||||
{
|
||||
m_page.mainFrame()->addToJavaScriptWindowObject("phantom", this);
|
||||
}
|
||||
|
||||
bool Phantom::isInspectorEnabled() const
|
||||
{
|
||||
return m_page.settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled);
|
||||
}
|
||||
|
||||
bool Phantom::isInspectorVisible() const
|
||||
{
|
||||
return m_inspector.isVisible();
|
||||
}
|
||||
|
||||
QString Phantom::loadStatus() const
|
||||
{
|
||||
return m_loadStatus;
|
||||
}
|
||||
|
||||
void Phantom::log(const QString &msg)
|
||||
{
|
||||
std::cout << qPrintable(msg) << std::endl;
|
||||
}
|
||||
|
||||
void Phantom::open(const QString &address)
|
||||
{
|
||||
m_page.triggerAction(QWebPage::Stop);
|
||||
m_loadStatus = "loading";
|
||||
m_page.mainFrame()->setUrl(address);
|
||||
}
|
||||
|
||||
void Phantom::setInspectorEnabled(bool enable)
|
||||
{
|
||||
m_page.settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable);
|
||||
}
|
||||
|
||||
void Phantom::setInspectorVisible(bool visible)
|
||||
{
|
||||
m_inspector.setVisible(visible);
|
||||
}
|
||||
|
||||
int Phantom::returnValue() const
|
||||
{
|
||||
return m_returnValue;
|
||||
}
|
||||
|
||||
void Phantom::sleep(int ms)
|
||||
{
|
||||
QTime startTime = QTime::currentTime();
|
||||
while (true) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 25);
|
||||
if (startTime.msecsTo(QTime::currentTime()) > ms)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Phantom::setStorage(const QString &value)
|
||||
{
|
||||
m_storage = value;
|
||||
}
|
||||
|
||||
QString Phantom::storage() const
|
||||
{
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
void Phantom::setUserAgent(const QString &ua)
|
||||
{
|
||||
m_page.m_userAgent = ua;
|
||||
}
|
||||
|
||||
QString Phantom::userAgent() const
|
||||
{
|
||||
return m_page.m_userAgent;
|
||||
}
|
||||
|
||||
#include "phantomjs.moc"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
std::cerr << "phantomjs script.js" << std::endl << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setApplicationName("PhantomJS");
|
||||
app.setOrganizationName("Ofi Labs");
|
||||
app.setOrganizationDomain("www.ofilabs.com");
|
||||
app.setApplicationVersion("1.0");
|
||||
|
||||
Phantom phantom;
|
||||
phantom.execute(QString::fromLocal8Bit(argv[1]));
|
||||
app.exec();
|
||||
return phantom.returnValue();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
TEMPLATE = app
|
||||
TARGET = phantomjs
|
||||
DESTDIR = ../bin
|
||||
SOURCES = phantomjs.cpp
|
||||
QT += network webkit
|
Loading…
Reference in New Issue