📄 html_formimpl.cpp
字号:
/* * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */#undef FORMS_DEBUG//#define FORMS_DEBUG#include "KWQLogging.h"#include "html/html_formimpl.h"#include "khtmlview.h"#include "khtml_part.h"#include "html/html_documentimpl.h"#include "html_imageimpl.h"#include "khtml_settings.h"#include "misc/htmlhashes.h"#include "css/cssstyleselector.h"#include "css/cssproperties.h"#include "css/csshelper.h"#include "xml/dom_textimpl.h"#include "xml/dom2_eventsimpl.h"#include "khtml_ext.h"#include "rendering/render_form.h"#include <kcharsets.h>#include <kglobal.h>#include <kdebug.h>#include <kmimetype.h>#include <kmessagebox.h>#include <klocale.h>#include <netaccess.h>#include <kfileitem.h>#include <qfile.h>#include <qtextcodec.h>// for keygen#include <qstring.h>#include <ksslkeygen.h>#include <assert.h>#if KWIQ#include <qbuttongroup.h>#endifusing namespace DOM;using namespace khtml;HTMLFormElementImpl::HTMLFormElementImpl(DocumentPtr *doc) : HTMLElementImpl(doc){ m_post = false; m_multipart = false; m_autocomplete = true; m_insubmit = false; m_doingsubmit = false; m_inreset = false; m_enctype = "application/x-www-form-urlencoded"; m_boundary = "----------0xKhTmLbOuNdArY"; m_acceptcharset = "UNKNOWN"; m_malformed = false;}HTMLFormElementImpl::~HTMLFormElementImpl(){ QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); for (; it.current(); ++it) it.current()->m_form = 0;}NodeImpl::Id HTMLFormElementImpl::id() const{ return ID_FORM;}#if APPLE_CHANGESbool HTMLFormElementImpl::formWouldHaveSecureSubmission(const DOMString &url){ if (url.isNull()) { return false; } return getDocument()->completeURL(url.string()).startsWith("https:", false);}#endifvoid HTMLFormElementImpl::attach(){ HTMLElementImpl::attach(); if (getDocument()->isHTMLDocument()) { HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument()); document->addNamedImageOrForm(oldNameAttr); document->addNamedImageOrForm(oldIdAttr); }#if APPLE_CHANGES // note we don't deal with calling secureFormRemoved() on detach, because the timing // was such that it cleared our state too early if (formWouldHaveSecureSubmission(m_url)) getDocument()->secureFormAdded();#endif}void HTMLFormElementImpl::detach(){ if (getDocument()->isHTMLDocument()) { HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument()); document->removeNamedImageOrForm(oldNameAttr); document->removeNamedImageOrForm(oldIdAttr); } HTMLElementImpl::detach();}long HTMLFormElementImpl::length() const{ int len = 0; QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); for (; it.current(); ++it) if (it.current()->isEnumeratable()) ++len; return len;}#if APPLE_CHANGESvoid HTMLFormElementImpl::submitClick(){ bool submitFound = false; QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); for (; it.current(); ++it) { if (it.current()->id() == ID_INPUT) { HTMLInputElementImpl *element = static_cast<HTMLInputElementImpl *>(it.current()); if (element->isSuccessfulSubmitButton() && element->renderer()) { submitFound = true; element->click(); break; } } } if (!submitFound) // submit the form without a submit or image input prepareSubmit();}#endif // APPLE_CHANGESstatic QCString encodeCString(const QCString& e){ // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 // safe characters like NS handles them for compatibility static const char *safe = "-._*"; int elen = e.length(); QCString encoded(( elen+e.contains( '\n' ) )*3+1); int enclen = 0; //QCString orig(e.data(), e.size()); for(int pos = 0; pos < elen; pos++) { unsigned char c = e[pos]; if ( (( c >= 'A') && ( c <= 'Z')) || (( c >= 'a') && ( c <= 'z')) || (( c >= '0') && ( c <= '9')) || (strchr(safe, c)) ) encoded[enclen++] = c; else if ( c == ' ' ) encoded[enclen++] = '+'; else if ( c == '\n' || ( c == '\r' && e[pos+1] != '\n' ) ) { encoded[enclen++] = '%'; encoded[enclen++] = '0'; encoded[enclen++] = 'D'; encoded[enclen++] = '%'; encoded[enclen++] = '0'; encoded[enclen++] = 'A'; } else if ( c != '\r' ) { encoded[enclen++] = '%'; unsigned int h = c / 16; h += (h > 9) ? ('A' - 10) : '0'; encoded[enclen++] = h; unsigned int l = c % 16; l += (l > 9) ? ('A' - 10) : '0'; encoded[enclen++] = l; } } encoded[enclen++] = '\0'; encoded.truncate(enclen); return encoded;}// Change plain CR and plain LF to CRLF pairs.static QCString fixLineBreaks(const QCString &s){#if KWIQ if ( s.isNull() ) return QCString();#endif // Compute the length. unsigned newLen = 0; const char *p = s.data(); while (char c = *p++) { if (c == '\r') { // Safe to look ahead because of trailing '\0'. if (*p != '\n') { // Turn CR into CRLF. newLen += 2; } } else if (c == '\n') { // Turn LF into CRLF. newLen += 2; } else { // Leave other characters alone. newLen += 1; } } if (newLen == s.length()) { return s; } // Make a copy of the string. p = s.data(); QCString result(newLen + 1); char *q = result.data(); while (char c = *p++) { if (c == '\r') { // Safe to look ahead because of trailing '\0'. if (*p != '\n') { // Turn CR into CRLF. *q++ = '\r'; *q++ = '\n'; } } else if (c == '\n') { // Turn LF into CRLF. *q++ = '\r'; *q++ = '\n'; } else { // Leave other characters alone. *q++ = c; } } return result;}inline static QCString fixUpfromUnicode(const QTextCodec* codec, const QString& s){ QCString str = fixLineBreaks(codec->fromUnicode(s)); str.truncate(str.length()); return str;}#if !APPLE_CHANGESvoid HTMLFormElementImpl::i18nData(){ QString foo1 = i18n( "You're about to send data to the Internet " "via an unencrypted connection. It might be possible " "for others to see this information.\n" "Do you want to continue?"); QString foo2 = i18n("KDE Web browser"); QString foo3 = i18n("When you send a password unencrypted to the Internet, " "it might be possible for others to capture it as plain text.\n" "Do you want to continue?"); QString foo5 = i18n("Your data submission is redirected to " "an insecure site. The data is sent unencrypted.\n" "Do you want to continue?"); QString foo6 = i18n("The page contents expired. You can repost the form" "data by using <a href=\"javascript:go(0);\">Reload</a>");}#endifQByteArray HTMLFormElementImpl::formData(bool& ok){#ifdef FORMS_DEBUG kdDebug( 6030 ) << "form: formData()" << endl;#endif QByteArray form_data(0); QCString enc_string = ""; // used for non-multipart data // find out the QTextcodec to use QString str = m_acceptcharset.string(); str.replace(',', ' '); QStringList charsets = QStringList::split(' ', str); QTextCodec* codec = 0; KHTMLPart *part = getDocument()->part(); for ( QStringList::Iterator it = charsets.begin(); it != charsets.end(); ++it ) { QString enc = (*it); if(enc.contains("UNKNOWN")) { // use standard document encoding enc = "ISO-8859-1"; if (part) enc = part->encoding(); } if((codec = KGlobal::charsets()->codecForName(enc.latin1()))) break; } if(!codec) codec = QTextCodec::codecForLocale(); QStringList fileUploads; for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) { HTMLGenericFormElementImpl* current = it.current(); khtml::encodingList lst; if (!current->disabled() && current->encoding(codec, lst, m_multipart)) { //kdDebug(6030) << "adding name " << current->name().string() << endl; khtml::encodingList::Iterator it; for( it = lst.begin(); it != lst.end(); ++it ) { if (!m_multipart) { // handle ISINDEX / <input name=isindex> special // but only if its the first entry if ( enc_string.isEmpty() && *it == "isindex" ) { ++it; enc_string += encodeCString( *it ); } else { if(!enc_string.isEmpty()) enc_string += '&'; enc_string += encodeCString(*it); enc_string += "="; ++it; enc_string += encodeCString(*it); } } else { QCString hstr("--"); hstr += m_boundary.string().latin1(); hstr += "\r\n"; hstr += "Content-Disposition: form-data; name=\""; hstr += (*it).data(); hstr += "\""; // if the current type is FILE, then we also need to // include the filename if (current->nodeType() == Node::ELEMENT_NODE && current->id() == ID_INPUT && static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::FILE) { QString path = static_cast<HTMLInputElementImpl*>(current)->value().string(); if (path.length()) fileUploads << path; // Turn non-ASCII characters into &-escaped form. // This doesn't work perfectly, because it doesn't escape &, for example. // But it seems to be what Gecko does. QString onlyfilename; for (uint i = path.findRev('/') + 1; i < path.length(); ++i) { QChar c = path.at(i).unicode(); if (c.unicode() >= 0x20 && c.unicode() <= 0x7F) { onlyfilename.append(&c, 1); } else { QString ampersandEscape; ampersandEscape.sprintf("&#%hu;", c.unicode()); onlyfilename.append(ampersandEscape); } } // FIXME: This won't work if the filename includes a " mark, // or control characters like CR or LF. hstr += ("; filename=\"" + onlyfilename + "\"").ascii(); if(!static_cast<HTMLInputElementImpl*>(current)->value().isEmpty()) {#if APPLE_CHANGES QString mimeType = part ? KWQ(part)->mimeTypeForFileName(onlyfilename) : QString();#else KMimeType::Ptr ptr = KMimeType::findByURL(KURL(path)); QString mimeType = ptr->name();#endif if (!mimeType.isEmpty()) { hstr += "\r\nContent-Type: "; hstr += mimeType.ascii(); } } } hstr += "\r\n\r\n"; ++it; // append body unsigned int old_size = form_data.size(); form_data.resize( old_size + hstr.length() + (*it).size() + 1); memcpy(form_data.data() + old_size, hstr.data(), hstr.length()); memcpy(form_data.data() + old_size + hstr.length(), (*it), (*it).size()); form_data[form_data.size()-2] = '\r'; form_data[form_data.size()-1] = '\n'; } } } }#if !APPLE_CHANGES if (fileUploads.count()) { int result = KMessageBox::warningContinueCancelList( 0, i18n("You're about to transfer the following files from " "your local computer to the Internet.\n" "Do you really want to continue?"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -