1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtSCriptTools module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
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.
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.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qscriptobjectsnapshot_p.h"
44 #include <QtCore/qmap.h>
45 #include <QtCore/qset.h>
46 #include <QtCore/qvector.h>
47 #include <QtCore/qnumeric.h>
48 #include <QtScript/qscriptvalueiterator.h>
52 QScriptObjectSnapshot::QScriptObjectSnapshot()
56 QScriptObjectSnapshot::~QScriptObjectSnapshot()
60 static bool _q_equal(const QScriptValue
&v1
, const QScriptValue
&v2
)
62 if (v1
.strictlyEquals(v2
))
64 if (v1
.isNumber() && v2
.isNumber() && qIsNaN(v1
.toNumber()) && qIsNaN(v2
.toNumber()))
69 QScriptObjectSnapshot::Delta
QScriptObjectSnapshot::capture(const QScriptValue
&object
)
72 QMap
<QString
, QScriptValueProperty
> currProps
;
73 QHash
<QString
, int> propertyNameToIndex
;
76 QScriptValueIterator
it(object
);
77 while (it
.hasNext()) {
79 QScriptValueProperty
prop(it
.name(), it
.value(), it
.flags());
80 currProps
.insert(it
.name(), prop
);
81 propertyNameToIndex
.insert(it
.name(), i
);
84 if (object
.prototype().isValid()) {
85 QString __proto__
= QString::fromLatin1("__proto__");
86 QScriptValueProperty
protoProp(
87 __proto__
, object
.prototype(),
88 QScriptValue::Undeletable
| QScriptValue::ReadOnly
);
89 currProps
.insert(__proto__
, protoProp
);
90 propertyNameToIndex
.insert(__proto__
, i
);
95 QSet
<QString
> prevSet
;
96 for (int i
= 0; i
< m_properties
.size(); ++i
)
97 prevSet
.insert(m_properties
.at(i
).name());
98 QSet
<QString
> currSet
= currProps
.keys().toSet();
99 QSet
<QString
> removedProperties
= prevSet
- currSet
;
100 QSet
<QString
> addedProperties
= currSet
- prevSet
;
101 QSet
<QString
> maybeChangedProperties
= currSet
& prevSet
;
104 QMap
<int, QScriptValueProperty
> am
;
105 QSet
<QString
>::const_iterator it
;
106 for (it
= addedProperties
.constBegin(); it
!= addedProperties
.constEnd(); ++it
) {
107 int idx
= propertyNameToIndex
[*it
];
108 am
[idx
] = currProps
[*it
];
110 result
.addedProperties
= am
.values();
114 QSet
<QString
>::const_iterator it
;
115 for (it
= maybeChangedProperties
.constBegin(); it
!= maybeChangedProperties
.constEnd(); ++it
) {
116 const QScriptValueProperty
&p1
= currProps
[*it
];
117 const QScriptValueProperty
&p2
= findProperty(*it
);
118 if (!_q_equal(p1
.value(), p2
.value())
119 || (p1
.flags() != p2
.flags())) {
120 result
.changedProperties
.append(p1
);
125 result
.removedProperties
= removedProperties
.toList();
127 m_properties
= currProps
.values();
132 QScriptValueProperty
QScriptObjectSnapshot::findProperty(const QString
&name
) const
134 for (int i
= 0; i
< m_properties
.size(); ++i
) {
135 if (m_properties
.at(i
).name() == name
)
136 return m_properties
.at(i
);
138 return QScriptValueProperty();
141 QScriptValuePropertyList
QScriptObjectSnapshot::properties() const