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

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

Issue 1092573003: Refactoring: Move a part of creteMarkupInternal to StyledMarkupSerializer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: nit Created 5 years, 8 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') | Source/core/editing/markup.cpp » ('j') | 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 16 matching lines...) Expand all
27 */ 27 */
28 28
29 #include "config.h" 29 #include "config.h"
30 #include "core/editing/StyledMarkupSerializer.h" 30 #include "core/editing/StyledMarkupSerializer.h"
31 31
32 #include "core/css/StylePropertySet.h" 32 #include "core/css/StylePropertySet.h"
33 #include "core/dom/Document.h" 33 #include "core/dom/Document.h"
34 #include "core/dom/Element.h" 34 #include "core/dom/Element.h"
35 #include "core/dom/Text.h" 35 #include "core/dom/Text.h"
36 #include "core/editing/EditingStyle.h" 36 #include "core/editing/EditingStyle.h"
37 #include "core/editing/VisibleSelection.h"
38 #include "core/editing/VisibleUnits.h"
37 #include "core/editing/htmlediting.h" 39 #include "core/editing/htmlediting.h"
38 #include "core/editing/iterators/TextIterator.h" 40 #include "core/editing/iterators/TextIterator.h"
39 #include "core/editing/markup.h" 41 #include "core/editing/markup.h"
42 #include "core/html/HTMLBodyElement.h"
40 #include "core/html/HTMLElement.h" 43 #include "core/html/HTMLElement.h"
41 #include "wtf/text/StringBuilder.h" 44 #include "wtf/text/StringBuilder.h"
42 45
43 namespace blink { 46 namespace blink {
44 47
45 namespace { 48 namespace {
46 49
47 const String& styleNodeCloseTag(bool isBlock) 50 const String& styleNodeCloseTag(bool isBlock)
48 { 51 {
49 DEFINE_STATIC_LOCAL(const String, divClose, ("</div>")); 52 DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 208 }
206 209
207 bool StyledMarkupAccumulator::shouldApplyWrappingStyle(const Node& node) const 210 bool StyledMarkupAccumulator::shouldApplyWrappingStyle(const Node& node) const
208 { 211 {
209 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod e() == node.parentNode() 212 return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNod e() == node.parentNode()
210 && m_serializer->wrappingStyle() && m_serializer->wrappingStyle()->style (); 213 && m_serializer->wrappingStyle() && m_serializer->wrappingStyle()->style ();
211 } 214 }
212 215
213 StyledMarkupSerializer::StyledMarkupSerializer(EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const Position& start, const Position& e nd, Node* highestNodeToBeSerialized) 216 StyledMarkupSerializer::StyledMarkupSerializer(EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const Position& start, const Position& e nd, Node* highestNodeToBeSerialized)
214 : m_markupAccumulator(this, shouldResolveURLs, start, end, shouldAnnotate, h ighestNodeToBeSerialized) 217 : m_markupAccumulator(this, shouldResolveURLs, start, end, shouldAnnotate, h ighestNodeToBeSerialized)
218 , m_start(start)
219 , m_end(end)
215 { 220 {
216 } 221 }
217 222
223 static bool needInterchangeNewlineAfter(const VisiblePosition& v)
224 {
225 VisiblePosition next = v.next();
226 Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
227 Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
228 // Add an interchange newline if a paragraph break is selected and a br won' t already be added to the markup to represent it.
229 return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement( *upstreamNode) && upstreamNode == downstreamNode);
230 }
231
232 static bool needInterchangeNewlineAt(const VisiblePosition& v)
233 {
234 // FIXME: |v.previous()| works on a DOM tree. We need to fix this to work on
235 // a composed tree.
236 return needInterchangeNewlineAfter(v.previous());
237 }
238
239 static bool areSameRanges(Node* node, const Position& startPosition, const Posit ion& endPosition)
240 {
241 ASSERT(node);
242 Position otherStartPosition;
243 Position otherEndPosition;
244 VisibleSelection::selectionFromContentsOfNode(node).toNormalizedPositions(ot herStartPosition, otherEndPosition);
245 return startPosition == otherStartPosition && endPosition == otherEndPositio n;
246 }
247
248 static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(c onst HTMLElement* element)
249 {
250 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlin eStyle());
251 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle
252 // the non-const-ness of styleFromMatchedRulesForElement.
253 style->mergeStyleFromRules(const_cast<HTMLElement*>(element));
254 return style.release();
255 }
256
257 String StyledMarkupSerializer::createMarkup(bool convertBlocksToInlines, Node* s pecialCommonAncestor)
258 {
259 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
260
261 Node* pastEnd = m_end.nodeAsRangePastLastNode();
262
263 Node* firstNode = m_start.nodeAsRangeFirstNode();
264 VisiblePosition visibleStart(m_start, VP_DEFAULT_AFFINITY);
265 VisiblePosition visibleEnd(m_end, VP_DEFAULT_AFFINITY);
266 if (m_markupAccumulator.shouldAnnotateForInterchange() && needInterchangeNew lineAfter(visibleStart)) {
267 if (visibleStart == visibleEnd.previous())
268 return interchangeNewlineString;
269
270 m_markupAccumulator.appendString(interchangeNewlineString);
271 firstNode = visibleStart.next().deepEquivalent().deprecatedNode();
272
273 if (pastEnd && Position::beforeNode(firstNode).compareTo(Position::befor eNode(pastEnd)) >= 0) {
274 // This condition hits in editing/pasteboard/copy-display-none.html.
275 return interchangeNewlineString;
276 }
277 }
278
279 Node* lastClosed = serializeNodes<EditingStrategy>(firstNode, pastEnd);
280
281 if (specialCommonAncestor && lastClosed) {
282 // TODO(hajimehoshi): This is calculated at createMarkupInternal too.
283 Node* commonAncestor = NodeTraversal::commonAncestor(*m_start.containerN ode(), *m_end.containerNode());
284 ASSERT(commonAncestor);
285 HTMLBodyElement* body = toHTMLBodyElement(enclosingElementWithTag(firstP ositionInNode(commonAncestor), bodyTag));
286 HTMLBodyElement* fullySelectedRoot = nullptr;
287 // FIXME: Do this for all fully selected blocks, not just the body.
288 if (body && areSameRanges(body, m_start, m_end))
289 fullySelectedRoot = body;
290
291 // Also include all of the ancestors of lastClosed up to this special an cestor.
292 // FIXME: What is ancestor?
293 for (ContainerNode* ancestor = NodeTraversal::parent(*lastClosed); ances tor; ancestor = NodeTraversal::parent(*ancestor)) {
294 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
295 RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleF romMatchedRulesAndInlineDecl(fullySelectedRoot);
296
297 // Bring the background attribute over, but not as an attribute because a background attribute on a div
298 // appears to have no effect.
299 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage))
300 && fullySelectedRoot->hasAttribute(backgroundAttr))
301 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + fullySelectedRoot->getAttribute(backgroundAttr) + "')");
302
303 if (fullySelectedRootStyle->style()) {
304 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup().
305 // This assertion is caused at least when we select all text of a <body> element whose
306 // 'text-decoration' property is "inherit", and copy it.
307 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyTextDecoration))
308 fullySelectedRootStyle->style()->setProperty(CSSProperty TextDecoration, CSSValueNone);
309 if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->st yle(), CSSPropertyWebkitTextDecorationsInEffect))
310 fullySelectedRootStyle->style()->setProperty(CSSProperty WebkitTextDecorationsInEffect, CSSValueNone);
311 wrapWithStyleNode(fullySelectedRootStyle->style(), true);
312 }
313 } else {
314 // Since this node and all the other ancestors are not in the se lection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
315 // so that styles that affect the exterior of the node are not i ncluded.
316 wrapWithNode(*ancestor, convertBlocksToInlines, StyledMarkupAccu mulator::DoesNotFullySelectNode);
317 }
318
319 if (ancestor == specialCommonAncestor)
320 break;
321 }
322 }
323
324 // FIXME: The interchange newline should be placed in the block that it's in , not after all of the content, unconditionally.
325 if (m_markupAccumulator.shouldAnnotateForInterchange() && needInterchangeNew lineAt(visibleEnd))
326 m_markupAccumulator.appendString(interchangeNewlineString);
327
328 return takeResults();
329 }
330
218 void StyledMarkupSerializer::wrapWithNode(ContainerNode& node, bool convertBlock sToInlines, StyledMarkupAccumulator::RangeFullySelectsNode rangeFullySelectsNode ) 331 void StyledMarkupSerializer::wrapWithNode(ContainerNode& node, bool convertBlock sToInlines, StyledMarkupAccumulator::RangeFullySelectsNode rangeFullySelectsNode )
219 { 332 {
220 StringBuilder markup; 333 StringBuilder markup;
221 if (node.isElementNode()) 334 if (node.isElementNode())
222 m_markupAccumulator.appendElement(markup, toElement(node), convertBlocks ToInlines && isBlock(&node), rangeFullySelectsNode); 335 m_markupAccumulator.appendElement(markup, toElement(node), convertBlocks ToInlines && isBlock(&node), rangeFullySelectsNode);
223 else 336 else
224 m_markupAccumulator.appendStartMarkup(markup, node, 0); 337 m_markupAccumulator.appendStartMarkup(markup, node, 0);
225 m_reversedPrecedingMarkup.append(markup.toString()); 338 m_reversedPrecedingMarkup.append(markup.toString());
226 if (node.isElementNode()) 339 if (node.isElementNode())
227 m_markupAccumulator.appendEndTag(toElement(node)); 340 m_markupAccumulator.appendEndTag(toElement(node));
228 } 341 }
229 342
230 void StyledMarkupSerializer::wrapWithStyleNode(StylePropertySet* style, bool isB lock) 343 void StyledMarkupSerializer::wrapWithStyleNode(StylePropertySet* style, bool isB lock)
231 { 344 {
232 StringBuilder openTag; 345 StringBuilder openTag;
233 m_markupAccumulator.appendStyleNodeOpenTag(openTag, style, isBlock); 346 m_markupAccumulator.appendStyleNodeOpenTag(openTag, style, isBlock);
234 m_reversedPrecedingMarkup.append(openTag.toString()); 347 m_reversedPrecedingMarkup.append(openTag.toString());
235 appendString(styleNodeCloseTag(isBlock)); 348 m_markupAccumulator.appendString(styleNodeCloseTag(isBlock));
236 } 349 }
237 350
238 String StyledMarkupSerializer::takeResults() 351 String StyledMarkupSerializer::takeResults()
239 { 352 {
240 StringBuilder result; 353 StringBuilder result;
241 result.reserveCapacity(MarkupAccumulator::totalLength(m_reversedPrecedingMar kup) + m_markupAccumulator.length()); 354 result.reserveCapacity(MarkupAccumulator::totalLength(m_reversedPrecedingMar kup) + m_markupAccumulator.length());
242 355
243 for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i) 356 for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i)
244 result.append(m_reversedPrecedingMarkup[i - 1]); 357 result.append(m_reversedPrecedingMarkup[i - 1]);
245 358
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 461 }
349 } 462 }
350 } 463 }
351 464
352 return lastClosed; 465 return lastClosed;
353 } 466 }
354 467
355 template Node* StyledMarkupSerializer::serializeNodes<EditingStrategy>(Node* sta rtNode, Node* endNode); 468 template Node* StyledMarkupSerializer::serializeNodes<EditingStrategy>(Node* sta rtNode, Node* endNode);
356 469
357 } // namespace blink 470 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/StyledMarkupSerializer.h ('k') | Source/core/editing/markup.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698