Permalink
Browse files

Implement support for native modules

  • Loading branch information...
1 parent 3229630 commit 5661b49b3b32b9b762ad11b22844ed9fe1595263 @execjosh committed Apr 24, 2013
Showing with 182 additions and 1 deletion.
  1. +80 −0 src/js/nativemodules.cpp
  2. +65 −0 src/js/nativemodules.h
  3. +30 −0 src/js/pjsengine.cpp
  4. +5 −1 src/js/pjsengine.h
  5. +2 −0 src/phantomjs.pro
@@ -0,0 +1,80 @@
+/*
+ This file is part of the PhantomJS project from Ofi Labs.
+
+ Copyright (C) 2013 execjosh, http://execjosh.blogspot.com
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "nativemodules.h"
+
+namespace JS
+{
+
+// public:
+
+NativeModules::NativeModules(QObject *parent)
+ : QObject(parent)
+ , m_childprocess((ChildProcess *) NULL)
+ , m_filesystem((FileSystem *) NULL)
+ , m_system((System *) NULL)
+{
+}
+
+NativeModules::~NativeModules()
+{
+}
+
+// public slots:
+
+QObject *NativeModules::getChildProcess()
+{
+ if ((ChildProcess *) NULL == m_childprocess) {
+ m_childprocess = new ChildProcess(this);
+ }
+
+ return m_childprocess;
+}
+
+QObject *NativeModules::getFileSystem()
+{
+ if ((FileSystem *) NULL == m_filesystem) {
+ m_filesystem = new FileSystem(this);
+ }
+
+ return m_filesystem;
+}
+
+QObject *NativeModules::getSystem()
+{
+ if ((System *) NULL == m_system) {
+ m_system = new System(this);
+ }
+
+ return m_system;
+}
+
+};
+
+// vim:ts=4:sw=4:sts=4:et:
@@ -0,0 +1,65 @@
+/*
+ This file is part of the PhantomJS project from Ofi Labs.
+
+ Copyright (C) 2013 execjosh, http://execjosh.blogspot.com
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef JS_NATIVEMODULES_H
+#define JS_NATIVEMODULES_H
+
+#include <QObject>
+
+#include "../filesystem.h"
+#include "../system.h"
+#include "../childprocess.h"
+
+namespace JS
+{
+
+class NativeModules : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit NativeModules(QObject *parent = 0);
+ virtual ~NativeModules();
+
+public slots:
+ QObject *getChildProcess();
+ QObject *getFileSystem();
+ QObject *getSystem();
+
+private:
+ ChildProcess *m_childprocess;
+ FileSystem *m_filesystem;
+ System *m_system;
+};
+
+};
+
+#endif // JS_NATIVEMODULES_H
+
+// vim:ts=4:sw=4:sts=4:et:
View
@@ -45,6 +45,7 @@ PJSEngine::PJSEngine(QObject *parent)
, m_js((QJSEngine *) NULL)
, m_console((JS::Console *) NULL)
, m_timers((JS::Timers *) NULL)
+ , m_nativemodules((JS::NativeModules *) NULL)
{
}
@@ -88,6 +89,11 @@ bool PJSEngine::init()
}
QJSValue timers = m_js->newQObject(m_timers);
+ if ((JS::NativeModules *) NULL == m_nativemodules) {
+ m_nativemodules = new JS::NativeModules(this);
+ }
+ QJSValue nativeModules = m_js->newQObject(m_nativemodules);
+
QJSValue me = m_js->newQObject(this);
QJSValue createTimerFunc = m_js->evaluate(
@@ -106,6 +112,10 @@ bool PJSEngine::init()
QJSValue phantom = m_js->newObject();
phantom.setProperty("exit", me.property("exit"));
+ phantom.setProperty("loadModule", me.property("loadModule"));
+ phantom.setProperty("_createChildProcess", nativeModules.property("getChildProcess"));
+ phantom.setProperty("createFilesystem", nativeModules.property("getFileSystem"));
+ phantom.setProperty("createSystem", nativeModules.property("getSystem"));
m_js->globalObject().setProperty("phantom", phantom);
m_initialized = true;
@@ -139,6 +149,26 @@ bool PJSEngine::isTerminated() const
return m_terminated;
}
+QJSValue PJSEngine::loadModule(const QString &moduleSource, const QString &filename)
+{
+ if (isTerminated()) {
+ return QJSValue(QJSValue::UndefinedValue);
+ }
+
+ QString scriptSource =
+ "(function(require, exports, module) {" +
+ moduleSource +
+ "}.call({},"
+ "require.cache['" + filename + "']._getRequire(),"
+ "require.cache['" + filename + "'].exports,"
+ "require.cache['" + filename + "']"
+ "));";
+ QJSValue res = m_js->evaluate(scriptSource, filename);
+ if (res.isError()) {
+ std::cerr << "uncaught exception: " << qPrintable(res.property("stack").toString()) << std::endl;
+ }
+ return res;
+}
};
View
@@ -32,10 +32,11 @@
#include <QObject>
#include <QJSEngine>
-#include <QVariant>
+#include <QJSValue>
#include "console.h"
#include "timers.h"
+#include "nativemodules.h"
namespace JS
{
@@ -57,13 +58,16 @@ public slots:
void exit(int code = 0);
bool isTerminated() const;
+ // Module stuff
+ QJSValue loadModule(const QString &moduleSource, const QString &filename);
private:
bool m_initialized;
bool m_terminated;
QJSEngine *m_js;
JS::Console *m_console;
Timers *m_timers;
+ NativeModules *m_nativemodules;
};
};
View
@@ -17,6 +17,7 @@ HEADERS += csconverter.h \
js/console.h \
js/timers.h \
js/timercontext.h \
+ js/nativemodules.h \
callback.h \
webpage.h \
webserver.h \
@@ -38,6 +39,7 @@ SOURCES += phantom.cpp \
js/console.cpp \
js/timers.cpp \
js/timercontext.cpp \
+ js/nativemodules.cpp \
callback.cpp \
webpage.cpp \
webserver.cpp \

0 comments on commit 5661b49

Please sign in to comment.