📄 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) * * 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. * * $Id: html_formimpl.cpp,v 1.195.2.3 2001/10/13 10:45:01 faure Exp $ */#undef FORMS_DEBUG//#define FORMS_DEBUG#include "html_formimpl.h"#include "khtmlview.h"#include "khtml_part.h"#include "html_documentimpl.h"#include "khtml_settings.h"#include "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 "rendering/render_form.h"#include <kcharsets.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>#include <assert.h>using namespace DOM;using namespace khtml;//template class QList<khtml::RenderFormElement>;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";}HTMLFormElementImpl::~HTMLFormElementImpl(){ QListIterator<HTMLGenericFormElementImpl> it(formElements); for (; it.current(); ++it) it.current()->setForm(0);}ushort HTMLFormElementImpl::id() const{ return ID_FORM;}long HTMLFormElementImpl::length() const{ int len = 0; QListIterator<HTMLGenericFormElementImpl> it(formElements); for (; it.current(); ++it) if (it.current()->isEnumeratable()) ++len; return len;}static 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 = "-._*"; QCString encoded(( e.length()+e.contains( '\n' ) )*3+1); int enclen = 0; //QCString orig(e.data(), e.size()); for(unsigned pos = 0; pos < e.length(); 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' ) { 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;}inline static QCString fixUpfromUnicode(const QTextCodec* codec, const QString& s){ QCString str = codec->fromUnicode(s); str.truncate(str.length()); return str;}void HTMLFormElementImpl::i18nData(){ QString foo1 = i18n( "You're about to send data to the Internet\n" "via an unencrypted connection.\nIt might be possible " "for others to see this information.\n\n" "Do you want to continue?"); QString foo2 = i18n("KDE Web browser"); QString foo3 = i18n("When you send a password unencrypted to the Internet,\n" "it might be possible for others to capture it as plain text.\n\n" "Do you want to continue?"); QString foo4 = i18n("You're about to transfer the following files from\n" "your local computer to the Internet.\n\n" "Do you really want to continue?"); QString foo5 = i18n("Your data submission is redirected to\n" "an insecure site. The data is sent unencrypted.\n\n" "Do you want to continue?");}QByteArray HTMLFormElementImpl::formData(){#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(); QChar space(' '); for(unsigned int i=0; i < str.length(); i++) if(str[i].latin1() == ',') str[i] = space; QStringList charsets = QStringList::split(' ', str); QTextCodec* codec = 0; 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(view && view->part()) enc = view->part()->encoding(); } if((codec = KGlobal::charsets()->codecForName(enc.latin1()))) break; } if(!codec) { QString n = KGlobal::charsets()->name(view->part()->settings()->charset()); if(n != "any") codec = KGlobal::charsets()->codecForName(n); } if(!codec) codec = QTextCodec::codecForLocale(); m_encCharset = codec->name(); for(unsigned int i=0; i < m_encCharset.length(); i++) m_encCharset[i] = m_encCharset[i].latin1() == ' ' ? QChar('-') : m_encCharset[i].lower(); for(HTMLGenericFormElementImpl *current = formElements.first(); current; current = formElements.next()) { khtml::encodingList lst; if (!current->disabled() && current->encoding(codec, lst, m_multipart)) { //kdDebug(6030) << "adding name " << current->name().string() << endl; ASSERT(!(lst.count()&1)); 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)->filename().string(); QString onlyfilename = path.mid(path.findRev('/')+1); hstr += ("; filename=\"" + onlyfilename + "\"").ascii(); if(!static_cast<HTMLInputElementImpl*>(current)->filename().isEmpty()) { hstr += "\r\nContent-Type: "; KMimeType::Ptr ptr = KMimeType::findByURL(KURL(path)); hstr += ptr->name().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 (m_multipart) enc_string = ("--" + m_boundary.string() + "--\r\n").ascii(); int old_size = form_data.size(); form_data.resize( form_data.size() + enc_string.length() ); memcpy(form_data.data() + old_size, enc_string.data(), enc_string.length() ); return form_data;}void HTMLFormElementImpl::setEnctype( const DOMString& type ){ if(type.string().find("multipart", 0, false) != -1 || type.string().find("form-data", 0, false) != -1) { m_enctype = "multipart/form-data"; m_multipart = true; m_post = true; } else { m_enctype = "application/x-www-form-urlencoded"; m_multipart = false; } m_encCharset = QString::null;}void HTMLFormElementImpl::setBoundary( const DOMString& bound ){ m_boundary = bound;}bool HTMLFormElementImpl::prepareSubmit(){ if(m_insubmit || !view || !view->part() || view->part()->onlyLocalReferences()) return m_insubmit; m_insubmit = true; m_doingsubmit = false; if ( dispatchHTMLEvent(EventImpl::SUBMIT_EVENT,true,true) && !m_doingsubmit ) m_doingsubmit = true; m_insubmit = false; if ( m_doingsubmit ) submit(); return m_doingsubmit;}void HTMLFormElementImpl::submit( ){ if ( m_insubmit ) { m_doingsubmit = true; return; } m_insubmit = true;#ifdef FORMS_DEBUG kdDebug( 6030 ) << "submitting!" << endl;#endif for(HTMLGenericFormElementImpl *current = formElements.first(); current; current = formElements.next()) { if (current->id() == ID_INPUT && static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::TEXT && static_cast<HTMLInputElementImpl*>(current)->autoComplete() ) { HTMLInputElementImpl *input = static_cast<HTMLInputElementImpl *>(current); view->addFormCompletionItem(input->name().string(), input->value().string()); } } QByteArray form_data = formData(); if(m_post) { view->part()->submitForm( "post", m_url.string(), form_data, m_target.string(), enctype().string(),// m_encCharset.isEmpty() ? enctype().string()// : QString(enctype().string() + "; charset=" + m_encCharset), boundary().string() ); } else { view->part()->submitForm( "get", m_url.string(), form_data, m_target.string() ); } m_doingsubmit = m_insubmit = false;}void HTMLFormElementImpl::reset( ){ if(m_inreset || !view || !view->part()) return; m_inreset = true;#ifdef FORMS_DEBUG kdDebug( 6030 ) << "reset pressed!" << endl;#endif // ### DOM2 labels this event as not cancelable, however // common browsers( sick! ) allow it be cancelled. if ( !dispatchHTMLEvent(EventImpl::RESET_EVENT,true, true) ) { m_inreset = false; return; } HTMLGenericFormElementImpl *current = formElements.first(); while(current) { current->reset(); current = formElements.next(); } if (ownerDocument()->isHTMLDocument()) static_cast<HTMLDocumentImpl*>(ownerDocument())->updateRendering(); m_inreset = false;}void HTMLFormElementImpl::parseAttribute(AttrImpl *attr){ switch(attr->attrId) { case ATTR_ACTION: m_url = khtml::parseURL(attr->value()); break; case ATTR_TARGET: m_target = attr->value(); break; case ATTR_METHOD: if ( strcasecmp( attr->value(), "post" ) == 0 ) m_post = true; break; case ATTR_ENCTYPE: setEnctype( attr->value() ); break; case ATTR_ACCEPT_CHARSET: // space separated list of charsets the server // accepts - see rfc2045 m_acceptcharset = attr->value(); break; case ATTR_ACCEPT: // ignore this one for the moment... break; case ATTR_AUTOCOMPLETE: m_autocomplete = strcasecmp( attr->value(), "off" ); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -