File indexing completed on 2024-04-28 15:23:29

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0006  *           (C) 2000 Dirk Mueller (mueller@kde.org)
0007  *           (C) 2004, 2005, 2006 Apple Computer, Inc.
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  *
0024  */
0025 #ifndef HTML_FORMIMPL_H
0026 #define HTML_FORMIMPL_H
0027 
0028 #include "html/html_elementimpl.h"
0029 #include "html/html_imageimpl.h"
0030 #include "dom/html_element.h"
0031 #include <wtf/HashSet.h>
0032 #include <wtf/Vector.h>
0033 
0034 class QTextCodec;
0035 
0036 namespace khtml
0037 {
0038 class RenderFormElement;
0039 class RenderTextArea;
0040 class RenderSelect;
0041 class RenderLineEdit;
0042 class RenderRadioButton;
0043 class RenderFileButton;
0044 
0045 typedef QList<QByteArray> encodingList;
0046 }
0047 
0048 namespace KWallet
0049 {
0050 class Wallet;
0051 }
0052 
0053 namespace DOM
0054 {
0055 
0056 class HTMLFormElement;
0057 class DOMString;
0058 class HTMLGenericFormElementImpl;
0059 class HTMLOptionElementImpl;
0060 class HTMLCollectionImpl;
0061 
0062 // -------------------------------------------------------------------------
0063 
0064 class HTMLFormElementImpl : public HTMLElementImpl
0065 {
0066 public:
0067     HTMLFormElementImpl(DocumentImpl *doc, bool implicit);
0068     virtual ~HTMLFormElementImpl();
0069 
0070     Id id() const override;
0071 
0072     void insertedIntoDocument() override;
0073     void removedFromDocument() override;
0074     void addId(const DOMString &id) override;
0075     void removeId(const DOMString &id) override;
0076 
0077     // See "past names map" in HTML5, 4.10.3, "The form element"
0078     HTMLGenericFormElementImpl *lookupByPastName(const DOMString &id);
0079     void bindPastName(HTMLGenericFormElementImpl *element);
0080 
0081     long length() const;
0082 
0083     QByteArray formData(bool &ok);
0084 
0085     DOMString enctype() const
0086     {
0087         return m_enctype;
0088     }
0089     void setEnctype(const DOMString &);
0090 
0091     DOMString target() const;
0092     DOMString action() const;
0093     HTMLCollectionImpl *elements();
0094 
0095     bool autoComplete() const
0096     {
0097         return m_autocomplete;
0098     }
0099     void doAutoFill();
0100     void walletOpened(KWallet::Wallet *w);
0101 
0102     void parseAttribute(AttributeImpl *attr) override;
0103 
0104     void uncheckOtherRadioButtonsInGroup(HTMLGenericFormElementImpl *caller, bool setDefaultChecked = false);
0105 
0106     void registerFormElement(HTMLGenericFormElementImpl *);
0107     void removeFormElement(HTMLGenericFormElementImpl *);
0108     void registerImgElement(HTMLImageElementImpl *);
0109     void removeImgElement(HTMLImageElementImpl *);
0110 
0111     void submitFromKeyboard();
0112     bool prepareSubmit();
0113     void submit();
0114     void reset();
0115 
0116     void setMalformed(bool malformed)
0117     {
0118         m_malformed = malformed;
0119     }
0120     bool isMalformed() const
0121     {
0122         return m_malformed;
0123     }
0124 
0125     friend class HTMLFormElement;
0126     friend class HTMLFormCollectionImpl;
0127 
0128 private:
0129     // Collects nodes that are inside the toGather set in tree order
0130     WTF::Vector<HTMLGenericFormElementImpl *> gatherInTreeOrder(NodeImpl *root,
0131             const WTF::HashSet<NodeImpl *> &toGather);
0132 
0133     void gatherWalletData();
0134     QList<HTMLGenericFormElementImpl *> formElements;
0135     QList<HTMLImageElementImpl *> imgElements;
0136     DOMString m_target;
0137     DOMString m_enctype;
0138     QString m_boundary;
0139     DOMString m_acceptcharset;
0140     bool m_post : 1;
0141     bool m_multipart : 1;
0142     bool m_autocomplete : 1;
0143     bool m_insubmit : 1;
0144     bool m_doingsubmit : 1;
0145     bool m_inreset : 1;
0146     bool m_malformed : 1;
0147     bool m_haveTextarea : 1; // for wallet storage
0148     bool m_havePassword : 1; // for wallet storage
0149     DOMString m_name;        // our name
0150     QMap<QString, QString> m_walletMap; // for wallet storage
0151 
0152     QHash<DOMString, HTMLGenericFormElementImpl *> m_pastNamesMap;
0153 };
0154 
0155 // -------------------------------------------------------------------------
0156 
0157 class HTMLGenericFormElementImpl : public HTMLElementImpl
0158 {
0159     friend class HTMLFormElementImpl;
0160     friend class khtml::RenderFormElement;
0161 
0162 public:
0163     HTMLGenericFormElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0164     virtual ~HTMLGenericFormElementImpl();
0165 
0166     HTMLFormElementImpl *form() const
0167     {
0168         return m_form;
0169     }
0170 
0171     void parseAttribute(AttributeImpl *attr) override;
0172     void attach() override;
0173     virtual void reset() {}
0174 
0175     void insertedIntoDocument() override;
0176     void removedFromDocument() override;
0177 
0178     void onSelect();
0179     void onChange();
0180 
0181     bool disabled() const
0182     {
0183         return m_disabled;
0184     }
0185     void setDisabled(bool _disabled);
0186 
0187     bool isFocusableImpl(FocusType ft) const override;
0188     virtual bool isEnumerable() const
0189     {
0190         return false;
0191     }
0192     virtual bool isDefault() const
0193     {
0194         return false;
0195     }
0196 
0197     bool readOnly() const
0198     {
0199         return m_readOnly;
0200     }
0201     void setReadOnly(bool _readOnly)
0202     {
0203         m_readOnly = _readOnly;
0204     }
0205 
0206     DOMString name() const;
0207     void setName(const DOMString &name);
0208 
0209     bool isGenericFormElement() const override
0210     {
0211         return true;
0212     }
0213     virtual bool isHiddenInput() const
0214     {
0215         return false;
0216     }
0217 
0218     bool hasPastNames() const
0219     {
0220         return m_hasPastNames;
0221     }
0222     void setHasPastNames()
0223     {
0224         m_hasPastNames = true;
0225     }
0226 
0227     /*
0228      * override in derived classes to get the encoded name=value pair
0229      * for submitting
0230      * return true for a successful control (see HTML4-17.13.2)
0231      */
0232     virtual bool encoding(const QTextCodec *, khtml::encodingList &, bool)
0233     {
0234         return false;
0235     }
0236 
0237     void defaultEventHandler(EventImpl *evt) override;
0238     virtual bool isEditable();
0239 
0240     virtual bool unsubmittedFormChanges() const
0241     {
0242         return false;
0243     }
0244 
0245 protected:
0246     HTMLFormElementImpl *getForm() const;
0247 
0248     DOMStringImpl *m_name;
0249     HTMLFormElementImpl *m_form;
0250     bool m_disabled, m_readOnly, m_hasPastNames;
0251 };
0252 
0253 // -------------------------------------------------------------------------
0254 
0255 class HTMLButtonElementImpl : public HTMLGenericFormElementImpl
0256 {
0257 public:
0258     HTMLButtonElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0259 
0260     virtual ~HTMLButtonElementImpl();
0261 
0262     enum typeEnum {
0263         SUBMIT,
0264         RESET,
0265         BUTTON
0266     };
0267 
0268     Id id() const override;
0269     bool isEnumerable() const override
0270     {
0271         return true;
0272     }
0273 
0274     DOMString type() const;
0275     typeEnum buttonType() const
0276     {
0277         return KDE_CAST_BF_ENUM(typeEnum, m_type);
0278     }
0279     void parseAttribute(AttributeImpl *attr) override;
0280     void defaultEventHandler(EventImpl *evt) override;
0281     bool encoding(const QTextCodec *, khtml::encodingList &, bool) override;
0282     void activate();
0283     void attach() override;
0284     void click();
0285 
0286 protected:
0287     DOMString             m_value;
0288     QString               m_currValue;
0289     KDE_BF_ENUM(typeEnum) m_type : 2;
0290     bool                  m_dirty : 1;
0291     bool                  m_clicked : 1;
0292     bool                  m_activeSubmit : 1;
0293 };
0294 
0295 // -------------------------------------------------------------------------
0296 
0297 class HTMLFieldSetElementImpl : public HTMLGenericFormElementImpl
0298 {
0299 public:
0300     HTMLFieldSetElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0301 
0302     virtual ~HTMLFieldSetElementImpl();
0303 
0304     Id id() const override;
0305     void attach() override;
0306     void parseAttribute(AttributeImpl *attr) override;
0307 
0308 };
0309 
0310 // -------------------------------------------------------------------------
0311 
0312 class HTMLInputElementImpl : public HTMLGenericFormElementImpl
0313 {
0314     friend class khtml::RenderLineEdit;
0315     friend class khtml::RenderRadioButton;
0316     friend class khtml::RenderFileButton;
0317 
0318 public:
0319     // do not change the order!
0320     enum typeEnum {
0321         TEXT,
0322         PASSWORD,
0323         ISINDEX,
0324         CHECKBOX,
0325         RADIO,
0326         SUBMIT,
0327         RESET,
0328         FILE,
0329         HIDDEN,
0330         IMAGE,
0331         BUTTON
0332     };
0333 
0334     HTMLInputElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0335     virtual ~HTMLInputElementImpl();
0336 
0337     Id id() const override;
0338 
0339     bool isEnumerable() const override
0340     {
0341         return inputType() != IMAGE;
0342     }
0343     bool isDefault() const override
0344     {
0345         return m_defaultChecked;
0346     }
0347     bool isHiddenInput() const override
0348     {
0349         return inputType() == HIDDEN;
0350     }
0351 
0352     bool autoComplete() const
0353     {
0354         return m_autocomplete;
0355     }
0356 
0357     bool defaultChecked() const
0358     {
0359         return m_defaultChecked;
0360     }
0361     bool checked() const
0362     {
0363         return m_useDefaultChecked ? m_defaultChecked : m_checked;
0364     }
0365     void setChecked(bool, bool setDefaultChecked = false);
0366     bool indeterminate() const
0367     {
0368         return m_indeterminate;
0369     }
0370     void setIndeterminate(bool);
0371     long maxLength() const
0372     {
0373         return m_maxLen;
0374     }
0375     int size() const
0376     {
0377         return m_size;
0378     }
0379     DOMString type() const;
0380     void setType(const DOMString &t);
0381 
0382     DOMString value() const;
0383     void setValue(DOMString val);
0384 
0385     DOMString valueWithDefault() const;
0386 
0387     bool maintainsState() override
0388     {
0389         return true;
0390     }
0391     QString state() override;
0392     void restoreState(const QString &state) override;
0393 
0394     void select();
0395     void click();
0396 
0397     void parseAttribute(AttributeImpl *attr) override;
0398 
0399     void copyNonAttributeProperties(const ElementImpl *source) override;
0400 
0401     void attach() override;
0402     bool encoding(const QTextCodec *, khtml::encodingList &, bool) override;
0403 
0404     typeEnum inputType() const
0405     {
0406         return KDE_CAST_BF_ENUM(typeEnum, m_type);
0407     }
0408     void reset() override;
0409 
0410     // used in case input type=image was clicked.
0411     int clickX() const
0412     {
0413         return xPos;
0414     }
0415     int clickY() const
0416     {
0417         return yPos;
0418     }
0419 
0420     void defaultEventHandler(EventImpl *evt) override;
0421     bool isEditable() override;
0422 
0423     DOMString altText() const;
0424     void activate();
0425 
0426     void setUnsubmittedFormChange(bool unsubmitted)
0427     {
0428         m_unsubmittedFormChange = unsubmitted;
0429     }
0430     bool unsubmittedFormChanges() const override
0431     {
0432         return m_unsubmittedFormChange;
0433     }
0434 
0435     //Mozilla extensions.
0436     long selectionStart();
0437     long selectionEnd();
0438     void setSelectionStart(long pos);
0439     void setSelectionEnd(long pos);
0440     void setSelectionRange(long start, long end);
0441 
0442     // HTML5
0443     void setPlaceholder(const DOMString &p);
0444     DOMString placeholder() const;
0445 
0446 protected:
0447     void parseType(const DOMString &t);
0448 
0449     DOMString m_value;
0450     int       xPos;
0451     short     m_maxLen;
0452     short     m_size;
0453     short     yPos;
0454 
0455     KDE_BF_ENUM(typeEnum) m_type : 4;
0456     bool m_clicked : 1;
0457     bool m_checked : 1;
0458     bool m_defaultChecked : 1; // could do without by checking ATTR_CHECKED
0459     bool m_useDefaultChecked : 1;
0460     bool m_indeterminate : 1;
0461     bool m_haveType : 1;
0462     bool m_activeSubmit : 1;
0463     bool m_autocomplete : 1;
0464     bool m_inited : 1;
0465     bool m_unsubmittedFormChange : 1;
0466 };
0467 
0468 // -------------------------------------------------------------------------
0469 
0470 class HTMLLabelElementImpl : public HTMLGenericFormElementImpl
0471 {
0472 public:
0473     HTMLLabelElementImpl(DocumentImpl *doc);
0474     virtual ~HTMLLabelElementImpl();
0475 
0476     Id id() const override;
0477     void attach() override;
0478     void defaultEventHandler(EventImpl *evt) override;
0479     bool isFocusableImpl(FocusType ft) const override;
0480     NodeImpl *getFormElement();
0481 
0482 private:
0483     DOMString m_formElementID;
0484 };
0485 
0486 // -------------------------------------------------------------------------
0487 
0488 class HTMLLegendElementImpl : public HTMLGenericFormElementImpl
0489 {
0490 public:
0491     HTMLLegendElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0492     virtual ~HTMLLegendElementImpl();
0493 
0494     Id id() const override;
0495     void attach() override;
0496     void parseAttribute(AttributeImpl *attr) override;
0497 };
0498 
0499 // -------------------------------------------------------------------------
0500 
0501 class HTMLSelectElementImpl : public HTMLGenericFormElementImpl
0502 {
0503     friend class khtml::RenderSelect;
0504 
0505 public:
0506     HTMLSelectElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0507     ~HTMLSelectElementImpl();
0508 
0509     Id id() const override;
0510 
0511     DOMString type() const;
0512 
0513     HTMLCollectionImpl *options();
0514 
0515     long selectedIndex() const;
0516     void setSelectedIndex(long index);
0517 
0518     bool isEnumerable() const override
0519     {
0520         return true;
0521     }
0522 
0523     long length() const;
0524 
0525     long minWidth() const
0526     {
0527         return m_minwidth;
0528     }
0529 
0530     long size() const
0531     {
0532         return m_size;
0533     }
0534 
0535     bool multiple() const
0536     {
0537         return m_multiple;
0538     }
0539 
0540     void add(HTMLElementImpl *element, HTMLElementImpl *before, int &exceptioncode);
0541     using DOM::NodeImpl::remove;
0542     void remove(long index);
0543 
0544     DOMString value() const;
0545     void setValue(DOMStringImpl *value);
0546 
0547     bool maintainsState() override
0548     {
0549         return true;
0550     }
0551     QString state() override;
0552     void restoreState(const QString &state) override;
0553 
0554     NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode) override;
0555     void      replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode) override;
0556     void      removeChild(NodeImpl *oldChild, int &exceptioncode) override;
0557     void      removeChildren() override;
0558     NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode) override;
0559     NodeImpl *addChild(NodeImpl *newChild) override;
0560 
0561     void childrenChanged() override;
0562 
0563     void parseAttribute(AttributeImpl *attr) override;
0564 
0565     void attach() override;
0566     bool encoding(const QTextCodec *, khtml::encodingList &, bool) override;
0567 
0568     // get the actual listbox index of the optionIndexth option
0569     int optionToListIndex(int optionIndex) const;
0570     // reverse of optionToListIndex - get optionIndex from listboxIndex
0571     int listToOptionIndex(int listIndex) const;
0572 
0573     void setRecalcListItems();
0574 
0575     QVector<HTMLGenericFormElementImpl *> listItems() const
0576     {
0577         if (m_recalcListItems) {
0578             const_cast<HTMLSelectElementImpl *>(this)->recalcListItems();
0579         }
0580         return m_listItems;
0581     }
0582     void reset() override;
0583     void notifyOptionSelected(HTMLOptionElementImpl *selectedOption, bool selected);
0584 
0585 private:
0586     void recalcListItems() const;
0587     HTMLOptionElementImpl *firstSelectedItem() const;
0588 
0589 protected:
0590     mutable QVector<HTMLGenericFormElementImpl *> m_listItems;
0591     short m_minwidth;
0592     signed short m_size : 15;
0593     bool m_multiple : 1;
0594     mutable bool m_recalcListItems : 1;
0595     mutable unsigned int   m_length: 31;
0596 };
0597 
0598 // -------------------------------------------------------------------------
0599 
0600 class HTMLKeygenElementImpl : public HTMLSelectElementImpl
0601 {
0602 public:
0603     HTMLKeygenElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0604 
0605     Id id() const override;
0606 
0607     DOMString type() const;
0608 
0609     long selectedIndex() const;
0610     void setSelectedIndex(long index);
0611 
0612     // ### this is just a rough guess
0613     bool isEnumerable() const override
0614     {
0615         return false;
0616     }
0617 
0618     void parseAttribute(AttributeImpl *attr) override;
0619     bool encoding(const QTextCodec *, khtml::encodingList &, bool) override;
0620 
0621 };
0622 
0623 // -------------------------------------------------------------------------
0624 
0625 class HTMLOptGroupElementImpl : public HTMLGenericFormElementImpl
0626 {
0627 public:
0628     HTMLOptGroupElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr)
0629         : HTMLGenericFormElementImpl(doc, f) {}
0630 
0631     Id id() const override;
0632 };
0633 
0634 // ---------------------------------------------------------------------------
0635 
0636 class HTMLOptionElementImpl : public HTMLGenericFormElementImpl
0637 {
0638     friend class khtml::RenderSelect;
0639     friend class DOM::HTMLSelectElementImpl;
0640 
0641 public:
0642     HTMLOptionElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0643 
0644     Id id() const override;
0645 
0646     DOMString text() const;
0647 
0648     long index() const;
0649     void setIndex(long);
0650     void parseAttribute(AttributeImpl *attr) override;
0651     DOMString value() const;
0652     void setValue(DOMStringImpl *value);
0653 
0654     bool isDefault() const override
0655     {
0656         return m_defaultSelected;
0657     }
0658 
0659     // For internal use --- just returns the bit
0660     bool selectedBit() const
0661     {
0662         return m_selected;
0663     }
0664 
0665     // DOM use --- may recompute information of a parent <select>
0666     bool selected() const;
0667     void setSelected(bool _selected);
0668     void setDefaultSelected(bool _defaultSelected);
0669 
0670     HTMLSelectElementImpl *getSelect() const;
0671 
0672 protected:
0673     DOMString m_value;
0674     bool m_selected;
0675     bool m_defaultSelected;
0676 };
0677 
0678 // -------------------------------------------------------------------------
0679 
0680 class HTMLTextAreaElementImpl : public HTMLGenericFormElementImpl
0681 {
0682     friend class khtml::RenderTextArea;
0683 
0684 public:
0685     enum WrapMethod {
0686         ta_NoWrap,
0687         ta_Virtual,
0688         ta_Physical
0689     };
0690 
0691     HTMLTextAreaElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0692     ~HTMLTextAreaElementImpl();
0693 
0694     Id id() const override;
0695     void childrenChanged() override;
0696 
0697     long cols() const
0698     {
0699         return m_cols;
0700     }
0701 
0702     long rows() const
0703     {
0704         return m_rows;
0705     }
0706 
0707     WrapMethod wrap() const
0708     {
0709         return m_wrap;
0710     }
0711 
0712     bool isEnumerable() const override
0713     {
0714         return true;
0715     }
0716 
0717     DOMString type() const;
0718 
0719     bool maintainsState() override
0720     {
0721         return true;
0722     }
0723     QString state() override;
0724     void restoreState(const QString &state) override;
0725 
0726     void select();
0727 
0728     void parseAttribute(AttributeImpl *attr) override;
0729     void attach() override;
0730     bool encoding(const QTextCodec *, khtml::encodingList &, bool) override;
0731     void reset() override;
0732     DOMString value();
0733     void setValue(DOMString _value);
0734     DOMString defaultValue();
0735     void setDefaultValue(DOMString _defaultValue);
0736 
0737     bool isEditable() override;
0738     void setUnsubmittedFormChange(bool unsubmitted)
0739     {
0740         m_unsubmittedFormChange = unsubmitted;
0741     }
0742     bool unsubmittedFormChanges() const override
0743     {
0744         return m_unsubmittedFormChange;
0745     }
0746 
0747     //Mozilla extensions.
0748     long selectionStart();
0749     long selectionEnd();
0750     void setSelectionStart(long pos);
0751     void setSelectionEnd(long pos);
0752     void setSelectionRange(long start, long end);
0753     long textLength();
0754 
0755     // HTML5
0756     void setPlaceholder(const DOMString &p);
0757     DOMString placeholder() const;
0758 
0759 protected:
0760     int m_rows;
0761     int m_cols;
0762     WrapMethod m_wrap;
0763     QString m_value;
0764     bool m_changed: 1;    //States whether the contents has been editted
0765     bool m_unsubmittedFormChange: 1;
0766     bool m_initialized: 1;
0767 };
0768 
0769 // -------------------------------------------------------------------------
0770 
0771 class HTMLIsIndexElementImpl : public HTMLInputElementImpl
0772 {
0773 public:
0774     HTMLIsIndexElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f = nullptr);
0775     ~HTMLIsIndexElementImpl();
0776 
0777     Id id() const override;
0778     void parseAttribute(AttributeImpl *attr) override;
0779 
0780     DOMString prompt() const;
0781     void setPrompt(const DOMString &_value);
0782 };
0783 
0784 } //namespace
0785 
0786 #endif