21 #include "scriptabletags.h"
23 #include <QtCore/QFile>
26 #include <QtQml/QJSEngine>
27 #include <QtQml/QJSValueIterator>
29 #include "nodebuiltins_p.h"
32 #include "exception.h"
34 #include "scriptablefilter.h"
35 #include "scriptablefilterexpression.h"
36 #include "scriptablenode.h"
37 #include "scriptablesafestring.h"
38 #include "scriptabletemplate.h"
39 #include "scriptablevariable.h"
44 Q_DECLARE_METATYPE(
Token)
48 QJSValue ScriptableHelperFunctions::markSafeFunction(QJSValue inputValue)
50 if (inputValue.isQObject()) {
51 auto obj = inputValue.toQObject();
52 auto ssObj = qobject_cast<ScriptableSafeString *>(obj);
54 return QJSValue::NullValue;
56 ssObj->setSafety(
true);
57 return m_scriptEngine->newQObject(ssObj);
59 }
else if (inputValue.isString()) {
60 auto str = inputValue.toString();
63 return m_scriptEngine->newQObject(ssObj);
65 return QJSValue::NullValue;
68 QJSValue ScriptableHelperFunctions::ScriptableFilterExpressionConstructor(
69 QString name, QObject *parserObj)
73 auto p = qobject_cast<Parser *>(parserObj);
75 object->init(name, p);
77 return m_scriptEngine->newQObject(
object);
81 ScriptableHelperFunctions::ScriptableNodeConstructor(QJSValue callContext)
83 QJSValueIterator it(callContext);
85 auto scriptableNodeName = it.value().toString();
87 = m_scriptEngine->globalObject().property(scriptableNodeName);
93 concreteNode = concreteNode.callAsConstructor(args);
95 auto renderMethod = concreteNode.property(QStringLiteral(
"render"));
98 object->setObjectName(scriptableNodeName);
99 object->setScriptEngine(m_scriptEngine);
100 object->init(concreteNode, renderMethod);
101 return m_scriptEngine->newQObject(
object);
104 QJSValue ScriptableHelperFunctions::ScriptableTemplateConstructor(
108 = m_scriptEngine->property(
"templateEngine").value<
Engine *>();
113 auto t = templateEngine->newTemplate(content, name);
116 return m_scriptEngine->newQObject(
object);
119 QJSValue ScriptableHelperFunctions::ScriptableVariableConstructor(
QString name)
127 object->setContent(name);
129 return m_scriptEngine->newQObject(
object);
132 ScriptableTagLibrary::ScriptableTagLibrary(QObject *parent)
133 : QObject(parent), m_scriptEngine(new QJSEngine(this)),
134 m_functions(m_scriptEngine->newQObject(
137 m_scriptEngine->globalObject().setProperty(
138 QStringLiteral(
"internalCuteleeFunctions"), m_functions);
141 m_scriptEngine->globalObject().setProperty(
142 QStringLiteral(
"Node"),
143 m_scriptEngine->evaluate(QStringLiteral(R
"javascript(
145 return internalCuteleeFunctions.ScriptableNodeConstructor(
146 Array.prototype.slice.call(arguments));
151 m_scriptEngine->globalObject().setProperty(
152 QStringLiteral(
"Variable"),
153 m_functions.property(QStringLiteral(
"ScriptableVariableConstructor")));
156 m_scriptEngine->globalObject().setProperty(
157 QStringLiteral(
"FilterExpression"),
158 m_functions.property(
159 QStringLiteral(
"ScriptableFilterExpressionConstructor")));
162 m_scriptEngine->globalObject().setProperty(
163 QStringLiteral(
"Template"),
164 m_functions.property(QStringLiteral(
"ScriptableTemplateConstructor")));
167 auto libraryObject = m_scriptEngine->newQObject(
this);
168 m_scriptEngine->globalObject().setProperty(QStringLiteral(
"Library"),
173 auto nodeFactoryObject = m_scriptEngine->newQObject(nodeFactory);
174 m_scriptEngine->globalObject().setProperty(
175 QStringLiteral(
"AbstractNodeFactory"), nodeFactoryObject);
178 m_scriptEngine->globalObject().setProperty(
179 QStringLiteral(
"mark_safe"),
180 m_functions.property(QStringLiteral(
"markSafeFunction")));
183 bool ScriptableTagLibrary::evaluateScript(
const QString &name)
185 QFile scriptFile(name);
187 if (!scriptFile.exists()
188 || !scriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
192 QTextStream fstream(&scriptFile);
193 fstream.setCodec(
"UTF-8");
194 const auto fileContent = fstream.readAll();
198 QJSValue result = m_scriptEngine->evaluate(fileContent);
199 if (result.isError())
205 QHash<QString, AbstractNodeFactory *>
208 m_factoryNames.clear();
209 m_nodeFactories.clear();
210 QHash<QString, AbstractNodeFactory *> h;
212 if (!evaluateScript(name)) {
216 return getFactories();
221 m_filterNames.clear();
223 QHash<QString, Filter *>
filters;
225 if (!evaluateScript(name)) {
232 QHash<QString, AbstractNodeFactory *> ScriptableTagLibrary::getFactories()
234 QHash<QString, AbstractNodeFactory *> factories;
235 for (
auto it = m_factoryNames.begin(), end = m_factoryNames.end(); it != end;
237 auto factoryName = it.value();
238 auto tagName = it.key();
240 auto factoryObject = m_scriptEngine->globalObject().property(factoryName);
243 snf->setScriptEngine(m_scriptEngine);
244 snf->setFactory(factoryObject);
246 factories.insert(tagName, snf);
252 QHash<QString, Filter *> ScriptableTagLibrary::getFilters()
254 QHash<QString, Filter *>
filters;
256 for (
auto &filterNameString : m_filterNames) {
258 = m_scriptEngine->globalObject().property(filterNameString);
260 = filterObject.property(QStringLiteral(
"filterName")).toString();
262 filters.insert(filterName, filter);
268 void ScriptableTagLibrary::addFactory(
const QString &factoryName,
271 m_factoryNames.insert(tagName, factoryName);
274 void ScriptableTagLibrary::addFilter(
const QString &filterName)
276 m_filterNames << filterName;
Cutelee::Engine is the main entry point for creating Cutelee Templates.
An exception for use when implementing template tags.
QHash< QString, AbstractNodeFactory * > nodeFactories(const QString &name={}) override
QHash< QString, Filter * > filters(const QString &name={}) override
The Cutelee namespace holds all public Cutelee API.
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Utility functions used throughout Cutelee.