📄 xmlhttprequest.cpp
字号:
// -*- c-basic-offset: 2 -*-/* * This file is part of the KDE libraries * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "xmlhttprequest.h"#include "xmlhttprequest.lut.h"#include "kjs_window.h"#include "kjs_events.h"#include "dom/dom_doc.h"#include "dom/dom_exception.h"#include "dom/dom_string.h"#include "misc/loader.h"#include "html/html_documentimpl.h"#include "xml/dom2_eventsimpl.h"#include "khtml_part.h"#include "khtmlview.h"#include <kdebug.h>#include <kio/job.h>#include <qobject.h>#ifdef APPLE_CHANGES#include "KWQLoader.h"#endifusing namespace KJS;using khtml::Decoder;////////////////////// XMLHttpRequest Object /////////////////////////* Source for XMLHttpRequestProtoTable.@begin XMLHttpRequestProtoTable 7 abort XMLHttpRequest::Abort DontDelete|Function 0 getAllResponseHeaders XMLHttpRequest::GetAllResponseHeaders DontDelete|Function 0 getResponseHeader XMLHttpRequest::GetResponseHeader DontDelete|Function 1 open XMLHttpRequest::Open DontDelete|Function 5 overrideMimeType XMLHttpRequest::OverrideMIMEType DontDelete|Function 1 send XMLHttpRequest::Send DontDelete|Function 1 setRequestHeader XMLHttpRequest::SetRequestHeader DontDelete|Function 2@end*/DEFINE_PROTOTYPE("XMLHttpRequest",XMLHttpRequestProto)IMPLEMENT_PROTOFUNC(XMLHttpRequestProtoFunc)IMPLEMENT_PROTOTYPE(XMLHttpRequestProto,XMLHttpRequestProtoFunc)namespace KJS {XMLHttpRequestQObject::XMLHttpRequestQObject(XMLHttpRequest *_jsObject) {#if KWIQ QOBJECT_TYPE(KJS::XMLHttpRequestQObject);#endif jsObject = _jsObject; }#if APPLE_CHANGESvoid XMLHttpRequestQObject::slotData( KIO::Job* job, const char *data, int size ){ jsObject->slotData(job, data, size);}#elsevoid XMLHttpRequestQObject::slotData( KIO::Job* job, const QByteArray &data ){ jsObject->slotData(job, data);}#endifvoid XMLHttpRequestQObject::slotFinished( KIO::Job* job ){ jsObject->slotFinished(job); }void XMLHttpRequestQObject::slotRedirection( KIO::Job* job, const KURL& url){ jsObject->slotRedirection( job, url ); }XMLHttpRequestConstructorImp::XMLHttpRequestConstructorImp(ExecState *, const DOM::Document &d) : doc(d){}bool XMLHttpRequestConstructorImp::implementsConstruct() const{ return true;}Object XMLHttpRequestConstructorImp::construct(ExecState *exec, const List &){ return Object(new XMLHttpRequest(exec, doc));}const ClassInfo XMLHttpRequest::info = { "XMLHttpRequest", 0, &XMLHttpRequestTable, 0 };/* Source for XMLHttpRequestTable.@begin XMLHttpRequestTable 7 readyState XMLHttpRequest::ReadyState DontDelete|ReadOnly responseText XMLHttpRequest::ResponseText DontDelete|ReadOnly responseXML XMLHttpRequest::ResponseXML DontDelete|ReadOnly status XMLHttpRequest::Status DontDelete|ReadOnly statusText XMLHttpRequest::StatusText DontDelete|ReadOnly onreadystatechange XMLHttpRequest::Onreadystatechange DontDelete onload XMLHttpRequest::Onload DontDelete@end*/Value XMLHttpRequest::tryGet(ExecState *exec, const Identifier &propertyName) const{ return DOMObjectLookupGetValue<XMLHttpRequest,DOMObject>(exec, propertyName, &XMLHttpRequestTable, this);}Value XMLHttpRequest::getValueProperty(ExecState *exec, int token) const{ switch (token) { case ReadyState: return Number(state); case ResponseText: return getStringOrNull(DOM::DOMString(response)); case ResponseXML: if (state != Completed) { return Undefined(); } if (!createdDocument) { QString mimeType; if (MIMETypeOverride.isEmpty()) { Value header = getResponseHeader("Content-Type"); if (header.type() == UndefinedType) { mimeType = "text/xml"; } else { mimeType = QStringList::split(";", header.toString(exec).qstring())[0].stripWhiteSpace(); } } else { mimeType = MIMETypeOverride; } if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "application/xhtml+xml") { responseXML = DOM::Document(doc->implementation()->createDocument()); DOM::DocumentImpl *docImpl = static_cast<DOM::DocumentImpl *>(responseXML.handle()); docImpl->open(); docImpl->write(response); docImpl->finishParsing(); docImpl->close(); typeIsXML = true; } else { typeIsXML = false; } createdDocument = true; } if (!typeIsXML) { return Undefined(); } return getDOMNode(exec,responseXML); case Status: return getStatus(); case StatusText: return getStatusText(); case Onreadystatechange: if (onReadyStateChangeListener && onReadyStateChangeListener->listenerObjImp()) { return onReadyStateChangeListener->listenerObj(); } else { return Null(); } case Onload: if (onLoadListener && onLoadListener->listenerObjImp()) { return onLoadListener->listenerObj(); } else { return Null(); } default: kdWarning() << "XMLHttpRequest::getValueProperty unhandled token " << token << endl; return Value(); }}void XMLHttpRequest::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr){ DOMObjectLookupPut<XMLHttpRequest,DOMObject>(exec, propertyName, value, attr, &XMLHttpRequestTable, this );}void XMLHttpRequest::putValue(ExecState *exec, int token, const Value& value, int /*attr*/){ switch(token) { case Onreadystatechange: onReadyStateChangeListener = Window::retrieveActive(exec)->getJSEventListener(value, true); if (onReadyStateChangeListener) onReadyStateChangeListener->ref(); break; case Onload: onLoadListener = Window::retrieveActive(exec)->getJSEventListener(value, true); if (onLoadListener) onLoadListener->ref(); break; default: kdWarning() << "HTMLDocument::putValue unhandled token " << token << endl; }}XMLHttpRequest::XMLHttpRequest(ExecState *exec, const DOM::Document &d) : DOMObject(XMLHttpRequestProto::self(exec)), qObject(new XMLHttpRequestQObject(this)), doc(static_cast<DOM::DocumentImpl*>(d.handle())), async(true), job(0), state(Uninitialized), onReadyStateChangeListener(0), onLoadListener(0), decoder(0), createdDocument(false), aborted(false){}XMLHttpRequest::~XMLHttpRequest(){ delete qObject; if (decoder) { decoder->deref(); }}void XMLHttpRequest::changeState(XMLHttpRequestState newState){ if (state != newState) { state = newState; if (onReadyStateChangeListener != 0 && doc->part()) { DOM::Event ev = doc->part()->document().createEvent("HTMLEvents"); ev.initEvent("readystatechange", true, true); onReadyStateChangeListener->handleEvent(ev, true); } if (state == Completed && onLoadListener != 0 && doc->part()) { DOM::Event ev = doc->part()->document().createEvent("HTMLEvents"); ev.initEvent("load", true, true); onLoadListener->handleEvent(ev, true); } }}bool XMLHttpRequest::urlMatchesDocumentDomain(const KURL& _url) const{ KURL documentURL(doc->URL()); // a local file can load anything if (documentURL.protocol().lower() == "file") { return true; } // but a remote document can only load from the same port on the server if (documentURL.protocol().lower() == _url.protocol().lower() && documentURL.host().lower() == _url.host().lower() && documentURL.port() == _url.port()) { return true; } return false;}void XMLHttpRequest::open(const QString& _method, const KURL& _url, bool _async){ abort(); aborted = false; // clear stuff from possible previous load requestHeaders = QString(); responseHeaders = QString(); response = QString(); createdDocument = false; responseXML = DOM::Document(); changeState(Uninitialized); if (aborted) { return; } if (!urlMatchesDocumentDomain(_url)) { return; } method = _method; url = _url; async = _async; changeState(Loading);}void XMLHttpRequest::send(const QString& _body){ aborted = false;#if !APPLE_CHANGES if (!async) { return; }#endif if (method.lower() == "post" && (url.protocol().lower() == "http" || url.protocol().lower() == "https") ) { // FIXME: determine post encoding correctly by looking in headers for charset job = KIO::http_post( url, QCString(_body.utf8()), false ); } else { job = KIO::get( url, false, false ); } if (requestHeaders.length() > 0) { job->addMetaData("customHTTPHeader", requestHeaders); }#if APPLE_CHANGES if (!async) { QByteArray data; KURL finalURL; QString headers; data = KWQServeSynchronousRequest(khtml::Cache::loader(), doc->docLoader(), job, finalURL, headers); job = 0; processSyncLoadResults(data, finalURL, headers); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -