Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(707)

Side by Side Diff: Source/core/editing/StyledMarkupSerializer.cpp

Issue 1177323005: Move StyledMarkupAccumulator::shouldApplyWrappingStyle to its serializer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/editing/StyledMarkupSerializer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 } 69 }
70 70
71 template<typename Strategy> 71 template<typename Strategy>
72 StyledMarkupSerializer<Strategy>::StyledMarkupSerializer(EAbsoluteURLs shouldRes olveURLs, EAnnotateForInterchange shouldAnnotate, const PositionType& start, con st PositionType& end, Node* highestNodeToBeSerialized, ConvertBlocksToInlines co nvertBlocksToInlines) 72 StyledMarkupSerializer<Strategy>::StyledMarkupSerializer(EAbsoluteURLs shouldRes olveURLs, EAnnotateForInterchange shouldAnnotate, const PositionType& start, con st PositionType& end, Node* highestNodeToBeSerialized, ConvertBlocksToInlines co nvertBlocksToInlines)
73 : m_start(start) 73 : m_start(start)
74 , m_end(end) 74 , m_end(end)
75 , m_shouldResolveURLs(shouldResolveURLs) 75 , m_shouldResolveURLs(shouldResolveURLs)
76 , m_shouldAnnotate(shouldAnnotate) 76 , m_shouldAnnotate(shouldAnnotate)
77 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) 77 , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
78 , m_convertBlocksToInlines(convertBlocksToInlines) 78 , m_convertBlocksToInlines(convertBlocksToInlines)
79 , m_lastClosed(highestNodeToBeSerialized)
79 { 80 {
80 } 81 }
81 82
82 static bool needInterchangeNewlineAfter(const VisiblePosition& v) 83 static bool needInterchangeNewlineAfter(const VisiblePosition& v)
83 { 84 {
84 VisiblePosition next = v.next(); 85 VisiblePosition next = v.next();
85 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode(); 86 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
86 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode(); 87 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
87 // Add an interchange newline if a paragraph break is selected and a br won' t already be added to the markup to represent it. 88 // Add an interchange newline if a paragraph break is selected and a br won' t already be added to the markup to represent it.
88 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode); 89 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode);
(...skipping 21 matching lines...) Expand all
110 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlin eStyle()); 111 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlin eStyle());
111 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle 112 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle
112 // the non-const-ness of styleFromMatchedRulesForElement. 113 // the non-const-ness of styleFromMatchedRulesForElement.
113 style->mergeStyleFromRules(const_cast<HTMLElement*>(element)); 114 style->mergeStyleFromRules(const_cast<HTMLElement*>(element));
114 return style.release(); 115 return style.release();
115 } 116 }
116 117
117 template<typename Strategy> 118 template<typename Strategy>
118 String StyledMarkupSerializer<Strategy>::createMarkup() 119 String StyledMarkupSerializer<Strategy>::createMarkup()
119 { 120 {
120 StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset( m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent ()), m_start.document(), m_shouldAnnotate, m_highestNodeToBeSerialized.get()); 121 StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset( m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent ()), m_start.document(), m_shouldAnnotate);
121 122
122 Node* pastEnd = m_end.nodeAsRangePastLastNode(); 123 Node* pastEnd = m_end.nodeAsRangePastLastNode();
123 124
124 Node* firstNode = m_start.nodeAsRangeFirstNode(); 125 Node* firstNode = m_start.nodeAsRangeFirstNode();
125 VisiblePosition visibleStart(toPositionInDOMTree(m_start), VP_DEFAULT_AFFINI TY); 126 VisiblePosition visibleStart(toPositionInDOMTree(m_start), VP_DEFAULT_AFFINI TY);
126 VisiblePosition visibleEnd(toPositionInDOMTree(m_end), VP_DEFAULT_AFFINITY); 127 VisiblePosition visibleEnd(toPositionInDOMTree(m_end), VP_DEFAULT_AFFINITY);
127 if (shouldAnnotate() && needInterchangeNewlineAfter(visibleStart)) { 128 if (shouldAnnotate() && needInterchangeNewlineAfter(visibleStart)) {
128 markupAccumulator.appendInterchangeNewline(); 129 markupAccumulator.appendInterchangeNewline();
129 if (visibleStart == visibleEnd.previous()) 130 if (visibleStart == visibleEnd.previous())
130 return markupAccumulator.takeResults(); 131 return markupAccumulator.takeResults();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup(). 166 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup().
166 // This assertion is caused at least when we select all text of a <body> element whose 167 // This assertion is caused at least when we select all text of a <body> element whose
167 // 'text-decoration' property is "inherit", and copy it. 168 // 'text-decoration' property is "inherit", and copy it.
168 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyTextDecoration)) 169 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyTextDecoration))
169 fullySelectedRootStyle->style()->setProperty(CSSProperty TextDecoration, CSSValueNone); 170 fullySelectedRootStyle->style()->setProperty(CSSProperty TextDecoration, CSSValueNone);
170 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyWebkitTextDecorationsInEffect)) 171 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyWebkitTextDecorationsInEffect))
171 fullySelectedRootStyle->style()->setProperty(CSSProperty WebkitTextDecorationsInEffect, CSSValueNone); 172 fullySelectedRootStyle->style()->setProperty(CSSProperty WebkitTextDecorationsInEffect, CSSValueNone);
172 markupAccumulator.wrapWithStyleNode(fullySelectedRootStyle-> style()); 173 markupAccumulator.wrapWithStyleNode(fullySelectedRootStyle-> style());
173 } 174 }
174 } else { 175 } else {
175 RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeed ed(markupAccumulator, *ancestor); 176 RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeed ed(*ancestor);
176 // Since this node and all the other ancestors are not in the se lection we want 177 // Since this node and all the other ancestors are not in the se lection we want
177 // styles that affect the exterior of the node not to be not inc luded. 178 // styles that affect the exterior of the node not to be not inc luded.
178 // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it 179 // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
179 // only the ones that affect it and the nodes within it. 180 // only the ones that affect it and the nodes within it.
180 if (style && style->style()) 181 if (style && style->style())
181 style->style()->removeProperty(CSSPropertyFloat); 182 style->style()->removeProperty(CSSPropertyFloat);
182 wrapWithNode(markupAccumulator, *ancestor, style); 183 wrapWithNode(markupAccumulator, *ancestor, style);
183 } 184 }
184 185
185 if (ancestor == m_highestNodeToBeSerialized) 186 if (ancestor == m_highestNodeToBeSerialized)
186 break; 187 break;
187 } 188 }
188 } 189 }
189 190
190 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally. 191 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally.
191 if (shouldAnnotate() && needInterchangeNewlineAt(visibleEnd)) 192 if (shouldAnnotate() && needInterchangeNewlineAt(visibleEnd))
192 markupAccumulator.appendInterchangeNewline(); 193 markupAccumulator.appendInterchangeNewline();
193 194
194 return markupAccumulator.takeResults(); 195 return markupAccumulator.takeResults();
195 } 196 }
196 197
197 template<typename Strategy> 198 template<typename Strategy>
198 Node* StyledMarkupSerializer<Strategy>::serializeNodes(Node* startNode, Node* pa stEnd, StyledMarkupAccumulator* markupAccumulator) 199 Node* StyledMarkupSerializer<Strategy>::serializeNodes(Node* startNode, Node* pa stEnd, StyledMarkupAccumulator* markupAccumulator)
199 { 200 {
200 if (!markupAccumulator->highestNodeToBeSerialized()) { 201 if (!m_lastClosed)
201 Node* lastClosed = traverseNodesForSerialization(startNode, pastEnd, nul lptr); 202 m_lastClosed = traverseNodesForSerialization(startNode, pastEnd, nullptr );
202 markupAccumulator->setHighestNodeToBeSerialized(lastClosed); 203 if (m_lastClosed && Strategy::parent(*m_lastClosed))
203 } 204 m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(Strategy:: parent(*m_lastClosed), shouldAnnotate());
204
205 Node* highestNodeToBeSerialized = markupAccumulator->highestNodeToBeSerializ ed();
206 if (highestNodeToBeSerialized && Strategy::parent(*highestNodeToBeSerialized )) {
207 RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = EditingStyle::wrappingS tyleForSerialization(Strategy::parent(*highestNodeToBeSerialized), shouldAnnotat e());
208 markupAccumulator->setWrappingStyle(wrappingStyle.release());
209 }
210 return traverseNodesForSerialization(startNode, pastEnd, markupAccumulator); 205 return traverseNodesForSerialization(startNode, pastEnd, markupAccumulator);
211 } 206 }
212 207
213 template<typename Strategy> 208 template<typename Strategy>
214 Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star tNode, Node* pastEnd, StyledMarkupAccumulator* markupAccumulator) 209 Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star tNode, Node* pastEnd, StyledMarkupAccumulator* markupAccumulator)
215 { 210 {
216 WillBeHeapVector<RawPtrWillBeMember<ContainerNode>> ancestorsToClose; 211 WillBeHeapVector<RawPtrWillBeMember<ContainerNode>> ancestorsToClose;
217 Node* next; 212 Node* next;
218 Node* lastClosed = nullptr; 213 Node* lastClosed = nullptr;
219 for (Node* n = startNode; n != pastEnd; n = next) { 214 for (Node* n = startNode; n != pastEnd; n = next) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 ASSERT(n); 273 ASSERT(n);
279 Node* lastAncestorClosedOrSelf = Strategy::isDescendantOf(*n, *lastClose d) ? lastClosed : n; 274 Node* lastAncestorClosedOrSelf = Strategy::isDescendantOf(*n, *lastClose d) ? lastClosed : n;
280 for (ContainerNode* parent = Strategy::parent(*lastAncestorClosedOrSelf) ; parent && parent != nextParent; parent = Strategy::parent(*parent)) { 275 for (ContainerNode* parent = Strategy::parent(*lastAncestorClosedOrSelf) ; parent && parent != nextParent; parent = Strategy::parent(*parent)) {
281 // All ancestors that aren't in the ancestorsToClose list should eit her be a) unrendered: 276 // All ancestors that aren't in the ancestorsToClose list should eit her be a) unrendered:
282 if (!parent->layoutObject()) 277 if (!parent->layoutObject())
283 continue; 278 continue;
284 // or b) ancestors that we never encountered during a pre-order trav ersal starting at startNode: 279 // or b) ancestors that we never encountered during a pre-order trav ersal starting at startNode:
285 ASSERT(startNode); 280 ASSERT(startNode);
286 ASSERT(Strategy::isDescendantOf(*startNode, *parent)); 281 ASSERT(Strategy::isDescendantOf(*startNode, *parent));
287 if (markupAccumulator) { 282 if (markupAccumulator) {
288 RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeed ed(*markupAccumulator, *parent); 283 RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeed ed(*parent);
289 wrapWithNode(*markupAccumulator, *parent, style); 284 wrapWithNode(*markupAccumulator, *parent, style);
290 } 285 }
291 lastClosed = parent; 286 lastClosed = parent;
292 } 287 }
293 } 288 }
294 289
295 return lastClosed; 290 return lastClosed;
296 } 291 }
297 292
298 template<typename Strategy> 293 template<typename Strategy>
(...skipping 11 matching lines...) Expand all
310 { 305 {
311 StringBuilder markup; 306 StringBuilder markup;
312 if (node.isDocumentNode()) { 307 if (node.isDocumentNode()) {
313 MarkupFormatter::appendXMLDeclaration(markup, toDocument(node)); 308 MarkupFormatter::appendXMLDeclaration(markup, toDocument(node));
314 accumulator.pushMarkup(markup.toString()); 309 accumulator.pushMarkup(markup.toString());
315 return; 310 return;
316 } 311 }
317 if (!node.isElementNode()) 312 if (!node.isElementNode())
318 return; 313 return;
319 Element& element = toElement(node); 314 Element& element = toElement(node);
320 if (accumulator.shouldApplyWrappingStyle(element) || needsInlineStyle(elemen t)) 315 if (shouldApplyWrappingStyle(element) || needsInlineStyle(element))
321 accumulator.appendElementWithInlineStyle(markup, element, style); 316 accumulator.appendElementWithInlineStyle(markup, element, style);
322 else 317 else
323 accumulator.appendElement(markup, element); 318 accumulator.appendElement(markup, element);
324 accumulator.pushMarkup(markup.toString()); 319 accumulator.pushMarkup(markup.toString());
325 accumulator.appendEndTag(toElement(node)); 320 accumulator.appendEndTag(toElement(node));
326 } 321 }
327 322
328 template<typename Strategy> 323 template<typename Strategy>
329 RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineS tyleIfNeeded(StyledMarkupAccumulator& accumulator, Node& node) 324 RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineS tyleIfNeeded(Node& node)
330 { 325 {
331 if (!node.isElementNode()) 326 if (!node.isElementNode())
332 return nullptr; 327 return nullptr;
333 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(accumulator , toElement(node)); 328 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(toElement(n ode));
334 if (convertBlocksToInlines() && isBlock(&node)) 329 if (convertBlocksToInlines() && isBlock(&node))
335 inlineStyle->forceInline(); 330 inlineStyle->forceInline();
336 return inlineStyle; 331 return inlineStyle;
337 } 332 }
338 333
339 template<typename Strategy> 334 template<typename Strategy>
340 void StyledMarkupSerializer<Strategy>::appendStartMarkup(StyledMarkupAccumulator & accumulator, Node& node) 335 void StyledMarkupSerializer<Strategy>::appendStartMarkup(StyledMarkupAccumulator & accumulator, Node& node)
341 { 336 {
342 switch (node.nodeType()) { 337 switch (node.nodeType()) {
343 case Node::TEXT_NODE: { 338 case Node::TEXT_NODE: {
344 Text& text = toText(node); 339 Text& text = toText(node);
345 if (text.parentElement() && text.parentElement()->tagQName() == textarea Tag) { 340 if (text.parentElement() && text.parentElement()->tagQName() == textarea Tag) {
346 accumulator.appendText(text); 341 accumulator.appendText(text);
347 break; 342 return;
yosin_UTC9 2015/06/17 07:45:21 s/return/break/
hajimehoshi 2015/06/17 07:49:32 Done.
348 } 343 }
349 accumulator.appendTextWithInlineStyle(text); 344 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
345 if (shouldApplyWrappingStyle(text)) {
346 inlineStyle = m_wrappingStyle->copy();
347 // FIXME: <rdar://problem/5371536> Style rules that match pasted con tent can change it's appearance
348 // Make sure spans are inline style in paste side e.g. span { displa y: block }.
349 inlineStyle->forceInline();
350 // FIXME: Should this be included in forceInline?
351 inlineStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
352 }
353 accumulator.appendTextWithInlineStyle(text, inlineStyle);
350 break; 354 break;
351 } 355 } case Node::ELEMENT_NODE: {
yosin_UTC9 2015/06/17 07:45:20 nit: please insert newline between "} case"
hajimehoshi 2015/06/17 07:49:32 Done.
352 case Node::ELEMENT_NODE: {
353 Element& element = toElement(node); 356 Element& element = toElement(node);
354 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(accumul ator, element); 357 if ((element.isHTMLElement() && shouldAnnotate()) || shouldApplyWrapping Style(element)) {
355 accumulator.appendElement(element, inlineStyle); 358 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(ele ment);
359 accumulator.appendElementWithInlineStyle(element, inlineStyle);
360 return;
361 }
362 accumulator.appendElement(element);
356 break; 363 break;
357 } 364 }
358 default: 365 default:
359 accumulator.appendStartMarkup(node); 366 accumulator.appendStartMarkup(node);
360 break; 367 break;
361 } 368 }
362 } 369 }
363 370
364 template<typename Strategy> 371 template<typename Strategy>
365 RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineS tyle(StyledMarkupAccumulator& accumulator, Element& element) 372 bool StyledMarkupSerializer<Strategy>::shouldApplyWrappingStyle(const Node& node ) const
373 {
374 return m_lastClosed && Strategy::parent(*m_lastClosed) == Strategy::parent(n ode)
375 && m_wrappingStyle && m_wrappingStyle->style();
376 }
377
378 template<typename Strategy>
379 RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineS tyle(Element& element)
366 { 380 {
367 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr; 381 RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
368 382
369 if (accumulator.shouldApplyWrappingStyle(element)) { 383 if (shouldApplyWrappingStyle(element)) {
370 inlineStyle = accumulator.wrappingStyle()->copy(); 384 inlineStyle = m_wrappingStyle->copy();
371 inlineStyle->removePropertiesInElementDefaultStyle(&element); 385 inlineStyle->removePropertiesInElementDefaultStyle(&element);
372 inlineStyle->removeStyleConflictingWithStyleOfElement(&element); 386 inlineStyle->removeStyleConflictingWithStyleOfElement(&element);
373 } else { 387 } else {
374 inlineStyle = EditingStyle::create(); 388 inlineStyle = EditingStyle::create();
375 } 389 }
376 390
377 if (element.isStyledElement() && element.inlineStyle()) 391 if (element.isStyledElement() && element.inlineStyle())
378 inlineStyle->overrideWithStyle(element.inlineStyle()); 392 inlineStyle->overrideWithStyle(element.inlineStyle());
379 393
380 if (element.isHTMLElement() && shouldAnnotate()) 394 if (element.isHTMLElement() && shouldAnnotate())
381 inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element) ); 395 inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element) );
382 396
383 return inlineStyle; 397 return inlineStyle;
384 } 398 }
385 399
386 template class StyledMarkupSerializer<EditingStrategy>; 400 template class StyledMarkupSerializer<EditingStrategy>;
387 401
388 } // namespace blink 402 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/StyledMarkupSerializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698