Initial import from the monolithic Qt.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativedom.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "private/qdeclarativedom_p.h"
43 #include "private/qdeclarativedom_p_p.h"
44
45 #include "private/qdeclarativecompiler_p.h"
46 #include "private/qdeclarativeengine_p.h"
47 #include "private/qdeclarativescriptparser_p.h"
48 #include "private/qdeclarativeglobal_p.h"
49
50 #include <QtCore/QByteArray>
51 #include <QtCore/QDebug>
52 #include <QtCore/QString>
53
54 QT_BEGIN_NAMESPACE
55
56 QDeclarativeDomDocumentPrivate::QDeclarativeDomDocumentPrivate()
57 : root(0)
58 {
59 }
60
61 QDeclarativeDomDocumentPrivate::~QDeclarativeDomDocumentPrivate()
62 {
63     if (root) root->release();
64 }
65
66 /*!
67     \class QDeclarativeDomDocument
68     \internal
69     \brief The QDeclarativeDomDocument class represents the root of a QML document
70
71     A QML document is a self-contained snippet of QML, usually contained in a
72     single file. Each document has a root object, accessible through
73     QDeclarativeDomDocument::rootObject().
74
75     The QDeclarativeDomDocument class allows the programmer to inspect a QML document by
76     calling QDeclarativeDomDocument::load().
77
78     The following example loads a QML file from disk, and prints out its root
79     object type and the properties assigned in the root object.
80     \code
81     QFile file(inputFileName);
82     file.open(QIODevice::ReadOnly);
83     QByteArray xmlData = file.readAll();
84
85     QDeclarativeDomDocument document;
86     document.load(qmlengine, xmlData);
87
88     QDeclarativeDomObject rootObject = document.rootObject();
89     qDebug() << rootObject.objectType();
90     foreach(QDeclarativeDomProperty property, rootObject.properties())
91         qDebug() << property.propertyName();
92     \endcode
93 */
94
95 /*!
96     Construct an empty QDeclarativeDomDocument.
97 */
98 QDeclarativeDomDocument::QDeclarativeDomDocument()
99 : d(new QDeclarativeDomDocumentPrivate)
100 {
101 }
102
103 /*!
104     Create a copy of \a other QDeclarativeDomDocument.
105 */
106 QDeclarativeDomDocument::QDeclarativeDomDocument(const QDeclarativeDomDocument &other)
107 : d(other.d)
108 {
109 }
110
111 /*!
112     Destroy the QDeclarativeDomDocument
113 */
114 QDeclarativeDomDocument::~QDeclarativeDomDocument()
115 {
116 }
117
118 /*!
119     Assign \a other to this QDeclarativeDomDocument.
120 */
121 QDeclarativeDomDocument &QDeclarativeDomDocument::operator=(const QDeclarativeDomDocument &other)
122 {
123     d = other.d;
124     return *this;
125 }
126
127 /*!
128     Returns all import statements in qml.
129 */
130 QList<QDeclarativeDomImport> QDeclarativeDomDocument::imports() const
131 {
132     return d->imports;
133 }
134
135 /*!
136     Loads a QDeclarativeDomDocument from \a data.  \a data should be valid QML
137     data.  On success, true is returned.  If the \a data is malformed, false
138     is returned and QDeclarativeDomDocument::errors() contains an error description.
139
140     \sa QDeclarativeDomDocument::loadError()
141 */
142 bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray &data, const QUrl &url)
143 {
144     d->errors.clear();
145     d->imports.clear();
146
147     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
148     QDeclarativeTypeData *td = ep->typeLoader.get(data, url, QDeclarativeTypeLoader::PreserveParser);
149
150     if(td->isError()) {
151         d->errors = td->errors();
152         td->release();
153         return false;
154     } else if(!td->isCompleteOrError()) {
155         QDeclarativeError error;
156         error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
157         d->errors << error;
158         td->release();
159         return false;
160     }
161
162     for (int i = 0; i < td->parser().imports().size(); ++i) {
163         QDeclarativeScriptParser::Import parserImport = td->parser().imports().at(i);
164         QDeclarativeDomImport domImport;
165         domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
166         domImport.d->uri = parserImport.uri;
167         domImport.d->qualifier = parserImport.qualifier;
168         domImport.d->version = parserImport.version;
169         d->imports += domImport;
170     }
171
172     if (td->parser().tree()) {
173         d->root = td->parser().tree();
174         d->root->addref();
175     }
176
177     td->release();
178     return true;
179 }
180
181 /*!
182     Returns the last load errors.  The load errors will be reset after a
183     successful call to load().
184
185     \sa load()
186 */
187 QList<QDeclarativeError> QDeclarativeDomDocument::errors() const
188 {
189     return d->errors;
190 }
191
192 /*!
193     Returns the document's root object, or an invalid QDeclarativeDomObject if the
194     document has no root.
195
196     In the sample QML below, the root object will be the QDeclarativeItem type.
197     \qml
198 Item {
199     Text {
200         text: "Hello World"
201     }
202 }
203     \endqml
204 */
205 QDeclarativeDomObject QDeclarativeDomDocument::rootObject() const
206 {
207     QDeclarativeDomObject rv;
208     rv.d->object = d->root;
209     if (rv.d->object) rv.d->object->addref();
210     return rv;
211 }
212
213 QDeclarativeDomPropertyPrivate::QDeclarativeDomPropertyPrivate()
214 : property(0)
215 {
216 }
217
218 QDeclarativeDomPropertyPrivate::~QDeclarativeDomPropertyPrivate()
219 {
220     if (property) property->release();
221 }
222
223 QDeclarativeDomDynamicPropertyPrivate::QDeclarativeDomDynamicPropertyPrivate():
224         valid(false)
225 {
226 }
227
228 QDeclarativeDomDynamicPropertyPrivate::~QDeclarativeDomDynamicPropertyPrivate()
229 {
230     if (valid && property.defaultValue) property.defaultValue->release();
231 }
232
233 /*!
234     \class QDeclarativeDomProperty
235     \internal
236     \brief The QDeclarativeDomProperty class represents one property assignment in the
237     QML DOM tree
238
239     Properties in QML can be assigned QML \l {QDeclarativeDomValue}{values}.
240
241     \sa QDeclarativeDomObject
242 */
243
244 /*!
245     Construct an invalid QDeclarativeDomProperty.
246 */
247 QDeclarativeDomProperty::QDeclarativeDomProperty()
248 : d(new QDeclarativeDomPropertyPrivate)
249 {
250 }
251
252 /*!
253     Create a copy of \a other QDeclarativeDomProperty.
254 */
255 QDeclarativeDomProperty::QDeclarativeDomProperty(const QDeclarativeDomProperty &other)
256 : d(other.d)
257 {
258 }
259
260 /*!
261     Destroy the QDeclarativeDomProperty.
262 */
263 QDeclarativeDomProperty::~QDeclarativeDomProperty()
264 {
265 }
266
267 /*!
268     Assign \a other to this QDeclarativeDomProperty.
269 */
270 QDeclarativeDomProperty &QDeclarativeDomProperty::operator=(const QDeclarativeDomProperty &other)
271 {
272     d = other.d;
273     return *this;
274 }
275
276 /*!
277     Returns true if this is a valid QDeclarativeDomProperty, false otherwise.
278 */
279 bool QDeclarativeDomProperty::isValid() const
280 {
281     return d->property != 0;
282 }
283
284
285 /*!
286     Return the name of this property.
287
288     \qml
289 Text {
290     x: 10
291     y: 10
292     font.bold: true
293 }
294     \endqml
295
296     As illustrated above, a property name can be a simple string, such as "x" or
297     "y", or a more complex "dot property", such as "font.bold".  In both cases
298     the full name is returned ("x", "y" and "font.bold") by this method.
299
300     For dot properties, a split version of the name can be accessed by calling
301     QDeclarativeDomProperty::propertyNameParts().
302
303     \sa QDeclarativeDomProperty::propertyNameParts()
304 */
305 QByteArray QDeclarativeDomProperty::propertyName() const
306 {
307     return d->propertyName;
308 }
309
310 /*!
311     Return the name of this property, split into multiple parts in the case
312     of dot properties.
313
314     \qml
315 Text {
316     x: 10
317     y: 10
318     font.bold: true
319 }
320     \endqml
321
322     For each of the properties shown above, this method would return ("x"),
323     ("y") and ("font", "bold").
324
325     \sa QDeclarativeDomProperty::propertyName()
326 */
327 QList<QByteArray> QDeclarativeDomProperty::propertyNameParts() const
328 {
329     if (d->propertyName.isEmpty()) return QList<QByteArray>();
330     else return d->propertyName.split('.');
331 }
332
333 /*!
334     Return true if this property is used as a default property in the QML
335     document.
336
337     \code
338 <Text text="hello"/>
339 <Text>hello</Text>
340     \endcode
341
342     The above two examples return the same DOM tree, except that the second has
343     the default property flag set on the text property.  Observe that whether
344     or not a property has isDefaultProperty set is determined by how the
345     property is used, and not only by whether the property is the types default
346     property.
347 */
348 bool QDeclarativeDomProperty::isDefaultProperty() const
349 {
350     return d->property && d->property->isDefault;
351 }
352
353 /*!
354     Returns the QDeclarativeDomValue that is assigned to this property, or an invalid
355     QDeclarativeDomValue if no value is assigned.
356 */
357 QDeclarativeDomValue QDeclarativeDomProperty::value() const
358 {
359     QDeclarativeDomValue rv;
360     if (d->property) {
361         rv.d->property = d->property;
362         if (d->property->values.count())
363             rv.d->value = d->property->values.at(0);
364         else
365             rv.d->value = d->property->onValues.at(0);
366         rv.d->property->addref();
367         rv.d->value->addref();
368     }
369     return rv;
370 }
371
372 /*!
373     Returns the position in the input data where the property ID startd, or -1 if
374  the property is invalid.
375 */
376 int QDeclarativeDomProperty::position() const
377 {
378     if (d && d->property) {
379         return d->property->location.range.offset;
380     } else
381         return -1;
382 }
383
384 /*!
385     Returns the length in the input data from where the property ID started upto
386  the end of it, or -1 if the property is invalid.
387 */
388 int QDeclarativeDomProperty::length() const
389 {
390     if (d && d->property)
391         return d->property->location.range.length;
392     else
393         return -1;
394 }
395
396 /*!
397     Construct an invalid QDeclarativeDomDynamicProperty.
398 */
399 QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty():
400         d(new QDeclarativeDomDynamicPropertyPrivate)
401 {
402 }
403
404 /*!
405     Create a copy of \a other QDeclarativeDomDynamicProperty.
406 */
407 QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty(const QDeclarativeDomDynamicProperty &other):
408         d(other.d)
409 {
410 }
411
412 /*!
413     Destroy the QDeclarativeDomDynamicProperty.
414 */
415 QDeclarativeDomDynamicProperty::~QDeclarativeDomDynamicProperty()
416 {
417 }
418
419 /*!
420     Assign \a other to this QDeclarativeDomDynamicProperty.
421 */
422 QDeclarativeDomDynamicProperty &QDeclarativeDomDynamicProperty::operator=(const QDeclarativeDomDynamicProperty &other)
423 {
424     d = other.d;
425     return *this;
426 }
427
428 bool QDeclarativeDomDynamicProperty::isValid() const
429 {
430     return d && d->valid;
431 }
432
433 /*!
434     Return the name of this dynamic property.
435
436     \qml
437 Item {
438     property int count: 10;
439 }
440     \endqml
441
442     As illustrated above, a dynamic property name can have a name and a
443     default value ("10").
444 */
445 QByteArray QDeclarativeDomDynamicProperty::propertyName() const
446 {
447     if (isValid())
448         return d->property.name;
449     else
450         return QByteArray();
451 }
452
453 /*!
454    Returns the type of the dynamic property. Note that when the property is an
455    alias property, this will return -1. Use QDeclarativeDomProperty::isAlias() to check
456    if the property is an alias.
457 */
458 int QDeclarativeDomDynamicProperty::propertyType() const
459 {
460     if (isValid()) {
461         switch (d->property.type) {
462             case QDeclarativeParser::Object::DynamicProperty::Bool:
463                 return QMetaType::type("bool");
464
465             case QDeclarativeParser::Object::DynamicProperty::Color:
466                 return QMetaType::type("QColor");
467
468             case QDeclarativeParser::Object::DynamicProperty::Time:
469                 return QMetaType::type("QTime");
470
471             case QDeclarativeParser::Object::DynamicProperty::Date:
472                 return QMetaType::type("QDate");
473
474             case QDeclarativeParser::Object::DynamicProperty::DateTime:
475                 return QMetaType::type("QDateTime");
476
477             case QDeclarativeParser::Object::DynamicProperty::Int:
478                 return QMetaType::type("int");
479
480             case QDeclarativeParser::Object::DynamicProperty::Real:
481                 return sizeof(qreal) == sizeof(double) ? QMetaType::type("double") : QMetaType::type("float");
482
483             case QDeclarativeParser::Object::DynamicProperty::String:
484                 return QMetaType::type("QString");
485
486             case QDeclarativeParser::Object::DynamicProperty::Url:
487                 return QMetaType::type("QUrl");
488
489             case QDeclarativeParser::Object::DynamicProperty::Variant:
490                 return QMetaType::type("QVariant");
491
492             default:
493                 break;
494         }
495     }
496
497     return -1;
498 }
499
500 QByteArray QDeclarativeDomDynamicProperty::propertyTypeName() const
501 {
502     if (isValid())
503         return d->property.customType;
504
505     return QByteArray();
506 }
507
508 /*!
509     Return true if this property is used as a default property in the QML
510     document.
511
512     \code
513 <Text text="hello"/>
514 <Text>hello</Text>
515     \endcode
516
517     The above two examples return the same DOM tree, except that the second has
518     the default property flag set on the text property.  Observe that whether
519     or not a property has isDefaultProperty set is determined by how the
520     property is used, and not only by whether the property is the types default
521     property.
522 */
523 bool QDeclarativeDomDynamicProperty::isDefaultProperty() const
524 {
525     if (isValid())
526         return d->property.isDefaultProperty;
527     else
528         return false;
529 }
530
531 /*!
532     Returns the default value as a QDeclarativeDomProperty.
533 */
534 QDeclarativeDomProperty QDeclarativeDomDynamicProperty::defaultValue() const
535 {
536     QDeclarativeDomProperty rp;
537
538     if (isValid() && d->property.defaultValue) {
539         rp.d->property = d->property.defaultValue;
540         rp.d->propertyName = propertyName();
541         rp.d->property->addref();
542     }
543
544     return rp;
545 }
546
547 /*!
548     Returns true if this dynamic property is an alias for another property,
549     false otherwise.
550 */
551 bool QDeclarativeDomDynamicProperty::isAlias() const
552 {
553     if (isValid())
554         return d->property.type == QDeclarativeParser::Object::DynamicProperty::Alias;
555     else
556         return false;
557 }
558
559 /*!
560     Returns the position in the input data where the property ID startd, or 0 if
561  the property is invalid.
562 */
563 int QDeclarativeDomDynamicProperty::position() const
564 {
565     if (isValid()) {
566         return d->property.location.range.offset;
567     } else
568         return -1;
569 }
570
571 /*!
572     Returns the length in the input data from where the property ID started upto
573  the end of it, or 0 if the property is invalid.
574 */
575 int QDeclarativeDomDynamicProperty::length() const
576 {
577     if (isValid())
578         return d->property.location.range.length;
579     else
580         return -1;
581 }
582
583 QDeclarativeDomObjectPrivate::QDeclarativeDomObjectPrivate()
584 : object(0)
585 {
586 }
587
588 QDeclarativeDomObjectPrivate::~QDeclarativeDomObjectPrivate()
589 {
590     if (object) object->release();
591 }
592
593 QDeclarativeDomObjectPrivate::Properties
594 QDeclarativeDomObjectPrivate::properties() const
595 {
596     Properties rv;
597
598     for (QHash<QByteArray, QDeclarativeParser::Property *>::ConstIterator iter =
599             object->properties.begin();
600             iter != object->properties.end();
601             ++iter) {
602
603         rv << properties(*iter);
604
605     }
606     return rv;
607 }
608
609 QDeclarativeDomObjectPrivate::Properties
610 QDeclarativeDomObjectPrivate::properties(QDeclarativeParser::Property *property) const
611 {
612     Properties rv;
613
614     if (property->value) {
615
616         for (QHash<QByteArray, QDeclarativeParser::Property *>::ConstIterator iter =
617                 property->value->properties.begin();
618                 iter != property->value->properties.end();
619                 ++iter) {
620
621             rv << properties(*iter);
622
623         }
624
625         QByteArray name(property->name + '.');
626         for (Properties::Iterator iter = rv.begin(); iter != rv.end(); ++iter)
627             iter->second.prepend(name);
628
629     } else {
630         rv << qMakePair(property, property->name);
631     }
632
633     return rv;
634 }
635
636 /*!
637     \class QDeclarativeDomObject
638     \internal
639     \brief The QDeclarativeDomObject class represents an object instantiation.
640
641     Each object instantiated in a QML file has a corresponding QDeclarativeDomObject
642     node in the QML DOM.
643
644     In addition to the type information that determines the object to
645     instantiate, QDeclarativeDomObject's also have a set of associated QDeclarativeDomProperty's.
646     Each QDeclarativeDomProperty represents a QML property assignment on the instantiated
647     object.  For example,
648
649     \qml
650 QGraphicsWidget {
651     opacity: 0.5
652     size: "100x100"
653 }
654     \endqml
655
656     describes a single QDeclarativeDomObject - "QGraphicsWidget" - with two properties,
657     "opacity" and "size".  Obviously QGraphicsWidget has many more properties than just
658     these two, but the QML DOM representation only contains those assigned
659     values (or bindings) in the QML file.
660 */
661
662 /*!
663     Construct an invalid QDeclarativeDomObject.
664 */
665 QDeclarativeDomObject::QDeclarativeDomObject()
666 : d(new QDeclarativeDomObjectPrivate)
667 {
668 }
669
670 /*!
671     Create a copy of \a other QDeclarativeDomObject.
672 */
673 QDeclarativeDomObject::QDeclarativeDomObject(const QDeclarativeDomObject &other)
674 : d(other.d)
675 {
676 }
677
678 /*!
679     Destroy the QDeclarativeDomObject.
680 */
681 QDeclarativeDomObject::~QDeclarativeDomObject()
682 {
683 }
684
685 /*!
686     Assign \a other to this QDeclarativeDomObject.
687 */
688 QDeclarativeDomObject &QDeclarativeDomObject::operator=(const QDeclarativeDomObject &other)
689 {
690     d = other.d;
691     return *this;
692 }
693
694 /*!
695     Returns true if this is a valid QDeclarativeDomObject, false otherwise.
696 */
697 bool QDeclarativeDomObject::isValid() const
698 {
699     return d->object != 0;
700 }
701
702 /*!
703     Returns the fully-qualified type name of this object.
704
705     For example, the type of this object would be "Qt/4.6/Rectangle".
706     \qml
707 Rectangle { }
708     \endqml
709 */
710 QByteArray QDeclarativeDomObject::objectType() const
711 {
712     if (d->object) return d->object->typeName;
713     else return QByteArray();
714 }
715
716 /*!
717     Returns the type name as referenced in the qml file.
718
719     For example, the type of this object would be "Rectangle".
720     \qml
721 Rectangle { }
722     \endqml
723 */
724 QByteArray QDeclarativeDomObject::objectClassName() const
725 {
726     if (d->object)
727         return d->object->className;
728     else
729         return QByteArray();
730 }
731
732 int QDeclarativeDomObject::objectTypeMajorVersion() const
733 {
734     if (d->object)
735         return d->object->majorVersion;
736     else
737         return -1;
738 }
739
740 int QDeclarativeDomObject::objectTypeMinorVersion() const
741 {
742     if (d->object)
743         return d->object->minorVersion;
744     else
745         return -1;
746 }
747
748 /*!
749     Returns the QML id assigned to this object, or an empty QByteArray if no id
750     has been assigned.
751
752     For example, the object id of this object would be "MyText".
753     \qml
754 Text { id: myText }
755     \endqml
756 */
757 QString QDeclarativeDomObject::objectId() const
758 {
759     if (d->object) {
760         return d->object->id;
761     } else {
762         return QString();
763     }
764 }
765
766 /*!
767     Returns the list of assigned properties on this object.
768
769     In the following example, "text" and "x" properties would be returned.
770     \qml
771 Text {
772     text: "Hello world!"
773     x: 100
774 }
775     \endqml
776 */
777 QList<QDeclarativeDomProperty> QDeclarativeDomObject::properties() const
778 {
779     QList<QDeclarativeDomProperty> rv;
780
781     if (!d->object || isComponent())
782         return rv;
783
784     QDeclarativeDomObjectPrivate::Properties properties = d->properties();
785     for (int ii = 0; ii < properties.count(); ++ii) {
786
787         QDeclarativeDomProperty domProperty;
788         domProperty.d->property = properties.at(ii).first;
789         domProperty.d->property->addref();
790         domProperty.d->propertyName = properties.at(ii).second;
791         rv << domProperty;
792
793     }
794
795     if (d->object->defaultProperty) {
796         QDeclarativeDomProperty domProperty;
797         domProperty.d->property = d->object->defaultProperty;
798         domProperty.d->property->addref();
799         domProperty.d->propertyName = d->object->defaultProperty->name;
800         rv << domProperty;
801     }
802
803     return rv;
804 }
805
806 /*!
807     Returns the object's \a name property if a value has been assigned to
808     it, or an invalid QDeclarativeDomProperty otherwise.
809
810     In the example below, \c {object.property("source")} would return a valid
811     QDeclarativeDomProperty, and \c {object.property("tile")} an invalid QDeclarativeDomProperty.
812
813     \qml
814 Image { source: "sample.jpg" }
815     \endqml
816 */
817 QDeclarativeDomProperty QDeclarativeDomObject::property(const QByteArray &name) const
818 {
819     QList<QDeclarativeDomProperty> props = properties();
820     for (int ii = 0; ii < props.count(); ++ii)
821         if (props.at(ii).propertyName() == name)
822             return props.at(ii);
823     return QDeclarativeDomProperty();
824 }
825
826 QList<QDeclarativeDomDynamicProperty> QDeclarativeDomObject::dynamicProperties() const
827 {
828     QList<QDeclarativeDomDynamicProperty> properties;
829
830     for (int i = 0; i < d->object->dynamicProperties.size(); ++i) {
831         QDeclarativeDomDynamicProperty p;
832         p.d = new QDeclarativeDomDynamicPropertyPrivate;
833         p.d->property = d->object->dynamicProperties.at(i);
834         p.d->valid = true;
835
836         if (p.d->property.defaultValue)
837             p.d->property.defaultValue->addref();
838
839         properties.append(p);
840     }
841
842     return properties;
843 }
844
845 QDeclarativeDomDynamicProperty QDeclarativeDomObject::dynamicProperty(const QByteArray &name) const
846 {
847     QDeclarativeDomDynamicProperty p;
848
849     if (!isValid())
850         return p;
851
852     for (int i = 0; i < d->object->dynamicProperties.size(); ++i) {
853         if (d->object->dynamicProperties.at(i).name == name) {
854             p.d = new QDeclarativeDomDynamicPropertyPrivate;
855             p.d->property = d->object->dynamicProperties.at(i);
856             if (p.d->property.defaultValue) p.d->property.defaultValue->addref();
857             p.d->valid = true;
858         }
859     }
860
861     return p;
862 }
863
864 /*!
865     Returns true if this object is a custom type.  Custom types are special
866     types that allow embeddeding non-QML data, such as SVG or HTML data,
867     directly into QML files.
868
869     \note Currently this method will always return false, and is a placekeeper
870     for future functionality.
871
872     \sa QDeclarativeDomObject::customTypeData()
873 */
874 bool QDeclarativeDomObject::isCustomType() const
875 {
876     return false;
877 }
878
879 /*!
880     If this object represents a custom type, returns the data associated with
881     the custom type, otherwise returns an empty QByteArray().
882     QDeclarativeDomObject::isCustomType() can be used to check if this object represents
883     a custom type.
884 */
885 QByteArray QDeclarativeDomObject::customTypeData() const
886 {
887     return QByteArray();
888 }
889
890 /*!
891     Returns true if this object is a sub-component object.  Sub-component
892     objects can be converted into QDeclarativeDomComponent instances by calling
893     QDeclarativeDomObject::toComponent().
894
895     \sa QDeclarativeDomObject::toComponent()
896 */
897 bool QDeclarativeDomObject::isComponent() const
898 {
899     return (d->object && (d->object->typeName == "Qt/Component" || d->object->typeName == "QtQuick/Component"));
900 }
901
902 /*!
903     Returns a QDeclarativeDomComponent for this object if it is a sub-component, or
904     an invalid QDeclarativeDomComponent if not.  QDeclarativeDomObject::isComponent() can be used
905     to check if this object represents a sub-component.
906
907     \sa QDeclarativeDomObject::isComponent()
908 */
909 QDeclarativeDomComponent QDeclarativeDomObject::toComponent() const
910 {
911     QDeclarativeDomComponent rv;
912     if (isComponent())
913         rv.d = d;
914     return rv;
915 }
916
917 /*!
918     Returns the position in the input data where the property assignment started
919 , or -1 if the property is invalid.
920 */
921 int QDeclarativeDomObject::position() const
922 {
923     if (d && d->object)
924         return d->object->location.range.offset;
925     else
926         return -1;
927 }
928
929 /*!
930     Returns the length in the input data from where the property assignment star
931 ted upto the end of it, or -1 if the property is invalid.
932 */
933 int QDeclarativeDomObject::length() const
934 {
935     if (d && d->object)
936         return d->object->location.range.length;
937     else
938         return -1;
939 }
940
941 // Returns the URL of the type, if it is an external type, or an empty URL if
942 // not
943 QUrl QDeclarativeDomObject::url() const
944 {
945     if (d && d->object)
946         return d->object->url;
947     else
948         return QUrl();
949 }
950
951 QDeclarativeDomBasicValuePrivate::QDeclarativeDomBasicValuePrivate()
952 : value(0)
953 {
954 }
955
956 QDeclarativeDomBasicValuePrivate::~QDeclarativeDomBasicValuePrivate()
957 {
958     if (value) value->release();
959 }
960
961 /*!
962     \class QDeclarativeDomValueLiteral
963     \internal
964     \brief The QDeclarativeDomValueLiteral class represents a literal value.
965
966     A literal value is a simple value, written inline with the QML.  In the
967     example below, the "x", "y" and "color" properties are being assigned
968     literal values.
969
970     \qml
971 Rectangle {
972     x: 10
973     y: 10
974     color: "red"
975 }
976     \endqml
977 */
978
979 /*!
980     Construct an empty QDeclarativeDomValueLiteral.
981 */
982 QDeclarativeDomValueLiteral::QDeclarativeDomValueLiteral():
983     d(new QDeclarativeDomBasicValuePrivate)
984 {
985 }
986
987 /*!
988     Create a copy of \a other QDeclarativeDomValueLiteral.
989 */
990 QDeclarativeDomValueLiteral::QDeclarativeDomValueLiteral(const QDeclarativeDomValueLiteral &other)
991 : d(other.d)
992 {
993 }
994
995 /*!
996     Destroy the QDeclarativeDomValueLiteral.
997 */
998 QDeclarativeDomValueLiteral::~QDeclarativeDomValueLiteral()
999 {
1000 }
1001
1002 /*!
1003     Assign \a other to this QDeclarativeDomValueLiteral.
1004 */
1005 QDeclarativeDomValueLiteral &QDeclarativeDomValueLiteral::operator=(const QDeclarativeDomValueLiteral &other)
1006 {
1007     d = other.d;
1008     return *this;
1009 }
1010
1011 /*!
1012     Return the literal value.
1013
1014     In the example below, the literal value will be the string "10".
1015     \qml
1016 Rectangle { x: 10 }
1017     \endqml
1018 */
1019 QString QDeclarativeDomValueLiteral::literal() const
1020 {
1021     if (d->value) return d->value->primitive();
1022     else return QString();
1023 }
1024
1025 /*!
1026     \class QDeclarativeDomValueBinding
1027     \internal
1028     \brief The QDeclarativeDomValueBinding class represents a property binding.
1029
1030     A property binding is an ECMAScript expression assigned to a property.  In
1031     the example below, the "x" property is being assigned a property binding.
1032
1033     \qml
1034 Rectangle { x: Other.x }
1035     \endqml
1036 */
1037
1038 /*!
1039     Construct an empty QDeclarativeDomValueBinding.
1040 */
1041 QDeclarativeDomValueBinding::QDeclarativeDomValueBinding():
1042         d(new QDeclarativeDomBasicValuePrivate)
1043 {
1044 }
1045
1046 /*!
1047     Create a copy of \a other QDeclarativeDomValueBinding.
1048 */
1049 QDeclarativeDomValueBinding::QDeclarativeDomValueBinding(const QDeclarativeDomValueBinding &other)
1050 : d(other.d)
1051 {
1052 }
1053
1054 /*!
1055     Destroy the QDeclarativeDomValueBinding.
1056 */
1057 QDeclarativeDomValueBinding::~QDeclarativeDomValueBinding()
1058 {
1059 }
1060
1061 /*!
1062     Assign \a other to this QDeclarativeDomValueBinding.
1063 */
1064 QDeclarativeDomValueBinding &QDeclarativeDomValueBinding::operator=(const QDeclarativeDomValueBinding &other)
1065 {
1066     d = other.d;
1067     return *this;
1068 }
1069
1070 /*!
1071     Return the binding expression.
1072
1073     In the example below, the string "Other.x" will be returned.
1074     \qml
1075 Rectangle { x: Other.x }
1076     \endqml
1077 */
1078 QString QDeclarativeDomValueBinding::binding() const
1079 {
1080     if (d->value)
1081         return d->value->value.asScript();
1082     else
1083         return QString();
1084 }
1085
1086 /*!
1087     \class QDeclarativeDomValueValueSource
1088     \internal
1089     \brief The QDeclarativeDomValueValueSource class represents a value source assignment value.
1090
1091     In QML, value sources are special value generating types that may be
1092     assigned to properties.  Value sources inherit the QDeclarativePropertyValueSource
1093     class.  In the example below, the "x" property is being assigned the
1094     NumberAnimation value source.
1095
1096     \qml
1097 Rectangle {
1098     x: NumberAnimation {
1099         from: 0
1100         to: 100
1101         loops: Animation.Infinite
1102     }
1103 }
1104     \endqml
1105 */
1106
1107 /*!
1108     Construct an empty QDeclarativeDomValueValueSource.
1109 */
1110 QDeclarativeDomValueValueSource::QDeclarativeDomValueValueSource():
1111         d(new QDeclarativeDomBasicValuePrivate)
1112 {
1113 }
1114
1115 /*!
1116     Create a copy of \a other QDeclarativeDomValueValueSource.
1117 */
1118 QDeclarativeDomValueValueSource::QDeclarativeDomValueValueSource(const QDeclarativeDomValueValueSource &other)
1119 : d(other.d)
1120 {
1121 }
1122
1123 /*!
1124     Destroy the QDeclarativeDomValueValueSource.
1125 */
1126 QDeclarativeDomValueValueSource::~QDeclarativeDomValueValueSource()
1127 {
1128 }
1129
1130 /*!
1131     Assign \a other to this QDeclarativeDomValueValueSource.
1132 */
1133 QDeclarativeDomValueValueSource &QDeclarativeDomValueValueSource::operator=(const QDeclarativeDomValueValueSource &other)
1134 {
1135     d = other.d;
1136     return *this;
1137 }
1138
1139 /*!
1140     Return the value source object.
1141
1142     In the example below, an object representing the NumberAnimation will be
1143     returned.
1144     \qml
1145 Rectangle {
1146     x: NumberAnimation {
1147         from: 0
1148         to: 100
1149         loops: Animation.Infinite
1150     }
1151 }
1152     \endqml
1153 */
1154 QDeclarativeDomObject QDeclarativeDomValueValueSource::object() const
1155 {
1156     QDeclarativeDomObject rv;
1157     if (d->value) {
1158         rv.d->object = d->value->object;
1159         rv.d->object->addref();
1160     }
1161     return rv;
1162 }
1163
1164 /*!
1165     \class QDeclarativeDomValueValueInterceptor
1166     \internal
1167     \brief The QDeclarativeDomValueValueInterceptor class represents a value interceptor assignment value.
1168
1169     In QML, value interceptor are special write-intercepting types that may be
1170     assigned to properties.  Value interceptor inherit the QDeclarativePropertyValueInterceptor
1171     class.  In the example below, the "x" property is being assigned the
1172     Behavior value interceptor.
1173
1174     \qml
1175 Rectangle {
1176     Behavior on x { NumberAnimation { duration: 500 } }
1177 }
1178     \endqml
1179 */
1180
1181 /*!
1182     Construct an empty QDeclarativeDomValueValueInterceptor.
1183 */
1184 QDeclarativeDomValueValueInterceptor::QDeclarativeDomValueValueInterceptor():
1185         d(new QDeclarativeDomBasicValuePrivate)
1186 {
1187 }
1188
1189 /*!
1190     Create a copy of \a other QDeclarativeDomValueValueInterceptor.
1191 */
1192 QDeclarativeDomValueValueInterceptor::QDeclarativeDomValueValueInterceptor(const QDeclarativeDomValueValueInterceptor &other)
1193 : d(other.d)
1194 {
1195 }
1196
1197 /*!
1198     Destroy the QDeclarativeDomValueValueInterceptor.
1199 */
1200 QDeclarativeDomValueValueInterceptor::~QDeclarativeDomValueValueInterceptor()
1201 {
1202 }
1203
1204 /*!
1205     Assign \a other to this QDeclarativeDomValueValueInterceptor.
1206 */
1207 QDeclarativeDomValueValueInterceptor &QDeclarativeDomValueValueInterceptor::operator=(const QDeclarativeDomValueValueInterceptor &other)
1208 {
1209     d = other.d;
1210     return *this;
1211 }
1212
1213 /*!
1214     Return the value interceptor object.
1215
1216     In the example below, an object representing the Behavior will be
1217     returned.
1218     \qml
1219 Rectangle {
1220     Behavior on x { NumberAnimation { duration: 500 } }
1221 }
1222     \endqml
1223 */
1224 QDeclarativeDomObject QDeclarativeDomValueValueInterceptor::object() const
1225 {
1226     QDeclarativeDomObject rv;
1227     if (d->value) {
1228         rv.d->object = d->value->object;
1229         rv.d->object->addref();
1230     }
1231     return rv;
1232 }
1233
1234 QDeclarativeDomValuePrivate::QDeclarativeDomValuePrivate()
1235 : property(0), value(0)
1236 {
1237 }
1238
1239 QDeclarativeDomValuePrivate::~QDeclarativeDomValuePrivate()
1240 {
1241     if (property) property->release();
1242     if (value) value->release();
1243 }
1244
1245 /*!
1246     \class QDeclarativeDomValue
1247     \internal
1248     \brief The QDeclarativeDomValue class represents a generic Qml value.
1249
1250     QDeclarativeDomValue's can be assigned to QML \l {QDeclarativeDomProperty}{properties}.  In
1251     QML, properties can be assigned various different values, including basic
1252     literals, property bindings, property value sources, objects and lists of
1253     values.  The QDeclarativeDomValue class allows a programmer to determine the specific
1254     value type being assigned and access more detailed information through a
1255     corresponding value type class.
1256
1257     For example, in the following example,
1258
1259     \qml
1260 Text {
1261     text: "Hello World!"
1262     y: Other.y
1263 }
1264     \endqml
1265
1266     The text property is being assigned a literal, and the y property a property
1267     binding.  To output the values assigned to the text and y properties in the
1268     above example from C++,
1269
1270     \code
1271     QDeclarativeDomDocument document;
1272     QDeclarativeDomObject root = document.rootObject();
1273
1274     QDeclarativeDomProperty text = root.property("text");
1275     if (text.value().isLiteral()) {
1276         QDeclarativeDomValueLiteral literal = text.value().toLiteral();
1277         qDebug() << literal.literal();
1278     }
1279
1280     QDeclarativeDomProperty y = root.property("y");
1281     if (y.value().isBinding()) {
1282         QDeclarativeDomValueBinding binding = y.value().toBinding();
1283         qDebug() << binding.binding();
1284     }
1285     \endcode
1286 */
1287
1288 /*!
1289     Construct an invalid QDeclarativeDomValue.
1290 */
1291 QDeclarativeDomValue::QDeclarativeDomValue()
1292 : d(new QDeclarativeDomValuePrivate)
1293 {
1294 }
1295
1296 /*!
1297     Create a copy of \a other QDeclarativeDomValue.
1298 */
1299 QDeclarativeDomValue::QDeclarativeDomValue(const QDeclarativeDomValue &other)
1300 : d(other.d)
1301 {
1302 }
1303
1304 /*!
1305     Destroy the QDeclarativeDomValue
1306 */
1307 QDeclarativeDomValue::~QDeclarativeDomValue()
1308 {
1309 }
1310
1311 /*!
1312     Assign \a other to this QDeclarativeDomValue.
1313 */
1314 QDeclarativeDomValue &QDeclarativeDomValue::operator=(const QDeclarativeDomValue &other)
1315 {
1316     d = other.d;
1317     return *this;
1318 }
1319
1320 /*!
1321     \enum QDeclarativeDomValue::Type
1322
1323     The type of the QDeclarativeDomValue node.
1324
1325     \value Invalid The QDeclarativeDomValue is invalid.
1326     \value Literal The QDeclarativeDomValue is a literal value assignment.  Use QDeclarativeDomValue::toLiteral() to access the type instance.
1327     \value PropertyBinding The QDeclarativeDomValue is a property binding.  Use QDeclarativeDomValue::toBinding() to access the type instance.
1328     \value ValueSource The QDeclarativeDomValue is a property value source.  Use QDeclarativeDomValue::toValueSource() to access the type instance.
1329     \value ValueInterceptor The QDeclarativeDomValue is a property value interceptor.  Use QDeclarativeDomValue::toValueInterceptor() to access the type instance.
1330     \value Object The QDeclarativeDomValue is an object assignment.  Use QDeclarativeDomValue::toObject() to access the type instnace.
1331     \value List The QDeclarativeDomValue is a list of other values.  Use QDeclarativeDomValue::toList() to access the type instance.
1332 */
1333
1334 /*!
1335     Returns the type of this QDeclarativeDomValue.
1336 */
1337 QDeclarativeDomValue::Type QDeclarativeDomValue::type() const
1338 {
1339     if (d->property)
1340         if (QDeclarativeMetaType::isList(d->property->type) ||
1341            (d->property && (d->property->values.count() + d->property->onValues.count()) > 1))
1342             return List;
1343
1344     QDeclarativeParser::Value *value = d->value;
1345     if (!value && !d->property)
1346         return Invalid;
1347
1348     switch(value->type) {
1349     case QDeclarativeParser::Value::Unknown:
1350         return Invalid;
1351     case QDeclarativeParser::Value::Literal:
1352         return Literal;
1353     case QDeclarativeParser::Value::PropertyBinding:
1354         return PropertyBinding;
1355     case QDeclarativeParser::Value::ValueSource:
1356         return ValueSource;
1357     case QDeclarativeParser::Value::ValueInterceptor:
1358         return ValueInterceptor;
1359     case QDeclarativeParser::Value::CreatedObject:
1360         return Object;
1361     case QDeclarativeParser::Value::SignalObject:
1362         return Invalid;
1363     case QDeclarativeParser::Value::SignalExpression:
1364         return Literal;
1365     case QDeclarativeParser::Value::Id:
1366         return Literal;
1367     }
1368     return Invalid;
1369 }
1370
1371 /*!
1372     Returns true if this is an invalid value, otherwise false.
1373 */
1374 bool QDeclarativeDomValue::isInvalid() const
1375 {
1376     return type() == Invalid;
1377 }
1378
1379 /*!
1380     Returns true if this is a literal value, otherwise false.
1381 */
1382 bool QDeclarativeDomValue::isLiteral() const
1383 {
1384     return type() == Literal;
1385 }
1386
1387 /*!
1388     Returns true if this is a property binding value, otherwise false.
1389 */
1390 bool QDeclarativeDomValue::isBinding() const
1391 {
1392     return type() == PropertyBinding;
1393 }
1394
1395 /*!
1396     Returns true if this is a value source value, otherwise false.
1397 */
1398 bool QDeclarativeDomValue::isValueSource() const
1399 {
1400     return type() == ValueSource;
1401 }
1402
1403 /*!
1404     Returns true if this is a value interceptor value, otherwise false.
1405 */
1406 bool QDeclarativeDomValue::isValueInterceptor() const
1407 {
1408     return type() == ValueInterceptor;
1409 }
1410
1411 /*!
1412     Returns true if this is an object value, otherwise false.
1413 */
1414 bool QDeclarativeDomValue::isObject() const
1415 {
1416     return type() == Object;
1417 }
1418
1419 /*!
1420     Returns true if this is a list value, otherwise false.
1421 */
1422 bool QDeclarativeDomValue::isList() const
1423 {
1424     return type() == List;
1425 }
1426
1427 /*!
1428     Returns a QDeclarativeDomValueLiteral if this value is a literal type, otherwise
1429     returns an invalid QDeclarativeDomValueLiteral.
1430
1431     \sa QDeclarativeDomValue::type()
1432 */
1433 QDeclarativeDomValueLiteral QDeclarativeDomValue::toLiteral() const
1434 {
1435     QDeclarativeDomValueLiteral rv;
1436     if (type() == Literal) {
1437         rv.d->value = d->value;
1438         rv.d->value->addref();
1439     }
1440     return rv;
1441 }
1442
1443 /*!
1444     Returns a QDeclarativeDomValueBinding if this value is a property binding type,
1445     otherwise returns an invalid QDeclarativeDomValueBinding.
1446
1447     \sa QDeclarativeDomValue::type()
1448 */
1449 QDeclarativeDomValueBinding QDeclarativeDomValue::toBinding() const
1450 {
1451     QDeclarativeDomValueBinding rv;
1452     if (type() == PropertyBinding) {
1453         rv.d->value = d->value;
1454         rv.d->value->addref();
1455     }
1456     return rv;
1457 }
1458
1459 /*!
1460     Returns a QDeclarativeDomValueValueSource if this value is a property value source
1461     type, otherwise returns an invalid QDeclarativeDomValueValueSource.
1462
1463     \sa QDeclarativeDomValue::type()
1464 */
1465 QDeclarativeDomValueValueSource QDeclarativeDomValue::toValueSource() const
1466 {
1467     QDeclarativeDomValueValueSource rv;
1468     if (type() == ValueSource) {
1469         rv.d->value = d->value;
1470         rv.d->value->addref();
1471     }
1472     return rv;
1473 }
1474
1475 /*!
1476     Returns a QDeclarativeDomValueValueInterceptor if this value is a property value interceptor
1477     type, otherwise returns an invalid QDeclarativeDomValueValueInterceptor.
1478
1479     \sa QDeclarativeDomValue::type()
1480 */
1481 QDeclarativeDomValueValueInterceptor QDeclarativeDomValue::toValueInterceptor() const
1482 {
1483     QDeclarativeDomValueValueInterceptor rv;
1484     if (type() == ValueInterceptor) {
1485         rv.d->value = d->value;
1486         rv.d->value->addref();
1487     }
1488     return rv;
1489 }
1490
1491 /*!
1492     Returns a QDeclarativeDomObject if this value is an object assignment type, otherwise
1493     returns an invalid QDeclarativeDomObject.
1494
1495     \sa QDeclarativeDomValue::type()
1496 */
1497 QDeclarativeDomObject QDeclarativeDomValue::toObject() const
1498 {
1499     QDeclarativeDomObject rv;
1500     if (type() == Object) {
1501         rv.d->object = d->value->object;
1502         rv.d->object->addref();
1503     }
1504     return rv;
1505 }
1506
1507 /*!
1508     Returns a QDeclarativeDomList if this value is a list type, otherwise returns an
1509     invalid QDeclarativeDomList.
1510
1511     \sa QDeclarativeDomValue::type()
1512 */
1513 QDeclarativeDomList QDeclarativeDomValue::toList() const
1514 {
1515     QDeclarativeDomList rv;
1516     if (type() == List) {
1517         rv.d = d;
1518     }
1519     return rv;
1520 }
1521
1522 /*!
1523     Returns the position in the input data where the property value startd, or -1
1524  if the value is invalid.
1525 */
1526 int QDeclarativeDomValue::position() const
1527 {
1528     if (type() == Invalid)
1529         return -1;
1530     else
1531         return d->value->location.range.offset;
1532 }
1533
1534 /*!
1535     Returns the length in the input data from where the property value started u
1536 pto the end of it, or -1 if the value is invalid.
1537 */
1538 int QDeclarativeDomValue::length() const
1539 {
1540     if (type() == Invalid)
1541         return -1;
1542     else
1543         return d->value->location.range.length;
1544 }
1545
1546 /*!
1547     \class QDeclarativeDomList
1548     \internal
1549     \brief The QDeclarativeDomList class represents a list of values assigned to a QML property.
1550
1551     Lists of values can be assigned to properties.  For example, the following
1552     example assigns multiple objects to Item's "children" property
1553     \qml
1554 Item {
1555     children: [
1556         Text { },
1557         Rectangle { }
1558     ]
1559 }
1560     \endqml
1561
1562     Lists can also be implicitly created by assigning multiple
1563     \l {QDeclarativeDomValueValueSource}{value sources} or constants to a property.
1564     \qml
1565 Item {
1566     x: 10
1567     x: NumberAnimation {
1568         running: false
1569         from: 0
1570         to: 100
1571     }
1572 }
1573     \endqml
1574 */
1575
1576 /*!
1577     Construct an empty QDeclarativeDomList.
1578 */
1579 QDeclarativeDomList::QDeclarativeDomList()
1580 {
1581 }
1582
1583 /*!
1584     Create a copy of \a other QDeclarativeDomList.
1585 */
1586 QDeclarativeDomList::QDeclarativeDomList(const QDeclarativeDomList &other)
1587 : d(other.d)
1588 {
1589 }
1590
1591 /*!
1592     Destroy the QDeclarativeDomList.
1593 */
1594 QDeclarativeDomList::~QDeclarativeDomList()
1595 {
1596 }
1597
1598 /*!
1599     Assign \a other to this QDeclarativeDomList.
1600 */
1601 QDeclarativeDomList &QDeclarativeDomList::operator=(const QDeclarativeDomList &other)
1602 {
1603     d = other.d;
1604     return *this;
1605 }
1606
1607 /*!
1608     Returns the list of QDeclarativeDomValue's.
1609 */
1610 QList<QDeclarativeDomValue> QDeclarativeDomList::values() const
1611 {
1612     QList<QDeclarativeDomValue> rv;
1613     if (!d->property)
1614         return rv;
1615
1616     for (int ii = 0; ii < d->property->values.count(); ++ii) {
1617         QDeclarativeDomValue v;
1618         v.d->value = d->property->values.at(ii);
1619         v.d->value->addref();
1620         rv << v;
1621     }
1622
1623     for (int ii = 0; ii < d->property->onValues.count(); ++ii) {
1624         QDeclarativeDomValue v;
1625         v.d->value = d->property->onValues.at(ii);
1626         v.d->value->addref();
1627         rv << v;
1628     }
1629
1630     return rv;
1631 }
1632
1633 /*!
1634     Returns the position in the input data where the list started, or -1 if
1635  the property is invalid.
1636 */
1637 int QDeclarativeDomList::position() const
1638 {
1639     if (d && d->property) {
1640         return d->property->listValueRange.offset;
1641     } else
1642         return -1;
1643 }
1644
1645 /*!
1646     Returns the length in the input data from where the list started upto
1647  the end of it, or 0 if the property is invalid.
1648 */
1649 int QDeclarativeDomList::length() const
1650 {
1651     if (d && d->property)
1652         return d->property->listValueRange.length;
1653     else
1654         return -1;
1655 }
1656
1657 /*!
1658   Returns a list of positions of the commas in the QML file.
1659 */
1660 QList<int> QDeclarativeDomList:: commaPositions() const
1661 {
1662     if (d && d->property)
1663         return d->property->listCommaPositions;
1664     else
1665         return QList<int>();
1666 }
1667
1668 /*!
1669     \class QDeclarativeDomComponent
1670     \internal
1671     \brief The QDeclarativeDomComponent class represents sub-component within a QML document.
1672
1673     Sub-components are QDeclarativeComponents defined within a QML document.  The
1674     following example shows the definition of a sub-component with the id
1675     "listDelegate".
1676
1677     \qml
1678 Item {
1679     Component {
1680         id: listDelegate
1681         Text {
1682             text: modelData.text
1683         }
1684     }
1685 }
1686     \endqml
1687
1688     Like QDeclarativeDomDocument's, components contain a single root object.
1689 */
1690
1691 /*!
1692     Construct an empty QDeclarativeDomComponent.
1693 */
1694 QDeclarativeDomComponent::QDeclarativeDomComponent()
1695 {
1696 }
1697
1698 /*!
1699     Create a copy of \a other QDeclarativeDomComponent.
1700 */
1701 QDeclarativeDomComponent::QDeclarativeDomComponent(const QDeclarativeDomComponent &other)
1702 : QDeclarativeDomObject(other)
1703 {
1704 }
1705
1706 /*!
1707     Destroy the QDeclarativeDomComponent.
1708 */
1709 QDeclarativeDomComponent::~QDeclarativeDomComponent()
1710 {
1711 }
1712
1713 /*!
1714     Assign \a other to this QDeclarativeDomComponent.
1715 */
1716 QDeclarativeDomComponent &QDeclarativeDomComponent::operator=(const QDeclarativeDomComponent &other)
1717 {
1718     static_cast<QDeclarativeDomObject &>(*this) = other;
1719     return *this;
1720 }
1721
1722 /*!
1723     Returns the component's root object.
1724
1725     In the example below, the root object is the "Text" object.
1726     \qml
1727 Item {
1728     Component {
1729         id: listDelegate
1730         Text {
1731             text: modelData.text
1732         }
1733     }
1734 }
1735     \endqml
1736 */
1737 QDeclarativeDomObject QDeclarativeDomComponent::componentRoot() const
1738 {
1739     QDeclarativeDomObject rv;
1740     if (d->object) {
1741         QDeclarativeParser::Object *obj = 0;
1742         if (d->object->defaultProperty &&
1743            d->object->defaultProperty->values.count() == 1 &&
1744            d->object->defaultProperty->values.at(0)->object)
1745             obj = d->object->defaultProperty->values.at(0)->object;
1746
1747         if (obj) {
1748             rv.d->object = obj;
1749             rv.d->object->addref();
1750         }
1751     }
1752
1753     return rv;
1754 }
1755
1756 QDeclarativeDomImportPrivate::QDeclarativeDomImportPrivate()
1757 : type(File)
1758 {
1759 }
1760
1761 QDeclarativeDomImportPrivate::~QDeclarativeDomImportPrivate()
1762 {
1763 }
1764
1765 /*!
1766     \class QDeclarativeDomImport
1767     \internal
1768     \brief The QDeclarativeDomImport class represents an import statement.
1769 */
1770
1771 /*!
1772     Construct an empty QDeclarativeDomImport.
1773 */
1774 QDeclarativeDomImport::QDeclarativeDomImport()
1775 : d(new QDeclarativeDomImportPrivate)
1776 {
1777 }
1778
1779 /*!
1780     Create a copy of \a other QDeclarativeDomImport.
1781 */
1782 QDeclarativeDomImport::QDeclarativeDomImport(const QDeclarativeDomImport &other)
1783 : d(other.d)
1784 {
1785 }
1786
1787 /*!
1788     Destroy the QDeclarativeDomImport.
1789 */
1790 QDeclarativeDomImport::~QDeclarativeDomImport()
1791 {
1792 }
1793
1794 /*!
1795     Assign \a other to this QDeclarativeDomImport.
1796 */
1797 QDeclarativeDomImport &QDeclarativeDomImport::operator=(const QDeclarativeDomImport &other)
1798 {
1799     d = other.d;
1800     return *this;
1801 }
1802
1803 /*!
1804   Returns the type of the import.
1805   */
1806 QDeclarativeDomImport::Type QDeclarativeDomImport::type() const
1807 {
1808     return static_cast<QDeclarativeDomImport::Type>(d->type);
1809 }
1810
1811 /*!
1812   Returns the URI of the import (e.g. 'subdir' or 'com.nokia.Qt')
1813   */
1814 QString QDeclarativeDomImport::uri() const
1815 {
1816     return d->uri;
1817 }
1818
1819 /*!
1820   Returns the version specified by the import. An empty string if no version was specified.
1821   */
1822 QString QDeclarativeDomImport::version() const
1823 {
1824     return d->version;
1825 }
1826
1827 /*!
1828   Returns the (optional) qualifier string (the token following the 'as' keyword) of the import.
1829   */
1830 QString QDeclarativeDomImport::qualifier() const
1831 {
1832     return d->qualifier;
1833 }
1834
1835 QT_END_NAMESPACE