File indexing completed on 2024-05-05 16:10:15

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
0005  *           (C) 1997 Torben Weis (weis@kde.org)
0006  *           (C) 1998 Waldo Bastian (bastian@kde.org)
0007  *           (C) 1999 Lars Knoll (knoll@kde.org)
0008  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0009  *           (C) 2006 Maksim Orlovich (maksim@kde.org)
0010  *
0011  * This library is free software; you can redistribute it and/or
0012  * modify it under the terms of the GNU Library General Public
0013  * License as published by the Free Software Foundation; either
0014  * version 2 of the License, or (at your option) any later version.
0015  *
0016  * This library is distributed in the hope that it will be useful,
0017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019  * Library General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU Library General Public License
0022  * along with this library; see the file COPYING.LIB.  If not, write to
0023  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0024  * Boston, MA 02110-1301, USA.
0025  *
0026  */
0027 #ifndef HTML_TABLEIMPL_H
0028 #define HTML_TABLEIMPL_H
0029 
0030 #include "html/html_elementimpl.h"
0031 
0032 namespace DOM
0033 {
0034 
0035 class HTMLTableElementImpl;
0036 class HTMLTableSectionElementImpl;
0037 class HTMLTableSectionElement;
0038 class HTMLTableRowElementImpl;
0039 class HTMLTableRowElement;
0040 class HTMLTableCellElementImpl;
0041 class HTMLTableCellElement;
0042 class HTMLTableColElementImpl;
0043 class HTMLTableColElement;
0044 class HTMLTableCaptionElementImpl;
0045 class HTMLTableCaptionElement;
0046 class HTMLElement;
0047 
0048 // -------------------------------------------------------------------------
0049 
0050 class HTMLTablePartElementImpl : public HTMLElementImpl
0051 
0052 {
0053 public:
0054     HTMLTablePartElementImpl(DocumentImpl *doc)
0055         : HTMLElementImpl(doc)
0056     { }
0057 
0058     void parseAttribute(AttributeImpl *attr) override;
0059 };
0060 
0061 // -------------------------------------------------------------------------
0062 
0063 class HTMLTableSectionElementImpl : public HTMLTablePartElementImpl
0064 {
0065 public:
0066     HTMLTableSectionElementImpl(DocumentImpl *doc, ushort tagid, bool implicit);
0067 
0068     ~HTMLTableSectionElementImpl();
0069 
0070     Id id() const override;
0071 
0072     HTMLElementImpl *insertRow(long index, int &exceptioncode);
0073     void deleteRow(long index, int &exceptioncode);
0074 
0075     int numRows() const;
0076 
0077 protected:
0078     ushort _id;
0079 };
0080 
0081 // -------------------------------------------------------------------------
0082 
0083 class HTMLTableRowElementImpl : public HTMLTablePartElementImpl
0084 {
0085 public:
0086     HTMLTableRowElementImpl(DocumentImpl *doc)
0087         : HTMLTablePartElementImpl(doc) {}
0088 
0089     Id id() const override;
0090 
0091     long rowIndex() const;
0092     long sectionRowIndex() const;
0093 
0094     HTMLElementImpl *insertCell(long index, int &exceptioncode);
0095     void deleteCell(long index, int &exceptioncode);
0096 
0097 protected:
0098     int ncols;
0099 };
0100 
0101 // -------------------------------------------------------------------------
0102 
0103 class HTMLTableCellElementImpl : public HTMLTablePartElementImpl
0104 {
0105 public:
0106     HTMLTableCellElementImpl(DocumentImpl *doc, int tagId);
0107     ~HTMLTableCellElementImpl();
0108 
0109     long cellIndex() const;
0110 
0111     int col() const
0112     {
0113         return _col;
0114     }
0115     void setCol(int col)
0116     {
0117         _col = col;
0118     }
0119     int row() const
0120     {
0121         return _row;
0122     }
0123     void setRow(int r)
0124     {
0125         _row = r;
0126     }
0127 
0128     int colSpan() const
0129     {
0130         return cSpan;
0131     }
0132     int rowSpan() const
0133     {
0134         return rSpan;
0135     }
0136 
0137     Id id() const override
0138     {
0139         return _id;
0140     }
0141     void parseAttribute(AttributeImpl *attr) override;
0142     void attach() override;
0143 
0144 protected:
0145     int _row;
0146     int _col;
0147     int rSpan;
0148     int cSpan;
0149     int _id;
0150     int rowHeight;
0151     bool m_solid        : 1;
0152     bool m_nowrap : 1;
0153 };
0154 
0155 // -------------------------------------------------------------------------
0156 
0157 class HTMLTableColElementImpl : public HTMLTablePartElementImpl
0158 {
0159 public:
0160     HTMLTableColElementImpl(DocumentImpl *doc, ushort i);
0161 
0162     Id id() const override;
0163 
0164     void setTable(HTMLTableElementImpl *t)
0165     {
0166         table = t;
0167     }
0168 
0169     // overrides
0170     void parseAttribute(AttributeImpl *attr) override;
0171 
0172     int span() const
0173     {
0174         return _span;
0175     }
0176 
0177 protected:
0178     // could be ID_COL or ID_COLGROUP ... The DOM is not quite clear on
0179     // this, but since both elements work quite similar, we use one
0180     // DOMElement for them...
0181     ushort _id;
0182     int _span;
0183     HTMLTableElementImpl *table;
0184 };
0185 
0186 // -------------------------------------------------------------------------
0187 
0188 class HTMLTableCaptionElementImpl : public HTMLTablePartElementImpl
0189 {
0190 public:
0191     HTMLTableCaptionElementImpl(DocumentImpl *doc)
0192         : HTMLTablePartElementImpl(doc) {}
0193 
0194     Id id() const override;
0195     void parseAttribute(AttributeImpl *attr) override;
0196 };
0197 
0198 // -------------------------------------------------------------------------
0199 
0200 /*
0201 This class helps memorize pointers to child objects that may be
0202 yanked around via the DOM. It always picks the first pointer of the
0203 given type.
0204 
0205 The pointer it stores can have 3 meanings:
0206 0      -- no child
0207 parent -- no idea about the state
0208 other  -- pointer to the child
0209 */
0210 template<typename ChildType, int ChildId> class ChildHolder
0211 {
0212 public:
0213     ChildHolder(): ptr(nullptr) {}
0214 
0215     ChildType *get(const ElementImpl *parent) const
0216     {
0217         if (static_cast<const NodeImpl *>(ptr) == parent) {
0218             //Do lookup.
0219             ptr = nullptr;
0220             for (NodeImpl *child = parent->firstChild(); child; child = child->nextSibling())
0221                 if (child->id() == ChildId) {
0222                     ptr = static_cast<ElementImpl *>(child);
0223                     break;
0224                 }
0225         }
0226         return static_cast<ChildType *>(ptr);
0227     }
0228 
0229     void childAdded(ElementImpl *parent, NodeImpl *child)
0230     {
0231         if (ptr) {
0232             ptr = parent;    //No clue now..
0233         } else {
0234             ptr = child;
0235         }
0236     }
0237 
0238     void childAppended(NodeImpl *child)
0239     {
0240         if (!ptr) {
0241             ptr = child;
0242         }
0243     }
0244 
0245     void childRemoved(ElementImpl *parent, NodeImpl *child)
0246     {
0247         if (child == ptr) {
0248             ptr = parent;    //We removed what was pointing - no clue now..
0249         }
0250         //else things are unchanged.
0251     }
0252 
0253     void clear()
0254     {
0255         ptr = nullptr;
0256     }
0257 
0258     void operator =(ChildType *child)
0259     {
0260         ptr = child;
0261     }
0262 private:
0263     mutable NodeImpl *ptr;
0264 };
0265 
0266 // -------------------------------------------------------------------------
0267 class HTMLTableElementImpl : public HTMLElementImpl
0268 {
0269 public:
0270     enum Rules {
0271         None    = 0x00,
0272         RGroups = 0x01,
0273         CGroups = 0x02,
0274         Groups  = 0x03,
0275         Rows    = 0x05,
0276         Cols    = 0x0a,
0277         All     = 0x0f
0278     };
0279     enum Frame {
0280         Void   = 0x00,
0281         Above  = 0x01,
0282         Below  = 0x02,
0283         Lhs    = 0x04,
0284         Rhs    = 0x08,
0285         Hsides = 0x03,
0286         Vsides = 0x0c,
0287         Box    = 0x0f
0288     };
0289 
0290     HTMLTableElementImpl(DocumentImpl *doc);
0291     ~HTMLTableElementImpl();
0292 
0293     Id id() const override;
0294 
0295     HTMLTableCaptionElementImpl *caption() const
0296     {
0297         return tCaption.get(this);
0298     }
0299     NodeImpl *setCaption(HTMLTableCaptionElementImpl *);
0300 
0301     HTMLTableSectionElementImpl *tHead() const
0302     {
0303         return head.get(this);
0304     }
0305     NodeImpl *setTHead(HTMLTableSectionElementImpl *);
0306 
0307     HTMLTableSectionElementImpl *tFoot() const
0308     {
0309         return foot.get(this);
0310     }
0311     NodeImpl *setTFoot(HTMLTableSectionElementImpl *);
0312 
0313     NodeImpl *setTBody(HTMLTableSectionElementImpl *);
0314 
0315     HTMLElementImpl *createTHead();
0316     void deleteTHead();
0317     HTMLElementImpl *createTFoot();
0318     void deleteTFoot();
0319     HTMLElementImpl *createCaption();
0320     void deleteCaption();
0321     HTMLElementImpl *insertRow(long index, int &exceptioncode);
0322     void deleteRow(long index, int &exceptioncode);
0323 
0324     // overrides
0325     NodeImpl *addChild(NodeImpl *child) override;
0326     NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode) override;
0327     void      replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode) override;
0328     void      removeChild(NodeImpl *oldChild, int &exceptioncode) override;
0329     void      removeChildren() override;
0330     NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode) override;
0331 
0332     void parseAttribute(AttributeImpl *attr) override;
0333     void attach() override;
0334     void close() override;
0335 
0336     /* Tries to find the section containing row number outIndex.
0337        Returns whether it succeeded or not. negative outIndex values
0338        are interpreted as being infinite.
0339 
0340        On success, outSection, outIndex points to section, and index in that
0341        section.
0342 
0343        On failure, outSection points to the last section of the table, and
0344        index is the offset the row would have if there was an additional section.
0345     */
0346     bool findRowSection(long inIndex,
0347                         HTMLTableSectionElementImpl *&outSection,
0348                         long                         &outIndex) const;
0349 protected:
0350     //Actual implementations of keeping things in place.
0351     void handleChildAdd(NodeImpl *newChild);
0352     void handleChildAppend(NodeImpl *newChild);
0353     void handleChildRemove(NodeImpl *oldChild);
0354 
0355     void updateFrame();
0356 
0357     ChildHolder<HTMLTableSectionElementImpl, ID_THEAD> head;
0358     ChildHolder<HTMLTableSectionElementImpl, ID_TFOOT> foot;
0359     ChildHolder<HTMLTableSectionElementImpl, ID_TBODY> firstBody;
0360     ChildHolder<HTMLTableCaptionElementImpl, ID_CAPTION> tCaption;
0361 
0362     HTMLTableSectionElementImpl *tFirstBody() const
0363     {
0364         return firstBody.get(this);
0365     }
0366 
0367     KDE_BF_ENUM(Frame) frame : 4;
0368     KDE_BF_ENUM(Rules) rules : 4;
0369 
0370     bool m_solid        : 1;
0371     uint unused     : 7;
0372     ushort padding  : 16;
0373     friend class HTMLTableCellElementImpl;
0374 };
0375 
0376 } //namespace
0377 
0378 #endif
0379