8#include <private/qqmlrefcount_p.h>
11#include <private/qv4domerrors_p.h>
12#include <private/qv4engine_p.h>
13#include <private/qv4functionobject_p.h>
14#include <private/qv4scopedvalue_p.h>
15#include <private/qv4jscall_p.h>
17#include <QtCore/qobject.h>
18#include <QtQml/qjsvalue.h>
19#include <QtQml/qjsengine.h>
20#include <QtQml/qqmlfile.h>
21#include <QtNetwork/qnetworkreply.h>
23#include <QtCore/qpointer.h>
24#include <QtCore/qstringconverter.h>
25#include <QtCore/qxmlstream.h>
26#include <QtCore/qstack.h>
27#include <QtCore/qdebug.h>
28#include <QtCore/qbuffer.h>
30#include <private/qv4objectproto_p.h>
31#include <private/qv4scopedvalue_p.h>
32#include <private/qv4arraybuffer_p.h>
33#include <private/qv4jsonobject_p.h>
37#define V4THROW_REFERENCE(string)
39 ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string)));
40 return scope.engine->throwError(error);
86 qDeleteAll(attributes);
121class DocumentImpl
final :
public QQmlRefCounted<DocumentImpl>,
public NodeImpl
123 using Base1 = QQmlRefCounted<DocumentImpl>;
151 if (listPtr ==
nullptr)
152 listPtr =
new QList<NodeImpl *>;
269 Scope scope(internalClass->engine);
270 ScopedObject o(scope,
this);
272 o->defineAccessorProperty(QStringLiteral(
"nodeName"), QV4::NodePrototype::method_get_nodeName,
nullptr);
273 o->defineAccessorProperty(QStringLiteral(
"nodeValue"), QV4::NodePrototype::method_get_nodeValue,
nullptr);
274 o->defineAccessorProperty(QStringLiteral(
"nodeType"), QV4::NodePrototype::method_get_nodeType,
nullptr);
275 o->defineAccessorProperty(QStringLiteral(
"namespaceUri"), QV4::NodePrototype::method_get_namespaceUri,
nullptr);
277 o->defineAccessorProperty(QStringLiteral(
"parentNode"), QV4::NodePrototype::method_get_parentNode,
nullptr);
278 o->defineAccessorProperty(QStringLiteral(
"childNodes"), QV4::NodePrototype::method_get_childNodes,
nullptr);
279 o->defineAccessorProperty(QStringLiteral(
"firstChild"), QV4::NodePrototype::method_get_firstChild,
nullptr);
280 o->defineAccessorProperty(QStringLiteral(
"lastChild"), QV4::NodePrototype::method_get_lastChild,
nullptr);
281 o->defineAccessorProperty(QStringLiteral(
"previousSibling"), QV4::NodePrototype::method_get_previousSibling,
nullptr);
282 o->defineAccessorProperty(QStringLiteral(
"nextSibling"), QV4::NodePrototype::method_get_nextSibling,
nullptr);
283 o->defineAccessorProperty(QStringLiteral(
"attributes"), QV4::NodePrototype::method_get_attributes,
nullptr);
291 V4_OBJECT2(
Node, Object)
376void NodeImpl::addref()
381void NodeImpl::release()
386ReturnedValue NodePrototype::method_get_nodeName(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
389 Scoped<Node> r(scope, thisObject->as<Node>());
394 switch (r->d()->d->type) {
395 case NodeImpl::Document:
396 name = QStringLiteral(
"#document");
398 case NodeImpl::CDATA:
399 name = QStringLiteral(
"#cdata-section");
402 name = QStringLiteral(
"#text");
405 name = r->d()->d->name;
408 return Encode(scope.engine->newString(name));
411ReturnedValue NodePrototype::method_get_nodeValue(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
414 Scoped<Node> r(scope, thisObject->as<Node>());
418 if (r->d()->d->type == NodeImpl::Document ||
419 r->d()->d->type == NodeImpl::DocumentFragment ||
420 r->d()->d->type == NodeImpl::DocumentType ||
421 r->d()->d->type == NodeImpl::Element ||
422 r->d()->d->type == NodeImpl::Entity ||
423 r->d()->d->type == NodeImpl::EntityReference ||
424 r->d()->d->type == NodeImpl::Notation)
425 RETURN_RESULT(Encode::null());
427 return Encode(scope.engine->newString(r->d()->d->data));
430ReturnedValue NodePrototype::method_get_nodeType(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
433 Scoped<Node> r(scope, thisObject->as<Node>());
437 return Encode(r->d()->d->type);
440ReturnedValue NodePrototype::method_get_namespaceUri(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
443 Scoped<Node> r(scope, thisObject->as<Node>());
447 return Encode(scope.engine->newString(r->d()->d->namespaceUri));
450ReturnedValue NodePrototype::method_get_parentNode(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
453 Scoped<Node> r(scope, thisObject->as<Node>());
457 if (r->d()->d->parent)
458 return Node::create(scope.engine, r->d()->d->parent);
460 return Encode::null();
463ReturnedValue NodePrototype::method_get_childNodes(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
466 Scoped<Node> r(scope, thisObject->as<Node>());
470 return NodeList::create(scope.engine, r->d()->d);
473ReturnedValue NodePrototype::method_get_firstChild(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
476 Scoped<Node> r(scope, thisObject->as<Node>());
480 if (r->d()->d->children.isEmpty())
481 return Encode::null();
483 return Node::create(scope.engine, r->d()->d->children.constFirst());
486ReturnedValue NodePrototype::method_get_lastChild(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
489 Scoped<Node> r(scope, thisObject->as<Node>());
493 if (r->d()->d->children.isEmpty())
494 return Encode::null();
496 return Node::create(scope.engine, r->d()->d->children.constLast());
499ReturnedValue NodePrototype::method_get_previousSibling(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
502 Scoped<Node> r(scope, thisObject->as<Node>());
506 if (!r->d()->d->parent)
507 RETURN_RESULT(Encode::null());
509 for (
int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
510 if (r->d()->d->parent->children.at(ii) == r->d()->d) {
512 return Encode::null();
514 return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
518 return Encode::null();
521ReturnedValue NodePrototype::method_get_nextSibling(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
524 Scoped<Node> r(scope, thisObject->as<Node>());
528 if (!r->d()->d->parent)
529 RETURN_RESULT(Encode::null());
531 for (
int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
532 if (r->d()->d->parent->children.at(ii) == r->d()->d) {
533 if ((ii + 1) == r->d()->d->parent->children.size())
534 return Encode::null();
536 return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
540 return Encode::null();
543ReturnedValue NodePrototype::method_get_attributes(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
546 Scoped<Node> r(scope, thisObject->as<Node>());
550 if (r->d()->d->type != NodeImpl::Element)
551 return Encode::null();
553 return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
556ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
559 QQmlXMLHttpRequestData *d = xhrdata(v4);
560 if (d->nodePrototype.isUndefined()) {
561 ScopedObject p(scope, v4->memoryManager->allocate<NodePrototype>());
562 d->nodePrototype.set(v4, p);
565 return d->nodePrototype.value();
568ReturnedValue Node::create(ExecutionEngine *v4, NodeImpl *data)
572 Scoped<Node> instance(scope, v4->memoryManager->allocate<Node>(data));
573 ScopedObject p(scope);
575 switch (data->type) {
577 instance->setPrototypeUnchecked((p = Attr::prototype(v4)));
579 case NodeImpl::Comment:
580 case NodeImpl::Document:
581 case NodeImpl::DocumentFragment:
582 case NodeImpl::DocumentType:
583 case NodeImpl::Entity:
584 case NodeImpl::EntityReference:
585 case NodeImpl::Notation:
586 case NodeImpl::ProcessingInstruction:
587 return Encode::undefined();
588 case NodeImpl::CDATA:
589 instance->setPrototypeUnchecked((p = CDATA::prototype(v4)));
592 instance->setPrototypeUnchecked((p = Text::prototype(v4)));
594 case NodeImpl::Element:
595 instance->setPrototypeUnchecked((p = Element::prototype(v4)));
599 return instance.asReturnedValue();
602ReturnedValue Element::prototype(ExecutionEngine *engine)
604 QQmlXMLHttpRequestData *d = xhrdata(engine);
605 if (d->elementPrototype.isUndefined()) {
607 ScopedObject p(scope, engine->newObject());
608 ScopedObject pp(scope);
609 p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine)));
610 p->defineAccessorProperty(QStringLiteral(
"tagName"), NodePrototype::method_get_nodeName,
nullptr);
611 d->elementPrototype.set(engine, p);
612 engine->freezeObject(p);
614 return d->elementPrototype.value();
617ReturnedValue Attr::prototype(ExecutionEngine *engine)
619 QQmlXMLHttpRequestData *d = xhrdata(engine);
620 if (d->attrPrototype.isUndefined()) {
622 ScopedObject p(scope, engine->newObject());
623 ScopedObject pp(scope);
624 p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine)));
625 p->defineAccessorProperty(QStringLiteral(
"name"), method_name,
nullptr);
626 p->defineAccessorProperty(QStringLiteral(
"value"), method_value,
nullptr);
627 p->defineAccessorProperty(QStringLiteral(
"ownerElement"), method_ownerElement,
nullptr);
628 d->attrPrototype.set(engine, p);
629 engine->freezeObject(p);
631 return d->attrPrototype.value();
634ReturnedValue Attr::method_name(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
637 Scoped<Node> r(scope, thisObject->as<Node>());
641 return Encode(scope.engine->newString(r->d()->d->name));
644ReturnedValue Attr::method_value(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
647 Scoped<Node> r(scope, thisObject->as<Node>());
651 return Encode(scope.engine->newString(r->d()->d->data));
654ReturnedValue Attr::method_ownerElement(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
657 Scoped<Node> r(scope, thisObject->as<Node>());
661 return Node::create(scope.engine, r->d()->d->parent);
664ReturnedValue CharacterData::method_length(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
667 Scoped<Node> r(scope, thisObject->as<Node>());
671 return Encode(
int(r->d()->d->data.size()));
674ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
676 QQmlXMLHttpRequestData *d = xhrdata(v4);
677 if (d->characterDataPrototype.isUndefined()) {
679 ScopedObject p(scope, v4->newObject());
680 ScopedObject pp(scope);
681 p->setPrototypeUnchecked((pp = NodePrototype::getProto(v4)));
682 p->defineAccessorProperty(QStringLiteral(
"data"), NodePrototype::method_get_nodeValue,
nullptr);
683 p->defineAccessorProperty(QStringLiteral(
"length"), method_length,
nullptr);
684 d->characterDataPrototype.set(v4, p);
687 return d->characterDataPrototype.value();
690ReturnedValue Text::method_isElementContentWhitespace(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
693 Scoped<Node> r(scope, thisObject->as<Node>());
697 return Encode(QStringView(r->d()->d->data).trimmed().isEmpty());
700ReturnedValue Text::method_wholeText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
703 Scoped<Node> r(scope, thisObject->as<Node>());
707 return Encode(scope.engine->newString(r->d()->d->data));
710ReturnedValue Text::prototype(ExecutionEngine *v4)
712 QQmlXMLHttpRequestData *d = xhrdata(v4);
713 if (d->textPrototype.isUndefined()) {
715 ScopedObject p(scope, v4->newObject());
716 ScopedObject pp(scope);
717 p->setPrototypeUnchecked((pp = CharacterData::prototype(v4)));
718 p->defineAccessorProperty(QStringLiteral(
"isElementContentWhitespace"), method_isElementContentWhitespace,
nullptr);
719 p->defineAccessorProperty(QStringLiteral(
"wholeText"), method_wholeText,
nullptr);
720 d->textPrototype.set(v4, p);
723 return d->textPrototype.value();
726ReturnedValue CDATA::prototype(ExecutionEngine *v4)
729 QQmlXMLHttpRequestData *d = xhrdata(v4);
730 if (d->cdataPrototype.isUndefined()) {
732 ScopedObject p(scope, v4->newObject());
733 ScopedObject pp(scope);
734 p->setPrototypeUnchecked((pp = Text::prototype(v4)));
735 d->cdataPrototype.set(v4, p);
738 return d->cdataPrototype.value();
741ReturnedValue Document::prototype(ExecutionEngine *v4)
743 QQmlXMLHttpRequestData *d = xhrdata(v4);
744 if (d->documentPrototype.isUndefined()) {
746 ScopedObject p(scope, v4->newObject());
747 ScopedObject pp(scope);
748 p->setPrototypeUnchecked((pp = NodePrototype::getProto(v4)));
749 p->defineAccessorProperty(QStringLiteral(
"xmlVersion"), method_xmlVersion,
nullptr);
750 p->defineAccessorProperty(QStringLiteral(
"xmlEncoding"), method_xmlEncoding,
nullptr);
751 p->defineAccessorProperty(QStringLiteral(
"xmlStandalone"), method_xmlStandalone,
nullptr);
752 p->defineAccessorProperty(QStringLiteral(
"documentElement"), method_documentElement,
nullptr);
753 d->documentPrototype.set(v4, p);
756 return d->documentPrototype.value();
759ReturnedValue Document::load(ExecutionEngine *v4,
const QByteArray &data)
763 DocumentImpl *document =
nullptr;
764 QStack<NodeImpl *> nodeStack;
766 QXmlStreamReader reader(data);
768 while (!reader.atEnd()) {
769 switch (reader.readNext()) {
770 case QXmlStreamReader::NoToken:
772 case QXmlStreamReader::Invalid:
774 case QXmlStreamReader::StartDocument:
776 document =
new DocumentImpl;
777 document->document = document;
778 document->version = reader.documentVersion().toString();
779 document->encoding = reader.documentEncoding().toString();
780 document->isStandalone = reader.isStandaloneDocument();
782 case QXmlStreamReader::EndDocument:
784 case QXmlStreamReader::StartElement:
787 NodeImpl *node =
new NodeImpl;
788 node->document = document;
789 node->namespaceUri = reader.namespaceUri().toString();
790 node->name = reader.name().toString();
791 if (nodeStack.isEmpty()) {
792 document->root = node;
794 node->parent = nodeStack.top();
795 node->parent->children.append(node);
797 nodeStack.append(node);
799 const auto attributes = reader.attributes();
800 for (
const QXmlStreamAttribute &a : attributes) {
801 NodeImpl *attr =
new NodeImpl;
802 attr->document = document;
803 attr->type = NodeImpl::Attr;
804 attr->namespaceUri = a.namespaceUri().toString();
805 attr->name = a.name().toString();
806 attr->data = a.value().toString();
808 node->attributes.append(attr);
812 case QXmlStreamReader::EndElement:
815 case QXmlStreamReader::Characters:
817 NodeImpl *node =
new NodeImpl;
818 node->document = document;
819 node->type = reader.isCDATA()?NodeImpl::CDATA:NodeImpl::Text;
820 node->parent = nodeStack.top();
821 node->parent->children.append(node);
822 node->data = reader.text().toString();
825 case QXmlStreamReader::Comment:
827 case QXmlStreamReader::DTD:
829 case QXmlStreamReader::EntityReference:
831 case QXmlStreamReader::ProcessingInstruction:
836 if (!document || reader.hasError()) {
839 return Encode::null();
842 ScopedObject instance(scope, v4->memoryManager->allocate<Node>(document));
844 ScopedObject p(scope);
845 instance->setPrototypeUnchecked((p = Document::prototype(v4)));
846 return instance.asReturnedValue();
849bool Node::isNull()
const
851 return d()->d ==
nullptr;
854ReturnedValue NamedNodeMap::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
856 Q_ASSERT(m->as<NamedNodeMap>());
858 const NamedNodeMap *r =
static_cast<
const NamedNodeMap *>(m);
859 QV4::ExecutionEngine *v4 = r->engine();
861 if (id.isArrayIndex()) {
862 uint index = id.asArrayIndex();
864 if ((
int)index < r->d()->list().size()) {
867 return Node::create(v4, r->d()->list().at(index));
870 *hasProperty =
false;
871 return Encode::undefined();
875 return Object::virtualGet(m, id, receiver, hasProperty);
877 if (id == v4->id_length()->propertyKey())
878 return Value::fromInt32(r->d()->list().size()).asReturnedValue();
880 QString str = id.toQString();
881 for (
int ii = 0; ii < r->d()->list().size(); ++ii) {
882 if (r->d()->list().at(ii)->name == str) {
885 return Node::create(v4, r->d()->list().at(ii));
890 *hasProperty =
false;
891 return Encode::undefined();
894ReturnedValue NamedNodeMap::create(ExecutionEngine *v4, NodeImpl *data,
const QList<NodeImpl *> &list)
896 return (v4->memoryManager->allocate<NamedNodeMap>(data, list))->asReturnedValue();
899ReturnedValue NodeList::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
901 Q_ASSERT(m->as<NodeList>());
902 const NodeList *r =
static_cast<
const NodeList *>(m);
903 QV4::ExecutionEngine *v4 = r->engine();
905 if (id.isArrayIndex()) {
906 uint index = id.asArrayIndex();
907 if ((
int)index < r->d()->d->children.size()) {
910 return Node::create(v4, r->d()->d->children.at(index));
913 *hasProperty =
false;
914 return Encode::undefined();
917 if (id == v4->id_length()->propertyKey())
918 return Value::fromInt32(r->d()->d->children.size()).asReturnedValue();
919 return Object::virtualGet(m, id, receiver, hasProperty);
922ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
924 return (v4->memoryManager->allocate<NodeList>(data))->asReturnedValue();
927ReturnedValue Document::method_documentElement(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
930 Scoped<Node> r(scope, thisObject->as<Node>());
931 if (!r || r->d()->d->type != NodeImpl::Document)
934 return Node::create(scope.engine,
static_cast<DocumentImpl *>(r->d()->d)->root);
937ReturnedValue Document::method_xmlStandalone(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
940 Scoped<Node> r(scope, thisObject->as<Node>());
941 if (!r || r->d()->d->type != NodeImpl::Document)
944 return Encode(
static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
947ReturnedValue Document::method_xmlVersion(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
950 Scoped<Node> r(scope, thisObject->as<Node>());
951 if (!r || r->d()->d->type != NodeImpl::Document)
954 return Encode(scope.engine->newString(
static_cast<DocumentImpl *>(r->d()->d)->version));
957ReturnedValue Document::method_xmlEncoding(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
960 Scoped<Node> r(scope, thisObject->as<Node>());
961 if (!r || r->d()->d->type != NodeImpl::Document)
964 return Encode(scope.engine->newString(
static_cast<DocumentImpl *>(r->d()->d)->encoding));
1018 void error(QNetworkReply::NetworkError);
1022 void requestFromUrl(
const QUrl &url);
1029 QByteArray m_responseEntityBody;
1031 int m_redirectCount;
1033 typedef std::pair<QByteArray, QByteArray> HeaderPair;
1034 typedef QList<HeaderPair> HeadersList;
1035 HeadersList m_headersList;
1036 void fillHeadersList();
1040 QByteArray m_charset;
1041 QByteArray m_overrideMime;
1042 QByteArray m_overrideCharset;
1044 QStringDecoder findTextDecoder()
const;
1045 void readEncoding();
1047 PersistentValue m_thisObject;
1048 QQmlRefPointer<QQmlContextData> m_qmlContext;
1049 bool m_wasConstructedWithQmlContext =
true;
1051 void dispatchCallbackNow(Object *thisObj);
1052 static void dispatchCallbackNow(Object *thisObj,
bool done,
bool error);
1053 void dispatchCallbackSafely();
1056 QString m_statusText;
1057 QNetworkRequest m_request;
1058 QStringList m_addedHeaders;
1059 QPointer<QNetworkReply> m_network;
1060 void destroyNetwork();
1062 QNetworkAccessManager *m_nam;
1063 QNetworkAccessManager *networkAccessManager() {
return m_nam; }
1065 QString m_responseType;
1066 QV4::PersistentValue m_parsedDocument;
1070 : m_state(
Unsent), m_errorFlag(
false), m_sendFlag(
false)
1071 , m_redirectCount(0), m_gotXml(
false),
m_network(
nullptr), m_nam(manager)
1073 m_wasConstructedWithQmlContext = !v4->callingQmlContext().isNull();
1103 return m_statusText;
1110 m_errorFlag =
false;
1111 m_responseEntityBody = QByteArray();
1114 m_request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, loadType == SynchronousLoad);
1116 m_addedHeaders.clear();
1117 dispatchCallbackNow(thisObject);
1118 return Encode::undefined();
1123 QByteArray utfname = name.toUtf8();
1125 if (m_addedHeaders.contains(name, Qt::CaseInsensitive)) {
1126 m_request.setRawHeader(utfname, m_request.rawHeader(utfname) +
',' + value.toUtf8());
1128 m_request.setRawHeader(utfname, value.toUtf8());
1129 m_addedHeaders.append(name);
1135 if (!m_headersList.isEmpty()) {
1136 const QByteArray utfname = name.toLower().toUtf8();
1137 for (
const HeaderPair &header : m_headersList) {
1138 if (header.first == utfname)
1139 return QString::fromUtf8(header.second);
1149 for (
const HeaderPair &header : m_headersList) {
1151 ret.append(QLatin1String(
"\r\n"));
1152 ret += QString::fromUtf8(header.first) + QLatin1String(
": ")
1153 + QString::fromUtf8(header.second);
1160 const QList<QByteArray> headerList = m_network->rawHeaderList();
1162 m_headersList.clear();
1163 for (
const QByteArray &header : headerList) {
1164 HeaderPair pair (header.toLower(), m_network->rawHeader(header));
1165 if (pair.first ==
"set-cookie" ||
1166 pair.first ==
"set-cookie2")
1169 m_headersList << pair;
1176 QNetworkRequest request = m_request;
1178 if (QQmlFile::isLocalFile(url)) {
1179 if (m_method == QLatin1String(
"PUT"))
1181 if (!xhrFileWrite()) {
1182 qWarning(
"XMLHttpRequest: Using PUT on a local file is disabled by default.\n"
1183 "Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature.");
1186 }
else if (m_method == QLatin1String(
"GET")) {
1187 if (!xhrFileRead()) {
1188 qWarning(
"XMLHttpRequest: Using GET on a local file is disabled by default.\n"
1189 "Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.");
1193 qWarning(
"XMLHttpRequest: Unsupported method used on a local file");
1198 request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
1199 request.setUrl(url);
1200 if(m_method == QLatin1String(
"POST") ||
1201 m_method == QLatin1String(
"PUT")) {
1202 QVariant var = request.header(QNetworkRequest::ContentTypeHeader);
1203 if (var.isValid()) {
1204 QString str = var.toString();
1205 int charsetIdx = str.indexOf(QLatin1String(
"charset="));
1206 if (charsetIdx == -1) {
1208 if (!str.isEmpty()) str.append(QLatin1Char(
';'));
1209 str.append(QLatin1String(
"charset=UTF-8"));
1213 int semiColon = str.indexOf(QLatin1Char(
';'), charsetIdx);
1214 if (semiColon == -1) {
1215 n = str.size() - charsetIdx;
1217 n = semiColon - charsetIdx;
1220 str.replace(charsetIdx, n, QLatin1String(
"UTF-8"));
1222 request.setHeader(QNetworkRequest::ContentTypeHeader, str);
1224 request.setHeader(QNetworkRequest::ContentTypeHeader,
1225 QLatin1String(
"text/plain;charset=UTF-8"));
1230 qWarning().nospace() <<
"XMLHttpRequest: " << qPrintable(m_method) <<
' ' << qPrintable(url.toString());
1231 if (!m_data.isEmpty()) {
1232 qWarning().nospace() <<
" "
1233 << qPrintable(QString::fromUtf8(m_data));
1237 if (m_method == QLatin1String(
"GET")) {
1238 m_network = networkAccessManager()->get(request);
1239 }
else if (m_method == QLatin1String(
"HEAD")) {
1240 m_network = networkAccessManager()->head(request);
1241 }
else if (m_method == QLatin1String(
"POST")) {
1242 m_network = networkAccessManager()->post(request, m_data);
1243 }
else if (m_method == QLatin1String(
"PUT")) {
1244 m_network = networkAccessManager()->put(request, m_data);
1245 }
else if (m_method == QLatin1String(
"DELETE")) {
1246 m_network = networkAccessManager()->deleteResource(request);
1247 }
else if ((m_method == QLatin1String(
"OPTIONS")) ||
1248 m_method == QLatin1String(
"PROPFIND") ||
1249 m_method == QLatin1String(
"PATCH")) {
1250 QBuffer *buffer =
new QBuffer;
1251 buffer->setData(m_data);
1252 buffer->open(QIODevice::ReadOnly);
1253 m_network = networkAccessManager()->sendCustomRequest(request, QByteArray(m_method.toUtf8().constData()), buffer);
1254 buffer->setParent(m_network);
1257 if (m_request.attribute(QNetworkRequest::SynchronousRequestAttribute).toBool()) {
1258 if (m_network->bytesAvailable() > 0)
1261 QNetworkReply::NetworkError networkError = m_network->error();
1262 if (networkError != QNetworkReply::NoError) {
1263 error(networkError);
1268 QObject::connect(m_network, SIGNAL(readyRead()),
1269 this, SLOT(readyRead()));
1270 QObject::connect(m_network, SIGNAL(errorOccurred(QNetworkReply::NetworkError)),
1271 this, SLOT(error(QNetworkReply::NetworkError)));
1272 QObject::connect(m_network, SIGNAL(finished()),
1273 this, SLOT(finished()));
1278 Object *thisObject,
const QQmlRefPointer<QQmlContextData> &context,
const QByteArray &data)
1280 m_errorFlag =
false;
1282 m_redirectCount = 0;
1285 m_thisObject = thisObject;
1286 m_qmlContext = context;
1288 requestFromUrl(m_url);
1290 return Encode::undefined();
1296 m_responseEntityBody = QByteArray();
1298 m_request = QNetworkRequest();
1300 if (!(m_state ==
Unsent ||
1301 (m_state ==
Opened && !m_sendFlag) ||
1306 dispatchCallbackNow(thisObject);
1311 return Encode::undefined();
1317 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1319 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1325 dispatchCallbackSafely();
1328 bool wasEmpty = m_responseEntityBody.isEmpty();
1329 m_responseEntityBody.append(m_network->readAll());
1330 if (wasEmpty && !m_responseEntityBody.isEmpty())
1333 dispatchCallbackSafely();
1338 int idx = QNetworkReply::staticMetaObject.indexOfEnumerator(
"NetworkError");
1339 if (idx == -1)
return "EnumLookupFailed";
1341 QMetaEnum e = QNetworkReply::staticMetaObject.enumerator(idx);
1343 const char *name = e.valueToKey(error);
1344 if (!name)
return "EnumLookupFailed";
1351 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1353 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1355 m_request = QNetworkRequest();
1360 qWarning().nospace() <<
"XMLHttpRequest: ERROR " << qPrintable(m_url.toString());
1361 qWarning().nospace() <<
" " << error <<
' ' << errorToString(error) <<
' ' << m_statusText;
1364 if (error == QNetworkReply::ContentAccessDenied ||
1365 error == QNetworkReply::ContentOperationNotPermittedError ||
1366 error == QNetworkReply::ContentNotFoundError ||
1367 error == QNetworkReply::AuthenticationRequiredError ||
1368 error == QNetworkReply::ContentReSendError ||
1369 error == QNetworkReply::UnknownContentError ||
1370 error == QNetworkReply::ProtocolInvalidOperationError ||
1371 error == QNetworkReply::InternalServerError ||
1372 error == QNetworkReply::OperationNotImplementedError ||
1373 error == QNetworkReply::ServiceUnavailableError ||
1374 error == QNetworkReply::UnknownServerError) {
1376 dispatchCallbackSafely();
1379 m_responseEntityBody = QByteArray();
1383 dispatchCallbackSafely();
1386#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION 15
1391 QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
1392 if (redirect.isValid()) {
1393 QUrl url = m_network->url().resolved(redirect.toUrl());
1394 if (!QQmlFile::isLocalFile(url)) {
1397 const QVariant code = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute);
1398 if (code.isValid() && code.toInt() == 303 && m_method != QLatin1String(
"GET"))
1399 m_method = QStringLiteral(
"GET");
1403 m_responseEntityBody = QByteArray();
1405 requestFromUrl(url);
1412 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1414 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1419 dispatchCallbackSafely();
1421 m_responseEntityBody.append(m_network->readAll());
1425 qWarning().nospace() <<
"XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
1426 if (!m_responseEntityBody.isEmpty()) {
1427 qWarning().nospace() <<
" "
1428 << qPrintable(QString::fromUtf8(m_responseEntityBody));
1436 dispatchCallbackSafely();
1440 dispatchCallbackSafely();
1442 m_thisObject.clear();
1443 m_qmlContext.reset();
1449 for (
const HeaderPair &header : std::as_const(m_headersList)) {
1450 if (header.first ==
"content-type") {
1451 int separatorIdx = header.second.indexOf(
';');
1452 if (separatorIdx == -1) {
1453 m_mime = header.second;
1455 m_mime = header.second.mid(0, separatorIdx);
1456 int charsetIdx = header.second.indexOf(
"charset=");
1457 if (charsetIdx != -1) {
1459 separatorIdx = header.second.indexOf(
';', charsetIdx);
1460 m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.size());
1467 const auto mime = mimeType();
1468 if (mime.isEmpty() || mime ==
"text/xml" || mime ==
"application/xml" || mime.endsWith(
"+xml"))
1486 return m_overrideMime.isEmpty() ? m_mime : m_overrideMime;
1493 return m_overrideCharset.isEmpty() ? m_charset : m_overrideCharset;
1498 return m_responseType;
1503 m_responseType = responseType;
1508 if (m_parsedDocument.isEmpty()) {
1509 Scope scope(engine);
1511 QJsonParseError error;
1512 const QString& jtext = responseBody();
1513 JsonParser parser(scope.engine, jtext.constData(), jtext.size());
1514 ScopedValue jsonObject(scope, parser.parse(&error));
1515 if (error.error != QJsonParseError::NoError)
1516 return engine->throwSyntaxError(QStringLiteral(
"JSON.parse: Parse error"));
1518 m_parsedDocument.set(scope.engine, jsonObject);
1521 return m_parsedDocument.value();
1526 if (m_parsedDocument.isEmpty()) {
1527 m_parsedDocument.set(engine, Document::load(engine, rawResponseBody()));
1530 return m_parsedDocument.value();
1535 QStringDecoder decoder;
1537 if (!charset().isEmpty())
1538 decoder = QStringDecoder(charset());
1540 if (!decoder.isValid() && m_gotXml) {
1541 QXmlStreamReader reader(m_responseEntityBody);
1543 decoder = QStringDecoder(reader.documentEncoding().toString().toUtf8());
1546 if (!decoder.isValid() && mimeType() ==
"text/html")
1547 decoder = QStringDecoder::decoderForHtml(m_responseEntityBody);
1549 if (!decoder.isValid()) {
1550 auto encoding = QStringConverter::encodingForData(m_responseEntityBody);
1552 decoder = QStringDecoder(*encoding);
1555 if (!decoder.isValid())
1556 decoder = QStringDecoder(QStringDecoder::Utf8);
1563 QStringDecoder toUtf16 = findTextDecoder();
1564 return toUtf16(m_responseEntityBody);
1569 return m_responseEntityBody;
1574 dispatchCallbackNow(thisObj, m_state == Done, m_errorFlag);
1581 const auto dispatch = [thisObj](
const QString &eventName) {
1582 QV4::Scope scope(thisObj->engine());
1583 ScopedString s(scope, scope.engine->newString(eventName));
1584 ScopedFunctionObject callback(scope, thisObj->get(s));
1589 QV4::JSCallArguments jsCallData(scope);
1590 callback->call(jsCallData);
1592 if (scope.hasException()) {
1593 QQmlError error = scope.engine->catchExceptionAsQmlError();
1594 QQmlEnginePrivate *qmlEnginePrivate = scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) :
nullptr;
1595 QQmlEnginePrivate::warning(qmlEnginePrivate, error);
1599 dispatch(QStringLiteral(
"onreadystatechange"));
1602 dispatch(QStringLiteral(
"onerror"));
1604 dispatch(QStringLiteral(
"onload"));
1605 dispatch(QStringLiteral(
"onloadend"));
1611 if (m_wasConstructedWithQmlContext && m_qmlContext.isNull()) {
1619 dispatchCallbackNow(m_thisObject.as<Object>());
1625 m_network->disconnect();
1626 m_network->deleteLater();
1627 m_network =
nullptr;
1647#define QQmlXMLHttpRequestCtorMembers(class, Member)
1648 Member(class, Pointer, Object *, proto)
1651 DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor)
1652 void init(ExecutionEngine *engine);
1710void Heap::QQmlXMLHttpRequestCtor::init(ExecutionEngine *engine)
1712 Heap::FunctionObject::init(engine, QStringLiteral(
"XMLHttpRequest"));
1713 Scope scope(engine);
1714 Scoped<QV4::QQmlXMLHttpRequestCtor> ctor(scope,
this);
1716 ctor->defineReadonlyProperty(QStringLiteral(
"UNSENT"), Value::fromInt32(QQmlXMLHttpRequest::Unsent));
1717 ctor->defineReadonlyProperty(QStringLiteral(
"OPENED"), Value::fromInt32(QQmlXMLHttpRequest::Opened));
1718 ctor->defineReadonlyProperty(QStringLiteral(
"HEADERS_RECEIVED"), Value::fromInt32(QQmlXMLHttpRequest::HeadersReceived));
1719 ctor->defineReadonlyProperty(QStringLiteral(
"LOADING"), Value::fromInt32(QQmlXMLHttpRequest::Loading));
1720 ctor->defineReadonlyProperty(QStringLiteral(
"DONE"), Value::fromInt32(QQmlXMLHttpRequest::Done));
1722 if (!ctor->d()->proto)
1724 ScopedString s(scope, engine->id_prototype());
1725 ctor->defineDefaultProperty(s, ScopedObject(scope, ctor->d()->proto));
1730void QQmlXMLHttpRequestCtor::setupProto()
1732 ExecutionEngine *v4 = engine();
1734 ScopedObject p(scope, v4->newObject());
1735 d()->proto.set(scope.engine, p->d());
1738 p->defineDefaultProperty(QStringLiteral(
"open"), method_open);
1739 p->defineDefaultProperty(QStringLiteral(
"setRequestHeader"), method_setRequestHeader);
1740 p->defineDefaultProperty(QStringLiteral(
"send"), method_send);
1741 p->defineDefaultProperty(QStringLiteral(
"abort"), method_abort);
1742 p->defineDefaultProperty(QStringLiteral(
"getResponseHeader"), method_getResponseHeader);
1743 p->defineDefaultProperty(QStringLiteral(
"getAllResponseHeaders"), method_getAllResponseHeaders);
1744 p->defineDefaultProperty(QStringLiteral(
"overrideMimeType"), method_overrideMimeType);
1747 p->defineAccessorProperty(QStringLiteral(
"readyState"), method_get_readyState,
nullptr);
1748 p->defineAccessorProperty(QStringLiteral(
"status"),method_get_status,
nullptr);
1749 p->defineAccessorProperty(QStringLiteral(
"statusText"),method_get_statusText,
nullptr);
1750 p->defineAccessorProperty(QStringLiteral(
"responseText"),method_get_responseText,
nullptr);
1751 p->defineAccessorProperty(QStringLiteral(
"responseXML"),method_get_responseXML,
nullptr);
1752 p->defineAccessorProperty(QStringLiteral(
"response"),method_get_response,
nullptr);
1753 p->defineAccessorProperty(QStringLiteral(
"responseURL"),method_get_responseURL,
nullptr);
1756 p->defineAccessorProperty(QStringLiteral(
"responseType"), method_get_responseType, method_set_responseType);
1759 p->defineReadonlyProperty(QStringLiteral(
"UNSENT"), Value::fromInt32(0));
1760 p->defineReadonlyProperty(QStringLiteral(
"OPENED"), Value::fromInt32(1));
1761 p->defineReadonlyProperty(QStringLiteral(
"HEADERS_RECEIVED"), Value::fromInt32(2));
1762 p->defineReadonlyProperty(QStringLiteral(
"LOADING"), Value::fromInt32(3));
1763 p->defineReadonlyProperty(QStringLiteral(
"DONE"), Value::fromInt32(4));
1768ReturnedValue QQmlXMLHttpRequestCtor::method_open(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1771 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1774 QQmlXMLHttpRequest *r = w->d()->request;
1776 if (argc < 2 || argc > 5)
1777 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1780 QString method = argv[0].toQStringNoThrow().toUpper();
1781 if (method != QLatin1String(
"GET") &&
1782 method != QLatin1String(
"PUT") &&
1783 method != QLatin1String(
"HEAD") &&
1784 method != QLatin1String(
"POST") &&
1785 method != QLatin1String(
"DELETE") &&
1786 method != QLatin1String(
"OPTIONS") &&
1787 method != QLatin1String(
"PROPFIND") &&
1788 method != QLatin1String(
"PATCH"))
1789 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Unsupported HTTP method type");
1792 QUrl url = QUrl(argv[1].toQStringNoThrow());
1794 if (url.isRelative()) {
1795 if (QQmlRefPointer<QQmlContextData> qmlContextData = scope.engine->callingQmlContext())
1796 url = qmlContextData->resolvedUrl(url);
1798 url = scope.engine->resolvedUrl(url.url());
1804 async = argv[2].booleanValue();
1808 QString username, password;
1810 username = argv[3].toQStringNoThrow();
1812 password = argv[4].toQStringNoThrow();
1815 url.setFragment(QString());
1818 if (!username.isNull()) url.setUserName(username);
1819 if (!password.isNull()) url.setPassword(password);
1821 return r->open(w, method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
1824ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1827 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1830 QQmlXMLHttpRequest *r = w->d()->request;
1833 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1835 if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
1836 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1838 QString name = argv[0].toQStringNoThrow();
1839 QString value = argv[1].toQStringNoThrow();
1843 QString nameUpper = name.toUpper();
1844 if (nameUpper == QLatin1String(
"ACCEPT-CHARSET") ||
1845 nameUpper == QLatin1String(
"ACCEPT-ENCODING") ||
1846 nameUpper == QLatin1String(
"CONNECTION") ||
1847 nameUpper == QLatin1String(
"CONTENT-LENGTH") ||
1848 nameUpper == QLatin1String(
"COOKIE") ||
1849 nameUpper == QLatin1String(
"COOKIE2") ||
1850 nameUpper == QLatin1String(
"CONTENT-TRANSFER-ENCODING") ||
1851 nameUpper == QLatin1String(
"DATE") ||
1852 nameUpper == QLatin1String(
"EXPECT") ||
1853 nameUpper == QLatin1String(
"HOST") ||
1854 nameUpper == QLatin1String(
"KEEP-ALIVE") ||
1855 nameUpper == QLatin1String(
"REFERER") ||
1856 nameUpper == QLatin1String(
"TE") ||
1857 nameUpper == QLatin1String(
"TRAILER") ||
1858 nameUpper == QLatin1String(
"TRANSFER-ENCODING") ||
1859 nameUpper == QLatin1String(
"UPGRADE") ||
1860 nameUpper == QLatin1String(
"VIA") ||
1861 nameUpper.startsWith(QLatin1String(
"PROXY-")) ||
1862 nameUpper.startsWith(QLatin1String(
"SEC-")))
1865 r->addHeader(name, value);
1870ReturnedValue QQmlXMLHttpRequestCtor::method_send(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1873 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1876 QQmlXMLHttpRequest *r = w->d()->request;
1878 if (r->readyState() != QQmlXMLHttpRequest::Opened ||
1880 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1884 if (
const ArrayBuffer *buffer = argv[0].as<ArrayBuffer>()) {
1885 data = buffer->asByteArray();
1887 data = argv[0].toQStringNoThrow().toUtf8();
1891 return r->send(w, scope.engine->callingQmlContext(), data);
1894ReturnedValue QQmlXMLHttpRequestCtor::method_abort(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1897 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1900 QQmlXMLHttpRequest *r = w->d()->request;
1905ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1908 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1911 QQmlXMLHttpRequest *r = w->d()->request;
1914 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1916 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
1917 r->readyState() != QQmlXMLHttpRequest::Done &&
1918 r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
1919 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1921 return Encode(scope.engine->newString(r->header(argv[0].toQStringNoThrow())));
1924ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int argc)
1927 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1930 QQmlXMLHttpRequest *r = w->d()->request;
1933 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1935 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
1936 r->readyState() != QQmlXMLHttpRequest::Done &&
1937 r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
1938 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1940 return Encode(scope.engine->newString(r->headers()));
1944ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1947 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1950 QQmlXMLHttpRequest *r = w->d()->request;
1952 return Encode(r->readyState());
1955ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1958 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1961 QQmlXMLHttpRequest *r = w->d()->request;
1963 if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
1964 r->readyState() == QQmlXMLHttpRequest::Opened)
1965 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1970 return Encode(r->replyStatus());
1973ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1976 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1979 QQmlXMLHttpRequest *r = w->d()->request;
1981 if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
1982 r->readyState() == QQmlXMLHttpRequest::Opened)
1983 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1986 return Encode(scope.engine->newString(QString()));
1988 return Encode(scope.engine->newString(r->replyStatusText()));
1991ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1994 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1997 QQmlXMLHttpRequest *r = w->d()->request;
1999 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2000 r->readyState() != QQmlXMLHttpRequest::Done)
2001 return Encode(scope.engine->newString(QString()));
2003 return Encode(scope.engine->newString(r->responseBody()));
2006ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2009 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2012 QQmlXMLHttpRequest *r = w->d()->request;
2014 if (!r->receivedXml() ||
2015 (r->readyState() != QQmlXMLHttpRequest::Loading &&
2016 r->readyState() != QQmlXMLHttpRequest::Done)) {
2017 return Encode::null();
2019 if (r->responseType().isEmpty())
2020 r->setResponseType(QLatin1String(
"document"));
2021 return r->xmlResponseBody(scope.engine);
2025ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2028 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2031 QQmlXMLHttpRequest *r = w->d()->request;
2033 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2034 r->readyState() != QQmlXMLHttpRequest::Done)
2035 RETURN_RESULT(scope.engine->newString(QString()));
2037 const QString& responseType = r->responseType();
2038 if (responseType.compare(QLatin1String(
"text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) {
2039 RETURN_RESULT(scope.engine->newString(r->responseBody()));
2040 }
else if (responseType.compare(QLatin1String(
"arraybuffer"), Qt::CaseInsensitive) == 0) {
2041 RETURN_RESULT(scope.engine->newArrayBuffer(r->rawResponseBody()));
2042 }
else if (responseType.compare(QLatin1String(
"json"), Qt::CaseInsensitive) == 0) {
2043 RETURN_RESULT(r->jsonResponseBody(scope.engine));
2044 }
else if (responseType.compare(QLatin1String(
"document"), Qt::CaseInsensitive) == 0) {
2045 RETURN_RESULT(r->xmlResponseBody(scope.engine));
2047 RETURN_RESULT(scope.engine->newString(QString()));
2052ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2055 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2058 QQmlXMLHttpRequest *r = w->d()->request;
2059 return Encode(scope.engine->newString(r->responseType()));
2062ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
2065 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2068 QQmlXMLHttpRequest *r = w->d()->request;
2071 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
2074 r->setResponseType(argv[0].toQStringNoThrow());
2076 return Encode::undefined();
2079ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseURL(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2082 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2085 QQmlXMLHttpRequest *r = w->d()->request;
2087 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2088 r->readyState() != QQmlXMLHttpRequest::Done) {
2089 return Encode(scope.engine->newString(QString()));
2091 QUrl url = r->url();
2092 url.setFragment(QString());
2093 return Encode(scope.engine->newString(url.toString()));
2097ReturnedValue QQmlXMLHttpRequestCtor::method_overrideMimeType(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
2100 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2103 QQmlXMLHttpRequest *r = w->d()->request;
2106 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
2109 if (r->readyState() == QQmlXMLHttpRequest::Loading ||
2110 r->readyState() == QQmlXMLHttpRequest::Done)
2111 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
2114 r->setOverrideMimeType(QStringLiteral(
"application/octet-stream"));
2115 const auto parts = argv[0].toQStringNoThrow().split(QLatin1Char(
';'));
2116 const auto type = parts.at(0).trimmed();
2118 const auto mimeInvalidCharacter = [](QChar uni) {
2119 if (uni.unicode() > 127)
2121 const char ch =
char(uni.unicode());
2122 return !(ch ==
'-' || ch ==
'/' || isAsciiLetterOrNumber(ch));
2126 if (type.count(QLatin1Char(
'/')) == 1
2127 && std::find_if(type.begin(), type.end(), mimeInvalidCharacter) == type.end()) {
2129 r->setOverrideMimeType(type);
2131 for (
const auto &part : parts) {
2132 const QLatin1String charset(
"charset=");
2134 if (part.trimmed().startsWith(charset)) {
2136 const int offset(part.indexOf(charset) + charset.size());
2137 r->setOverrideCharset(part.sliced(offset).trimmed());
2141 return Encode::undefined();
2154 Scoped<QQmlXMLHttpRequestCtor> ctor(scope, v4->memoryManager->allocate<QQmlXMLHttpRequestCtor>(v4));
2155 ScopedString s(scope, v4->newString(QStringLiteral(
"XMLHttpRequest")));
2156 v4->globalObject->defineReadonlyProperty(s, ctor);
2164#include <qqmlxmlhttprequest.moc>
friend class QQmlEnginePrivate
void setOverrideCharset(QStringView charset)
void setResponseType(const QString &)
void setOverrideMimeType(QStringView mimeType)
ReturnedValue abort(Object *thisObject)
QQmlXMLHttpRequest(QNetworkAccessManager *manager, QV4::ExecutionEngine *v4)
QV4::ReturnedValue jsonResponseBody(QV4::ExecutionEngine *)
const QByteArray charset() const
quint32 readyState() const
const QByteArray & rawResponseBody() const
void addHeader(const QString &, const QString &)
virtual ~QQmlXMLHttpRequest()
QString header(const QString &name) const
QString replyStatusText() const
const QString & responseType() const
const QByteArray mimeType() const
QV4::ReturnedValue xmlResponseBody(QV4::ExecutionEngine *)
ReturnedValue send(Object *thisObject, const QQmlRefPointer< QQmlContextData > &context, const QByteArray &)
ReturnedValue open(Object *thisObject, const QString &, const QUrl &, LoadType)
static ReturnedValue prototype(ExecutionEngine *)
static ReturnedValue method_name(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_value(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_ownerElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue prototype(ExecutionEngine *v4)
static ReturnedValue prototype(ExecutionEngine *v4)
static ReturnedValue method_length(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_xmlStandalone(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue load(ExecutionEngine *engine, const QByteArray &data)
static ReturnedValue prototype(ExecutionEngine *)
static ReturnedValue method_xmlVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_xmlEncoding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue prototype(ExecutionEngine *)
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
QList< NodeImpl * > attributes
QList< NodeImpl * > children
static ReturnedValue create(ExecutionEngine *, NodeImpl *)
static ReturnedValue method_get_childNodes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_nodeValue(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_previousSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_namespaceUri(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue getProto(ExecutionEngine *v4)
static ReturnedValue method_get_parentNode(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_nextSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_nodeType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_lastChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_firstChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_attributes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_nodeName(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_wholeText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue prototype(ExecutionEngine *)
static ReturnedValue method_isElementContentWhitespace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext)
DEFINE_OBJECT_VTABLE(Node)
DEFINE_OBJECT_VTABLE(NodeList)
DEFINE_OBJECT_VTABLE(NamedNodeMap)
DEFINE_OBJECT_VTABLE(NodePrototype)
#define DEFINE_BOOL_CONFIG_OPTION(name, var)
static const char * errorToString(QNetworkReply::NetworkError error)
DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestWrapper)
static QQmlXMLHttpRequestData * xhrdata(ExecutionEngine *v4)
void * qt_add_qmlxmlhttprequest(ExecutionEngine *v4)
DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestCtor)
void qt_rem_qmlxmlhttprequest(ExecutionEngine *, void *d)
#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION
#define V4THROW_REFERENCE(string)
PersistentValue characterDataPrototype
PersistentValue documentPrototype
PersistentValue nodeFunction
PersistentValue elementPrototype
PersistentValue textPrototype
PersistentValue attrPrototype
PersistentValue cdataPrototype
PersistentValue nodePrototype
~QQmlXMLHttpRequestData()
QList< NodeImpl * > * listPtr
void init(NodeImpl *data, const QList< NodeImpl * > &list)
QList< NodeImpl * > & list()
void init(NodeImpl *data)
void init(NodeImpl *data)
QQmlXMLHttpRequest * request
void init(QQmlXMLHttpRequest *request)
static ReturnedValue method_getAllResponseHeaders(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_response(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_responseURL(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setRequestHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_readyState(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_responseText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_open(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_overrideMimeType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getResponseHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_responseXML(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_abort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_statusText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_status(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_send(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)