Reviewed by Dave.
[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     void blur();
319     void focus();
320
321     virtual bool maintainsState() { return m_type != PASSWORD; }
322     virtual QString state();
323     virtual void restoreState(QStringList &);
324
325     void select();
326     
327     virtual void click();
328     virtual void accessKeyAction();
329
330     virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
331     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
332
333     virtual void attach();
334     virtual bool rendererIsNeeded(khtml::RenderStyle *);
335     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
336     virtual bool appendFormData(FormDataList&, bool);
337
338     virtual bool isSuccessfulSubmitButton() const;
339     virtual bool isActivatedSubmit() const;
340     virtual void setActivatedSubmit(bool flag);
341
342     typeEnum inputType() const { return m_type; }
343     virtual void reset();
344
345     // used in case input type=image was clicked.
346     int clickX() const { return xPos; }
347     int clickY() const { return yPos; }
348
349     virtual void defaultEventHandler(EventImpl *evt);
350     virtual bool isEditable();
351
352     DOMString altText() const;
353     
354     virtual bool isURLAttribute(AttributeImpl *attr) const;
355
356 #if APPLE_CHANGES
357     long maxResults() const { return m_maxResults; }
358 #endif
359     
360 protected:
361     bool storesValueSeparateFromAttribute() const;
362
363     DOMString m_value;
364     int       xPos;
365     short     m_maxLen;
366     short     m_size;
367     short     yPos;
368
369 #if APPLE_CHANGES
370     short     m_maxResults;
371 #endif
372
373     HTMLImageLoader* m_imageLoader;
374
375     typeEnum m_type : 4;
376     bool m_checked : 1;
377     bool m_defaultChecked : 1;
378     bool m_useDefaultChecked : 1;
379     bool m_haveType : 1;
380     bool m_activeSubmit : 1;
381     bool m_autocomplete : 1;
382 };
383
384 // -------------------------------------------------------------------------
385
386 class HTMLLabelElementImpl : public HTMLElementImpl
387 {
388 public:
389     HTMLLabelElementImpl(DocumentPtr *doc);
390     virtual ~HTMLLabelElementImpl();
391
392     virtual bool isFocusable() const;
393     
394     virtual Id id() const;
395
396     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
397
398     virtual void accessKeyAction();
399
400     /**
401      * the form element this label is associated to.
402      */
403     ElementImpl *formElement();
404
405  private:
406     DOMString m_formElementID;
407 };
408
409 // -------------------------------------------------------------------------
410
411 class HTMLLegendElementImpl : public HTMLGenericFormElementImpl
412 {
413 public:
414     HTMLLegendElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
415     virtual ~HTMLLegendElementImpl();
416
417     virtual bool isFocusable() const;
418     
419     virtual Id id() const;
420     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
421
422     virtual DOMString type() const;
423 };
424
425 // -------------------------------------------------------------------------
426
427 class HTMLSelectElementImpl : public HTMLGenericFormElementImpl
428 {
429     friend class khtml::RenderSelect;
430
431 public:
432     HTMLSelectElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
433     ~HTMLSelectElementImpl();
434
435     virtual Id id() const;
436     DOMString type() const;
437
438     virtual void recalcStyle( StyleChange );
439
440     long selectedIndex() const;
441     void setSelectedIndex( long index );
442
443     virtual bool isEnumeratable() const { return true; }
444
445     long length() const;
446
447     long minWidth() const { return m_minwidth; }
448
449     long size() const { return m_size; }
450
451     bool multiple() const { return m_multiple; }
452
453     void add ( HTMLElementImpl *element, HTMLElementImpl *before );
454     void remove ( long index );
455     void blur();
456     void focus();
457
458     DOMString value();
459     void setValue(DOMStringImpl* value);
460     
461     HTMLOptionsCollectionImpl *options();
462
463     virtual bool maintainsState() { return true; }
464     virtual QString state();
465     virtual void restoreState(QStringList &);
466
467     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
468     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
469     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
470     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
471     virtual NodeImpl *addChild( NodeImpl* newChild );
472
473     virtual void childrenChanged();
474
475     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
476
477     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
478     virtual bool appendFormData(FormDataList&, bool);
479
480     // get the actual listbox index of the optionIndexth option
481     int optionToListIndex(int optionIndex) const;
482     // reverse of optionToListIndex - get optionIndex from listboxIndex
483     int listToOptionIndex(int listIndex) const;
484
485     void setRecalcListItems();
486
487     QMemArray<HTMLGenericFormElementImpl*> listItems() const
488      {
489          if (m_recalcListItems) const_cast<HTMLSelectElementImpl*>(this)->recalcListItems();
490          return m_listItems;
491      }
492     virtual void reset();
493     void notifyOptionSelected(HTMLOptionElementImpl *selectedOption, bool selected);
494
495 #if APPLE_CHANGES
496     virtual void defaultEventHandler(EventImpl *evt);
497 #endif
498
499     virtual void accessKeyAction();
500
501 private:
502     void recalcListItems();
503
504 protected:
505     mutable QMemArray<HTMLGenericFormElementImpl*> m_listItems;
506     HTMLOptionsCollectionImpl *m_options;
507     short m_minwidth;
508     short m_size;
509     bool m_multiple;
510     bool m_recalcListItems;
511 };
512
513 // -------------------------------------------------------------------------
514
515 class HTMLKeygenElementImpl : public HTMLSelectElementImpl
516 {
517 public:
518     HTMLKeygenElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
519
520     virtual Id id() const;
521
522     DOMString type() const;
523
524     // ### this is just a rough guess
525     virtual bool isEnumeratable() const { return false; }
526
527     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
528     virtual bool appendFormData(FormDataList&, bool);
529 protected:
530     AtomicString m_challenge;
531     AtomicString m_keyType;
532 };
533
534 // -------------------------------------------------------------------------
535
536 class HTMLOptGroupElementImpl : public HTMLGenericFormElementImpl
537 {
538 public:
539     HTMLOptGroupElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
540     virtual ~HTMLOptGroupElementImpl();
541
542     virtual Id id() const;
543     DOMString type() const;
544
545     virtual bool isFocusable() const;
546     
547     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
548     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
549     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
550     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
551     virtual NodeImpl *addChild( NodeImpl* newChild );
552     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
553     void recalcSelectOptions();
554
555 };
556
557
558 // ---------------------------------------------------------------------------
559
560 class HTMLOptionElementImpl : public HTMLGenericFormElementImpl
561 {
562     friend class khtml::RenderSelect;
563     friend class DOM::HTMLSelectElementImpl;
564
565 public:
566     HTMLOptionElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
567
568     virtual bool isFocusable() const;
569     
570     virtual Id id() const;
571     DOMString type() const;
572
573     DOMString text() const;
574
575     long index() const;
576     void setIndex( long );
577     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
578     DOMString value() const;
579     void setValue(DOMStringImpl* value);
580
581     bool selected() const { return m_selected; }
582     void setSelected(bool _selected);
583
584     HTMLSelectElementImpl *getSelect() const;
585
586     virtual void childrenChanged();
587
588 protected:
589     DOMString m_value;
590     bool m_selected;
591 };
592
593
594 // -------------------------------------------------------------------------
595
596 class HTMLTextAreaElementImpl : public HTMLGenericFormElementImpl
597 {
598     friend class khtml::RenderTextArea;
599
600 public:
601     enum WrapMethod {
602         ta_NoWrap,
603         ta_Virtual,
604         ta_Physical
605     };
606
607     HTMLTextAreaElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
608     ~HTMLTextAreaElementImpl();
609
610     virtual Id id() const;
611
612     long cols() const { return m_cols; }
613
614     long rows() const { return m_rows; }
615
616     WrapMethod wrap() const { return m_wrap; }
617
618     virtual bool isEnumeratable() const { return true; }
619
620     DOMString type() const;
621
622     virtual bool maintainsState() { return true; }
623     virtual QString state();
624     virtual void restoreState(QStringList &);
625
626     void select (  );
627
628     virtual void childrenChanged();
629     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
630     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
631     virtual bool appendFormData(FormDataList&, bool);
632     virtual void reset();
633     DOMString value();
634     void setValue(DOMString _value);
635     DOMString defaultValue();
636     void setDefaultValue(DOMString _defaultValue);
637     void blur();
638     void focus();
639
640     virtual bool isEditable();
641     
642     virtual void accessKeyAction();
643     
644 protected:
645     int m_rows;
646     int m_cols;
647     WrapMethod m_wrap;
648     QString m_value;
649     bool m_dirtyvalue;
650 };
651
652 // -------------------------------------------------------------------------
653
654 class HTMLIsIndexElementImpl : public HTMLInputElementImpl
655 {
656 public:
657     HTMLIsIndexElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
658
659     virtual Id id() const;
660     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
661
662 protected:
663     DOMString m_prompt;
664 };
665
666 // -------------------------------------------------------------------------
667
668 class HTMLOptionsCollectionImpl : public khtml::Shared<HTMLOptionsCollectionImpl>
669 {
670 public:
671     HTMLOptionsCollectionImpl(HTMLSelectElementImpl *impl) : m_select(impl) { }
672
673     unsigned long length() const;
674     void setLength(unsigned long);
675     NodeImpl *item(unsigned long index) const;
676     NodeImpl *namedItem(const DOMString &name) const;
677
678     void detach() { m_select = 0; }
679
680 private:
681     HTMLSelectElementImpl *m_select;
682 };
683
684 } //namespace
685
686 #endif