| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 const String& styleNodeCloseTag(bool isBlock = false); | 141 const String& styleNodeCloseTag(bool isBlock = false); |
| 142 virtual void appendText(StringBuilder& out, Text&) OVERRIDE; | 142 virtual void appendText(StringBuilder& out, Text&) OVERRIDE; |
| 143 String renderedText(Node&, const Range*); | 143 String renderedText(Node&, const Range*); |
| 144 String stringValueForRange(const Node&, const Range*); | 144 String stringValueForRange(const Node&, const Range*); |
| 145 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang
eFullySelectsNode); | 145 void appendElement(StringBuilder& out, Element&, bool addDisplayInline, Rang
eFullySelectsNode); |
| 146 virtual void appendElement(StringBuilder& out, Element& element, Namespaces*
) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); } | 146 virtual void appendElement(StringBuilder& out, Element& element, Namespaces*
) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); } |
| 147 | 147 |
| 148 enum NodeTraversalMode { EmitString, DoNotEmitString }; | 148 enum NodeTraversalMode { EmitString, DoNotEmitString }; |
| 149 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav
ersalMode); | 149 Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTrav
ersalMode); |
| 150 | 150 |
| 151 bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; } | 151 bool shouldAnnotate() const { return m_shouldAnnotate == AnnotateForIntercha
nge || m_shouldAnnotate == AnnotateForNavigationTransition; } |
| 152 bool shouldApplyWrappingStyle(const Node& node) const | 152 bool shouldApplyWrappingStyle(const Node& node) const |
| 153 { | 153 { |
| 154 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren
tNode() == node.parentNode() | 154 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->paren
tNode() == node.parentNode() |
| 155 && m_wrappingStyle && m_wrappingStyle->style(); | 155 && m_wrappingStyle && m_wrappingStyle->style(); |
| 156 } | 156 } |
| 157 | 157 |
| 158 Vector<String> m_reversedPrecedingMarkup; | 158 Vector<String> m_reversedPrecedingMarkup; |
| 159 const EAnnotateForInterchange m_shouldAnnotate; | 159 const EAnnotateForInterchange m_shouldAnnotate; |
| 160 RawPtrWillBeMember<Node> m_highestNodeToBeSerialized; | 160 RawPtrWillBeMember<Node> m_highestNodeToBeSerialized; |
| 161 RefPtrWillBeMember<EditingStyle> m_wrappingStyle; | 161 RefPtrWillBeMember<EditingStyle> m_wrappingStyle; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 } else | 309 } else |
| 310 newInlineStyle = EditingStyle::create(); | 310 newInlineStyle = EditingStyle::create(); |
| 311 | 311 |
| 312 if (element.isStyledElement() && element.inlineStyle()) | 312 if (element.isStyledElement() && element.inlineStyle()) |
| 313 newInlineStyle->overrideWithStyle(element.inlineStyle()); | 313 newInlineStyle->overrideWithStyle(element.inlineStyle()); |
| 314 | 314 |
| 315 if (shouldAnnotateOrForceInline) { | 315 if (shouldAnnotateOrForceInline) { |
| 316 if (shouldAnnotate()) | 316 if (shouldAnnotate()) |
| 317 newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLEleme
nt(element)); | 317 newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLEleme
nt(element)); |
| 318 | 318 |
| 319 if (element == m_highestNodeToBeSerialized && m_shouldAnnotate == An
notateForNavigationTransition) |
| 320 newInlineStyle->addAbsolutePositioningFromElement(element); |
| 321 |
| 319 if (addDisplayInline) | 322 if (addDisplayInline) |
| 320 newInlineStyle->forceInline(); | 323 newInlineStyle->forceInline(); |
| 321 | 324 |
| 322 // If the node is not fully selected by the range, then we don't wan
t to keep styles that affect its relationship to the nodes around it | 325 // If the node is not fully selected by the range, then we don't wan
t to keep styles that affect its relationship to the nodes around it |
| 323 // only the ones that affect it and the nodes within it. | 326 // only the ones that affect it and the nodes within it. |
| 324 if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyl
e->style()) | 327 if (rangeFullySelectsNode == DoesNotFullySelectNode && newInlineStyl
e->style()) |
| 325 newInlineStyle->style()->removeProperty(CSSPropertyFloat); | 328 newInlineStyle->style()->removeProperty(CSSPropertyFloat); |
| 326 } | 329 } |
| 327 | 330 |
| 328 if (!newInlineStyle->isEmpty()) { | 331 if (!newInlineStyle->isEmpty()) { |
| 329 out.appendLiteral(" style=\""); | 332 out.appendLiteral(" style=\""); |
| 330 appendAttributeValue(out, newInlineStyle->style()->asText(), documen
tIsHTML); | 333 appendAttributeValue(out, newInlineStyle->style()->asText(), documen
tIsHTML); |
| 331 out.append('\"'); | 334 out.append('\"'); |
| 332 } | 335 } |
| 333 } | 336 } |
| 334 | 337 |
| 335 appendCloseTag(out, element); | 338 appendCloseTag(out, element); |
| 336 } | 339 } |
| 337 | 340 |
| 338 Node* StyledMarkupAccumulator::serializeNodes(Node* startNode, Node* pastEnd) | 341 Node* StyledMarkupAccumulator::serializeNodes(Node* startNode, Node* pastEnd) |
| 339 { | 342 { |
| 340 if (!m_highestNodeToBeSerialized) { | 343 if (!m_highestNodeToBeSerialized) { |
| 341 Node* lastClosed = traverseNodesForSerialization(startNode, pastEnd, DoN
otEmitString); | 344 Node* lastClosed = traverseNodesForSerialization(startNode, pastEnd, DoN
otEmitString); |
| 342 m_highestNodeToBeSerialized = lastClosed; | 345 m_highestNodeToBeSerialized = lastClosed; |
| 343 } | 346 } |
| 344 | 347 |
| 345 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode()
) | 348 if (m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode()
) { |
| 346 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN
odeToBeSerialized->parentNode(), shouldAnnotate()); | 349 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(m_highestN
odeToBeSerialized->parentNode(), shouldAnnotate()); |
| 350 if (m_shouldAnnotate == AnnotateForNavigationTransition) |
| 351 m_wrappingStyle->style()->removeProperty(CSSPropertyBackground); |
| 352 } |
| 353 |
| 347 | 354 |
| 348 return traverseNodesForSerialization(startNode, pastEnd, EmitString); | 355 return traverseNodesForSerialization(startNode, pastEnd, EmitString); |
| 349 } | 356 } |
| 350 | 357 |
| 351 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
de* pastEnd, NodeTraversalMode traversalMode) | 358 Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
de* pastEnd, NodeTraversalMode traversalMode) |
| 352 { | 359 { |
| 353 const bool shouldEmit = traversalMode == EmitString; | 360 const bool shouldEmit = traversalMode == EmitString; |
| 354 WillBeHeapVector<RawPtrWillBeMember<Node> > ancestorsToClose; | 361 WillBeHeapVector<RawPtrWillBeMember<Node> > ancestorsToClose; |
| 355 Node* next; | 362 Node* next; |
| 356 Node* lastClosed = 0; | 363 Node* lastClosed = 0; |
| 357 for (Node* n = startNode; n != pastEnd; n = next) { | 364 for (Node* n = startNode; n != pastEnd; n = next) { |
| 358 // According to <rdar://problem/5730668>, it is possible for n to blow | 365 // According to <rdar://problem/5730668>, it is possible for n to blow |
| 359 // past pastEnd and become null here. This shouldn't be possible. | 366 // past pastEnd and become null here. This shouldn't be possible. |
| 360 // This null check will prevent crashes (but create too much markup) | 367 // This null check will prevent crashes (but create too much markup) |
| 361 // and the ASSERT will hopefully lead us to understanding the problem. | 368 // and the ASSERT will hopefully lead us to understanding the problem. |
| 362 ASSERT(n); | 369 ASSERT(n); |
| 363 if (!n) | 370 if (!n) |
| 364 break; | 371 break; |
| 365 | 372 |
| 366 next = NodeTraversal::next(*n); | 373 next = NodeTraversal::next(*n); |
| 367 bool openedTag = false; | 374 bool openedTag = false; |
| 368 | 375 |
| 369 if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) | 376 if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) |
| 370 // Don't write out empty block containers that aren't fully selected
. | 377 // Don't write out empty block containers that aren't fully selected
. |
| 371 continue; | 378 continue; |
| 372 | 379 |
| 373 if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode(
n), selectTag)) { | 380 if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode(
n), selectTag) && m_shouldAnnotate != AnnotateForNavigationTransition) { |
| 374 next = NodeTraversal::nextSkippingChildren(*n); | 381 next = NodeTraversal::nextSkippingChildren(*n); |
| 375 // Don't skip over pastEnd. | 382 // Don't skip over pastEnd. |
| 376 if (pastEnd && pastEnd->isDescendantOf(n)) | 383 if (pastEnd && pastEnd->isDescendantOf(n)) |
| 377 next = pastEnd; | 384 next = pastEnd; |
| 378 } else { | 385 } else { |
| 379 // Add the node to the markup if we're not skipping the descendants | 386 // Add the node to the markup if we're not skipping the descendants |
| 380 if (shouldEmit) | 387 if (shouldEmit) |
| 381 appendStartTag(*n); | 388 appendStartTag(*n); |
| 382 | 389 |
| 383 // If node has no children, close the tag now. | 390 // If node has no children, close the tag now. |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 if (!next || !next->isTextNode()) | 1082 if (!next || !next->isTextNode()) |
| 1076 return; | 1083 return; |
| 1077 | 1084 |
| 1078 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); | 1085 RefPtrWillBeRawPtr<Text> textNode = toText(node.get()); |
| 1079 RefPtrWillBeRawPtr<Text> textNext = toText(next); | 1086 RefPtrWillBeRawPtr<Text> textNext = toText(next); |
| 1080 textNode->appendData(textNext->data()); | 1087 textNode->appendData(textNext->data()); |
| 1081 if (textNext->parentNode()) // Might have been removed by mutation event. | 1088 if (textNext->parentNode()) // Might have been removed by mutation event. |
| 1082 textNext->remove(exceptionState); | 1089 textNext->remove(exceptionState); |
| 1083 } | 1090 } |
| 1084 | 1091 |
| 1092 String createStyledMarkupForNavigationTransition(Node* node) |
| 1093 { |
| 1094 StyledMarkupAccumulator accumulator(0, ResolveAllURLs, AnnotateForNavigation
Transition, 0, 0); |
| 1095 accumulator.serializeNodes(node, NodeTraversal::nextSkippingChildren(*node))
; |
| 1096 |
| 1097 return accumulator.takeResults(); |
| 1085 } | 1098 } |
| 1099 |
| 1100 } |
| OLD | NEW |