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 |