QDeclarativeContextData::QDeclarativeContextData()
: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
- isPragmaLibraryContext(false), publicContext(0), activeVMEData(0), propertyNames(0), contextObject(0),
- imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
- contextGuards(0), idValues(0), idValueCount(0), linkedContext(0), componentAttached(0),
- v4bindings(0), v8bindings(0)
+ isPragmaLibraryContext(false), unresolvedNames(false), publicContext(0), activeVMEData(0),
+ propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
+ expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
+ componentAttached(0), v4bindings(0), v8bindings(0)
{
}
QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
- isPragmaLibraryContext(false), publicContext(ctxt), activeVMEData(0), propertyNames(0),
- contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0),
- contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
+ isPragmaLibraryContext(false), unresolvedNames(false), publicContext(ctxt), activeVMEData(0),
+ propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
+ expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
componentAttached(0), v4bindings(0), v8bindings(0)
{
}
expression->refresh();
}
-void QDeclarativeContextData::refreshExpressionsRecursive()
+static inline bool expressions_to_run(QDeclarativeContextData *ctxt, bool isGlobalRefresh)
+{
+ return ctxt->expressions && (!isGlobalRefresh || ctxt->unresolvedNames);
+}
+
+void QDeclarativeContextData::refreshExpressionsRecursive(bool isGlobal)
{
// For efficiency, we try and minimize the number of guards we have to create
- if (expressions && (nextChild || childContexts)) {
+ if (expressions_to_run(this, isGlobal) && (nextChild || childContexts)) {
QDeclarativeGuardedContextData guard(this);
if (childContexts)
- childContexts->refreshExpressionsRecursive();
+ childContexts->refreshExpressionsRecursive(isGlobal);
if (guard.isNull()) return;
if (nextChild)
- nextChild->refreshExpressionsRecursive();
+ nextChild->refreshExpressionsRecursive(isGlobal);
if (guard.isNull()) return;
- if (expressions)
+ if (expressions_to_run(this, isGlobal))
refreshExpressionsRecursive(expressions);
- } else if (expressions) {
+ } else if (expressions_to_run(this, isGlobal)) {
refreshExpressionsRecursive(expressions);
QDeclarativeGuardedContextData guard(this);
- childContexts->refreshExpressionsRecursive();
+ childContexts->refreshExpressionsRecursive(isGlobal);
if (!guard.isNull() && nextChild)
- nextChild->refreshExpressionsRecursive();
+ nextChild->refreshExpressionsRecursive(isGlobal);
} else if (nextChild) {
- nextChild->refreshExpressionsRecursive();
+ nextChild->refreshExpressionsRecursive(isGlobal);
} else if (childContexts) {
- childContexts->refreshExpressionsRecursive();
+ childContexts->refreshExpressionsRecursive(isGlobal);
}
}
// *structure* (not values) changes.
void QDeclarativeContextData::refreshExpressions()
{
+ bool isGlobal = (parent == 0);
+
// For efficiency, we try and minimize the number of guards we have to create
- if (expressions && childContexts) {
+ if (expressions_to_run(this, isGlobal) && childContexts) {
QDeclarativeGuardedContextData guard(this);
- childContexts->refreshExpressionsRecursive();
+ childContexts->refreshExpressionsRecursive(isGlobal);
- if (!guard.isNull() && expressions)
+ if (!guard.isNull() && expressions_to_run(this, isGlobal))
refreshExpressionsRecursive(expressions);
- } else if (expressions) {
+ } else if (expressions_to_run(this, isGlobal)) {
refreshExpressionsRecursive(expressions);
} else if (childContexts) {
- childContexts->refreshExpressionsRecursive();
+ childContexts->refreshExpressionsRecursive(isGlobal);
}
}
void refreshExpressions();
void refreshExpressionsCrash();
+ void refreshExpressionsRootContext();
private:
QDeclarativeEngine engine;
delete o1;
}
+// Test that updating the root context, only causes expressions in contexts with an
+// unresolved name to reevaluate
+void tst_qdeclarativecontext::refreshExpressionsRootContext()
+{
+ QDeclarativeEngine engine;
+
+ CountCommand command;
+ engine.rootContext()->setContextProperty("countCommand", &command);
+
+ QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
+ QDeclarativeComponent component2(&engine, TEST_FILE("refreshExpressionsRootContext.qml"));
+
+ QDeclarativeContext context(engine.rootContext());
+ QDeclarativeContext context2(engine.rootContext());
+
+ QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: Can't find variable: unresolvedName");
+
+ QObject *o1 = component.create(&context);
+
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+ QObject *o2 = component2.create(&context2);
+
+ QCOMPARE(command.count, 3);
+
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+ QDeclarativeContextData::get(engine.rootContext())->refreshExpressions();
+
+ QCOMPARE(command.count, 4);
+
+ delete o2;
+ delete o1;
+}
+
QTEST_MAIN(tst_qdeclarativecontext)
#include "tst_qdeclarativecontext.moc"