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
00067
00068
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 );
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 );
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
00221
00222
00223
00224 if(!firstBody && !head && !foot && !hasChildNodes())
00225 setTBody( new HTMLTableSectionElementImpl(docPtr(), ID_TBODY, true ) );
00226
00227
00228
00229
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
00241 if ( !append )
00242 {
00243 int rows = section->numRows();
00244 if ( rows > index )
00245 break;
00246 else
00247 index -= rows;
00248
00249 }
00250 }
00251
00252 else if ( node->id() == ID_TR )
00253 {
00254 section = 0L;
00255
00256 if (!append && !index)
00257 {
00258
00259 HTMLTableRowElementImpl* row = new HTMLTableRowElementImpl(docPtr());
00260 insertBefore(row, node, exceptioncode );
00261 return row;
00262 }
00263 if ( !append )
00264 index--;
00265
00266 }
00267 section = 0L;
00268 }
00269
00270
00271 if ( !section && ( index == 0 || append ) )
00272 {
00273 section = lastSection;
00274 index = section ? section->numRows() : 0;
00275 }
00276 if ( section && ( index >= 0 || append ) ) {
00277
00278 return section->insertRow( index, exceptioncode );
00279 } else {
00280
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
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
00370
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
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
00598
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
00605 if ( index < -1 || index > numRows ) {
00606 exceptioncode = DOMException::INDEX_SIZE_ERR;
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
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;
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
00766
00767 break;
00768 case ATTR_ROWSPAN:
00769
00770 rSpan = attr->val() ? attr->val()->toInt() : 1;
00771
00772 if(rSpan < 1 || rSpan > 1024) rSpan = 1;
00773 break;
00774 case ATTR_COLSPAN:
00775
00776 cSpan = attr->val() ? attr->val()->toInt() : 1;
00777
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 }