2
This file is part of the Grantlee template system.
4
Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either version
9
2 of the Licence, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with this library. If not, see <http://www.gnu.org/licenses/>.
21
#include "scriptablenode.h"
23
#include <QtScript/QScriptEngine>
26
#include "scriptablecontext.h"
27
#include "scriptableparser.h"
29
#include "exception.h"
32
Q_DECLARE_METATYPE( Engine* )
34
QScriptValue nodeToScriptValue( QScriptEngine *engine, Node* const &node )
36
return engine->newQObject( node );
39
void nodeFromScriptValue( const QScriptValue &object, Node* &out )
41
out = qobject_cast<Node*>( object.toQObject() );
45
Q_SCRIPT_DECLARE_QMETAOBJECT( ScriptableNode, Node* )
47
QScriptValue ScriptableNodeConstructor( QScriptContext *context,
48
QScriptEngine *engine )
50
QString scriptableNodeName = context->argument( 0 ).toString();
51
QScriptValue concreteNode = engine->globalObject().property( scriptableNodeName );
53
QScriptValueList args;
54
// First is the node type
55
for ( int i = 1; i < context->argumentCount(); ++i ) {
56
args << context->argument( i );
59
concreteNode.call( concreteNode, args );
61
QScriptValue renderMethod = concreteNode.property( "render" );
63
ScriptableNode *object = new ScriptableNode( engine );
64
object->setObjectName( scriptableNodeName );
65
object->setScriptEngine( engine );
66
object->init( concreteNode, renderMethod );
67
return engine->newQObject( object );
71
ScriptableNode::ScriptableNode( QObject* parent ): Node( parent ), m_scriptEngine( 0 )
76
void ScriptableNode::setScriptEngine( QScriptEngine *engine )
78
m_scriptEngine = engine;
81
void ScriptableNode::init( const QScriptValue &concreteNode,
82
const QScriptValue &renderMethod )
84
m_concreteNode = concreteNode;
85
m_renderMethod = renderMethod;
88
void ScriptableNode::render( OutputStream *stream, Context *c )
90
ScriptableContext sc( c );
91
QScriptValue contextObject = m_scriptEngine->newQObject( &sc );
93
QScriptValueList args;
94
args << contextObject;
96
// Call the render method in the context of the concreteNode
97
QScriptValue value = m_renderMethod.call( m_concreteNode, args );
99
if ( value.isValid() && !value.isUndefined() )
100
( *stream ) << value.toString();
103
ScriptableNodeFactory::ScriptableNodeFactory( QObject* parent )
104
: AbstractNodeFactory( parent ), m_scriptEngine( 0 )
109
void ScriptableNodeFactory::setScriptEngine( QScriptEngine *engine )
111
m_scriptEngine = engine;
114
void ScriptableNodeFactory::setEngine(Engine* engine)
116
m_scriptEngine->setProperty( "templateEngine", QVariant::fromValue( engine ) );
119
void ScriptableNodeFactory::setFactory( QScriptValue factoryMethod )
121
m_factoryMethod = factoryMethod;
124
Node* ScriptableNodeFactory::getNode( const QString &tagContent, Parser *p ) const
126
if ( m_scriptEngine->hasUncaughtException() ) {
127
throw Grantlee::Exception( TagSyntaxError, m_scriptEngine->uncaughtExceptionBacktrace().join( " " ) );
129
ScriptableParser *sp = new ScriptableParser( p, m_scriptEngine );
130
QScriptValue parserObject = m_scriptEngine->newQObject( sp );
132
QScriptValueList args;
134
args << parserObject;
136
QScriptValue factory = m_factoryMethod;
138
QScriptValue scriptNode = factory.call( factory, args );
139
if ( m_scriptEngine->hasUncaughtException() )
140
throw Grantlee::Exception( TagSyntaxError, m_scriptEngine->uncaughtExceptionBacktrace().join( " " ) );
142
Node* node = qscriptvalue_cast<Node*>( scriptNode );
143
node->setParent( p );
147
QScriptEngine* ScriptableNode::engine()
149
return m_scriptEngine;
152
void ScriptableNode::setNodeList( const QString &name, QObjectList objectList )
154
QScriptValue objectListArray = m_scriptEngine->newArray( objectList.size() );
156
for ( int i = 0; i < objectList.size(); ++i ) {
157
objectListArray.setProperty( i, m_scriptEngine->newQObject( objectList.at( i ) ) );
159
m_concreteNode.setProperty( name, objectListArray );
163
#include "scriptablenode.moc"