Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. |
| 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. |
| 4 * Copyright (C) 2011 Igalia S.L. | 4 * Copyright (C) 2011 Igalia S.L. |
| 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
| 6 * | 6 * |
| 7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
| 8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 changes.append(AttributeChange(&element, attribute.name(), KURL( parsedBaseURL, attribute.value()).getString())); | 120 changes.append(AttributeChange(&element, attribute.name(), KURL( parsedBaseURL, attribute.value()).getString())); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 for (auto& change : changes) | 124 for (auto& change : changes) |
| 125 change.apply(); | 125 change.apply(); |
| 126 } | 126 } |
| 127 | 127 |
| 128 static bool isHTMLBlockElement(const Node* node) | 128 static bool isHTMLBlockElement(const Node* node) |
| 129 { | 129 { |
| 130 ASSERT(node); | 130 DCHECK(node); |
| 131 return isHTMLTableCellElement(*node) | 131 return isHTMLTableCellElement(*node) |
| 132 || isNonTableCellHTMLBlockElement(node); | 132 || isNonTableCellHTMLBlockElement(node); |
| 133 } | 133 } |
| 134 | 134 |
| 135 static HTMLElement* ancestorToRetainStructureAndAppearanceForBlock(Element* comm onAncestorBlock) | 135 static HTMLElement* ancestorToRetainStructureAndAppearanceForBlock(Element* comm onAncestorBlock) |
| 136 { | 136 { |
| 137 if (!commonAncestorBlock) | 137 if (!commonAncestorBlock) |
| 138 return 0; | 138 return 0; |
| 139 | 139 |
| 140 if (commonAncestorBlock->hasTagName(tbodyTag) || isHTMLTableRowElement(*comm onAncestorBlock)) | 140 if (commonAncestorBlock->hasTagName(tbodyTag) || isHTMLTableRowElement(*comm onAncestorBlock)) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 || element.hasTagName(iTag) || element.hasTagName(emTag) || element.hasT agName(bTag) || element.hasTagName(strongTag); | 179 || element.hasTagName(iTag) || element.hasTagName(emTag) || element.hasT agName(bTag) || element.hasTagName(strongTag); |
| 180 } | 180 } |
| 181 | 181 |
| 182 template<typename Strategy> | 182 template<typename Strategy> |
| 183 static HTMLElement* highestAncestorToWrapMarkup(const PositionTemplate<Strategy> & startPosition, const PositionTemplate<Strategy>& endPosition, EAnnotateForInte rchange shouldAnnotate, Node* constrainingAncestor) | 183 static HTMLElement* highestAncestorToWrapMarkup(const PositionTemplate<Strategy> & startPosition, const PositionTemplate<Strategy>& endPosition, EAnnotateForInte rchange shouldAnnotate, Node* constrainingAncestor) |
| 184 { | 184 { |
| 185 Node* firstNode = startPosition.nodeAsRangeFirstNode(); | 185 Node* firstNode = startPosition.nodeAsRangeFirstNode(); |
| 186 // For compatibility reason, we use container node of start and end | 186 // For compatibility reason, we use container node of start and end |
| 187 // positions rather than first node and last node in selection. | 187 // positions rather than first node and last node in selection. |
| 188 Node* commonAncestor = Strategy::commonAncestor(*startPosition.computeContai nerNode(), *endPosition.computeContainerNode()); | 188 Node* commonAncestor = Strategy::commonAncestor(*startPosition.computeContai nerNode(), *endPosition.computeContainerNode()); |
| 189 ASSERT(commonAncestor); | 189 DCHECK(commonAncestor); |
| 190 HTMLElement* specialCommonAncestor = nullptr; | 190 HTMLElement* specialCommonAncestor = nullptr; |
| 191 if (shouldAnnotate == AnnotateForInterchange) { | 191 if (shouldAnnotate == AnnotateForInterchange) { |
| 192 // Include ancestors that aren't completely inside the range but are req uired to retain | 192 // Include ancestors that aren't completely inside the range but are req uired to retain |
| 193 // the structure and appearance of the copied markup. | 193 // the structure and appearance of the copied markup. |
| 194 specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAnc estor); | 194 specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAnc estor); |
| 195 if (Node* parentListNode = enclosingNodeOfType(firstPositionInOrBeforeNo de(firstNode), isListItem)) { | 195 if (Node* parentListNode = enclosingNodeOfType(firstPositionInOrBeforeNo de(firstNode), isListItem)) { |
| 196 EphemeralRangeTemplate<Strategy> markupRange = EphemeralRangeTemplat e<Strategy>(startPosition, endPosition); | 196 EphemeralRangeTemplate<Strategy> markupRange = EphemeralRangeTemplat e<Strategy>(startPosition, endPosition); |
| 197 EphemeralRangeTemplate<Strategy> nodeRange = normalizeRange(Ephemera lRangeTemplate<Strategy>::rangeOfContents(*parentListNode)); | 197 EphemeralRangeTemplate<Strategy> nodeRange = normalizeRange(Ephemera lRangeTemplate<Strategy>::rangeOfContents(*parentListNode)); |
| 198 if (nodeRange == markupRange) { | 198 if (nodeRange == markupRange) { |
| 199 ContainerNode* ancestor = parentListNode->parentNode(); | 199 ContainerNode* ancestor = parentListNode->parentNode(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 | 305 |
| 306 static void trimFragment(DocumentFragment* fragment, Comment* nodeBeforeContext, Comment* nodeAfterContext) | 306 static void trimFragment(DocumentFragment* fragment, Comment* nodeBeforeContext, Comment* nodeAfterContext) |
| 307 { | 307 { |
| 308 Node* next = nullptr; | 308 Node* next = nullptr; |
| 309 for (Node* node = fragment->firstChild(); node; node = next) { | 309 for (Node* node = fragment->firstChild(); node; node = next) { |
| 310 if (nodeBeforeContext->isDescendantOf(node)) { | 310 if (nodeBeforeContext->isDescendantOf(node)) { |
| 311 next = NodeTraversal::next(*node); | 311 next = NodeTraversal::next(*node); |
| 312 continue; | 312 continue; |
| 313 } | 313 } |
| 314 next = NodeTraversal::nextSkippingChildren(*node); | 314 next = NodeTraversal::nextSkippingChildren(*node); |
| 315 ASSERT(!node->contains(nodeAfterContext)); | 315 DCHECK(!node->contains(nodeAfterContext)); |
|
yosin_UTC9
2016/04/14 04:35:04
How about adding |<< node << ' ' << nodeAfterConte
| |
| 316 node->parentNode()->removeChild(node, ASSERT_NO_EXCEPTION); | 316 node->parentNode()->removeChild(node, ASSERT_NO_EXCEPTION); |
| 317 if (nodeBeforeContext == node) | 317 if (nodeBeforeContext == node) |
| 318 break; | 318 break; |
| 319 } | 319 } |
| 320 | 320 |
| 321 ASSERT(nodeAfterContext->parentNode()); | 321 DCHECK(nodeAfterContext->parentNode()); |
|
yosin_UTC9
2016/04/14 04:35:04
How about adding |<< nodeAfterContext|?
| |
| 322 for (Node* node = nodeAfterContext; node; node = next) { | 322 for (Node* node = nodeAfterContext; node; node = next) { |
| 323 next = NodeTraversal::nextSkippingChildren(*node); | 323 next = NodeTraversal::nextSkippingChildren(*node); |
| 324 node->parentNode()->removeChild(node, ASSERT_NO_EXCEPTION); | 324 node->parentNode()->removeChild(node, ASSERT_NO_EXCEPTION); |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 DocumentFragment* createFragmentFromMarkupWithContext(Document& document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, | 328 DocumentFragment* createFragmentFromMarkupWithContext(Document& document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, |
| 329 const String& baseURL, ParserContentPolicy parserContentPolicy) | 329 const String& baseURL, ParserContentPolicy parserContentPolicy) |
| 330 { | 330 { |
| 331 // FIXME: Need to handle the case where the markup already contains these ma rkers. | 331 // FIXME: Need to handle the case where the markup already contains these ma rkers. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 | 383 |
| 384 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng) | 384 static void fillContainerFromString(ContainerNode* paragraph, const String& stri ng) |
| 385 { | 385 { |
| 386 Document& document = paragraph->document(); | 386 Document& document = paragraph->document(); |
| 387 | 387 |
| 388 if (string.isEmpty()) { | 388 if (string.isEmpty()) { |
| 389 paragraph->appendChild(HTMLBRElement::create(document)); | 389 paragraph->appendChild(HTMLBRElement::create(document)); |
| 390 return; | 390 return; |
| 391 } | 391 } |
| 392 | 392 |
| 393 ASSERT(string.find('\n') == kNotFound); | 393 DCHECK_EQ(string.find('\n'), kNotFound); |
|
yosin_UTC9
2016/04/14 04:35:04
How about adding |<< string|?
| |
| 394 | 394 |
| 395 Vector<String> tabList; | 395 Vector<String> tabList; |
| 396 string.split('\t', true, tabList); | 396 string.split('\t', true, tabList); |
| 397 StringBuilder tabText; | 397 StringBuilder tabText; |
| 398 bool first = true; | 398 bool first = true; |
| 399 size_t numEntries = tabList.size(); | 399 size_t numEntries = tabList.size(); |
| 400 for (size_t i = 0; i < numEntries; ++i) { | 400 for (size_t i = 0; i < numEntries; ++i) { |
| 401 const String& s = tabList[i]; | 401 const String& s = tabList[i]; |
| 402 | 402 |
| 403 // append the non-tab textual part | 403 // append the non-tab textual part |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 416 tabText.append('\t'); | 416 tabText.append('\t'); |
| 417 else if (!tabText.isEmpty()) | 417 else if (!tabText.isEmpty()) |
| 418 paragraph->appendChild(createTabSpanElement(document, tabText.toStri ng())); | 418 paragraph->appendChild(createTabSpanElement(document, tabText.toStri ng())); |
| 419 | 419 |
| 420 first = false; | 420 first = false; |
| 421 } | 421 } |
| 422 } | 422 } |
| 423 | 423 |
| 424 bool isPlainTextMarkup(Node* node) | 424 bool isPlainTextMarkup(Node* node) |
| 425 { | 425 { |
| 426 ASSERT(node); | 426 DCHECK(node); |
| 427 if (!isHTMLDivElement(*node)) | 427 if (!isHTMLDivElement(*node)) |
| 428 return false; | 428 return false; |
| 429 | 429 |
| 430 HTMLDivElement& element = toHTMLDivElement(*node); | 430 HTMLDivElement& element = toHTMLDivElement(*node); |
| 431 if (!element.hasAttributes()) | 431 if (!element.hasAttributes()) |
| 432 return false; | 432 return false; |
| 433 | 433 |
| 434 if (element.hasOneChild()) | 434 if (element.hasOneChild()) |
| 435 return element.firstChild()->isTextNode() || element.firstChild()->hasCh ildren(); | 435 return element.firstChild()->isTextNode() || element.firstChild()->hasCh ildren(); |
| 436 | 436 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 element = createDefaultParagraphElement(document); | 508 element = createDefaultParagraphElement(document); |
| 509 fillContainerFromString(element, s); | 509 fillContainerFromString(element, s); |
| 510 } | 510 } |
| 511 fragment->appendChild(element); | 511 fragment->appendChild(element); |
| 512 } | 512 } |
| 513 return fragment; | 513 return fragment; |
| 514 } | 514 } |
| 515 | 515 |
| 516 DocumentFragment* createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, Ex ceptionState& exceptionState) | 516 DocumentFragment* createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, Ex ceptionState& exceptionState) |
| 517 { | 517 { |
| 518 ASSERT(contextElement); | 518 DCHECK(contextElement); |
| 519 Document& document = isHTMLTemplateElement(*contextElement) ? contextElement ->document().ensureTemplateDocument() : contextElement->document(); | 519 Document& document = isHTMLTemplateElement(*contextElement) ? contextElement ->document().ensureTemplateDocument() : contextElement->document(); |
| 520 DocumentFragment* fragment = DocumentFragment::create(document); | 520 DocumentFragment* fragment = DocumentFragment::create(document); |
| 521 | 521 |
| 522 if (document.isHTMLDocument()) { | 522 if (document.isHTMLDocument()) { |
| 523 fragment->parseHTML(markup, contextElement, parserContentPolicy); | 523 fragment->parseHTML(markup, contextElement, parserContentPolicy); |
| 524 return fragment; | 524 return fragment; |
| 525 } | 525 } |
| 526 | 526 |
| 527 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli cy); | 527 bool wasValid = fragment->parseXML(markup, contextElement, parserContentPoli cy); |
| 528 if (!wasValid) { | 528 if (!wasValid) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 for (Node* child = element->firstChild(); child; child = nextChild) { | 562 for (Node* child = element->firstChild(); child; child = nextChild) { |
| 563 nextChild = child->nextSibling(); | 563 nextChild = child->nextSibling(); |
| 564 element->removeChild(child); | 564 element->removeChild(child); |
| 565 fragment->insertBefore(child, element); | 565 fragment->insertBefore(child, element); |
| 566 } | 566 } |
| 567 fragment->removeChild(element); | 567 fragment->removeChild(element); |
| 568 } | 568 } |
| 569 | 569 |
| 570 static inline bool isSupportedContainer(Element* element) | 570 static inline bool isSupportedContainer(Element* element) |
| 571 { | 571 { |
| 572 ASSERT(element); | 572 DCHECK(element); |
| 573 if (!element->isHTMLElement()) | 573 if (!element->isHTMLElement()) |
| 574 return true; | 574 return true; |
| 575 | 575 |
| 576 HTMLElement& htmlElement = toHTMLElement(*element); | 576 HTMLElement& htmlElement = toHTMLElement(*element); |
| 577 if (htmlElement.hasTagName(colTag) || htmlElement.hasTagName(colgroupTag) || htmlElement.hasTagName(framesetTag) | 577 if (htmlElement.hasTagName(colTag) || htmlElement.hasTagName(colgroupTag) || htmlElement.hasTagName(framesetTag) |
| 578 || htmlElement.hasTagName(headTag) || htmlElement.hasTagName(styleTag) | | htmlElement.hasTagName(titleTag)) { | 578 || htmlElement.hasTagName(headTag) || htmlElement.hasTagName(styleTag) | | htmlElement.hasTagName(titleTag)) { |
| 579 return false; | 579 return false; |
| 580 } | 580 } |
| 581 return !htmlElement.ieForbidsInsertHTML(); | 581 return !htmlElement.ieForbidsInsertHTML(); |
| 582 } | 582 } |
| 583 | 583 |
| 584 DocumentFragment* createContextualFragment(const String& markup, Element* elemen t, ParserContentPolicy parserContentPolicy, ExceptionState& exceptionState) | 584 DocumentFragment* createContextualFragment(const String& markup, Element* elemen t, ParserContentPolicy parserContentPolicy, ExceptionState& exceptionState) |
| 585 { | 585 { |
| 586 ASSERT(element); | 586 DCHECK(element); |
| 587 if (!isSupportedContainer(element)) { | 587 if (!isSupportedContainer(element)) { |
| 588 exceptionState.throwDOMException(NotSupportedError, "The range's contain er is '" + element->localName() + "', which is not supported."); | 588 exceptionState.throwDOMException(NotSupportedError, "The range's contain er is '" + element->localName() + "', which is not supported."); |
| 589 return nullptr; | 589 return nullptr; |
| 590 } | 590 } |
| 591 | 591 |
| 592 DocumentFragment* fragment = createFragmentForInnerOuterHTML(markup, element , parserContentPolicy, "createContextualFragment", exceptionState); | 592 DocumentFragment* fragment = createFragmentForInnerOuterHTML(markup, element , parserContentPolicy, "createContextualFragment", exceptionState); |
| 593 if (!fragment) | 593 if (!fragment) |
| 594 return nullptr; | 594 return nullptr; |
| 595 | 595 |
| 596 // We need to pop <html> and <body> elements and remove <head> to | 596 // We need to pop <html> and <body> elements and remove <head> to |
| 597 // accommodate folks passing complete HTML documents to make the | 597 // accommodate folks passing complete HTML documents to make the |
| 598 // child of an element. | 598 // child of an element. |
| 599 | 599 |
| 600 Node* nextNode = nullptr; | 600 Node* nextNode = nullptr; |
| 601 for (Node* node = fragment->firstChild(); node; node = nextNode) { | 601 for (Node* node = fragment->firstChild(); node; node = nextNode) { |
| 602 nextNode = node->nextSibling(); | 602 nextNode = node->nextSibling(); |
| 603 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl ement(*node)) { | 603 if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyEl ement(*node)) { |
| 604 HTMLElement* element = toHTMLElement(node); | 604 HTMLElement* element = toHTMLElement(node); |
| 605 if (Node* firstChild = element->firstChild()) | 605 if (Node* firstChild = element->firstChild()) |
| 606 nextNode = firstChild; | 606 nextNode = firstChild; |
| 607 removeElementPreservingChildren(fragment, element); | 607 removeElementPreservingChildren(fragment, element); |
| 608 } | 608 } |
| 609 } | 609 } |
| 610 return fragment; | 610 return fragment; |
| 611 } | 611 } |
| 612 | 612 |
| 613 void replaceChildrenWithFragment(ContainerNode* container, DocumentFragment* fra gment, ExceptionState& exceptionState) | 613 void replaceChildrenWithFragment(ContainerNode* container, DocumentFragment* fra gment, ExceptionState& exceptionState) |
| 614 { | 614 { |
| 615 ASSERT(container); | 615 DCHECK(container); |
| 616 ContainerNode* containerNode(container); | 616 ContainerNode* containerNode(container); |
| 617 | 617 |
| 618 ChildListMutationScope mutation(*containerNode); | 618 ChildListMutationScope mutation(*containerNode); |
| 619 | 619 |
| 620 if (!fragment->firstChild()) { | 620 if (!fragment->firstChild()) { |
| 621 containerNode->removeChildren(); | 621 containerNode->removeChildren(); |
| 622 return; | 622 return; |
| 623 } | 623 } |
| 624 | 624 |
| 625 // FIXME: This is wrong if containerNode->firstChild() has more than one ref ! | 625 // FIXME: This is wrong if containerNode->firstChild() has more than one ref ! |
| 626 if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) { | 626 if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) { |
| 627 toText(containerNode->firstChild())->setData(toText(fragment->firstChild ())->data()); | 627 toText(containerNode->firstChild())->setData(toText(fragment->firstChild ())->data()); |
| 628 return; | 628 return; |
| 629 } | 629 } |
| 630 | 630 |
| 631 // FIXME: No need to replace the child it is a text node and its contents ar e already == text. | 631 // FIXME: No need to replace the child it is a text node and its contents ar e already == text. |
| 632 if (containerNode->hasOneChild()) { | 632 if (containerNode->hasOneChild()) { |
| 633 containerNode->replaceChild(fragment, containerNode->firstChild(), excep tionState); | 633 containerNode->replaceChild(fragment, containerNode->firstChild(), excep tionState); |
| 634 return; | 634 return; |
| 635 } | 635 } |
| 636 | 636 |
| 637 containerNode->removeChildren(); | 637 containerNode->removeChildren(); |
| 638 containerNode->appendChild(fragment, exceptionState); | 638 containerNode->appendChild(fragment, exceptionState); |
| 639 } | 639 } |
| 640 | 640 |
| 641 void replaceChildrenWithText(ContainerNode* container, const String& text, Excep tionState& exceptionState) | 641 void replaceChildrenWithText(ContainerNode* container, const String& text, Excep tionState& exceptionState) |
| 642 { | 642 { |
| 643 ASSERT(container); | 643 DCHECK(container); |
| 644 ContainerNode* containerNode(container); | 644 ContainerNode* containerNode(container); |
| 645 | 645 |
| 646 ChildListMutationScope mutation(*containerNode); | 646 ChildListMutationScope mutation(*containerNode); |
| 647 | 647 |
| 648 // FIXME: This is wrong if containerNode->firstChild() has more than one ref ! Example: | 648 // FIXME: This is wrong if containerNode->firstChild() has more than one ref ! Example: |
| 649 // <div>foo</div> | 649 // <div>foo</div> |
| 650 // <script> | 650 // <script> |
| 651 // var oldText = div.firstChild; | 651 // var oldText = div.firstChild; |
| 652 // console.log(oldText.data); // foo | 652 // console.log(oldText.data); // foo |
| 653 // div.innerText = "bar"; | 653 // div.innerText = "bar"; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 668 containerNode->replaceChild(textNode, containerNode->firstChild(), excep tionState); | 668 containerNode->replaceChild(textNode, containerNode->firstChild(), excep tionState); |
| 669 return; | 669 return; |
| 670 } | 670 } |
| 671 | 671 |
| 672 containerNode->removeChildren(); | 672 containerNode->removeChildren(); |
| 673 containerNode->appendChild(textNode, exceptionState); | 673 containerNode->appendChild(textNode, exceptionState); |
| 674 } | 674 } |
| 675 | 675 |
| 676 void mergeWithNextTextNode(Text* textNode, ExceptionState& exceptionState) | 676 void mergeWithNextTextNode(Text* textNode, ExceptionState& exceptionState) |
| 677 { | 677 { |
| 678 ASSERT(textNode); | 678 DCHECK(textNode); |
| 679 Node* next = textNode->nextSibling(); | 679 Node* next = textNode->nextSibling(); |
| 680 if (!next || !next->isTextNode()) | 680 if (!next || !next->isTextNode()) |
| 681 return; | 681 return; |
| 682 | 682 |
| 683 Text* textNext = toText(next); | 683 Text* textNext = toText(next); |
| 684 textNode->appendData(textNext->data()); | 684 textNode->appendData(textNext->data()); |
| 685 if (textNext->parentNode()) // Might have been removed by mutation event. | 685 if (textNext->parentNode()) // Might have been removed by mutation event. |
| 686 textNext->remove(exceptionState); | 686 textNext->remove(exceptionState); |
| 687 } | 687 } |
| 688 | 688 |
| 689 template class CORE_TEMPLATE_EXPORT CreateMarkupAlgorithm<EditingStrategy>; | 689 template class CORE_TEMPLATE_EXPORT CreateMarkupAlgorithm<EditingStrategy>; |
| 690 template class CORE_TEMPLATE_EXPORT CreateMarkupAlgorithm<EditingInFlatTreeStrat egy>; | 690 template class CORE_TEMPLATE_EXPORT CreateMarkupAlgorithm<EditingInFlatTreeStrat egy>; |
| 691 | 691 |
| 692 } // namespace blink | 692 } // namespace blink |
| OLD | NEW |