Reviewed by Maciej.
[WebKit-https.git] / WebCore / khtml / html / html_formimpl.h
1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2000 Dirk Mueller (mueller@kde.org)
7  * Copyright (C) 2004 Apple Computer, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  *
24  */
25 #ifndef HTML_FORMIMPL_H
26 #define HTML_FORMIMPL_H
27
28 #include "html/html_elementimpl.h"
29 #include "dom/html_element.h"
30 #include "html/html_miscimpl.h"
31
32 #include <qptrvector.h>
33 #include <qmemarray.h>
34
35 class KHTMLView;
36 class QTextCodec;
37
38 namespace khtml
39 {
40     class FormData;
41     class RenderFormElement;
42     class RenderTextArea;
43     class RenderSelect;
44     class RenderLineEdit;
45     class RenderRadioButton;
46     class RenderFileButton;
47 #if APPLE_CHANGES
48     class RenderSlider;
49 #endif
50 }
51
52 namespace DOM {
53
54 class DOMString;
55 class FormDataList;
56 class HTMLFormElement;
57 class HTMLGenericFormElementImpl;
58 class HTMLImageElementImpl;
59 class HTMLImageLoader;
60 class HTMLOptionElementImpl;
61 class HTMLOptionsCollectionImpl;
62
63 // -------------------------------------------------------------------------
64
65 class HTMLFormElementImpl : public HTMLElementImpl
66 {
67 public:
68     HTMLFormElementImpl(DocumentPtr *doc);
69     virtual ~HTMLFormElementImpl();
70
71     virtual Id id() const;
72
73     virtual void attach();
74     virtual void detach();
75
76     long length() const;
77
78     DOMString enctype() const { return m_enctype; }
79     void setEnctype( const DOMString & );
80
81     DOMString boundary() const { return m_boundary; }
82     void setBoundary( const DOMString & );
83
84     bool autoComplete() const { return m_autocomplete; }
85
86     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
87
88     void radioClicked( HTMLGenericFormElementImpl *caller );
89
90     void registerFormElement(HTMLGenericFormElementImpl *);
91     void removeFormElement(HTMLGenericFormElementImpl *);
92     void makeFormElementDormant(HTMLGenericFormElementImpl *);
93     void registerImgElement(HTMLImageElementImpl *);
94     void removeImgElement(HTMLImageElementImpl *);
95
96     bool prepareSubmit();
97     void submit(bool activateSubmitButton);
98     void reset();
99
100     void setMalformed(bool malformed) { m_malformed = malformed; }
101     virtual bool isMalformed() { return m_malformed; }
102     
103     virtual bool isURLAttribute(AttributeImpl *attr) const;
104     
105 #if APPLE_CHANGES
106     void submitClick();
107     bool formWouldHaveSecureSubmission(const DOMString &url);
108 #endif
109    
110     static void i18nData();
111
112     friend class HTMLFormElement;
113     friend class HTMLFormCollectionImpl;
114
115     HTMLCollectionImpl::CollectionInfo *collectionInfo;
116
117     QPtrVector<HTMLGenericFormElementImpl> formElements;
118     QPtrVector<HTMLGenericFormElementImpl> dormantFormElements;
119     QPtrVector<HTMLImageElementImpl> imgElements;
120     DOMString m_url;
121     DOMString m_target;
122     DOMString m_enctype;
123     DOMString m_boundary;
124     DOMString m_acceptcharset;
125     bool m_post : 1;
126     bool m_multipart : 1;
127     bool m_autocomplete : 1;
128     bool m_insubmit : 1;
129     bool m_doingsubmit : 1;
130     bool m_inreset : 1;
131     bool m_malformed : 1;
132
133  private:
134     bool formData(khtml::FormData &) const;
135
136     QString oldIdAttr;
137     QString oldNameAttr;
138 };
139
140 // -------------------------------------------------------------------------
141
142 class HTMLGenericFormElementImpl : public HTMLElementImpl
143 {
144     friend class HTMLFormElementImpl;
145     friend class khtml::RenderFormElement;
146
147 public:
148     HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
149     virtual ~HTMLGenericFormElementImpl();
150
151     HTMLFormElementImpl *form() { return m_form; }
152
153     virtual DOMString type() const = 0;
154
155     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
156     virtual void attach();
157     virtual void insertedIntoDocument();
158     virtual void removedFromDocument();
159
160     virtual void reset() {}
161
162     void onSelect();
163     void onChange();
164
165     virtual bool disabled() const;
166     void setDisabled(bool _disabled);
167
168     virtual bool isFocusable() const;
169     virtual bool isKeyboardFocusable() const;
170     virtual bool isMouseFocusable() const;
171     virtual bool isEnumeratable() const { return false; }
172
173     bool readOnly() const { return m_readOnly; }
174     void setReadOnly(bool _readOnly) { m_readOnly = _readOnly; }
175
176     virtual void recalcStyle( StyleChange );
177
178     DOMString name() const;
179     void setName(const DOMString& name);
180
181     virtual bool isGenericFormElement() const { return true; }
182
183     /*
184      * override in derived classes to get the encoded name=value pair
185      * for submitting
186      * return true for a successful control (see HTML4-17.13.2)
187      */
188     virtual bool appendFormData(FormDataList&, bool) { return false; }
189
190     virtual void defaultEventHandler(EventImpl *evt);
191     virtual bool isEditable();
192
193     virtual QString state();
194     QString findMatchingState(QStringList &states);
195
196     virtual bool isSuccessfulSubmitButton() const { return false; }
197     virtual bool isActivatedSubmit() const { return false; }
198     virtual void setActivatedSubmit(bool flag) { }
199
200 protected:
201     HTMLFormElementImpl *getForm() const;
202
203     DOMStringImpl* m_name;
204     HTMLFormElementImpl *m_form;
205     bool m_disabled, m_readOnly;
206
207     bool m_inited : 1;
208     bool m_dormant : 1;
209 };
210
211 // -------------------------------------------------------------------------
212
213 class HTMLButtonElementImpl : public HTMLGenericFormElementImpl
214 {
215 public:
216     HTMLButtonElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
217
218     virtual ~HTMLButtonElementImpl();
219
220     enum typeEnum {
221         SUBMIT,
222         RESET,
223         BUTTON
224     };
225
226     virtual Id id() const;
227     DOMString type() const;
228
229     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
230     virtual void defaultEventHandler(EventImpl *evt);
231     virtual bool appendFormData(FormDataList&, bool);
232
233     virtual bool isSuccessfulSubmitButton() const;
234     virtual bool isActivatedSubmit() const;
235     virtual void setActivatedSubmit(bool flag);
236
237     virtual void click();
238     virtual void accessKeyAction();
239     
240 protected:
241     DOMString m_value;
242     DOMString m_currValue;
243     typeEnum  m_type : 2;
244     bool      m_dirty : 1;
245     bool      m_activeSubmit : 1;
246 };
247
248 // -------------------------------------------------------------------------
249
250 class HTMLFieldSetElementImpl : public HTMLGenericFormElementImpl
251 {
252 public:
253     HTMLFieldSetElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
254
255     virtual ~HTMLFieldSetElementImpl();
256
257     virtual Id id() const;
258     
259     virtual bool isFocusable() const;
260     
261     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
262
263     virtual DOMString type() const;
264 };
265
266 // -------------------------------------------------------------------------
267
268 class HTMLInputElementImpl : public HTMLGenericFormElementImpl
269 {
270     friend class khtml::RenderLineEdit;
271     friend class khtml::RenderRadioButton;
272     friend class khtml::RenderFileButton;
273
274 #if APPLE_CHANGES
275     friend class HTMLSelectElementImpl;
276     friend class khtml::RenderSlider;
277 #endif
278
279 public:
280     // do not change the order!
281     enum typeEnum {
282         TEXT,
283         PASSWORD,
284         ISINDEX,
285         CHECKBOX,
286         RADIO,
287         SUBMIT,
288         RESET,
289         FILE,
290         HIDDEN,
291         IMAGE,
292         BUTTON
293 #if APPLE_CHANGES
294         ,SEARCH,
295         RANGE
296 #endif
297     };
298
299     HTMLInputElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
300     virtual ~HTMLInputElementImpl();
301
302     virtual Id id() const;
303
304     virtual bool isEnumeratable() const { return inputType() != IMAGE; }
305
306     bool autoComplete() const { return m_autocomplete; }
307
308     bool checked() const { return m_checked; }
309     void setChecked(bool);
310     long maxLength() const { return m_maxLen; }
311     int size() const { return m_size; }
312     DOMString type() const;
313     void setType(const DOMString& t);
314
315     DOMString value() const;
316     void setValue(const DOMString &);
317
318     DOMString valueWithDefault() const;
319
320     void setValueFromRenderer(const DOMString &);
321     bool valueMatchesRenderer() const { return m_valueMatchesRenderer; }
322     void setValueMatchesRenderer() { m_valueMatchesRenderer = true; }
323
324     void blur();
325     void focus();
326
327     virtual bool maintainsState() { return m_type != PASSWORD; }
328     virtual QString state();
329     virtual void restoreState(QStringList &);
330
331     void select();
332     
333     virtual void click();
334     virtual void accessKeyAction();
335
336     virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
337     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
338
339     virtual void attach();
340     virtual bool rendererIsNeeded(khtml::RenderStyle *);
341     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
342     virtual void detach();
343     virtual bool appendFormData(FormDataList&, bool);
344
345     virtual bool isSuccessfulSubmitButton() const;
346     virtual bool isActivatedSubmit() const;
347     virtual void setActivatedSubmit(bool flag);
348
349     typeEnum inputType() const { return m_type; }
350     virtual void reset();
351
352     // used in case input type=image was clicked.
353     int clickX() const { return xPos; }
354     int clickY() const { return yPos; }
355
356     virtual void defaultEventHandler(EventImpl *evt);
357     virtual bool isEditable();
358
359     DOMString altText() const;
360     
361     virtual bool isURLAttribute(AttributeImpl *attr) const;
362
363 #if APPLE_CHANGES
364     long maxResults() const { return m_maxResults; }
365 #endif
366     
367 protected:
368     bool storesValueSeparateFromAttribute() const;
369
370     DOMString m_value;
371     int       xPos;
372     short     m_maxLen;
373     short     m_size;
374     short     yPos;
375
376 #if APPLE_CHANGES
377     short     m_maxResults;
378 #endif
379
380     HTMLImageLoader* m_imageLoader;
381
382     typeEnum m_type : 4;
383     bool m_checked : 1;
384     bool m_defaultChecked : 1;
385     bool m_useDefaultChecked : 1;
386     bool m_haveType : 1;
387     bool m_activeSubmit : 1;
388     bool m_autocomplete : 1;
389     bool m_valueMatchesRenderer : 1;
390 };
391
392 // -------------------------------------------------------------------------
393
394 class HTMLLabelElementImpl : public HTMLElementImpl
395 {
396 public:
397     HTMLLabelElementImpl(DocumentPtr *doc);
398     virtual ~HTMLLabelElementImpl();
399
400     virtual bool isFocusable() const;
401     
402     virtual Id id() const;
403
404     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
405
406     virtual void accessKeyAction();
407
408     /**
409      * the form element this label is associated to.
410      */
411     ElementImpl *formElement();
412
413  private:
414     DOMString m_formElementID;
415 };
416
417 // -------------------------------------------------------------------------
418
419 class HTMLLegendElementImpl : public HTMLGenericFormElementImpl
420 {
421 public:
422     HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
423     virtual ~HTMLLegendElementImpl();
424
425     virtual bool isFocusable() const;
426     
427     virtual Id id() const;
428     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
429
430     virtual DOMString type() const;
431 };
432
433 // -------------------------------------------------------------------------
434
435 class HTMLSelectElementImpl : public HTMLGenericFormElementImpl
436 {
437     friend class khtml::RenderSelect;
438
439 public:
440     HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
441     ~HTMLSelectElementImpl();
442
443     virtual Id id() const;
444     DOMString type() const;
445
446     virtual void recalcStyle( StyleChange );
447
448     long selectedIndex() const;
449     void setSelectedIndex( long index );
450
451     virtual bool isEnumeratable() const { return true; }
452
453     long length() const;
454
455     long minWidth() const { return m_minwidth; }
456
457     long size() const { return m_size; }
458
459     bool multiple() const { return m_multiple; }
460
461     void add ( HTMLElementImpl *element, HTMLElementImpl *before );
462     void remove ( long index );
463     void blur();
464     void focus();
465
466     DOMString value();
467     void setValue(DOMStringImpl* value);
468     
469     HTMLOptionsCollectionImpl *options();
470
471     virtual bool maintainsState() { return true; }
472     virtual QString state();
473     virtual void restoreState(QStringList &);
474
475     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
476     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
477     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
478     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
479     virtual NodeImpl *addChild( NodeImpl* newChild );
480
481     virtual void childrenChanged();
482
483     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
484
485     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
486     virtual bool appendFormData(FormDataList&, bool);
487
488     // get the actual listbox index of the optionIndexth option
489     int optionToListIndex(int optionIndex) const;
490     // reverse of optionToListIndex - get optionIndex from listboxIndex
491     int listToOptionIndex(int listIndex) const;
492
493     void setRecalcListItems();
494
495     QMemArray<HTMLGenericFormElementImpl*> listItems() const
496      {
497          if (m_recalcListItems) const_cast<HTMLSelectElementImpl*>(this)->recalcListItems();
498          return m_listItems;
499      }
500     virtual void reset();
501     void notifyOptionSelected(HTMLOptionElementImpl *selectedOption, bool selected);
502
503 #if APPLE_CHANGES
504     virtual void defaultEventHandler(EventImpl *evt);
505 #endif
506
507     virtual void accessKeyAction();
508
509 private:
510     void recalcListItems();
511
512 protected:
513     mutable QMemArray<HTMLGenericFormElementImpl*> m_listItems;
514     HTMLOptionsCollectionImpl *m_options;
515     short m_minwidth;
516     short m_size;
517     bool m_multiple;
518     bool m_recalcListItems;
519 };
520
521 // -------------------------------------------------------------------------
522
523 class HTMLKeygenElementImpl : public HTMLSelectElementImpl
524 {
525 public:
526     HTMLKeygenElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
527
528     virtual Id id() const;
529
530     DOMString type() const;
531
532     // ### this is just a rough guess
533     virtual bool isEnumeratable() const { return false; }
534
535     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
536     virtual bool appendFormData(FormDataList&, bool);
537 protected:
538     AtomicString m_challenge;
539     AtomicString m_keyType;
540 };
541
542 // -------------------------------------------------------------------------
543
544 class HTMLOptGroupElementImpl : public HTMLGenericFormElementImpl
545 {
546 public:
547     HTMLOptGroupElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
548     virtual ~HTMLOptGroupElementImpl();
549
550     virtual Id id() const;
551     DOMString type() const;
552
553     virtual bool isFocusable() const;
554     
555     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
556     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
557     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
558     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
559     virtual NodeImpl *addChild( NodeImpl* newChild );
560     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
561     void recalcSelectOptions();
562
563 };
564
565
566 // ---------------------------------------------------------------------------
567
568 class HTMLOptionElementImpl : public HTMLGenericFormElementImpl
569 {
570     friend class khtml::RenderSelect;
571     friend class DOM::HTMLSelectElementImpl;
572
573 public:
574     HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
575
576     virtual bool isFocusable() const;
577     
578     virtual Id id() const;
579     DOMString type() const;
580
581     DOMString text() const;
582
583     long index() const;
584     void setIndex( long );
585     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
586     DOMString value() const;
587     void setValue(DOMStringImpl* value);
588
589     bool selected() const { return m_selected; }
590     void setSelected(bool _selected);
591
592     HTMLSelectElementImpl *getSelect() const;
593
594     virtual void childrenChanged();
595
596 protected:
597     DOMString m_value;
598     bool m_selected;
599 };
600
601
602 // -------------------------------------------------------------------------
603
604 class HTMLTextAreaElementImpl : public HTMLGenericFormElementImpl
605 {
606     friend class khtml::RenderTextArea;
607
608 public:
609     enum WrapMethod {
610         ta_NoWrap,
611         ta_Virtual,
612         ta_Physical
613     };
614
615     HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
616     ~HTMLTextAreaElementImpl();
617
618     virtual Id id() const;
619
620     long cols() const { return m_cols; }
621
622     long rows() const { return m_rows; }
623
624     WrapMethod wrap() const { return m_wrap; }
625
626     virtual bool isEnumeratable() const { return true; }
627
628     DOMString type() const;
629
630     virtual bool maintainsState() { return true; }
631     virtual QString state();
632     virtual void restoreState(QStringList &);
633
634     void select (  );
635
636     virtual void childrenChanged();
637     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
638     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
639     virtual void detach();
640     virtual bool appendFormData(FormDataList&, bool);
641     virtual void reset();
642     DOMString value();
643     void setValue(const DOMString &value);
644     DOMString defaultValue();
645     void setDefaultValue(const DOMString &value);
646     void blur();
647     void focus();
648
649     void invalidateValue() { m_valueIsValid = false; }
650     void updateValue();
651
652     bool valueMatchesRenderer() const { return m_valueMatchesRenderer; }
653     void setValueMatchesRenderer() { m_valueMatchesRenderer = true; }
654
655     virtual bool isEditable();
656     
657     virtual void accessKeyAction();
658     
659 protected:
660     int m_rows;
661     int m_cols;
662     WrapMethod m_wrap;
663     QString m_value;
664     bool m_valueIsValid;
665     bool m_valueMatchesRenderer;
666 };
667
668 // -------------------------------------------------------------------------
669
670 class HTMLIsIndexElementImpl : public HTMLInputElementImpl
671 {
672 public:
673     HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
674
675     virtual Id id() const;
676     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
677
678 protected:
679     DOMString m_prompt;
680 };
681
682 // -------------------------------------------------------------------------
683
684 class HTMLOptionsCollectionImpl : public khtml::Shared<HTMLOptionsCollectionImpl>
685 {
686 public:
687     HTMLOptionsCollectionImpl(HTMLSelectElementImpl *impl) : m_select(impl) { }
688
689     unsigned long length() const;
690     void setLength(unsigned long);
691     NodeImpl *item(unsigned long index) const;
692     NodeImpl *namedItem(const DOMString &name) const;
693
694     void detach() { m_select = 0; }
695
696 private:
697     HTMLSelectElementImpl *m_select;
698 };
699
700 } //namespace
701
702 #endif