├── webkit_server.pro ├── .gitignore ├── src ├── webkit_server.qrc ├── Url.h ├── Body.h ├── Header.h ├── Reset.h ├── SetProxy.h ├── Find.h ├── SetCookie.h ├── Status.h ├── Execute.h ├── Headers.h ├── Visit.h ├── ClearCookies.h ├── CurrentUrl.h ├── SetTimeout.h ├── NullCommand.h ├── RequestedUrl.h ├── ResizeWindow.h ├── SetPromptText.h ├── ClearPromptText.h ├── ConsoleMessages.h ├── GetWindowHandle.h ├── Render.h ├── SetConfirmAction.h ├── SetPromptAction.h ├── GetWindowHandles.h ├── IgnoreSslErrors.h ├── SetUrlBlacklist.h ├── Evaluate.h ├── GetTimeout.h ├── SetSkipImageLoading.h ├── Authenticate.h ├── GetCookies.h ├── JavascriptAlertMessages.h ├── EnableLogging.h ├── JavascriptPromptMessages.h ├── JavascriptConfirmMessages.h ├── Node.h ├── GetTimeout.cpp ├── EnableLogging.cpp ├── Server.h ├── SetPromptText.cpp ├── ClearPromptText.cpp ├── Reset.cpp ├── Source.h ├── WindowFocus.h ├── GetWindowHandle.cpp ├── NullCommand.cpp ├── SetPromptAction.cpp ├── SetConfirmAction.cpp ├── Status.cpp ├── CommandFactory.h ├── IgnoreSslErrors.cpp ├── NetworkCookieJar.h ├── NoOpReply.h ├── Url.cpp ├── SetSkipImageLoading.cpp ├── ClearCookies.cpp ├── JavascriptInvocation.cpp ├── Visit.cpp ├── RequestedUrl.cpp ├── CurrentUrl.cpp ├── body.cpp ├── ConsoleMessages.cpp ├── Headers.cpp ├── UnsupportedContentHandler.h ├── Evaluate.cpp ├── ResizeWindow.cpp ├── JavascriptAlertMessages.cpp ├── JavascriptPromptMessages.cpp ├── JavascriptConfirmMessages.cpp ├── Render.cpp ├── SetUrlBlacklist.cpp ├── JsonSerializer.h ├── SetCookie.cpp ├── SetTimeout.cpp ├── Execute.cpp ├── JavascriptInvocation.h ├── SocketCommand.cpp ├── Command.cpp ├── FrameFocus.h ├── GetCookies.cpp ├── Command.h ├── Find.cpp ├── Response.h ├── Authenticate.cpp ├── Source.cpp ├── GetWindowHandles.cpp ├── SocketCommand.h ├── Header.cpp ├── Server.cpp ├── Node.cpp ├── main.cpp ├── Response.cpp ├── SetProxy.cpp ├── UnsupportedContentHandler.cpp ├── CommandParser.h ├── WindowFocus.cpp ├── NoOpReply.cpp ├── Connection.h ├── TimeoutCommand.h ├── PageLoadingCommand.h ├── find_command.h ├── CommandFactory.cpp ├── NetworkAccessManager.h ├── WebPageManager.h ├── FrameFocus.cpp ├── PageLoadingCommand.cpp ├── CommandParser.cpp ├── Connection.cpp ├── TimeoutCommand.cpp ├── webkit_server.pro ├── JsonSerializer.cpp ├── WebPage.h ├── NetworkCookieJar.cpp ├── WebPageManager.cpp ├── NetworkAccessManager.cpp ├── webkit_server.js └── WebPage.cpp ├── README.markdown ├── bin └── Info.plist └── LICENSE /webkit_server.pro: -------------------------------------------------------------------------------- 1 | CONFIG += ordered 2 | SUBDIRS += src/webkit_server.pro 3 | TEMPLATE = subdirs 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.moc 3 | Makefile* 4 | qrc_* 5 | moc_*.cpp 6 | bin/webkit_server 7 | src/webkit_server 8 | -------------------------------------------------------------------------------- /src/webkit_server.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | webkit_server.js 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Url.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Url : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Url(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Body.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Body : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Body(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Header.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Header : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Header(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/Reset.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Reset : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Reset(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/SetProxy.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetProxy : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | SetProxy(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/Find.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Find : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Find(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/SetCookie.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetCookie : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | SetCookie(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/Status.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Status : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Status(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Execute.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Execute : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Execute(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Headers.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Headers : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Headers(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Visit.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class Visit : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | Visit(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/ClearCookies.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class ClearCookies : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | ClearCookies(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/CurrentUrl.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class CurrentUrl : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | CurrentUrl(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/SetTimeout.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetTimeout : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | SetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/NullCommand.h: -------------------------------------------------------------------------------- 1 | #include "Command.h" 2 | 3 | class NullCommand : public Command { 4 | Q_OBJECT 5 | 6 | public: 7 | NullCommand(QString name, QObject *parent = 0); 8 | virtual void start(); 9 | 10 | private: 11 | QString m_name; 12 | }; 13 | -------------------------------------------------------------------------------- /src/RequestedUrl.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class RequestedUrl : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | RequestedUrl(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/ResizeWindow.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class ResizeWindow : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | ResizeWindow(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/SetPromptText.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetPromptText : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | SetPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/ClearPromptText.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class ClearPromptText : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/ConsoleMessages.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class ConsoleMessages : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | ConsoleMessages(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/GetWindowHandle.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class GetWindowHandle : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | GetWindowHandle(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/Render.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | #include 3 | 4 | class Render : public SocketCommand { 5 | Q_OBJECT 6 | 7 | public: 8 | Render(WebPageManager *page, QStringList &arguments, QObject *parent = 0); 9 | virtual void start(); 10 | }; 11 | -------------------------------------------------------------------------------- /src/SetConfirmAction.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetConfirmAction : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | SetConfirmAction(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/SetPromptAction.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetPromptAction : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | SetPromptAction(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/GetWindowHandles.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class GetWindowHandles : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | GetWindowHandles(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/IgnoreSslErrors.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class IgnoreSslErrors : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | IgnoreSslErrors(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /src/SetUrlBlacklist.h: -------------------------------------------------------------------------------- 1 | 2 | #include "SocketCommand.h" 3 | 4 | class SetUrlBlacklist : public SocketCommand { 5 | Q_OBJECT 6 | 7 | public: 8 | SetUrlBlacklist(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 9 | virtual void start(); 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /src/Evaluate.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | #include 4 | 5 | class Evaluate : public SocketCommand { 6 | Q_OBJECT 7 | 8 | public: 9 | Evaluate(WebPageManager *, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /src/GetTimeout.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class WebPageManager; 4 | 5 | class GetTimeout : public SocketCommand { 6 | Q_OBJECT; 7 | 8 | public: 9 | GetTimeout(WebPageManager *page, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | }; 12 | -------------------------------------------------------------------------------- /src/SetSkipImageLoading.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class SetSkipImageLoading : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | SetSkipImageLoading(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/Authenticate.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class WebPage; 4 | 5 | class Authenticate : public SocketCommand { 6 | Q_OBJECT 7 | 8 | public: 9 | Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /src/GetCookies.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class GetCookies : public SocketCommand { 4 | Q_OBJECT; 5 | 6 | public: 7 | GetCookies(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | 10 | private: 11 | QString m_buffer; 12 | }; 13 | -------------------------------------------------------------------------------- /src/JavascriptAlertMessages.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class JavascriptAlertMessages : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | JavascriptAlertMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/EnableLogging.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class WebPageManager; 4 | 5 | class EnableLogging : public SocketCommand { 6 | Q_OBJECT 7 | 8 | public: 9 | EnableLogging(WebPageManager *, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /src/JavascriptPromptMessages.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class JavascriptPromptMessages : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | JavascriptPromptMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/JavascriptConfirmMessages.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class JavascriptConfirmMessages : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | JavascriptConfirmMessages(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | }; 10 | -------------------------------------------------------------------------------- /src/Node.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | #include 3 | 4 | class Node : public SocketCommand { 5 | Q_OBJECT 6 | 7 | public: 8 | Node(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); 9 | virtual void start(); 10 | virtual QString toString() const; 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /src/GetTimeout.cpp: -------------------------------------------------------------------------------- 1 | #include "GetTimeout.h" 2 | #include "WebPageManager.h" 3 | 4 | GetTimeout::GetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 5 | } 6 | 7 | void GetTimeout::start() { 8 | emitFinished(true, QString::number(manager()->getTimeout())); 9 | } 10 | -------------------------------------------------------------------------------- /src/EnableLogging.cpp: -------------------------------------------------------------------------------- 1 | #include "EnableLogging.h" 2 | #include "WebPageManager.h" 3 | 4 | EnableLogging::EnableLogging(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 5 | } 6 | 7 | void EnableLogging::start() { 8 | manager()->enableLogging(); 9 | emitFinished(true); 10 | } 11 | -------------------------------------------------------------------------------- /src/Server.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class QTcpServer; 4 | 5 | class Server : public QObject { 6 | Q_OBJECT 7 | 8 | public: 9 | Server(QObject *parent); 10 | bool start(); 11 | quint16 server_port() const; 12 | 13 | public slots: 14 | void handleConnection(); 15 | 16 | private: 17 | QTcpServer *m_tcp_server; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /src/SetPromptText.cpp: -------------------------------------------------------------------------------- 1 | #include "SetPromptText.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | SetPromptText::SetPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 6 | 7 | void SetPromptText::start() 8 | { 9 | page()->setPromptText(arguments()[0]); 10 | emitFinished(true); 11 | } 12 | -------------------------------------------------------------------------------- /src/ClearPromptText.cpp: -------------------------------------------------------------------------------- 1 | #include "ClearPromptText.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | ClearPromptText::ClearPromptText(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 6 | 7 | void ClearPromptText::start() 8 | { 9 | page()->setPromptText(QString()); 10 | emitFinished(true); 11 | } 12 | -------------------------------------------------------------------------------- /src/Reset.cpp: -------------------------------------------------------------------------------- 1 | #include "Reset.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Reset::Reset(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Reset::start() { 9 | page()->triggerAction(QWebPage::Stop); 10 | 11 | manager()->reset(); 12 | 13 | emitFinished(true); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/Source.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class QNetworkReply; 4 | 5 | class Source : public SocketCommand { 6 | Q_OBJECT 7 | 8 | public: 9 | Source(WebPageManager *, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | 12 | public slots: 13 | void sourceLoaded(); 14 | 15 | private: 16 | QNetworkReply *reply; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /src/WindowFocus.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class WindowFocus : public SocketCommand { 4 | Q_OBJECT 5 | 6 | public: 7 | WindowFocus(WebPageManager *, QStringList &arguments, QObject *parent = 0); 8 | virtual void start(); 9 | 10 | private: 11 | void success(WebPage *); 12 | void windowNotFound(); 13 | void focusWindow(QString); 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /src/GetWindowHandle.cpp: -------------------------------------------------------------------------------- 1 | #include "GetWindowHandle.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include 5 | 6 | GetWindowHandle::GetWindowHandle(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void GetWindowHandle::start() { 10 | emitFinished(true, page()->uuid()); 11 | } 12 | -------------------------------------------------------------------------------- /src/NullCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "NullCommand.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | NullCommand::NullCommand(QString name, QObject *parent) : Command(parent) { 6 | m_name = name; 7 | } 8 | 9 | void NullCommand::start() { 10 | QString failure = QString("[WebKit Server] Unknown command: ") + m_name + "\n"; 11 | emitFinished(false, failure); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/SetPromptAction.cpp: -------------------------------------------------------------------------------- 1 | #include "SetPromptAction.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | SetPromptAction::SetPromptAction(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 6 | 7 | void SetPromptAction::start() 8 | { 9 | page()->setPromptAction(arguments()[0]); 10 | emitFinished(true); 11 | } 12 | -------------------------------------------------------------------------------- /src/SetConfirmAction.cpp: -------------------------------------------------------------------------------- 1 | #include "SetConfirmAction.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | SetConfirmAction::SetConfirmAction(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 6 | 7 | void SetConfirmAction::start() 8 | { 9 | page()->setConfirmAction(arguments()[0]); 10 | emitFinished(true); 11 | } 12 | -------------------------------------------------------------------------------- /src/Status.cpp: -------------------------------------------------------------------------------- 1 | #include "Status.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include 5 | 6 | Status::Status(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void Status::start() { 10 | int status = page()->getLastStatus(); 11 | emitFinished(true, QString::number(status)); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/CommandFactory.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Command; 4 | class WebPage; 5 | class WebPageManager; 6 | 7 | class CommandFactory : public QObject { 8 | Q_OBJECT 9 | 10 | public: 11 | CommandFactory(WebPageManager *, QObject *parent = 0); 12 | Command *createCommand(const char *name, QStringList &arguments); 13 | 14 | private: 15 | WebPageManager *m_manager; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /src/IgnoreSslErrors.cpp: -------------------------------------------------------------------------------- 1 | #include "IgnoreSslErrors.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | IgnoreSslErrors::IgnoreSslErrors(WebPageManager *manager, QStringList &arguments, QObject *parent) : 6 | SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void IgnoreSslErrors::start() { 10 | manager()->setIgnoreSslErrors(true); 11 | emitFinished(true); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/NetworkCookieJar.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class NetworkCookieJar : public QNetworkCookieJar { 5 | 6 | Q_OBJECT; 7 | 8 | public: 9 | 10 | NetworkCookieJar(QObject *parent = 0); 11 | 12 | QList getAllCookies() const; 13 | void clearCookies(); 14 | void overwriteCookies(const QList& cookieList); 15 | }; 16 | -------------------------------------------------------------------------------- /src/NoOpReply.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class NoOpReply : public QNetworkReply { 5 | Q_OBJECT 6 | 7 | public: 8 | NoOpReply(QNetworkRequest &request, QObject *parent = 0); 9 | 10 | void abort(); 11 | qint64 bytesAvailable() const; 12 | bool isSequential() const; 13 | 14 | protected: 15 | qint64 readData(char *data, qint64 maxSize); 16 | 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /src/Url.cpp: -------------------------------------------------------------------------------- 1 | #include "Url.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Url::Url(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Url::start() { 9 | QUrl humanUrl = page()->currentFrame()->url(); 10 | QByteArray encodedBytes = humanUrl.toEncoded(); 11 | emit finished(new Response(true, encodedBytes)); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/SetSkipImageLoading.cpp: -------------------------------------------------------------------------------- 1 | #include "SetSkipImageLoading.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | SetSkipImageLoading::SetSkipImageLoading(WebPageManager *manager, QStringList &arguments, QObject *parent) : 6 | SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void SetSkipImageLoading::start() { 10 | page()->setSkipImageLoading(arguments().contains("true")); 11 | emitFinished(true); 12 | } 13 | -------------------------------------------------------------------------------- /src/ClearCookies.cpp: -------------------------------------------------------------------------------- 1 | #include "ClearCookies.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "NetworkCookieJar.h" 5 | #include 6 | 7 | ClearCookies::ClearCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 8 | 9 | void ClearCookies::start() 10 | { 11 | manager()->cookieJar()->clearCookies(); 12 | emitFinished(true); 13 | } 14 | -------------------------------------------------------------------------------- /src/JavascriptInvocation.cpp: -------------------------------------------------------------------------------- 1 | #include "JavascriptInvocation.h" 2 | 3 | JavascriptInvocation::JavascriptInvocation(const QString &functionName, const QStringList &arguments, QObject *parent) : QObject(parent) { 4 | m_functionName = functionName; 5 | m_arguments = arguments; 6 | } 7 | 8 | QString &JavascriptInvocation::functionName() { 9 | return m_functionName; 10 | } 11 | 12 | QStringList &JavascriptInvocation::arguments() { 13 | return m_arguments; 14 | } 15 | -------------------------------------------------------------------------------- /src/Visit.cpp: -------------------------------------------------------------------------------- 1 | #include "Visit.h" 2 | #include "SocketCommand.h" 3 | #include "WebPage.h" 4 | #include "WebPageManager.h" 5 | 6 | Visit::Visit(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void Visit::start() { 10 | QUrl requestedUrl = QUrl::fromEncoded(arguments()[0].toUtf8(), QUrl::StrictMode); 11 | page()->currentFrame()->load(QUrl(requestedUrl)); 12 | emitFinished(true); 13 | } 14 | -------------------------------------------------------------------------------- /src/RequestedUrl.cpp: -------------------------------------------------------------------------------- 1 | #include "RequestedUrl.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | RequestedUrl::RequestedUrl(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void RequestedUrl::start() { 9 | QUrl humanUrl = page()->currentFrame()->requestedUrl(); 10 | QByteArray encodedBytes = humanUrl.toEncoded(); 11 | emit finished(new Response(true, encodedBytes)); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/CurrentUrl.cpp: -------------------------------------------------------------------------------- 1 | #include "CurrentUrl.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | CurrentUrl::CurrentUrl(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void CurrentUrl::start() { 9 | QStringList arguments; 10 | QVariant result = page()->invokeWebKitServerFunction("currentUrl", arguments); 11 | QString url = result.toString(); 12 | emitFinished(true, url); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/body.cpp: -------------------------------------------------------------------------------- 1 | #include "Body.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Body::Body(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Body::start() { 9 | QString result; 10 | if (page()->unsupportedContentLoaded()) 11 | result = page()->currentFrame()->toPlainText(); 12 | else 13 | result = page()->currentFrame()->toHtml(); 14 | 15 | emitFinished(true, result); 16 | } 17 | -------------------------------------------------------------------------------- /src/ConsoleMessages.cpp: -------------------------------------------------------------------------------- 1 | #include "ConsoleMessages.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "JsonSerializer.h" 5 | 6 | ConsoleMessages::ConsoleMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void ConsoleMessages::start() { 10 | JsonSerializer serializer; 11 | QByteArray json = serializer.serialize(page()->consoleMessages()); 12 | emitFinished(true, json); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/Headers.cpp: -------------------------------------------------------------------------------- 1 | #include "Headers.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Headers::Headers(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Headers::start() { 9 | QStringList headers; 10 | 11 | foreach(QNetworkReply::RawHeaderPair header, page()->pageHeaders()) 12 | headers << header.first+": "+header.second; 13 | 14 | emitFinished(true, headers.join("\n")); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/UnsupportedContentHandler.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class WebPage; 4 | class QNetworkReply; 5 | 6 | class UnsupportedContentHandler : public QObject { 7 | Q_OBJECT 8 | 9 | public: 10 | UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent = 0); 11 | void waitForReplyToFinish(); 12 | void renderNonHtmlContent(); 13 | 14 | public slots: 15 | void replyFinished(); 16 | 17 | private: 18 | WebPage *m_page; 19 | QNetworkReply *m_reply; 20 | }; 21 | -------------------------------------------------------------------------------- /src/Evaluate.cpp: -------------------------------------------------------------------------------- 1 | #include "Evaluate.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "JsonSerializer.h" 5 | #include 6 | 7 | Evaluate::Evaluate(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 8 | } 9 | 10 | void Evaluate::start() { 11 | QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]); 12 | JsonSerializer serializer; 13 | emitFinished(true, serializer.serialize(result)); 14 | } 15 | -------------------------------------------------------------------------------- /src/ResizeWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "ResizeWindow.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | ResizeWindow::ResizeWindow(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void ResizeWindow::start() { 9 | int width = arguments()[0].toInt(); 10 | int height = arguments()[1].toInt(); 11 | 12 | QSize size(width, height); 13 | page()->setViewportSize(size); 14 | 15 | emitFinished(true); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/JavascriptAlertMessages.cpp: -------------------------------------------------------------------------------- 1 | #include "JavascriptAlertMessages.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "JsonSerializer.h" 5 | 6 | JavascriptAlertMessages::JavascriptAlertMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 7 | 8 | void JavascriptAlertMessages::start() 9 | { 10 | JsonSerializer serializer; 11 | QByteArray json = serializer.serialize(page()->alertMessages()); 12 | emitFinished(true, json); 13 | } 14 | -------------------------------------------------------------------------------- /src/JavascriptPromptMessages.cpp: -------------------------------------------------------------------------------- 1 | #include "JavascriptPromptMessages.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "JsonSerializer.h" 5 | 6 | JavascriptPromptMessages::JavascriptPromptMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 7 | 8 | void JavascriptPromptMessages::start() 9 | { 10 | JsonSerializer serializer; 11 | QByteArray json = serializer.serialize(page()->promptMessages()); 12 | emitFinished(true, json); 13 | } 14 | -------------------------------------------------------------------------------- /src/JavascriptConfirmMessages.cpp: -------------------------------------------------------------------------------- 1 | #include "JavascriptConfirmMessages.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "JsonSerializer.h" 5 | 6 | JavascriptConfirmMessages::JavascriptConfirmMessages(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 7 | 8 | void JavascriptConfirmMessages::start() 9 | { 10 | JsonSerializer serializer; 11 | QByteArray json = serializer.serialize(page()->confirmMessages()); 12 | emitFinished(true, json); 13 | } 14 | -------------------------------------------------------------------------------- /src/Render.cpp: -------------------------------------------------------------------------------- 1 | #include "Render.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Render::Render(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Render::start() { 9 | QString imagePath = arguments()[0]; 10 | int width = arguments()[1].toInt(); 11 | int height = arguments()[2].toInt(); 12 | 13 | QSize size(width, height); 14 | 15 | bool result = page()->render( imagePath, size ); 16 | 17 | emitFinished(result); 18 | } 19 | -------------------------------------------------------------------------------- /src/SetUrlBlacklist.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "SetUrlBlacklist.h" 3 | #include "WebPageManager.h" 4 | #include "WebPage.h" 5 | #include "NetworkAccessManager.h" 6 | 7 | SetUrlBlacklist::SetUrlBlacklist(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 8 | } 9 | 10 | void SetUrlBlacklist::start() { 11 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager(); 12 | networkAccessManager->setUrlBlacklist(arguments()); 13 | emitFinished(true); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/JsonSerializer.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class JsonSerializer : public QObject { 5 | Q_OBJECT 6 | 7 | public: 8 | JsonSerializer(QObject *parent = 0); 9 | QByteArray serialize(const QVariant &object); 10 | 11 | private: 12 | void addVariant(const QVariant &object); 13 | void addString(const QString &string); 14 | void addArray(const QVariantList &list); 15 | void addMap(const QVariantMap &map); 16 | QByteArray sanitizeString(QString string); 17 | 18 | QByteArray m_buffer; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /src/SetCookie.cpp: -------------------------------------------------------------------------------- 1 | #include "SetCookie.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "NetworkCookieJar.h" 5 | #include 6 | 7 | SetCookie::SetCookie(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 8 | 9 | void SetCookie::start() 10 | { 11 | QList cookies = QNetworkCookie::parseCookies(arguments()[0].toAscii()); 12 | NetworkCookieJar *jar = manager()->cookieJar(); 13 | jar->overwriteCookies(cookies); 14 | emitFinished(true); 15 | } 16 | -------------------------------------------------------------------------------- /src/SetTimeout.cpp: -------------------------------------------------------------------------------- 1 | #include "SetTimeout.h" 2 | #include "WebPageManager.h" 3 | 4 | SetTimeout::SetTimeout(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 5 | } 6 | 7 | void SetTimeout::start() { 8 | QString timeoutString = arguments()[0]; 9 | bool ok; 10 | int timeout = timeoutString.toInt(&ok); 11 | 12 | if (ok) { 13 | manager()->setTimeout(timeout); 14 | emitFinished(true); 15 | } else { 16 | emitFinished(false, QString("Invalid value for timeout")); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/Execute.cpp: -------------------------------------------------------------------------------- 1 | #include "Execute.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Execute::Execute(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Execute::start() { 9 | QString script = arguments()[0] + QString("; 'success'"); 10 | QVariant result = page()->currentFrame()->evaluateJavaScript(script); 11 | if (result.isValid()) { 12 | emitFinished(true); 13 | } else { 14 | emitFinished(false, QString("Javascript failed to execute")); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/JavascriptInvocation.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class JavascriptInvocation : public QObject { 6 | Q_OBJECT 7 | Q_PROPERTY(QString functionName READ functionName) 8 | Q_PROPERTY(QStringList arguments READ arguments) 9 | 10 | public: 11 | JavascriptInvocation(const QString &functionName, const QStringList &arguments, QObject *parent = 0); 12 | QString &functionName(); 13 | QStringList &arguments(); 14 | 15 | private: 16 | QString m_functionName; 17 | QStringList m_arguments; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /src/SocketCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | SocketCommand::SocketCommand(WebPageManager *manager, QStringList &arguments, QObject *parent) : Command(parent) { 6 | m_manager = manager; 7 | m_arguments = arguments; 8 | } 9 | 10 | WebPage *SocketCommand::page() const { 11 | return m_manager->currentPage(); 12 | } 13 | 14 | const QStringList &SocketCommand::arguments() const { 15 | return m_arguments; 16 | } 17 | 18 | WebPageManager *SocketCommand::manager() const { 19 | return m_manager; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/Command.cpp: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | Command::Command(QObject *parent) : QObject(parent) { 4 | } 5 | 6 | QString Command::toString() const { 7 | return metaObject()->className(); 8 | } 9 | 10 | void Command::emitFinished(bool success) { 11 | emit finished(new Response(success, this)); 12 | } 13 | 14 | void Command::emitFinished(bool success, QString message) { 15 | emit finished(new Response(success, message, this)); 16 | } 17 | 18 | void Command::emitFinished(bool success, QByteArray message) { 19 | emit finished(new Response(success, message, this)); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/FrameFocus.h: -------------------------------------------------------------------------------- 1 | #include "SocketCommand.h" 2 | 3 | class QWebFrame; 4 | 5 | class FrameFocus : public SocketCommand { 6 | Q_OBJECT 7 | 8 | public: 9 | FrameFocus(WebPageManager *, QStringList &arguments, QObject *parent = 0); 10 | virtual void start(); 11 | 12 | private: 13 | void findFrames(); 14 | 15 | void focusParent(); 16 | 17 | void focusIndex(int index); 18 | bool isFrameAtIndex(int index); 19 | 20 | void focusId(QString id); 21 | 22 | void success(); 23 | void frameNotFound(); 24 | 25 | QList frames; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /src/GetCookies.cpp: -------------------------------------------------------------------------------- 1 | #include "GetCookies.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "NetworkCookieJar.h" 5 | 6 | GetCookies::GetCookies(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) 7 | { 8 | m_buffer = ""; 9 | } 10 | 11 | void GetCookies::start() 12 | { 13 | NetworkCookieJar *jar = manager()->cookieJar(); 14 | foreach (QNetworkCookie cookie, jar->getAllCookies()) { 15 | m_buffer.append(cookie.toRawForm()); 16 | m_buffer.append("\n"); 17 | } 18 | emitFinished(true, m_buffer); 19 | } 20 | -------------------------------------------------------------------------------- /src/Command.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_H 2 | #define COMMAND_H 3 | 4 | #include 5 | #include "Response.h" 6 | #include 7 | 8 | class Command : public QObject { 9 | Q_OBJECT 10 | 11 | public: 12 | Command(QObject *parent = 0); 13 | virtual void start() = 0; 14 | virtual QString toString() const; 15 | 16 | protected: 17 | void emitFinished(bool success); 18 | void emitFinished(bool success, QString message); 19 | void emitFinished(bool success, QByteArray message); 20 | 21 | signals: 22 | void finished(Response *response); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/Find.cpp: -------------------------------------------------------------------------------- 1 | #include "Find.h" 2 | #include "SocketCommand.h" 3 | #include "WebPage.h" 4 | #include "WebPageManager.h" 5 | 6 | Find::Find(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void Find::start() { 10 | QString message; 11 | QVariant result = page()->invokeWebKitServerFunction("find", arguments()); 12 | 13 | if (result.isValid()) { 14 | message = result.toString(); 15 | emitFinished(true, message); 16 | } else { 17 | emitFinished(false, QString("Invalid XPath expression")); 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/Response.h: -------------------------------------------------------------------------------- 1 | #ifndef RESPONSE_H 2 | #define RESPONSE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Response : public QObject { 9 | Q_OBJECT 10 | 11 | public: 12 | Response(bool success, QString message, QObject *parent); 13 | Response(bool success, QByteArray message, QObject *parent); 14 | Response(bool success, QObject *parent); 15 | bool isSuccess() const; 16 | QByteArray message() const; 17 | QString toString() const; 18 | 19 | private: 20 | bool m_success; 21 | QByteArray m_message; 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/Authenticate.cpp: -------------------------------------------------------------------------------- 1 | #include "Authenticate.h" 2 | #include "WebPage.h" 3 | #include "NetworkAccessManager.h" 4 | 5 | Authenticate::Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Authenticate::start() { 9 | QString username = arguments()[0]; 10 | QString password = arguments()[1]; 11 | 12 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager(); 13 | networkAccessManager->setUserName(username); 14 | networkAccessManager->setPassword(password); 15 | 16 | emitFinished(true); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "Source.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Source::Source(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Source::start() { 9 | QNetworkAccessManager* accessManager = page()->networkAccessManager(); 10 | QNetworkRequest request(page()->currentFrame()->url()); 11 | reply = accessManager->get(request); 12 | 13 | connect(reply, SIGNAL(finished()), this, SLOT(sourceLoaded())); 14 | } 15 | 16 | void Source::sourceLoaded() { 17 | emit finished(new Response(true, reply->readAll())); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/GetWindowHandles.cpp: -------------------------------------------------------------------------------- 1 | #include "GetWindowHandles.h" 2 | #include "WebPageManager.h" 3 | #include "CommandFactory.h" 4 | #include "WebPage.h" 5 | #include "JsonSerializer.h" 6 | #include 7 | 8 | GetWindowHandles::GetWindowHandles(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 9 | } 10 | 11 | void GetWindowHandles::start() { 12 | QVariantList handles; 13 | 14 | foreach(WebPage *page, manager()->pages()) 15 | handles << page->uuid(); 16 | 17 | JsonSerializer serializer; 18 | QByteArray json = serializer.serialize(handles); 19 | 20 | emitFinished(true, json); 21 | } 22 | -------------------------------------------------------------------------------- /src/SocketCommand.h: -------------------------------------------------------------------------------- 1 | #ifndef SOCKET_COMMAND_H 2 | #define SOCKET_COMMAND_H 3 | 4 | #include 5 | #include 6 | #include "Command.h" 7 | 8 | class WebPage; 9 | class WebPageManager; 10 | class Response; 11 | 12 | class SocketCommand : public Command { 13 | Q_OBJECT 14 | 15 | public: 16 | SocketCommand(WebPageManager *, QStringList &arguments, QObject *parent = 0); 17 | 18 | protected: 19 | WebPage *page() const; 20 | const QStringList &arguments() const; 21 | WebPageManager *manager() const; 22 | 23 | private: 24 | QStringList m_arguments; 25 | WebPageManager *m_manager; 26 | 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/Header.cpp: -------------------------------------------------------------------------------- 1 | #include "Header.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "NetworkAccessManager.h" 5 | 6 | Header::Header(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void Header::start() { 10 | QString key = arguments()[0]; 11 | QString value = arguments()[1]; 12 | NetworkAccessManager* networkAccessManager = page()->networkAccessManager(); 13 | if (key.toLower().replace("-", "_") == "user_agent") { 14 | page()->setUserAgent(value); 15 | } else { 16 | networkAccessManager->addHeader(key, value); 17 | } 18 | emitFinished(true); 19 | } 20 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # webkit-server 2 | 3 | A standalone version of the WebKit server in [capybara-webkit](https://github.com/thoughtbot/capybara-webkit). 4 | 5 | ## Dependencies 6 | 7 | webkit-server depends on a WebKit implementation from Qt, a cross-platform development toolkit. You'll need to download the Qt libraries to build the binary. See [Installing Qt](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit) for how to install it on your system. 8 | 9 | ## Building 10 | 11 | To generate the necessary files and build the binary: 12 | 13 | ./build.sh 14 | 15 | ## License 16 | 17 | webkit-server uses the MIT license. See LICENSE for more details. 18 | -------------------------------------------------------------------------------- /src/Server.cpp: -------------------------------------------------------------------------------- 1 | #include "Server.h" 2 | #include "Connection.h" 3 | #include "WebPageManager.h" 4 | 5 | #include 6 | 7 | Server::Server(QObject *parent) : QObject(parent) { 8 | m_tcp_server = new QTcpServer(this); 9 | } 10 | 11 | bool Server::start() { 12 | connect(m_tcp_server, SIGNAL(newConnection()), this, SLOT(handleConnection())); 13 | return m_tcp_server->listen(QHostAddress::LocalHost, 0); 14 | } 15 | 16 | quint16 Server::server_port() const { 17 | return m_tcp_server->serverPort(); 18 | } 19 | 20 | void Server::handleConnection() { 21 | QTcpSocket *socket = m_tcp_server->nextPendingConnection(); 22 | new Connection(socket, new WebPageManager(this), this); 23 | } 24 | -------------------------------------------------------------------------------- /src/Node.cpp: -------------------------------------------------------------------------------- 1 | #include "Node.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | 5 | Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 6 | } 7 | 8 | void Node::start() { 9 | QStringList functionArguments(arguments()); 10 | QString functionName = functionArguments.takeFirst(); 11 | QVariant result = page()->invokeWebKitServerFunction(functionName, functionArguments); 12 | QString attributeValue = result.toString(); 13 | emitFinished(true, attributeValue); 14 | } 15 | 16 | QString Node::toString() const { 17 | QStringList functionArguments(arguments()); 18 | return QString("Node.") + functionArguments.takeFirst(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Server.h" 2 | #include 3 | #include 4 | #ifdef Q_OS_UNIX 5 | #include 6 | #endif 7 | 8 | int main(int argc, char **argv) { 9 | #ifdef Q_OS_UNIX 10 | if (setpgid(0, 0) < 0) { 11 | std::cerr << "Unable to set new process group." << std::endl; 12 | return 1; 13 | } 14 | #endif 15 | 16 | QApplication app(argc, argv); 17 | app.setApplicationName("webkit_server"); 18 | 19 | Server server(0); 20 | 21 | if (server.start()) { 22 | std::cout << "webkit_server server started, listening on port: " << server.server_port() << std::endl; 23 | return app.exec(); 24 | } else { 25 | std::cerr << "Couldn't start webkit_server." << std::endl; 26 | return 1; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bin/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | 7 | CFBundlePackageType 8 | APPL 9 | CFBundleGetInfoString 10 | Created by Qt/QMake 11 | CFBundleSignature 12 | ???? 13 | CFBundleExecutable 14 | webkit_server 15 | CFBundleIdentifier 16 | com.yourcompany.webkit_server 17 | NOTE 18 | This file was generated by Qt/QMake. 19 | LSUIElement 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Response.cpp: -------------------------------------------------------------------------------- 1 | #include "Response.h" 2 | #include 3 | 4 | Response::Response(bool success, QString message, QObject *parent) : QObject(parent) { 5 | m_success = success; 6 | m_message = message.toUtf8(); 7 | } 8 | 9 | Response::Response(bool success, QByteArray message, QObject *parent) : QObject(parent) { 10 | m_success = success; 11 | m_message = message; 12 | } 13 | 14 | Response::Response(bool success, QObject *parent) : QObject(parent) { 15 | m_success = success; 16 | } 17 | 18 | bool Response::isSuccess() const { 19 | return m_success; 20 | } 21 | 22 | QByteArray Response::message() const { 23 | return m_message; 24 | } 25 | 26 | QString Response::toString() const { 27 | return QString(m_success ? "Success(" : "Failure(") + m_message + ")"; 28 | } 29 | -------------------------------------------------------------------------------- /src/SetProxy.cpp: -------------------------------------------------------------------------------- 1 | #include "SetProxy.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "NetworkAccessManager.h" 5 | #include 6 | 7 | SetProxy::SetProxy(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {} 8 | 9 | void SetProxy::start() 10 | { 11 | // default to empty proxy 12 | QNetworkProxy proxy; 13 | 14 | if (arguments().size() > 0) 15 | proxy = QNetworkProxy(QNetworkProxy::HttpProxy, 16 | arguments()[0], 17 | (quint16)(arguments()[1].toInt()), 18 | arguments()[2], 19 | arguments()[3]); 20 | 21 | page()->networkAccessManager()->setProxy(proxy); 22 | emitFinished(true); 23 | } 24 | -------------------------------------------------------------------------------- /src/UnsupportedContentHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "UnsupportedContentHandler.h" 2 | #include "WebPage.h" 3 | #include 4 | 5 | UnsupportedContentHandler::UnsupportedContentHandler(WebPage *page, QNetworkReply *reply, QObject *parent) : QObject(parent) { 6 | m_page = page; 7 | m_reply = reply; 8 | } 9 | 10 | void UnsupportedContentHandler::renderNonHtmlContent() { 11 | QByteArray text = m_reply->readAll(); 12 | m_page->mainFrame()->setContent(text, QString("text/plain"), m_reply->url()); 13 | m_page->unsupportedContentFinishedReply(m_reply); 14 | this->deleteLater(); 15 | } 16 | 17 | void UnsupportedContentHandler::waitForReplyToFinish() { 18 | connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished())); 19 | } 20 | 21 | void UnsupportedContentHandler::replyFinished() { 22 | renderNonHtmlContent(); 23 | } 24 | -------------------------------------------------------------------------------- /src/CommandParser.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class QIODevice; 5 | class CommandFactory; 6 | class Command; 7 | 8 | class CommandParser : public QObject { 9 | Q_OBJECT 10 | 11 | public: 12 | CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent = 0); 13 | 14 | public slots: 15 | void checkNext(); 16 | 17 | signals: 18 | void commandReady(Command *command); 19 | 20 | private: 21 | void readLine(); 22 | void readDataBlock(); 23 | void processNext(const char *line); 24 | void processArgument(const char *data); 25 | void reset(); 26 | QIODevice *m_device; 27 | QString m_commandName; 28 | QStringList m_arguments; 29 | int m_argumentsExpected; 30 | int m_expectingDataSize; 31 | CommandFactory *m_commandFactory; 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /src/WindowFocus.cpp: -------------------------------------------------------------------------------- 1 | #include "WindowFocus.h" 2 | #include "SocketCommand.h" 3 | #include "WebPage.h" 4 | #include "CommandFactory.h" 5 | #include "WebPageManager.h" 6 | 7 | WindowFocus::WindowFocus(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 8 | } 9 | 10 | void WindowFocus::start() { 11 | focusWindow(arguments()[0]); 12 | } 13 | 14 | void WindowFocus::windowNotFound() { 15 | emitFinished(false, QString("Unable to locate window. ")); 16 | } 17 | 18 | void WindowFocus::success(WebPage *page) { 19 | page->setFocus(); 20 | emitFinished(true); 21 | } 22 | 23 | void WindowFocus::focusWindow(QString selector) { 24 | foreach(WebPage *page, manager()->pages()) { 25 | if (page->matchesWindowSelector(selector)) { 26 | success(page); 27 | return; 28 | } 29 | } 30 | 31 | windowNotFound(); 32 | } 33 | -------------------------------------------------------------------------------- /src/NoOpReply.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "NoOpReply.h" 3 | 4 | NoOpReply::NoOpReply(QNetworkRequest &request, QObject *parent) : QNetworkReply(parent) { 5 | open(ReadOnly | Unbuffered); 6 | setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200); 7 | setHeader(QNetworkRequest::ContentLengthHeader, QVariant(0)); 8 | setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QString("text/plain"))); 9 | setUrl(request.url()); 10 | 11 | QTimer::singleShot( 0, this, SIGNAL(readyRead()) ); 12 | QTimer::singleShot( 0, this, SIGNAL(finished()) ); 13 | } 14 | 15 | void NoOpReply::abort() { 16 | // NO-OP 17 | } 18 | 19 | qint64 NoOpReply::bytesAvailable() const { 20 | return 0; 21 | } 22 | 23 | bool NoOpReply::isSequential() const { 24 | return true; 25 | } 26 | 27 | qint64 NoOpReply::readData(char *data, qint64 maxSize) { 28 | Q_UNUSED(data); 29 | Q_UNUSED(maxSize); 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/Connection.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class QTcpSocket; 5 | class WebPage; 6 | class Command; 7 | class Response; 8 | class CommandParser; 9 | class CommandFactory; 10 | class PageLoadingCommand; 11 | class WebPageManager; 12 | 13 | class Connection : public QObject { 14 | Q_OBJECT 15 | 16 | public: 17 | Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent = 0); 18 | 19 | public slots: 20 | void commandReady(Command *command); 21 | void finishCommand(Response *response); 22 | void pendingLoadFinished(bool success); 23 | 24 | private: 25 | void startCommand(Command *); 26 | void writeResponse(Response *response); 27 | void writePageLoadFailure(); 28 | 29 | QTcpSocket *m_socket; 30 | WebPageManager *m_manager; 31 | CommandParser *m_commandParser; 32 | CommandFactory *m_commandFactory; 33 | bool m_pageSuccess; 34 | WebPage *currentPage(); 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /src/TimeoutCommand.h: -------------------------------------------------------------------------------- 1 | #include "Command.h" 2 | #include 3 | #include 4 | 5 | class Response; 6 | class WebPageManager; 7 | class QTimer; 8 | 9 | /* Decorates a command with a timeout. 10 | * 11 | * If the timeout, using a QTimer is reached before 12 | * the command is finished, the load page load will 13 | * be stopped and failure response will be issued. 14 | * 15 | */ 16 | class TimeoutCommand : public Command { 17 | Q_OBJECT 18 | 19 | public: 20 | TimeoutCommand(Command *command, WebPageManager *page, QObject *parent = 0); 21 | virtual void start(); 22 | 23 | public slots: 24 | void commandTimeout(); 25 | void commandFinished(Response *response); 26 | void pageLoadingFromCommand(); 27 | void pendingLoadFinished(bool); 28 | 29 | protected: 30 | void startCommand(); 31 | void startTimeout(); 32 | 33 | private: 34 | WebPageManager *m_manager; 35 | QTimer *m_timer; 36 | Command *m_command; 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /src/PageLoadingCommand.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Command.h" 4 | 5 | class Response; 6 | class WebPageManager; 7 | 8 | /* 9 | * Decorates a Command by deferring the finished() signal until any pending 10 | * page loads are complete. 11 | * 12 | * If a Command starts a page load, no signal will be emitted until the page 13 | * load is finished. 14 | * 15 | * If a pending page load fails, the command's response will be discarded and a 16 | * failure response will be emitted instead. 17 | */ 18 | class PageLoadingCommand : public Command { 19 | Q_OBJECT 20 | 21 | public: 22 | PageLoadingCommand(Command *command, WebPageManager *page, QObject *parent = 0); 23 | virtual void start(); 24 | 25 | public slots: 26 | void pageLoadingFromCommand(); 27 | void pendingLoadFinished(bool success); 28 | void commandFinished(Response *response); 29 | 30 | private: 31 | WebPageManager *m_manager; 32 | Command *m_command; 33 | Response *m_pendingResponse; 34 | bool m_pageSuccess; 35 | bool m_pageLoadingFromCommand; 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2013 thoughtbot, inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/find_command.h: -------------------------------------------------------------------------------- 1 | #define CHECK_COMMAND(expectedName) \ 2 | if (strcmp(#expectedName, name) == 0) { \ 3 | return new expectedName(m_manager, arguments, this); \ 4 | } 5 | 6 | CHECK_COMMAND(Visit) 7 | CHECK_COMMAND(Find) 8 | CHECK_COMMAND(Reset) 9 | CHECK_COMMAND(Node) 10 | CHECK_COMMAND(Evaluate) 11 | CHECK_COMMAND(Execute) 12 | CHECK_COMMAND(FrameFocus) 13 | CHECK_COMMAND(Header) 14 | CHECK_COMMAND(Render) 15 | CHECK_COMMAND(Body) 16 | CHECK_COMMAND(Status) 17 | CHECK_COMMAND(Headers) 18 | CHECK_COMMAND(SetCookie) 19 | CHECK_COMMAND(ClearCookies) 20 | CHECK_COMMAND(GetCookies) 21 | CHECK_COMMAND(SetProxy) 22 | CHECK_COMMAND(ConsoleMessages) 23 | CHECK_COMMAND(CurrentUrl) 24 | CHECK_COMMAND(ResizeWindow) 25 | CHECK_COMMAND(IgnoreSslErrors) 26 | CHECK_COMMAND(SetSkipImageLoading) 27 | CHECK_COMMAND(WindowFocus) 28 | CHECK_COMMAND(GetWindowHandles) 29 | CHECK_COMMAND(GetWindowHandle) 30 | CHECK_COMMAND(Authenticate) 31 | CHECK_COMMAND(EnableLogging) 32 | CHECK_COMMAND(SetConfirmAction) 33 | CHECK_COMMAND(SetPromptAction) 34 | CHECK_COMMAND(SetPromptText) 35 | CHECK_COMMAND(ClearPromptText) 36 | CHECK_COMMAND(JavascriptAlertMessages) 37 | CHECK_COMMAND(JavascriptConfirmMessages) 38 | CHECK_COMMAND(JavascriptPromptMessages) 39 | CHECK_COMMAND(GetTimeout) 40 | CHECK_COMMAND(SetTimeout) 41 | CHECK_COMMAND(SetUrlBlacklist) 42 | 43 | -------------------------------------------------------------------------------- /src/CommandFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "CommandFactory.h" 2 | #include "NullCommand.h" 3 | #include "SocketCommand.h" 4 | #include "Visit.h" 5 | #include "Find.h" 6 | #include "Reset.h" 7 | #include "Node.h" 8 | #include "Evaluate.h" 9 | #include "Execute.h" 10 | #include "FrameFocus.h" 11 | #include "Header.h" 12 | #include "Render.h" 13 | #include "Body.h" 14 | #include "Status.h" 15 | #include "Headers.h" 16 | #include "SetCookie.h" 17 | #include "ClearCookies.h" 18 | #include "GetCookies.h" 19 | #include "SetProxy.h" 20 | #include "ConsoleMessages.h" 21 | #include "CurrentUrl.h" 22 | #include "SetTimeout.h" 23 | #include "GetTimeout.h" 24 | #include "ResizeWindow.h" 25 | #include "IgnoreSslErrors.h" 26 | #include "SetSkipImageLoading.h" 27 | #include "WindowFocus.h" 28 | #include "GetWindowHandles.h" 29 | #include "GetWindowHandle.h" 30 | #include "WebPageManager.h" 31 | #include "Authenticate.h" 32 | #include "EnableLogging.h" 33 | #include "SetConfirmAction.h" 34 | #include "SetPromptAction.h" 35 | #include "SetPromptText.h" 36 | #include "ClearPromptText.h" 37 | #include "JavascriptAlertMessages.h" 38 | #include "JavascriptConfirmMessages.h" 39 | #include "JavascriptPromptMessages.h" 40 | #include "SetUrlBlacklist.h" 41 | 42 | CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) { 43 | m_manager = manager; 44 | } 45 | 46 | Command *CommandFactory::createCommand(const char *name, QStringList &arguments) { 47 | #include "find_command.h" 48 | return new NullCommand(QString(name)); 49 | } 50 | -------------------------------------------------------------------------------- /src/NetworkAccessManager.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | class NetworkAccessManager : public QNetworkAccessManager { 7 | 8 | Q_OBJECT 9 | 10 | struct NetworkResponse { 11 | int statusCode; 12 | QList headers; 13 | NetworkResponse() : statusCode(0) { } 14 | }; 15 | 16 | public: 17 | NetworkAccessManager(QObject *parent = 0); 18 | void addHeader(QString key, QString value); 19 | void resetHeaders(); 20 | void setUserName(const QString &userName); 21 | void setPassword(const QString &password); 22 | int statusFor(QUrl url); 23 | const QList &headersFor(QUrl url); 24 | void setUrlBlacklist(QStringList urlBlacklist); 25 | 26 | protected: 27 | QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData); 28 | QString m_userName; 29 | QString m_password; 30 | QList m_urlBlacklist; 31 | 32 | 33 | private: 34 | QHash m_headers; 35 | QHash m_responses; 36 | bool isBlacklisted(QUrl url); 37 | QHash m_redirectMappings; 38 | 39 | private slots: 40 | void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator); 41 | void finished(QNetworkReply *); 42 | 43 | signals: 44 | void requestCreated(QByteArray &url, QNetworkReply *reply); 45 | }; 46 | -------------------------------------------------------------------------------- /src/WebPageManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _WEBPAGEMANAGER_H 2 | #define _WEBPAGEMANAGER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class WebPage; 11 | class NetworkCookieJar; 12 | 13 | class WebPageManager : public QObject { 14 | Q_OBJECT 15 | 16 | public: 17 | WebPageManager(QObject *parent = 0); 18 | void append(WebPage *value); 19 | QList pages() const; 20 | void setCurrentPage(WebPage *); 21 | WebPage *currentPage() const; 22 | WebPage *createPage(QObject *parent); 23 | void setIgnoreSslErrors(bool); 24 | bool ignoreSslErrors(); 25 | void setTimeout(int); 26 | int getTimeout(); 27 | void reset(); 28 | NetworkCookieJar *cookieJar(); 29 | bool isLoading() const; 30 | QDebug logger() const; 31 | void enableLogging(); 32 | void replyFinished(QNetworkReply *reply); 33 | 34 | public slots: 35 | void emitLoadStarted(); 36 | void setPageStatus(bool); 37 | void requestCreated(QByteArray &url, QNetworkReply *reply); 38 | void handleReplyFinished(); 39 | 40 | signals: 41 | void pageFinished(bool); 42 | void loadStarted(); 43 | 44 | private: 45 | void emitPageFinished(); 46 | static void handleDebugMessage(QtMsgType type, const char *message); 47 | 48 | QList m_pages; 49 | WebPage *m_currentPage; 50 | bool m_ignoreSslErrors; 51 | NetworkCookieJar *m_cookieJar; 52 | QSet m_started; 53 | bool m_success; 54 | bool m_loggingEnabled; 55 | QFile *m_ignoredOutput; 56 | int m_timeout; 57 | }; 58 | 59 | #endif // _WEBPAGEMANAGER_H 60 | 61 | -------------------------------------------------------------------------------- /src/FrameFocus.cpp: -------------------------------------------------------------------------------- 1 | #include "FrameFocus.h" 2 | #include "SocketCommand.h" 3 | #include "WebPage.h" 4 | #include "WebPageManager.h" 5 | 6 | FrameFocus::FrameFocus(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) { 7 | } 8 | 9 | void FrameFocus::start() { 10 | findFrames(); 11 | switch(arguments().length()) { 12 | case 1: 13 | focusId(arguments()[0]); 14 | break; 15 | case 2: 16 | focusIndex(arguments()[1].toInt()); 17 | break; 18 | default: 19 | focusParent(); 20 | } 21 | } 22 | 23 | void FrameFocus::findFrames() { 24 | frames = page()->currentFrame()->childFrames(); 25 | } 26 | 27 | void FrameFocus::focusIndex(int index) { 28 | if (isFrameAtIndex(index)) { 29 | frames[index]->setFocus(); 30 | success(); 31 | } else { 32 | frameNotFound(); 33 | } 34 | } 35 | 36 | bool FrameFocus::isFrameAtIndex(int index) { 37 | return 0 <= index && index < frames.length(); 38 | } 39 | 40 | void FrameFocus::focusId(QString name) { 41 | for (int i = 0; i < frames.length(); i++) { 42 | if (frames[i]->frameName().compare(name) == 0) { 43 | frames[i]->setFocus(); 44 | success(); 45 | return; 46 | } 47 | } 48 | 49 | frameNotFound(); 50 | } 51 | 52 | void FrameFocus::focusParent() { 53 | if (page()->currentFrame()->parentFrame() == 0) { 54 | emitFinished(false, QString("Already at parent frame.")); 55 | } else { 56 | page()->currentFrame()->parentFrame()->setFocus(); 57 | success(); 58 | } 59 | } 60 | 61 | void FrameFocus::frameNotFound() { 62 | emitFinished(false, QString("Unable to locate frame. ")); 63 | } 64 | 65 | void FrameFocus::success() { 66 | emitFinished(true); 67 | } 68 | -------------------------------------------------------------------------------- /src/PageLoadingCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "PageLoadingCommand.h" 2 | #include "SocketCommand.h" 3 | #include "WebPage.h" 4 | #include "WebPageManager.h" 5 | 6 | PageLoadingCommand::PageLoadingCommand(Command *command, WebPageManager *manager, QObject *parent) : Command(parent) { 7 | m_manager = manager; 8 | m_command = command; 9 | m_pageLoadingFromCommand = false; 10 | m_pageSuccess = true; 11 | m_pendingResponse = NULL; 12 | m_command->setParent(this); 13 | } 14 | 15 | void PageLoadingCommand::start() { 16 | m_manager->logger() << "Started" << m_command->toString(); 17 | connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *))); 18 | connect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 19 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); 20 | m_command->start(); 21 | }; 22 | 23 | void PageLoadingCommand::pendingLoadFinished(bool success) { 24 | m_pageSuccess = success; 25 | if (m_pageLoadingFromCommand) { 26 | m_pageLoadingFromCommand = false; 27 | if (m_pendingResponse) { 28 | m_manager->logger() << "Page load from command finished"; 29 | if (m_pageSuccess) { 30 | emit finished(m_pendingResponse); 31 | } else { 32 | QString message = m_manager->currentPage()->failureString(); 33 | emitFinished(false, message); 34 | } 35 | } 36 | } 37 | } 38 | 39 | void PageLoadingCommand::pageLoadingFromCommand() { 40 | m_manager->logger() << m_command->toString() << "started page load"; 41 | m_pageLoadingFromCommand = true; 42 | } 43 | 44 | void PageLoadingCommand::commandFinished(Response *response) { 45 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 46 | m_manager->logger() << "Finished" << m_command->toString() << "with response" << response->toString(); 47 | 48 | if (m_pageLoadingFromCommand) 49 | m_pendingResponse = response; 50 | else 51 | emit finished(response); 52 | } 53 | -------------------------------------------------------------------------------- /src/CommandParser.cpp: -------------------------------------------------------------------------------- 1 | #include "CommandParser.h" 2 | #include "CommandFactory.h" 3 | #include "SocketCommand.h" 4 | 5 | #include 6 | 7 | CommandParser::CommandParser(QIODevice *device, CommandFactory *commandFactory, QObject *parent) : 8 | QObject(parent) { 9 | m_device = device; 10 | m_expectingDataSize = -1; 11 | m_commandFactory = commandFactory; 12 | connect(m_device, SIGNAL(readyRead()), this, SLOT(checkNext())); 13 | } 14 | 15 | void CommandParser::checkNext() { 16 | if (m_expectingDataSize == -1) { 17 | if (m_device->canReadLine()) { 18 | readLine(); 19 | checkNext(); 20 | } 21 | } else { 22 | if (m_device->bytesAvailable() >= m_expectingDataSize) { 23 | readDataBlock(); 24 | checkNext(); 25 | } 26 | } 27 | } 28 | 29 | void CommandParser::readLine() { 30 | char buffer[128]; 31 | qint64 lineLength = m_device->readLine(buffer, 128); 32 | if (lineLength != -1) { 33 | buffer[lineLength - 1] = 0; 34 | processNext(buffer); 35 | } 36 | } 37 | 38 | void CommandParser::readDataBlock() { 39 | char *buffer = new char[m_expectingDataSize + 1]; 40 | m_device->read(buffer, m_expectingDataSize); 41 | buffer[m_expectingDataSize] = 0; 42 | processNext(buffer); 43 | m_expectingDataSize = -1; 44 | delete[] buffer; 45 | } 46 | 47 | void CommandParser::processNext(const char *data) { 48 | if (m_commandName.isNull()) { 49 | m_commandName = data; 50 | m_argumentsExpected = -1; 51 | } else { 52 | processArgument(data); 53 | } 54 | } 55 | 56 | void CommandParser::processArgument(const char *data) { 57 | if (m_argumentsExpected == -1) { 58 | m_argumentsExpected = QString(data).toInt(); 59 | } else if (m_expectingDataSize == -1) { 60 | m_expectingDataSize = QString(data).toInt(); 61 | } else { 62 | m_arguments.append(QString::fromUtf8(data)); 63 | } 64 | 65 | if (m_arguments.length() == m_argumentsExpected) { 66 | Command *command = m_commandFactory->createCommand(m_commandName.toAscii().constData(), m_arguments); 67 | emit commandReady(command); 68 | reset(); 69 | } 70 | } 71 | 72 | void CommandParser::reset() { 73 | m_commandName = QString(); 74 | m_arguments.clear(); 75 | m_argumentsExpected = -1; 76 | } 77 | -------------------------------------------------------------------------------- /src/Connection.cpp: -------------------------------------------------------------------------------- 1 | #include "Connection.h" 2 | #include "WebPage.h" 3 | #include "WebPageManager.h" 4 | #include "CommandParser.h" 5 | #include "CommandFactory.h" 6 | #include "PageLoadingCommand.h" 7 | #include "TimeoutCommand.h" 8 | #include "SocketCommand.h" 9 | 10 | #include 11 | 12 | Connection::Connection(QTcpSocket *socket, WebPageManager *manager, QObject *parent) : 13 | QObject(parent) { 14 | m_socket = socket; 15 | m_manager = manager; 16 | m_commandFactory = new CommandFactory(m_manager, this); 17 | m_commandParser = new CommandParser(socket, m_commandFactory, this); 18 | m_pageSuccess = true; 19 | connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext())); 20 | connect(m_commandParser, SIGNAL(commandReady(Command *)), this, SLOT(commandReady(Command *))); 21 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); 22 | } 23 | 24 | void Connection::commandReady(Command *command) { 25 | m_manager->logger() << "Received" << command->toString(); 26 | startCommand(command); 27 | } 28 | 29 | void Connection::startCommand(Command *command) { 30 | if (m_pageSuccess) { 31 | command = new TimeoutCommand(new PageLoadingCommand(command, m_manager, this), m_manager, this); 32 | connect(command, SIGNAL(finished(Response *)), this, SLOT(finishCommand(Response *))); 33 | command->start(); 34 | } else { 35 | writePageLoadFailure(); 36 | } 37 | } 38 | 39 | void Connection::pendingLoadFinished(bool success) { 40 | m_pageSuccess = m_pageSuccess && success; 41 | } 42 | 43 | void Connection::writePageLoadFailure() { 44 | m_pageSuccess = true; 45 | QString message = currentPage()->failureString(); 46 | Response *response = new Response(false, message, this); 47 | writeResponse(response); 48 | delete response; 49 | } 50 | 51 | void Connection::finishCommand(Response *response) { 52 | m_pageSuccess = true; 53 | writeResponse(response); 54 | sender()->deleteLater(); 55 | } 56 | 57 | void Connection::writeResponse(Response *response) { 58 | if (response->isSuccess()) 59 | m_socket->write("ok\n"); 60 | else 61 | m_socket->write("failure\n"); 62 | 63 | m_manager->logger() << "Wrote response" << response->isSuccess() << response->message(); 64 | 65 | QByteArray messageUtf8 = response->message(); 66 | QString messageLength = QString::number(messageUtf8.size()) + "\n"; 67 | m_socket->write(messageLength.toAscii()); 68 | m_socket->write(messageUtf8); 69 | } 70 | 71 | WebPage *Connection::currentPage() { 72 | return m_manager->currentPage(); 73 | } 74 | -------------------------------------------------------------------------------- /src/TimeoutCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "TimeoutCommand.h" 2 | #include "Command.h" 3 | #include "WebPageManager.h" 4 | #include "WebPage.h" 5 | #include 6 | #include 7 | 8 | TimeoutCommand::TimeoutCommand(Command *command, WebPageManager *manager, QObject *parent) : Command(parent) { 9 | m_command = command; 10 | m_manager = manager; 11 | m_timer = new QTimer(this); 12 | m_timer->setSingleShot(true); 13 | m_command->setParent(this); 14 | connect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout())); 15 | connect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 16 | } 17 | 18 | void TimeoutCommand::start() { 19 | QApplication::processEvents(); 20 | if (m_manager->isLoading()) { 21 | m_manager->logger() << this->toString() << "waiting for load to finish"; 22 | connect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); 23 | startTimeout(); 24 | } else { 25 | startCommand(); 26 | } 27 | } 28 | 29 | void TimeoutCommand::startCommand() { 30 | connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *))); 31 | m_command->start(); 32 | } 33 | 34 | void TimeoutCommand::startTimeout() { 35 | int timeout = m_manager->getTimeout(); 36 | if (timeout > 0) { 37 | m_timer->start(timeout * 1000); 38 | } 39 | } 40 | 41 | void TimeoutCommand::pendingLoadFinished(bool success) { 42 | disconnect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); 43 | if (success) { 44 | startCommand(); 45 | } else { 46 | disconnect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout())); 47 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 48 | emitFinished(false, m_manager->currentPage()->failureString()); 49 | } 50 | } 51 | 52 | void TimeoutCommand::pageLoadingFromCommand() { 53 | startTimeout(); 54 | } 55 | 56 | void TimeoutCommand::commandTimeout() { 57 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 58 | disconnect(m_manager, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool))); 59 | disconnect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *))); 60 | m_manager->currentPage()->triggerAction(QWebPage::Stop); 61 | emit finished(new Response(false, QString("timeout"), this)); 62 | } 63 | 64 | void TimeoutCommand::commandFinished(Response *response) { 65 | disconnect(m_timer, SIGNAL(timeout()), this, SLOT(commandTimeout())); 66 | disconnect(m_manager, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand())); 67 | emit finished(response); 68 | } 69 | 70 | -------------------------------------------------------------------------------- /src/webkit_server.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = webkit_server 3 | DESTDIR = . 4 | HEADERS = \ 5 | EnableLogging.h \ 6 | Authenticate.h \ 7 | SetConfirmAction.h \ 8 | SetPromptAction.h \ 9 | SetPromptText.h \ 10 | ClearPromptText.h \ 11 | JavascriptAlertMessages.h \ 12 | JavascriptConfirmMessages.h \ 13 | JavascriptPromptMessages.h \ 14 | IgnoreSslErrors.h \ 15 | ResizeWindow.h \ 16 | CurrentUrl.h \ 17 | ConsoleMessages.h \ 18 | WebPage.h \ 19 | Server.h \ 20 | Connection.h \ 21 | Command.h \ 22 | SocketCommand.h \ 23 | Visit.h \ 24 | Find.h \ 25 | Reset.h \ 26 | Node.h \ 27 | JavascriptInvocation.h \ 28 | Evaluate.h \ 29 | Execute.h \ 30 | FrameFocus.h \ 31 | Response.h \ 32 | NetworkAccessManager.h \ 33 | NetworkCookieJar.h \ 34 | Header.h \ 35 | Render.h \ 36 | Body.h \ 37 | Status.h \ 38 | Headers.h \ 39 | UnsupportedContentHandler.h \ 40 | SetCookie.h \ 41 | ClearCookies.h \ 42 | GetCookies.h \ 43 | CommandParser.h \ 44 | CommandFactory.h \ 45 | SetProxy.h \ 46 | NullCommand.h \ 47 | PageLoadingCommand.h \ 48 | SetSkipImageLoading.h \ 49 | WebPageManager.h \ 50 | WindowFocus.h \ 51 | GetWindowHandles.h \ 52 | GetWindowHandle.h \ 53 | GetTimeout.h \ 54 | SetTimeout.h \ 55 | TimeoutCommand.h \ 56 | SetUrlBlacklist.h \ 57 | NoOpReply.h \ 58 | JsonSerializer.h 59 | 60 | SOURCES = \ 61 | EnableLogging.cpp \ 62 | Authenticate.cpp \ 63 | SetConfirmAction.cpp \ 64 | SetPromptAction.cpp \ 65 | SetPromptText.cpp \ 66 | ClearPromptText.cpp \ 67 | JavascriptAlertMessages.cpp \ 68 | JavascriptConfirmMessages.cpp \ 69 | JavascriptPromptMessages.cpp \ 70 | IgnoreSslErrors.cpp \ 71 | ResizeWindow.cpp \ 72 | CurrentUrl.cpp \ 73 | ConsoleMessages.cpp \ 74 | main.cpp \ 75 | WebPage.cpp \ 76 | Server.cpp \ 77 | Connection.cpp \ 78 | Command.cpp \ 79 | SocketCommand.cpp \ 80 | Visit.cpp \ 81 | Find.cpp \ 82 | Reset.cpp \ 83 | Node.cpp \ 84 | JavascriptInvocation.cpp \ 85 | Evaluate.cpp \ 86 | Execute.cpp \ 87 | FrameFocus.cpp \ 88 | Response.cpp \ 89 | NetworkAccessManager.cpp \ 90 | NetworkCookieJar.cpp \ 91 | Header.cpp \ 92 | Render.cpp \ 93 | body.cpp \ 94 | Status.cpp \ 95 | Headers.cpp \ 96 | UnsupportedContentHandler.cpp \ 97 | SetCookie.cpp \ 98 | ClearCookies.cpp \ 99 | GetCookies.cpp \ 100 | CommandParser.cpp \ 101 | CommandFactory.cpp \ 102 | SetProxy.cpp \ 103 | NullCommand.cpp \ 104 | PageLoadingCommand.cpp \ 105 | SetTimeout.cpp \ 106 | GetTimeout.cpp \ 107 | SetSkipImageLoading.cpp \ 108 | WebPageManager.cpp \ 109 | WindowFocus.cpp \ 110 | GetWindowHandles.cpp \ 111 | GetWindowHandle.cpp \ 112 | TimeoutCommand.cpp \ 113 | SetUrlBlacklist.cpp \ 114 | NoOpReply.cpp \ 115 | JsonSerializer.cpp 116 | 117 | RESOURCES = webkit_server.qrc 118 | QT += network webkit 119 | CONFIG += console 120 | CONFIG -= app_bundle 121 | 122 | -------------------------------------------------------------------------------- /src/JsonSerializer.cpp: -------------------------------------------------------------------------------- 1 | #include "JsonSerializer.h" 2 | #include 3 | 4 | JsonSerializer::JsonSerializer(QObject *parent) : QObject(parent) { 5 | } 6 | 7 | QByteArray JsonSerializer::serialize(const QVariant &object) { 8 | addVariant(object); 9 | return m_buffer; 10 | } 11 | 12 | void JsonSerializer::addVariant(const QVariant &object) { 13 | if (object.isValid()) { 14 | switch(object.type()) { 15 | case QMetaType::QString: 16 | { 17 | QString string = object.toString(); 18 | addString(string); 19 | } 20 | break; 21 | case QMetaType::QVariantList: 22 | { 23 | QVariantList list = object.toList(); 24 | addArray(list); 25 | } 26 | break; 27 | case QMetaType::Double: 28 | if (std::isinf(object.toDouble())) 29 | m_buffer.append("null"); 30 | else 31 | m_buffer.append(object.toString()); 32 | break; 33 | case QMetaType::QVariantMap: 34 | { 35 | QVariantMap map = object.toMap(); 36 | addMap(map); 37 | break; 38 | } 39 | case QMetaType::Bool: 40 | { 41 | m_buffer.append(object.toString()); 42 | break; 43 | } 44 | case QMetaType::Int: 45 | { 46 | m_buffer.append(object.toString()); 47 | break; 48 | } 49 | default: 50 | m_buffer.append("null"); 51 | } 52 | } else { 53 | m_buffer.append("null"); 54 | } 55 | } 56 | 57 | void JsonSerializer::addString(const QString &string) { 58 | m_buffer.append("\""); 59 | m_buffer.append(sanitizeString(string)); 60 | m_buffer.append("\""); 61 | } 62 | 63 | void JsonSerializer::addArray(const QVariantList &list) { 64 | m_buffer.append("["); 65 | for (int i = 0; i < list.length(); i++) { 66 | if (i > 0) 67 | m_buffer.append(","); 68 | addVariant(list[i]); 69 | } 70 | m_buffer.append("]"); 71 | } 72 | 73 | void JsonSerializer::addMap(const QVariantMap &map) { 74 | m_buffer.append("{"); 75 | QMapIterator iterator(map); 76 | while (iterator.hasNext()) { 77 | iterator.next(); 78 | QString key = iterator.key(); 79 | QVariant value = iterator.value(); 80 | addString(key); 81 | m_buffer.append(":"); 82 | addVariant(value); 83 | if (iterator.hasNext()) 84 | m_buffer.append(","); 85 | } 86 | m_buffer.append("}"); 87 | } 88 | 89 | QByteArray JsonSerializer::sanitizeString(QString str) { 90 | str.replace("\\", "\\\\"); 91 | str.replace("\"", "\\\""); 92 | str.replace("\b", "\\b"); 93 | str.replace("\f", "\\f"); 94 | str.replace("\n", "\\n"); 95 | str.replace("\r", "\\r"); 96 | str.replace("\t", "\\t"); 97 | 98 | QByteArray result; 99 | const ushort* unicode = str.utf16(); 100 | unsigned int i = 0; 101 | 102 | while (unicode[i]) { 103 | if (unicode[i] > 31 && unicode[i] < 128) { 104 | result.append(unicode[i]); 105 | } 106 | else { 107 | QString hexCode = QString::number(unicode[i], 16).rightJustified(4, '0'); 108 | 109 | result.append("\\u").append(hexCode); 110 | } 111 | ++i; 112 | } 113 | 114 | return result; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /src/WebPage.h: -------------------------------------------------------------------------------- 1 | #ifndef _WEBPAGE_H 2 | #define _WEBPAGE_H 3 | #include 4 | 5 | class WebPageManager; 6 | class NetworkAccessManager; 7 | 8 | class WebPage : public QWebPage { 9 | Q_OBJECT 10 | 11 | public: 12 | WebPage(WebPageManager *, QObject *parent = 0); 13 | QVariant invokeWebKitServerFunction(const char *name, const QStringList &arguments); 14 | QVariant invokeWebKitServerFunction(QString &name, const QStringList &arguments); 15 | QString failureString(); 16 | QString userAgentForUrl(const QUrl &url ) const; 17 | void setUserAgent(QString userAgent); 18 | void setConfirmAction(QString action); 19 | void setPromptAction(QString action); 20 | void setPromptText(QString action); 21 | int getLastStatus(); 22 | void setCustomNetworkAccessManager(); 23 | bool render(const QString &fileName, const QSize &minimumSize); 24 | virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0); 25 | void setSkipImageLoading(bool skip); 26 | QVariantList consoleMessages(); 27 | QVariantList alertMessages(); 28 | QVariantList confirmMessages(); 29 | QVariantList promptMessages(); 30 | void resetWindowSize(); 31 | QWebPage *createWindow(WebWindowType type); 32 | QString uuid(); 33 | QString getWindowName(); 34 | bool matchesWindowSelector(QString); 35 | void setFocus(); 36 | NetworkAccessManager *networkAccessManager(); 37 | bool unsupportedContentLoaded(); 38 | void unsupportedContentFinishedReply(QNetworkReply *reply); 39 | 40 | public slots: 41 | bool shouldInterruptJavaScript(); 42 | void injectJavascriptHelpers(); 43 | void loadStarted(); 44 | void loadFinished(bool); 45 | bool isLoading() const; 46 | const QList &pageHeaders(); 47 | void frameCreated(QWebFrame *); 48 | void handleSslErrorsForReply(QNetworkReply *reply, const QList &); 49 | void handleUnsupportedContent(QNetworkReply *reply); 50 | 51 | signals: 52 | void pageFinished(bool); 53 | void requestCreated(QByteArray &url, QNetworkReply *reply); 54 | void replyFinished(QNetworkReply *reply); 55 | 56 | protected: 57 | virtual void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID); 58 | virtual void javaScriptAlert(QWebFrame *frame, const QString &message); 59 | virtual bool javaScriptConfirm(QWebFrame *frame, const QString &message); 60 | virtual bool javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result); 61 | virtual QString chooseFile(QWebFrame * parentFrame, const QString &suggestedFile); 62 | virtual bool supportsExtension(Extension extension) const; 63 | 64 | private: 65 | QString m_javascriptString; 66 | QString m_userAgent; 67 | bool m_loading; 68 | bool m_failed; 69 | QStringList getAttachedFileNames(); 70 | void loadJavascript(); 71 | void setUserStylesheet(); 72 | bool m_confirm; 73 | bool m_prompt; 74 | QVariantList m_consoleMessages; 75 | QVariantList m_alertMessages; 76 | QVariantList m_confirmMessages; 77 | QString m_prompt_text; 78 | QVariantList m_promptMessages; 79 | QString m_uuid; 80 | WebPageManager *m_manager; 81 | QString m_errorPageMessage; 82 | bool m_unsupportedContentLoaded; 83 | }; 84 | 85 | #endif //_WEBPAGE_H 86 | 87 | -------------------------------------------------------------------------------- /src/NetworkCookieJar.cpp: -------------------------------------------------------------------------------- 1 | #include "NetworkCookieJar.h" 2 | #include "QtCore/qdatetime.h" 3 | 4 | NetworkCookieJar::NetworkCookieJar(QObject *parent) 5 | : QNetworkCookieJar(parent) 6 | { } 7 | 8 | QList NetworkCookieJar::getAllCookies() const 9 | { 10 | return allCookies(); 11 | } 12 | 13 | void NetworkCookieJar::clearCookies() 14 | { 15 | setAllCookies(QList()); 16 | } 17 | 18 | static inline bool isParentDomain(QString domain, QString reference) 19 | { 20 | if (!reference.startsWith(QLatin1Char('.'))) 21 | return domain == reference; 22 | 23 | return domain.endsWith(reference) || domain == reference.mid(1); 24 | } 25 | 26 | void NetworkCookieJar::overwriteCookies(const QList& cookieList) 27 | { 28 | /* this function is basically a copy-and-paste of the original 29 | QNetworkCookieJar::setCookiesFromUrl with the domain and 30 | path validations removed */ 31 | 32 | QString defaultPath(QLatin1Char('/')); 33 | QDateTime now = QDateTime::currentDateTime(); 34 | QList newCookies = allCookies(); 35 | 36 | foreach (QNetworkCookie cookie, cookieList) { 37 | bool isDeletion = (!cookie.isSessionCookie() && 38 | cookie.expirationDate() < now); 39 | 40 | // validate the cookie & set the defaults if unset 41 | if (cookie.path().isEmpty()) 42 | cookie.setPath(defaultPath); 43 | 44 | // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815 45 | // else if (!isParentPath(pathAndFileName, cookie.path())) { 46 | // continue; // not accepted 47 | // } 48 | 49 | if (cookie.domain().isEmpty()) { 50 | continue; 51 | } else { 52 | // Ensure the domain starts with a dot if its field was not empty 53 | // in the HTTP header. There are some servers that forget the 54 | // leading dot and this is actually forbidden according to RFC 2109, 55 | // but all browsers accept it anyway so we do that as well. 56 | if (!cookie.domain().startsWith(QLatin1Char('.'))) 57 | cookie.setDomain(QLatin1Char('.') + cookie.domain()); 58 | 59 | QString domain = cookie.domain(); 60 | 61 | // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2 62 | // redundant; the "leading dot" rule has been relaxed anyway, see above 63 | // we remove the leading dot for this check 64 | /* 65 | if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1))) 66 | continue; // not accepted 67 | */ 68 | } 69 | 70 | for (int i = 0; i < newCookies.size(); ++i) { 71 | // does this cookie already exist? 72 | const QNetworkCookie ¤t = newCookies.at(i); 73 | if (cookie.name() == current.name() && 74 | cookie.domain() == current.domain() && 75 | cookie.path() == current.path()) { 76 | // found a match 77 | newCookies.removeAt(i); 78 | break; 79 | } 80 | } 81 | 82 | // did not find a match 83 | if (!isDeletion) { 84 | int countForDomain = 0; 85 | for (int i = newCookies.size() - 1; i >= 0; --i) { 86 | // Start from the end and delete the oldest cookies to keep a maximum count of 50. 87 | const QNetworkCookie ¤t = newCookies.at(i); 88 | if (isParentDomain(cookie.domain(), current.domain()) 89 | || isParentDomain(current.domain(), cookie.domain())) { 90 | if (countForDomain >= 49) 91 | newCookies.removeAt(i); 92 | else 93 | ++countForDomain; 94 | } 95 | } 96 | 97 | newCookies += cookie; 98 | } 99 | } 100 | setAllCookies(newCookies); 101 | } 102 | -------------------------------------------------------------------------------- /src/WebPageManager.cpp: -------------------------------------------------------------------------------- 1 | #include "WebPageManager.h" 2 | #include "WebPage.h" 3 | #include "NetworkCookieJar.h" 4 | 5 | WebPageManager::WebPageManager(QObject *parent) : QObject(parent) { 6 | m_ignoreSslErrors = false; 7 | m_cookieJar = new NetworkCookieJar(this); 8 | m_success = true; 9 | m_loggingEnabled = false; 10 | m_ignoredOutput = new QFile(this); 11 | m_timeout = -1; 12 | createPage(this)->setFocus(); 13 | } 14 | 15 | void WebPageManager::append(WebPage *value) { 16 | m_pages.append(value); 17 | } 18 | 19 | QList WebPageManager::pages() const { 20 | return m_pages; 21 | } 22 | 23 | void WebPageManager::setCurrentPage(WebPage *page) { 24 | m_currentPage = page; 25 | } 26 | 27 | WebPage *WebPageManager::currentPage() const { 28 | return m_currentPage; 29 | } 30 | 31 | WebPage *WebPageManager::createPage(QObject *parent) { 32 | WebPage *page = new WebPage(this, parent); 33 | connect(page, SIGNAL(loadStarted()), 34 | this, SLOT(emitLoadStarted())); 35 | connect(page, SIGNAL(pageFinished(bool)), 36 | this, SLOT(setPageStatus(bool))); 37 | connect(page, SIGNAL(requestCreated(QByteArray &, QNetworkReply *)), 38 | this, SLOT(requestCreated(QByteArray &, QNetworkReply *))); 39 | append(page); 40 | return page; 41 | } 42 | 43 | void WebPageManager::emitLoadStarted() { 44 | if (m_started.empty()) { 45 | logger() << "Load started"; 46 | emit loadStarted(); 47 | } 48 | m_started += qobject_cast(sender()); 49 | } 50 | 51 | void WebPageManager::requestCreated(QByteArray &url, QNetworkReply *reply) { 52 | logger() << "Started request to" << url; 53 | if (reply->isFinished()) 54 | replyFinished(reply); 55 | else { 56 | connect(reply, SIGNAL(finished()), SLOT(handleReplyFinished())); 57 | } 58 | } 59 | 60 | void WebPageManager::handleReplyFinished() { 61 | QNetworkReply *reply = qobject_cast(sender()); 62 | disconnect(reply, SIGNAL(finished()), this, SLOT(handleReplyFinished())); 63 | replyFinished(reply); 64 | } 65 | 66 | void WebPageManager::replyFinished(QNetworkReply *reply) { 67 | int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 68 | logger() << "Received" << status << "from" << reply->url().toString(); 69 | } 70 | 71 | void WebPageManager::setPageStatus(bool success) { 72 | logger() << "Page finished with" << success; 73 | m_started.remove(qobject_cast(sender())); 74 | m_success = success && m_success; 75 | if (m_started.empty()) { 76 | emitPageFinished(); 77 | } 78 | } 79 | 80 | void WebPageManager::emitPageFinished() { 81 | logger() << "Load finished"; 82 | emit pageFinished(m_success); 83 | m_success = true; 84 | } 85 | 86 | void WebPageManager::setIgnoreSslErrors(bool value) { 87 | m_ignoreSslErrors = value; 88 | } 89 | 90 | bool WebPageManager::ignoreSslErrors() { 91 | return m_ignoreSslErrors; 92 | } 93 | 94 | int WebPageManager::getTimeout() { 95 | return m_timeout; 96 | } 97 | 98 | void WebPageManager::setTimeout(int timeout) { 99 | m_timeout = timeout; 100 | } 101 | 102 | void WebPageManager::reset() { 103 | m_timeout = -1; 104 | m_cookieJar->clearCookies(); 105 | m_pages.first()->deleteLater(); 106 | m_pages.clear(); 107 | createPage(this)->setFocus(); 108 | } 109 | 110 | NetworkCookieJar *WebPageManager::cookieJar() { 111 | return m_cookieJar; 112 | } 113 | 114 | bool WebPageManager::isLoading() const { 115 | foreach(WebPage *page, pages()) { 116 | if (page->isLoading()) { 117 | return true; 118 | } 119 | } 120 | return false; 121 | } 122 | 123 | QDebug WebPageManager::logger() const { 124 | if (m_loggingEnabled) 125 | return qDebug(); 126 | else 127 | return QDebug(m_ignoredOutput); 128 | } 129 | 130 | void WebPageManager::enableLogging() { 131 | m_loggingEnabled = true; 132 | } 133 | -------------------------------------------------------------------------------- /src/NetworkAccessManager.cpp: -------------------------------------------------------------------------------- 1 | #include "NetworkAccessManager.h" 2 | #include "WebPage.h" 3 | #include 4 | #include 5 | #include "NoOpReply.h" 6 | 7 | NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) { 8 | connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*))); 9 | connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(finished(QNetworkReply *))); 10 | } 11 | 12 | QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) { 13 | QNetworkRequest new_request(request); 14 | QByteArray url = new_request.url().toEncoded(); 15 | if (this->isBlacklisted(new_request.url())) { 16 | return new NoOpReply(new_request, this); 17 | } else { 18 | if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) { 19 | new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant()); 20 | } 21 | QHashIterator item(m_headers); 22 | while (item.hasNext()) { 23 | item.next(); 24 | new_request.setRawHeader(item.key().toAscii(), item.value().toAscii()); 25 | } 26 | QNetworkReply *reply = QNetworkAccessManager::createRequest(operation, new_request, outgoingData); 27 | emit requestCreated(url, reply); 28 | return reply; 29 | } 30 | }; 31 | 32 | void NetworkAccessManager::finished(QNetworkReply *reply) { 33 | QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); 34 | if (redirectUrl.isValid()) 35 | m_redirectMappings[reply->url().resolved(redirectUrl)] = reply->url(); 36 | else { 37 | QUrl requestedUrl = reply->url(); 38 | while (m_redirectMappings.contains(requestedUrl)) 39 | requestedUrl = m_redirectMappings.take(requestedUrl); 40 | NetworkResponse response; 41 | response.statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 42 | response.headers = reply->rawHeaderPairs(); 43 | m_responses[requestedUrl] = response; 44 | } 45 | } 46 | 47 | void NetworkAccessManager::addHeader(QString key, QString value) { 48 | m_headers.insert(key, value); 49 | } 50 | 51 | void NetworkAccessManager::resetHeaders() { 52 | m_headers.clear(); 53 | } 54 | 55 | void NetworkAccessManager::setUserName(const QString &userName) { 56 | m_userName = userName; 57 | } 58 | 59 | void NetworkAccessManager::setPassword(const QString &password) { 60 | m_password = password; 61 | } 62 | 63 | void NetworkAccessManager::provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) { 64 | Q_UNUSED(reply); 65 | if (m_userName != authenticator->user()) 66 | authenticator->setUser(m_userName); 67 | if (m_password != authenticator->password()) 68 | authenticator->setPassword(m_password); 69 | } 70 | 71 | int NetworkAccessManager::statusFor(QUrl url) { 72 | return m_responses[url].statusCode; 73 | } 74 | 75 | const QList &NetworkAccessManager::headersFor(QUrl url) { 76 | return m_responses[url].headers; 77 | } 78 | 79 | void NetworkAccessManager::setUrlBlacklist(QStringList urlBlacklist) { 80 | m_urlBlacklist.clear(); 81 | 82 | QStringListIterator iter(urlBlacklist); 83 | while (iter.hasNext()) { 84 | m_urlBlacklist << QUrl(iter.next()); 85 | } 86 | }; 87 | 88 | bool NetworkAccessManager::isBlacklisted(QUrl url) { 89 | QListIterator iter(m_urlBlacklist); 90 | 91 | while (iter.hasNext()) { 92 | QUrl blacklisted = iter.next(); 93 | 94 | if (blacklisted == url) { 95 | return true; 96 | } else if (blacklisted.path().isEmpty() && blacklisted.isParentOf(url)) { 97 | return true; 98 | } 99 | } 100 | 101 | return false; 102 | }; 103 | 104 | -------------------------------------------------------------------------------- /src/webkit_server.js: -------------------------------------------------------------------------------- 1 | window.WebKitServer = { 2 | nodes : {}, 3 | nextIndex : 0, 4 | attachedFiles : [], 5 | 6 | invoke: function() { 7 | return this[WebKitServerInvocation.functionName].apply(this, WebKitServerInvocation.arguments); 8 | }, 9 | 10 | find: function(selector) { 11 | return this.findRelativeTo(document, selector); 12 | }, 13 | 14 | currentUrl: function() { 15 | return window.location.toString(); 16 | }, 17 | 18 | findWithin: function(index, selector) { 19 | return this.findRelativeTo(this.nodes[index], selector); 20 | }, 21 | 22 | findRelativeTo: function(parent, selector) { 23 | var results = [], 24 | elements = parent.querySelectorAll(selector); 25 | 26 | for (var index = 0, length = elements.length; index < length; index++) { 27 | this.nodes[results.push(++this.nextIndex)] = elements[index]; 28 | } 29 | 30 | return results.join(","); 31 | }, 32 | 33 | isAttached: function(index) { 34 | return document.evaluate("ancestor-or-self::html", this.nodes[index], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue != null; 35 | }, 36 | 37 | text: function(index) { 38 | var node = this.nodes[index], 39 | type = (node.type || node.tagName).toLowerCase(); 40 | 41 | if (type == "textarea") { 42 | return node.innerHTML; 43 | } else { 44 | return node.innerText; 45 | } 46 | }, 47 | 48 | attribute: function(index, name) { 49 | var node = this.nodes[index]; 50 | 51 | switch(name) { 52 | case "checked": return node.checked; 53 | case "disabled": return node.disabled; 54 | case "multiple": return node.multiple; 55 | default: return node.getAttribute(name); 56 | } 57 | }, 58 | 59 | hasAttribtue: function(index, name) { 60 | return this.nodes[index].hasAttribute(name); 61 | }, 62 | 63 | tagName: function(index) { 64 | return this.nodes[index].tagName.toLowerCase(); 65 | }, 66 | 67 | submit: function(index) { 68 | return this.nodes[index].submit(); 69 | }, 70 | 71 | mousedown: function(index) { 72 | var mousedownEvent = document.createEvent("MouseEvents"); 73 | mousedownEvent.initMouseEvent("mousedown", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 74 | this.nodes[index].dispatchEvent(mousedownEvent); 75 | }, 76 | 77 | mouseup: function(index) { 78 | var mouseupEvent = document.createEvent("MouseEvents"); 79 | mouseupEvent.initMouseEvent("mouseup", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 80 | this.nodes[index].dispatchEvent(mouseupEvent); 81 | }, 82 | 83 | click: function(index) { 84 | this.mousedown(index); 85 | this.focus(index); 86 | this.mouseup(index); 87 | 88 | var clickEvent = document.createEvent("MouseEvents"); 89 | clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 90 | this.nodes[index].dispatchEvent(clickEvent); 91 | }, 92 | 93 | trigger: function(index, eventName) { 94 | var eventObject = document.createEvent("HTMLEvents"); 95 | eventObject.initEvent(eventName, true, true); 96 | this.nodes[index].dispatchEvent(eventObject); 97 | }, 98 | 99 | keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) { 100 | var eventObject = document.createEvent("Events"); 101 | eventObject.initEvent("keypress", true, true); 102 | eventObject.window = window; 103 | eventObject.altKey = altKey; 104 | eventObject.ctrlKey = ctrlKey; 105 | eventObject.shiftKey = shiftKey; 106 | eventObject.metaKey = metaKey; 107 | eventObject.keyCode = keyCode; 108 | eventObject.charCode = charCode; 109 | eventObject.which = keyCode; 110 | this.nodes[index].dispatchEvent(eventObject); 111 | }, 112 | 113 | keyupdown: function(index, eventName, keyCode) { 114 | var eventObject = document.createEvent("HTMLEvents"); 115 | eventObject.initEvent(eventName, true, true); 116 | eventObject.keyCode = keyCode; 117 | eventObject.which = keyCode; 118 | eventObject.charCode = 0; 119 | this.nodes[index].dispatchEvent(eventObject); 120 | }, 121 | 122 | visible: function(index) { 123 | var element = this.nodes[index]; 124 | 125 | while (element) { 126 | var style = element.ownerDocument.defaultView.getComputedStyle(element, null); 127 | 128 | if (style.getPropertyValue("display") == "none" || style.getPropertyValue("visibility") == "hidden") { 129 | return false; 130 | } 131 | 132 | element = element.parentElement; 133 | } 134 | 135 | return true; 136 | }, 137 | 138 | selected: function(index) { 139 | return this.nodes[index].selected; 140 | }, 141 | 142 | value: function(index) { 143 | return this.nodes[index].value; 144 | }, 145 | 146 | getInnerHTML: function(index) { 147 | return this.nodes[index].innerHTML; 148 | }, 149 | 150 | setInnerHTML: function(index, value) { 151 | this.nodes[index].innerHTML = value; 152 | return true; 153 | }, 154 | 155 | characterToKeyCode: function(character) { 156 | var code = character.toUpperCase().charCodeAt(0); 157 | var specialKeys = { 158 | 96: 192, //` 159 | 45: 189, //- 160 | 61: 187, //= 161 | 91: 219, //[ 162 | 93: 221, //] 163 | 92: 220, //\ 164 | 59: 186, //; 165 | 39: 222, //' 166 | 44: 188, //, 167 | 46: 190, //. 168 | 47: 191, /// 169 | 127: 46, //delete 170 | 126: 192, //~ 171 | 33: 49, //! 172 | 64: 50, //@ 173 | 35: 51, //# 174 | 36: 52, //$ 175 | 37: 53, //% 176 | 94: 54, //^ 177 | 38: 55, //& 178 | 42: 56, //* 179 | 40: 57, //( 180 | 41: 48, //) 181 | 95: 189, //_ 182 | 43: 187, //+ 183 | 123: 219, //{ 184 | 125: 221, //} 185 | 124: 220, //| 186 | 58: 186, //: 187 | 34: 222, //" 188 | 60: 188, //< 189 | 62: 190, //> 190 | 63: 191 //? 191 | }; 192 | 193 | if (specialKeys[code]) { 194 | code = specialKeys[code]; 195 | } 196 | 197 | return code; 198 | }, 199 | 200 | set: function(index, value) { 201 | var node = this.nodes[index], 202 | type = (node.type || node.tagName).toLowerCase(), 203 | textTypes = ["email", "number", "password", "search", "tel", "text", "textarea", "url"]; 204 | 205 | if (textTypes.indexOf(type) !== -1) { 206 | this.focus(index); 207 | 208 | node.value = ""; 209 | 210 | var length = value.length, 211 | maxLength = this.attribute(index, "maxlength"); 212 | 213 | if (maxLength && value.length > maxLength) { 214 | length = maxLength; 215 | } 216 | 217 | for (var offset = 0; offset < length; offset++) { 218 | node.value += value[offset]; 219 | 220 | var keyCode = this.characterToKeyCode(value[strindex]); 221 | this.keyupdown(index, "keydown", keyCode); 222 | this.keypress(index, false, false, false, false, value.charCodeAt(strindex), value.charCodeAt(strindex)); 223 | this.keyupdown(index, "keyup", keyCode); 224 | this.trigger(index, "input"); 225 | } 226 | 227 | this.trigger(index, "change"); 228 | } else if (type === "checkbox" || type === "radio") { 229 | if (node.checked != (value === "true")) { 230 | this.click(index); 231 | } 232 | } else if (type === "file") { 233 | this.attachedFiles = Array.prototype.slice.call(arguments, 1); 234 | this.click(index); 235 | } else { 236 | node.value = value; 237 | } 238 | }, 239 | 240 | focus: function(index) { 241 | this.index[index].focus(); 242 | }, 243 | 244 | selectOption: function(index) { 245 | this.nodes[index].selected = true; 246 | this.trigger(index, "change"); 247 | }, 248 | 249 | unselectOption: function(index) { 250 | this.nodes[index].selected = false; 251 | this.trigger(index, "change"); 252 | }, 253 | 254 | centerPosition: function(element) { 255 | this.reflow(element); 256 | 257 | var rect = element.getBoundingClientRect(), 258 | position = { 259 | x: rect.width / 2, 260 | y: rect.height / 2 261 | }; 262 | 263 | do { 264 | position.x += element.offsetLeft; 265 | position.y += element.offsetTop; 266 | } while ((element = element.offsetParent)); 267 | 268 | position.x = Math.floor(position.x); 269 | position.y = Math.floor(position.y); 270 | 271 | return position; 272 | }, 273 | 274 | reflow: function(element, force) { 275 | if (force || element.offsetWidth === 0) { 276 | var property, 277 | oldStyle = {}, 278 | newStyle = { 279 | display : "block", 280 | position : "absolute", 281 | visibility : "hidden", 282 | }; 283 | 284 | for (property in newStyle) { 285 | oldStyle[property] = element.style[property]; 286 | element.style[property] = newStyle[property]; 287 | } 288 | 289 | element.offsetWidth; 290 | element.offsetHeight; 291 | 292 | for (property in oldStyle) { 293 | element.style[property] = oldStyle[property]; 294 | } 295 | } 296 | }, 297 | 298 | dragTo: function(index, targetIndex) { 299 | var element = this.nodes[index], 300 | target = this.nodes[targetIndex], 301 | position = this.centerPosition(element), 302 | options = { 303 | clientX: position.x, 304 | clientY: position.y 305 | }, 306 | mouseTrigger = function(eventName, options) { 307 | var eventObject = document.createEvent("MouseEvents"); 308 | eventObject.initMouseEvent(eventName, true, true, window, 0, 0, 0, options.clientX || 0, options.clientY || 0, false, false, false, false, 0, null); 309 | element.dispatchEvent(eventObject); 310 | }; 311 | 312 | mouseTrigger("mousedown", options); 313 | 314 | options.clientX += 1; 315 | options.clientY += 1; 316 | 317 | mouseTrigger("mousemove", options); 318 | 319 | position = this.centerPosition(target); 320 | options = { 321 | clientX: position.x, 322 | clientY: position.y 323 | }; 324 | 325 | mouseTrigger("mousemove", options); 326 | mouseTrigger("mouseup", options); 327 | }, 328 | 329 | equals: function(index, targetIndex) { 330 | return this.nodes[index] === this.nodes[targetIndex]; 331 | } 332 | }; 333 | -------------------------------------------------------------------------------- /src/WebPage.cpp: -------------------------------------------------------------------------------- 1 | #include "WebPage.h" 2 | #include "WebPageManager.h" 3 | #include "JavascriptInvocation.h" 4 | #include "NetworkAccessManager.h" 5 | #include "NetworkCookieJar.h" 6 | #include "UnsupportedContentHandler.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) { 13 | m_loading = false; 14 | m_failed = false; 15 | m_manager = manager; 16 | m_uuid = QUuid::createUuid().toString(); 17 | m_unsupportedContentLoaded = false; 18 | 19 | setForwardUnsupportedContent(true); 20 | loadJavascript(); 21 | setUserStylesheet(); 22 | 23 | m_confirm = true; 24 | m_prompt = false; 25 | m_prompt_text = QString(); 26 | this->setCustomNetworkAccessManager(); 27 | 28 | connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted())); 29 | connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); 30 | connect(this, SIGNAL(frameCreated(QWebFrame *)), 31 | this, SLOT(frameCreated(QWebFrame *))); 32 | connect(this, SIGNAL(unsupportedContent(QNetworkReply*)), 33 | this, SLOT(handleUnsupportedContent(QNetworkReply*))); 34 | resetWindowSize(); 35 | 36 | settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true); 37 | } 38 | 39 | void WebPage::resetWindowSize() { 40 | this->setViewportSize(QSize(1680, 1050)); 41 | this->settings()->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true); 42 | } 43 | 44 | void WebPage::setCustomNetworkAccessManager() { 45 | NetworkAccessManager *manager = new NetworkAccessManager(this); 46 | manager->setCookieJar(m_manager->cookieJar()); 47 | this->setNetworkAccessManager(manager); 48 | connect(manager, SIGNAL(sslErrors(QNetworkReply *, QList)), 49 | this, SLOT(handleSslErrorsForReply(QNetworkReply *, QList))); 50 | connect(manager, SIGNAL(requestCreated(QByteArray &, QNetworkReply *)), 51 | SIGNAL(requestCreated(QByteArray &, QNetworkReply *))); 52 | } 53 | 54 | void WebPage::unsupportedContentFinishedReply(QNetworkReply *reply) { 55 | m_unsupportedContentLoaded = true; 56 | m_manager->replyFinished(reply); 57 | } 58 | 59 | void WebPage::loadJavascript() { 60 | QResource javascript(":/webkit_server.js"); 61 | if (javascript.isCompressed()) { 62 | QByteArray uncompressedBytes(qUncompress(javascript.data(), javascript.size())); 63 | m_javascriptString = QString(uncompressedBytes); 64 | } else { 65 | char * javascriptString = new char[javascript.size() + 1]; 66 | strcpy(javascriptString, (const char *)javascript.data()); 67 | javascriptString[javascript.size()] = 0; 68 | m_javascriptString = javascriptString; 69 | } 70 | } 71 | 72 | void WebPage::setUserStylesheet() { 73 | QString data = QString("*, :before, :after { font-family: 'Arial' ! important; }").toUtf8().toBase64(); 74 | QUrl url = QUrl(QString("data:text/css;charset=utf-8;base64,") + data); 75 | settings()->setUserStyleSheetUrl(url); 76 | } 77 | 78 | QString WebPage::userAgentForUrl(const QUrl &url ) const { 79 | if (!m_userAgent.isEmpty()) { 80 | return m_userAgent; 81 | } else { 82 | return QWebPage::userAgentForUrl(url); 83 | } 84 | } 85 | 86 | QVariantList WebPage::consoleMessages() { 87 | return m_consoleMessages; 88 | } 89 | 90 | QVariantList WebPage::alertMessages() { 91 | return m_alertMessages; 92 | } 93 | 94 | QVariantList WebPage::confirmMessages() { 95 | return m_confirmMessages; 96 | } 97 | 98 | QVariantList WebPage::promptMessages() { 99 | return m_promptMessages; 100 | } 101 | 102 | void WebPage::setUserAgent(QString userAgent) { 103 | m_userAgent = userAgent; 104 | } 105 | 106 | void WebPage::frameCreated(QWebFrame * frame) { 107 | connect(frame, SIGNAL(javaScriptWindowObjectCleared()), 108 | this, SLOT(injectJavascriptHelpers())); 109 | } 110 | 111 | void WebPage::injectJavascriptHelpers() { 112 | QWebFrame* frame = qobject_cast(QObject::sender()); 113 | frame->evaluateJavaScript(m_javascriptString); 114 | } 115 | 116 | bool WebPage::shouldInterruptJavaScript() { 117 | return false; 118 | } 119 | 120 | QVariant WebPage::invokeWebKitServerFunction(const char *name, const QStringList &arguments) { 121 | QString qname(name); 122 | QString objectName("WebKitServerInvocation"); 123 | JavascriptInvocation invocation(qname, arguments); 124 | currentFrame()->addToJavaScriptWindowObject(objectName, &invocation); 125 | QString javascript = QString("WebKitServer.invoke()"); 126 | return currentFrame()->evaluateJavaScript(javascript); 127 | } 128 | 129 | QVariant WebPage::invokeWebKitServerFunction(QString &name, const QStringList &arguments) { 130 | return invokeWebKitServerFunction(name.toAscii().data(), arguments); 131 | } 132 | 133 | void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) { 134 | QVariantMap m; 135 | m["message"] = message; 136 | QString fullMessage = QString(message); 137 | if (!sourceID.isEmpty()) { 138 | fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage; 139 | m["source"] = sourceID; 140 | m["line_number"] = lineNumber; 141 | } 142 | m_consoleMessages.append(m); 143 | m_manager->logger() << qPrintable(fullMessage); 144 | } 145 | 146 | void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) { 147 | Q_UNUSED(frame); 148 | m_alertMessages.append(message); 149 | m_manager->logger() << "ALERT:" << qPrintable(message); 150 | } 151 | 152 | bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) { 153 | Q_UNUSED(frame); 154 | m_confirmMessages.append(message); 155 | return m_confirm; 156 | } 157 | 158 | bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result) { 159 | Q_UNUSED(frame) 160 | m_promptMessages.append(message); 161 | if (m_prompt) { 162 | if (m_prompt_text.isNull()) { 163 | *result = defaultValue; 164 | } else { 165 | *result = m_prompt_text; 166 | } 167 | } 168 | return m_prompt; 169 | } 170 | 171 | void WebPage::loadStarted() { 172 | m_loading = true; 173 | m_errorPageMessage = QString(); 174 | m_unsupportedContentLoaded = false; 175 | } 176 | 177 | void WebPage::loadFinished(bool success) { 178 | Q_UNUSED(success); 179 | m_loading = false; 180 | emit pageFinished(!m_failed); 181 | m_failed = false; 182 | } 183 | 184 | bool WebPage::isLoading() const { 185 | return m_loading; 186 | } 187 | 188 | QString WebPage::failureString() { 189 | QString message = QString("Unable to load URL: ") + currentFrame()->requestedUrl().toString(); 190 | if (m_errorPageMessage.isEmpty()) 191 | return message; 192 | else 193 | return message + m_errorPageMessage; 194 | } 195 | 196 | bool WebPage::render(const QString &fileName, const QSize &minimumSize) { 197 | QFileInfo fileInfo(fileName); 198 | QDir dir; 199 | dir.mkpath(fileInfo.absolutePath()); 200 | 201 | QSize viewportSize = this->viewportSize(); 202 | this->setViewportSize(minimumSize); 203 | QSize pageSize = this->mainFrame()->contentsSize(); 204 | if (pageSize.isEmpty()) { 205 | return false; 206 | } 207 | 208 | QImage buffer(pageSize, QImage::Format_ARGB32); 209 | buffer.fill(qRgba(255, 255, 255, 0)); 210 | 211 | QPainter p(&buffer); 212 | p.setRenderHint( QPainter::Antialiasing, true); 213 | p.setRenderHint( QPainter::TextAntialiasing, true); 214 | p.setRenderHint( QPainter::SmoothPixmapTransform, true); 215 | 216 | this->setViewportSize(pageSize); 217 | this->mainFrame()->render(&p); 218 | p.end(); 219 | this->setViewportSize(viewportSize); 220 | 221 | return buffer.save(fileName); 222 | } 223 | 224 | QString WebPage::chooseFile(QWebFrame *parentFrame, const QString &suggestedFile) { 225 | Q_UNUSED(parentFrame); 226 | Q_UNUSED(suggestedFile); 227 | 228 | return getAttachedFileNames().first(); 229 | } 230 | 231 | bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) { 232 | if (extension == ChooseMultipleFilesExtension) { 233 | static_cast(output)->fileNames = getAttachedFileNames(); 234 | return true; 235 | } 236 | else if (extension == QWebPage::ErrorPageExtension) { 237 | ErrorPageExtensionOption *errorOption = (ErrorPageExtensionOption*) option; 238 | m_errorPageMessage = " because of error loading " + errorOption->url.toString() + ": " + errorOption->errorString; 239 | m_failed = true; 240 | return false; 241 | } 242 | return false; 243 | } 244 | 245 | QStringList WebPage::getAttachedFileNames() { 246 | return currentFrame()->evaluateJavaScript(QString("WebKitServer.attachedFiles")).toStringList(); 247 | } 248 | 249 | void WebPage::handleSslErrorsForReply(QNetworkReply *reply, const QList &errors) { 250 | if (m_manager->ignoreSslErrors()) 251 | reply->ignoreSslErrors(errors); 252 | } 253 | 254 | void WebPage::setSkipImageLoading(bool skip) { 255 | settings()->setAttribute(QWebSettings::AutoLoadImages, !skip); 256 | } 257 | 258 | int WebPage::getLastStatus() { 259 | return networkAccessManager()->statusFor(currentFrame()->requestedUrl()); 260 | } 261 | 262 | const QList &WebPage::pageHeaders() { 263 | return networkAccessManager()->headersFor(currentFrame()->requestedUrl()); 264 | } 265 | 266 | NetworkAccessManager *WebPage::networkAccessManager() { 267 | return qobject_cast(QWebPage::networkAccessManager()); 268 | } 269 | 270 | void WebPage::handleUnsupportedContent(QNetworkReply *reply) { 271 | QVariant contentMimeType = reply->header(QNetworkRequest::ContentTypeHeader); 272 | if(!contentMimeType.isNull()) { 273 | triggerAction(QWebPage::Stop); 274 | UnsupportedContentHandler *handler = new UnsupportedContentHandler(this, reply); 275 | if (reply->isFinished()) 276 | handler->renderNonHtmlContent(); 277 | else 278 | handler->waitForReplyToFinish(); 279 | } 280 | } 281 | 282 | bool WebPage::unsupportedContentLoaded() { 283 | return m_unsupportedContentLoaded; 284 | } 285 | 286 | bool WebPage::supportsExtension(Extension extension) const { 287 | if (extension == ErrorPageExtension) 288 | return true; 289 | else if (extension == ChooseMultipleFilesExtension) 290 | return true; 291 | else 292 | return false; 293 | } 294 | 295 | QWebPage *WebPage::createWindow(WebWindowType type) { 296 | Q_UNUSED(type); 297 | return m_manager->createPage(this); 298 | } 299 | 300 | QString WebPage::uuid() { 301 | return m_uuid; 302 | } 303 | 304 | QString WebPage::getWindowName() { 305 | QVariant windowName = mainFrame()->evaluateJavaScript("window.name"); 306 | 307 | if (windowName.isValid()) 308 | return windowName.toString(); 309 | else 310 | return ""; 311 | } 312 | 313 | bool WebPage::matchesWindowSelector(QString selector) { 314 | return (selector == getWindowName() || 315 | selector == mainFrame()->title() || 316 | selector == mainFrame()->url().toString() || 317 | selector == uuid()); 318 | } 319 | 320 | void WebPage::setFocus() { 321 | m_manager->setCurrentPage(this); 322 | } 323 | 324 | void WebPage::setConfirmAction(QString action) { 325 | m_confirm = (action == "Yes"); 326 | } 327 | 328 | void WebPage::setPromptAction(QString action) { 329 | m_prompt = (action == "Yes"); 330 | } 331 | 332 | void WebPage::setPromptText(QString text) { 333 | m_prompt_text = text; 334 | } 335 | 336 | --------------------------------------------------------------------------------