Skip to content
This repository was archived by the owner on Jan 21, 2025. It is now read-only.

Commit f0deb97

Browse files
committed
Import the old, working prototype.
1 parent ec32150 commit f0deb97

File tree

3 files changed

+301
-0
lines changed

3 files changed

+301
-0
lines changed

phantomjs.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
TEMPLATE = subdirs
2+
CONFIG += ordered
3+
SUBDIRS += src/phantomjs.pro

src/phantomjs.cpp

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/*
2+
This file is part of the PhantomJS project from Ofi Labs.
3+
4+
Copyright (C) 2010 Ariya Hidayat <[email protected]>
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
* Redistributions in binary form must reproduce the above copyright
12+
notice, this list of conditions and the following disclaimer in the
13+
documentation and/or other materials provided with the distribution.
14+
* Neither the name of the <organization> nor the
15+
names of its contributors may be used to endorse or promote products
16+
derived from this software without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include <QtGui>
31+
#include <QtWebKit>
32+
#include <iostream>
33+
34+
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
35+
#error Use Qt 4.7 or later version
36+
#endif
37+
38+
class WebPage: public QWebPage
39+
{
40+
Q_OBJECT
41+
public:
42+
WebPage(QObject *parent = 0);
43+
44+
public slots:
45+
bool shouldInterruptJavaScript();
46+
47+
protected:
48+
QString userAgentForUrl(const QUrl &url) const;
49+
50+
private:
51+
QString m_userAgent;
52+
friend class Phantom;
53+
};
54+
55+
WebPage::WebPage(QObject *parent)
56+
: QWebPage(parent)
57+
{
58+
m_userAgent = QWebPage::userAgentForUrl(QUrl());
59+
}
60+
61+
bool WebPage::shouldInterruptJavaScript()
62+
{
63+
QApplication::processEvents(QEventLoop::AllEvents, 42);
64+
return false;
65+
}
66+
67+
QString WebPage::userAgentForUrl(const QUrl &url) const
68+
{
69+
Q_UNUSED(url);
70+
return m_userAgent;
71+
}
72+
73+
class Phantom: public QObject
74+
{
75+
Q_OBJECT
76+
Q_PROPERTY(QStringList arguments READ arguments)
77+
Q_PROPERTY(QString content READ content WRITE setContent)
78+
Q_PROPERTY(bool inspectorEnabled READ isInspectorEnabled WRITE setInspectorEnabled)
79+
Q_PROPERTY(bool inspectorVisible READ isInspectorVisible WRITE setInspectorVisible)
80+
Q_PROPERTY(QString loadStatus READ loadStatus)
81+
Q_PROPERTY(QString storage READ storage WRITE setStorage)
82+
Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent)
83+
84+
public:
85+
Phantom(QObject *parent = 0);
86+
87+
QStringList arguments() const;
88+
89+
QString content() const;
90+
void setContent(const QString &content);
91+
92+
void execute(const QString &fileName);
93+
int returnValue() const;
94+
95+
QString loadStatus() const;
96+
97+
bool isInspectorEnabled() const;
98+
void setInspectorEnabled(bool enable);
99+
100+
bool isInspectorVisible() const;
101+
void setInspectorVisible(bool visible);
102+
103+
void setStorage(const QString &value);
104+
QString storage() const;
105+
106+
void setUserAgent(const QString &ua);
107+
QString userAgent() const;
108+
109+
public slots:
110+
void exit(int code = 0);
111+
void log(const QString &msg);
112+
void open(const QString &address);
113+
void sleep(int ms);
114+
115+
private slots:
116+
void inject();
117+
void finish(bool);
118+
119+
private:
120+
QStringList m_arguments;
121+
QWebInspector m_inspector;
122+
QString m_loadStatus;
123+
WebPage m_page;
124+
int m_returnValue;
125+
QString m_script;
126+
QString m_storage;
127+
};
128+
129+
Phantom::Phantom(QObject *parent)
130+
: QObject(parent)
131+
, m_returnValue(0)
132+
{
133+
QPalette palette = m_page.palette();
134+
palette.setBrush(QPalette::Base, Qt::transparent);
135+
m_page.setPalette(palette);
136+
137+
// first argument: program name (phantomjs)
138+
// second argument: script name
139+
m_arguments = QApplication::arguments();
140+
m_arguments.removeFirst();
141+
m_arguments.removeFirst();
142+
143+
m_inspector.setPage(&m_page);
144+
145+
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), SLOT(inject()));
146+
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(finish(bool)));
147+
148+
m_page.settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
149+
m_page.settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
150+
m_page.settings()->setLocalStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
151+
m_page.settings()->setOfflineStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
152+
}
153+
154+
QStringList Phantom::arguments() const
155+
{
156+
return m_arguments;
157+
}
158+
159+
QString Phantom::content() const
160+
{
161+
return m_page.mainFrame()->toHtml();
162+
}
163+
164+
void Phantom::setContent(const QString &content)
165+
{
166+
m_page.mainFrame()->setHtml(content);
167+
}
168+
169+
void Phantom::execute(const QString &fileName)
170+
{
171+
QFile file;
172+
file.setFileName(fileName);
173+
if (!file.open(QFile::ReadOnly)) {
174+
std::cerr << "Can't open " << qPrintable(fileName) << std::endl << std::endl;
175+
QApplication::instance()->exit(1);
176+
return;
177+
}
178+
m_script = file.readAll();
179+
file.close();
180+
181+
m_page.mainFrame()->evaluateJavaScript(m_script);
182+
}
183+
184+
void Phantom::exit(int code)
185+
{
186+
m_returnValue = code;
187+
QTimer::singleShot(0, qApp, SLOT(quit()));
188+
}
189+
190+
void Phantom::finish(bool success)
191+
{
192+
m_loadStatus = success ? "success" : "fail";
193+
m_page.mainFrame()->evaluateJavaScript(m_script);
194+
}
195+
196+
void Phantom::inject()
197+
{
198+
m_page.mainFrame()->addToJavaScriptWindowObject("phantom", this);
199+
}
200+
201+
bool Phantom::isInspectorEnabled() const
202+
{
203+
return m_page.settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled);
204+
}
205+
206+
bool Phantom::isInspectorVisible() const
207+
{
208+
return m_inspector.isVisible();
209+
}
210+
211+
QString Phantom::loadStatus() const
212+
{
213+
return m_loadStatus;
214+
}
215+
216+
void Phantom::log(const QString &msg)
217+
{
218+
std::cout << qPrintable(msg) << std::endl;
219+
}
220+
221+
void Phantom::open(const QString &address)
222+
{
223+
m_page.triggerAction(QWebPage::Stop);
224+
m_loadStatus = "loading";
225+
m_page.mainFrame()->setUrl(address);
226+
}
227+
228+
void Phantom::setInspectorEnabled(bool enable)
229+
{
230+
m_page.settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable);
231+
}
232+
233+
void Phantom::setInspectorVisible(bool visible)
234+
{
235+
m_inspector.setVisible(visible);
236+
}
237+
238+
int Phantom::returnValue() const
239+
{
240+
return m_returnValue;
241+
}
242+
243+
void Phantom::sleep(int ms)
244+
{
245+
QTime startTime = QTime::currentTime();
246+
while (true) {
247+
QApplication::processEvents(QEventLoop::AllEvents, 25);
248+
if (startTime.msecsTo(QTime::currentTime()) > ms)
249+
break;
250+
}
251+
}
252+
253+
void Phantom::setStorage(const QString &value)
254+
{
255+
m_storage = value;
256+
}
257+
258+
QString Phantom::storage() const
259+
{
260+
return m_storage;
261+
}
262+
263+
void Phantom::setUserAgent(const QString &ua)
264+
{
265+
m_page.m_userAgent = ua;
266+
}
267+
268+
QString Phantom::userAgent() const
269+
{
270+
return m_page.m_userAgent;
271+
}
272+
273+
#include "phantomjs.moc"
274+
275+
int main(int argc, char** argv)
276+
{
277+
if (argc < 2) {
278+
std::cerr << "phantomjs script.js" << std::endl << std::endl;
279+
return 1;
280+
}
281+
282+
QApplication app(argc, argv);
283+
284+
app.setApplicationName("PhantomJS");
285+
app.setOrganizationName("Ofi Labs");
286+
app.setOrganizationDomain("www.ofilabs.com");
287+
app.setApplicationVersion("1.0");
288+
289+
Phantom phantom;
290+
phantom.execute(QString::fromLocal8Bit(argv[1]));
291+
app.exec();
292+
return phantom.returnValue();
293+
}

src/phantomjs.pro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TEMPLATE = app
2+
TARGET = phantomjs
3+
DESTDIR = ../bin
4+
SOURCES = phantomjs.cpp
5+
QT += network webkit

0 commit comments

Comments
 (0)