| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# html_tableimpl.cpp

    00001
    00026 #include "html/html_documentimpl.h"
    00027 #include "html/html_tableimpl.h"
    00028
    00029 #include "dom/dom_exception.h"
    00030 #include "dom/dom_node.h"
    00031
    00032 #include "misc/htmlhashes.h"
    00033 #include "khtmlview.h"
    00034 #include "khtml_part.h"
    00035
    00036 #include "css/cssstyleselector.h"
    00037 #include "css/cssproperties.h"
    00038 #include "css/cssvalues.h"
    00039 #include "css/csshelper.h"
    00040
    00041 #include "rendering/render_table.h"
    00042
    00043 #include <kdebug.h>
    00044 #include <kglobal.h>
    00045
    00046 using namespace khtml;
    00047 using namespace DOM;
    00048
    00049 HTMLTableElementImpl::HTMLTableElementImpl(DocumentPtr *doc)
    00050   : HTMLElementImpl(doc)
    00051 {
    00052     tCaption = 0;
    00053     head = 0;
    00054     foot = 0;
    00055     firstBody = 0;
    00056
    00057 #if 0
    00058     rules = None;
    00059     frame = Void;
    00060 #endif
    00061     padding = 1;
    00062
    00063     m_noBorder = true;
    00064     m_solid = false;
    00065
    00066     // reset font color and sizes here, if we don't have strict parse mode.
    00067     // this is 90% compatible to ie and mozilla, and the by way easiest solution...
    00068     // only difference to 100% correct is that in strict mode <font> elements are propagated into tables.
    00069     if ( getDocument()->parseMode() != DocumentImpl::Strict ) {
    00070         addCSSProperty( CSS_PROP_FONT_SIZE, CSS_VAL_MEDIUM );
    00071         addCSSProperty( CSS_PROP_COLOR, "-konq-text" );
    00072         addCSSProperty( CSS_PROP_FONT_FAMILY, "konq_default" );
    00073     }
    00074 }
    00075
    00076 HTMLTableElementImpl::~HTMLTableElementImpl()
    00077 {
    00078 }
    00079
    00080 NodeImpl::Id HTMLTableElementImpl::id() const
    00081 {
    00082     return ID_TABLE;
    00083 }
    00084
    00085 NodeImpl* HTMLTableElementImpl::setCaption( HTMLTableCaptionElementImpl *c )
    00086 {
    00087     int exceptioncode = 0;
    00088     NodeImpl* r;
    00089     if(tCaption) {
    00090         replaceChild ( c, tCaption, exceptioncode );
    00091         r = c;
    00092     }
    00093     else
    00094         r = insertBefore( c, firstChild(), exceptioncode );
    00095     tCaption = c;
    00096     return r;
    00097 }
    00098
    00099 NodeImpl* HTMLTableElementImpl::setTHead( HTMLTableSectionElementImpl *s )
    00100 {
    00101     int exceptioncode = 0;
    00102     NodeImpl* r;
    00103     if(head) {
    00104         replaceChild( s, head, exceptioncode );
    00105         r = s;
    00106     }
    00107     else if( foot )
    00108         r = insertBefore( s, foot, exceptioncode );
    00109     else if( firstBody )
    00110         r = insertBefore( s, firstBody, exceptioncode );
    00111     else
    00112         r = appendChild( s, exceptioncode );
    00113
    00114     head = s;
    00115     return r;
    00116 }
    00117
    00118 NodeImpl* HTMLTableElementImpl::setTFoot( HTMLTableSectionElementImpl *s )
    00119 {
    00120     int exceptioncode = 0;
    00121     NodeImpl* r;
    00122     if(foot) {
    00123         replaceChild ( s, foot, exceptioncode );
    00124         r = s;
    00125     }
    00126     else if( firstBody )
    00127         r = insertBefore( s, firstBody, exceptioncode );
    00128     else
    00129         r = appendChild( s, exceptioncode );
    00130     foot = s;
    00131     return r;
    00132 }
    00133
    00134 NodeImpl* HTMLTableElementImpl::setTBody( HTMLTableSectionElementImpl *s )
    00135 {
    00136     int exceptioncode = 0;
    00137     NodeImpl* r;
    00138
    00139     if(!firstBody)
    00140         firstBody = s;
    00141
    00142     if( foot )
    00143         r = insertBefore( s, foot, exceptioncode );
    00144     else
    00145         r = appendChild( s, exceptioncode );
    00146
    00147     return r;
    00148 }
    00149
    00150 HTMLElementImpl *HTMLTableElementImpl::createTHead(  )
    00151 {
    00152     if(!head)
    00153     {
    00154         int exceptioncode = 0;
    00155         head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD, true /* implicit */);
    00156         if(foot)
    00157             insertBefore( head, foot, exceptioncode );
    00158         if(firstBody)
    00159             insertBefore( head, firstBody, exceptioncode);
    00160         else
    00161             appendChild(head, exceptioncode);
    00162     }
    00163     return head;
    00164 }
    00165
    00166 void HTMLTableElementImpl::deleteTHead(  )
    00167 {
    00168     if(head) {
    00169         int exceptioncode = 0;
    00170         HTMLElementImpl::removeChild(head, exceptioncode);
    00171     }
    00172     head = 0;
    00173 }
    00174
    00175 HTMLElementImpl *HTMLTableElementImpl::createTFoot(  )
    00176 {
    00177     if(!foot)
    00178     {
    00179         int exceptioncode = 0;
    00180         foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT, true /*implicit */);
    00181         if(firstBody)
    00182             insertBefore( foot, firstBody, exceptioncode );
    00183         else
    00184             appendChild(foot, exceptioncode);
    00185     }
    00186     return foot;
    00187 }
    00188
    00189 void HTMLTableElementImpl::deleteTFoot(  )
    00190 {
    00191     if(foot) {
    00192         int exceptioncode = 0;
    00193         HTMLElementImpl::removeChild(foot, exceptioncode);
    00194     }
    00195     foot = 0;
    00196 }
    00197
    00198 HTMLElementImpl *HTMLTableElementImpl::createCaption(  )
    00199 {
    00200     if(!tCaption)
    00201     {
    00202         int exceptioncode = 0;
    00203         tCaption = new HTMLTableCaptionElementImpl(docPtr());
    00204         insertBefore( tCaption, firstChild(), exceptioncode );
    00205     }
    00206     return tCaption;
    00207 }
    00208
    00209 void HTMLTableElementImpl::deleteCaption(  )
    00210 {
    00211     if(tCaption) {
    00212         int exceptioncode = 0;
    00213         HTMLElementImpl::removeChild(tCaption, exceptioncode);
    00214     }
    00215     tCaption = 0;
    00216 }
    00217
    00218 HTMLElementImpl *HTMLTableElementImpl::insertRow( long index, int &exceptioncode )
    00219 {
    00220     // The DOM requires that we create a tbody if the table is empty
    00221     // (cf DOM2TS HTMLTableElement31 test)
    00222     // (note: this is different from "if the table has no sections", since we can have
    00223     // <TABLE><TR>)
    00224     if(!firstBody && !head && !foot && !hasChildNodes())
    00225         setTBody( new HTMLTableSectionElementImpl(docPtr(), ID_TBODY, true /* implicit */) );
    00226
    00227     //kdDebug(6030) << k_funcinfo << index << endl;
    00228     // IE treats index=-1 as default value meaning 'append after last'
    00229     // This isn't in the DOM. So, not implemented yet.
    00230     HTMLTableSectionElementImpl* section = 0L;
    00231     HTMLTableSectionElementImpl* lastSection = 0L;
    00232     NodeImpl *node = firstChild();
    00233     bool append = index == -1;
    00234     for ( ; node && (index>=0 || append) ; node = node->nextSibling() )
    00235     {
    00236         if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
    00237         {
    00238             section = static_cast<HTMLTableSectionElementImpl *>(node);
    00239             lastSection = section;
    00240             //kdDebug(6030) << k_funcinfo << "section id=" << node->id() << " rows:" << section->numRows() << endl;
    00241             if ( !append )
    00242             {
    00243                 int rows = section->numRows();
    00244                 if ( rows > index )
    00245                     break;
    00246                 else
    00247                     index -= rows;
    00248                 //kdDebug(6030) << "       index is now " << index << endl;
    00249             }
    00250         }
    00251         // Note: we now can have both TR and sections (THEAD/TBODY/TFOOT) as children of a TABLE
    00252         else if ( node->id() == ID_TR )
    00253         {
    00254             section = 0L;
    00255             //kdDebug(6030) << k_funcinfo << "row" << endl;
    00256             if (!append && !index)
    00257             {
    00258                 // Insert row right here, before "node"
    00259                 HTMLTableRowElementImpl* row = new HTMLTableRowElementImpl(docPtr());
    00260                 insertBefore(row, node, exceptioncode );
    00261                 return row;
    00262             }
    00263             if ( !append )
    00264                 index--;
    00265             //kdDebug(6030) << "       index is now " << index << endl;
    00266         }
    00267         section = 0L;
    00268     }
    00269     // Index == 0 means "insert before first row in current section"
    00270     // or "append after last row" (if there's no current section anymore)
    00271     if ( !section && ( index == 0 || append ) )
    00272     {
    00273         section = lastSection;
    00274         index = section ? section->numRows() : 0;
    00275     }
    00276     if ( section && ( index >= 0 || append ) ) {
    00277         //kdDebug(6030) << "Inserting row into section " << section << " at index " << index << endl;
    00278         return section->insertRow( index, exceptioncode );
    00279     } else {
    00280         // No more sections => index is too big
    00281         exceptioncode = DOMException::INDEX_SIZE_ERR;
    00282         return 0L;
    00283     }
    00284 }
    00285
    00286 void HTMLTableElementImpl::deleteRow( long index, int &exceptioncode )
    00287 {
    00288     HTMLTableSectionElementImpl* section = 0L;
    00289     NodeImpl *node = firstChild();
    00290     bool lastRow = index == -1;
    00291     HTMLTableSectionElementImpl* lastSection = 0L;
    00292     for ( ; node ; node = node->nextSibling() )
    00293     {
    00294         if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
    00295         {
    00296             section = static_cast<HTMLTableSectionElementImpl *>(node);
    00297             lastSection = section;
    00298             int rows = section->numRows();
    00299             if ( !lastRow )
    00300             {
    00301                 if ( rows > index )
    00302                     break;
    00303                 else
    00304                     index -= rows;
    00305             }
    00306         }
    00307         section = 0L;
    00308     }
    00309     if ( lastRow )
    00310         lastSection->deleteRow( -1, exceptioncode );
    00311     else if ( section && index >= 0 && index < section->numRows() )
    00312         section->deleteRow( index, exceptioncode );
    00313     else
    00314         exceptioncode = DOMException::INDEX_SIZE_ERR;
    00315 }
    00316
    00317 NodeImpl *HTMLTableElementImpl::addChild(NodeImpl *child)
    00318 {
    00319 #ifdef DEBUG_LAYOUT
    00320     kdDebug( 6030 ) << nodeName().string() << "(Table)::addChild( " << child->nodeName().string() << " )" << endl;
    00321 #endif
    00322
    00323     switch(child->id())
    00324     {
    00325     case ID_CAPTION:
    00326         return setCaption(static_cast<HTMLTableCaptionElementImpl *>(child));
    00327         break;
    00328     case ID_COL:
    00329     case ID_COLGROUP:
    00330         if(head || foot || firstBody)
    00331             return 0;
    00332         {
    00333             int exceptioncode = 0;
    00334             return appendChild(child, exceptioncode);
    00335         }
    00336     case ID_THEAD:
    00337         return setTHead(static_cast<HTMLTableSectionElementImpl *>(child));
    00338         break;
    00339     case ID_TFOOT:
    00340         return setTFoot(static_cast<HTMLTableSectionElementImpl *>(child));
    00341         break;
    00342     case ID_TBODY:
    00343         return setTBody(static_cast<HTMLTableSectionElementImpl *>(child));
    00344         break;
    00345     }
    00346     return 0;
    00347 }
    00348
    00349 void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
    00350 {
    00351     // ### to CSS!!
    00352     switch(attr->id())
    00353     {
    00354     case ATTR_WIDTH:
    00355         if (!attr->value().isEmpty())
    00356             addCSSLength( CSS_PROP_WIDTH, attr->value() );
    00357         else
    00358             removeCSSProperty(CSS_PROP_WIDTH);
    00359         break;
    00360     case ATTR_HEIGHT:
    00361         if (!attr->value().isEmpty())
    00362             addCSSLength(CSS_PROP_HEIGHT, attr->value());
    00363         else
    00364             removeCSSProperty(CSS_PROP_HEIGHT);
    00365         break;
    00366     case ATTR_BORDER:
    00367     {
    00368         int border;
    00369         // ### this needs more work, as the border value is not only
    00370         //     the border of the box, but also between the cells
    00371         if(!attr->val())
    00372             border = 0;
    00373         else if(attr->val()->l == 0)
    00374             border = 1;
    00375         else
    00376             border = attr->val()->toInt();
    00377 #ifdef DEBUG_DRAW_BORDER
    00378         border=1;
    00379 #endif
    00380         m_noBorder = !border;
    00381         DOMString v = QString::number( border );
    00382         addCSSLength(CSS_PROP_BORDER_WIDTH, v );
    00383 #if 0
    00384         // wanted by HTML4 specs
    00385         if(!border)
    00386             frame = Void, rules = None;
    00387         else
    00388             frame = Box, rules = All;
    00389 #endif
    00390         break;
    00391     }
    00392     case ATTR_BGCOLOR:
    00393         if (!attr->value().isEmpty())
    00394             addCSSProperty(CSS_PROP_BACKGROUND_COLOR, attr->value());
    00395         else
    00396             removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
    00397         break;
    00398     case ATTR_BORDERCOLOR:
    00399         if(!attr->value().isEmpty()) {
    00400             addCSSProperty(CSS_PROP_BORDER_COLOR, attr->value());
    00401             addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
    00402             addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
    00403             addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
    00404             addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
    00405             m_solid = true;
    00406         }
    00407         break;
    00408     case ATTR_BACKGROUND:
    00409     {
    00410         if (!attr->value().isEmpty()) {
    00411             QString url = khtml::parseURL( attr->value() ).string();
    00412             url = getDocument()->completeURL( url );
    00413             addCSSProperty(CSS_PROP_BACKGROUND_IMAGE, "url('"+url+"')" );
    00414         }
    00415         else
    00416             removeCSSProperty(CSS_PROP_BACKGROUND_IMAGE);
    00417         break;
    00418     }
    00419     case ATTR_FRAME:
    00420 #if 0
    00421         if ( strcasecmp( attr->value(), "void" ) == 0 )
    00422             frame = Void;
    00423         else if ( strcasecmp( attr->value(), "border" ) == 0 )
    00424             frame = Box;
    00425         else if ( strcasecmp( attr->value(), "box" ) == 0 )
    00426             frame = Box;
    00427         else if ( strcasecmp( attr->value(), "hsides" ) == 0 )
    00428             frame = Hsides;
    00429         else if ( strcasecmp( attr->value(), "vsides" ) == 0 )
    00430             frame = Vsides;
    00431         else if ( strcasecmp( attr->value(), "above" ) == 0 )
    00432             frame = Above;
    00433         else if ( strcasecmp( attr->value(), "below" ) == 0 )
    00434             frame = Below;
    00435         else if ( strcasecmp( attr->value(), "lhs" ) == 0 )
    00436             frame = Lhs;
    00437         else if ( strcasecmp( attr->value(), "rhs" ) == 0 )
    00438             frame = Rhs;
    00439 #endif
    00440         break;
    00441     case ATTR_RULES:
    00442 #if 0
    00443         if ( strcasecmp( attr->value(), "none" ) == 0 )
    00444             rules = None;
    00445         else if ( strcasecmp( attr->value(), "groups" ) == 0 )
    00446             rules = Groups;
    00447         else if ( strcasecmp( attr->value(), "rows" ) == 0 )
    00448             rules = Rows;
    00449         else if ( strcasecmp( attr->value(), "cols" ) == 0 )
    00450             rules = Cols;
    00451         else if ( strcasecmp( attr->value(), "all" ) == 0 )
    00452             rules = All;
    00453 #endif
    00454         break;
    00455    case ATTR_CELLSPACING:
    00456         if (!attr->value().isEmpty())
    00457             addCSSLength(CSS_PROP_BORDER_SPACING, attr->value(), true);
    00458         else
    00459             removeCSSProperty(CSS_PROP_BORDER_SPACING);
    00460         break;
    00461     case ATTR_CELLPADDING:
    00462         if (!attr->value().isEmpty()) {
    00463             addCSSLength(CSS_PROP_PADDING_TOP, attr->value(), true);
    00464             addCSSLength(CSS_PROP_PADDING_LEFT, attr->value(), true);
    00465             addCSSLength(CSS_PROP_PADDING_BOTTOM, attr->value(), true);
    00466             addCSSLength(CSS_PROP_PADDING_RIGHT, attr->value(), true);
    00467             padding = kMax( 0, attr->value().toInt() );
    00468         }
    00469         else {
    00470             removeCSSProperty(CSS_PROP_PADDING_TOP);
    00471             removeCSSProperty(CSS_PROP_PADDING_LEFT);
    00472             removeCSSProperty(CSS_PROP_PADDING_BOTTOM);
    00473             removeCSSProperty(CSS_PROP_PADDING_RIGHT);
    00474             padding = 1;
    00475         }
    00476         break;
    00477     case ATTR_COLS:
    00478     {
    00479         // ###
    00480 #if 0
    00481         int c;
    00482         c = attr->val()->toInt();
    00483         addColumns(c-totalCols);
    00484         break;
    00485 #endif
    00486     }
    00487     case ATTR_ALIGN:
    00488         if (!attr->value().isEmpty())
    00489             addCSSProperty(CSS_PROP_FLOAT, attr->value());
    00490         else
    00491             removeCSSProperty(CSS_PROP_FLOAT);
    00492         break;
    00493     case ATTR_VALIGN:
    00494         if (!attr->value().isEmpty())
    00495             addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value());
    00496         else
    00497             removeCSSProperty(CSS_PROP_VERTICAL_ALIGN);
    00498         break;
    00499     case ATTR_NOSAVE:
    00500         break;
    00501     default:
    00502         HTMLElementImpl::parseAttribute(attr);
    00503     }
    00504 }
    00505
    00506 void HTMLTableElementImpl::attach()
    00507 {
    00508     if (!m_noBorder) {
    00509         int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
    00510         addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
    00511         addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
    00512         addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
    00513         addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
    00514     }
    00515
    00516     HTMLElementImpl::attach();
    00517     if ( m_render && m_render->isTable() )
    00518         static_cast<RenderTable *>(m_render)->setCellPadding( padding );
    00519 }
    00520
    00521 // --------------------------------------------------------------------------
    00522
    00523 void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr)
    00524 {
    00525     switch(attr->id())
    00526     {
    00527     case ATTR_BGCOLOR:
    00528         if (attr->val())
    00529             addCSSProperty(CSS_PROP_BACKGROUND_COLOR, attr->value() );
    00530         else
    00531             removeCSSProperty(CSS_PROP_BACKGROUND_COLOR);
    00532         break;
    00533     case ATTR_BACKGROUND:
    00534     {
    00535         if (attr->val()) {
    00536             QString url = khtml::parseURL( attr->value() ).string();
    00537             url = getDocument()->completeURL( url );
    00538             addCSSProperty(CSS_PROP_BACKGROUND_IMAGE,  "url('"+url+"')" );
    00539         }
    00540         else
    00541             removeCSSProperty(CSS_PROP_BACKGROUND_IMAGE);
    00542         break;
    00543     }
    00544     case ATTR_BORDERCOLOR:
    00545     {
    00546         if(!attr->value().isEmpty()) {
    00547             addCSSProperty(CSS_PROP_BORDER_COLOR, attr->value());
    00548             addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
    00549             addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
    00550             addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
    00551             addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
    00552             m_solid = true;
    00553         }
    00554         break;
    00555     }
    00556     case ATTR_VALIGN:
    00557     {
    00558         if (!attr->value().isEmpty())
    00559             addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value());
    00560         else
    00561             removeCSSProperty(CSS_PROP_VERTICAL_ALIGN);
    00562         break;
    00563     }
    00564     case ATTR_HEIGHT:
    00565         if (!attr->value().isEmpty())
    00566             addCSSLength(CSS_PROP_HEIGHT, attr->value());
    00567         else
    00568             removeCSSProperty(CSS_PROP_HEIGHT);
    00569         break;
    00570     case ATTR_NOSAVE:
    00571         break;
    00572     default:
    00573         HTMLElementImpl::parseAttribute(attr);
    00574     }
    00575 }
    00576
    00577 // -------------------------------------------------------------------------
    00578
    00579 HTMLTableSectionElementImpl::HTMLTableSectionElementImpl(DocumentPtr *doc,
    00580                                                          ushort tagid, bool implicit)
    00581     : HTMLTablePartElementImpl(doc)
    00582 {
    00583     _id = tagid;
    00584     m_implicit = implicit;
    00585 }
    00586
    00587 HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl()
    00588 {
    00589 }
    00590
    00591 NodeImpl::Id HTMLTableSectionElementImpl::id() const
    00592 {
    00593     return _id;
    00594 }
    00595
    00596
    00597 // these functions are rather slow, since we need to get the row at
    00598 // the index... but they aren't used during usual HTML parsing anyway
    00599 HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index, int& exceptioncode )
    00600 {
    00601     HTMLTableRowElementImpl *r = 0L;
    00602     NodeListImpl *children = childNodes();
    00603     int numRows = children ? (int)children->length() : 0;
    00604     //kdDebug(6030) << k_funcinfo << "index=" << index << " numRows=" << numRows << endl;
    00605     if ( index < -1 || index > numRows ) {
    00606         exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
    00607     }
    00608     else
    00609     {
    00610         r = new HTMLTableRowElementImpl(docPtr());
    00611         if ( numRows == index || index == -1 )
    00612             appendChild(r, exceptioncode);
    00613         else {
    00614             NodeImpl *n;
    00615             if(index < 1)
    00616                 n = firstChild();
    00617             else
    00618                 n = children->item(index);
    00619             insertBefore(r, n, exceptioncode );
    00620         }
    00621     }
    00622     delete children;
    00623     return r;
    00624 }
    00625
    00626 void HTMLTableSectionElementImpl::deleteRow( long index, int &exceptioncode )
    00627 {
    00628     NodeListImpl *children = childNodes();
    00629     int numRows = children ? (int)children->length() : 0;
    00630     if ( index == -1 ) index = numRows - 1;
    00631     if( index >= 0 && index < numRows )
    00632         HTMLElementImpl::removeChild(children->item(index), exceptioncode);
    00633     else
    00634         exceptioncode = DOMException::INDEX_SIZE_ERR;
    00635     delete children;
    00636 }
    00637
    00638
    00639 int HTMLTableSectionElementImpl::numRows() const
    00640 {
    00641     int rows = 0;
    00642     const NodeImpl *n = firstChild();
    00643     while (n) {
    00644         if (n->id() == ID_TR)
    00645             rows++;
    00646         n = n->nextSibling();
    00647     }
    00648
    00649     return rows;
    00650 }
    00651
    00652 // -------------------------------------------------------------------------
    00653
    00654 HTMLTableRowElementImpl::HTMLTableRowElementImpl(DocumentPtr *doc)
    00655   : HTMLTablePartElementImpl(doc)
    00656 {
    00657 }
    00658
    00659 HTMLTableRowElementImpl::~HTMLTableRowElementImpl()
    00660 {
    00661 }
    00662
    00663 NodeImpl::Id HTMLTableRowElementImpl::id() const
    00664 {
    00665     return ID_TR;
    00666 }
    00667
    00668 long HTMLTableRowElementImpl::rowIndex() const
    00669 {
    00670     // some complex traversal stuff here to take into account that some rows may be in different sections
    00671     int rIndex = 0;
    00672     const NodeImpl *n = this;
    00673     do {
    00674         while (!n->previousSibling() && !(n->isElementNode() && n->id() == ID_TABLE))
    00675             n = n->parentNode();
    00676         if (n->isElementNode() && n->id() == ID_TABLE)
    00677             n = 0;
    00678         if (n) {
    00679             n = n->previousSibling();
    00680             while (!(n->isElementNode() && n->id() == ID_TR) && n->lastChild())
    00681                 n = n->lastChild();
    00682         }
    00683
    00684         if (n && n->isElementNode() && n->id() == ID_TR)
    00685             rIndex++;
    00686     }
    00687     while (n && n->isElementNode() && n->id() == ID_TR);
    00688
    00689     return rIndex;
    00690 }
    00691
    00692 long HTMLTableRowElementImpl::sectionRowIndex() const
    00693 {
    00694     int rIndex = 0;
    00695     const NodeImpl *n = this;
    00696     do {
    00697         n = n->previousSibling();
    00698         if (n && n->isElementNode() && n->id() == ID_TR)
    00699             rIndex++;
    00700     }
    00701     while (n);
    00702
    00703     return rIndex;
    00704 }
    00705
    00706 HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index, int &exceptioncode )
    00707 {
    00708     HTMLTableCellElementImpl *c = 0L;
    00709     NodeListImpl *children = childNodes();
    00710     int numCells = children ? children->length() : 0;
    00711     if ( index < -1 || index > numCells )
    00712         exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
    00713     else
    00714     {
    00715         c = new HTMLTableCellElementImpl(docPtr(), ID_TD);
    00716         if(numCells == index || index == -1)
    00717             appendChild(c, exceptioncode);
    00718         else {
    00719             NodeImpl *n;
    00720             if(index < 1)
    00721                 n = firstChild();
    00722             else
    00723                 n = children->item(index);
    00724             insertBefore(c, n, exceptioncode);
    00725         }
    00726     }
    00727     delete children;
    00728     return c;
    00729 }
    00730
    00731 void HTMLTableRowElementImpl::deleteCell( long index, int &exceptioncode )
    00732 {
    00733     NodeListImpl *children = childNodes();
    00734     int numCells = children ? children->length() : 0;
    00735     if ( index == -1 ) index = numCells-1;
    00736     if( index >= 0 && index < numCells )
    00737         HTMLElementImpl::removeChild(children->item(index), exceptioncode);
    00738     else
    00739         exceptioncode = DOMException::INDEX_SIZE_ERR;
    00740     delete children;
    00741 }
    00742
    00743 // -------------------------------------------------------------------------
    00744
    00745 HTMLTableCellElementImpl::HTMLTableCellElementImpl(DocumentPtr *doc, int tag)
    00746   : HTMLTablePartElementImpl(doc)
    00747 {
    00748   _col = -1;
    00749   _row = -1;
    00750   cSpan = rSpan = 1;
    00751   m_nowrap = false;
    00752   _id = tag;
    00753   rowHeight = 0;
    00754 }
    00755
    00756 HTMLTableCellElementImpl::~HTMLTableCellElementImpl()
    00757 {
    00758 }
    00759
    00760 void HTMLTableCellElementImpl::parseAttribute(AttributeImpl *attr)
    00761 {
    00762     switch(attr->id())
    00763     {
    00764     case ATTR_BORDER:
    00765         // euhm? not supported by other browsers as far as I can see (Dirk)
    00766         //addCSSLength(CSS_PROP_BORDER_WIDTH, attr->value());
    00767         break;
    00768     case ATTR_ROWSPAN:
    00769         // ###
    00770         rSpan = attr->val() ? attr->val()->toInt() : 1;
    00771         // limit this to something not causing an overflow with short int
    00772         if(rSpan < 1 || rSpan > 1024) rSpan = 1;
    00773         break;
    00774     case ATTR_COLSPAN:
    00775         // ###
    00776         cSpan = attr->val() ? attr->val()->toInt() : 1;
    00777         // limit this to something not causing an overflow with short int
    00778         if(cSpan < 1 || cSpan > 1024) cSpan = 1;
    00779         break;
    00780     case ATTR_NOWRAP:
    00781         m_nowrap = (attr->val() != 0);
    00782         break;
    00783     case ATTR_WIDTH:
    00784         if (!attr->value().isEmpty())
    00785             addCSSLength( CSS_PROP_WIDTH, attr->value() );
    00786         else
    00787             removeCSSProperty(CSS_PROP_WIDTH);
    00788         break;
    00789     case ATTR_NOSAVE:
    00790         break;
    00791     default:
    00792         HTMLTablePartElementImpl::parseAttribute(attr);
    00793     }
    00794 }
    00795
    00796 void HTMLTableCellElementImpl::attach()
    00797 {
    00798     HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parentNode());
    00799     while(p && p->id() != ID_TABLE)
    00800         p = static_cast<HTMLElementImpl*>(p->parentNode());
    00801
    00802     if(p) {
    00803         HTMLTableElementImpl* table = static_cast<HTMLTableElementImpl*>(p);
    00804         if (table->m_noBorder) {
    00805             addCSSProperty(CSS_PROP_BORDER_WIDTH, "0");
    00806         }
    00807         else {
    00808             addCSSProperty(CSS_PROP_BORDER_WIDTH, "1px");
    00809             int v = (table->m_solid || m_solid) ? CSS_VAL_SOLID : CSS_VAL_INSET;
    00810             addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
    00811             addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
    00812             addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
    00813             addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
    00814
    00815             if (!m_solid)
    00816                 addCSSProperty(CSS_PROP_BORDER_COLOR, "inherit");
    00817         }
    00818     }
    00819
    00820     HTMLTablePartElementImpl::attach();
    00821 }
    00822
    00823 // -------------------------------------------------------------------------
    00824
    00825 HTMLTableColElementImpl::HTMLTableColElementImpl(DocumentPtr *doc, ushort i)
    00826     : HTMLTablePartElementImpl(doc)
    00827 {
    00828     _id = i;
    00829     _span = (_id == ID_COLGROUP ? 0 : 1);
    00830 }
    00831
    00832 HTMLTableColElementImpl::~HTMLTableColElementImpl()
    00833 {
    00834 }
    00835
    00836 NodeImpl::Id HTMLTableColElementImpl::id() const
    00837 {
    00838     return _id;
    00839 }
    00840
    00841
    00842 void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr)
    00843 {
    00844     switch(attr->id())
    00845     {
    00846     case ATTR_SPAN:
    00847         _span = attr->val() ? attr->val()->toInt() : 1;
    00848         break;
    00849     case ATTR_WIDTH:
    00850         if (!attr->value().isEmpty())
    00851             addCSSLength(CSS_PROP_WIDTH, attr->value(), false, true );
    00852         else
    00853             removeCSSProperty(CSS_PROP_WIDTH);
    00854         break;
    00855     case ATTR_VALIGN:
    00856         if (!attr->value().isEmpty())
    00857             addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value());
    00858         else
    00859             removeCSSProperty(CSS_PROP_VERTICAL_ALIGN);
    00860         break;
    00861     default:
    00862         HTMLTablePartElementImpl::parseAttribute(attr);
    00863     }
    00864
    00865 }
    00866
    00867 // -------------------------------------------------------------------------
    00868
    00869 HTMLTableCaptionElementImpl::HTMLTableCaptionElementImpl(DocumentPtr *doc)
    00870   : HTMLTablePartElementImpl(doc)
    00871 {
    00872 }
    00873
    00874 HTMLTableCaptionElementImpl::~HTMLTableCaptionElementImpl()
    00875 {
    00876 }
    00877
    00878 NodeImpl::Id HTMLTableCaptionElementImpl::id() const
    00879 {
    00880     return ID_CAPTION;
    00881 }
    00882
    00883
    00884 void HTMLTableCaptionElementImpl::parseAttribute(AttributeImpl *attr)
    00885 {
    00886     switch(attr->id())
    00887     {
    00888     case ATTR_ALIGN:
    00889         if (!attr->value().isEmpty())
    00890             addCSSProperty(CSS_PROP_CAPTION_SIDE, attr->value());
    00891         else
    00892             removeCSSProperty(CSS_PROP_CAPTION_SIDE);
    00893         break;
    00894     default:
    00895         HTMLElementImpl::parseAttribute(attr);
    00896     }
    00897
    00898 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:59 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001