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