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