Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: third_party/WebKit/Source/core/layout/TableLayoutAlgorithmAuto.cpp

Issue 1361693002: Fix behaviour of empty cells in tables with colspans (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1302-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
3 * (C) 2002 Dirk Mueller (mueller@kde.org) 3 * (C) 2002 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License. 9 * version 2 of the License.
10 * 10 *
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 for (unsigned i = 0; i < numRows; i++) { 60 for (unsigned i = 0; i < numRows; i++) {
61 LayoutTableSection::CellStruct current = section->cellAt(i, effC ol); 61 LayoutTableSection::CellStruct current = section->cellAt(i, effC ol);
62 LayoutTableCell* cell = current.primaryCell(); 62 LayoutTableCell* cell = current.primaryCell();
63 63
64 if (current.inColSpan || !cell) 64 if (current.inColSpan || !cell)
65 continue; 65 continue;
66 columnLayout.columnHasNoCells = false; 66 columnLayout.columnHasNoCells = false;
67 67
68 if (cell->maxPreferredLogicalWidth()) 68 if (cell->maxPreferredLogicalWidth())
69 columnLayout.emptyCellsOnly = false; 69 columnLayout.emptyCellsOnly = false;
70 if (cell->colSpan() == 1) {
70 71
71 if (cell->colSpan() == 1) {
72 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer redLogicalWidth(), columnLayout.minLogicalWidth); 72 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer redLogicalWidth(), columnLayout.minLogicalWidth);
73 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic alWidth) { 73 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic alWidth) {
74 columnLayout.maxLogicalWidth = cell->maxPreferredLogical Width(); 74 columnLayout.maxLogicalWidth = cell->maxPreferredLogical Width();
75 maxContributor = cell; 75 maxContributor = cell;
76 } 76 }
77 77
78 // All browsers implement a size limit on the cell's max wid th. 78 // All browsers implement a size limit on the cell's max wid th.
79 // Our limit is based on KHTML's representation that used 16 bits widths. 79 // Our limit is based on KHTML's representation that used 16 bits widths.
80 // FIXME: Other browsers have a lower limit for the cell's m ax width. 80 // FIXME: Other browsers have a lower limit for the cell's m ax width.
81 const int cCellMaxWidth = 32760; 81 const int cCellMaxWidth = 32760;
(...skipping 26 matching lines...) Expand all
108 case Percent: 108 case Percent:
109 m_hasPercent = true; 109 m_hasPercent = true;
110 // TODO(alancutter): Make this work correctly for calc l engths. 110 // TODO(alancutter): Make this work correctly for calc l engths.
111 if (cellLogicalWidth.isPositive() && (!columnLayout.logi calWidth.hasPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.va lue())) 111 if (cellLogicalWidth.isPositive() && (!columnLayout.logi calWidth.hasPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.va lue()))
112 columnLayout.logicalWidth = cellLogicalWidth; 112 columnLayout.logicalWidth = cellLogicalWidth;
113 break; 113 break;
114 default: 114 default:
115 break; 115 break;
116 } 116 }
117 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != c ell) { 117 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != c ell) {
118 // If a cell originates in this spanning column ensure we ha ve a min/max width of at least 1px for it.
119 columnLayout.minLogicalWidth = std::max<int>(columnLayout.mi nLogicalWidth, cell->maxPreferredLogicalWidth() ? 1 : 0);
120
121 // This spanning cell originates in this column. Insert the cell into spanning cells list. 118 // This spanning cell originates in this column. Insert the cell into spanning cells list.
122 insertSpanCell(cell); 119 insertSpanCell(cell);
123 } 120 }
124 } 121 }
125 } 122 }
126 } 123 }
127 124
128 // Nav/IE weirdness 125 // Nav/IE weirdness
129 if (columnLayout.logicalWidth.isFixed()) { 126 if (columnLayout.logicalWidth.isFixed()) {
130 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { 127 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRo wDirection; 302 int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRo wDirection;
306 int cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRo wDirection; 303 int cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRo wDirection;
307 float totalPercent = 0; 304 float totalPercent = 0;
308 int spanMinLogicalWidth = 0; 305 int spanMinLogicalWidth = 0;
309 int spanMaxLogicalWidth = 0; 306 int spanMaxLogicalWidth = 0;
310 bool allColsArePercent = true; 307 bool allColsArePercent = true;
311 bool allColsAreFixed = true; 308 bool allColsAreFixed = true;
312 bool haveAuto = false; 309 bool haveAuto = false;
313 bool spanHasEmptyCellsOnly = true; 310 bool spanHasEmptyCellsOnly = true;
314 int fixedWidth = 0; 311 int fixedWidth = 0;
312 int numAuto = 0;
315 while (lastCol < nEffCols && span > 0) { 313 while (lastCol < nEffCols && span > 0) {
316 Layout& columnLayout = m_layoutStruct[lastCol]; 314 Layout& columnLayout = m_layoutStruct[lastCol];
317 switch (columnLayout.logicalWidth.type()) { 315 switch (columnLayout.logicalWidth.type()) {
318 case Percent: 316 case Percent:
319 totalPercent += columnLayout.logicalWidth.percent(); 317 totalPercent += columnLayout.logicalWidth.percent();
320 allColsAreFixed = false; 318 allColsAreFixed = false;
321 break; 319 break;
322 case Fixed: 320 case Fixed:
323 if (columnLayout.logicalWidth.value() > 0) { 321 if (columnLayout.logicalWidth.value() > 0) {
324 fixedWidth += columnLayout.logicalWidth.value(); 322 fixedWidth += columnLayout.logicalWidth.value();
325 allColsArePercent = false; 323 allColsArePercent = false;
326 // IE resets effWidth to Auto here, but this breaks the konq ueror about page and seems to be some bad 324 // IE resets effWidth to Auto here, but this breaks the konq ueror about page and seems to be some bad
327 // legacy behaviour anyway. mozilla doesn't do this so I dec ided we don't neither. 325 // legacy behaviour anyway. mozilla doesn't do this so I dec ided we don't neither.
328 break; 326 break;
329 } 327 }
330 // fall through 328 // fall through
331 case Auto: 329 case Auto:
332 haveAuto = true; 330 haveAuto = true;
331 if (!columnLayout.columnHasNoCells)
332 numAuto++;
333 // fall through 333 // fall through
334 default: 334 default:
335 // If the column is a percentage width, do not let the spanning cell overwrite the 335 // If the column is a percentage width, do not let the spanning cell overwrite the
336 // width value. This caused a mis-layout on amazon.com. 336 // width value. This caused a mis-layout on amazon.com.
337 // Sample snippet: 337 // Sample snippet:
338 // <table border=2 width=100%>< 338 // <table border=2 width=100%><
339 // <tr><td>1</td><td colspan=2>2-3</tr> 339 // <tr><td>1</td><td colspan=2>2-3</tr>
340 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> 340 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr>
341 // </table> 341 // </table>
342 // TODO(alancutter): Make this work correctly for calc lengths. 342 // TODO(alancutter): Make this work correctly for calc lengths.
(...skipping 20 matching lines...) Expand all
363 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent) { 363 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent) {
364 // can't satify this condition, treat as variable 364 // can't satify this condition, treat as variable
365 cellLogicalWidth = Length(); 365 cellLogicalWidth = Length();
366 } else { 366 } else {
367 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std ::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen t())); 367 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std ::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen t()));
368 368
369 // all non percent columns in the span get percent values to sum up correctly. 369 // all non percent columns in the span get percent values to sum up correctly.
370 float percentMissing = cellLogicalWidth.percent() - totalPercent ; 370 float percentMissing = cellLogicalWidth.percent() - totalPercent ;
371 int totalWidth = 0; 371 int totalWidth = 0;
372 for (unsigned pos = effCol; pos < lastCol; ++pos) { 372 for (unsigned pos = effCol; pos < lastCol; ++pos) {
373 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent()) 373 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent() && (!m_layoutStruct[pos].emptyCellsOnly || spanHasEmptyCellsOnly))
374 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLog icalWidth(); 374 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLog icalWidth();
375 } 375 }
376 376
377 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p os) { 377 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p os) {
378 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent()) { 378 // Empty columns shouldn't get any share of a span's percent width.
379 float percent = percentMissing * static_cast<float>(m_la youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; 379 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent() && (!m_layoutStruct[pos].emptyCellsOnly || spanHasEmptyCellsOnly)) {
380 float percent = percentMissing * static_cast<float>(m_la youtStruct[pos].clampedEffectiveMaxLogicalWidth()) / totalWidth;
380 totalWidth -= m_layoutStruct[pos].clampedEffectiveMaxLog icalWidth(); 381 totalWidth -= m_layoutStruct[pos].clampedEffectiveMaxLog icalWidth();
381 percentMissing -= percent; 382 percentMissing -= percent;
382 if (percent > 0) 383 if (percent > 0 && !m_layoutStruct[pos].columnHasNoCells )
383 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P ercent, percent); 384 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P ercent, percent);
384 else 385 else
385 m_layoutStruct[pos].effectiveLogicalWidth = Length() ; 386 m_layoutStruct[pos].effectiveLogicalWidth = Length() ;
386 } 387 }
387 } 388 }
388 } 389 }
389 } 390 }
390 391
391 // make sure minWidth and maxWidth of the spanning cell are honoured 392 // make sure minWidth and maxWidth of the spanning cell are honoured
392 if (cellMinLogicalWidth > spanMinLogicalWidth) { 393 if (cellMinLogicalWidth > spanMinLogicalWidth) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv eMaxLogicalWidth; 441 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv eMaxLogicalWidth;
441 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv eMinLogicalWidth; 442 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv eMinLogicalWidth;
442 cellMinLogicalWidth -= colMinLogicalWidth; 443 cellMinLogicalWidth -= colMinLogicalWidth;
443 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog icalWidth; 444 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog icalWidth;
444 } 445 }
445 } 446 }
446 } 447 }
447 } 448 }
448 if (!cellLogicalWidth.hasPercent()) { 449 if (!cellLogicalWidth.hasPercent()) {
449 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { 450 if (cellMaxLogicalWidth > spanMaxLogicalWidth) {
451 int widthAvailableToAuto = cellMaxLogicalWidth - fixedWidth;
450 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la stCol; ++pos) { 452 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la stCol; ++pos) {
451 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic alWidth : cellMaxLogicalWidth)); 453 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic alWidth : cellMaxLogicalWidth));
452 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic alWidth; 454 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic alWidth;
453 cellMaxLogicalWidth -= colMaxLogicalWidth; 455 cellMaxLogicalWidth -= colMaxLogicalWidth;
454 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical Width; 456 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical Width;
457 if (m_layoutStruct[pos].logicalWidth.isAuto() && m_layoutStr uct[pos].emptyCellsOnly && !m_layoutStruct[pos].columnHasNoCells && !spanHasEmpt yCellsOnly)
458 m_layoutStruct[pos].effectiveMinLogicalWidth = widthAvai lableToAuto / numAuto;
455 } 459 }
456 } 460 }
457 } else { 461 } else {
458 for (unsigned pos = effCol; pos < lastCol; ++pos) 462 for (unsigned pos = effCol; pos < lastCol; ++pos)
459 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); 463 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth);
460 } 464 }
461 // treat span ranges consisting of empty cells only as if they had conte nt 465 // treat span ranges consisting of empty cells only as if they had conte nt
462 if (spanHasEmptyCellsOnly) { 466 if (spanHasEmptyCellsOnly) {
463 for (unsigned pos = effCol; pos < lastCol; ++pos) 467 for (unsigned pos = effCol; pos < lastCol; ++pos)
464 m_layoutStruct[pos].emptyCellsOnly = false; 468 m_layoutStruct[pos].emptyCellsOnly = false;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 havePercent = true; 538 havePercent = true;
535 totalPercent += logicalWidth.percent(); 539 totalPercent += logicalWidth.percent();
536 break; 540 break;
537 case Fixed: 541 case Fixed:
538 numFixed++; 542 numFixed++;
539 totalFixed += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth(); 543 totalFixed += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth();
540 // fall through 544 // fall through
541 break; 545 break;
542 case Auto: 546 case Auto:
543 if (m_layoutStruct[i].emptyCellsOnly) { 547 if (m_layoutStruct[i].emptyCellsOnly) {
544 numAutoEmptyCellsOnly++; 548 if (!m_layoutStruct[i].columnHasNoCells)
549 numAutoEmptyCellsOnly++;
545 } else { 550 } else {
546 numAuto++; 551 numAuto++;
547 totalAuto += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth() ; 552 totalAuto += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth() ;
548 } 553 }
549 if (!m_layoutStruct[i].columnHasNoCells) 554 if (!m_layoutStruct[i].columnHasNoCells)
550 allocAuto += cellLogicalWidth; 555 allocAuto += cellLogicalWidth;
551 break; 556 break;
552 default: 557 default:
553 break; 558 break;
554 } 559 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 697 int reduce = available * minMaxDiff / logicalWidthBeyondMin;
693 m_layoutStruct[i].computedLogicalWidth += reduce; 698 m_layoutStruct[i].computedLogicalWidth += reduce;
694 available -= reduce; 699 available -= reduce;
695 logicalWidthBeyondMin -= minMaxDiff; 700 logicalWidthBeyondMin -= minMaxDiff;
696 if (available >= 0) 701 if (available >= 0)
697 break; 702 break;
698 } 703 }
699 } 704 }
700 } 705 }
701 } 706 }
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1302-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698