diff options
| author | Javier <dev.git@javispedro.com> | 2014-12-01 03:12:00 +0100 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2014-12-01 03:14:10 +0100 |
| commit | be139d8ff95160782b424134a025b30c82083e28 (patch) | |
| tree | 70cda209c44a657db3dd436afacaabe53b192838 | |
| parent | 1e3794c476caf5c41360c36cc13c8425ec0dd26c (diff) | |
add stub xmlhttprequest and allow showConfig event
| -rw-r--r-- | daemon/jskitmanager.cpp | 14 | ||||
| -rw-r--r-- | daemon/jskitmanager.h | 3 | ||||
| -rw-r--r-- | daemon/jskitobjects.cpp | 114 | ||||
| -rw-r--r-- | daemon/jskitobjects.h | 56 | ||||
| -rw-r--r-- | daemon/manager.cpp | 8 |
5 files changed, 188 insertions, 7 deletions
diff --git a/daemon/jskitmanager.cpp b/daemon/jskitmanager.cpp index f8ec34a..6023a9a 100644 --- a/daemon/jskitmanager.cpp +++ b/daemon/jskitmanager.cpp @@ -19,6 +19,18 @@ JSKitManager::~JSKitManager() } } +QJSEngine * JSKitManager::engine() +{ + return _engine; +} + +void JSKitManager::showConfiguration() +{ + if (_engine) { + _jspebble->invokeCallbacks("showConfiguration"); + } +} + void JSKitManager::handleAppStarted(const QUuid &uuid) { AppInfo info = _apps->info(uuid); @@ -83,6 +95,8 @@ void JSKitManager::startJsApp() windowObj.setProperty("localStorage", globalObj.property("localStorage")); globalObj.setProperty("window", windowObj); + _engine->evaluate("function XMLHttpRequest() { return Pebble.createXMLHttpRequest(); }"); + QFile scriptFile(_curApp.path() + "/pebble-js-app.js"); if (!scriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) { logger()->warn() << "Failed to open JS file at:" << scriptFile.fileName(); diff --git a/daemon/jskitmanager.h b/daemon/jskitmanager.h index d09bf54..73d7853 100644 --- a/daemon/jskitmanager.h +++ b/daemon/jskitmanager.h @@ -18,10 +18,13 @@ public: explicit JSKitManager(AppManager *apps, AppMsgManager *appmsg, QObject *parent = 0); ~JSKitManager(); + QJSEngine * engine(); + signals: void appNotification(const QUuid &uuid, const QString &title, const QString &body); public slots: + void showConfiguration(); private slots: void handleAppStarted(const QUuid &uuid); diff --git a/daemon/jskitobjects.cpp b/daemon/jskitobjects.cpp index aecc55d..f745233 100644 --- a/daemon/jskitobjects.cpp +++ b/daemon/jskitobjects.cpp @@ -1,6 +1,7 @@ #include <QStandardPaths> #include <QDesktopServices> #include <QUrl> +#include <QBuffer> #include <QDir> #include "jskitobjects.h" @@ -61,6 +62,13 @@ void JSKitPebble::openUrl(const QUrl &url) } } +QJSValue JSKitPebble::createXMLHttpRequest() +{ + JSKitXMLHttpRequest *xhr = new JSKitXMLHttpRequest(_mgr, 0); + // Should be deleted by JS engine. + return _mgr->engine()->newQObject(xhr); +} + void JSKitPebble::invokeCallbacks(const QString &type, const QJSValueList &args) { if (!_callbacks.contains(type)) return; @@ -144,3 +152,109 @@ QString JSKitLocalStorage::getStorageFileFor(const QUuid &uuid) fileName.remove('}'); return dataDir.absoluteFilePath("js-storage/" + fileName + ".ini"); } + +JSKitXMLHttpRequest::JSKitXMLHttpRequest(JSKitManager *mgr, QObject *parent) + : QObject(parent), _mgr(mgr), + _net(new QNetworkAccessManager(this)), _reply(0) +{ + logger()->debug() << "constructed"; +} + +JSKitXMLHttpRequest::~JSKitXMLHttpRequest() +{ + logger()->debug() << "destructed"; +} + +void JSKitXMLHttpRequest::open(const QString &method, const QString &url, bool async) +{ + if (_reply) { + _reply->deleteLater(); + _reply = 0; + } + + _request = QNetworkRequest(QUrl(url)); + _verb = method; + Q_UNUSED(async); +} + +void JSKitXMLHttpRequest::setRequestHeader(const QString &header, const QString &value) +{ + logger()->debug() << "setRequestHeader" << header << value; + _request.setRawHeader(header.toLatin1(), value.toLatin1()); +} + +void JSKitXMLHttpRequest::send(const QString &body) +{ + QBuffer *buffer = new QBuffer; + buffer->setData(body.toUtf8()); + logger()->debug() << "sending" << _verb << "to" << _request.url() << "with" << body; + _reply = _net->sendCustomRequest(_request, _verb.toLatin1(), buffer); + connect(_reply, &QNetworkReply::finished, this, &JSKitXMLHttpRequest::handleReplyFinished); + buffer->setParent(_reply); // So that it gets deleted alongside the reply object. +} + +void JSKitXMLHttpRequest::abort() +{ + if (_reply) { + _reply->deleteLater(); + _reply = 0; + } +} + +QJSValue JSKitXMLHttpRequest::onload() const +{ + return _onload; +} + +void JSKitXMLHttpRequest::setOnload(const QJSValue &value) +{ + _onload = value; +} + +unsigned short JSKitXMLHttpRequest::readyState() const +{ + if (!_reply) { + return UNSENT; + } else if (_reply->isFinished()) { + return DONE; + } else { + return LOADING; + } +} + +unsigned short JSKitXMLHttpRequest::status() const +{ + if (!_reply || !_reply->isFinished()) { + return 0; + } else { + return _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt(); + } +} + +QString JSKitXMLHttpRequest::responseText() const +{ + return QString::fromUtf8(_response); +} + +void JSKitXMLHttpRequest::handleReplyFinished() +{ + if (!_reply) { + logger()->info() << "reply finished too late"; + return; + } + + _response = _reply->readAll(); + logger()->debug() << "reply finished, reply text:" << QString::fromUtf8(_response); + + emit readyStateChanged(); + emit statusChanged(); + emit responseTextChanged(); + + + if (_onload.isCallable()) { + logger()->debug() << "going to call onload handler:" << _onload.toString(); + _onload.callWithInstance(_mgr->engine()->toScriptValue(this)); + } else { + logger()->debug() << "No onload set"; + } +} diff --git a/daemon/jskitobjects.h b/daemon/jskitobjects.h index c59bfac..1962e01 100644 --- a/daemon/jskitobjects.h +++ b/daemon/jskitobjects.h @@ -2,6 +2,8 @@ #define JSKITMANAGER_P_H #include <QSettings> +#include <QNetworkRequest> +#include <QNetworkReply> #include "jskitmanager.h" class JSKitPebble : public QObject @@ -21,6 +23,8 @@ public: Q_INVOKABLE void openUrl(const QUrl &url); + Q_INVOKABLE QJSValue createXMLHttpRequest(); + void invokeCallbacks(const QString &type, const QJSValueList &args = QJSValueList()); private: @@ -69,4 +73,56 @@ private: int _len; }; +class JSKitXMLHttpRequest : public QObject +{ + Q_OBJECT + LOG4QT_DECLARE_QCLASS_LOGGER + + Q_PROPERTY(QJSValue onload READ onload WRITE setOnload) + Q_PROPERTY(unsigned short readyState READ readyState NOTIFY readyStateChanged) + Q_PROPERTY(unsigned short status READ status NOTIFY statusChanged) + Q_PROPERTY(QString responseText READ responseText NOTIFY responseTextChanged) + +public: + explicit JSKitXMLHttpRequest(JSKitManager *mgr, QObject *parent = 0); + ~JSKitXMLHttpRequest(); + + enum ReadyStates { + UNSENT, + OPENED, + HEADERS_RECEIVED, + LOADING, + DONE + }; + + Q_INVOKABLE void open(const QString &method, const QString &url, bool async); + Q_INVOKABLE void setRequestHeader(const QString &header, const QString &value); + Q_INVOKABLE void send(const QString &body); + Q_INVOKABLE void abort(); + + QJSValue onload() const; + void setOnload(const QJSValue &value); + + unsigned short readyState() const; + unsigned short status() const; + QString responseText() const; + +signals: + void readyStateChanged(); + void statusChanged(); + void responseTextChanged(); + +private slots: + void handleReplyFinished(); + +private: + JSKitManager *_mgr; + QNetworkAccessManager *_net; + QString _verb; + QNetworkRequest _request; + QNetworkReply *_reply; + QByteArray _response; + QJSValue _onload; +}; + #endif // JSKITMANAGER_P_H diff --git a/daemon/manager.cpp b/daemon/manager.cpp index 8d41c89..9db4c70 100644 --- a/daemon/manager.cpp +++ b/daemon/manager.cpp @@ -395,11 +395,5 @@ void Manager::test() { logger()->debug() << "Starting test"; - watch->getAppbankStatus([this](const QString &s) { - logger()->debug() << "Callback invoked" << s; - }); - - watch->getAppbankUuids([this](const QList<QUuid> &uuids) { - logger()->debug() << "Callback invoked. UUIDs:" << uuids.size(); - }); + js->showConfiguration(); } |
