| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * Copyright (C) 2011 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 m_tree.setForm(closestFormAncestor(*contextElement)); | 311 m_tree.setForm(closestFormAncestor(*contextElement)); |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 | 314 |
| 315 HTMLTreeBuilder::~HTMLTreeBuilder() | 315 HTMLTreeBuilder::~HTMLTreeBuilder() |
| 316 { | 316 { |
| 317 } | 317 } |
| 318 | 318 |
| 319 void HTMLTreeBuilder::trace(Visitor* visitor) | 319 void HTMLTreeBuilder::trace(Visitor* visitor) |
| 320 { | 320 { |
| 321 visitor->trace(m_fragmentContext); |
| 321 visitor->trace(m_tree); | 322 visitor->trace(m_tree); |
| 322 visitor->trace(m_parser); | 323 visitor->trace(m_parser); |
| 323 visitor->trace(m_scriptToProcess); | 324 visitor->trace(m_scriptToProcess); |
| 324 } | 325 } |
| 325 | 326 |
| 326 void HTMLTreeBuilder::detach() | 327 void HTMLTreeBuilder::detach() |
| 327 { | 328 { |
| 328 #ifndef NDEBUG | 329 #ifndef NDEBUG |
| 329 // This call makes little sense in fragment mode, but for consistency | 330 // This call makes little sense in fragment mode, but for consistency |
| 330 // DocumentParser expects detach() to always be called before it's destroyed
. | 331 // DocumentParser expects detach() to always be called before it's destroyed
. |
| 331 m_isAttached = false; | 332 m_isAttached = false; |
| 332 #endif | 333 #endif |
| 333 // HTMLConstructionSite might be on the callstack when detach() is called | 334 // HTMLConstructionSite might be on the callstack when detach() is called |
| 334 // otherwise we'd just call m_tree.clear() here instead. | 335 // otherwise we'd just call m_tree.clear() here instead. |
| 335 m_tree.detach(); | 336 m_tree.detach(); |
| 336 } | 337 } |
| 337 | 338 |
| 338 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() | 339 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() |
| 339 : m_fragment(0) | 340 : m_fragment(nullptr) |
| 340 { | 341 { |
| 341 } | 342 } |
| 342 | 343 |
| 343 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) | 344 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) |
| 344 : m_fragment(fragment) | 345 : m_fragment(fragment) |
| 345 { | 346 { |
| 346 ASSERT(!fragment->hasChildren()); | 347 ASSERT(!fragment->hasChildren()); |
| 347 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); | 348 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); |
| 348 } | 349 } |
| 349 | 350 |
| 350 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() | 351 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() |
| 351 { | 352 { |
| 352 } | 353 } |
| 353 | 354 |
| 355 void HTMLTreeBuilder::FragmentParsingContext::trace(Visitor* visitor) |
| 356 { |
| 357 visitor->trace(m_fragment); |
| 358 visitor->trace(m_contextElementStackItem); |
| 359 } |
| 360 |
| 354 PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPositio
n& scriptStartPosition) | 361 PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPositio
n& scriptStartPosition) |
| 355 { | 362 { |
| 356 ASSERT(m_scriptToProcess); | 363 ASSERT(m_scriptToProcess); |
| 357 ASSERT(!m_tree.hasPendingTasks()); | 364 ASSERT(!m_tree.hasPendingTasks()); |
| 358 // Unpause ourselves, callers may pause us again when processing the script. | 365 // Unpause ourselves, callers may pause us again when processing the script. |
| 359 // The HTML5 spec is written as though scripts are executed inside the tree | 366 // The HTML5 spec is written as though scripts are executed inside the tree |
| 360 // builder. We pause the parser to exit the tree builder, and then resume | 367 // builder. We pause the parser to exit the tree builder, and then resume |
| 361 // before running scripts. | 368 // before running scripts. |
| 362 scriptStartPosition = m_scriptToProcessStartPosition; | 369 scriptStartPosition = m_scriptToProcessStartPosition; |
| 363 m_scriptToProcessStartPosition = uninitializedPositionValue1(); | 370 m_scriptToProcessStartPosition = uninitializedPositionValue1(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 } | 487 } |
| 481 | 488 |
| 482 } | 489 } |
| 483 | 490 |
| 484 template <bool shouldClose(const HTMLStackItem*)> | 491 template <bool shouldClose(const HTMLStackItem*)> |
| 485 void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token) | 492 void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token) |
| 486 { | 493 { |
| 487 m_framesetOk = false; | 494 m_framesetOk = false; |
| 488 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); | 495 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); |
| 489 while (1) { | 496 while (1) { |
| 490 RefPtr<HTMLStackItem> item = nodeRecord->stackItem(); | 497 RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem(); |
| 491 if (shouldClose(item.get())) { | 498 if (shouldClose(item.get())) { |
| 492 ASSERT(item->isElementNode()); | 499 ASSERT(item->isElementNode()); |
| 493 processFakeEndTag(item->localName()); | 500 processFakeEndTag(item->localName()); |
| 494 break; | 501 break; |
| 495 } | 502 } |
| 496 if (item->isSpecialNode() && !item->hasTagName(addressTag) && !item->has
TagName(divTag) && !item->hasTagName(pTag)) | 503 if (item->isSpecialNode() && !item->hasTagName(addressTag) && !item->has
TagName(divTag) && !item->hasTagName(pTag)) |
| 497 break; | 504 break; |
| 498 nodeRecord = nodeRecord->next(); | 505 nodeRecord = nodeRecord->next(); |
| 499 } | 506 } |
| 500 processFakePEndTagIfPInButtonScope(); | 507 processFakePEndTagIfPInButtonScope(); |
| (...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 notImplemented(); // Emit a more specific parse error based on stack content
s. | 1448 notImplemented(); // Emit a more specific parse error based on stack content
s. |
| 1442 setInsertionMode(AfterBodyMode); | 1449 setInsertionMode(AfterBodyMode); |
| 1443 return true; | 1450 return true; |
| 1444 } | 1451 } |
| 1445 | 1452 |
| 1446 void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token) | 1453 void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token) |
| 1447 { | 1454 { |
| 1448 ASSERT(token->type() == HTMLToken::EndTag); | 1455 ASSERT(token->type() == HTMLToken::EndTag); |
| 1449 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord()
; | 1456 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord()
; |
| 1450 while (1) { | 1457 while (1) { |
| 1451 RefPtr<HTMLStackItem> item = record->stackItem(); | 1458 RefPtrWillBeRawPtr<HTMLStackItem> item = record->stackItem(); |
| 1452 if (item->matchesHTMLTag(token->name())) { | 1459 if (item->matchesHTMLTag(token->name())) { |
| 1453 m_tree.generateImpliedEndTagsWithExclusion(token->name()); | 1460 m_tree.generateImpliedEndTagsWithExclusion(token->name()); |
| 1454 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) | 1461 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) |
| 1455 parseError(token); | 1462 parseError(token); |
| 1456 m_tree.openElements()->popUntilPopped(item->element()); | 1463 m_tree.openElements()->popUntilPopped(item->element()); |
| 1457 return; | 1464 return; |
| 1458 } | 1465 } |
| 1459 if (item->isSpecialNode()) { | 1466 if (item->isSpecialNode()) { |
| 1460 parseError(token); | 1467 parseError(token); |
| 1461 return; | 1468 return; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 // 5. | 1507 // 5. |
| 1501 HTMLElementStack::ElementRecord* furthestBlock = m_tree.openElements()->
furthestBlockForFormattingElement(formattingElement); | 1508 HTMLElementStack::ElementRecord* furthestBlock = m_tree.openElements()->
furthestBlockForFormattingElement(formattingElement); |
| 1502 // 6. | 1509 // 6. |
| 1503 if (!furthestBlock) { | 1510 if (!furthestBlock) { |
| 1504 m_tree.openElements()->popUntilPopped(formattingElement); | 1511 m_tree.openElements()->popUntilPopped(formattingElement); |
| 1505 m_tree.activeFormattingElements()->remove(formattingElement); | 1512 m_tree.activeFormattingElements()->remove(formattingElement); |
| 1506 return; | 1513 return; |
| 1507 } | 1514 } |
| 1508 // 7. | 1515 // 7. |
| 1509 ASSERT(furthestBlock->isAbove(formattingElementRecord)); | 1516 ASSERT(furthestBlock->isAbove(formattingElementRecord)); |
| 1510 RefPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->
stackItem(); | 1517 RefPtrWillBeRawPtr<HTMLStackItem> commonAncestor = formattingElementReco
rd->next()->stackItem(); |
| 1511 // 8. | 1518 // 8. |
| 1512 HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingEl
ements()->bookmarkFor(formattingElement); | 1519 HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingEl
ements()->bookmarkFor(formattingElement); |
| 1513 // 9. | 1520 // 9. |
| 1514 HTMLElementStack::ElementRecord* node = furthestBlock; | 1521 HTMLElementStack::ElementRecord* node = furthestBlock; |
| 1515 HTMLElementStack::ElementRecord* nextNode = node->next(); | 1522 HTMLElementStack::ElementRecord* nextNode = node->next(); |
| 1516 HTMLElementStack::ElementRecord* lastNode = furthestBlock; | 1523 HTMLElementStack::ElementRecord* lastNode = furthestBlock; |
| 1517 // 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop. | 1524 // 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop. |
| 1518 for (int i = 0; i < innerIterationLimit; ++i) { | 1525 for (int i = 0; i < innerIterationLimit; ++i) { |
| 1519 // 9.4 | 1526 // 9.4 |
| 1520 node = nextNode; | 1527 node = nextNode; |
| 1521 ASSERT(node); | 1528 ASSERT(node); |
| 1522 nextNode = node->next(); // Save node->next() for the next iteration
in case node is deleted in 9.5. | 1529 nextNode = node->next(); // Save node->next() for the next iteration
in case node is deleted in 9.5. |
| 1523 // 9.5 | 1530 // 9.5 |
| 1524 if (!m_tree.activeFormattingElements()->contains(node->element())) { | 1531 if (!m_tree.activeFormattingElements()->contains(node->element())) { |
| 1525 m_tree.openElements()->remove(node->element()); | 1532 m_tree.openElements()->remove(node->element()); |
| 1526 node = 0; | 1533 node = 0; |
| 1527 continue; | 1534 continue; |
| 1528 } | 1535 } |
| 1529 // 9.6 | 1536 // 9.6 |
| 1530 if (node == formattingElementRecord) | 1537 if (node == formattingElementRecord) |
| 1531 break; | 1538 break; |
| 1532 // 9.7 | 1539 // 9.7 |
| 1533 RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(n
ode->stackItem().get()); | 1540 RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFrom
SavedToken(node->stackItem().get()); |
| 1534 | 1541 |
| 1535 HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattin
gElements()->find(node->element()); | 1542 HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattin
gElements()->find(node->element()); |
| 1536 nodeEntry->replaceElement(newItem); | 1543 nodeEntry->replaceElement(newItem); |
| 1537 node->replaceElement(newItem.release()); | 1544 node->replaceElement(newItem.release()); |
| 1538 | 1545 |
| 1539 // 9.8 | 1546 // 9.8 |
| 1540 if (lastNode == furthestBlock) | 1547 if (lastNode == furthestBlock) |
| 1541 bookmark.moveToAfter(nodeEntry); | 1548 bookmark.moveToAfter(nodeEntry); |
| 1542 // 9.9 | 1549 // 9.9 |
| 1543 m_tree.reparent(node, lastNode); | 1550 m_tree.reparent(node, lastNode); |
| 1544 // 9.10 | 1551 // 9.10 |
| 1545 lastNode = node; | 1552 lastNode = node; |
| 1546 } | 1553 } |
| 1547 // 10. | 1554 // 10. |
| 1548 m_tree.insertAlreadyParsedChild(commonAncestor.get(), lastNode); | 1555 m_tree.insertAlreadyParsedChild(commonAncestor.get(), lastNode); |
| 1549 // 11. | 1556 // 11. |
| 1550 RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(forma
ttingElementRecord->stackItem().get()); | 1557 RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFromSave
dToken(formattingElementRecord->stackItem().get()); |
| 1551 // 12. | 1558 // 12. |
| 1552 m_tree.takeAllChildren(newItem.get(), furthestBlock); | 1559 m_tree.takeAllChildren(newItem.get(), furthestBlock); |
| 1553 // 13. | 1560 // 13. |
| 1554 m_tree.reparent(furthestBlock, newItem.get()); | 1561 m_tree.reparent(furthestBlock, newItem.get()); |
| 1555 // 14. | 1562 // 14. |
| 1556 m_tree.activeFormattingElements()->swapTo(formattingElement, newItem, bo
okmark); | 1563 m_tree.activeFormattingElements()->swapTo(formattingElement, newItem, bo
okmark); |
| 1557 // 15. | 1564 // 15. |
| 1558 m_tree.openElements()->remove(formattingElement); | 1565 m_tree.openElements()->remove(formattingElement); |
| 1559 m_tree.openElements()->insertAbove(newItem, furthestBlock); | 1566 m_tree.openElements()->insertAbove(newItem, furthestBlock); |
| 1560 } | 1567 } |
| 1561 } | 1568 } |
| 1562 | 1569 |
| 1563 void HTMLTreeBuilder::resetInsertionModeAppropriately() | 1570 void HTMLTreeBuilder::resetInsertionModeAppropriately() |
| 1564 { | 1571 { |
| 1565 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#
reset-the-insertion-mode-appropriately | 1572 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#
reset-the-insertion-mode-appropriately |
| 1566 bool last = false; | 1573 bool last = false; |
| 1567 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); | 1574 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); |
| 1568 while (1) { | 1575 while (1) { |
| 1569 RefPtr<HTMLStackItem> item = nodeRecord->stackItem(); | 1576 RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem(); |
| 1570 if (item->node() == m_tree.openElements()->rootNode()) { | 1577 if (item->node() == m_tree.openElements()->rootNode()) { |
| 1571 last = true; | 1578 last = true; |
| 1572 if (isParsingFragment()) | 1579 if (isParsingFragment()) |
| 1573 item = m_fragmentContext.contextElementStackItem(); | 1580 item = m_fragmentContext.contextElementStackItem(); |
| 1574 } | 1581 } |
| 1575 if (item->hasTagName(templateTag)) | 1582 if (item->hasTagName(templateTag)) |
| 1576 return setInsertionMode(m_templateInsertionModes.last()); | 1583 return setInsertionMode(m_templateInsertionModes.last()); |
| 1577 if (item->hasTagName(selectTag)) { | 1584 if (item->hasTagName(selectTag)) { |
| 1578 if (!last) { | 1585 if (!last) { |
| 1579 while (item->node() != m_tree.openElements()->rootNode() && !ite
m->hasTagName(templateTag)) { | 1586 while (item->node() != m_tree.openElements()->rootNode() && !ite
m->hasTagName(templateTag)) { |
| (...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 ASSERT(m_isAttached); | 2796 ASSERT(m_isAttached); |
| 2790 // Warning, this may detach the parser. Do not do anything else after this. | 2797 // Warning, this may detach the parser. Do not do anything else after this. |
| 2791 m_tree.finishedParsing(); | 2798 m_tree.finishedParsing(); |
| 2792 } | 2799 } |
| 2793 | 2800 |
| 2794 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) | 2801 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) |
| 2795 { | 2802 { |
| 2796 } | 2803 } |
| 2797 | 2804 |
| 2798 } // namespace WebCore | 2805 } // namespace WebCore |
| OLD | NEW |