aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/imports.pro5
-rw-r--r--src/imports/layouts/qquicklayout_p.h2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp19
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp15
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp2
-rw-r--r--src/qml/jsruntime/qv4promiseobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4proxy.cpp24
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp3
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp35
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp6
-rw-r--r--src/qmlmodels/qqmldelegatecomponent.cpp8
-rw-r--r--src/qmlmodels/qqmllistmodel.cpp8
-rw-r--r--src/qmltest/quicktestresult.cpp14
-rw-r--r--src/quick/configure.json2
-rw-r--r--src/quick/doc/images/declarative-textformat.pngbin11498 -> 8301 bytes
-rw-r--r--src/quick/doc/snippets/qml/text/textEditFormats.qml76
-rw-r--r--src/quick/doc/snippets/qml/text/textFormats.qml75
-rw-r--r--src/quick/doc/snippets/qml/xmlrole.xml20
-rw-r--r--src/quick/items/qquicktext.cpp61
-rw-r--r--src/quick/items/qquicktextedit.cpp59
-rw-r--r--src/quickshapes/qquickshapegenericrenderer_p.h1
28 files changed, 326 insertions, 139 deletions
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 9973883024..e0f66838ec 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -20,8 +20,9 @@ qtHaveModule(quick) {
labsanimation \
layouts \
qtquick2 \
- window \
- wavefrontmesh
+ window
+
+ qtConfig(quick-shadereffect): SUBDIRS += wavefrontmesh
qtHaveModule(testlib): SUBDIRS += testlib
qtConfig(systemsemaphore): SUBDIRS += sharedimage
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index b31bffa290..3f076c7304 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -131,7 +131,7 @@ class QQuickLayoutPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickLayout)
public:
- QQuickLayoutPrivate() : m_isReady(false), m_disableRearrange(true) {}
+ QQuickLayoutPrivate() : m_isReady(false), m_disableRearrange(true), m_hasItemChangeListeners(false) {}
protected:
unsigned m_isReady : 1;
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 7b38bf34b1..e6f6fd1b7a 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -362,7 +362,7 @@ ReturnedValue ArrayPrototype::method_toString(const FunctionObject *builtin, con
ScopedString string(scope, scope.engine->newString(QStringLiteral("join")));
ScopedFunctionObject f(scope, that->get(string));
if (f)
- return f->call(that, argv, argc);
+ return checkedResult(scope.engine, f->call(that, argv, argc));
return ObjectPrototype::method_toString(builtin, that, argv, argc);
}
@@ -1211,6 +1211,7 @@ ReturnedValue ArrayPrototype::method_every(const FunctionObject *b, const Value
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
r = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
ok = r->toBoolean();
}
return Encode(ok);
@@ -1278,6 +1279,7 @@ ReturnedValue ArrayPrototype::method_some(const FunctionObject *b, const Value *
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
result = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
if (result->toBoolean())
return Encode(true);
}
@@ -1347,6 +1349,7 @@ ReturnedValue ArrayPrototype::method_map(const FunctionObject *b, const Value *t
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
mapped = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
a->arraySet(k, mapped);
}
return a.asReturnedValue();
@@ -1382,6 +1385,7 @@ ReturnedValue ArrayPrototype::method_filter(const FunctionObject *b, const Value
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
selected = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
if (selected->toBoolean()) {
a->arraySet(to, arguments[0]);
++to;
@@ -1432,6 +1436,7 @@ ReturnedValue ArrayPrototype::method_reduce(const FunctionObject *b, const Value
arguments[2] = Value::fromDouble(k);
arguments[3] = instance;
acc = callback->call(nullptr, arguments, 4);
+ CHECK_EXCEPTION();
}
++k;
}
@@ -1485,6 +1490,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(const FunctionObject *b, const
arguments[2] = Value::fromDouble(k - 1);
arguments[3] = instance;
acc = callback->call(nullptr, arguments, 4);
+ CHECK_EXCEPTION();
}
--k;
}
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index cc89947cec..c2f48ffeac 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -1561,7 +1561,7 @@ ReturnedValue DatePrototype::method_toJSON(const FunctionObject *b, const Value
if (!toIso)
return v4->throwTypeError();
- return toIso->call(O, nullptr, 0);
+ return checkedResult(v4, toIso->call(O, nullptr, 0));
}
ReturnedValue DatePrototype::method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index dfef52583e..cdb3b8942b 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -358,7 +358,7 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons
return v4->throwTypeError();
thisObject = argc ? argv : nullptr;
if (argc < 2 || argv[1].isNullOrUndefined())
- return f->call(thisObject, argv, 0);
+ return checkedResult(v4, f->call(thisObject, argv, 0));
Object *arr = argv[1].objectValue();
if (!arr)
@@ -398,13 +398,14 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons
}
}
- return f->call(thisObject, arguments, len);
+ return checkedResult(v4, f->call(thisObject, arguments, len));
}
ReturnedValue FunctionPrototype::method_call(const QV4::FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
+ QV4::ExecutionEngine *v4 = b->engine();
if (!thisObject->isFunctionObject())
- return b->engine()->throwTypeError();
+ return v4->throwTypeError();
const FunctionObject *f = static_cast<const FunctionObject *>(thisObject);
@@ -413,7 +414,7 @@ ReturnedValue FunctionPrototype::method_call(const QV4::FunctionObject *b, const
++argv;
--argc;
}
- return f->call(thisObject, argv, argc);
+ return checkedResult(v4, f->call(thisObject, argv, argc));
}
ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
@@ -713,12 +714,12 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject
ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value *, const Value *argv, int argc)
{
- const BoundFunction *f = static_cast<const BoundFunction *>(fo);
- Scope scope(f->engine());
-
- if (scope.hasException())
+ QV4::ExecutionEngine *v4 = fo->engine();
+ if (v4->hasException)
return Encode::undefined();
+ const BoundFunction *f = static_cast<const BoundFunction *>(fo);
+ Scope scope(v4);
Scoped<MemberData> boundArgs(scope, f->boundArgs());
ScopedFunctionObject target(scope, f->target());
JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
@@ -729,7 +730,7 @@ ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value *
argp += boundArgs->size();
}
memcpy(argp, argv, argc*sizeof(Value));
- return target->call(jsCallData);
+ return checkedResult(v4, target->call(jsCallData));
}
ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *)
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index c99cad8e33..78be58c60a 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -328,6 +328,10 @@ inline bool FunctionObject::isBoundFunction() const
return d()->vtable() == BoundFunction::staticVTable();
}
+inline ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
+{
+ return v4->hasException ? QV4::Encode::undefined() : result;
+}
}
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 936c032fad..ce759111f4 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -703,6 +703,8 @@ QString Stringify::Str(const QString &key, const Value &v)
*jsCallData->thisObject = value;
jsCallData->args[0] = v4->newString(key);
value = toJSON->call(jsCallData);
+ if (v4->hasException)
+ return QString();
}
}
@@ -714,6 +716,8 @@ QString Stringify::Str(const QString &key, const Value &v)
jsCallData->args[1] = value;
*jsCallData->thisObject = holder;
value = replacerFunction->call(jsCallData);
+ if (v4->hasException)
+ return QString();
}
o = value->asReturnedValue();
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 0cda6b864a..d3ea50867a 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -309,7 +309,8 @@ ReturnedValue Lookup::getterAccessor(Lookup *l, ExecutionEngine *engine, const V
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
+ return checkedResult(engine, static_cast<const FunctionObject *>(getter)->call(
+ &object, nullptr, 0));
}
}
l->getter = getterFallback;
@@ -326,7 +327,8 @@ ReturnedValue Lookup::getterProtoAccessor(Lookup *l, ExecutionEngine *engine, co
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
+ return checkedResult(engine, static_cast<const FunctionObject *>(getter)->call(
+ &object, nullptr, 0));
}
return getterTwoClasses(l, engine, object);
}
@@ -346,7 +348,8 @@ ReturnedValue Lookup::getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
+ return checkedResult(engine, static_cast<const FunctionObject *>(getter)->call(
+ &object, nullptr, 0));
}
}
l->getter = getterFallback;
@@ -391,7 +394,8 @@ ReturnedValue Lookup::primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
+ return checkedResult(engine, static_cast<const FunctionObject *>(getter)->call(
+ &object, nullptr, 0));
}
}
l->getter = getterGeneric;
@@ -429,7 +433,8 @@ ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engi
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- return static_cast<const FunctionObject *>(getter)->call(engine->globalObject, nullptr, 0);
+ return checkedResult(engine, static_cast<const FunctionObject *>(getter)->call(
+ engine->globalObject, nullptr, 0));
}
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 89161433ed..b723141caa 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -105,7 +105,7 @@ ReturnedValue Object::getValueAccessor(const Value *thisObject, const Value &v,
JSCallData jsCallData(scope);
if (thisObject)
*jsCallData->thisObject = *thisObject;
- return f->call(jsCallData);
+ return checkedResult(scope.engine, f->call(jsCallData));
}
bool Object::putValue(uint memberIndex, PropertyAttributes attrs, const Value &value)
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 7d910a1cbc..0c8cc192fc 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -667,7 +667,7 @@ ReturnedValue ObjectPrototype::method_toLocaleString(const FunctionObject *b, co
if (!f)
THROW_TYPE_ERROR();
- return f->call(thisObject, argv, argc);
+ return checkedResult(scope.engine, f->call(thisObject, argv, argc));
}
ReturnedValue ObjectPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
diff --git a/src/qml/jsruntime/qv4promiseobject.cpp b/src/qml/jsruntime/qv4promiseobject.cpp
index 17d218a6eb..ecaff72b22 100644
--- a/src/qml/jsruntime/qv4promiseobject.cpp
+++ b/src/qml/jsruntime/qv4promiseobject.cpp
@@ -618,7 +618,7 @@ ReturnedValue PromiseCtor::method_all(const FunctionObject *f, const Value *this
}
ScopedObject nextPromise(scope, Value::fromReturnedValue(resolve->call(thisObject, nextValue, 1)));
- if (!nextPromise || scope.hasException()) {
+ if (scope.hasException() || !nextPromise) {
ScopedValue completion(scope, Runtime::IteratorClose::call(e, iteratorObject, doneValue));
if (scope.hasException()) {
completion = e->exceptionValue->asReturnedValue();
@@ -764,7 +764,7 @@ ReturnedValue PromiseCtor::method_race(const FunctionObject *f, const Value *thi
}
ScopedObject nextPromise(scope, Value::fromReturnedValue(resolve->call(thisObject, nextValue, 1)));
- if (!nextPromise || scope.hasException()) {
+ if (scope.hasException() || !nextPromise) {
ScopedValue completion(scope, Runtime::IteratorClose::call(e, iteratorObject, doneValue));
if (scope.hasException()) {
completion = e->exceptionValue->asReturnedValue();
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index 51f96b9003..24676ffd00 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -96,6 +96,8 @@ ReturnedValue ProxyObject::virtualGet(const Managed *m, PropertyKey id, const Va
cdata.args[2] = *receiver;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return Encode::undefined();
ScopedProperty targetDesc(scope);
PropertyAttributes attributes = target->getOwnProperty(id, targetDesc);
if (attributes != Attr_Invalid && !attributes.isConfigurable()) {
@@ -136,7 +138,7 @@ bool ProxyObject::virtualPut(Managed *m, PropertyKey id, const Value &value, Val
cdata.args[3] = *receiver;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
- if (!trapResult->toBoolean())
+ if (scope.engine->hasException || !trapResult->toBoolean())
return false;
ScopedProperty targetDesc(scope);
PropertyAttributes attributes = target->getOwnProperty(id, targetDesc);
@@ -176,7 +178,7 @@ bool ProxyObject::virtualDeleteProperty(Managed *m, PropertyKey id)
cdata.args[2] = o->d(); // ### fix receiver handling
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
- if (!trapResult->toBoolean())
+ if (scope.engine->hasException || !trapResult->toBoolean())
return false;
ScopedProperty targetDesc(scope);
PropertyAttributes attributes = target->getOwnProperty(id, targetDesc);
@@ -211,6 +213,8 @@ bool ProxyObject::virtualHasProperty(const Managed *m, PropertyKey id)
cdata.args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol();
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return false;
bool result = trapResult->toBoolean();
if (!result) {
ScopedProperty targetDesc(scope);
@@ -251,6 +255,8 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property
cdata.args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol();
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return Attr_Invalid;
if (!trapResult->isObject() && !trapResult->isUndefined()) {
scope.engine->throwTypeError();
return Attr_Invalid;
@@ -323,7 +329,7 @@ bool ProxyObject::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Pro
cdata.args[2] = ObjectPrototype::fromPropertyDescriptor(scope.engine, p, attrs);
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
- bool result = trapResult->toBoolean();
+ bool result = !scope.engine->hasException && trapResult->toBoolean();
if (!result)
return false;
@@ -373,6 +379,8 @@ bool ProxyObject::virtualIsExtensible(const Managed *m)
cdata.args[0] = target;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return false;
bool result = trapResult->toBoolean();
if (result != target->isExtensible()) {
scope.engine->throwTypeError();
@@ -404,6 +412,8 @@ bool ProxyObject::virtualPreventExtensions(Managed *m)
cdata.args[0] = target;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return false;
bool result = trapResult->toBoolean();
if (result && target->isExtensible()) {
scope.engine->throwTypeError();
@@ -439,6 +449,8 @@ Heap::Object *ProxyObject::virtualGetPrototypeOf(const Managed *m)
cdata.args[0] = target;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return nullptr;
if (!trapResult->isNull() && !trapResult->isObject()) {
scope.engine->throwTypeError();
return nullptr;
@@ -482,7 +494,7 @@ bool ProxyObject::virtualSetPrototypeOf(Managed *m, const Object *p)
cdata.args[1] = p ? p->asReturnedValue() : Encode::null();
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
- bool result = trapResult->toBoolean();
+ bool result = !scope.engine->hasException && trapResult->toBoolean();
if (!result)
return false;
if (!target->isExtensible()) {
@@ -573,6 +585,8 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val
JSCallData cdata(scope, 1, nullptr, handler);
cdata.args[0] = target;
ScopedObject trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ if (scope.engine->hasException)
+ return nullptr;
if (!trapResult) {
scope.engine->throwTypeError();
return nullptr;
@@ -699,7 +713,7 @@ ReturnedValue ProxyFunctionObject::virtualCall(const FunctionObject *f, const Va
if (scope.hasException())
return Encode::undefined();
if (trap->isNullOrUndefined())
- return target->call(thisObject, argv, argc);
+ return checkedResult(scope.engine, target->call(thisObject, argv, argc));
if (!trap->isFunctionObject())
return scope.engine->throwTypeError();
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index 0772770d63..2a6c61f044 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -98,7 +98,8 @@ ReturnedValue Reflect::method_apply(const FunctionObject *f, const Value *, cons
if (scope.hasException())
return Encode::undefined();
- return static_cast<const FunctionObject &>(argv[0]).call(&argv[1], arguments.argv, arguments.argc);
+ return checkedResult(scope.engine, static_cast<const FunctionObject &>(argv[0]).call(
+ &argv[1], arguments.argv, arguments.argc));
}
ReturnedValue Reflect::method_construct(const FunctionObject *f, const Value *, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index f1375e4ca4..a8a37cda37 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -481,6 +481,8 @@ ReturnedValue RegExpPrototype::exec(ExecutionEngine *engine, const Object *o, co
ScopedFunctionObject exec(scope, o->get(key));
if (exec) {
ScopedValue result(scope, exec->call(o, s, 1));
+ if (scope.hasException())
+ RETURN_UNDEFINED();
if (!result->isNull() && !result->isObject())
return scope.engine->throwTypeError();
return result->asReturnedValue();
@@ -737,6 +739,8 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val
cData->args[nCaptures + 1] = Encode(position);
cData->args[nCaptures + 2] = s;
ScopedValue replValue(scope, replaceFunction->call(cData));
+ if (scope.hasException())
+ return Encode::undefined();
replacement = replValue->toQString();
} else {
replacement = RegExp::getSubstitution(matchString->toQString(), s->toQString(), position, cData.args, nCaptures, replaceValue->toQString());
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 01b5ff6611..f9e4d258fc 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -390,7 +390,7 @@ QV4::ReturnedValue Runtime::Instanceof::call(ExecutionEngine *engine, const Valu
return engine->throwTypeError();
ScopedValue result(scope, fHasInstance->call(&rval, &lval, 1));
- return Encode(result->toBoolean());
+ return scope.hasException() ? Encode::undefined() : Encode(result->toBoolean());
}
QV4::ReturnedValue Runtime::In::call(ExecutionEngine *engine, const Value &left, const Value &right)
@@ -515,6 +515,8 @@ ReturnedValue RuntimeHelpers::ordinaryToPrimitive(ExecutionEngine *engine, const
ScopedValue conv(scope, object->get(meth1));
if (FunctionObject *o = conv->as<FunctionObject>()) {
result = o->call(object, nullptr, 0);
+ if (engine->hasException)
+ return Encode::undefined();
if (result->isPrimitive())
return result->asReturnedValue();
}
@@ -525,6 +527,8 @@ ReturnedValue RuntimeHelpers::ordinaryToPrimitive(ExecutionEngine *engine, const
conv = object->get(meth2);
if (FunctionObject *o = conv->as<FunctionObject>()) {
result = o->call(object, nullptr, 0);
+ if (engine->hasException)
+ return Encode::undefined();
if (result->isPrimitive())
return result->asReturnedValue();
}
@@ -800,6 +804,8 @@ ReturnedValue Runtime::GetIterator::call(ExecutionEngine *engine, const Value &i
return engine->throwTypeError();
JSCallData cData(scope, 0, nullptr, o);
ScopedObject it(scope, f->call(cData));
+ if (engine->hasException)
+ return Encode::undefined();
if (!it)
return engine->throwTypeError();
return it->asReturnedValue();
@@ -1341,7 +1347,8 @@ ReturnedValue Runtime::CallGlobalLookup::call(ExecutionEngine *engine, uint inde
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]->toQString());
}
- return static_cast<FunctionObject &>(function).call(&thisObject, argv, argc);
+ return checkedResult(engine, static_cast<FunctionObject &>(function).call(
+ &thisObject, argv, argc));
}
ReturnedValue Runtime::CallQmlContextPropertyLookup::call(ExecutionEngine *engine, uint index,
@@ -1356,7 +1363,8 @@ ReturnedValue Runtime::CallQmlContextPropertyLookup::call(ExecutionEngine *engin
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]->toQString());
}
- return static_cast<FunctionObject &>(function).call(thisObject, argv, argc);
+ return checkedResult(engine, static_cast<FunctionObject &>(function).call(
+ thisObject, argv, argc));
}
ReturnedValue Runtime::CallPossiblyDirectEval::call(ExecutionEngine *engine, Value *argv, int argc)
@@ -1375,7 +1383,7 @@ ReturnedValue Runtime::CallPossiblyDirectEval::call(ExecutionEngine *engine, Val
if (function->d() == engine->evalFunction()->d())
return static_cast<EvalFunction *>(function.getPointer())->evalCall(thisObject, argv, argc, true);
- return function->call(thisObject, argv, argc);
+ return checkedResult(engine, function->call(thisObject, argv, argc));
}
ReturnedValue Runtime::CallName::call(ExecutionEngine *engine, int nameIndex, Value *argv, int argc)
@@ -1395,7 +1403,7 @@ ReturnedValue Runtime::CallName::call(ExecutionEngine *engine, int nameIndex, Va
->runtimeStrings[nameIndex]->toQString());
}
- return f->call(thisObject, argv, argc);
+ return checkedResult(engine, f->call(thisObject, argv, argc));
}
ReturnedValue Runtime::CallProperty::call(ExecutionEngine *engine, const Value &baseRef, int nameIndex, Value *argv, int argc)
@@ -1437,7 +1445,7 @@ ReturnedValue Runtime::CallProperty::call(ExecutionEngine *engine, const Value &
return engine->throwTypeError(error);
}
- return f->call(base, argv, argc);
+ return checkedResult(engine, f->call(base, argv, argc));
}
ReturnedValue Runtime::CallPropertyLookup::call(ExecutionEngine *engine, const Value &base, uint index, Value *argv, int argc)
@@ -1449,7 +1457,7 @@ ReturnedValue Runtime::CallPropertyLookup::call(ExecutionEngine *engine, const V
if (!f.isFunctionObject())
return engine->throwTypeError();
- return static_cast<FunctionObject &>(f).call(&base, argv, argc);
+ return checkedResult(engine, static_cast<FunctionObject &>(f).call(&base, argv, argc));
}
ReturnedValue Runtime::CallElement::call(ExecutionEngine *engine, const Value &baseRef, const Value &index, Value *argv, int argc)
@@ -1467,7 +1475,7 @@ ReturnedValue Runtime::CallElement::call(ExecutionEngine *engine, const Value &b
if (!f)
return engine->throwTypeError();
- return f->call(base, argv, argc);
+ return checkedResult(engine, f->call(base, argv, argc));
}
ReturnedValue Runtime::CallValue::call(ExecutionEngine *engine, const Value &func, Value *argv, int argc)
@@ -1475,7 +1483,8 @@ ReturnedValue Runtime::CallValue::call(ExecutionEngine *engine, const Value &fun
if (!func.isFunctionObject())
return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
Value undef = Value::undefinedValue();
- return static_cast<const FunctionObject &>(func).call(&undef, argv, argc);
+ return checkedResult(engine, static_cast<const FunctionObject &>(func).call(
+ &undef, argv, argc));
}
ReturnedValue Runtime::CallWithReceiver::call(ExecutionEngine *engine, const Value &func,
@@ -1483,7 +1492,8 @@ ReturnedValue Runtime::CallWithReceiver::call(ExecutionEngine *engine, const Val
{
if (!func.isFunctionObject())
return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
- return static_cast<const FunctionObject &>(func).call(&thisObject, argv, argc);
+ return checkedResult(engine, static_cast<const FunctionObject &>(func).call(
+ &thisObject, argv, argc));
}
struct CallArgs {
@@ -1537,7 +1547,8 @@ ReturnedValue Runtime::CallWithSpread::call(ExecutionEngine *engine, const Value
if (engine->hasException)
return Encode::undefined();
- return static_cast<const FunctionObject &>(function).call(&thisObject, arguments.argv, arguments.argc);
+ return checkedResult(engine, static_cast<const FunctionObject &>(function).call(
+ &thisObject, arguments.argv, arguments.argc));
}
ReturnedValue Runtime::Construct::call(ExecutionEngine *engine, const Value &function, const Value &newTarget, Value *argv, int argc)
@@ -1580,7 +1591,7 @@ ReturnedValue Runtime::TailCall::call(CppStackFrame *frame, ExecutionEngine *eng
if (!frame->callerCanHandleTailCall || !fo.canBeTailCalled() || engine->debugger()
|| unsigned(argc) > fo.formalParameterCount()) {
// Cannot tailcall, do a normal call:
- return fo.call(&thisObject, argv, argc);
+ return checkedResult(engine, fo.call(&thisObject, argv, argc));
}
memcpy(frame->jsFrame->args, argv, argc * sizeof(Value));
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 9b4a2d575e..209a1b4e76 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -591,7 +591,7 @@ ReturnedValue StringPrototype::method_match(const FunctionObject *b, const Value
ScopedFunctionObject match(scope, that->get(scope.engine->symbol_match()));
if (!match)
return scope.engine->throwTypeError();
- return match->call(that, s, 1);
+ return checkedResult(scope.engine, match->call(that, s, 1));
}
ReturnedValue StringPrototype::method_normalize(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index a5a720abc0..6a1b003b25 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -763,6 +763,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_every(const FunctionObject *b
arguments[1] = Value::fromDouble(k);
arguments[2] = v;
r = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
ok = r->toBoolean();
}
return Encode(ok);
@@ -862,6 +863,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_filter(const FunctionObject *
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
selected = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
if (selected->toBoolean()) {
++arguments;
scope.alloc(1);
@@ -1201,6 +1203,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_map(const FunctionObject *b,
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
mapped = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
a->put(k, mapped);
}
return a->asReturnedValue();
@@ -1250,6 +1253,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_reduce(const FunctionObject *
arguments[2] = Value::fromDouble(k);
arguments[3] = instance;
acc = callback->call(nullptr, arguments, 4);
+ CHECK_EXCEPTION();
}
++k;
}
@@ -1305,6 +1309,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_reduceRight(const FunctionObj
arguments[2] = Value::fromDouble(k - 1);
arguments[3] = instance;
acc = callback->call(nullptr, arguments, 4);
+ CHECK_EXCEPTION();
}
--k;
}
@@ -1366,6 +1371,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_some(const FunctionObject *b,
arguments[1] = Value::fromDouble(k);
arguments[2] = instance;
result = callback->call(that, arguments, 3);
+ CHECK_EXCEPTION();
if (result->toBoolean())
return Encode(true);
}
diff --git a/src/qmlmodels/qqmldelegatecomponent.cpp b/src/qmlmodels/qqmldelegatecomponent.cpp
index cc3b38ec93..ccd54bccec 100644
--- a/src/qmlmodels/qqmldelegatecomponent.cpp
+++ b/src/qmlmodels/qqmldelegatecomponent.cpp
@@ -73,7 +73,7 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in
*/
/*!
- \qmlproperty string QtQml.Models::DelegateChoice::roleValue
+ \qmlproperty variant QtQml.Models::DelegateChoice::roleValue
This property holds the value used to match the role data for the role provided by \l DelegateChooser::role.
*/
QVariant QQmlDelegateChoice::roleValue() const
@@ -91,7 +91,7 @@ void QQmlDelegateChoice::setRoleValue(const QVariant &value)
}
/*!
- \qmlproperty index QtQml.Models::DelegateChoice::row
+ \qmlproperty int QtQml.Models::DelegateChoice::row
This property holds the value used to match the row value of model elements.
With models that have only the index property (and thus only one column), this property
should be intended as an index, and set to the desired index value.
@@ -103,7 +103,7 @@ void QQmlDelegateChoice::setRoleValue(const QVariant &value)
*/
/*!
- \qmlproperty index QtQml.Models::DelegateChoice::index
+ \qmlproperty int QtQml.Models::DelegateChoice::index
This property holds the value used to match the index value of model elements.
This is effectively an alias for \l row.
@@ -125,7 +125,7 @@ void QQmlDelegateChoice::setRow(int r)
}
/*!
- \qmlproperty index QtQml.Models::DelegateChoice::column
+ \qmlproperty int QtQml.Models::DelegateChoice::column
This property holds the value used to match the column value of model elements.
*/
int QQmlDelegateChoice::column() const
diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp
index f79910204a..083e80a0a3 100644
--- a/src/qmlmodels/qqmllistmodel.cpp
+++ b/src/qmlmodels/qqmllistmodel.cpp
@@ -2802,10 +2802,12 @@ bool QQmlListModelParser::applyProperty(
QV4::ScopedContext context(scope, QV4::QmlContext::create(v4->rootContext(), QQmlContextData::get(qmlContext(model->m_modelCache)), nullptr));
QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(context, compilationUnit->runtimeFunctions[id]));
- QV4::ReturnedValue result = function->call(v4->globalObject, nullptr, 0);
-
QJSValue v;
- QJSValuePrivate::setValue(&v, v4, result);
+ QV4::ScopedValue result(scope, function->call(v4->globalObject, nullptr, 0));
+ if (v4->hasException)
+ v4->catchException();
+ else
+ QJSValuePrivate::setValue(&v, v4, result->asReturnedValue());
value.setValue<QJSValue>(v);
} else {
QByteArray script = scriptStr.toUtf8();
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 49552e1901..cddf21c7ed 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -480,7 +480,7 @@ static QString qtestFixUrl(const QUrl &location)
void QuickTestResult::fail
(const QString &message, const QUrl &location, int line)
{
- QTestResult::addFailure(message.toLatin1().constData(),
+ QTestResult::addFailure(message.toUtf8().constData(),
qtestFixUrl(location).toLatin1().constData(), line);
}
@@ -493,7 +493,7 @@ bool QuickTestResult::verify
qtestFixUrl(location).toLatin1().constData(), line);
} else {
return QTestResult::verify
- (success, message.toLatin1().constData(), "",
+ (success, message.toUtf8().constData(), "",
qtestFixUrl(location).toLatin1().constData(), line);
}
}
@@ -601,7 +601,7 @@ bool QuickTestResult::compare
const QUrl &location, int line)
{
return QTestResult::compare
- (success, message.toLocal8Bit().constData(),
+ (success, message.toUtf8().constData(),
QTest::toString(val1.toString().toLatin1().constData()),
QTest::toString(val2.toString().toLatin1().constData()),
"", "",
@@ -611,7 +611,7 @@ bool QuickTestResult::compare
void QuickTestResult::skip
(const QString &message, const QUrl &location, int line)
{
- QTestResult::addSkip(message.toLatin1().constData(),
+ QTestResult::addSkip(message.toUtf8().constData(),
qtestFixUrl(location).toLatin1().constData(), line);
QTestResult::setSkipCurrentTest(true);
}
@@ -630,13 +630,13 @@ bool QuickTestResult::expectFailContinue
{
return QTestResult::expectFail
(tag.toLatin1().constData(),
- QTest::toString(comment.toLatin1().constData()),
+ QTest::toString(comment.toUtf8().constData()),
QTest::Continue, qtestFixUrl(location).toLatin1().constData(), line);
}
void QuickTestResult::warn(const QString &message, const QUrl &location, int line)
{
- QTestLog::warn(message.toLatin1().constData(), qtestFixUrl(location).toLatin1().constData(), line);
+ QTestLog::warn(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line);
}
void QuickTestResult::ignoreWarning(const QJSValue &message)
@@ -646,7 +646,7 @@ void QuickTestResult::ignoreWarning(const QJSValue &message)
QTestLog::ignoreMessage(QtWarningMsg, message.toVariant().toRegularExpression());
#endif
} else {
- QTestLog::ignoreMessage(QtWarningMsg, message.toString().toLatin1());
+ QTestLog::ignoreMessage(QtWarningMsg, message.toString().toUtf8());
}
}
diff --git a/src/quick/configure.json b/src/quick/configure.json
index f8277332dc..8d1ddaea7c 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -134,7 +134,7 @@
"label": "Path support",
"purpose": "Provides Path elements.",
"section": "Qt Quick",
- "condition": "features.quick-shadereffect",
+ "condition": "module.gui",
"output": [
"privateFeature"
]
diff --git a/src/quick/doc/images/declarative-textformat.png b/src/quick/doc/images/declarative-textformat.png
index ade1b45429..a671fbf3d6 100644
--- a/src/quick/doc/images/declarative-textformat.png
+++ b/src/quick/doc/images/declarative-textformat.png
Binary files differ
diff --git a/src/quick/doc/snippets/qml/text/textEditFormats.qml b/src/quick/doc/snippets/qml/text/textEditFormats.qml
new file mode 100644
index 0000000000..9065cc6a1c
--- /dev/null
+++ b/src/quick/doc/snippets/qml/text/textEditFormats.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.14
+
+//![0]
+Column {
+ TextEdit {
+ font.pointSize: 24
+ textFormat: TextEdit.AutoText
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ TextEdit {
+ font.pointSize: 24
+ textFormat: TextEdit.RichText
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ TextEdit {
+ font.pointSize: 24
+ textFormat: TextEdit.PlainText
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ TextEdit {
+ font.pointSize: 24
+ textFormat: TextEdit.MarkdownText
+ text: "**Hello** *World!*"
+ }
+}
+//![0]
+
diff --git a/src/quick/doc/snippets/qml/text/textFormats.qml b/src/quick/doc/snippets/qml/text/textFormats.qml
new file mode 100644
index 0000000000..b292a3ee13
--- /dev/null
+++ b/src/quick/doc/snippets/qml/text/textFormats.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.14
+
+//![0]
+Column {
+ Text {
+ font.pointSize: 24
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ Text {
+ font.pointSize: 24
+ textFormat: Text.RichText
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ Text {
+ font.pointSize: 24
+ textFormat: Text.PlainText
+ text: "<b>Hello</b> <i>World!</i>"
+ }
+ Text {
+ font.pointSize: 24
+ textFormat: Text.MarkdownText
+ text: "**Hello** *World!*"
+ }
+}
+//![0]
+
diff --git a/src/quick/doc/snippets/qml/xmlrole.xml b/src/quick/doc/snippets/qml/xmlrole.xml
deleted file mode 100644
index 70280e067d..0000000000
--- a/src/quick/doc/snippets/qml/xmlrole.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1" ?>
-<catalog>
- <book type="Online" wanted="true">
- <title>Qt 5 Cadaques</title>
- <year>2014</year>
- <author>Juergen Bocklage-Ryannel</author>
- <author>Johan Thelin</author>
- </book>
- <book type="Hardcover">
- <title>C++ GUI Programming with Qt 4</title>
- <year>2006</year>
- <author>Jasmin Blanchette</author>
- <author>Mark Summerfield</author>
- </book>
- <book type="Paperback">
- <title>Programming with Qt</title>
- <year>2002</year>
- <author>Matthias Kalle Dalheimer</author>
- </book>
- </catalog>
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index ae849aeb4b..b95a2559ff 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1640,6 +1640,9 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
The item will try to automatically determine whether the text should
be treated as styled text. This determination is made using Qt::mightBeRichText().
+ However, detection of Markdown is not automatic.
+
+ \sa textFormat
*/
QString QQuickText::text() const
{
@@ -2067,26 +2070,25 @@ void QQuickText::resetMaximumLineCount()
/*!
\qmlproperty enumeration QtQuick::Text::textFormat
- The way the text property should be displayed.
+ The way the \l text property should be displayed.
Supported text formats are:
- \list
- \li Text.AutoText (default)
- \li Text.PlainText
- \li Text.StyledText
- \li Text.RichText
- \endlist
+ \value Text.AutoText (default) detected via the Qt::mightBeRichText() heuristic
+ \value Text.PlainText all styling tags are treated as plain text
+ \value Text.StyledText optimized basic rich text as in HTML 3.2
+ \value Text.RichText \l {Supported HTML Subset} {a subset of HTML 4}
+ \value Text.MarkdownText \l {https://commonmark.org/help/}{CommonMark} plus the
+ \l {https://guides.github.com/features/mastering-markdown/}{GitHub}
+ extensions for tables and task lists (since 5.14)
If the text format is \c Text.AutoText the Text item
will automatically determine whether the text should be treated as
- styled text. This determination is made using Qt::mightBeRichText()
- which uses a fast and therefore simple heuristic. It mainly checks
- whether there is something that looks like a tag before the first
- line break. Although the result may be correct for common cases,
- there is no guarantee.
+ styled text. This determination is made using Qt::mightBeRichText(),
+ which can detect the presence of an HTML tag on the first line of text,
+ but cannot distinguish Markdown from plain text.
- Text.StyledText is an optimized format supporting some basic text
+ \c Text.StyledText is an optimized format supporting some basic text
styling markup, in the style of HTML 3.2:
\code
@@ -2112,30 +2114,21 @@ void QQuickText::resetMaximumLineCount()
\table
\row
\li
- \qml
-Column {
- Text {
- font.pointSize: 24
- text: "<b>Hello</b> <i>World!</i>"
- }
- Text {
- font.pointSize: 24
- textFormat: Text.RichText
- text: "<b>Hello</b> <i>World!</i>"
- }
- Text {
- font.pointSize: 24
- textFormat: Text.PlainText
- text: "<b>Hello</b> <i>World!</i>"
- }
-}
- \endqml
+ \snippet qml/text/textFormats.qml 0
\li \image declarative-textformat.png
\endtable
- Text.RichText supports a larger subset of HTML 4, as described on the
- \l {Supported HTML Subset} page. You should prefer using Text.PlainText
- or Text.StyledText instead, as they offer better performance.
+ \c Text.RichText supports a larger subset of HTML 4, as described on the
+ \l {Supported HTML Subset} page. You should prefer using \c Text.PlainText,
+ \c Text.StyledText or \c Text.MarkdownText instead, as they offer better performance.
+
+ \note With \c Text.MarkdownText, and with the supported subset of HTML,
+ some decorative elements are not rendered as they would be in a web browser:
+ \list
+ \li code blocks use the \l {QFontDatabase::FixedFont}{default monospace font} but without a surrounding highlight box
+ \li block quotes are indented, but there is no vertical line alongside the quote
+ \li horizontal rules are not rendered
+ \endlist
*/
QQuickText::TextFormat QQuickText::textFormat() const
{
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 7d34cc3f56..650b1961a4 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -395,6 +395,7 @@ QString QQuickTextEdit::text() const
The text to display. If the text format is AutoText the text edit will
automatically determine whether the text should be treated as
rich text. This determination is made using Qt::mightBeRichText().
+ However, detection of Markdown is not automatic.
The text-property is mostly suitable for setting the initial content and
handling modifications to relatively small text content. The append(),
@@ -402,7 +403,7 @@ QString QQuickTextEdit::text() const
remarkably better performance for modifying especially large rich text
content.
- \sa clear()
+ \sa clear(), textFormat
*/
void QQuickTextEdit::setText(const QString &text)
{
@@ -444,41 +445,43 @@ QString QQuickTextEdit::preeditText() const
/*!
\qmlproperty enumeration QtQuick::TextEdit::textFormat
- The way the text property should be displayed.
+ The way the \l text property should be displayed.
- \list
- \li TextEdit.AutoText
- \li TextEdit.PlainText
- \li TextEdit.RichText
- \endlist
+ Supported text formats are:
- The default is TextEdit.PlainText. If the text format is TextEdit.AutoText the text edit
- will automatically determine whether the text should be treated as
- rich text. This determination is made using Qt::mightBeRichText().
+ \value TextEdit.PlainText (default) all styling tags are treated as plain text
+ \value TextEdit.AutoText detected via the Qt::mightBeRichText() heuristic
+ \value TextEdit.RichText \l {Supported HTML Subset} {a subset of HTML 4}
+ \value TextEdit.MarkdownText \l {https://commonmark.org/help/}{CommonMark} plus the
+ \l {https://guides.github.com/features/mastering-markdown/}{GitHub}
+ extensions for tables and task lists (since 5.14)
+
+ The default is \c TextEdit.PlainText. If the text format is set to
+ \c TextEdit.AutoText, the text edit will automatically determine whether
+ the text should be treated as rich text. This determination is made using
+ Qt::mightBeRichText(), which can detect the presence of an HTML tag on the
+ first line of text, but cannot distinguish Markdown from plain text.
\table
\row
\li
- \qml
-Column {
- TextEdit {
- font.pointSize: 24
- text: "<b>Hello</b> <i>World!</i>"
- }
- TextEdit {
- font.pointSize: 24
- textFormat: TextEdit.RichText
- text: "<b>Hello</b> <i>World!</i>"
- }
- TextEdit {
- font.pointSize: 24
- textFormat: TextEdit.PlainText
- text: "<b>Hello</b> <i>World!</i>"
- }
-}
- \endqml
+ \snippet qml/text/textEditFormats.qml 0
\li \image declarative-textformat.png
\endtable
+
+ With \c TextEdit.MarkdownText, checkboxes that result from using the
+ \l {https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown}{GitHub checkbox extension}
+ are interactively checkable.
+
+ \note Interactively typing markup or markdown formatting is not supported.
+
+ \note With \c Text.MarkdownText, and with the supported subset of HTML,
+ some decorative elements are not rendered as they would be in a web browser:
+ \list
+ \li code blocks use the \l {QFontDatabase::FixedFont}{default monospace font} but without a surrounding highlight box
+ \li block quotes are indented, but there is no vertical line alongside the quote
+ \li horizontal rules are not rendered
+ \endlist
*/
QQuickTextEdit::TextFormat QQuickTextEdit::textFormat() const
{
diff --git a/src/quickshapes/qquickshapegenericrenderer_p.h b/src/quickshapes/qquickshapegenericrenderer_p.h
index 4590c662c1..75c4277383 100644
--- a/src/quickshapes/qquickshapegenericrenderer_p.h
+++ b/src/quickshapes/qquickshapegenericrenderer_p.h
@@ -57,6 +57,7 @@
#include <qsggeometry.h>
#include <qsgmaterial.h>
#include <qsgrendererinterface.h>
+#include <qsgtexture.h>
#include <QtCore/qrunnable.h>
QT_BEGIN_NAMESPACE