00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #undef FORMS_DEBUG
00026
00027
00028 #include "html/html_formimpl.h"
00029
00030 #include "khtmlview.h"
00031 #include "khtml_part.h"
00032 #include "html/html_documentimpl.h"
00033 #include "khtml_settings.h"
00034 #include "misc/htmlhashes.h"
00035
00036 #include "css/cssstyleselector.h"
00037 #include "css/cssproperties.h"
00038 #include "css/cssvalues.h"
00039 #include "css/csshelper.h"
00040 #include "xml/dom_textimpl.h"
00041 #include "xml/dom_docimpl.h"
00042 #include "xml/dom2_eventsimpl.h"
00043 #include "khtml_ext.h"
00044
00045 #include "rendering/render_form.h"
00046
00047 #include <kcharsets.h>
00048 #include <kglobal.h>
00049 #include <kdebug.h>
00050 #include <kmimetype.h>
00051 #include <kmessagebox.h>
00052 #include <kapplication.h>
00053 #include <klocale.h>
00054 #include <netaccess.h>
00055 #include <kfileitem.h>
00056 #include <qfile.h>
00057 #include <qtextcodec.h>
00058
00059
00060 #include <qstring.h>
00061 #include <ksslkeygen.h>
00062
00063 #include <assert.h>
00064
00065 using namespace DOM;
00066 using namespace khtml;
00067
00068 HTMLFormElementImpl::HTMLFormElementImpl(DocumentPtr *doc, bool implicit)
00069 : HTMLElementImpl(doc)
00070 {
00071 m_implicit = implicit;
00072 m_post = false;
00073 m_multipart = false;
00074 m_autocomplete = true;
00075 m_insubmit = false;
00076 m_doingsubmit = false;
00077 m_inreset = false;
00078 m_enctype = "application/x-www-form-urlencoded";
00079 m_boundary = "----------" + KApplication::randomString( 42 + 13 );
00080 m_acceptcharset = "UNKNOWN";
00081 }
00082
00083 HTMLFormElementImpl::~HTMLFormElementImpl()
00084 {
00085 QPtrListIterator<HTMLGenericFormElementImpl> it(formElements);
00086 for (; it.current(); ++it)
00087 it.current()->m_form = 0;
00088 QPtrListIterator<HTMLImageElementImpl> it2(imgElements);
00089 for (; it2.current(); ++it2)
00090 it2.current()->m_form = 0;
00091 }
00092
00093 NodeImpl::Id HTMLFormElementImpl::id() const
00094 {
00095 return ID_FORM;
00096 }
00097
00098 long HTMLFormElementImpl::length() const
00099 {
00100 int len = 0;
00101 QPtrListIterator<HTMLGenericFormElementImpl> it(formElements);
00102 for (; it.current(); ++it)
00103 if (it.current()->isEnumeratable())
00104 ++len;
00105
00106 return len;
00107 }
00108
00109 static QCString encodeCString(const QCString& e)
00110 {
00111
00112
00113 static const char *safe = "-._*";
00114 QCString encoded(( e.length()+e.contains( '\n' ) )*3
00115 +e.contains('\r') * 3 + 1);
00116 int enclen = 0;
00117 bool crmissing = false;
00118 unsigned char oldc;
00119 unsigned char c ='\0';
00120
00121
00122
00123 for(unsigned pos = 0; pos < e.length(); pos++) {
00124 oldc = c;
00125 c = e[pos];
00126
00127 if (crmissing && c != '\n') {
00128 encoded[enclen++] = '%';
00129 encoded[enclen++] = '0';
00130 encoded[enclen++] = 'D';
00131 crmissing = false;
00132 }
00133
00134 if ( (( c >= 'A') && ( c <= 'Z')) ||
00135 (( c >= 'a') && ( c <= 'z')) ||
00136 (( c >= '0') && ( c <= '9')) ||
00137 (strchr(safe, c))
00138 )
00139 encoded[enclen++] = c;
00140 else if ( c == ' ' )
00141 encoded[enclen++] = '+';
00142 else if ( c == '\n' )
00143 {
00144 encoded[enclen++] = '%';
00145 encoded[enclen++] = '0';
00146 encoded[enclen++] = 'D';
00147 encoded[enclen++] = '%';
00148 encoded[enclen++] = '0';
00149 encoded[enclen++] = 'A';
00150 crmissing = false;
00151 }
00152 else if (c == '\r' && oldc != '\n') {
00153 crmissing = true;
00154 }
00155 else if ( c != '\r' )
00156 {
00157 encoded[enclen++] = '%';
00158 unsigned int h = c / 16;
00159 h += (h > 9) ? ('A' - 10) : '0';
00160 encoded[enclen++] = h;
00161
00162 unsigned int l = c % 16;
00163 l += (l > 9) ? ('A' - 10) : '0';
00164 encoded[enclen++] = l;
00165 }
00166 }
00167 encoded[enclen++] = '\0';
00168 encoded.truncate(enclen);
00169
00170 return encoded;
00171 }
00172
00173 inline static QCString fixUpfromUnicode(const QTextCodec* codec, const QString& s)
00174 {
00175 QCString str = codec->fromUnicode(s);
00176 str.truncate(str.length());
00177 return str;
00178 }
00179
00180 QByteArray HTMLFormElementImpl::formData(bool& ok)
00181 {
00182 #ifdef FORMS_DEBUG
00183 kdDebug( 6030 ) << "form: formData()" << endl;
00184 #endif
00185
00186 QByteArray form_data(0);
00187 QCString enc_string = "";
00188
00189
00190 QString str = m_acceptcharset.string();
00191 QChar space(' ');
00192 for(unsigned int i=0; i < str.length(); i++) if(str[i].latin1() == ',') str[i] = space;
00193 QStringList charsets = QStringList::split(' ', str);
00194 QTextCodec* codec = 0;
00195 KHTMLView *view = getDocument()->view();
00196 for ( QStringList::Iterator it = charsets.begin(); it != charsets.end(); ++it )
00197 {
00198 QString enc = (*it);
00199 if(enc.contains("UNKNOWN"))
00200 {
00201
00202 enc = "ISO 8859-1";
00203 if(view && view->part())
00204 enc = view->part()->encoding();
00205 }
00206 if((codec = KGlobal::charsets()->codecForName(enc.latin1())))
00207 break;
00208 }
00209
00210 if(!codec)
00211 codec = QTextCodec::codecForLocale();
00212
00213
00214
00215 if ( codec->mibEnum() == 11 )
00216 codec = QTextCodec::codecForMib( 85 );
00217
00218 m_encCharset = codec->name();
00219 for(unsigned int i=0; i < m_encCharset.length(); i++)
00220 m_encCharset[i] = m_encCharset[i].latin1() == ' ' ? QChar('-') : m_encCharset[i].lower();
00221
00222 QStringList fileUploads;
00223
00224 for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) {
00225 HTMLGenericFormElementImpl* current = it.current();
00226 khtml::encodingList lst;
00227
00228 if (!current->disabled() && current->encoding(codec, lst, m_multipart))
00229 {
00230
00231 khtml::encodingList::Iterator it;
00232 for( it = lst.begin(); it != lst.end(); ++it )
00233 {
00234 if (!m_multipart)
00235 {
00236
00237
00238 if ( enc_string.isEmpty() && *it == "isindex" ) {
00239 ++it;
00240 enc_string += encodeCString( *it );
00241 }
00242 else {
00243 if(!enc_string.isEmpty())
00244 enc_string += '&';
00245
00246 enc_string += encodeCString(*it);
00247 enc_string += "=";
00248 ++it;
00249 enc_string += encodeCString(*it);
00250 }
00251 }
00252 else
00253 {
00254 QCString hstr("--");
00255 hstr += m_boundary.latin1();
00256 hstr += "\r\n";
00257 hstr += "Content-Disposition: form-data; name=\"";
00258 hstr += (*it).data();
00259 hstr += "\"";
00260
00261
00262
00263 if (current->nodeType() == Node::ELEMENT_NODE && current->id() == ID_INPUT &&
00264 static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::FILE)
00265 {
00266 QString path = static_cast<HTMLInputElementImpl*>(current)->value().string();
00267 if (path.length()) fileUploads << path;
00268 QString onlyfilename = path.mid(path.findRev('/')+1);
00269
00270 hstr += fixUpfromUnicode(codec, "; filename=\"" + onlyfilename + "\"");
00271 if(!static_cast<HTMLInputElementImpl*>(current)->value().isEmpty())
00272 {
00273 hstr += "\r\nContent-Type: ";
00274 KMimeType::Ptr ptr = KMimeType::findByURL(KURL(path));
00275 hstr += ptr->name().ascii();
00276 }
00277 }
00278
00279 hstr += "\r\n\r\n";
00280 ++it;
00281
00282
00283 unsigned int old_size = form_data.size();
00284 form_data.resize( old_size + hstr.length() + (*it).size() + 1);
00285 memcpy(form_data.data() + old_size, hstr.data(), hstr.length());
00286 memcpy(form_data.data() + old_size + hstr.length(), *it, (*it).size());
00287 form_data[form_data.size()-2] = '\r';
00288 form_data[form_data.size()-1] = '\n';
00289 }
00290 }
00291 }
00292 }
00293
00294 if (fileUploads.count()) {
00295 int result = KMessageBox::warningContinueCancelList( 0,
00296 i18n("You're about to transfer the following files from "
00297 "your local computer to the Internet.\n"
00298 "Do you really want to continue?"),
00299 fileUploads);
00300
00301
00302 if (result == KMessageBox::Cancel) {
00303 ok = false;
00304 return QByteArray();
00305 }
00306 }
00307
00308 if (m_multipart)
00309 enc_string = ("--" + m_boundary + "--\r\n").ascii();
00310
00311 int old_size = form_data.size();
00312 form_data.resize( form_data.size() + enc_string.length() );
00313 memcpy(form_data.data() + old_size, enc_string.data(), enc_string.length() );
00314
00315 ok = true;
00316 return form_data;
00317 }
00318
00319 void HTMLFormElementImpl::setEnctype( const DOMString& type )
00320 {
00321 if(type.string().find("multipart", 0, false) != -1 || type.string().find("form-data", 0, false) != -1)
00322 {
00323 m_enctype = "multipart/form-data";
00324 m_multipart = true;
00325 m_post = true;
00326 } else if (type.string().find("text", 0, false) != -1 || type.string().find("plain", 0, false) != -1)
00327 {
00328 m_enctype = "text/plain";
00329 m_multipart = false;
00330 }
00331 else
00332 {
00333 m_enctype = "application/x-www-form-urlencoded";
00334 m_multipart = false;
00335 }
00336 m_encCharset = QString::null;
00337 }
00338
00339 void HTMLFormElementImpl::submitFromKeyboard()
00340 {
00341
00342
00343
00344 unsigned int inputtext = 0;
00345 for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) {
00346 if (it.current()->id() == ID_BUTTON) {
00347 HTMLButtonElementImpl* current = static_cast<HTMLButtonElementImpl *>(it.current());
00348 if (current->buttonType() == HTMLButtonElementImpl::SUBMIT && !current->disabled()) {
00349 current->activate();
00350 return;
00351 }
00352 } else if (it.current()->id() == ID_INPUT) {
00353 HTMLInputElementImpl* current = static_cast<HTMLInputElementImpl *>(it.current());
00354 switch(current->inputType()) {
00355 case HTMLInputElementImpl::SUBMIT:
00356 case HTMLInputElementImpl::IMAGE:
00357 current->activate();
00358 return;
00359 case HTMLInputElementImpl::TEXT:
00360 case HTMLInputElementImpl::PASSWORD:
00361 ++inputtext;
00362 default:
00363 break;
00364 }
00365 }
00366 }
00367
00368 if (inputtext <= 1)
00369 prepareSubmit();
00370 }
00371
00372 bool HTMLFormElementImpl::prepareSubmit()
00373 {
00374 KHTMLView *view = getDocument()->view();
00375 if(m_insubmit || !view || !view->part() || view->part()->onlyLocalReferences())
00376 return m_insubmit;
00377
00378 m_insubmit = true;
00379 m_doingsubmit = false;
00380
00381 if ( dispatchHTMLEvent(EventImpl::SUBMIT_EVENT,true,true) && !m_doingsubmit )
00382 m_doingsubmit = true;
00383
00384 m_insubmit = false;
00385
00386 if ( m_doingsubmit )
00387 submit();
00388
00389 return m_doingsubmit;
00390 }
00391
00392 void HTMLFormElementImpl::submit( )
00393 {
00394 if ( m_insubmit ) {
00395 m_doingsubmit = true;
00396 return;
00397 }
00398
00399 m_insubmit = true;
00400
00401 #ifdef FORMS_DEBUG
00402 kdDebug( 6030 ) << "submitting!" << endl;
00403 #endif
00404
00405 KHTMLView *view = getDocument()->view();
00406 for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) {
00407 HTMLGenericFormElementImpl* current = it.current();
00408 if (current->id() == ID_INPUT &&
00409 static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::TEXT &&
00410 static_cast<HTMLInputElementImpl*>(current)->autoComplete() )
00411 {
00412 HTMLInputElementImpl *input = static_cast<HTMLInputElementImpl *>(current);
00413 view->addFormCompletionItem(input->name().string(), input->value().string());
00414 }
00415 }
00416
00417 bool ok;
00418 QByteArray form_data = formData(ok);
00419 if (ok) {
00420 DOMString url(khtml::parseURL(getAttribute(ATTR_ACTION)));
00421 if(m_post) {
00422 view->part()->submitForm( "post", url.string(), form_data,
00423 m_target.string(),
00424 enctype().string(),
00425 m_boundary );
00426 }
00427 else {
00428 view->part()->submitForm( "get", url.string(), form_data,
00429 m_target.string() );
00430 }
00431 }
00432
00433 m_doingsubmit = m_insubmit = false;
00434 }
00435
00436 void HTMLFormElementImpl::reset( )
00437 {
00438 KHTMLView *view = getDocument()->view();
00439 if(m_inreset || !view || !view->part()) return;
00440
00441 m_inreset = true;
00442
00443 #ifdef FORMS_DEBUG
00444 kdDebug( 6030 ) << "reset pressed!" << endl;
00445 #endif
00446
00447
00448
00449 if ( !dispatchHTMLEvent(EventImpl::RESET_EVENT,true, true) ) {
00450 m_inreset = false;
00451 return;
00452 }
00453
00454 for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it)
00455 it.current()->reset();
00456
00457 m_inreset = false;
00458 }
00459
00460 void HTMLFormElementImpl::parseAttribute(AttributeImpl *attr)
00461 {
00462 switch(attr->id())
00463 {
00464 case ATTR_ACTION:
00465 break;
00466 case ATTR_TARGET:
00467 m_target = attr->value();
00468 break;
00469 case ATTR_METHOD:
00470 m_post = ( strcasecmp( attr->value(), "post" ) == 0 );
00471 break;
00472 case ATTR_ENCTYPE:
00473 setEnctype( attr->value() );
00474 break;
00475 case ATTR_ACCEPT_CHARSET:
00476
00477
00478 m_acceptcharset = attr->value();
00479 break;
00480 case ATTR_ACCEPT:
00481
00482 break;
00483 case ATTR_AUTOCOMPLETE:
00484 m_autocomplete = strcasecmp( attr->value(), "off" );
00485 break;
00486 case ATTR_ONSUBMIT:
00487 setHTMLEventListener(EventImpl::SUBMIT_EVENT,
00488 getDocument()->createHTMLEventListener(attr->value().string()));
00489 break;
00490 case ATTR_ONRESET:
00491 setHTMLEventListener(EventImpl::RESET_EVENT,
00492 getDocument()->createHTMLEventListener(attr->value().string()));
00493 break;
00494 case ATTR_ID:
00495 case ATTR_NAME:
00496 break;
00497 default:
00498 HTMLElementImpl::parseAttribute(attr);
00499 }
00500 }
00501
00502 void HTMLFormElementImpl::radioClicked( HTMLGenericFormElementImpl *caller )
00503 {
00504 for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) {
00505 HTMLGenericFormElementImpl *current = it.current();
00506 if (current->id() == ID_INPUT &&
00507 static_cast<HTMLInputElementImpl*>(current)->inputType() == HTMLInputElementImpl::RADIO &&
00508 current != caller && current->form() == caller->form() && current->name() == caller->name()) {
00509 static_cast<HTMLInputElementImpl*>(current)->setChecked(false);
00510 }
00511 }
00512 }
00513
00514 void HTMLFormElementImpl::registerFormElement(HTMLGenericFormElementImpl *e)
00515 {
00516 formElements.append(e);
00517 }
00518
00519 void HTMLFormElementImpl::removeFormElement(HTMLGenericFormElementImpl *e)
00520 {
00521 formElements.remove(e);
00522 }
00523
00524 void HTMLFormElementImpl::registerImgElement(HTMLImageElementImpl *e)
00525 {
00526 imgElements.append(e);
00527 }
00528
00529 void HTMLFormElementImpl::removeImgElement(HTMLImageElementImpl *e)
00530 {
00531 imgElements.remove(e);
00532 }
00533
00534
00535
00536 HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
00537 : HTMLElementImpl(doc)
00538 {
00539 m_disabled = m_readOnly = false;
00540 m_name = 0;
00541
00542 if (f)
00543 m_form = f;
00544 else
00545 m_form = getForm();
00546 if (m_form)
00547 m_form->registerFormElement(this);
00548 }
00549
00550 void HTMLGenericFormElementImpl::insertedIntoDocument()
00551 {
00552 HTMLElementImpl::insertedIntoDocument();
00553
00554 HTMLFormElementImpl* newform = getForm();
00555
00556 if (!m_form && newform) {
00557 m_form = newform;
00558 m_form->registerFormElement(this);
00559 }
00560 }
00561
00562 void HTMLGenericFormElementImpl::removedFromDocument()
00563 {
00564 HTMLElementImpl::removedFromDocument();
00565
00566 if (m_form)
00567 m_form->removeFormElement(this);
00568
00569 m_form = 0;
00570 }
00571
00572 HTMLGenericFormElementImpl::~HTMLGenericFormElementImpl()
00573 {
00574 if (m_form)
00575 m_form->removeFormElement(this);
00576 }
00577
00578 void HTMLGenericFormElementImpl::parseAttribute(AttributeImpl *attr)
00579 {
00580 switch(attr->id())
00581 {
00582 case ATTR_NAME:
00583 break;
00584 case ATTR_DISABLED:
00585 setDisabled( attr->val() != 0 );
00586 break;
00587 case ATTR_READONLY:
00588 {
00589 bool m_oldreadOnly = m_readOnly;
00590 m_readOnly = attr->val() != 0;
00591 if (m_oldreadOnly != m_readOnly) setChanged();
00592 break;
00593 }
00594 default:
00595 HTMLElementImpl::parseAttribute(attr);
00596 }
00597 }
00598
00599 void HTMLGenericFormElementImpl::attach()
00600 {
00601 assert(!attached());
00602
00603 if (m_render) {
00604 assert(m_render->style());
00605 parentNode()->renderer()->addChild(m_render, nextRenderer());
00606 m_render->updateFromElement();
00607 }
00608
00609 NodeBaseImpl::attach();
00610 }
00611
00612 HTMLFormElementImpl *HTMLGenericFormElementImpl::getForm() const
00613 {
00614 NodeImpl *p = parentNode();
00615 while(p)
00616 {
00617 if( p->id() == ID_FORM )
00618 return static_cast<HTMLFormElementImpl *>(p);
00619 p = p->parentNode();
00620 }
00621 #ifdef FORMS_DEBUG
00622 kdDebug( 6030 ) << "couldn't find form!" << endl;
00623 kdDebug( 6030 ) << kdBacktrace() << endl;
00624 #endif
00625 return 0;
00626 }
00627
00628 DOMString HTMLGenericFormElementImpl::name() const
00629 {
00630 if (m_name) return m_name;
00631
00632
00633
00634
00635 DOMString n = getAttribute(ATTR_NAME);
00636 if (n.isNull())
00637 return new DOMStringImpl("");
00638
00639 return n;
00640 }
00641
00642 void HTMLGenericFormElementImpl::setName(const DOMString& name)
00643 {
00644 if (m_name) m_name->deref();
00645 m_name = name.implementation();
00646 if (m_name) m_name->ref();
00647 }
00648
00649 void HTMLGenericFormElementImpl::onSelect()
00650 {
00651
00652 dispatchHTMLEvent(EventImpl::SELECT_EVENT,true,false);
00653 }
00654
00655 void HTMLGenericFormElementImpl::onChange()
00656 {
00657
00658 dispatchHTMLEvent(EventImpl::CHANGE_EVENT,true,false);
00659 }
00660
00661 void HTMLGenericFormElementImpl::setDisabled( bool _disabled )
00662 {
00663 if ( m_disabled != _disabled ) {
00664 m_disabled = _disabled;
00665 setChanged();
00666 }
00667 }
00668
00669 bool HTMLGenericFormElementImpl::isSelectable() const
00670 {
00671 return m_render && m_render->isWidget() &&
00672 static_cast<RenderWidget*>(m_render)->widget() &&
00673 static_cast<RenderWidget*>(m_render)->widget()->focusPolicy() >= QWidget::TabFocus;
00674 }
00675
00676 void HTMLGenericFormElementImpl::defaultEventHandler(EventImpl *evt)
00677 {
00678 if (evt->target()==this && !m_disabled)
00679 {
00680
00681 KHTMLView *view = getDocument()->view();
00682 if (evt->id()==EventImpl::DOMFOCUSIN_EVENT && isEditable() && m_render && m_render->isWidget()) {
00683 KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension *>(view->part()->browserExtension());
00684 QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
00685 if (ext)
00686 ext->editableWidgetFocused(widget);
00687 }
00688 if (evt->id()==EventImpl::MOUSEDOWN_EVENT || evt->id()==EventImpl::KHTML_KEYDOWN_EVENT)
00689 {
00690 setActive();
00691 }
00692 else if (evt->id() == EventImpl::MOUSEUP_EVENT || evt->id()==EventImpl::KHTML_KEYUP_EVENT)
00693 {
00694 if (m_active)
00695 {
00696 setActive(false);
00697 setFocus();
00698 }
00699 else {
00700 setActive(false);
00701 }
00702 }
00703
00704 if (evt->id()==EventImpl::KHTML_KEYDOWN_EVENT ||
00705 evt->id()==EventImpl::KHTML_KEYUP_EVENT)
00706 {
00707 TextEventImpl * k = static_cast<TextEventImpl *>(evt);
00708 if (k->keyVal() == QChar('\n').unicode() && m_render && m_render->isWidget() && k->qKeyEvent)
00709 QApplication::sendEvent(static_cast<RenderWidget *>(m_render)->widget(), k->qKeyEvent);
00710 }
00711
00712 if (evt->id()==EventImpl::DOMFOCUSOUT_EVENT && isEditable() && m_render && m_render->isWidget()) {
00713 KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension *>(view->part()->browserExtension());
00714 QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
00715 if (ext)
00716 ext->editableWidgetBlurred(widget);
00717
00718
00719
00720 }
00721 }
00722 if (evt->target() == this && evt->isMouseEvent() && renderer())
00723 evt->setDefaultHandled();
00724
00725 HTMLElementImpl::defaultEventHandler(evt);
00726 }
00727
00728 bool HTMLGenericFormElementImpl::isEditable()
00729 {
00730 return false;
00731 }
00732
00733
00734
00735 HTMLButtonElementImpl::HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
00736 : HTMLGenericFormElementImpl(doc, f)
00737 {
00738 m_clicked = false;
00739 m_type = SUBMIT;
00740 m_dirty = true;
00741 m_activeSubmit = false;
00742 }
00743
00744 HTMLButtonElementImpl::~HTMLButtonElementImpl()
00745 {
00746 }
00747
00748 NodeImpl::Id HTMLButtonElementImpl::id() const
00749 {
00750 return ID_BUTTON;
00751 }
00752
00753 DOMString HTMLButtonElementImpl::type() const
00754 {
00755 return getAttribute(ATTR_TYPE);
00756 }
00757
00758 void HTMLButtonElementImpl::parseAttribute(AttributeImpl *attr)
00759 {
00760 switch(attr->id())
00761 {
00762 case ATTR_TYPE:
00763 if ( strcasecmp( attr->value(), "submit" ) == 0 )
00764 m_type = SUBMIT;
00765 else if ( strcasecmp( attr->value(), "reset" ) == 0 )
00766 m_type = RESET;
00767 else if ( strcasecmp( attr->value(), "button" ) == 0 )
00768 m_type = BUTTON;
00769 break;
00770 case ATTR_VALUE:
00771 m_value = attr->value();
00772 m_currValue = m_value.string();
00773 break;
00774 case ATTR_ACCESSKEY:
00775 break;
00776 case ATTR_ONFOCUS:
00777 setHTMLEventListener(EventImpl::FOCUS_EVENT,
00778 getDocument()->createHTMLEventListener(attr->value().string()));
00779 break;
00780 case ATTR_ONBLUR:
00781 setHTMLEventListener(EventImpl::BLUR_EVENT,
00782 getDocument()->createHTMLEventListener(attr->value().string()));
00783 break;
00784 default:
00785 HTMLGenericFormElementImpl::parseAttribute(attr);
00786 }
00787 }
00788
00789 void HTMLButtonElementImpl::attach()
00790 {
00791 assert(!attached());
00792 assert(!m_render);
00793 assert(parentNode());
00794 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
00795 _style->ref();
00796 if (parentNode()->renderer() && _style->display() != NONE) {
00797 m_render = new RenderCustomButton(this);
00798 m_render->setStyle(_style);
00799 }
00800 HTMLGenericFormElementImpl::attach();
00801 _style->deref();
00802 }
00803
00804 void HTMLButtonElementImpl::defaultEventHandler(EventImpl *evt)
00805 {
00806 if (m_type != BUTTON && (evt->id() == EventImpl::DOMACTIVATE_EVENT) && !m_disabled)
00807 activate();
00808 HTMLGenericFormElementImpl::defaultEventHandler(evt);
00809 }
00810
00811 void HTMLButtonElementImpl::activate()
00812 {
00813 m_clicked = true;
00814
00815 if(m_form && m_type == SUBMIT) {
00816 m_activeSubmit = true;
00817 m_form->prepareSubmit();
00818 m_activeSubmit = false;
00819 }
00820 if(m_form && m_type == RESET)
00821 m_form->reset();
00822 }
00823
00824 bool HTMLButtonElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoding, bool )
00825 {
00826 if (m_type != SUBMIT || name().isEmpty() || !m_activeSubmit)
00827 return false;
00828
00829 encoding += fixUpfromUnicode(codec, name().string());
00830 QString enc_str = m_currValue.isNull() ? QString("") : m_currValue;
00831 encoding += fixUpfromUnicode(codec, enc_str);
00832
00833 return true;
00834 }
00835
00836
00837
00838
00839 HTMLFieldSetElementImpl::HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
00840 : HTMLGenericFormElementImpl(doc, f), m_legend(0)
00841 {
00842 }
00843
00844 HTMLFieldSetElementImpl::~HTMLFieldSetElementImpl()
00845 {
00846 }
00847
00848 NodeImpl::Id HTMLFieldSetElementImpl::id() const
00849 {
00850 return ID_FIELDSET;
00851 }
00852
00853 void HTMLFieldSetElementImpl::attach()
00854 {
00855 assert(!attached());
00856 assert(!m_render);
00857 assert(parentNode());
00858 addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
00859 addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
00860 addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
00861 addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
00862 addCSSProperty(CSS_PROP_BORDER_WIDTH, "1px");
00863 addCSSProperty(CSS_PROP_PADDING_LEFT, "4px");
00864 addCSSProperty(CSS_PROP_PADDING_RIGHT, "4px");
00865 addCSSProperty(CSS_PROP_PADDING_BOTTOM, "4px");
00866
00867
00868 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
00869 _style->ref();
00870 if (parentNode()->renderer() && _style->display() != NONE) {
00871 m_render = new RenderFieldset(this);
00872 m_render->setStyle(_style);
00873 }
00874 HTMLGenericFormElementImpl::attach();
00875 _style->deref();
00876 }
00877
00878 NodeImpl *HTMLFieldSetElementImpl::addChild(NodeImpl *child)
00879 {
00880 if(!m_legend && child->id() == ID_LEGEND) {
00881 int exceptioncode = 0;
00882 NodeImpl* r = insertBefore( child, firstChild(), exceptioncode );
00883 m_legend = child;
00884 return r;
00885 }
00886 return HTMLGenericFormElementImpl::addChild(child);
00887 }
00888
00889 void HTMLFieldSetElementImpl::parseAttribute(AttributeImpl *attr)
00890 {
00891 HTMLElementImpl::parseAttribute(attr);
00892 }
00893
00894
00895
00896 HTMLInputElementImpl::HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
00897 : HTMLGenericFormElementImpl(doc, f)
00898 {
00899 m_type = TEXT;
00900 m_maxLen = -1;
00901 m_size = 20;
00902 m_clicked = false;
00903 m_checked = false;
00904
00905 m_activeSubmit = false;
00906 m_autocomplete = true;
00907 m_inited = false;
00908
00909 xPos = 0;
00910 yPos = 0;
00911
00912 if ( m_form )
00913 m_autocomplete = f->autoComplete();
00914 }
00915
00916 HTMLInputElementImpl::~HTMLInputElementImpl()
00917 {
00918 if (getDocument()) getDocument()->deregisterMaintainsState(this);
00919 }
00920
00921 NodeImpl::Id HTMLInputElementImpl::id() const
00922 {
00923 return ID_INPUT;
00924 }
00925
00926 void HTMLInputElementImpl::setType(const DOMString& )
00927 {
00928
00929 }
00930
00931 DOMString HTMLInputElementImpl::type() const
00932 {
00933
00934 switch (m_type) {
00935 case TEXT: return "text";
00936 case PASSWORD: return "password";
00937 case CHECKBOX: return "checkbox";
00938 case RADIO: return "radio";
00939 case SUBMIT: return "submit";
00940 case RESET: return "reset";
00941 case FILE: return "file";
00942 case HIDDEN: return "hidden";
00943 case IMAGE: return "image";
00944 case BUTTON: return "button";
00945 default: return "";
00946 }
00947 }
00948
00949 QString HTMLInputElementImpl::state( )
00950 {
00951 switch (m_type) {
00952 case PASSWORD:
00953 return QString::fromLatin1(".");
00954 case CHECKBOX:
00955 case RADIO:
00956 return QString::fromLatin1(m_checked ? "on" : "off");
00957 default:
00958 return value().string()+'.';
00959 }
00960 }
00961
00962 void HTMLInputElementImpl::restoreState(const QString &state)
00963 {
00964 switch (m_type) {
00965 case CHECKBOX:
00966 case RADIO:
00967 setChecked((state == QString::fromLatin1("on")));
00968 break;
00969 case FILE:
00970 m_value = DOMString(state.left(state.length()-1));
00971 setChanged();
00972 break;
00973 default:
00974 setValue(DOMString(state.left(state.length()-1)));
00975 break;
00976 }
00977 }
00978
00979 void HTMLInputElementImpl::select( )
00980 {
00981 if(!m_render) return;
00982
00983 if (m_type == TEXT || m_type == PASSWORD)
00984 static_cast<RenderLineEdit*>(m_render)->select();
00985 else if (m_type == FILE)
00986 static_cast<RenderFileButton*>(m_render)->select();
00987 }
00988
00989 void HTMLInputElementImpl::click( )
00990 {
00991
00992 #ifdef FORMS_DEBUG
00993 kdDebug( 6030 ) << " HTMLInputElementImpl::click( )" << endl;
00994 #endif
00995 }
00996
00997 void HTMLInputElementImpl::parseAttribute(AttributeImpl *attr)
00998 {
00999 switch(attr->id())
01000 {
01001 case ATTR_AUTOCOMPLETE:
01002 m_autocomplete = strcasecmp( attr->value(), "off" );
01003 break;
01004 case ATTR_TYPE:
01005
01006 break;
01007 case ATTR_VALUE:
01008 case ATTR_CHECKED:
01009
01010 break;
01011 case ATTR_MAXLENGTH:
01012 {
01013 m_maxLen = -1;
01014 if (!attr->val()) break;
01015 bool ok;
01016 int ml = attr->val()->toInt(&ok);
01017 if (ml > 0 && ml < 1024)
01018 m_maxLen = ml;
01019 else if (ok && ml <= 0)
01020 m_maxLen = 0;
01021 setChanged();
01022 }
01023 break;
01024 case ATTR_SIZE:
01025 m_size = attr->val() ? attr->val()->toInt() : 20;
01026 break;
01027 case ATTR_ALT:
01028 case ATTR_SRC:
01029 if (m_render && m_type == IMAGE) m_render->updateFromElement();
01030 break;
01031 case ATTR_USEMAP:
01032 case ATTR_ACCESSKEY:
01033
01034 break;
01035 case ATTR_ALIGN:
01036 addHTMLAlignment( attr->value() );
01037 break;
01038 case ATTR_WIDTH:
01039
01040
01041
01042 break;
01043 case ATTR_HEIGHT:
01044 addCSSLength(CSS_PROP_HEIGHT, attr->value() );
01045 break;
01046 case ATTR_ONFOCUS:
01047 setHTMLEventListener(EventImpl::FOCUS_EVENT,
01048 getDocument()->createHTMLEventListener(attr->value().string()));
01049 break;
01050 case ATTR_ONBLUR:
01051 setHTMLEventListener(EventImpl::BLUR_EVENT,
01052 getDocument()->createHTMLEventListener(attr->value().string()));
01053 break;
01054 case ATTR_ONSELECT:
01055 setHTMLEventListener(EventImpl::SELECT_EVENT,
01056 getDocument()->createHTMLEventListener(attr->value().string()));
01057 break;
01058 case ATTR_ONCHANGE:
01059 setHTMLEventListener(EventImpl::CHANGE_EVENT,
01060 getDocument()->createHTMLEventListener(attr->value().string()));
01061 break;
01062 default:
01063 HTMLGenericFormElementImpl::parseAttribute(attr);
01064 }
01065 }
01066
01067 void HTMLInputElementImpl::attach()
01068 {
01069 assert(!attached());
01070 assert(!m_render);
01071 assert(parentNode());
01072
01073 if (!m_inited) {
01074 DOMString type = getAttribute(ATTR_TYPE);
01075 if ( strcasecmp( type, "password" ) == 0 )
01076 m_type = PASSWORD;
01077 else if ( strcasecmp( type, "checkbox" ) == 0 )
01078 m_type = CHECKBOX;
01079 else if ( strcasecmp( type, "radio" ) == 0 )
01080 m_type = RADIO;
01081 else if ( strcasecmp( type, "submit" ) == 0 )
01082 m_type = SUBMIT;
01083 else if ( strcasecmp( type, "reset" ) == 0 )
01084 m_type = RESET;
01085 else if ( strcasecmp( type, "file" ) == 0 )
01086 m_type = FILE;
01087 else if ( strcasecmp( type, "hidden" ) == 0 )
01088 m_type = HIDDEN;
01089 else if ( strcasecmp( type, "image" ) == 0 )
01090 m_type = IMAGE;
01091 else if ( strcasecmp( type, "button" ) == 0 )
01092 m_type = BUTTON;
01093 else if ( strcasecmp( type, "khtml_isindex" ) == 0 )
01094 m_type = ISINDEX;
01095 else
01096 m_type = TEXT;
01097
01098 if (m_type != FILE) m_value = getAttribute(ATTR_VALUE);
01099 if ((uint) m_type <= ISINDEX && !m_value.isEmpty()) {
01100 QString value = m_value.string();
01101
01102 QString nvalue;
01103 for (unsigned int i = 0; i < value.length(); ++i)
01104 if (value[i] >= ' ')
01105 nvalue += value[i];
01106 m_value = nvalue;
01107 }
01108 m_checked = (getAttribute(ATTR_CHECKED) != 0);
01109 m_inited = true;
01110 }
01111
01112
01113
01114
01115
01116 switch( m_type ) {
01117 case TEXT:
01118 case PASSWORD:
01119 addCSSProperty(CSS_PROP_FONT_FAMILY, "monospace");
01120
01121 case ISINDEX:
01122 case FILE:
01123 addCSSProperty(CSS_PROP_COLOR, "text");
01124 break;
01125 case SUBMIT:
01126 case RESET:
01127 case BUTTON:
01128 case CHECKBOX:
01129 case RADIO:
01130 addCSSProperty(CSS_PROP_COLOR, "buttontext" );
01131 case HIDDEN:
01132 case IMAGE:
01133 if (!getAttribute(ATTR_WIDTH).isNull())
01134 addCSSLength(CSS_PROP_WIDTH, getAttribute(ATTR_WIDTH));
01135 break;
01136 };
01137
01138 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
01139 _style->ref();
01140 if (parentNode()->renderer() && _style->display() != NONE) {
01141 switch(m_type)
01142 {
01143 case TEXT:
01144 case PASSWORD:
01145 case ISINDEX: m_render = new RenderLineEdit(this); break;
01146 case CHECKBOX: m_render = new RenderCheckBox(this); break;
01147 case RADIO: m_render = new RenderRadioButton(this); break;
01148 case SUBMIT: m_render = new RenderSubmitButton(this); break;
01149 case IMAGE: m_render = new RenderImageButton(this); break;
01150 case RESET: m_render = new RenderResetButton(this); break;
01151 case FILE: m_render = new RenderFileButton(this); break;
01152 case BUTTON: m_render = new RenderPushButton(this);
01153 case HIDDEN: break;
01154 }
01155 }
01156
01157 if (m_render)
01158 m_render->setStyle(_style);
01159
01160 HTMLGenericFormElementImpl::attach();
01161 _style->deref();
01162 }
01163
01164 DOMString HTMLInputElementImpl::altText() const
01165 {
01166
01167
01168
01169 DOMString alt = getAttribute( ATTR_ALT );
01170
01171 if ( alt.isNull() )
01172 alt = getAttribute( ATTR_TITLE );
01173 if ( alt.isNull() )
01174 alt = getAttribute( ATTR_VALUE );
01175 if ( alt.isEmpty() )
01176 alt = i18n( "Submit" );
01177
01178 return alt;
01179 }
01180
01181 bool HTMLInputElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoding, bool multipart)
01182 {
01183 QString nme = name().string();
01184
01185
01186 if (nme.isEmpty() && m_type != IMAGE) return false;
01187
01188
01189 if(m_type != IMAGE) encoding += fixUpfromUnicode(codec, nme);
01190
01191 switch (m_type) {
01192 case CHECKBOX:
01193
01194 if( checked() ) {
01195 encoding += fixUpfromUnicode(codec, value().string());
01196 return true;
01197 }
01198 break;
01199
01200 case RADIO:
01201
01202 if( checked() ) {
01203 encoding += fixUpfromUnicode(codec, value().string());
01204 return true;
01205 }
01206 break;
01207
01208 case BUTTON:
01209 case RESET:
01210
01211 return false;
01212
01213 case IMAGE:
01214
01215 if(m_clicked)
01216 {
01217 m_clicked = false;
01218 QString astr(nme.isEmpty() ? QString::fromLatin1("x") : nme + ".x");
01219
01220 encoding += fixUpfromUnicode(codec, astr);
01221 astr.setNum(KMAX( clickX(), 0 ));
01222 encoding += fixUpfromUnicode(codec, astr);
01223 astr = nme.isEmpty() ? QString::fromLatin1("y") : nme + ".y";
01224 encoding += fixUpfromUnicode(codec, astr);
01225 astr.setNum(KMAX( clickY(), 0 ) );
01226 encoding += fixUpfromUnicode(codec, astr);
01227
01228 return true;
01229 }
01230 break;
01231
01232 case SUBMIT:
01233
01234 if (m_activeSubmit)
01235 {
01236 QString enc_str = m_value.isNull() ?
01237 static_cast<RenderSubmitButton*>(m_render)->defaultLabel() : value().string();
01238
01239 if(!enc_str.isEmpty())
01240 {
01241 encoding += fixUpfromUnicode(codec, enc_str);
01242 return true;
01243 }
01244 }
01245 break;
01246
01247 case FILE:
01248 {
01249
01250 if(!renderer() || renderer()->style()->visibility() != khtml::VISIBLE)
01251 return false;
01252
01253 QString local;
01254 QCString dummy("");
01255
01256 KURL fileurl(value().string());
01257 KIO::UDSEntry filestat;
01258
01259
01260 if (multipart && KIO::NetAccess::stat(fileurl, filestat)) {
01261 KFileItem fileitem(filestat, fileurl, true, false);
01262
01263 if ( fileitem.isFile() && KIO::NetAccess::download(KURL(value().string()), local) ) {
01264 QFile file(local);
01265 if (file.open(IO_ReadOnly)) {
01266 QCString filearray(file.size()+1);
01267 int readbytes = file.readBlock( filearray.data(), file.size());
01268 if ( readbytes >= 0 )
01269 filearray[readbytes] = '\0';
01270 file.close();
01271
01272 encoding += filearray;
01273 KIO::NetAccess::removeTempFile( local );
01274
01275 return true;
01276 }
01277 }
01278 }
01279
01280 }
01281 case HIDDEN:
01282 case TEXT:
01283 case PASSWORD:
01284
01285 encoding += fixUpfromUnicode(codec, value().string());
01286 return true;
01287 case ISINDEX:
01288 encoding += fixUpfromUnicode(codec, m_value.string());
01289 return true;
01290 }
01291 return false;
01292 }
01293
01294 void HTMLInputElementImpl::reset()
01295 {
01296 setValue(getAttribute(ATTR_VALUE));
01297 setChecked(getAttribute(ATTR_CHECKED) != 0);
01298 }
01299
01300 void HTMLInputElementImpl::setChecked(bool _checked)
01301 {
01302 if (m_form && m_type == RADIO && _checked && !name().isEmpty())
01303 m_form->radioClicked(this);
01304
01305 if (m_checked == _checked) return;
01306 m_checked = _checked;
01307 setChanged();
01308 }
01309
01310
01311 DOMString HTMLInputElementImpl::value() const
01312 {
01313 if(m_value.isNull())
01314 return (m_type == CHECKBOX || m_type ==RADIO) ?
01315 DOMString("on") : DOMString("");
01316
01317 return m_value;
01318 }
01319
01320
01321 void HTMLInputElementImpl::setValue(DOMString val)
01322 {
01323 if (m_type == FILE) return;
01324
01325 m_value = (val.isNull() ? DOMString("") : val);
01326 setChanged();
01327 }
01328
01329 void HTMLInputElementImpl::blur()
01330 {
01331 if(getDocument()->focusNode() == this)
01332 getDocument()->setFocusNode(0);
01333 }
01334
01335 void HTMLInputElementImpl::focus()
01336 {
01337 getDocument()->setFocusNode(this);
01338 }
01339
01340 void HTMLInputElementImpl::defaultEventHandler(EventImpl *evt)
01341 {
01342 if ( !m_disabled )
01343 {
01344 if (evt->isMouseEvent() &&
01345 evt->id() == EventImpl::CLICK_EVENT && m_type == IMAGE && m_render) {
01346
01347 MouseEventImpl *me = static_cast<MouseEventImpl*>(evt);
01348 int offsetX, offsetY;
01349 m_render->absolutePosition(offsetX,offsetY);
01350 xPos = me->clientX()-offsetX;
01351 yPos = me->clientY()-offsetY;
01352 }
01353
01354
01355
01356
01357
01358 if ((evt->id() == EventImpl::DOMACTIVATE_EVENT) &&
01359 (m_type == IMAGE || m_type == SUBMIT || m_type == RESET))
01360 activate();
01361 }
01362 HTMLGenericFormElementImpl::defaultEventHandler(evt);
01363 }
01364
01365 void HTMLInputElementImpl::activate()
01366 {
01367 if (!m_form || !m_render)
01368 return;
01369
01370 m_clicked = true;
01371 if (m_type == RESET) {
01372 m_form->reset();
01373 }
01374 else {
01375 m_activeSubmit = true;
01376 if (!m_form->prepareSubmit()) {
01377 xPos = 0;
01378 yPos = 0;
01379 }
01380 m_activeSubmit = false;
01381 }
01382 }
01383
01384 bool HTMLInputElementImpl::isEditable()
01385 {
01386 return ((m_type == TEXT) || (m_type == PASSWORD) || (m_type == ISINDEX) || (m_type == FILE));
01387 }
01388
01389
01390
01391 HTMLLabelElementImpl::HTMLLabelElementImpl(DocumentPtr *doc)
01392 : HTMLGenericFormElementImpl(doc)
01393 {
01394 }
01395
01396 HTMLLabelElementImpl::~HTMLLabelElementImpl()
01397 {
01398 }
01399
01400 NodeImpl::Id HTMLLabelElementImpl::id() const
01401 {
01402 return ID_LABEL;
01403 }
01404
01405 void HTMLLabelElementImpl::parseAttribute(AttributeImpl *attr)
01406 {
01407 switch(attr->id())
01408 {
01409 case ATTR_ONFOCUS:
01410 setHTMLEventListener(EventImpl::FOCUS_EVENT,
01411 getDocument()->createHTMLEventListener(attr->value().string()));
01412 break;
01413 case ATTR_ONBLUR:
01414 setHTMLEventListener(EventImpl::BLUR_EVENT,
01415 getDocument()->createHTMLEventListener(attr->value().string()));
01416 break;
01417 default:
01418 HTMLElementImpl::parseAttribute(attr);
01419 }
01420 }
01421
01422 void HTMLLabelElementImpl::attach()
01423 {
01424
01425 HTMLElementImpl::attach();
01426 }
01427
01428 #if 0
01429 ElementImpl *HTMLLabelElementImpl::formElement()
01430 {
01431 DOMString formElementId = getAttribute(ATTR_FOR);
01432 if (formElementId.isEmpty())
01433 return 0;
01434 return getDocument()->getElementById(formElementId);
01435 }
01436 #endif
01437
01438
01439
01440 HTMLLegendElementImpl::HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
01441 : HTMLGenericFormElementImpl(doc, f)
01442 {
01443 }
01444
01445 HTMLLegendElementImpl::~HTMLLegendElementImpl()
01446 {
01447 }
01448
01449 NodeImpl::Id HTMLLegendElementImpl::id() const
01450 {
01451 return ID_LEGEND;
01452 }
01453
01454 void HTMLLegendElementImpl::attach()
01455 {
01456 assert(!attached());
01457 assert(!m_render);
01458 assert(parentNode());
01459 addCSSProperty(CSS_PROP_PADDING_LEFT, "1px");
01460 addCSSProperty(CSS_PROP_PADDING_RIGHT, "1px");
01461 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
01462 _style->ref();
01463 if (parentNode()->renderer() && _style->display() != NONE) {
01464 m_render = new RenderLegend(this);
01465 m_render->setStyle(_style);
01466 }
01467 HTMLGenericFormElementImpl::attach();
01468 _style->deref();
01469 }
01470
01471 void HTMLLegendElementImpl::parseAttribute(AttributeImpl *attr)
01472 {
01473 switch(attr->id())
01474 {
01475 case ATTR_ACCESSKEY:
01476
01477 break;
01478 default:
01479 HTMLElementImpl::parseAttribute(attr);
01480 }
01481 }
01482
01483
01484
01485 HTMLSelectElementImpl::HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
01486 : HTMLGenericFormElementImpl(doc, f)
01487 {
01488 m_multiple = false;
01489 m_recalcListItems = false;
01490
01491 m_size = 0;
01492 m_minwidth = 0;
01493 }
01494
01495 HTMLSelectElementImpl::~HTMLSelectElementImpl()
01496 {
01497 if (getDocument()) getDocument()->deregisterMaintainsState(this);
01498 }
01499
01500 NodeImpl::Id HTMLSelectElementImpl::id() const
01501 {
01502 return ID_SELECT;
01503 }
01504
01505 DOMString HTMLSelectElementImpl::type() const
01506 {
01507 return (m_multiple ? "select-multiple" : "select-one");
01508 }
01509
01510 long HTMLSelectElementImpl::selectedIndex() const
01511 {
01512
01513 uint o = 0;
01514 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01515 for (unsigned int i = 0; i < items.size(); i++) {
01516 if (items[i]->id() == ID_OPTION) {
01517 if (static_cast<HTMLOptionElementImpl*>(items[i])->selected())
01518 return o;
01519 o++;
01520 }
01521 }
01522 Q_ASSERT(m_multiple || items.isEmpty());
01523 return -1;
01524 }
01525
01526 void HTMLSelectElementImpl::setSelectedIndex( long index )
01527 {
01528
01529 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01530 int listIndex;
01531 for (listIndex = 0; listIndex < int(items.size()); listIndex++) {
01532 if (items[listIndex]->id() == ID_OPTION)
01533 static_cast<HTMLOptionElementImpl*>(items[listIndex])->setSelected(false);
01534 }
01535 listIndex = optionToListIndex(index);
01536 if (listIndex >= 0)
01537 static_cast<HTMLOptionElementImpl*>(items[listIndex])->setSelected(true);
01538
01539 setChanged(true);
01540 }
01541
01542 long HTMLSelectElementImpl::length() const
01543 {
01544 int len = 0;
01545 uint i;
01546 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01547 for (i = 0; i < items.size(); i++) {
01548 if (items[i]->id() == ID_OPTION)
01549 len++;
01550 }
01551 return len;
01552 }
01553
01554 void HTMLSelectElementImpl::add( const HTMLElement &element, const HTMLElement &before, int& exceptioncode )
01555 {
01556 if(element.isNull() || element.handle()->id() != ID_OPTION)
01557 return;
01558
01559 insertBefore(element.handle(), before.handle(), exceptioncode );
01560 if (!exceptioncode)
01561 setRecalcListItems();
01562 }
01563
01564 void HTMLSelectElementImpl::remove( long index )
01565 {
01566 int exceptioncode = 0;
01567 int listIndex = optionToListIndex(index);
01568
01569 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01570 if(listIndex < 0 || index >= int(items.size()))
01571 return;
01572
01573 removeChild(items[listIndex], exceptioncode);
01574 if( !exceptioncode )
01575 setRecalcListItems();
01576 }
01577
01578 void HTMLSelectElementImpl::blur()
01579 {
01580 if(getDocument()->focusNode() == this)
01581 getDocument()->setFocusNode(0);
01582 }
01583
01584 void HTMLSelectElementImpl::focus()
01585 {
01586 getDocument()->setFocusNode(this);
01587 }
01588
01589 DOMString HTMLSelectElementImpl::value( )
01590 {
01591 uint i;
01592 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01593 for (i = 0; i < items.size(); i++) {
01594 if ( items[i]->id() == ID_OPTION
01595 && static_cast<HTMLOptionElementImpl*>(items[i])->selected())
01596 return static_cast<HTMLOptionElementImpl*>(items[i])->value();
01597 }
01598 return DOMString("");
01599 }
01600
01601 void HTMLSelectElementImpl::setValue(DOMStringImpl* )
01602 {
01603
01604
01605 kdWarning() << "Unimplemented HTMLSelectElementImpl::setValue called" << endl;
01606 }
01607
01608 QString HTMLSelectElementImpl::state( )
01609 {
01610 QString state;
01611 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01612
01613 int l = items.count();
01614
01615 state.fill('.', l);
01616 for(int i = 0; i < l; i++)
01617 if(items[i]->id() == ID_OPTION && static_cast<HTMLOptionElementImpl*>(items[i])->selected())
01618 state[i] = 'X';
01619
01620 return state;
01621 }
01622
01623 void HTMLSelectElementImpl::restoreState(const QString &_state)
01624 {
01625 recalcListItems();
01626
01627 QString state = _state;
01628 if(!state.isEmpty() && !state.contains('X') && !m_multiple && m_size <= 1) {
01629 qWarning("should not happen in restoreState!");
01630 state[0] = 'X';
01631 }
01632
01633 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01634
01635 int l = items.count();
01636 for(int i = 0; i < l; i++) {
01637 if(items[i]->id() == ID_OPTION) {
01638 HTMLOptionElementImpl* oe = static_cast<HTMLOptionElementImpl*>(items[i]);
01639 oe->setSelected(state[i] == 'X');
01640 }
01641 }
01642 setChanged(true);
01643 }
01644
01645 NodeImpl *HTMLSelectElementImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode )
01646 {
01647 NodeImpl *result = HTMLGenericFormElementImpl::insertBefore(newChild,refChild, exceptioncode );
01648 if (!exceptioncode)
01649 setRecalcListItems();
01650 return result;
01651 }
01652
01653 NodeImpl *HTMLSelectElementImpl::replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode )
01654 {
01655 NodeImpl *result = HTMLGenericFormElementImpl::replaceChild(newChild,oldChild, exceptioncode);
01656 if( !exceptioncode )
01657 setRecalcListItems();
01658 return result;
01659 }
01660
01661 NodeImpl *HTMLSelectElementImpl::removeChild ( NodeImpl *oldChild, int &exceptioncode )
01662 {
01663 NodeImpl *result = HTMLGenericFormElementImpl::removeChild(oldChild, exceptioncode);
01664 if( !exceptioncode )
01665 setRecalcListItems();
01666 return result;
01667 }
01668
01669 NodeImpl *HTMLSelectElementImpl::appendChild ( NodeImpl *newChild, int &exceptioncode )
01670 {
01671 NodeImpl *result = HTMLGenericFormElementImpl::appendChild(newChild, exceptioncode);
01672 if( !exceptioncode )
01673 setRecalcListItems();
01674 setChanged(true);
01675 return result;
01676 }
01677
01678 NodeImpl* HTMLSelectElementImpl::addChild(NodeImpl* newChild)
01679 {
01680 setRecalcListItems();
01681 return HTMLGenericFormElementImpl::addChild(newChild);
01682 }
01683
01684 void HTMLSelectElementImpl::parseAttribute(AttributeImpl *attr)
01685 {
01686 switch(attr->id())
01687 {
01688 case ATTR_SIZE:
01689 m_size = QMAX( attr->val()->toInt(), 1 );
01690 break;
01691 case ATTR_WIDTH:
01692 m_minwidth = QMAX( attr->val()->toInt(), 0 );
01693 break;
01694 case ATTR_MULTIPLE:
01695 m_multiple = (attr->val() != 0);
01696 break;
01697 case ATTR_ACCESSKEY:
01698
01699 break;
01700 case ATTR_ONFOCUS:
01701 setHTMLEventListener(EventImpl::FOCUS_EVENT,
01702 getDocument()->createHTMLEventListener(attr->value().string()));
01703 break;
01704 case ATTR_ONBLUR:
01705 setHTMLEventListener(EventImpl::BLUR_EVENT,
01706 getDocument()->createHTMLEventListener(attr->value().string()));
01707 break;
01708 case ATTR_ONCHANGE:
01709 setHTMLEventListener(EventImpl::CHANGE_EVENT,
01710 getDocument()->createHTMLEventListener(attr->value().string()));
01711 break;
01712 default:
01713 HTMLGenericFormElementImpl::parseAttribute(attr);
01714 }
01715 }
01716
01717 void HTMLSelectElementImpl::attach()
01718 {
01719 assert(!attached());
01720 assert(parentNode());
01721 assert(!renderer());
01722
01723 addCSSProperty(CSS_PROP_COLOR, "text");
01724
01725 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
01726 _style->ref();
01727 if (parentNode()->renderer() && _style->display() != NONE) {
01728 m_render = new RenderSelect(this);
01729 m_render->setStyle(_style);
01730 }
01731
01732 HTMLGenericFormElementImpl::attach();
01733 _style->deref();
01734 }
01735
01736 bool HTMLSelectElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoded_values, bool)
01737 {
01738 bool successful = false;
01739 QCString enc_name = fixUpfromUnicode(codec, name().string());
01740 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01741
01742 uint i;
01743 for (i = 0; i < items.size(); i++) {
01744 if (items[i]->id() == ID_OPTION) {
01745 HTMLOptionElementImpl *option = static_cast<HTMLOptionElementImpl*>(items[i]);
01746 if (option->selected()) {
01747 encoded_values += enc_name;
01748 encoded_values += fixUpfromUnicode(codec, option->value().string());
01749 successful = true;
01750 }
01751 }
01752 }
01753
01754
01755
01756
01757 if (!successful && !m_multiple && m_size <= 1 && items.size() &&
01758 (items[0]->id() == ID_OPTION) ) {
01759 HTMLOptionElementImpl *option = static_cast<HTMLOptionElementImpl*>(items[0]);
01760 encoded_values += enc_name;
01761 if (option->value().isNull())
01762 encoded_values += fixUpfromUnicode(codec, option->text().string().stripWhiteSpace());
01763 else
01764 encoded_values += fixUpfromUnicode(codec, option->value().string());
01765 successful = true;
01766 }
01767
01768 return successful;
01769 }
01770
01771 int HTMLSelectElementImpl::optionToListIndex(int optionIndex) const
01772 {
01773 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01774 if (optionIndex < 0 || optionIndex >= int(items.size()))
01775 return -1;
01776
01777 int listIndex = 0;
01778 int optionIndex2 = 0;
01779 for (;
01780 optionIndex2 < int(items.size()) && optionIndex2 <= optionIndex;
01781 listIndex++) {
01782 if (items[listIndex]->id() == ID_OPTION)
01783 optionIndex2++;
01784 }
01785 listIndex--;
01786 return listIndex;
01787 }
01788
01789 int HTMLSelectElementImpl::listToOptionIndex(int listIndex) const
01790 {
01791 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01792 if (listIndex < 0 || listIndex >= int(items.size()) ||
01793 items[listIndex]->id() != ID_OPTION)
01794 return -1;
01795
01796 int optionIndex = 0;
01797 int i;
01798 for (i = 0; i < listIndex; i++)
01799 if (items[i]->id() == ID_OPTION)
01800 optionIndex++;
01801 return optionIndex;
01802 }
01803
01804 void HTMLSelectElementImpl::recalcListItems()
01805 {
01806 NodeImpl* current = firstChild();
01807 m_listItems.resize(0);
01808 HTMLOptionElementImpl* foundSelected = 0;
01809 while(current) {
01810 if (current->id() == ID_OPTGROUP && current->firstChild()) {
01811
01812 m_listItems.resize(m_listItems.size()+1);
01813 m_listItems[m_listItems.size()-1] = static_cast<HTMLGenericFormElementImpl*>(current);
01814 current = current->firstChild();
01815 }
01816 if (current->id() == ID_OPTION) {
01817 m_listItems.resize(m_listItems.size()+1);
01818 m_listItems[m_listItems.size()-1] = static_cast<HTMLGenericFormElementImpl*>(current);
01819 if (!foundSelected && !m_multiple && m_size <= 1) {
01820 foundSelected = static_cast<HTMLOptionElementImpl*>(current);
01821 foundSelected->m_selected = true;
01822 }
01823 else if (foundSelected && !m_multiple && static_cast<HTMLOptionElementImpl*>(current)->selected()) {
01824 foundSelected->m_selected = false;
01825 foundSelected = static_cast<HTMLOptionElementImpl*>(current);
01826 }
01827 }
01828 NodeImpl *parent = current->parentNode();
01829 current = current->nextSibling();
01830 if (!current) {
01831 if (parent != this)
01832 current = parent->nextSibling();
01833 }
01834 }
01835 m_recalcListItems = false;
01836 }
01837
01838 void HTMLSelectElementImpl::childrenChanged()
01839 {
01840 setRecalcListItems();
01841
01842 HTMLGenericFormElementImpl::childrenChanged();
01843 }
01844
01845 void HTMLSelectElementImpl::setRecalcListItems()
01846 {
01847 m_recalcListItems = true;
01848 if (m_render)
01849 static_cast<khtml::RenderSelect*>(m_render)->setOptionsChanged(true);
01850 setChanged();
01851 }
01852
01853 void HTMLSelectElementImpl::reset()
01854 {
01855 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01856 uint i;
01857 for (i = 0; i < items.size(); i++) {
01858 if (items[i]->id() == ID_OPTION) {
01859 HTMLOptionElementImpl *option = static_cast<HTMLOptionElementImpl*>(items[i]);
01860 bool selected = (!option->getAttribute(ATTR_SELECTED).isNull());
01861 option->setSelected(selected);
01862 }
01863 }
01864 if ( m_render )
01865 static_cast<RenderSelect*>(m_render)->setSelectionChanged(true);
01866 setChanged( true );
01867 }
01868
01869 void HTMLSelectElementImpl::notifyOptionSelected(HTMLOptionElementImpl *selectedOption, bool selected)
01870 {
01871 if (selected && !m_multiple) {
01872
01873 QMemArray<HTMLGenericFormElementImpl*> items = listItems();
01874 uint i;
01875 for (i = 0; i < items.size(); i++) {
01876 if (items[i]->id() == ID_OPTION)
01877 static_cast<HTMLOptionElementImpl*>(items[i])->m_selected = (items[i] == selectedOption);
01878 }
01879 }
01880 if (m_render)
01881 static_cast<RenderSelect*>(m_render)->setSelectionChanged(true);
01882
01883 setChanged(true);
01884 }
01885
01886
01887
01888 HTMLKeygenElementImpl::HTMLKeygenElementImpl(DocumentPtr* doc, HTMLFormElementImpl* f)
01889 : HTMLSelectElementImpl(doc, f)
01890 {
01891 QStringList keys = KSSLKeyGen::supportedKeySizes();
01892 for (QStringList::Iterator i = keys.begin(); i != keys.end(); ++i) {
01893 HTMLOptionElementImpl* o = new HTMLOptionElementImpl(doc, form());
01894 addChild(o);
01895 o->addChild(doc->document()->createTextNode(DOMString(*i).implementation()));
01896 }
01897 }
01898
01899 NodeImpl::Id HTMLKeygenElementImpl::id() const
01900 {
01901 return ID_KEYGEN;
01902 }
01903
01904 void HTMLKeygenElementImpl::parseAttribute(AttributeImpl* attr)
01905 {
01906 switch(attr->id())
01907 {
01908 case ATTR_CHALLENGE:
01909 break;
01910 default:
01911
01912 HTMLGenericFormElementImpl::parseAttribute(attr);
01913 }
01914 }
01915
01916 bool HTMLKeygenElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoded_values, bool)
01917 {
01918 bool successful = false;
01919 QCString enc_name = fixUpfromUnicode(codec, name().string());
01920
01921 encoded_values += enc_name;
01922
01923
01924 KSSLKeyGen *kg = new KSSLKeyGen(static_cast<RenderWidget *>(m_render)->widget(), "Key Generator", true);
01925
01926 kg->setKeySize(0);
01927 successful = (QDialog::Accepted == kg->exec());
01928
01929 delete kg;
01930
01931 encoded_values += "deadbeef";
01932
01933 return successful;
01934 }
01935
01936
01937
01938 NodeImpl::Id HTMLOptGroupElementImpl::id() const
01939 {
01940 return ID_OPTGROUP;
01941 }
01942
01943
01944
01945 HTMLOptionElementImpl::HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
01946 : HTMLGenericFormElementImpl(doc, f)
01947 {
01948 m_selected = false;
01949 }
01950
01951 NodeImpl::Id HTMLOptionElementImpl::id() const
01952 {
01953 return ID_OPTION;
01954 }
01955
01956 DOMString HTMLOptionElementImpl::text() const
01957 {
01958 if (firstChild() && firstChild()->nodeType() == Node::TEXT_NODE) {
01959 if (firstChild()->nextSibling()) {
01960 DOMString ret = "";
01961 NodeImpl *n = firstChild();
01962 for (; n; n = n->nextSibling()) {
01963 if (n->nodeType() == Node::TEXT_NODE ||
01964 n->nodeType() == Node::CDATA_SECTION_NODE)
01965 ret += n->nodeValue();
01966 }
01967 return ret;
01968 }
01969 else
01970 return firstChild()->nodeValue();
01971 }
01972 return "";
01973 }
01974
01975 long HTMLOptionElementImpl::index() const
01976 {
01977
01978
01979 QMemArray<HTMLGenericFormElementImpl*> items = getSelect()->listItems();
01980 int l = items.count();
01981 int optionIndex = 0;
01982 for(int i = 0; i < l; i++) {
01983 if(items[i]->id() == ID_OPTION)
01984 {
01985 if (static_cast<HTMLOptionElementImpl*>(items[i]) == this)
01986 return optionIndex;
01987 optionIndex++;
01988 }
01989 }
01990 kdWarning() << "HTMLOptionElementImpl::index(): option not found!" << endl;
01991 return 0;
01992 }
01993
01994 void HTMLOptionElementImpl::setIndex( long )
01995 {
01996 kdWarning() << "Unimplemented HTMLOptionElementImpl::setIndex(long) called" << endl;
01997
01998 }
01999
02000 void HTMLOptionElementImpl::parseAttribute(AttributeImpl *attr)
02001 {
02002 switch(attr->id())
02003 {
02004 case ATTR_SELECTED:
02005 m_selected = (attr->val() != 0);
02006 break;
02007 case ATTR_VALUE:
02008 m_value = attr->value();
02009 break;
02010 default:
02011 HTMLGenericFormElementImpl::parseAttribute(attr);
02012 }
02013 }
02014
02015 DOMString HTMLOptionElementImpl::value() const
02016 {
02017 if ( !m_value.isNull() )
02018 return m_value;
02019
02020 return text().string().simplifyWhiteSpace();
02021 }
02022
02023 void HTMLOptionElementImpl::setValue(DOMStringImpl* value)
02024 {
02025 setAttribute(ATTR_VALUE, value);
02026 }
02027
02028 void HTMLOptionElementImpl::setSelected(bool _selected)
02029 {
02030 if(m_selected == _selected)
02031 return;
02032 m_selected = _selected;
02033 HTMLSelectElementImpl *select = getSelect();
02034 if (select)
02035 select->notifyOptionSelected(this,_selected);
02036 }
02037
02038 HTMLSelectElementImpl *HTMLOptionElementImpl::getSelect() const
02039 {
02040 NodeImpl *select = parentNode();
02041 while (select && select->id() != ID_SELECT)
02042 select = select->parentNode();
02043 return static_cast<HTMLSelectElementImpl*>(select);
02044 }
02045
02046
02047
02048 HTMLTextAreaElementImpl::HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
02049 : HTMLGenericFormElementImpl(doc, f)
02050 {
02051
02052 m_rows = 2;
02053 m_cols = 20;
02054 m_wrap = ta_Virtual;
02055 m_dirtyvalue = true;
02056 }
02057
02058 HTMLTextAreaElementImpl::~HTMLTextAreaElementImpl()
02059 {
02060 if (getDocument()) getDocument()->deregisterMaintainsState(this);
02061 }
02062
02063 NodeImpl::Id HTMLTextAreaElementImpl::id() const
02064 {
02065 return ID_TEXTAREA;
02066 }
02067
02068 DOMString HTMLTextAreaElementImpl::type() const
02069 {
02070 return "textarea";
02071 }
02072
02073 QString HTMLTextAreaElementImpl::state( )
02074 {
02075
02076 return value().string()+'.';
02077 }
02078
02079 void HTMLTextAreaElementImpl::restoreState(const QString &state)
02080 {
02081 setDefaultValue(state.left(state.length()-1));
02082
02083 }
02084
02085 void HTMLTextAreaElementImpl::select( )
02086 {
02087 if (m_render)
02088 static_cast<RenderTextArea*>(m_render)->select();
02089 onSelect();
02090 }
02091
02092 void HTMLTextAreaElementImpl::parseAttribute(AttributeImpl *attr)
02093 {
02094 switch(attr->id())
02095 {
02096 case ATTR_ROWS:
02097 m_rows = attr->val() ? attr->val()->toInt() : 3;
02098 break;
02099 case ATTR_COLS:
02100 m_cols = attr->val() ? attr->val()->toInt() : 60;
02101 break;
02102 case ATTR_WRAP:
02103
02104
02105 if ( strcasecmp( attr->value(), "virtual" ) == 0 || strcasecmp( attr->value(), "soft") == 0)
02106 m_wrap = ta_Virtual;
02107 else if ( strcasecmp ( attr->value(), "physical" ) == 0 || strcasecmp( attr->value(), "hard") == 0)
02108 m_wrap = ta_Physical;
02109 else if(strcasecmp( attr->value(), "on" ) == 0)
02110 m_wrap = ta_Physical;
02111 else if(strcasecmp( attr->value(), "off") == 0)
02112 m_wrap = ta_NoWrap;
02113 break;
02114 case ATTR_ACCESSKEY:
02115
02116 break;
02117 case ATTR_ONFOCUS:
02118 setHTMLEventListener(EventImpl::FOCUS_EVENT,
02119 getDocument()->createHTMLEventListener(attr->value().string()));
02120 break;
02121 case ATTR_ONBLUR:
02122 setHTMLEventListener(EventImpl::BLUR_EVENT,
02123 getDocument()->createHTMLEventListener(attr->value().string()));
02124 break;
02125 case ATTR_ONSELECT:
02126 setHTMLEventListener(EventImpl::SELECT_EVENT,
02127 getDocument()->createHTMLEventListener(attr->value().string()));
02128 break;
02129 case ATTR_ONCHANGE:
02130 setHTMLEventListener(EventImpl::CHANGE_EVENT,
02131 getDocument()->createHTMLEventListener(attr->value().string()));
02132 break;
02133 default:
02134 HTMLGenericFormElementImpl::parseAttribute(attr);
02135 }
02136 }
02137
02138 void HTMLTextAreaElementImpl::attach()
02139 {
02140 assert(!attached());
02141 assert(!m_render);
02142 assert(parentNode());
02143
02144 addCSSProperty(CSS_PROP_COLOR, "text");
02145 addCSSProperty( CSS_PROP_FONT_FAMILY, "monospace" );
02146
02147 RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
02148 _style->ref();
02149 if (parentNode()->renderer() && _style->display() != NONE) {
02150 m_render = new RenderTextArea(this);
02151 m_render->setStyle(_style);
02152 }
02153
02154 HTMLGenericFormElementImpl::attach();
02155 _style->deref();
02156 }
02157
02158 bool HTMLTextAreaElementImpl::encoding(const QTextCodec* codec, encodingList& encoding, bool)
02159 {
02160 if (name().isEmpty() || !m_render) return false;
02161
02162 encoding += fixUpfromUnicode(codec, name().string());
02163 encoding += fixUpfromUnicode(codec, value().string());
02164
02165 return true;
02166 }
02167
02168 void HTMLTextAreaElementImpl::reset()
02169 {
02170 setValue(defaultValue());
02171 }
02172
02173 DOMString HTMLTextAreaElementImpl::value()
02174 {
02175 if ( m_dirtyvalue) {
02176 if ( m_render ) m_value = static_cast<RenderTextArea*>( m_render )->text();
02177 m_dirtyvalue = false;
02178 }
02179
02180 if ( m_value.isNull() ) return "";
02181
02182 return m_value;
02183 }
02184
02185 void HTMLTextAreaElementImpl::setValue(DOMString _value)
02186 {
02187
02188 QString str = _value.string().replace( "\r\n", "\n" );
02189 m_value = str.replace( "\r", "\n" );
02190 m_dirtyvalue = false;
02191 setChanged(true);
02192 }
02193
02194
02195 DOMString HTMLTextAreaElementImpl::defaultValue()
02196 {
02197 DOMString val = "";
02198
02199 NodeImpl *n;
02200 for (n = firstChild(); n; n = n->nextSibling())
02201 if (n->isTextNode())
02202 val += static_cast<TextImpl*>(n)->data();
02203 if (val[0] == '\r' && val[1] == '\n') {
02204 val = val.copy();
02205 val.remove(0,2);
02206 }
02207 else if (val[0] == '\r' || val[0] == '\n') {
02208 val = val.copy();
02209 val.remove(0,1);
02210 }
02211
02212 return val;
02213 }
02214
02215 void HTMLTextAreaElementImpl::setDefaultValue(DOMString _defaultValue)
02216 {
02217
02218 QPtrList<NodeImpl> toRemove;
02219 NodeImpl *n;
02220 for (n = firstChild(); n; n = n->nextSibling())
02221 if (n->isTextNode())
02222 toRemove.append(n);
02223 QPtrListIterator<NodeImpl> it(toRemove);
02224 int exceptioncode = 0;
02225 for (; it.current(); ++it) {
02226 removeChild(it.current(), exceptioncode);
02227 }
02228 insertBefore(getDocument()->createTextNode(_defaultValue.implementation()),firstChild(), exceptioncode);
02229 setValue(_defaultValue);
02230 }
02231
02232 void HTMLTextAreaElementImpl::blur()
02233 {
02234 if(getDocument()->focusNode() == this)
02235 getDocument()->setFocusNode(0);
02236 }
02237
02238 void HTMLTextAreaElementImpl::focus()
02239 {
02240 getDocument()->setFocusNode(this);
02241 }
02242
02243 bool HTMLTextAreaElementImpl::isEditable()
02244 {
02245 return true;
02246 }
02247
02248
02249
02250 HTMLIsIndexElementImpl::HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
02251 : HTMLInputElementImpl(doc, f)
02252 {
02253 m_type = TEXT;
02254 setName("isindex");
02255 }
02256
02257 HTMLIsIndexElementImpl::~HTMLIsIndexElementImpl()
02258 {
02259 }
02260
02261 NodeImpl::Id HTMLIsIndexElementImpl::id() const
02262 {
02263 return ID_ISINDEX;
02264 }
02265
02266 void HTMLIsIndexElementImpl::parseAttribute(AttributeImpl* attr)
02267 {
02268
02269
02270 HTMLGenericFormElementImpl::parseAttribute(attr);
02271 }
02272
02273 DOMString HTMLIsIndexElementImpl::prompt() const
02274 {
02275
02276
02277 DOM::NodeImpl* prev = previousSibling();
02278 if ( prev && prev->nodeType() == DOM::Node::TEXT_NODE)
02279 return prev->nodeValue();
02280 return "";
02281 }
02282
02283 void HTMLIsIndexElementImpl::setPrompt(const DOMString& str)
02284 {
02285
02286
02287 int exceptioncode = 0;
02288 DOM::NodeImpl* prev = previousSibling();
02289 if ( prev && prev->nodeType() == DOM::Node::TEXT_NODE)
02290 static_cast<DOM::TextImpl *>(prev)->setData(str, exceptioncode);
02291 }
02292
02293
02294