Index: branches/REL1_18/phase3/CREDITS |
— | — | @@ -81,7 +81,6 @@ |
82 | 82 | * Antonio Ospite |
83 | 83 | * Azliq7 |
84 | 84 | * Bergi |
85 | | -* Bluehairedlawyer |
86 | 85 | * Borislav Manolov |
87 | 86 | * Brad Jorsch |
88 | 87 | * Brent G |
Index: branches/REL1_18/phase3/tests/parser/parserTests.txt |
— | — | @@ -1246,10 +1246,8 @@ |
1247 | 1247 | |} |
1248 | 1248 | !! result |
1249 | 1249 | <table> |
1250 | | -<caption>caption |
1251 | | -</caption> |
1252 | | -<tr><td></td></tr> |
1253 | | -</table> |
| 1250 | +<caption> caption |
| 1251 | +</caption><tr><td></td></tr></table> |
1254 | 1252 | |
1255 | 1253 | !! end |
1256 | 1254 | |
— | — | @@ -1264,376 +1262,18 @@ |
1265 | 1263 | !! result |
1266 | 1264 | <table> |
1267 | 1265 | <tr> |
1268 | | -<td>1 |
1269 | | -</td> |
1270 | | -<td>2 |
1271 | | -</td> |
1272 | | -</tr> |
| 1266 | +<td> 1 </td> |
| 1267 | +<td> 2 |
| 1268 | +</td></tr> |
1273 | 1269 | <tr> |
1274 | | -<td>3 |
1275 | | -</td> |
1276 | | -<td>4 |
1277 | | -</td> |
1278 | | -</tr> |
1279 | | -</table> |
| 1270 | +<td> 3 </td> |
| 1271 | +<td> 4 |
| 1272 | +</td></tr></table> |
1280 | 1273 | |
1281 | 1274 | !! end |
1282 | 1275 | |
1283 | 1276 | !! test |
1284 | | -Table inside unclosed table w/o cells |
1285 | | -!! input |
1286 | | -{| |
1287 | | -{| |
1288 | | -| foo bar |
1289 | | -|} |
1290 | | - |
1291 | | -!! result |
1292 | | -<table> |
1293 | | -<tr> |
1294 | | -<td> |
1295 | | -<table> |
1296 | | -<tr> |
1297 | | -<td>foo bar |
1298 | | -</td> |
1299 | | -</tr> |
1300 | | -</table> |
1301 | | -<p><br /> |
1302 | | -</p> |
1303 | | -</td> |
1304 | | -</tr> |
1305 | | -</table> |
1306 | | - |
1307 | | -!! end |
1308 | | - |
1309 | 1277 | !! test |
1310 | | -Table with thead |
1311 | | -!! input |
1312 | | -{| |
1313 | | -! Number !! Another number |
1314 | | -|- |
1315 | | -| 1 || 2 |
1316 | | -|- |
1317 | | -| 3 || 4 |
1318 | | -|} |
1319 | | -!! result |
1320 | | -<table> |
1321 | | -<thead> |
1322 | | -<tr> |
1323 | | -<th>Number |
1324 | | -</th> |
1325 | | -<th>Another number |
1326 | | -</th> |
1327 | | -</tr></thead> |
1328 | | -<tbody> |
1329 | | -<tr> |
1330 | | -<td>1 |
1331 | | -</td> |
1332 | | -<td>2 |
1333 | | -</td> |
1334 | | -</tr> |
1335 | | -<tr> |
1336 | | -<td>3 |
1337 | | -</td> |
1338 | | -<td>4 |
1339 | | -</td> |
1340 | | -</tr></tbody> |
1341 | | -</table> |
1342 | | - |
1343 | | -!! end |
1344 | | - |
1345 | | -!! test |
1346 | | -Table with multiple captions: Only keep first |
1347 | | -!! input |
1348 | | -{| |
1349 | | -|+ caption 1 |
1350 | | -|+ caption 2 |
1351 | | -|} |
1352 | | -!! result |
1353 | | -<table> |
1354 | | -<caption>caption 1 |
1355 | | -</caption> |
1356 | | -<tr><td></td></tr> |
1357 | | -</table> |
1358 | | - |
1359 | | -!! end |
1360 | | - |
1361 | | -!! test |
1362 | | -Table with multiline caption |
1363 | | -!! input |
1364 | | -{| |
1365 | | -|+ caption 1 |
1366 | | -further caption |
1367 | | -|} |
1368 | | -!! result |
1369 | | -<table> |
1370 | | -<caption>caption 1 |
1371 | | -further caption |
1372 | | -</caption> |
1373 | | -<tr><td></td></tr> |
1374 | | -</table> |
1375 | | - |
1376 | | -!! end |
1377 | | -!! test |
1378 | | -Table with multiple thead |
1379 | | -!! input |
1380 | | -{| |
1381 | | -! Number !! Another number |
1382 | | -|- |
1383 | | -| 1 || 2 |
1384 | | -|- |
1385 | | -! Some other number !! Another number |
1386 | | -|- |
1387 | | -| 3 || 4 |
1388 | | -|} |
1389 | | -!! result |
1390 | | -<table> |
1391 | | -<thead> |
1392 | | -<tr> |
1393 | | -<th>Number |
1394 | | -</th> |
1395 | | -<th>Another number |
1396 | | -</th> |
1397 | | -</tr></thead> |
1398 | | -<tbody> |
1399 | | -<tr> |
1400 | | -<td>1 |
1401 | | -</td> |
1402 | | -<td>2 |
1403 | | -</td> |
1404 | | -</tr></tbody> |
1405 | | -<thead> |
1406 | | -<tr> |
1407 | | -<th>Some other number |
1408 | | -</th> |
1409 | | -<th>Another number |
1410 | | -</th> |
1411 | | -</tr></thead> |
1412 | | -<tbody> |
1413 | | -<tr> |
1414 | | -<td>3 |
1415 | | -</td> |
1416 | | -<td>4 |
1417 | | -</td> |
1418 | | -</tr></tbody> |
1419 | | -</table> |
1420 | | - |
1421 | | -!! end |
1422 | | -!! test |
1423 | | -Table with thead & tfoot |
1424 | | -!! input |
1425 | | -{| |
1426 | | -! Number !! Another number |
1427 | | -|- |
1428 | | -| 1 || 2 |
1429 | | -|- |
1430 | | -! Some other number !! Another number |
1431 | | -|- |
1432 | | -| 3 || 4 |
1433 | | -|- |
1434 | | -! Total: 4 !! Total: 6 |
1435 | | -|} |
1436 | | -!! result |
1437 | | -<table> |
1438 | | -<thead> |
1439 | | -<tr> |
1440 | | -<th>Number |
1441 | | -</th> |
1442 | | -<th>Another number |
1443 | | -</th> |
1444 | | -</tr></thead> |
1445 | | -<tbody> |
1446 | | -<tr> |
1447 | | -<td>1 |
1448 | | -</td> |
1449 | | -<td>2 |
1450 | | -</td> |
1451 | | -</tr></tbody> |
1452 | | -<thead> |
1453 | | -<tr> |
1454 | | -<th>Some other number |
1455 | | -</th> |
1456 | | -<th>Another number |
1457 | | -</th> |
1458 | | -</tr></thead> |
1459 | | -<tbody> |
1460 | | -<tr> |
1461 | | -<td>3 |
1462 | | -</td> |
1463 | | -<td>4 |
1464 | | -</td> |
1465 | | -</tr></tbody> |
1466 | | -<tfoot> |
1467 | | -<tr> |
1468 | | -<th>Total: 4 |
1469 | | -</th> |
1470 | | -<th>Total: 6 |
1471 | | -</th> |
1472 | | -</tr></tfoot> |
1473 | | -</table> |
1474 | | - |
1475 | | -!! end |
1476 | | - |
1477 | | -!! test |
1478 | | -Table have th inside tfoot |
1479 | | -!! input |
1480 | | -{| |
1481 | | -| cell1 || cell2 |
1482 | | -|- |
1483 | | -! Footer1 !! Footer2 |
1484 | | -|} |
1485 | | -!! result |
1486 | | -<table> |
1487 | | -<tbody> |
1488 | | -<tr> |
1489 | | -<td>cell1 |
1490 | | -</td> |
1491 | | -<td>cell2 |
1492 | | -</td> |
1493 | | -</tr></tbody> |
1494 | | -<tfoot> |
1495 | | -<tr> |
1496 | | -<th>Footer1 |
1497 | | -</th> |
1498 | | -<th>Footer2 |
1499 | | -</th> |
1500 | | -</tr></tfoot> |
1501 | | -</table> |
1502 | | - |
1503 | | -!! end |
1504 | | - |
1505 | | -!! test |
1506 | | -Table have th inside thead |
1507 | | -!! input |
1508 | | -{| |
1509 | | -! Header1 !! Header2 |
1510 | | -|- |
1511 | | -| cell1 || cell2 |
1512 | | -|} |
1513 | | -!! result |
1514 | | -<table> |
1515 | | -<thead> |
1516 | | -<tr> |
1517 | | -<th>Header1 |
1518 | | -</th> |
1519 | | -<th>Header2 |
1520 | | -</th> |
1521 | | -</tr></thead> |
1522 | | -<tbody> |
1523 | | -<tr> |
1524 | | -<td>cell1 |
1525 | | -</td> |
1526 | | -<td>cell2 |
1527 | | -</td> |
1528 | | -</tr></tbody> |
1529 | | -</table> |
1530 | | - |
1531 | | -!! end |
1532 | | - |
1533 | | -!! test |
1534 | | -Table with list inside |
1535 | | -!! input |
1536 | | -{| |
1537 | | -|style="width: 5em; text-align: center"| gives |
1538 | | -|style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em"| |
1539 | | -# Some |
1540 | | -# list |
1541 | | -# Lorem |
1542 | | -# ipsum |
1543 | | -# dolor |
1544 | | -|} |
1545 | | -!! result |
1546 | | -<table> |
1547 | | -<tr> |
1548 | | -<td style="width: 5em; text-align: center">gives |
1549 | | -</td> |
1550 | | -<td style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em"> |
1551 | | -<ol><li> Some |
1552 | | -</li><li> list |
1553 | | -</li><li> Lorem |
1554 | | -</li><li> ipsum |
1555 | | -</li><li> dolor |
1556 | | -</li></ol> |
1557 | | -</td> |
1558 | | -</tr> |
1559 | | -</table> |
1560 | | - |
1561 | | -!! end |
1562 | | -!! test |
1563 | | -Table with broken up list inside |
1564 | | -!! input |
1565 | | -{| |
1566 | | -|style="width: 5em; text-align: center"| gives |
1567 | | -|style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em"| |
1568 | | -# Some |
1569 | | -# list |
1570 | | -# Lorem |
1571 | | - |
1572 | | -# ipsum |
1573 | | -# dolor |
1574 | | -|} |
1575 | | -!! result |
1576 | | -<table> |
1577 | | -<tr> |
1578 | | -<td style="width: 5em; text-align: center">gives |
1579 | | -</td> |
1580 | | -<td style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em"> |
1581 | | -<ol><li> Some |
1582 | | -</li><li> list |
1583 | | -</li><li> Lorem |
1584 | | -</li></ol> |
1585 | | -<ol><li> ipsum |
1586 | | -</li><li> dolor |
1587 | | -</li></ol> |
1588 | | -</td> |
1589 | | -</tr> |
1590 | | -</table> |
1591 | | - |
1592 | | -!! end |
1593 | | - |
1594 | | -!! test |
1595 | | -Indented table wrapped in html tags (Related to Bug 26362) |
1596 | | -!! input |
1597 | | -<div> |
1598 | | -:{| |
1599 | | -|- |
1600 | | -| test |
1601 | | -|}</div> |
1602 | | - |
1603 | | -!! result |
1604 | | -<div> |
1605 | | -<dl><dd><table> |
1606 | | -<tr> |
1607 | | -<td>test |
1608 | | -</td> |
1609 | | -</tr> |
1610 | | -</table></dd></dl></div> |
1611 | | - |
1612 | | -!! end |
1613 | | - |
1614 | | -!! test |
1615 | | -Table with multiline contents |
1616 | | -!! input |
1617 | | -{| |
1618 | | -| Alice |
1619 | | -Bob |
1620 | | -dfdfg |
1621 | | -dfg |
1622 | | -|} |
1623 | | -!! result |
1624 | | -<table> |
1625 | | -<tr> |
1626 | | -<td>Alice |
1627 | | -<p>Bob |
1628 | | -dfdfg |
1629 | | -dfg |
1630 | | -</p> |
1631 | | -</td> |
1632 | | -</tr> |
1633 | | -</table> |
1634 | | - |
1635 | | -!! end |
1636 | | - |
1637 | | -!! test |
1638 | 1278 | Multiplication table |
1639 | 1279 | !! input |
1640 | 1280 | {| border="1" cellpadding="2" |
— | — | @@ -1660,69 +1300,47 @@ |
1661 | 1301 | <table border="1" cellpadding="2"> |
1662 | 1302 | <caption>Multiplication table |
1663 | 1303 | </caption> |
1664 | | -<thead> |
1665 | 1304 | <tr> |
1666 | | -<th>× |
1667 | | -</th> |
1668 | | -<th>1 |
1669 | | -</th> |
1670 | | -<th>2 |
1671 | | -</th> |
1672 | | -<th>3 |
1673 | | -</th> |
1674 | | -</tr></thead> |
1675 | | -<tbody> |
| 1305 | +<th> × </th> |
| 1306 | +<th> 1 </th> |
| 1307 | +<th> 2 </th> |
| 1308 | +<th> 3 |
| 1309 | +</th></tr> |
1676 | 1310 | <tr> |
1677 | | -<th>1 |
| 1311 | +<th> 1 |
1678 | 1312 | </th> |
1679 | | -<td>1 |
1680 | | -</td> |
1681 | | -<td>2 |
1682 | | -</td> |
1683 | | -<td>3 |
1684 | | -</td> |
1685 | | -</tr> |
| 1313 | +<td> 1 </td> |
| 1314 | +<td> 2 </td> |
| 1315 | +<td> 3 |
| 1316 | +</td></tr> |
1686 | 1317 | <tr> |
1687 | | -<th>2 |
| 1318 | +<th> 2 |
1688 | 1319 | </th> |
1689 | | -<td>2 |
1690 | | -</td> |
1691 | | -<td>4 |
1692 | | -</td> |
1693 | | -<td>6 |
1694 | | -</td> |
1695 | | -</tr> |
| 1320 | +<td> 2 </td> |
| 1321 | +<td> 4 </td> |
| 1322 | +<td> 6 |
| 1323 | +</td></tr> |
1696 | 1324 | <tr> |
1697 | | -<th>3 |
| 1325 | +<th> 3 |
1698 | 1326 | </th> |
1699 | | -<td>3 |
1700 | | -</td> |
1701 | | -<td>6 |
1702 | | -</td> |
1703 | | -<td>9 |
1704 | | -</td> |
1705 | | -</tr> |
| 1327 | +<td> 3 </td> |
| 1328 | +<td> 6 </td> |
| 1329 | +<td> 9 |
| 1330 | +</td></tr> |
1706 | 1331 | <tr> |
1707 | | -<th>4 |
| 1332 | +<th> 4 |
1708 | 1333 | </th> |
1709 | | -<td>4 |
1710 | | -</td> |
1711 | | -<td>8 |
1712 | | -</td> |
1713 | | -<td>12 |
1714 | | -</td> |
1715 | | -</tr> |
| 1334 | +<td> 4 </td> |
| 1335 | +<td> 8 </td> |
| 1336 | +<td> 12 |
| 1337 | +</td></tr> |
1716 | 1338 | <tr> |
1717 | | -<th>5 |
| 1339 | +<th> 5 |
1718 | 1340 | </th> |
1719 | | -<td>5 |
1720 | | -</td> |
1721 | | -<td>10 |
1722 | | -</td> |
1723 | | -<td>15 |
1724 | | -</td> |
1725 | | -</tr></tbody> |
1726 | | -</table> |
| 1341 | +<td> 5 </td> |
| 1342 | +<td> 10 </td> |
| 1343 | +<td> 15 |
| 1344 | +</td></tr></table> |
1727 | 1345 | |
1728 | 1346 | !! end |
1729 | 1347 | |
— | — | @@ -1740,20 +1358,17 @@ |
1741 | 1359 | !! result |
1742 | 1360 | <table align="right" border="1"> |
1743 | 1361 | <tr> |
1744 | | -<td>Cell 1, row 1 |
| 1362 | +<td> Cell 1, row 1 |
1745 | 1363 | </td> |
1746 | | -<td rowspan="2">Cell 2, row 1 (and 2) |
| 1364 | +<td rowspan="2"> Cell 2, row 1 (and 2) |
1747 | 1365 | </td> |
1748 | | -<td>Cell 3, row 1 |
1749 | | -</td> |
1750 | | -</tr> |
| 1366 | +<td> Cell 3, row 1 |
| 1367 | +</td></tr> |
1751 | 1368 | <tr> |
1752 | | -<td>Cell 1, row 2 |
| 1369 | +<td> Cell 1, row 2 |
1753 | 1370 | </td> |
1754 | | -<td>Cell 3, row 2 |
1755 | | -</td> |
1756 | | -</tr> |
1757 | | -</table> |
| 1371 | +<td> Cell 3, row 2 |
| 1372 | +</td></tr></table> |
1758 | 1373 | |
1759 | 1374 | !! end |
1760 | 1375 | |
— | — | @@ -1773,24 +1388,19 @@ |
1774 | 1389 | !! result |
1775 | 1390 | <table border="1"> |
1776 | 1391 | <tr> |
1777 | | -<td>α |
| 1392 | +<td> α |
1778 | 1393 | </td> |
1779 | 1394 | <td> |
1780 | 1395 | <table bgcolor="#ABCDEF" border="2"> |
1781 | 1396 | <tr> |
1782 | 1397 | <td>nested |
1783 | | -</td> |
1784 | | -</tr> |
| 1398 | +</td></tr> |
1785 | 1399 | <tr> |
1786 | 1400 | <td>table |
| 1401 | +</td></tr></table> |
1787 | 1402 | </td> |
1788 | | -</tr> |
1789 | | -</table> |
1790 | | -</td> |
1791 | 1403 | <td>the original table again |
1792 | | -</td> |
1793 | | -</tr> |
1794 | | -</table> |
| 1404 | +</td></tr></table> |
1795 | 1405 | |
1796 | 1406 | !! end |
1797 | 1407 | |
— | — | @@ -1804,87 +1414,12 @@ |
1805 | 1415 | <table> |
1806 | 1416 | <tr> |
1807 | 1417 | <td>broken |
1808 | | -</td> |
1809 | | -</tr> |
1810 | | -</table> |
| 1418 | +</td></tr></table> |
1811 | 1419 | |
1812 | 1420 | !! end |
1813 | 1421 | |
1814 | | -!! test |
1815 | | -Heading inside table (affected by r85922) |
1816 | | -!! input |
1817 | | -{| |
1818 | | -|- valign="top" |
1819 | | -| |
1820 | | -=== Heading === |
1821 | | -|} |
1822 | | -!! result |
1823 | | -<table> |
1824 | | -<tr valign="top"> |
1825 | | -<td> |
1826 | | -<h3><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Heading">edit</a>]</span> <span class="mw-headline" id="Heading"> Heading </span></h3> |
1827 | | -</td> |
1828 | | -</tr> |
1829 | | -</table> |
1830 | 1422 | |
1831 | | -!! end |
1832 | | - |
1833 | 1423 | !! test |
1834 | | -A table with a caption with unclosed italic |
1835 | | -!! input |
1836 | | -{| |
1837 | | -|+ ''caption |
1838 | | -| Cell |
1839 | | -|} |
1840 | | -!! result |
1841 | | -<table> |
1842 | | -<caption><i>caption</i> |
1843 | | -</caption> |
1844 | | -<tr> |
1845 | | -<td>Cell |
1846 | | -</td> |
1847 | | -</tr> |
1848 | | -</table> |
1849 | | - |
1850 | | -!! end |
1851 | | - |
1852 | | -!! test |
1853 | | -A table with unclosed italic in a cell |
1854 | | -!! input |
1855 | | -{| |
1856 | | -| ''Cell |
1857 | | -|} |
1858 | | -!! result |
1859 | | -<table> |
1860 | | -<tr> |
1861 | | -<td><i>Cell</i> |
1862 | | -</td> |
1863 | | -</tr> |
1864 | | -</table> |
1865 | | - |
1866 | | -!! end |
1867 | | - |
1868 | | -!! test |
1869 | | -A table with unclosed italic in a th |
1870 | | -!! input |
1871 | | -{| |
1872 | | -|- |
1873 | | -! ''Cell |
1874 | | -|| Value |
1875 | | -|} |
1876 | | -!! result |
1877 | | -<table> |
1878 | | -<tr> |
1879 | | -<th><i>Cell</i> |
1880 | | -</th> |
1881 | | -<td>Value |
1882 | | -</td> |
1883 | | -</tr> |
1884 | | -</table> |
1885 | | - |
1886 | | -!! end |
1887 | | - |
1888 | | -!! test |
1889 | 1424 | Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html) |
1890 | 1425 | !! input |
1891 | 1426 | {| |
— | — | @@ -1892,8 +1427,7 @@ |
1893 | 1428 | !! result |
1894 | 1429 | <table> |
1895 | 1430 | <tr> |
1896 | | -<td>[<a rel="nofollow" class="external free" href="ftp://%7Cx">ftp://%7Cx</a> |
1897 | | -</td> |
| 1431 | +<td>[<a rel="nofollow" class="external free" href="ftp://%7Cx">ftp://%7Cx</a></td> |
1898 | 1432 | <td>]" onmouseover="alert(document.cookie)">test |
1899 | 1433 | </td> |
1900 | 1434 | </tr> |
— | — | @@ -1901,73 +1435,8 @@ |
1902 | 1436 | |
1903 | 1437 | !! end |
1904 | 1438 | |
1905 | | -!! test |
1906 | | -Indented Tables, bug 20078 |
1907 | | -!! input |
1908 | | -: {| |
1909 | | -| 1 || 2 |
1910 | | -|- |
1911 | | -| 3 || 4 |
1912 | | -|} |
1913 | | -!! result |
1914 | | -<dl><dd><table> |
1915 | | -<tr> |
1916 | | -<td>1 |
1917 | | -</td> |
1918 | | -<td>2 |
1919 | | -</td> |
1920 | | -</tr> |
1921 | | -<tr> |
1922 | | -<td>3 |
1923 | | -</td> |
1924 | | -<td>4 |
1925 | | -</td> |
1926 | | -</tr> |
1927 | | -</table></dd></dl> |
1928 | 1439 | |
1929 | | -!! end |
1930 | 1440 | |
1931 | | -!! test |
1932 | | -Arbitrary whitespace should not be prepended |
1933 | | -!! input |
1934 | | -{| |
1935 | | -| 1 || 2 |
1936 | | - |
1937 | | -|- |
1938 | | - |
1939 | | - |
1940 | | -| 3 || 4 |
1941 | | -|- |
1942 | | - |
1943 | | -| 6 || 8 |
1944 | | -|} |
1945 | | -!! result |
1946 | | -<table> |
1947 | | -<tr> |
1948 | | -<td>1 |
1949 | | -</td> |
1950 | | -<td>2 |
1951 | | -<p><br /> |
1952 | | -</p> |
1953 | | -</td> |
1954 | | -</tr> |
1955 | | -<tr> |
1956 | | -<td>3 |
1957 | | -</td> |
1958 | | -<td>4 |
1959 | | -</td> |
1960 | | -</tr> |
1961 | | -<tr> |
1962 | | -<td>6 |
1963 | | -</td> |
1964 | | -<td>8 |
1965 | | -</td> |
1966 | | -</tr> |
1967 | | -</table> |
1968 | | - |
1969 | | -!! end |
1970 | | - |
1971 | | - |
1972 | 1441 | ### |
1973 | 1442 | ### Internal links |
1974 | 1443 | ### |
— | — | @@ -3256,9 +2725,7 @@ |
3257 | 2726 | <table> |
3258 | 2727 | <tr> |
3259 | 2728 | <td>[[{{{1}}}|{{{2}}}]] |
3260 | | -</td> |
3261 | | -</tr> |
3262 | | -</table> |
| 2729 | +</td></tr></table> |
3263 | 2730 | |
3264 | 2731 | !! end |
3265 | 2732 | |
— | — | @@ -3367,18 +2834,13 @@ |
3368 | 2835 | </p> |
3369 | 2836 | <table> |
3370 | 2837 | <tr> |
3371 | | -<td>1 |
3372 | | -</td> |
3373 | | -<td>2 |
3374 | | -</td> |
3375 | | -</tr> |
| 2838 | +<td> 1 </td> |
| 2839 | +<td> 2 |
| 2840 | +</td></tr> |
3376 | 2841 | <tr> |
3377 | | -<td>3 |
3378 | | -</td> |
3379 | | -<td>4 |
3380 | | -</td> |
3381 | | -</tr> |
3382 | | -</table> |
| 2842 | +<td> 3 </td> |
| 2843 | +<td> 4 |
| 2844 | +</td></tr></table> |
3383 | 2845 | |
3384 | 2846 | !! end |
3385 | 2847 | |
— | — | @@ -3392,18 +2854,13 @@ |
3393 | 2855 | </p> |
3394 | 2856 | <table> |
3395 | 2857 | <tr> |
3396 | | -<td>1 |
3397 | | -</td> |
3398 | | -<td>2 |
3399 | | -</td> |
3400 | | -</tr> |
| 2858 | +<td> 1 </td> |
| 2859 | +<td> 2 |
| 2860 | +</td></tr> |
3401 | 2861 | <tr> |
3402 | | -<td>3 |
3403 | | -</td> |
3404 | | -<td>4 |
3405 | | -</td> |
3406 | | -</tr> |
3407 | | -</table> |
| 2862 | +<td> 3 </td> |
| 2863 | +<td> 4 |
| 2864 | +</td></tr></table> |
3408 | 2865 | |
3409 | 2866 | !! end |
3410 | 2867 | |
— | — | @@ -5055,10 +4512,8 @@ |
5056 | 4513 | !! result |
5057 | 4514 | <table> |
5058 | 4515 | <tr> |
5059 | | -<th class="awesome">status |
5060 | | -</th> |
5061 | | -</tr> |
5062 | | -</table> |
| 4516 | +<th class="awesome"> status |
| 4517 | +</th></tr></table> |
5063 | 4518 | |
5064 | 4519 | !!end |
5065 | 4520 | |
— | — | @@ -5502,10 +4957,8 @@ |
5503 | 4958 | !! result |
5504 | 4959 | <table> |
5505 | 4960 | <tr> |
5506 | | -<th style="color:blue">status |
5507 | | -</th> |
5508 | | -</tr> |
5509 | | -</table> |
| 4961 | +<th style="color:blue"> status |
| 4962 | +</th></tr></table> |
5510 | 4963 | |
5511 | 4964 | !!end |
5512 | 4965 | |
— | — | @@ -5518,10 +4971,8 @@ |
5519 | 4972 | !! result |
5520 | 4973 | <table> |
5521 | 4974 | <tr> |
5522 | | -<th style="/* insecure input */">status |
5523 | | -</th> |
5524 | | -</tr> |
5525 | | -</table> |
| 4975 | +<th style="/* insecure input */"> status |
| 4976 | +</th></tr></table> |
5526 | 4977 | |
5527 | 4978 | !! end |
5528 | 4979 | |
— | — | @@ -6143,7 +5594,8 @@ |
6144 | 5595 | !! result |
6145 | 5596 | <table> |
6146 | 5597 | <tr> |
6147 | | -<td></td> |
| 5598 | +<td> |
| 5599 | +</td> |
6148 | 5600 | </tr> |
6149 | 5601 | </table> |
6150 | 5602 | |
— | — | @@ -6169,14 +5621,10 @@ |
6170 | 5622 | !! input |
6171 | 5623 | ==a== |
6172 | 5624 | {| STYLE=__TOC__ |
6173 | | -|foo |
6174 | 5625 | !! result |
6175 | 5626 | <h2><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2> |
6176 | 5627 | <table style="__TOC__"> |
6177 | | -<tr> |
6178 | | -<td>foo |
6179 | | -</td> |
6180 | | -</tr> |
| 5628 | +<tr><td></td></tr> |
6181 | 5629 | </table> |
6182 | 5630 | |
6183 | 5631 | !! end |
— | — | @@ -6192,11 +5640,11 @@ |
6193 | 5641 | !! result |
6194 | 5642 | <table> |
6195 | 5643 | <tr> |
6196 | | -<th>https:// |
6197 | | -</th> |
| 5644 | +<th>https://</th> |
6198 | 5645 | <th></th> |
6199 | 5646 | <th></th> |
6200 | | -<th></th> |
| 5647 | +<th> |
| 5648 | +</td> |
6201 | 5649 | </tr> |
6202 | 5650 | </table> |
6203 | 5651 | |
— | — | @@ -6211,9 +5659,10 @@ |
6212 | 5660 | !! result |
6213 | 5661 | <table> |
6214 | 5662 | <tr> |
6215 | | -<th><a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');" |
| 5663 | +<th> <a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');" |
6216 | 5664 | </th> |
6217 | | -<td></td> |
| 5665 | +<td> |
| 5666 | +</td> |
6218 | 5667 | </tr> |
6219 | 5668 | </table> |
6220 | 5669 | |
— | — | @@ -6225,31 +5674,17 @@ |
6226 | 5675 | http://===r:::https://b |
6227 | 5676 | |
6228 | 5677 | {| |
6229 | | - |
6230 | 5678 | !!result |
6231 | 5679 | <p><a rel="nofollow" class="external free" href="http://===r:::https://b">http://===r:::https://b</a> |
6232 | 5680 | </p><p><br /> |
6233 | 5681 | </p> |
| 5682 | +<table> |
| 5683 | +<tr><td></td></tr> |
| 5684 | +</table> |
| 5685 | + |
6234 | 5686 | !! end |
6235 | 5687 | |
6236 | 5688 | # Known to produce bad XML for now |
6237 | | - |
6238 | | -# Note: the current result listed for this is not what the original one was, |
6239 | | -# but the original bug was JavaScript injection, which is fixed in any case. |
6240 | | -# It's not clear that the original result listed was any more correct than the |
6241 | | -# current one. Original result: |
6242 | | -# <table> |
6243 | | -# {{{| |
6244 | | -# <u class="|">}}}} > |
6245 | | -# <br style="onmouseover='alert(document.cookie);'" /> |
6246 | | -# |
6247 | | -# MOVE YOUR MOUSE CURSOR OVER THIS TEXT |
6248 | | -# <tr> |
6249 | | -# <td></u> |
6250 | | -# </td> |
6251 | | -# </tr> |
6252 | | -# </table> |
6253 | | -# Known to produce bad XML for now |
6254 | 5689 | !! test |
6255 | 5690 | Fuzz testing: Parser24 |
6256 | 5691 | !! options |
— | — | @@ -6264,12 +5699,12 @@ |
6265 | 5700 | MOVE YOUR MOUSE CURSOR OVER THIS TEXT |
6266 | 5701 | | |
6267 | 5702 | !! result |
6268 | | -<p>{{{| |
| 5703 | +<table> |
| 5704 | +{{{| |
6269 | 5705 | <u class="|">}}}} > |
6270 | 5706 | <br style="onmouseover='alert(document.cookie);'" /> |
6271 | | -</p><p>MOVE YOUR MOUSE CURSOR OVER THIS TEXT |
6272 | | -</p> |
6273 | | -<table> |
| 5707 | +MOVE YOUR MOUSE CURSOR OVER THIS TEXT |
| 5708 | +MOVE YOUR MOUSE CURSOR OVER THIS TEXT |
6274 | 5709 | <tr> |
6275 | 5710 | <td></u> |
6276 | 5711 | </td> |
— | — | @@ -8478,18 +7913,13 @@ |
8479 | 7914 | </p> |
8480 | 7915 | <table> |
8481 | 7916 | <tr> |
8482 | | -<td>1 |
8483 | | -</td> |
8484 | | -<td>2 |
8485 | | -</td> |
8486 | | -</tr> |
| 7917 | +<td> 1 </td> |
| 7918 | +<td> 2 |
| 7919 | +</td></tr> |
8487 | 7920 | <tr> |
8488 | | -<td>3 |
8489 | | -</td> |
8490 | | -<td>4 |
8491 | | -</td> |
8492 | | -</tr> |
8493 | | -</table> |
| 7921 | +<td> 3 </td> |
| 7922 | +<td> 4 |
| 7923 | +</td></tr></table> |
8494 | 7924 | <p>y |
8495 | 7925 | </p> |
8496 | 7926 | !! end |
Index: branches/REL1_18/phase3/includes/parser/Parser.php |
— | — | @@ -815,300 +815,189 @@ |
816 | 816 | |
817 | 817 | $lines = StringUtils::explode( "\n", $text ); |
818 | 818 | $out = ''; |
819 | | - $output =& $out; |
| 819 | + $td_history = array(); # Is currently a td tag open? |
| 820 | + $last_tag_history = array(); # Save history of last lag activated (td, th or caption) |
| 821 | + $tr_history = array(); # Is currently a tr tag open? |
| 822 | + $tr_attributes = array(); # history of tr attributes |
| 823 | + $has_opened_tr = array(); # Did this table open a <tr> element? |
| 824 | + $indent_level = 0; # indent level of the table |
820 | 825 | |
821 | 826 | foreach ( $lines as $outLine ) { |
822 | 827 | $line = trim( $outLine ); |
823 | 828 | |
824 | | - # empty line, go to next line, |
825 | | - # but only append \n if outside of table |
826 | | - if ( $line === '') { |
827 | | - $output .= $outLine . "\n"; |
| 829 | + if ( $line === '' ) { # empty line, go to next line |
| 830 | + $out .= $outLine."\n"; |
828 | 831 | continue; |
829 | 832 | } |
830 | | - $firstChars = $line[0]; |
831 | | - if ( strlen( $line ) > 1 ) { |
832 | | - $firstChars .= in_array( $line[1], array( '}', '+', '-' ) ) ? $line[1] : ''; |
833 | | - } |
| 833 | + |
| 834 | + $first_character = $line[0]; |
834 | 835 | $matches = array(); |
835 | 836 | |
836 | | - if ( preg_match( '/^(:*)\s*\{\|(.*)$/', $line , $matches ) ) { |
837 | | - $tables[] = array(); |
838 | | - $table =& $this->last( $tables ); |
839 | | - $table[0] = array(); // first row |
840 | | - $currentRow =& $table[0]; |
841 | | - $table['indent'] = strlen( $matches[1] ); |
| 837 | + if ( preg_match( '/^(:*)\{\|(.*)$/', $line , $matches ) ) { |
| 838 | + # First check if we are starting a new table |
| 839 | + $indent_level = strlen( $matches[1] ); |
842 | 840 | |
843 | 841 | $attributes = $this->mStripState->unstripBoth( $matches[2] ); |
844 | 842 | $attributes = Sanitizer::fixTagAttributes( $attributes , 'table' ); |
845 | 843 | |
846 | | - if ( $attributes !== '' ) { |
847 | | - $table['attributes'] = $attributes; |
848 | | - } |
849 | | - } elseif ( !isset( $tables[0] ) ) { |
850 | | - // we're outside the table |
| 844 | + $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>"; |
| 845 | + array_push( $td_history , false ); |
| 846 | + array_push( $last_tag_history , '' ); |
| 847 | + array_push( $tr_history , false ); |
| 848 | + array_push( $tr_attributes , '' ); |
| 849 | + array_push( $has_opened_tr , false ); |
| 850 | + } elseif ( count( $td_history ) == 0 ) { |
| 851 | + # Don't do any of the following |
| 852 | + $out .= $outLine."\n"; |
| 853 | + continue; |
| 854 | + } elseif ( substr( $line , 0 , 2 ) === '|}' ) { |
| 855 | + # We are ending a table |
| 856 | + $line = '</table>' . substr( $line , 2 ); |
| 857 | + $last_tag = array_pop( $last_tag_history ); |
851 | 858 | |
852 | | - $out .= $outLine . "\n"; |
853 | | - } elseif ( $firstChars === '|}' ) { |
854 | | - // trim the |} code from the line |
855 | | - $line = substr ( $line , 2 ); |
856 | | - |
857 | | - // Shorthand for last row |
858 | | - $lastRow =& $this->last( $table ); |
859 | | - |
860 | | - // a thead at the end becomes a tfoot, unless there is only one row |
861 | | - // Do this before deleting empty last lines to allow headers at the bottom of tables |
862 | | - if ( isset( $lastRow['type'] ) && $lastRow['type'] == 'thead' && isset( $table[1] ) ) { |
863 | | - $lastRow['type'] = 'tfoot'; |
864 | | - for ( $i = 0; isset( $lastRow[$i] ); $i++ ) { |
865 | | - $lastRow[$i]['type'] = 'th'; |
866 | | - } |
| 859 | + if ( !array_pop( $has_opened_tr ) ) { |
| 860 | + $line = "<tr><td></td></tr>{$line}"; |
867 | 861 | } |
868 | 862 | |
869 | | - // Delete empty last lines |
870 | | - if ( empty( $lastRow ) ) { |
871 | | - $lastRow = NULL; |
| 863 | + if ( array_pop( $tr_history ) ) { |
| 864 | + $line = "</tr>{$line}"; |
872 | 865 | } |
873 | | - $o = ''; |
874 | | - $curtable = array_pop( $tables ); |
875 | 866 | |
876 | | - #Add a line-ending before the table, but only if there isn't one already |
877 | | - if ( substr( $out, -1 ) !== "\n" ) { |
878 | | - $o .= "\n"; |
| 867 | + if ( array_pop( $td_history ) ) { |
| 868 | + $line = "</{$last_tag}>{$line}"; |
879 | 869 | } |
880 | | - $o .= $this->generateTableHTML( $curtable ) . $line . "\n"; |
| 870 | + array_pop( $tr_attributes ); |
| 871 | + $outLine = $line . str_repeat( '</dd></dl>' , $indent_level ); |
| 872 | + } elseif ( substr( $line , 0 , 2 ) === '|-' ) { |
| 873 | + # Now we have a table row |
| 874 | + $line = preg_replace( '#^\|-+#', '', $line ); |
881 | 875 | |
882 | | - if ( count( $tables ) > 0 ) { |
883 | | - $table =& $this->last( $tables ); |
884 | | - $currentRow =& $this->last( $table ); |
885 | | - $currentElement =& $this->last( $currentRow ); |
886 | | - |
887 | | - $output =& $currentElement['content']; |
888 | | - } else { |
889 | | - $output =& $out; |
890 | | - } |
891 | | - |
892 | | - $output .= $o; |
893 | | - |
894 | | - } elseif ( $firstChars === '|-' ) { |
895 | | - // start a new row element |
896 | | - // but only when we haven't started one already |
897 | | - if ( count( $currentRow ) != 0 ) { |
898 | | - $table[] = array(); |
899 | | - $currentRow =& $this->last( $table ); |
900 | | - } |
901 | | - // Get the attributes, there's nothing else useful in $line now |
902 | | - $line = substr ( $line , 2 ); |
| 876 | + # Whats after the tag is now only attributes |
903 | 877 | $attributes = $this->mStripState->unstripBoth( $line ); |
904 | 878 | $attributes = Sanitizer::fixTagAttributes( $attributes, 'tr' ); |
905 | | - if ( $attributes !== '' ) { |
906 | | - $currentRow['attributes'] = $attributes; |
907 | | - } |
| 879 | + array_pop( $tr_attributes ); |
| 880 | + array_push( $tr_attributes, $attributes ); |
908 | 881 | |
909 | | - } elseif ( $firstChars === '|+' ) { |
910 | | - // a table caption, but only proceed if there isn't one already |
911 | | - if ( !isset ( $table['caption'] ) ) { |
912 | | - $line = substr ( $line , 2 ); |
| 882 | + $line = ''; |
| 883 | + $last_tag = array_pop( $last_tag_history ); |
| 884 | + array_pop( $has_opened_tr ); |
| 885 | + array_push( $has_opened_tr , true ); |
913 | 886 | |
914 | | - $c = $this->getCellAttr( $line , 'caption' ); |
915 | | - $table['caption'] = array(); |
916 | | - $table['caption']['content'] = $c[0]; |
917 | | - if ( isset( $c[1] ) ) $table['caption']['attributes'] = $c[1]; |
918 | | - unset( $c ); |
919 | | - $output =& $table['caption']['content']; |
| 887 | + if ( array_pop( $tr_history ) ) { |
| 888 | + $line = '</tr>'; |
920 | 889 | } |
921 | | - } elseif ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) { |
922 | | - // Which kind of cells are we dealing with |
923 | | - $currentTag = 'td'; |
924 | | - $line = substr ( $line , 1 ); |
925 | 890 | |
926 | | - if ( $firstChars === '!' || $firstChars === '!+' ) { |
927 | | - $line = str_replace ( '!!' , '||' , $line ); |
928 | | - $currentTag = 'th'; |
| 891 | + if ( array_pop( $td_history ) ) { |
| 892 | + $line = "</{$last_tag}>{$line}"; |
929 | 893 | } |
930 | 894 | |
931 | | - // Split up multiple cells on the same line. |
932 | | - $cells = StringUtils::explodeMarkup( '||' , $line ); |
933 | | - $line = ''; // save memory |
934 | | - |
935 | | - // decide whether thead to tbody |
936 | | - if ( !array_key_exists( 'type', $currentRow ) ) { |
937 | | - $currentRow['type'] = ( $firstChars === '!' ) ? 'thead' : 'tbody' ; |
938 | | - } elseif ( $firstChars === '|' ) { |
939 | | - $currentRow['type'] = 'tbody'; |
| 895 | + $outLine = $line; |
| 896 | + array_push( $tr_history , false ); |
| 897 | + array_push( $td_history , false ); |
| 898 | + array_push( $last_tag_history , '' ); |
| 899 | + } elseif ( $first_character === '|' || $first_character === '!' || substr( $line , 0 , 2 ) === '|+' ) { |
| 900 | + # This might be cell elements, td, th or captions |
| 901 | + if ( substr( $line , 0 , 2 ) === '|+' ) { |
| 902 | + $first_character = '+'; |
| 903 | + $line = substr( $line , 1 ); |
940 | 904 | } |
941 | 905 | |
942 | | - // Loop through each table cell |
943 | | - foreach ( $cells as $cell ) { |
944 | | - // a new cell |
945 | | - $currentRow[] = array(); |
946 | | - $currentElement =& $this->last( $currentRow ); |
| 906 | + $line = substr( $line , 1 ); |
947 | 907 | |
948 | | - $currentElement['type'] = $currentTag; |
949 | | - |
950 | | - $c = $this->getCellAttr( $cell , $currentTag ); |
951 | | - $currentElement['content'] = $c[0]; |
952 | | - if ( isset( $c[1] ) ) $currentElement['attributes'] = $c[1]; |
953 | | - unset( $c ); |
| 908 | + if ( $first_character === '!' ) { |
| 909 | + $line = str_replace( '!!' , '||' , $line ); |
954 | 910 | } |
955 | | - $output =& $currentElement['content']; |
956 | 911 | |
957 | | - } else { |
958 | | - $output .= "\n$outLine"; |
959 | | - } |
960 | | - } |
| 912 | + # Split up multiple cells on the same line. |
| 913 | + # FIXME : This can result in improper nesting of tags processed |
| 914 | + # by earlier parser steps, but should avoid splitting up eg |
| 915 | + # attribute values containing literal "||". |
| 916 | + $cells = StringUtils::explodeMarkup( '||' , $line ); |
961 | 917 | |
962 | | - # Remove trailing line-ending (b/c) |
963 | | - if ( substr( $out, -1 ) === "\n" ) { |
964 | | - $out = substr( $out, 0, -1 ); |
965 | | - } |
| 918 | + $outLine = ''; |
966 | 919 | |
967 | | - # Close any unclosed tables |
968 | | - if ( isset( $tables ) && count( $tables ) > 0 ) { |
969 | | - for ( $i = 0; $i < count( $tables ); $i++ ) { |
970 | | - $curtable = array_pop( $tables ); |
971 | | - $curtable = $this->generateTableHTML( $curtable ); |
972 | | - #Add a line-ending before the table, but only if there isn't one already |
973 | | - if ( substr( $out, -1 ) !== "\n" && $curtable !== "" ) { |
974 | | - $out .= "\n"; |
975 | | - } |
976 | | - $out .= $curtable; |
977 | | - } |
978 | | - } |
| 920 | + # Loop through each table cell |
| 921 | + foreach ( $cells as $cell ) { |
| 922 | + $previous = ''; |
| 923 | + if ( $first_character !== '+' ) { |
| 924 | + $tr_after = array_pop( $tr_attributes ); |
| 925 | + if ( !array_pop( $tr_history ) ) { |
| 926 | + $previous = "<tr{$tr_after}>\n"; |
| 927 | + } |
| 928 | + array_push( $tr_history , true ); |
| 929 | + array_push( $tr_attributes , '' ); |
| 930 | + array_pop( $has_opened_tr ); |
| 931 | + array_push( $has_opened_tr , true ); |
| 932 | + } |
979 | 933 | |
980 | | - wfProfileOut( __METHOD__ ); |
| 934 | + $last_tag = array_pop( $last_tag_history ); |
981 | 935 | |
982 | | - return $out; |
983 | | - } |
| 936 | + if ( array_pop( $td_history ) ) { |
| 937 | + $previous = "</{$last_tag}>\n{$previous}"; |
| 938 | + } |
984 | 939 | |
985 | | - /** |
986 | | - * Helper function for doTableStuff() separating the contents of cells from |
987 | | - * attributes. Particularly useful as there's a possible bug and this action |
988 | | - * is repeated twice. |
989 | | - * |
990 | | - * @private |
991 | | - * @param $cell |
992 | | - * @param $tagName |
993 | | - * @return array |
994 | | - */ |
995 | | - function getCellAttr ( $cell, $tagName ) { |
996 | | - $attributes = null; |
| 940 | + if ( $first_character === '|' ) { |
| 941 | + $last_tag = 'td'; |
| 942 | + } elseif ( $first_character === '!' ) { |
| 943 | + $last_tag = 'th'; |
| 944 | + } elseif ( $first_character === '+' ) { |
| 945 | + $last_tag = 'caption'; |
| 946 | + } else { |
| 947 | + $last_tag = ''; |
| 948 | + } |
997 | 949 | |
998 | | - $cell = trim ( $cell ); |
| 950 | + array_push( $last_tag_history , $last_tag ); |
999 | 951 | |
1000 | | - // A cell could contain both parameters and data |
1001 | | - $cellData = explode ( '|' , $cell , 2 ); |
| 952 | + # A cell could contain both parameters and data |
| 953 | + $cell_data = explode( '|' , $cell , 2 ); |
1002 | 954 | |
1003 | | - // Bug 553: Note that a '|' inside an invalid link should not |
1004 | | - // be mistaken as delimiting cell parameters |
1005 | | - if ( strpos( $cellData[0], '[[' ) !== false ) { |
1006 | | - $content = trim ( $cell ); |
1007 | | - } |
1008 | | - elseif ( count ( $cellData ) == 1 ) { |
1009 | | - $content = trim ( $cellData[0] ); |
1010 | | - } else { |
1011 | | - $attributes = $this->mStripState->unstripBoth( $cellData[0] ); |
1012 | | - $attributes = Sanitizer::fixTagAttributes( $attributes , $tagName ); |
| 955 | + # Bug 553: Note that a '|' inside an invalid link should not |
| 956 | + # be mistaken as delimiting cell parameters |
| 957 | + if ( strpos( $cell_data[0], '[[' ) !== false ) { |
| 958 | + $cell = "{$previous}<{$last_tag}>{$cell}"; |
| 959 | + } elseif ( count( $cell_data ) == 1 ) { |
| 960 | + $cell = "{$previous}<{$last_tag}>{$cell_data[0]}"; |
| 961 | + } else { |
| 962 | + $attributes = $this->mStripState->unstripBoth( $cell_data[0] ); |
| 963 | + $attributes = Sanitizer::fixTagAttributes( $attributes , $last_tag ); |
| 964 | + $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}"; |
| 965 | + } |
1013 | 966 | |
1014 | | - $content = trim ( $cellData[1] ); |
| 967 | + $outLine .= $cell; |
| 968 | + array_push( $td_history , true ); |
| 969 | + } |
| 970 | + } |
| 971 | + $out .= $outLine . "\n"; |
1015 | 972 | } |
1016 | | - return array( $content, $attributes ); |
1017 | | - } |
1018 | 973 | |
1019 | | - |
1020 | | - /** |
1021 | | - * Helper function for doTableStuff(). This converts the structured array into html. |
1022 | | - * |
1023 | | - * @private |
1024 | | - */ |
1025 | | - function generateTableHTML( &$table ) { |
1026 | | - $return = ""; |
1027 | | - $return .= str_repeat( '<dl><dd>' , $table['indent'] ); |
1028 | | - $return .= '<table'; |
1029 | | - $return .= isset( $table['attributes'] ) ? $table['attributes'] : ''; |
1030 | | - $return .= '>'; |
1031 | | - unset( $table['attributes'] ); |
1032 | | - |
1033 | | - if ( isset( $table['caption'] ) ) { |
1034 | | - $return .= "\n<caption"; |
1035 | | - $return .= isset( $table['caption']['attributes'] ) ? $table['caption']['attributes'] : ''; |
1036 | | - $return .= '>'; |
1037 | | - $return .= $table['caption']['content']; |
1038 | | - $return .= "\n</caption>"; |
1039 | | - } |
1040 | | - $lastSection = ''; |
1041 | | - $empty = true; |
1042 | | - $simple = true; |
1043 | | - |
1044 | | - // If we only have tbodies, mark table as simple |
1045 | | - for ( $i = 0; isset( $table[$i] ); $i++ ) { |
1046 | | - if ( !count( $table[$i] ) ) continue; |
1047 | | - if ( !isset( $table[$i]['type'] ) ) { |
1048 | | - $table[$i]['type'] = 'tbody'; |
| 974 | + # Closing open td, tr && table |
| 975 | + while ( count( $td_history ) > 0 ) { |
| 976 | + if ( array_pop( $td_history ) ) { |
| 977 | + $out .= "</td>\n"; |
1049 | 978 | } |
1050 | | - if ( !$lastSection ) { |
1051 | | - $lastSection = $table[$i]['type']; |
1052 | | - } elseif ( $lastSection != $table[$i]['type'] ) { |
1053 | | - $simple = false; |
| 979 | + if ( array_pop( $tr_history ) ) { |
| 980 | + $out .= "</tr>\n"; |
1054 | 981 | } |
1055 | | - } |
1056 | | - $lastSection = ''; |
1057 | | - for ( $i = 0; isset( $table[$i] ); $i++ ) { |
1058 | | - if ( !count( $table[$i] ) ) continue; |
1059 | | - $empty = false; // check for empty tables |
1060 | | - |
1061 | | - if ( $table[$i]['type'] != $lastSection && !$simple ) { |
1062 | | - $return .= "\n<" . $table[$i]['type'] . '>'; |
| 982 | + if ( !array_pop( $has_opened_tr ) ) { |
| 983 | + $out .= "<tr><td></td></tr>\n" ; |
1063 | 984 | } |
1064 | 985 | |
1065 | | - $return .= "\n<tr"; |
1066 | | - $return .= isset( $table[$i]['attributes'] ) ? $table[$i]['attributes'] : ''; |
1067 | | - $return .= '>'; |
1068 | | - for ( $j = 0; isset( $table[$i][$j] ); $j++ ) { |
1069 | | - if ( !isset( $table[$i][$j]['type'] ) ) $table[$i][$j]['type'] = 'td'; |
1070 | | - $return .= "\n<" . $table[$i][$j]['type']; |
1071 | | - $return .= isset( $table[$i][$j]['attributes'] ) ? $table[$i][$j]['attributes'] : ''; |
1072 | | - $return .= '>'; |
| 986 | + $out .= "</table>\n"; |
| 987 | + } |
1073 | 988 | |
1074 | | - $return .= $table[$i][$j]['content']; |
1075 | | - if ( $table[$i][$j]['content'] != '' ) |
1076 | | - $return .= "\n"; |
| 989 | + # Remove trailing line-ending (b/c) |
| 990 | + if ( substr( $out, -1 ) === "\n" ) { |
| 991 | + $out = substr( $out, 0, -1 ); |
| 992 | + } |
1077 | 993 | |
1078 | | - $return .= '</' . $table[$i][$j]['type'] . '>'; |
1079 | | - unset( $table[$i][$j] ); |
1080 | | - } |
1081 | | - $return .= "\n</tr>"; |
1082 | | - |
1083 | | - if ( ( !isset( $table[$i + 1] ) && !$simple ) || ( isset( $table[$i + 1] ) && isset( $table[$i + 1]['type'] ) && $table[$i]['type'] != $table[$i + 1]['type'] ) ) { |
1084 | | - $return .= '</' . $table[$i]['type'] . '>'; |
1085 | | - } |
1086 | | - $lastSection = $table[$i]['type']; |
1087 | | - unset( $table[$i] ); |
| 994 | + # special case: don't return empty table |
| 995 | + if ( $out === "<table>\n<tr><td></td></tr>\n</table>" ) { |
| 996 | + $out = ''; |
1088 | 997 | } |
1089 | | - if ( $empty ) { |
1090 | | - if ( isset( $table['caption'] ) ) { |
1091 | | - $return .= "\n<tr><td></td></tr>"; |
1092 | | - } else { |
1093 | | - return ''; |
1094 | | - } |
1095 | | - } |
1096 | | - $return .= "\n</table>"; |
1097 | | - $return .= str_repeat( '</dd></dl>' , $table['indent'] ); |
1098 | 998 | |
1099 | | - return $return; |
1100 | | - } |
| 999 | + wfProfileOut( __METHOD__ ); |
1101 | 1000 | |
1102 | | - /** |
1103 | | - * like end() but only works on the numeric array index and php's internal pointers |
1104 | | - * returns a reference to the last element of an array much like "\$arr[-1]" in perl |
1105 | | - * ignores associative elements and will create a 0 key will a NULL value if there were |
1106 | | - * no numric elements and an array itself if not previously defined. |
1107 | | - * |
1108 | | - * @private |
1109 | | - */ |
1110 | | - function &last ( &$arr ) { |
1111 | | - for ( $i = count( $arr ); ( !isset( $arr[$i] ) && $i > 0 ); $i-- ) { } |
1112 | | - return $arr[$i]; |
| 1001 | + return $out; |
1113 | 1002 | } |
1114 | 1003 | |
1115 | 1004 | /** |
Index: branches/REL1_18/phase3/includes/Sanitizer.php |
— | — | @@ -371,7 +371,7 @@ |
372 | 372 | 'strike', 'strong', 'tt', 'var', 'div', 'center', |
373 | 373 | 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre', |
374 | 374 | 'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'abbr', 'dfn', |
375 | | - 'kbd', 'samp', 'thead', 'tbody', 'tfoot' |
| 375 | + 'kbd', 'samp' |
376 | 376 | ); |
377 | 377 | $htmlsingle = array( |
378 | 378 | 'br', 'hr', 'li', 'dt', 'dd' |
Index: branches/REL1_18/phase3/resources/jquery/jquery.tablesorter.js |
— | — | @@ -217,6 +217,26 @@ |
218 | 218 | } |
219 | 219 | table.tBodies[0].appendChild( fragment ); |
220 | 220 | } |
| 221 | + |
| 222 | + /** |
| 223 | + * Find all header rows in a thead-less table and put them in a <thead> tag. |
| 224 | + * This only treats a row as a header row if it contains only <th>s (no <td>s) |
| 225 | + * and if it is preceded entirely by header rows. The algorithm stops when |
| 226 | + * it encounters the first non-header row. |
| 227 | + * @param $table jQuery object for a <table> |
| 228 | + */ |
| 229 | + function emulateTHead( $table ) { |
| 230 | + var $thead = $( '<thead>' ); |
| 231 | + $table.find( 'tr' ).each( function() { |
| 232 | + if ( $(this).children( 'td' ).length > 0 ) { |
| 233 | + // This row contains a <td>, so it's not a header row |
| 234 | + // Stop here |
| 235 | + return false; |
| 236 | + } |
| 237 | + $thead.append( this ); |
| 238 | + } ); |
| 239 | + $table.prepend( $thead ); |
| 240 | + } |
221 | 241 | |
222 | 242 | function buildHeaders( table, msg ) { |
223 | 243 | var maxSeen = 0, |
— | — | @@ -499,17 +519,27 @@ |
500 | 520 | */ |
501 | 521 | construct: function( $tables, settings ) { |
502 | 522 | return $tables.each( function( i, table ) { |
503 | | - |
504 | | - // Quit if no thead or tbody. |
505 | | - if ( !table.tHead || !table.tBodies ) { |
506 | | - return; |
507 | | - } |
508 | 523 | // Declare and cache. |
509 | 524 | var $document, $headers, cache, config, sortOrder, |
510 | 525 | $table = $( table ), |
511 | 526 | shiftDown = 0, |
512 | 527 | firstTime = true; |
513 | 528 | |
| 529 | + // Quit if no tbody |
| 530 | + if ( !table.tBodies ) { |
| 531 | + return; |
| 532 | + } |
| 533 | + if ( !table.tHead ) { |
| 534 | + // No thead found. Look for rows with <th>s and |
| 535 | + // move them into a <thead> tag |
| 536 | + emulateTHead( $table ); |
| 537 | + |
| 538 | + // Still no thead? Then quit |
| 539 | + if ( !table.tHead ) { |
| 540 | + return; |
| 541 | + } |
| 542 | + } |
| 543 | + |
514 | 544 | // New config object. |
515 | 545 | table.config = {}; |
516 | 546 | |
— | — | @@ -544,9 +574,11 @@ |
545 | 575 | |
546 | 576 | // Legacy fix of .sortbottoms |
547 | 577 | // Wrap them inside inside a tfoot (because that's what they actually want to be) & |
548 | | - // Move them up one level in the DOM |
549 | | - var sortbottoms = $table.find('tr.sortbottom').wrap('<tfoot>'); |
550 | | - sortbottoms.parents('table').append(sortbottoms.parent()); |
| 578 | + // and put the <tfoot> at the end of the <table> |
| 579 | + var $sortbottoms = $table.find( 'tr.sortbottom' ); |
| 580 | + if ( $sortbottoms.length ) { |
| 581 | + $table.append( $( '<tfoot>' ).append( $sortbottoms ) ) |
| 582 | + } |
551 | 583 | |
552 | 584 | explodeRowspans( $table ); |
553 | 585 | // try to auto detect column type, and store in tables config |