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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 { | 52 { |
| 53 if (position.isNull()) | 53 if (position.isNull()) |
| 54 return TextOffset(); | 54 return TextOffset(); |
| 55 | 55 |
| 56 if (!position.containerNode()->isTextNode()) | 56 if (!position.containerNode()->isTextNode()) |
| 57 return TextOffset(); | 57 return TextOffset(); |
| 58 | 58 |
| 59 return TextOffset(toText(position.containerNode()), position.offsetInContain erNode()); | 59 return TextOffset(toText(position.containerNode()), position.offsetInContain erNode()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 template<typename EditingStrategy> | |
| 63 static bool handleSelectionBoundary(Node*); | |
|
yosin_UTC9
2015/06/19 06:16:16
|const Node&| if |isSelectionBoundaryShadowHost()|
hajimehoshi
2015/06/19 06:26:51
Done.
| |
| 64 | |
| 65 template<> | |
| 66 bool handleSelectionBoundary<EditingStrategy>(Node*) | |
| 67 { | |
| 68 return false; | |
| 69 } | |
| 70 | |
| 71 template<> | |
| 72 bool handleSelectionBoundary<EditingInComposedTreeStrategy>(Node* node) | |
| 73 { | |
| 74 return EditingInComposedTreeStrategy::isSelectionBoundaryShadowHost(node); | |
| 75 } | |
| 76 | |
| 62 } // namespace | 77 } // namespace |
| 63 | 78 |
| 64 using namespace HTMLNames; | 79 using namespace HTMLNames; |
| 65 | 80 |
| 66 template<typename Strategy> | 81 template<typename Strategy> |
| 67 class StyledMarkupTraverser { | 82 class StyledMarkupTraverser { |
| 68 WTF_MAKE_NONCOPYABLE(StyledMarkupTraverser); | 83 WTF_MAKE_NONCOPYABLE(StyledMarkupTraverser); |
| 69 STACK_ALLOCATED(); | 84 STACK_ALLOCATED(); |
| 70 public: | 85 public: |
| 71 StyledMarkupTraverser(); | 86 StyledMarkupTraverser(); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 Node* lastClosed = nullptr; | 282 Node* lastClosed = nullptr; |
| 268 for (Node* n = startNode; n != pastEnd; n = next) { | 283 for (Node* n = startNode; n != pastEnd; n = next) { |
| 269 // According to <rdar://problem/5730668>, it is possible for n to blow | 284 // According to <rdar://problem/5730668>, it is possible for n to blow |
| 270 // past pastEnd and become null here. This shouldn't be possible. | 285 // past pastEnd and become null here. This shouldn't be possible. |
| 271 // This null check will prevent crashes (but create too much markup) | 286 // This null check will prevent crashes (but create too much markup) |
| 272 // and the ASSERT will hopefully lead us to understanding the problem. | 287 // and the ASSERT will hopefully lead us to understanding the problem. |
| 273 ASSERT(n); | 288 ASSERT(n); |
| 274 if (!n) | 289 if (!n) |
| 275 break; | 290 break; |
| 276 | 291 |
| 277 next = Strategy::next(*n); | 292 // If |n| is a selection boundary such as <input>, traverse the child |
| 278 | 293 // nodes in the DOM tree instead of the composed tree. |
| 279 if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) { | 294 if (handleSelectionBoundary<Strategy>(n)) { |
| 280 // Don't write out empty block containers that aren't fully selected . | 295 lastClosed = StyledMarkupTraverser<EditingStrategy>(m_accumulator, m _lastClosed.get()).traverse(n, EditingStrategy::nextSkippingChildren(*n)); |
| 281 continue; | 296 next = EditingInComposedTreeStrategy::nextSkippingChildren(*n); |
| 282 } | |
| 283 | |
| 284 if (!n->layoutObject() && !enclosingElementWithTag(firstPositionInOrBefo reNode(n), selectTag)) { | |
| 285 next = Strategy::nextSkippingChildren(*n); | |
| 286 // Don't skip over pastEnd. | |
| 287 if (pastEnd && Strategy::isDescendantOf(*pastEnd, *n)) | |
| 288 next = pastEnd; | |
| 289 } else { | 297 } else { |
| 290 // Add the node to the markup if we're not skipping the descendants | 298 next = Strategy::next(*n); |
| 291 appendStartMarkup(*n); | 299 if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) { |
| 292 | 300 // Don't write out empty block containers that aren't fully sele cted. |
| 293 // If node has no children, close the tag now. | |
| 294 if (Strategy::hasChildren(*n)) { | |
| 295 ancestorsToClose.append(toContainerNode(n)); | |
| 296 continue; | 301 continue; |
| 297 } | 302 } |
| 298 appendEndMarkup(*n); | 303 |
| 299 lastClosed = n; | 304 if (!n->layoutObject() && !enclosingElementWithTag(firstPositionInOr BeforeNode(n), selectTag)) { |
| 305 next = Strategy::nextSkippingChildren(*n); | |
| 306 // Don't skip over pastEnd. | |
| 307 if (pastEnd && Strategy::isDescendantOf(*pastEnd, *n)) | |
| 308 next = pastEnd; | |
| 309 } else { | |
| 310 // Add the node to the markup if we're not skipping the descenda nts | |
| 311 appendStartMarkup(*n); | |
| 312 | |
| 313 // If node has no children, close the tag now. | |
| 314 if (Strategy::hasChildren(*n)) { | |
| 315 ancestorsToClose.append(toContainerNode(n)); | |
| 316 continue; | |
| 317 } | |
| 318 appendEndMarkup(*n); | |
| 319 lastClosed = n; | |
| 320 } | |
| 300 } | 321 } |
| 301 | 322 |
| 302 // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors. | 323 // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors. |
| 303 // FIXME: What happens if we just inserted open tag and reached the end? | 324 // FIXME: What happens if we just inserted open tag and reached the end? |
| 304 if (Strategy::nextSibling(*n) && next != pastEnd) | 325 if (Strategy::nextSibling(*n) && next != pastEnd) |
| 305 continue; | 326 continue; |
| 306 | 327 |
| 307 // Close up the ancestors. | 328 // Close up the ancestors. |
| 308 while (!ancestorsToClose.isEmpty()) { | 329 while (!ancestorsToClose.isEmpty()) { |
| 309 ContainerNode* ancestor = ancestorsToClose.last(); | 330 ContainerNode* ancestor = ancestorsToClose.last(); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 if (element.isStyledElement() && element.inlineStyle()) | 476 if (element.isStyledElement() && element.inlineStyle()) |
| 456 inlineStyle->overrideWithStyle(element.inlineStyle()); | 477 inlineStyle->overrideWithStyle(element.inlineStyle()); |
| 457 | 478 |
| 458 if (element.isHTMLElement() && shouldAnnotate()) | 479 if (element.isHTMLElement() && shouldAnnotate()) |
| 459 inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element) ); | 480 inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element) ); |
| 460 | 481 |
| 461 return inlineStyle; | 482 return inlineStyle; |
| 462 } | 483 } |
| 463 | 484 |
| 464 template class StyledMarkupSerializer<EditingStrategy>; | 485 template class StyledMarkupSerializer<EditingStrategy>; |
| 486 template class StyledMarkupSerializer<EditingInComposedTreeStrategy>; | |
| 465 | 487 |
| 466 } // namespace blink | 488 } // namespace blink |
| OLD | NEW |