📄 html_formimpl.cpp
字号:
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
form_data.appendData(hstr.data(), hstr.length());
#if APPLE_CHANGES
const FormDataListItem &item = *it;
size_t dataSize = item.m_data.size();
if (dataSize != 0)
form_data.appendData(item.m_data, dataSize - 1);
else if (!item.m_path.isEmpty())
form_data.appendFile(item.m_path);
#else
form_data.appendData((*it).m_data, (*it).m_data.size() - 1);
#endif
form_data.appendData("\r\n", 2);
}
}
}
}
#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?"),
fileUploads);
if (result == KMessageBox::Cancel) {
return false;
}
}
#endif
if (m_multipart)
enc_string = ("--" + m_boundary.string() + "--\r\n").ascii();
form_data.appendData(enc_string.data(), enc_string.length());
return true;
}
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 if (type.string().find("text", 0, false) != -1 || type.string().find("plain", 0, false) != -1)
{
m_enctype = "text/plain";
m_multipart = false;
}
else
{
m_enctype = "application/x-www-form-urlencoded";
m_multipart = false;
}
}
void HTMLFormElementImpl::setBoundary( const DOMString& bound )
{
m_boundary = bound;
}
bool HTMLFormElementImpl::prepareSubmit()
{
KHTMLPart *part = getDocument()->part();
if(m_insubmit || !part || part->onlyLocalReferences())
return m_insubmit;
m_insubmit = true;
m_doingsubmit = false;
if ( dispatchHTMLEvent(EventImpl::SUBMIT_EVENT,false,true) && !m_doingsubmit )
m_doingsubmit = true;
m_insubmit = false;
if ( m_doingsubmit )
submit(true);
return m_doingsubmit;
}
void HTMLFormElementImpl::submit( bool activateSubmitButton )
{
KHTMLView *view = getDocument()->view();
KHTMLPart *part = getDocument()->part();
if (!view || !part) {
return;
}
if ( m_insubmit ) {
m_doingsubmit = true;
return;
}
m_insubmit = true;
#ifdef FORMS_DEBUG
kdDebug( 6030 ) << "submitting!" << endl;
#endif
HTMLGenericFormElementImpl* firstSuccessfulSubmitButton = 0;
bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
#if APPLE_CHANGES
KWQ(part)->clearRecordedFormValues();
#endif
for (unsigned i = 0; i < formElements.count(); ++i) {
HTMLGenericFormElementImpl* current = formElements[i];
#if APPLE_CHANGES
// Our app needs to get form values for password fields for doing password autocomplete,
// so we are more lenient in pushing values, and let the app decide what to save when.
if (current->id() == ID_INPUT) {
HTMLInputElementImpl *input = static_cast<HTMLInputElementImpl*>(current);
if (input->inputType() == HTMLInputElementImpl::TEXT
|| input->inputType() == HTMLInputElementImpl::PASSWORD
|| input->inputType() == HTMLInputElementImpl::SEARCH)
{
KWQ(part)->recordFormValue(input->name().string(), input->value().string(), this);
if (input->renderer() && input->inputType() == HTMLInputElementImpl::SEARCH)
static_cast<RenderLineEdit*>(input->renderer())->addSearchResult();
}
}
#else
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());
}
#endif
if (needButtonActivation) {
if (current->isActivatedSubmit()) {
needButtonActivation = false;
} else if (firstSuccessfulSubmitButton == 0 && current->isSuccessfulSubmitButton()) {
firstSuccessfulSubmitButton = current;
}
}
}
if (needButtonActivation && firstSuccessfulSubmitButton) {
firstSuccessfulSubmitButton->setActivatedSubmit(true);
}
FormData form_data;
if (formData(form_data)) {
if(m_post) {
part->submitForm( "post", m_url.string(), form_data,
m_target.string(),
enctype().string(),
boundary().string() );
}
else {
part->submitForm( "get", m_url.string(), form_data,
m_target.string() );
}
}
if (needButtonActivation && firstSuccessfulSubmitButton) {
firstSuccessfulSubmitButton->setActivatedSubmit(false);
}
m_doingsubmit = m_insubmit = false;
}
void HTMLFormElementImpl::reset( )
{
KHTMLPart *part = getDocument()->part();
if(m_inreset || !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;
}
for (unsigned i = 0; i < formElements.count(); ++i)
formElements[i]->reset();
m_inreset = false;
}
void HTMLFormElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
switch(attr->id())
{
case ATTR_ACTION:
#if APPLE_CHANGES
{
bool oldURLWasSecure = formWouldHaveSecureSubmission(m_url);
#endif
m_url = khtml::parseURL(attr->value());
#if APPLE_CHANGES
bool newURLIsSecure = formWouldHaveSecureSubmission(m_url);
if (m_attached && (oldURLWasSecure != newURLIsSecure))
if (newURLIsSecure)
getDocument()->secureFormAdded();
else
getDocument()->secureFormRemoved();
}
#endif
break;
case ATTR_TARGET:
m_target = attr->value();
break;
case ATTR_METHOD:
if ( strcasecmp( attr->value(), "post" ) == 0 )
m_post = true;
else if ( strcasecmp( attr->value(), "get" ) == 0 )
m_post = false;
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;
case ATTR_ONSUBMIT:
setHTMLEventListener(EventImpl::SUBMIT_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_ONRESET:
setHTMLEventListener(EventImpl::RESET_EVENT,
getDocument()->createHTMLEventListener(attr->value().string(), this));
break;
case ATTR_NAME:
{
QString newNameAttr = attr->value().string();
if (attached() && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldNameAttr);
document->addNamedImageOrForm(newNameAttr);
}
oldNameAttr = newNameAttr;
}
break;
case ATTR_ID:
{
QString newIdAttr = attr->value().string();
if (attached() && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldIdAttr);
document->addNamedImageOrForm(newIdAttr);
}
oldIdAttr = newIdAttr;
}
// fall through
default:
HTMLElementImpl::parseHTMLAttribute(attr);
}
}
void HTMLFormElementImpl::radioClicked( HTMLGenericFormElementImpl *caller )
{
for (unsigned i = 0; i < formElements.count(); ++i) {
HTMLGenericFormElementImpl *current = formElements[i];
if (current->id() == ID_INPUT &&
static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::RADIO &&
current != caller && current->form() == caller->form() && current->name() == caller->name()) {
static_cast<HTMLInputElementImpl*>(current)->setChecked(false);
}
}
}
template<class T> static void appendToVector(QPtrVector<T> &vec, T *item)
{
unsigned size = vec.size();
unsigned count = vec.count();
if (size == count)
vec.resize(size == 0 ? 8 : (int)(size * 1.5));
vec.insert(count, item);
}
template<class T> static void removeFromVector(QPtrVector<T> &vec, T *item)
{
int pos = vec.findRef(item);
int count = vec.count();
if (pos < 0)
return;
for (int i = pos; i < count - 1; i++) {
vec.insert(i, vec[i+1]);
}
vec.remove(count - 1);
}
void HTMLFormElementImpl::registerFormElement(HTMLGenericFormElementImpl *e)
{
appendToVector(formElements, e);
removeFromVector(dormantFormElements, e);
}
void HTMLFormElementImpl::removeFormElement(HTMLGenericFormElementImpl *e)
{
removeFromVector(formElements, e);
removeFromVector(dormantFormElements, e);
}
void HTMLFormElementImpl::makeFormElementDormant(HTMLGenericFormElementImpl *e)
{
appendToVector(dormantFormElements, e);
removeFromVector(formElements, e);
}
bool HTMLFormElementImpl::isURLAttribute(AttributeImpl *attr) const
{
return attr->id() == ATTR_ACTION;
}
void HTMLFormElementImpl::registerImgElement(HTMLImageElementImpl *e)
{
appendToVector(imgElements, e);
}
void HTMLFormElementImpl::removeImgElement(HTMLImageElementImpl *e)
{
removeFromVector(imgElements, e);
}
// -------------------------------------------------------------------------
HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
: HTMLElementImpl(doc)
{
m_disabled = m_readOnly = false;
m_name = 0;
m_dormant = false;
if (f)
m_form = f;
else
m_form = getForm();
if (m_form)
m_form->registerFormElement(this);
}
HTMLGenericFormElementImpl::~HTMLGenericFormElementImpl()
{
if (m_form)
m_form->removeFormElement(this);
if (m_name) m_name->deref();
}
void HTMLGenericFormElementImpl::parseHTMLAttribute(HTMLAttributeImpl *attr)
{
switch(attr->id())
{
case ATTR_NAME:
break;
case ATTR_DISABLED:
setDisabled( !attr->isNull() );
break;
case ATTR_READONLY:
{
bool m_oldreadOnly = m_readOnly;
m_readOnly = !attr->isNull();
if (m_oldreadOnly != m_readOnly) setChanged();
break;
}
default:
HTMLElementImpl::parseHTMLAttribute(attr);
}
}
void HTMLGenericFormElementImpl::attach()
{
assert(!attached());
// FIXME: This handles the case of a new form element being created by
// JavaScript and inserted inside a form. What it does not handle is
// a form element being moved from inside a form to outside, or from one
// inside one form to another. The reason this other case is hard to fix
// is that during parsing, we may have been passed a form that we are not
// inside, DOM-tree-wise. If so, it's hard for us to know when we should
// be removed from that form's element list.
if (!m_form) {
m_form = getForm();
if (m_form)
m_form->registerFormElement(this);
}
HTMLElementImpl::attach();
// The call to updateFromElement() needs to go after the call through
// to the base class's attach() because that can sometimes do a close
// on the renderer.
if (m_render) {
m_render->updateFromElement();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -