summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2014-12-01 03:12:00 +0100
committerJavier <dev.git@javispedro.com>2014-12-01 03:14:10 +0100
commitbe139d8ff95160782b424134a025b30c82083e28 (patch)
tree70cda209c44a657db3dd436afacaabe53b192838
parent1e3794c476caf5c41360c36cc13c8425ec0dd26c (diff)
add stub xmlhttprequest and allow showConfig event
-rw-r--r--daemon/jskitmanager.cpp14
-rw-r--r--daemon/jskitmanager.h3
-rw-r--r--daemon/jskitobjects.cpp114
-rw-r--r--daemon/jskitobjects.h56
-rw-r--r--daemon/manager.cpp8
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();
}