1 /*
2     SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
3     SPDX-FileCopyrightText: 2008 Harri Porten <porten@kde.org>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "executor_kjs_p.h"
9 
10 #include <kjs/kjsarguments.h>
11 #include <kjs/kjsinterpreter.h>
12 #include <kjs/kjsobject.h>
13 #include <kjs/kjsprototype.h>
14 #include <kjs_version.h>
15 
16 #include <QDebug>
17 
18 #include "../debug_p.h"
19 #include "../document_p.h"
20 
21 #include "config-okular.h"
22 #include "event_p.h"
23 #include "kjs_app_p.h"
24 #include "kjs_console_p.h"
25 #include "kjs_data_p.h"
26 #include "kjs_display_p.h"
27 #include "kjs_document_p.h"
28 #include "kjs_event_p.h"
29 #include "kjs_field_p.h"
30 #include "kjs_fullscreen_p.h"
31 #include "kjs_ocg_p.h"
32 #include "kjs_spell_p.h"
33 #include "kjs_util_p.h"
34 
35 using namespace Okular;
36 
37 class Okular::ExecutorKJSPrivate
38 {
39 public:
ExecutorKJSPrivate(DocumentPrivate * doc)40     explicit ExecutorKJSPrivate(DocumentPrivate *doc)
41         : m_doc(doc)
42     {
43         initTypes();
44     }
~ExecutorKJSPrivate()45     ~ExecutorKJSPrivate()
46     {
47         delete m_interpreter;
48     }
49 
50     void initTypes();
51 
52     DocumentPrivate *m_doc;
53     KJSInterpreter *m_interpreter;
54     KJSGlobalObject m_docObject;
55 };
56 
initTypes()57 void ExecutorKJSPrivate::initTypes()
58 {
59     m_docObject = JSDocument::wrapDocument(m_doc);
60     m_interpreter = new KJSInterpreter(m_docObject);
61 
62 #if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0)
63     m_interpreter->setTimeoutTime(2000); // max 2 secs allowed
64 #endif
65     KJSContext *ctx = m_interpreter->globalContext();
66 
67     JSApp::initType(ctx);
68     JSFullscreen::initType(ctx);
69     JSConsole::initType(ctx);
70     JSData::initType(ctx);
71     JSDisplay::initType(ctx);
72     JSDocument::initType(ctx);
73     JSEvent::initType(ctx);
74     JSField::initType(ctx);
75     JSOCG::initType(ctx);
76     JSSpell::initType(ctx);
77     JSUtil::initType(ctx);
78 
79     m_docObject.setProperty(ctx, QStringLiteral("app"), JSApp::object(ctx, m_doc));
80     m_docObject.setProperty(ctx, QStringLiteral("console"), JSConsole::object(ctx));
81     m_docObject.setProperty(ctx, QStringLiteral("Doc"), m_docObject);
82     m_docObject.setProperty(ctx, QStringLiteral("display"), JSDisplay::object(ctx));
83     m_docObject.setProperty(ctx, QStringLiteral("OCG"), JSOCG::object(ctx));
84     m_docObject.setProperty(ctx, QStringLiteral("spell"), JSSpell::object(ctx));
85     m_docObject.setProperty(ctx, QStringLiteral("util"), JSUtil::object(ctx));
86 }
87 
ExecutorKJS(DocumentPrivate * doc)88 ExecutorKJS::ExecutorKJS(DocumentPrivate *doc)
89     : d(new ExecutorKJSPrivate(doc))
90 {
91 }
92 
~ExecutorKJS()93 ExecutorKJS::~ExecutorKJS()
94 {
95     JSField::clearCachedFields();
96     JSApp::clearCachedFields();
97     JSOCG::clearCachedFields();
98     delete d;
99 }
100 
execute(const QString & script,Event * event)101 void ExecutorKJS::execute(const QString &script, Event *event)
102 {
103     KJSContext *ctx = d->m_interpreter->globalContext();
104 
105     d->m_docObject.setProperty(ctx, QStringLiteral("event"), event ? JSEvent::wrapEvent(ctx, event) : KJSUndefined());
106 
107 #if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0)
108     d->m_interpreter->startTimeoutCheck();
109 #endif
110     KJSResult result = d->m_interpreter->evaluate(QStringLiteral("okular.js"), 1, script, &d->m_docObject);
111 #if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0)
112     d->m_interpreter->stopTimeoutCheck();
113 #endif
114 
115     if (result.isException() || ctx->hasException()) {
116         qCDebug(OkularCoreDebug) << "JS exception" << result.errorMessage();
117     } else {
118         qCDebug(OkularCoreDebug) << "result:" << result.value().toString(ctx);
119 
120         if (event) {
121             qCDebug(OkularCoreDebug) << "Event Result:" << event->name() << event->type() << "value:" << event->value();
122         }
123     }
124 }
125