9#include <private/qqmlrefcount_p.h>
12#include <private/qv4domerrors_p.h>
13#include <private/qv4engine_p.h>
14#include <private/qv4functionobject_p.h>
15#include <private/qv4scopedvalue_p.h>
16#include <private/qv4jscall_p.h>
18#include <QtCore/qobject.h>
19#include <QtQml/qjsvalue.h>
20#include <QtQml/qjsengine.h>
21#include <QtQml/qqmlfile.h>
22#include <QtNetwork/qnetworkreply.h>
24#include <QtCore/qpointer.h>
25#include <QtCore/qstringconverter.h>
26#include <QtCore/qxmlstream.h>
27#include <QtCore/qstack.h>
28#include <QtCore/qdebug.h>
29#include <QtCore/qbuffer.h>
31#include <private/qv4objectproto_p.h>
32#include <private/qv4scopedvalue_p.h>
33#include <private/qv4arraybuffer_p.h>
34#include <private/qv4jsonobject_p.h>
38#define V4THROW_REFERENCE(string)
40 ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string)));
41 return scope.engine->throwError(error);
87 qDeleteAll(attributes);
122class DocumentImpl
final :
public QQmlRefCounted<DocumentImpl>,
public NodeImpl
124 using Base1 = QQmlRefCounted<DocumentImpl>;
152 if (listPtr ==
nullptr)
153 listPtr =
new QList<NodeImpl *>;
270 Scope scope(internalClass->engine);
271 ScopedObject o(scope,
this);
273 o->defineAccessorProperty(QStringLiteral(
"nodeName"), QV4::NodePrototype::method_get_nodeName,
nullptr);
274 o->defineAccessorProperty(QStringLiteral(
"nodeValue"), QV4::NodePrototype::method_get_nodeValue,
nullptr);
275 o->defineAccessorProperty(QStringLiteral(
"nodeType"), QV4::NodePrototype::method_get_nodeType,
nullptr);
276 o->defineAccessorProperty(QStringLiteral(
"namespaceUri"), QV4::NodePrototype::method_get_namespaceUri,
nullptr);
278 o->defineAccessorProperty(QStringLiteral(
"parentNode"), QV4::NodePrototype::method_get_parentNode,
nullptr);
279 o->defineAccessorProperty(QStringLiteral(
"childNodes"), QV4::NodePrototype::method_get_childNodes,
nullptr);
280 o->defineAccessorProperty(QStringLiteral(
"firstChild"), QV4::NodePrototype::method_get_firstChild,
nullptr);
281 o->defineAccessorProperty(QStringLiteral(
"lastChild"), QV4::NodePrototype::method_get_lastChild,
nullptr);
282 o->defineAccessorProperty(QStringLiteral(
"previousSibling"), QV4::NodePrototype::method_get_previousSibling,
nullptr);
283 o->defineAccessorProperty(QStringLiteral(
"nextSibling"), QV4::NodePrototype::method_get_nextSibling,
nullptr);
284 o->defineAccessorProperty(QStringLiteral(
"attributes"), QV4::NodePrototype::method_get_attributes,
nullptr);
292 V4_OBJECT2(
Node, Object)
377void NodeImpl::addref()
382void NodeImpl::release()
387ReturnedValue NodePrototype::method_get_nodeName(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
390 Scoped<Node> r(scope, thisObject->as<Node>());
395 switch (r->d()->d->type) {
396 case NodeImpl::Document:
397 name = QStringLiteral(
"#document");
399 case NodeImpl::CDATA:
400 name = QStringLiteral(
"#cdata-section");
403 name = QStringLiteral(
"#text");
406 name = r->d()->d->name;
409 return Encode(scope.engine->newString(name));
412ReturnedValue NodePrototype::method_get_nodeValue(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
415 Scoped<Node> r(scope, thisObject->as<Node>());
419 if (r->d()->d->type == NodeImpl::Document ||
420 r->d()->d->type == NodeImpl::DocumentFragment ||
421 r->d()->d->type == NodeImpl::DocumentType ||
422 r->d()->d->type == NodeImpl::Element ||
423 r->d()->d->type == NodeImpl::Entity ||
424 r->d()->d->type == NodeImpl::EntityReference ||
425 r->d()->d->type == NodeImpl::Notation)
426 RETURN_RESULT(Encode::null());
428 return Encode(scope.engine->newString(r->d()->d->data));
431ReturnedValue NodePrototype::method_get_nodeType(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
434 Scoped<Node> r(scope, thisObject->as<Node>());
438 return Encode(r->d()->d->type);
441ReturnedValue NodePrototype::method_get_namespaceUri(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
444 Scoped<Node> r(scope, thisObject->as<Node>());
448 return Encode(scope.engine->newString(r->d()->d->namespaceUri));
451ReturnedValue NodePrototype::method_get_parentNode(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
454 Scoped<Node> r(scope, thisObject->as<Node>());
458 if (r->d()->d->parent)
459 return Node::create(scope.engine, r->d()->d->parent);
461 return Encode::null();
464ReturnedValue NodePrototype::method_get_childNodes(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
467 Scoped<Node> r(scope, thisObject->as<Node>());
471 return NodeList::create(scope.engine, r->d()->d);
474ReturnedValue NodePrototype::method_get_firstChild(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
477 Scoped<Node> r(scope, thisObject->as<Node>());
481 if (r->d()->d->children.isEmpty())
482 return Encode::null();
484 return Node::create(scope.engine, r->d()->d->children.constFirst());
487ReturnedValue NodePrototype::method_get_lastChild(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
490 Scoped<Node> r(scope, thisObject->as<Node>());
494 if (r->d()->d->children.isEmpty())
495 return Encode::null();
497 return Node::create(scope.engine, r->d()->d->children.constLast());
500ReturnedValue NodePrototype::method_get_previousSibling(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
503 Scoped<Node> r(scope, thisObject->as<Node>());
507 if (!r->d()->d->parent)
508 RETURN_RESULT(Encode::null());
510 for (
int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
511 if (r->d()->d->parent->children.at(ii) == r->d()->d) {
513 return Encode::null();
515 return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
519 return Encode::null();
522ReturnedValue NodePrototype::method_get_nextSibling(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
525 Scoped<Node> r(scope, thisObject->as<Node>());
529 if (!r->d()->d->parent)
530 RETURN_RESULT(Encode::null());
532 for (
int ii = 0; ii < r->d()->d->parent->children.size(); ++ii) {
533 if (r->d()->d->parent->children.at(ii) == r->d()->d) {
534 if ((ii + 1) == r->d()->d->parent->children.size())
535 return Encode::null();
537 return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
541 return Encode::null();
544ReturnedValue NodePrototype::method_get_attributes(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
547 Scoped<Node> r(scope, thisObject->as<Node>());
551 if (r->d()->d->type != NodeImpl::Element)
552 return Encode::null();
554 return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
557ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
560 QQmlXMLHttpRequestData *d = xhrdata(v4);
561 if (d->nodePrototype.isUndefined()) {
562 ScopedObject p(scope, v4->memoryManager->allocate<NodePrototype>());
563 d->nodePrototype.set(v4, p);
566 return d->nodePrototype.value();
569ReturnedValue Node::create(ExecutionEngine *v4, NodeImpl *data)
573 Scoped<Node> instance(scope, v4->memoryManager->allocate<Node>(data));
574 ScopedObject p(scope);
576 switch (data->type) {
578 instance->setPrototypeUnchecked((p = Attr::prototype(v4)));
580 case NodeImpl::Comment:
581 case NodeImpl::Document:
582 case NodeImpl::DocumentFragment:
583 case NodeImpl::DocumentType:
584 case NodeImpl::Entity:
585 case NodeImpl::EntityReference:
586 case NodeImpl::Notation:
587 case NodeImpl::ProcessingInstruction:
588 return Encode::undefined();
589 case NodeImpl::CDATA:
590 instance->setPrototypeUnchecked((p = CDATA::prototype(v4)));
593 instance->setPrototypeUnchecked((p = Text::prototype(v4)));
595 case NodeImpl::Element:
596 instance->setPrototypeUnchecked((p = Element::prototype(v4)));
600 return instance.asReturnedValue();
603ReturnedValue Element::prototype(ExecutionEngine *engine)
605 QQmlXMLHttpRequestData *d = xhrdata(engine);
606 if (d->elementPrototype.isUndefined()) {
608 ScopedObject p(scope, engine->newObject());
609 ScopedObject pp(scope);
610 p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine)));
611 p->defineAccessorProperty(QStringLiteral(
"tagName"), NodePrototype::method_get_nodeName,
nullptr);
612 d->elementPrototype.set(engine, p);
613 engine->freezeObject(p);
615 return d->elementPrototype.value();
618ReturnedValue Attr::prototype(ExecutionEngine *engine)
620 QQmlXMLHttpRequestData *d = xhrdata(engine);
621 if (d->attrPrototype.isUndefined()) {
623 ScopedObject p(scope, engine->newObject());
624 ScopedObject pp(scope);
625 p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine)));
626 p->defineAccessorProperty(QStringLiteral(
"name"), method_name,
nullptr);
627 p->defineAccessorProperty(QStringLiteral(
"value"), method_value,
nullptr);
628 p->defineAccessorProperty(QStringLiteral(
"ownerElement"), method_ownerElement,
nullptr);
629 d->attrPrototype.set(engine, p);
630 engine->freezeObject(p);
632 return d->attrPrototype.value();
635ReturnedValue Attr::method_name(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
638 Scoped<Node> r(scope, thisObject->as<Node>());
642 return Encode(scope.engine->newString(r->d()->d->name));
645ReturnedValue Attr::method_value(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
648 Scoped<Node> r(scope, thisObject->as<Node>());
652 return Encode(scope.engine->newString(r->d()->d->data));
655ReturnedValue Attr::method_ownerElement(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
658 Scoped<Node> r(scope, thisObject->as<Node>());
662 return Node::create(scope.engine, r->d()->d->parent);
665ReturnedValue CharacterData::method_length(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
668 Scoped<Node> r(scope, thisObject->as<Node>());
672 return Encode(
int(r->d()->d->data.size()));
675ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
677 QQmlXMLHttpRequestData *d = xhrdata(v4);
678 if (d->characterDataPrototype.isUndefined()) {
680 ScopedObject p(scope, v4->newObject());
681 ScopedObject pp(scope);
682 p->setPrototypeUnchecked((pp = NodePrototype::getProto(v4)));
683 p->defineAccessorProperty(QStringLiteral(
"data"), NodePrototype::method_get_nodeValue,
nullptr);
684 p->defineAccessorProperty(QStringLiteral(
"length"), method_length,
nullptr);
685 d->characterDataPrototype.set(v4, p);
688 return d->characterDataPrototype.value();
691ReturnedValue Text::method_isElementContentWhitespace(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
694 Scoped<Node> r(scope, thisObject->as<Node>());
698 return Encode(QStringView(r->d()->d->data).trimmed().isEmpty());
701ReturnedValue Text::method_wholeText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
704 Scoped<Node> r(scope, thisObject->as<Node>());
708 return Encode(scope.engine->newString(r->d()->d->data));
711ReturnedValue Text::prototype(ExecutionEngine *v4)
713 QQmlXMLHttpRequestData *d = xhrdata(v4);
714 if (d->textPrototype.isUndefined()) {
716 ScopedObject p(scope, v4->newObject());
717 ScopedObject pp(scope);
718 p->setPrototypeUnchecked((pp = CharacterData::prototype(v4)));
719 p->defineAccessorProperty(QStringLiteral(
"isElementContentWhitespace"), method_isElementContentWhitespace,
nullptr);
720 p->defineAccessorProperty(QStringLiteral(
"wholeText"), method_wholeText,
nullptr);
721 d->textPrototype.set(v4, p);
724 return d->textPrototype.value();
727ReturnedValue CDATA::prototype(ExecutionEngine *v4)
730 QQmlXMLHttpRequestData *d = xhrdata(v4);
731 if (d->cdataPrototype.isUndefined()) {
733 ScopedObject p(scope, v4->newObject());
734 ScopedObject pp(scope);
735 p->setPrototypeUnchecked((pp = Text::prototype(v4)));
736 d->cdataPrototype.set(v4, p);
739 return d->cdataPrototype.value();
742ReturnedValue Document::prototype(ExecutionEngine *v4)
744 QQmlXMLHttpRequestData *d = xhrdata(v4);
745 if (d->documentPrototype.isUndefined()) {
747 ScopedObject p(scope, v4->newObject());
748 ScopedObject pp(scope);
749 p->setPrototypeUnchecked((pp = NodePrototype::getProto(v4)));
750 p->defineAccessorProperty(QStringLiteral(
"xmlVersion"), method_xmlVersion,
nullptr);
751 p->defineAccessorProperty(QStringLiteral(
"xmlEncoding"), method_xmlEncoding,
nullptr);
752 p->defineAccessorProperty(QStringLiteral(
"xmlStandalone"), method_xmlStandalone,
nullptr);
753 p->defineAccessorProperty(QStringLiteral(
"documentElement"), method_documentElement,
nullptr);
754 d->documentPrototype.set(v4, p);
757 return d->documentPrototype.value();
760ReturnedValue Document::load(ExecutionEngine *v4,
const QByteArray &data)
764 DocumentImpl *document =
nullptr;
765 QStack<NodeImpl *> nodeStack;
767 QXmlStreamReader reader(data);
769 while (!reader.atEnd()) {
770 switch (reader.readNext()) {
771 case QXmlStreamReader::NoToken:
773 case QXmlStreamReader::Invalid:
775 case QXmlStreamReader::StartDocument:
777 document =
new DocumentImpl;
778 document->document = document;
779 document->version = reader.documentVersion().toString();
780 document->encoding = reader.documentEncoding().toString();
781 document->isStandalone = reader.isStandaloneDocument();
783 case QXmlStreamReader::EndDocument:
785 case QXmlStreamReader::StartElement:
788 NodeImpl *node =
new NodeImpl;
789 node->document = document;
790 node->namespaceUri = reader.namespaceUri().toString();
791 node->name = reader.name().toString();
792 if (nodeStack.isEmpty()) {
793 document->root = node;
795 node->parent = nodeStack.top();
796 node->parent->children.append(node);
798 nodeStack.append(node);
800 const auto attributes = reader.attributes();
801 for (
const QXmlStreamAttribute &a : attributes) {
802 NodeImpl *attr =
new NodeImpl;
803 attr->document = document;
804 attr->type = NodeImpl::Attr;
805 attr->namespaceUri = a.namespaceUri().toString();
806 attr->name = a.name().toString();
807 attr->data = a.value().toString();
809 node->attributes.append(attr);
813 case QXmlStreamReader::EndElement:
816 case QXmlStreamReader::Characters:
818 NodeImpl *node =
new NodeImpl;
819 node->document = document;
820 node->type = reader.isCDATA()?NodeImpl::CDATA:NodeImpl::Text;
821 node->parent = nodeStack.top();
822 node->parent->children.append(node);
823 node->data = reader.text().toString();
826 case QXmlStreamReader::Comment:
828 case QXmlStreamReader::DTD:
830 case QXmlStreamReader::EntityReference:
832 case QXmlStreamReader::ProcessingInstruction:
837 if (!document || reader.hasError()) {
840 return Encode::null();
843 ScopedObject instance(scope, v4->memoryManager->allocate<Node>(document));
845 ScopedObject p(scope);
846 instance->setPrototypeUnchecked((p = Document::prototype(v4)));
847 return instance.asReturnedValue();
850bool Node::isNull()
const
852 return d()->d ==
nullptr;
855ReturnedValue NamedNodeMap::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
857 Q_ASSERT(m->as<NamedNodeMap>());
859 const NamedNodeMap *r =
static_cast<
const NamedNodeMap *>(m);
860 QV4::ExecutionEngine *v4 = r->engine();
862 if (id.isArrayIndex()) {
863 uint index = id.asArrayIndex();
865 if ((
int)index < r->d()->list().size()) {
868 return Node::create(v4, r->d()->list().at(index));
871 *hasProperty =
false;
872 return Encode::undefined();
876 return Object::virtualGet(m, id, receiver, hasProperty);
878 if (id == v4->id_length()->propertyKey())
879 return Value::fromInt32(r->d()->list().size()).asReturnedValue();
881 QString str = id.toQString();
882 for (
int ii = 0; ii < r->d()->list().size(); ++ii) {
883 if (r->d()->list().at(ii)->name == str) {
886 return Node::create(v4, r->d()->list().at(ii));
891 *hasProperty =
false;
892 return Encode::undefined();
895ReturnedValue NamedNodeMap::create(ExecutionEngine *v4, NodeImpl *data,
const QList<NodeImpl *> &list)
897 return (v4->memoryManager->allocate<NamedNodeMap>(data, list))->asReturnedValue();
900ReturnedValue NodeList::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
902 Q_ASSERT(m->as<NodeList>());
903 const NodeList *r =
static_cast<
const NodeList *>(m);
904 QV4::ExecutionEngine *v4 = r->engine();
906 if (id.isArrayIndex()) {
907 uint index = id.asArrayIndex();
908 if ((
int)index < r->d()->d->children.size()) {
911 return Node::create(v4, r->d()->d->children.at(index));
914 *hasProperty =
false;
915 return Encode::undefined();
918 if (id == v4->id_length()->propertyKey())
919 return Value::fromInt32(r->d()->d->children.size()).asReturnedValue();
920 return Object::virtualGet(m, id, receiver, hasProperty);
923ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
925 return (v4->memoryManager->allocate<NodeList>(data))->asReturnedValue();
928ReturnedValue Document::method_documentElement(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
931 Scoped<Node> r(scope, thisObject->as<Node>());
932 if (!r || r->d()->d->type != NodeImpl::Document)
935 return Node::create(scope.engine,
static_cast<DocumentImpl *>(r->d()->d)->root);
938ReturnedValue Document::method_xmlStandalone(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
941 Scoped<Node> r(scope, thisObject->as<Node>());
942 if (!r || r->d()->d->type != NodeImpl::Document)
945 return Encode(
static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
948ReturnedValue Document::method_xmlVersion(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
951 Scoped<Node> r(scope, thisObject->as<Node>());
952 if (!r || r->d()->d->type != NodeImpl::Document)
955 return Encode(scope.engine->newString(
static_cast<DocumentImpl *>(r->d()->d)->version));
958ReturnedValue Document::method_xmlEncoding(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
961 Scoped<Node> r(scope, thisObject->as<Node>());
962 if (!r || r->d()->d->type != NodeImpl::Document)
965 return Encode(scope.engine->newString(
static_cast<DocumentImpl *>(r->d()->d)->encoding));
1019 void error(QNetworkReply::NetworkError);
1023 void requestFromUrl(
const QUrl &url);
1030 QByteArray m_responseEntityBody;
1032 int m_redirectCount;
1034 typedef std::pair<QByteArray, QByteArray> HeaderPair;
1035 typedef QList<HeaderPair> HeadersList;
1036 HeadersList m_headersList;
1037 void fillHeadersList();
1041 QByteArray m_charset;
1042 QByteArray m_overrideMime;
1043 QByteArray m_overrideCharset;
1045 QStringDecoder findTextDecoder()
const;
1046 void readEncoding();
1048 PersistentValue m_thisObject;
1049 QQmlRefPointer<QQmlContextData> m_qmlContext;
1050 bool m_wasConstructedWithQmlContext =
true;
1052 void dispatchCallbackNow(Object *thisObj);
1053 static void dispatchCallbackNow(Object *thisObj,
bool done,
bool error);
1054 void dispatchCallbackSafely();
1057 QString m_statusText;
1058 QNetworkRequest m_request;
1059 QStringList m_addedHeaders;
1060 QPointer<QNetworkReply> m_network;
1061 void destroyNetwork();
1063 QNetworkAccessManager *m_nam;
1064 QNetworkAccessManager *networkAccessManager() {
return m_nam; }
1066 QString m_responseType;
1067 QV4::PersistentValue m_parsedDocument;
1071 : m_state(
Unsent), m_errorFlag(
false), m_sendFlag(
false)
1072 , m_redirectCount(0), m_gotXml(
false),
m_network(
nullptr), m_nam(manager)
1074 m_wasConstructedWithQmlContext = !v4->callingQmlContext().isNull();
1104 return m_statusText;
1111 m_errorFlag =
false;
1112 m_responseEntityBody = QByteArray();
1115 m_request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, loadType == SynchronousLoad);
1117 m_addedHeaders.clear();
1118 dispatchCallbackNow(thisObject);
1119 return Encode::undefined();
1124 QByteArray utfname = name.toUtf8();
1126 if (m_addedHeaders.contains(name, Qt::CaseInsensitive)) {
1127 m_request.setRawHeader(utfname, m_request.rawHeader(utfname) +
',' + value.toUtf8());
1129 m_request.setRawHeader(utfname, value.toUtf8());
1130 m_addedHeaders.append(name);
1136 if (!m_headersList.isEmpty()) {
1137 const QByteArray utfname = name.toLower().toUtf8();
1138 for (
const HeaderPair &header : m_headersList) {
1139 if (header.first == utfname)
1140 return QString::fromUtf8(header.second);
1150 for (
const HeaderPair &header : m_headersList) {
1152 ret.append(QLatin1String(
"\r\n"));
1153 ret += QString::fromUtf8(header.first) + QLatin1String(
": ")
1154 + QString::fromUtf8(header.second);
1161 const QList<QByteArray> headerList = m_network->rawHeaderList();
1163 m_headersList.clear();
1164 for (
const QByteArray &header : headerList) {
1165 HeaderPair pair (header.toLower(), m_network->rawHeader(header));
1166 if (pair.first ==
"set-cookie" ||
1167 pair.first ==
"set-cookie2")
1170 m_headersList << pair;
1177 QNetworkRequest request = m_request;
1179 if (QQmlFile::isLocalFile(url)) {
1180 if (m_method == QLatin1String(
"PUT"))
1182 if (!xhrFileWrite()) {
1183 qWarning(
"XMLHttpRequest: Using PUT on a local file is disabled by default.\n"
1184 "Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature.");
1187 }
else if (m_method == QLatin1String(
"GET")) {
1188 if (!xhrFileRead()) {
1189 qWarning(
"XMLHttpRequest: Using GET on a local file is disabled by default.\n"
1190 "Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.");
1194 qWarning(
"XMLHttpRequest: Unsupported method used on a local file");
1199 request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
1200 request.setUrl(url);
1201 if(m_method == QLatin1String(
"POST") ||
1202 m_method == QLatin1String(
"PUT")) {
1203 QVariant var = request.header(QNetworkRequest::ContentTypeHeader);
1204 if (var.isValid()) {
1205 QString str = var.toString();
1206 int charsetIdx = str.indexOf(QLatin1String(
"charset="));
1207 if (charsetIdx == -1) {
1209 if (!str.isEmpty()) str.append(QLatin1Char(
';'));
1210 str.append(QLatin1String(
"charset=UTF-8"));
1214 int semiColon = str.indexOf(QLatin1Char(
';'), charsetIdx);
1215 if (semiColon == -1) {
1216 n = str.size() - charsetIdx;
1218 n = semiColon - charsetIdx;
1221 str.replace(charsetIdx, n, QLatin1String(
"UTF-8"));
1223 request.setHeader(QNetworkRequest::ContentTypeHeader, str);
1225 request.setHeader(QNetworkRequest::ContentTypeHeader,
1226 QLatin1String(
"text/plain;charset=UTF-8"));
1231 qWarning().nospace() <<
"XMLHttpRequest: " << qPrintable(m_method) <<
' ' << qPrintable(url.toString());
1232 if (!m_data.isEmpty()) {
1233 qWarning().nospace() <<
" "
1234 << qPrintable(QString::fromUtf8(m_data));
1238 if (m_method == QLatin1String(
"GET")) {
1239 m_network = networkAccessManager()->get(request);
1240 }
else if (m_method == QLatin1String(
"HEAD")) {
1241 m_network = networkAccessManager()->head(request);
1242 }
else if (m_method == QLatin1String(
"POST")) {
1243 m_network = networkAccessManager()->post(request, m_data);
1244 }
else if (m_method == QLatin1String(
"PUT")) {
1245 m_network = networkAccessManager()->put(request, m_data);
1246 }
else if (m_method == QLatin1String(
"DELETE")) {
1247 m_network = networkAccessManager()->deleteResource(request);
1248 }
else if ((m_method == QLatin1String(
"OPTIONS")) ||
1249 m_method == QLatin1String(
"PROPFIND") ||
1250 m_method == QLatin1String(
"PATCH")) {
1251 QBuffer *buffer =
new QBuffer;
1252 buffer->setData(m_data);
1253 buffer->open(QIODevice::ReadOnly);
1254 m_network = networkAccessManager()->sendCustomRequest(request, QByteArray(m_method.toUtf8().constData()), buffer);
1255 buffer->setParent(m_network);
1258 if (m_request.attribute(QNetworkRequest::SynchronousRequestAttribute).toBool()) {
1259 if (m_network->bytesAvailable() > 0)
1262 QNetworkReply::NetworkError networkError = m_network->error();
1263 if (networkError != QNetworkReply::NoError) {
1264 error(networkError);
1269 QObject::connect(m_network, SIGNAL(readyRead()),
1270 this, SLOT(readyRead()));
1271 QObject::connect(m_network, SIGNAL(errorOccurred(QNetworkReply::NetworkError)),
1272 this, SLOT(error(QNetworkReply::NetworkError)));
1273 QObject::connect(m_network, SIGNAL(finished()),
1274 this, SLOT(finished()));
1279 Object *thisObject,
const QQmlRefPointer<QQmlContextData> &context,
const QByteArray &data)
1281 m_errorFlag =
false;
1283 m_redirectCount = 0;
1286 m_thisObject = thisObject;
1287 m_qmlContext = context;
1289 requestFromUrl(m_url);
1291 return Encode::undefined();
1297 m_responseEntityBody = QByteArray();
1299 m_request = QNetworkRequest();
1301 if (!(m_state ==
Unsent ||
1302 (m_state ==
Opened && !m_sendFlag) ||
1307 dispatchCallbackNow(thisObject);
1312 return Encode::undefined();
1318 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1320 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1326 dispatchCallbackSafely();
1329 bool wasEmpty = m_responseEntityBody.isEmpty();
1330 m_responseEntityBody.append(m_network->readAll());
1331 if (wasEmpty && !m_responseEntityBody.isEmpty())
1334 dispatchCallbackSafely();
1339 int idx = QNetworkReply::staticMetaObject.indexOfEnumerator(
"NetworkError");
1340 if (idx == -1)
return "EnumLookupFailed";
1342 QMetaEnum e = QNetworkReply::staticMetaObject.enumerator(idx);
1344 const char *name = e.valueToKey(error);
1345 if (!name)
return "EnumLookupFailed";
1352 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1354 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1356 m_request = QNetworkRequest();
1361 qWarning().nospace() <<
"XMLHttpRequest: ERROR " << qPrintable(m_url.toString());
1362 qWarning().nospace() <<
" " << error <<
' ' << errorToString(error) <<
' ' << m_statusText;
1365 if (error == QNetworkReply::ContentAccessDenied ||
1366 error == QNetworkReply::ContentOperationNotPermittedError ||
1367 error == QNetworkReply::ContentNotFoundError ||
1368 error == QNetworkReply::AuthenticationRequiredError ||
1369 error == QNetworkReply::ContentReSendError ||
1370 error == QNetworkReply::ContentConflictError ||
1371 error == QNetworkReply::ContentGoneError ||
1372 error == QNetworkReply::UnknownContentError ||
1373 error == QNetworkReply::ProtocolInvalidOperationError ||
1374 error == QNetworkReply::InternalServerError ||
1375 error == QNetworkReply::OperationNotImplementedError ||
1376 error == QNetworkReply::ServiceUnavailableError ||
1377 error == QNetworkReply::UnknownServerError) {
1379 dispatchCallbackSafely();
1382 m_responseEntityBody = QByteArray();
1386 dispatchCallbackSafely();
1389#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION 15
1394 QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
1395 if (redirect.isValid()) {
1396 QUrl url = m_network->url().resolved(redirect.toUrl());
1397 if (!QQmlFile::isLocalFile(url)) {
1400 const QVariant code = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute);
1401 if (code.isValid() && code.toInt() == 303 && m_method != QLatin1String(
"GET"))
1402 m_method = QStringLiteral(
"GET");
1406 m_responseEntityBody = QByteArray();
1408 requestFromUrl(url);
1415 m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
1417 QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
1422 dispatchCallbackSafely();
1424 m_responseEntityBody.append(m_network->readAll());
1428 qWarning().nospace() <<
"XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
1429 if (!m_responseEntityBody.isEmpty()) {
1430 qWarning().nospace() <<
" "
1431 << qPrintable(QString::fromUtf8(m_responseEntityBody));
1439 dispatchCallbackSafely();
1443 dispatchCallbackSafely();
1445 m_thisObject.clear();
1446 m_qmlContext.reset();
1452 for (
const HeaderPair &header : std::as_const(m_headersList)) {
1453 if (header.first ==
"content-type") {
1454 int separatorIdx = header.second.indexOf(
';');
1455 if (separatorIdx == -1) {
1456 m_mime = header.second;
1458 m_mime = header.second.mid(0, separatorIdx);
1459 int charsetIdx = header.second.indexOf(
"charset=");
1460 if (charsetIdx != -1) {
1462 separatorIdx = header.second.indexOf(
';', charsetIdx);
1463 m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.size());
1470 const auto mime = mimeType();
1471 if (mime.isEmpty() || mime ==
"text/xml" || mime ==
"application/xml" || mime.endsWith(
"+xml"))
1489 return m_overrideMime.isEmpty() ? m_mime : m_overrideMime;
1496 return m_overrideCharset.isEmpty() ? m_charset : m_overrideCharset;
1501 return m_responseType;
1506 m_responseType = responseType;
1511 if (m_parsedDocument.isEmpty()) {
1512 Scope scope(engine);
1514 QJsonParseError error;
1515 const QString& jtext = responseBody();
1516 JsonParser parser(scope.engine, jtext.constData(), jtext.size());
1517 ScopedValue jsonObject(scope, parser.parse(&error));
1518 if (error.error != QJsonParseError::NoError)
1519 return engine->throwSyntaxError(QStringLiteral(
"JSON.parse: Parse error"));
1521 m_parsedDocument.set(scope.engine, jsonObject);
1524 return m_parsedDocument.value();
1529 if (m_parsedDocument.isEmpty()) {
1530 m_parsedDocument.set(engine, Document::load(engine, rawResponseBody()));
1533 return m_parsedDocument.value();
1538 QStringDecoder decoder;
1540 if (!charset().isEmpty())
1541 decoder = QStringDecoder(charset());
1543 if (!decoder.isValid() && m_gotXml) {
1544 QXmlStreamReader reader(m_responseEntityBody);
1546 decoder = QStringDecoder(reader.documentEncoding().toString().toUtf8());
1549 if (!decoder.isValid() && mimeType() ==
"text/html")
1550 decoder = QStringDecoder::decoderForHtml(m_responseEntityBody);
1552 if (!decoder.isValid()) {
1553 auto encoding = QStringConverter::encodingForData(m_responseEntityBody);
1555 decoder = QStringDecoder(*encoding);
1558 if (!decoder.isValid())
1559 decoder = QStringDecoder(QStringDecoder::Utf8);
1566 QStringDecoder toUtf16 = findTextDecoder();
1567 return toUtf16(m_responseEntityBody);
1572 return m_responseEntityBody;
1577 dispatchCallbackNow(thisObj, m_state == Done, m_errorFlag);
1584 const auto dispatch = [thisObj](
const QString &eventName) {
1585 QV4::Scope scope(thisObj->engine());
1586 ScopedString s(scope, scope.engine->newString(eventName));
1587 ScopedFunctionObject callback(scope, thisObj->get(s));
1592 QV4::JSCallArguments jsCallData(scope);
1593 callback->call(jsCallData);
1595 if (scope.hasException()) {
1596 QQmlError error = scope.engine->catchExceptionAsQmlError();
1597 QQmlEnginePrivate *qmlEnginePrivate = scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) :
nullptr;
1598 QQmlEnginePrivate::warning(qmlEnginePrivate, error);
1602 dispatch(QStringLiteral(
"onreadystatechange"));
1605 dispatch(QStringLiteral(
"onerror"));
1607 dispatch(QStringLiteral(
"onload"));
1608 dispatch(QStringLiteral(
"onloadend"));
1614 if (m_wasConstructedWithQmlContext && m_qmlContext.isNull()) {
1622 dispatchCallbackNow(m_thisObject.as<Object>());
1628 m_network->disconnect();
1629 m_network->deleteLater();
1630 m_network =
nullptr;
1650#define QQmlXMLHttpRequestCtorMembers(class, Member)
1651 Member(class, Pointer, Object *, proto)
1654 DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor)
1655 void init(ExecutionEngine *engine);
1713void Heap::QQmlXMLHttpRequestCtor::init(ExecutionEngine *engine)
1715 Heap::FunctionObject::init(engine, QStringLiteral(
"XMLHttpRequest"));
1716 Scope scope(engine);
1717 Scoped<QV4::QQmlXMLHttpRequestCtor> ctor(scope,
this);
1719 ctor->defineReadonlyProperty(QStringLiteral(
"UNSENT"), Value::fromInt32(QQmlXMLHttpRequest::Unsent));
1720 ctor->defineReadonlyProperty(QStringLiteral(
"OPENED"), Value::fromInt32(QQmlXMLHttpRequest::Opened));
1721 ctor->defineReadonlyProperty(QStringLiteral(
"HEADERS_RECEIVED"), Value::fromInt32(QQmlXMLHttpRequest::HeadersReceived));
1722 ctor->defineReadonlyProperty(QStringLiteral(
"LOADING"), Value::fromInt32(QQmlXMLHttpRequest::Loading));
1723 ctor->defineReadonlyProperty(QStringLiteral(
"DONE"), Value::fromInt32(QQmlXMLHttpRequest::Done));
1725 if (!ctor->d()->proto)
1727 ScopedString s(scope, engine->id_prototype());
1728 ctor->defineDefaultProperty(s, ScopedObject(scope, ctor->d()->proto));
1733void QQmlXMLHttpRequestCtor::setupProto()
1735 ExecutionEngine *v4 = engine();
1737 ScopedObject p(scope, v4->newObject());
1738 d()->proto.set(scope.engine, p->d());
1741 p->defineDefaultProperty(QStringLiteral(
"open"), method_open);
1742 p->defineDefaultProperty(QStringLiteral(
"setRequestHeader"), method_setRequestHeader);
1743 p->defineDefaultProperty(QStringLiteral(
"send"), method_send);
1744 p->defineDefaultProperty(QStringLiteral(
"abort"), method_abort);
1745 p->defineDefaultProperty(QStringLiteral(
"getResponseHeader"), method_getResponseHeader);
1746 p->defineDefaultProperty(QStringLiteral(
"getAllResponseHeaders"), method_getAllResponseHeaders);
1747 p->defineDefaultProperty(QStringLiteral(
"overrideMimeType"), method_overrideMimeType);
1750 p->defineAccessorProperty(QStringLiteral(
"readyState"), method_get_readyState,
nullptr);
1751 p->defineAccessorProperty(QStringLiteral(
"status"),method_get_status,
nullptr);
1752 p->defineAccessorProperty(QStringLiteral(
"statusText"),method_get_statusText,
nullptr);
1753 p->defineAccessorProperty(QStringLiteral(
"responseText"),method_get_responseText,
nullptr);
1754 p->defineAccessorProperty(QStringLiteral(
"responseXML"),method_get_responseXML,
nullptr);
1755 p->defineAccessorProperty(QStringLiteral(
"response"),method_get_response,
nullptr);
1756 p->defineAccessorProperty(QStringLiteral(
"responseURL"),method_get_responseURL,
nullptr);
1759 p->defineAccessorProperty(QStringLiteral(
"responseType"), method_get_responseType, method_set_responseType);
1762 p->defineReadonlyProperty(QStringLiteral(
"UNSENT"), Value::fromInt32(0));
1763 p->defineReadonlyProperty(QStringLiteral(
"OPENED"), Value::fromInt32(1));
1764 p->defineReadonlyProperty(QStringLiteral(
"HEADERS_RECEIVED"), Value::fromInt32(2));
1765 p->defineReadonlyProperty(QStringLiteral(
"LOADING"), Value::fromInt32(3));
1766 p->defineReadonlyProperty(QStringLiteral(
"DONE"), Value::fromInt32(4));
1771ReturnedValue QQmlXMLHttpRequestCtor::method_open(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1774 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1777 QQmlXMLHttpRequest *r = w->d()->request;
1779 if (argc < 2 || argc > 5)
1780 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1783 QString method = argv[0].toQStringNoThrow().toUpper();
1784 if (method != QLatin1String(
"GET") &&
1785 method != QLatin1String(
"PUT") &&
1786 method != QLatin1String(
"HEAD") &&
1787 method != QLatin1String(
"POST") &&
1788 method != QLatin1String(
"DELETE") &&
1789 method != QLatin1String(
"OPTIONS") &&
1790 method != QLatin1String(
"PROPFIND") &&
1791 method != QLatin1String(
"PATCH"))
1792 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Unsupported HTTP method type");
1795 QUrl url = QUrl(argv[1].toQStringNoThrow());
1797 if (url.isRelative()) {
1798 if (QQmlRefPointer<QQmlContextData> qmlContextData = scope.engine->callingQmlContext())
1799 url = qmlContextData->resolvedUrl(url);
1801 url = scope.engine->resolvedUrl(url.url());
1807 async = argv[2].booleanValue();
1811 QString username, password;
1813 username = argv[3].toQStringNoThrow();
1815 password = argv[4].toQStringNoThrow();
1818 url.setFragment(QString());
1821 if (!username.isNull()) url.setUserName(username);
1822 if (!password.isNull()) url.setPassword(password);
1824 return r->open(w, method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
1827ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1830 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1833 QQmlXMLHttpRequest *r = w->d()->request;
1836 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1838 if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
1839 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1841 QString name = argv[0].toQStringNoThrow();
1842 QString value = argv[1].toQStringNoThrow();
1846 QString nameUpper = name.toUpper();
1847 if (nameUpper == QLatin1String(
"ACCEPT-CHARSET") ||
1848 nameUpper == QLatin1String(
"ACCEPT-ENCODING") ||
1849 nameUpper == QLatin1String(
"CONNECTION") ||
1850 nameUpper == QLatin1String(
"CONTENT-LENGTH") ||
1851 nameUpper == QLatin1String(
"COOKIE") ||
1852 nameUpper == QLatin1String(
"COOKIE2") ||
1853 nameUpper == QLatin1String(
"CONTENT-TRANSFER-ENCODING") ||
1854 nameUpper == QLatin1String(
"DATE") ||
1855 nameUpper == QLatin1String(
"EXPECT") ||
1856 nameUpper == QLatin1String(
"HOST") ||
1857 nameUpper == QLatin1String(
"KEEP-ALIVE") ||
1858 nameUpper == QLatin1String(
"REFERER") ||
1859 nameUpper == QLatin1String(
"TE") ||
1860 nameUpper == QLatin1String(
"TRAILER") ||
1861 nameUpper == QLatin1String(
"TRANSFER-ENCODING") ||
1862 nameUpper == QLatin1String(
"UPGRADE") ||
1863 nameUpper == QLatin1String(
"VIA") ||
1864 nameUpper.startsWith(QLatin1String(
"PROXY-")) ||
1865 nameUpper.startsWith(QLatin1String(
"SEC-")))
1868 r->addHeader(name, value);
1873ReturnedValue QQmlXMLHttpRequestCtor::method_send(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1876 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1879 QQmlXMLHttpRequest *r = w->d()->request;
1881 if (r->readyState() != QQmlXMLHttpRequest::Opened ||
1883 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1887 if (
const ArrayBuffer *buffer = argv[0].as<ArrayBuffer>()) {
1888 data = buffer->asByteArray();
1890 data = argv[0].toQStringNoThrow().toUtf8();
1894 return r->send(w, scope.engine->callingQmlContext(), data);
1897ReturnedValue QQmlXMLHttpRequestCtor::method_abort(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1900 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1903 QQmlXMLHttpRequest *r = w->d()->request;
1908ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
1911 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1914 QQmlXMLHttpRequest *r = w->d()->request;
1917 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1919 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
1920 r->readyState() != QQmlXMLHttpRequest::Done &&
1921 r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
1922 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1924 return Encode(scope.engine->newString(r->header(argv[0].toQStringNoThrow())));
1927ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int argc)
1930 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1933 QQmlXMLHttpRequest *r = w->d()->request;
1936 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
1938 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
1939 r->readyState() != QQmlXMLHttpRequest::Done &&
1940 r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
1941 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1943 return Encode(scope.engine->newString(r->headers()));
1947ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1950 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1953 QQmlXMLHttpRequest *r = w->d()->request;
1955 return Encode(r->readyState());
1958ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1961 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1964 QQmlXMLHttpRequest *r = w->d()->request;
1966 if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
1967 r->readyState() == QQmlXMLHttpRequest::Opened)
1968 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1973 return Encode(r->replyStatus());
1976ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1979 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
1982 QQmlXMLHttpRequest *r = w->d()->request;
1984 if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
1985 r->readyState() == QQmlXMLHttpRequest::Opened)
1986 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
1989 return Encode(scope.engine->newString(QString()));
1991 return Encode(scope.engine->newString(r->replyStatusText()));
1994ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
1997 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2000 QQmlXMLHttpRequest *r = w->d()->request;
2002 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2003 r->readyState() != QQmlXMLHttpRequest::Done)
2004 return Encode(scope.engine->newString(QString()));
2006 return Encode(scope.engine->newString(r->responseBody()));
2009ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2012 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2015 QQmlXMLHttpRequest *r = w->d()->request;
2017 if (!r->receivedXml() ||
2018 (r->readyState() != QQmlXMLHttpRequest::Loading &&
2019 r->readyState() != QQmlXMLHttpRequest::Done)) {
2020 return Encode::null();
2022 if (r->responseType().isEmpty())
2023 r->setResponseType(QLatin1String(
"document"));
2024 return r->xmlResponseBody(scope.engine);
2028ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2031 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2034 QQmlXMLHttpRequest *r = w->d()->request;
2036 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2037 r->readyState() != QQmlXMLHttpRequest::Done)
2038 RETURN_RESULT(scope.engine->newString(QString()));
2040 const QString& responseType = r->responseType();
2041 if (responseType.compare(QLatin1String(
"text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) {
2042 RETURN_RESULT(scope.engine->newString(r->responseBody()));
2043 }
else if (responseType.compare(QLatin1String(
"arraybuffer"), Qt::CaseInsensitive) == 0) {
2044 RETURN_RESULT(scope.engine->newArrayBuffer(r->rawResponseBody()));
2045 }
else if (responseType.compare(QLatin1String(
"json"), Qt::CaseInsensitive) == 0) {
2046 RETURN_RESULT(r->jsonResponseBody(scope.engine));
2047 }
else if (responseType.compare(QLatin1String(
"document"), Qt::CaseInsensitive) == 0) {
2048 RETURN_RESULT(r->xmlResponseBody(scope.engine));
2050 RETURN_RESULT(scope.engine->newString(QString()));
2055ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2058 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2061 QQmlXMLHttpRequest *r = w->d()->request;
2062 return Encode(scope.engine->newString(r->responseType()));
2065ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
2068 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2071 QQmlXMLHttpRequest *r = w->d()->request;
2074 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
2077 r->setResponseType(argv[0].toQStringNoThrow());
2079 return Encode::undefined();
2082ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseURL(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
2085 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2088 QQmlXMLHttpRequest *r = w->d()->request;
2090 if (r->readyState() != QQmlXMLHttpRequest::Loading &&
2091 r->readyState() != QQmlXMLHttpRequest::Done) {
2092 return Encode(scope.engine->newString(QString()));
2094 QUrl url = r->url();
2095 url.setFragment(QString());
2096 return Encode(scope.engine->newString(url.toString()));
2100ReturnedValue QQmlXMLHttpRequestCtor::method_overrideMimeType(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
2103 Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
2106 QQmlXMLHttpRequest *r = w->d()->request;
2109 THROW_DOM(DOMEXCEPTION_SYNTAX_ERR,
"Incorrect argument count");
2112 if (r->readyState() == QQmlXMLHttpRequest::Loading ||
2113 r->readyState() == QQmlXMLHttpRequest::Done)
2114 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR,
"Invalid state");
2117 r->setOverrideMimeType(QStringLiteral(
"application/octet-stream"));
2118 const auto parts = argv[0].toQStringNoThrow().split(QLatin1Char(
';'));
2119 const auto type = parts.at(0).trimmed();
2121 const auto mimeInvalidCharacter = [](QChar uni) {
2122 if (uni.unicode() > 127)
2124 const char ch =
char(uni.unicode());
2125 return !(ch ==
'-' || ch ==
'/' || isAsciiLetterOrNumber(ch));
2129 if (type.count(QLatin1Char(
'/')) == 1
2130 && std::find_if(type.begin(), type.end(), mimeInvalidCharacter) == type.end()) {
2132 r->setOverrideMimeType(type);
2134 for (
const auto &part : parts) {
2135 const QLatin1String charset(
"charset=");
2137 if (part.trimmed().startsWith(charset)) {
2139 const int offset(part.indexOf(charset) + charset.size());
2140 r->setOverrideCharset(part.sliced(offset).trimmed());
2144 return Encode::undefined();
2157 Scoped<QQmlXMLHttpRequestCtor> ctor(scope, v4->memoryManager->allocate<QQmlXMLHttpRequestCtor>(v4));
2158 ScopedString s(scope, v4->newString(QStringLiteral(
"XMLHttpRequest")));
2159 v4->globalObject->defineReadonlyProperty(s, ctor);
2167#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)