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

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

Issue 418223004: Use tighter typing in editing/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Clean up Created 6 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 26 matching lines...) Expand all
37 #include "core/dom/NodeTraversal.h" 37 #include "core/dom/NodeTraversal.h"
38 #include "core/dom/Range.h" 38 #include "core/dom/Range.h"
39 #include "core/dom/Text.h" 39 #include "core/dom/Text.h"
40 #include "core/editing/EditingStyle.h" 40 #include "core/editing/EditingStyle.h"
41 #include "core/editing/HTMLInterchange.h" 41 #include "core/editing/HTMLInterchange.h"
42 #include "core/editing/PlainTextRange.h" 42 #include "core/editing/PlainTextRange.h"
43 #include "core/editing/TextIterator.h" 43 #include "core/editing/TextIterator.h"
44 #include "core/editing/VisibleUnits.h" 44 #include "core/editing/VisibleUnits.h"
45 #include "core/editing/htmlediting.h" 45 #include "core/editing/htmlediting.h"
46 #include "core/frame/UseCounter.h" 46 #include "core/frame/UseCounter.h"
47 #include "core/html/HTMLFontElement.h"
48 #include "core/html/HTMLSpanElement.h"
47 #include "core/rendering/RenderObject.h" 49 #include "core/rendering/RenderObject.h"
48 #include "core/rendering/RenderText.h" 50 #include "core/rendering/RenderText.h"
49 #include "platform/heap/Handle.h" 51 #include "platform/heap/Handle.h"
50 #include "wtf/StdLibExtras.h" 52 #include "wtf/StdLibExtras.h"
51 #include "wtf/text/StringBuilder.h" 53 #include "wtf/text/StringBuilder.h"
52 54
53 namespace blink { 55 namespace blink {
54 56
55 using namespace HTMLNames; 57 using namespace HTMLNames;
56 58
57 static String& styleSpanClassString() 59 static String& styleSpanClassString()
58 { 60 {
59 DEFINE_STATIC_LOCAL(String, styleSpanClassString, ((AppleStyleSpanClass))); 61 DEFINE_STATIC_LOCAL(String, styleSpanClassString, ((AppleStyleSpanClass)));
60 return styleSpanClassString; 62 return styleSpanClassString;
61 } 63 }
62 64
63 bool isLegacyAppleStyleSpan(const Node *node) 65 bool isLegacyAppleStyleSpan(const Node* node)
64 { 66 {
65 if (!node || !node->isHTMLElement()) 67 if (!isHTMLSpanElement(node))
66 return false; 68 return false;
67 69
68 const HTMLElement& element = toHTMLElement(*node); 70 const HTMLSpanElement& span = toHTMLSpanElement(*node);
69 if (!isHTMLSpanElement(element) || element.getAttribute(classAttr) != styleS panClassString()) 71 if (span.getAttribute(classAttr) != styleSpanClassString())
70 return false; 72 return false;
71 UseCounter::count(element.document(), UseCounter::EditingAppleStyleSpanClass ); 73 UseCounter::count(span.document(), UseCounter::EditingAppleStyleSpanClass);
72 return true; 74 return true;
73 } 75 }
74 76
75 static bool hasNoAttributeOrOnlyStyleAttribute(const Element* element, ShouldSty leAttributeBeEmpty shouldStyleAttributeBeEmpty) 77 static bool hasNoAttributeOrOnlyStyleAttribute(const HTMLElement* element, Shoul dStyleAttributeBeEmpty shouldStyleAttributeBeEmpty)
76 { 78 {
77 if (!element->hasAttributes()) 79 if (!element->hasAttributes())
78 return true; 80 return true;
79 81
80 unsigned matchedAttributes = 0; 82 unsigned matchedAttributes = 0;
81 if (element->getAttribute(classAttr) == styleSpanClassString()) 83 if (element->getAttribute(classAttr) == styleSpanClassString())
82 matchedAttributes++; 84 matchedAttributes++;
83 if (element->hasAttribute(styleAttr) && (shouldStyleAttributeBeEmpty == Allo wNonEmptyStyleAttribute 85 if (element->hasAttribute(styleAttr) && (shouldStyleAttributeBeEmpty == Allo wNonEmptyStyleAttribute
84 || !element->inlineStyle() || element->inlineStyle()->isEmpty())) 86 || !element->inlineStyle() || element->inlineStyle()->isEmpty()))
85 matchedAttributes++; 87 matchedAttributes++;
86 88
87 ASSERT(matchedAttributes <= element->attributes().size()); 89 ASSERT(matchedAttributes <= element->attributes().size());
88 return matchedAttributes == element->attributes().size(); 90 return matchedAttributes == element->attributes().size();
89 } 91 }
90 92
91 bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element* element) 93 bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element* element)
92 { 94 {
93 if (!isHTMLSpanElement(element)) 95 if (!isHTMLSpanElement(element))
94 return false; 96 return false;
95 return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), AllowNonEm ptyStyleAttribute); 97 return hasNoAttributeOrOnlyStyleAttribute(toHTMLSpanElement(element), AllowN onEmptyStyleAttribute);
96 } 98 }
97 99
98 static inline bool isSpanWithoutAttributesOrUnstyledStyleSpan(const Node* node) 100 static inline bool isSpanWithoutAttributesOrUnstyledStyleSpan(const Node* node)
99 { 101 {
100 if (!isHTMLSpanElement(node)) 102 if (!isHTMLSpanElement(node))
101 return false; 103 return false;
102 return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(node), StyleAttribut eShouldBeEmpty); 104 return hasNoAttributeOrOnlyStyleAttribute(toHTMLSpanElement(node), StyleAttr ibuteShouldBeEmpty);
103 } 105 }
104 106
105 bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldSt yleAttributeBeEmpty) 107 bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldSt yleAttributeBeEmpty)
106 { 108 {
107 if (!isHTMLFontElement(element)) 109 if (!isHTMLFontElement(element))
108 return false; 110 return false;
109 111
110 return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyl eAttributeBeEmpty); 112 return hasNoAttributeOrOnlyStyleAttribute(toHTMLFontElement(element), should StyleAttributeBeEmpty);
111 } 113 }
112 114
113 static PassRefPtrWillBeRawPtr<Element> createFontElement(Document& document) 115 static PassRefPtrWillBeRawPtr<HTMLFontElement> createFontElement(Document& docum ent)
114 { 116 {
115 return createHTMLElement(document, fontTag); 117 return toHTMLFontElement(createHTMLElement(document, fontTag).get());
116 } 118 }
117 119
118 PassRefPtrWillBeRawPtr<HTMLElement> createStyleSpanElement(Document& document) 120 PassRefPtrWillBeRawPtr<HTMLSpanElement> createStyleSpanElement(Document& documen t)
119 { 121 {
120 return createHTMLElement(document, spanTag); 122 return toHTMLSpanElement(createHTMLElement(document, spanTag).get());
121 } 123 }
122 124
123 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, EditAction editingAction, EPropertyLevel propertyLevel) 125 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty le, EditAction editingAction, EPropertyLevel propertyLevel)
124 : CompositeEditCommand(document) 126 : CompositeEditCommand(document)
125 , m_style(style->copy()) 127 , m_style(style->copy())
126 , m_editingAction(editingAction) 128 , m_editingAction(editingAction)
127 , m_propertyLevel(propertyLevel) 129 , m_propertyLevel(propertyLevel)
128 , m_start(endingSelection().start().downstream()) 130 , m_start(endingSelection().start().downstream())
129 , m_end(endingSelection().end().upstream()) 131 , m_end(endingSelection().end().upstream())
130 , m_useEndingSelection(true) 132 , m_useEndingSelection(true)
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), firstPosition InNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 263 RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), firstPosition InNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
262 int startIndex = TextIterator::rangeLength(startRange.get(), true); 264 int startIndex = TextIterator::rangeLength(startRange.get(), true);
263 int endIndex = TextIterator::rangeLength(endRange.get(), true); 265 int endIndex = TextIterator::rangeLength(endRange.get(), true);
264 266
265 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); 267 VisiblePosition paragraphStart(startOfParagraph(visibleStart));
266 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next()); 268 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next());
267 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next()); 269 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next());
268 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) { 270 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) {
269 StyleChange styleChange(style, paragraphStart.deepEquivalent()); 271 StyleChange styleChange(style, paragraphStart.deepEquivalent());
270 if (styleChange.cssStyle().length() || m_removeOnly) { 272 if (styleChange.cssStyle().length() || m_removeOnly) {
271 RefPtrWillBeRawPtr<Node> block = enclosingBlock(paragraphStart.deepE quivalent().deprecatedNode()); 273 RefPtrWillBeRawPtr<Element> block = enclosingBlock(paragraphStart.de epEquivalent().deprecatedNode());
272 const Position& paragraphStartToMove = paragraphStart.deepEquivalent (); 274 const Position& paragraphStartToMove = paragraphStart.deepEquivalent ();
273 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) { 275 if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) {
274 RefPtrWillBeRawPtr<Element> newBlock = moveParagraphContentsToNe wBlockIfNecessary(paragraphStartToMove); 276 RefPtrWillBeRawPtr<Element> newBlock = moveParagraphContentsToNe wBlockIfNecessary(paragraphStartToMove);
275 if (newBlock) 277 if (newBlock)
276 block = newBlock; 278 block = newBlock;
277 } 279 }
278 ASSERT(!block || block->isElementNode());
279 if (block && block->isHTMLElement()) { 280 if (block && block->isHTMLElement()) {
280 removeCSSStyle(style, toHTMLElement(block)); 281 removeCSSStyle(style, toHTMLElement(block));
281 if (!m_removeOnly) 282 if (!m_removeOnly)
282 addBlockStyle(styleChange, toHTMLElement(block)); 283 addBlockStyle(styleChange, toHTMLElement(block));
283 } 284 }
284 285
285 if (nextParagraphStart.isOrphan()) 286 if (nextParagraphStart.isOrphan())
286 nextParagraphStart = endOfParagraph(paragraphStart).next(); 287 nextParagraphStart = endOfParagraph(paragraphStart).next();
287 } 288 }
288 289
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 384
384 // These spans were added by us. If empty after font size changes, they can be removed. 385 // These spans were added by us. If empty after font size changes, they can be removed.
385 WillBeHeapVector<RefPtrWillBeMember<HTMLElement> > unstyledSpans; 386 WillBeHeapVector<RefPtrWillBeMember<HTMLElement> > unstyledSpans;
386 387
387 Node* lastStyledNode = 0; 388 Node* lastStyledNode = 0;
388 for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(* node)) { 389 for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(* node)) {
389 ASSERT(node); 390 ASSERT(node);
390 RefPtrWillBeRawPtr<HTMLElement> element = nullptr; 391 RefPtrWillBeRawPtr<HTMLElement> element = nullptr;
391 if (node->isHTMLElement()) { 392 if (node->isHTMLElement()) {
392 // Only work on fully selected nodes. 393 // Only work on fully selected nodes.
393 if (!nodeFullySelected(node, start, end)) 394 if (!elementFullySelected(toHTMLElement(*node), start, end))
394 continue; 395 continue;
395 element = toHTMLElement(node); 396 element = toHTMLElement(node);
396 } else if (node->isTextNode() && node->renderer() && node->parentNode() != lastStyledNode) { 397 } else if (node->isTextNode() && node->renderer() && node->parentNode() != lastStyledNode) {
397 // Last styled node was not parent node of this text node, but we wi sh to style this 398 // Last styled node was not parent node of this text node, but we wi sh to style this
398 // text node. To make this possible, add a style span to surround th is text node. 399 // text node. To make this possible, add a style span to surround th is text node.
399 RefPtrWillBeRawPtr<HTMLElement> span = createStyleSpanElement(docume nt()); 400 RefPtrWillBeRawPtr<HTMLSpanElement> span = createStyleSpanElement(do cument());
400 surroundNodeRangeWithElement(node, node, span.get()); 401 surroundNodeRangeWithElement(node, node, span.get());
401 element = span.release(); 402 element = span.release();
402 } else { 403 } else {
403 // Only handle HTML elements and text nodes. 404 // Only handle HTML elements and text nodes.
404 continue; 405 continue;
405 } 406 }
406 lastStyledNode = node; 407 lastStyledNode = node;
407 408
408 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCre ateEmpty(element->inlineStyle()); 409 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCre ateEmpty(element->inlineStyle());
409 float currentFontSize = computedFontSize(node); 410 float currentFontSize = computedFontSize(node);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 next = node->nextSibling(); 452 next = node->nextSibling();
452 if (isSpanWithoutAttributesOrUnstyledStyleSpan(node)) 453 if (isSpanWithoutAttributesOrUnstyledStyleSpan(node))
453 removeNodePreservingChildren(node); 454 removeNodePreservingChildren(node);
454 } 455 }
455 } 456 }
456 457
457 HTMLElement* ApplyStyleCommand::splitAncestorsWithUnicodeBidi(Node* node, bool b efore, WritingDirection allowedDirection) 458 HTMLElement* ApplyStyleCommand::splitAncestorsWithUnicodeBidi(Node* node, bool b efore, WritingDirection allowedDirection)
458 { 459 {
459 // We are allowed to leave the highest ancestor with unicode-bidi unsplit if it is unicode-bidi: embed and direction: allowedDirection. 460 // We are allowed to leave the highest ancestor with unicode-bidi unsplit if it is unicode-bidi: embed and direction: allowedDirection.
460 // In that case, we return the unsplit ancestor. Otherwise, we return 0. 461 // In that case, we return the unsplit ancestor. Otherwise, we return 0.
461 Node* block = enclosingBlock(node); 462 Element* block = enclosingBlock(node);
462 if (!block) 463 if (!block)
463 return 0; 464 return 0;
464 465
465 Node* highestAncestorWithUnicodeBidi = 0; 466 ContainerNode* highestAncestorWithUnicodeBidi = 0;
466 Node* nextHighestAncestorWithUnicodeBidi = 0; 467 ContainerNode* nextHighestAncestorWithUnicodeBidi = 0;
467 int highestAncestorUnicodeBidi = 0; 468 int highestAncestorUnicodeBidi = 0;
468 for (Node* n = node->parentNode(); n != block; n = n->parentNode()) { 469 for (ContainerNode* n = node->parentNode(); n != block; n = n->parentNode()) {
469 int unicodeBidi = getIdentifierValue(CSSComputedStyleDeclaration::create (n).get(), CSSPropertyUnicodeBidi); 470 int unicodeBidi = getIdentifierValue(CSSComputedStyleDeclaration::create (n).get(), CSSPropertyUnicodeBidi);
470 if (unicodeBidi && unicodeBidi != CSSValueNormal) { 471 if (unicodeBidi && unicodeBidi != CSSValueNormal) {
471 highestAncestorUnicodeBidi = unicodeBidi; 472 highestAncestorUnicodeBidi = unicodeBidi;
472 nextHighestAncestorWithUnicodeBidi = highestAncestorWithUnicodeBidi; 473 nextHighestAncestorWithUnicodeBidi = highestAncestorWithUnicodeBidi;
473 highestAncestorWithUnicodeBidi = n; 474 highestAncestorWithUnicodeBidi = n;
474 } 475 }
475 } 476 }
476 477
477 if (!highestAncestorWithUnicodeBidi) 478 if (!highestAncestorWithUnicodeBidi)
478 return 0; 479 return 0;
(...skipping 19 matching lines...) Expand all
498 RefPtrWillBeRawPtr<Element> parent = toElement(currentNode->parentNode() ); 499 RefPtrWillBeRawPtr<Element> parent = toElement(currentNode->parentNode() );
499 if (before ? currentNode->previousSibling() : currentNode->nextSibling() ) 500 if (before ? currentNode->previousSibling() : currentNode->nextSibling() )
500 splitElement(parent, before ? currentNode.get() : currentNode->nextS ibling()); 501 splitElement(parent, before ? currentNode.get() : currentNode->nextS ibling());
501 if (parent == highestAncestorWithUnicodeBidi) 502 if (parent == highestAncestorWithUnicodeBidi)
502 break; 503 break;
503 currentNode = parent; 504 currentNode = parent;
504 } 505 }
505 return unsplitAncestor; 506 return unsplitAncestor;
506 } 507 }
507 508
508 void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsp litAncestor) 509 void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, HTMLElemen t* unsplitAncestor)
509 { 510 {
510 Node* block = enclosingBlock(node); 511 Element* block = enclosingBlock(node);
511 if (!block) 512 if (!block)
512 return; 513 return;
513 514
514 for (Node* n = node->parentNode(); n != block && n != unsplitAncestor; n = n ->parentNode()) { 515 for (ContainerNode* n = node->parentNode(); n != block && n != unsplitAncest or; n = n->parentNode()) {
515 if (!n->isStyledElement()) 516 if (!n->isStyledElement())
516 continue; 517 continue;
517 518
518 Element* element = toElement(n); 519 Element* element = toElement(n);
519 int unicodeBidi = getIdentifierValue(CSSComputedStyleDeclaration::create (element).get(), CSSPropertyUnicodeBidi); 520 int unicodeBidi = getIdentifierValue(CSSComputedStyleDeclaration::create (element).get(), CSSPropertyUnicodeBidi);
520 if (!unicodeBidi || unicodeBidi == CSSValueNormal) 521 if (!unicodeBidi || unicodeBidi == CSSValueNormal)
521 continue; 522 continue;
522 523
523 // FIXME: This code should really consider the mapped attribute 'dir', t he inline style declaration, 524 // FIXME: This code should really consider the mapped attribute 'dir', t he inline style declaration,
524 // and all matching style rules in order to determine how to best set th e unicode-bidi property to 'normal'. 525 // and all matching style rules in order to determine how to best set th e unicode-bidi property to 'normal'.
525 // For now, it assumes that if the 'dir' attribute is present, then remo ving it will suffice, and 526 // For now, it assumes that if the 'dir' attribute is present, then remo ving it will suffice, and
526 // otherwise it sets the property in the inline style declaration. 527 // otherwise it sets the property in the inline style declaration.
527 if (element->hasAttribute(dirAttr)) { 528 if (element->hasAttribute(dirAttr)) {
528 // FIXME: If this is a BDO element, we should probably just remove i t if it has no 529 // FIXME: If this is a BDO element, we should probably just remove i t if it has no
529 // other attributes, like we (should) do with B and I elements. 530 // other attributes, like we (should) do with B and I elements.
530 removeNodeAttribute(element, dirAttr); 531 removeNodeAttribute(element, dirAttr);
531 } else { 532 } else {
532 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleO rCreateEmpty(element->inlineStyle()); 533 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleO rCreateEmpty(element->inlineStyle());
533 inlineStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal); 534 inlineStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
534 inlineStyle->removeProperty(CSSPropertyDirection); 535 inlineStyle->removeProperty(CSSPropertyDirection);
535 setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asTex t())); 536 setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asTex t()));
536 if (isSpanWithoutAttributesOrUnstyledStyleSpan(element)) 537 if (isSpanWithoutAttributesOrUnstyledStyleSpan(element))
537 removeNodePreservingChildren(element); 538 removeNodePreservingChildren(element);
538 } 539 }
539 } 540 }
540 } 541 }
541 542
542 static Node* highestEmbeddingAncestor(Node* startNode, Node* enclosingNode) 543 static HTMLElement* highestEmbeddingAncestor(Node* startNode, Node* enclosingNod e)
543 { 544 {
544 for (Node* n = startNode; n && n != enclosingNode; n = n->parentNode()) { 545 for (Node* n = startNode; n && n != enclosingNode; n = n->parentNode()) {
545 if (n->isHTMLElement() && getIdentifierValue(CSSComputedStyleDeclaration ::create(n).get(), CSSPropertyUnicodeBidi) == CSSValueEmbed) 546 if (n->isHTMLElement() && getIdentifierValue(CSSComputedStyleDeclaration ::create(n).get(), CSSPropertyUnicodeBidi) == CSSValueEmbed)
546 return n; 547 return toHTMLElement(n);
547 } 548 }
548 549
549 return 0; 550 return 0;
550 } 551 }
551 552
552 void ApplyStyleCommand::applyInlineStyle(EditingStyle* style) 553 void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
553 { 554 {
554 RefPtrWillBeRawPtr<ContainerNode> startDummySpanAncestor = nullptr; 555 RefPtrWillBeRawPtr<ContainerNode> startDummySpanAncestor = nullptr;
555 RefPtrWillBeRawPtr<ContainerNode> endDummySpanAncestor = nullptr; 556 RefPtrWillBeRawPtr<ContainerNode> endDummySpanAncestor = nullptr;
556 557
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr; 609 RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr;
609 if (hasTextDirection) { 610 if (hasTextDirection) {
610 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one. 611 // Leave alone an ancestor that provides the desired single level embedd ing, if there is one.
611 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. deprecatedNode(), true, textDirection); 612 HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start. deprecatedNode(), true, textDirection);
612 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.depr ecatedNode(), false, textDirection); 613 HTMLElement* endUnsplitAncestor = splitAncestorsWithUnicodeBidi(end.depr ecatedNode(), false, textDirection);
613 removeEmbeddingUpToEnclosingBlock(start.deprecatedNode(), startUnsplitAn cestor); 614 removeEmbeddingUpToEnclosingBlock(start.deprecatedNode(), startUnsplitAn cestor);
614 removeEmbeddingUpToEnclosingBlock(end.deprecatedNode(), endUnsplitAncest or); 615 removeEmbeddingUpToEnclosingBlock(end.deprecatedNode(), endUnsplitAncest or);
615 616
616 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors. 617 // Avoid removing the dir attribute and the unicode-bidi and direction p roperties from the unsplit ancestors.
617 Position embeddingRemoveStart = removeStart; 618 Position embeddingRemoveStart = removeStart;
618 if (startUnsplitAncestor && nodeFullySelected(startUnsplitAncestor, remo veStart, end)) 619 if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end))
619 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or); 620 embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncest or);
620 621
621 Position embeddingRemoveEnd = end; 622 Position embeddingRemoveEnd = end;
622 if (endUnsplitAncestor && nodeFullySelected(endUnsplitAncestor, removeSt art, end)) 623 if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, remo veStart, end))
623 embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor) .downstream(); 624 embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor) .downstream();
624 625
625 if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) { 626 if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) {
626 styleWithoutEmbedding = style->copy(); 627 styleWithoutEmbedding = style->copy();
627 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDirectio n(); 628 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDirectio n();
628 629
629 if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0) 630 if (comparePositions(embeddingRemoveStart, embeddingRemoveEnd) <= 0)
630 removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, em beddingRemoveEnd); 631 removeInlineStyle(embeddingStyle.get(), embeddingRemoveStart, em beddingRemoveEnd);
631 } 632 }
632 } 633 }
(...skipping 16 matching lines...) Expand all
649 } 650 }
650 651
651 // update document layout once before running the rest of the function 652 // update document layout once before running the rest of the function
652 // so that we avoid the expense of updating before each and every call 653 // so that we avoid the expense of updating before each and every call
653 // to check a computed style 654 // to check a computed style
654 document().updateLayoutIgnorePendingStylesheets(); 655 document().updateLayoutIgnorePendingStylesheets();
655 656
656 RefPtrWillBeRawPtr<EditingStyle> styleToApply = style; 657 RefPtrWillBeRawPtr<EditingStyle> styleToApply = style;
657 if (hasTextDirection) { 658 if (hasTextDirection) {
658 // Avoid applying the unicode-bidi and direction properties beneath ance stors that already have them. 659 // Avoid applying the unicode-bidi and direction properties beneath ance stors that already have them.
659 Node* embeddingStartNode = highestEmbeddingAncestor(start.deprecatedNode (), enclosingBlock(start.deprecatedNode())); 660 HTMLElement* embeddingStartElement = highestEmbeddingAncestor(start.depr ecatedNode(), enclosingBlock(start.deprecatedNode()));
660 Node* embeddingEndNode = highestEmbeddingAncestor(end.deprecatedNode(), enclosingBlock(end.deprecatedNode())); 661 HTMLElement* embeddingEndElement = highestEmbeddingAncestor(end.deprecat edNode(), enclosingBlock(end.deprecatedNode()));
661 662
662 if (embeddingStartNode || embeddingEndNode) { 663 if (embeddingStartElement || embeddingEndElement) {
663 Position embeddingApplyStart = embeddingStartNode ? positionInParent AfterNode(*embeddingStartNode) : start; 664 Position embeddingApplyStart = embeddingStartElement ? positionInPar entAfterNode(*embeddingStartElement) : start;
664 Position embeddingApplyEnd = embeddingEndNode ? positionInParentBefo reNode(*embeddingEndNode) : end; 665 Position embeddingApplyEnd = embeddingEndElement ? positionInParentB eforeNode(*embeddingEndElement) : end;
665 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul l()); 666 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul l());
666 667
667 if (!embeddingStyle) { 668 if (!embeddingStyle) {
668 styleWithoutEmbedding = style->copy(); 669 styleWithoutEmbedding = style->copy();
669 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire ction(); 670 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire ction();
670 } 671 }
671 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar t, embeddingApplyEnd); 672 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar t, embeddingApplyEnd);
672 673
673 styleToApply = styleWithoutEmbedding; 674 styleToApply = styleWithoutEmbedding;
674 } 675 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 visitor->trace(end); 752 visitor->trace(end);
752 visitor->trace(pastEndNode); 753 visitor->trace(pastEndNode);
753 visitor->trace(positionForStyleComputation); 754 visitor->trace(positionForStyleComputation);
754 visitor->trace(dummyElement); 755 visitor->trace(dummyElement);
755 } 756 }
756 757
757 RefPtrWillBeMember<Node> start; 758 RefPtrWillBeMember<Node> start;
758 RefPtrWillBeMember<Node> end; 759 RefPtrWillBeMember<Node> end;
759 RefPtrWillBeMember<Node> pastEndNode; 760 RefPtrWillBeMember<Node> pastEndNode;
760 Position positionForStyleComputation; 761 Position positionForStyleComputation;
761 RefPtrWillBeMember<Node> dummyElement; 762 RefPtrWillBeMember<HTMLSpanElement> dummyElement;
762 StyleChange change; 763 StyleChange change;
763 }; 764 };
764 765
765 } // namespace blink 766 } // namespace blink
766 767
767 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::InlineRunToApplyStyle); 768 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::InlineRunToApplyStyle);
768 769
769 namespace blink { 770 namespace blink {
770 771
771 void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef PtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> pastEndNode) 772 void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef PtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> pastEndNode)
772 { 773 {
773 if (m_removeOnly) 774 if (m_removeOnly)
774 return; 775 return;
775 776
776 document().updateLayoutIgnorePendingStylesheets(); 777 document().updateLayoutIgnorePendingStylesheets();
777 778
778 WillBeHeapVector<InlineRunToApplyStyle> runs; 779 WillBeHeapVector<InlineRunToApplyStyle> runs;
779 RefPtrWillBeRawPtr<Node> node = startNode; 780 RefPtrWillBeRawPtr<Node> node = startNode;
780 for (RefPtrWillBeRawPtr<Node> next; node && node != pastEndNode; node = next ) { 781 for (RefPtrWillBeRawPtr<Node> next; node && node != pastEndNode; node = next ) {
781 next = NodeTraversal::next(*node); 782 next = NodeTraversal::next(*node);
782 783
783 if (!node->renderer() || !node->hasEditableStyle()) 784 if (!node->renderer() || !node->hasEditableStyle())
784 continue; 785 continue;
785 786
786 if (!node->rendererIsRichlyEditable() && node->isHTMLElement()) { 787 if (!node->rendererIsRichlyEditable() && node->isHTMLElement()) {
788 HTMLElement* element = toHTMLElement(node);
787 // This is a plaintext-only region. Only proceed if it's fully selec ted. 789 // This is a plaintext-only region. Only proceed if it's fully selec ted.
788 // pastEndNode is the node after the last fully selected node, so if it's inside node then 790 // pastEndNode is the node after the last fully selected node, so if it's inside node then
789 // node isn't fully selected. 791 // node isn't fully selected.
790 if (pastEndNode && pastEndNode->isDescendantOf(node.get())) 792 if (pastEndNode && pastEndNode->isDescendantOf(element))
791 break; 793 break;
792 // Add to this element's inline style and skip over its contents. 794 // Add to this element's inline style and skip over its contents.
793 HTMLElement* element = toHTMLElement(node);
794 next = NodeTraversal::nextSkippingChildren(*node); 795 next = NodeTraversal::nextSkippingChildren(*node);
795 if (!style->style()) 796 if (!style->style())
796 continue; 797 continue;
797 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleO rCreateEmpty(element->inlineStyle()); 798 RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleO rCreateEmpty(element->inlineStyle());
798 inlineStyle->mergeAndOverrideOnConflict(style->style()); 799 inlineStyle->mergeAndOverrideOnConflict(style->style());
799 setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asTex t())); 800 setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asTex t()));
800 continue; 801 continue;
801 } 802 }
802 803
803 if (isBlock(node.get())) 804 if (isBlock(node.get()))
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 for (RefPtrWillBeRawPtr<Node> node = next; node && node->inDocument() && nod e != pastEndNode; node = next) { 883 for (RefPtrWillBeRawPtr<Node> node = next; node && node->inDocument() && nod e != pastEndNode; node = next) {
883 if (editingIgnoresContent(node.get())) { 884 if (editingIgnoresContent(node.get())) {
884 ASSERT(!node->contains(pastEndNode.get())); 885 ASSERT(!node->contains(pastEndNode.get()));
885 next = NodeTraversal::nextSkippingChildren(*node); 886 next = NodeTraversal::nextSkippingChildren(*node);
886 } else { 887 } else {
887 next = NodeTraversal::next(*node); 888 next = NodeTraversal::next(*node);
888 } 889 }
889 if (!node->isHTMLElement()) 890 if (!node->isHTMLElement())
890 continue; 891 continue;
891 892
892 RefPtrWillBeRawPtr<Node> previousSibling = node->previousSibling(); 893 HTMLElement& element = toHTMLElement(*node);
893 RefPtrWillBeRawPtr<Node> nextSibling = node->nextSibling(); 894 RefPtrWillBeRawPtr<Node> previousSibling = element.previousSibling();
894 RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode(); 895 RefPtrWillBeRawPtr<Node> nextSibling = element.nextSibling();
895 removeInlineStyleFromElement(style, toHTMLElement(node), RemoveAlways); 896 RefPtrWillBeRawPtr<ContainerNode> parent = element.parentNode();
896 if (!node->inDocument()) { 897 removeInlineStyleFromElement(style, &element, RemoveAlways);
898 if (!element.inDocument()) {
897 // FIXME: We might need to update the start and the end of current s election here but need a test. 899 // FIXME: We might need to update the start and the end of current s election here but need a test.
898 if (runStart == node) 900 if (runStart == element)
899 runStart = previousSibling ? previousSibling->nextSibling() : pa rent->firstChild(); 901 runStart = previousSibling ? previousSibling->nextSibling() : pa rent->firstChild();
900 if (runEnd == node) 902 if (runEnd == element)
901 runEnd = nextSibling ? nextSibling->previousSibling() : parent-> lastChild(); 903 runEnd = nextSibling ? nextSibling->previousSibling() : parent-> lastChild();
902 } 904 }
903 } 905 }
904 } 906 }
905 907
906 bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRe fPtrWillBeRawPtr<HTMLElement> element, InlineStyleRemovalMode mode, EditingStyle * extractedStyle) 908 bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRe fPtrWillBeRawPtr<HTMLElement> element, InlineStyleRemovalMode mode, EditingStyle * extractedStyle)
907 { 909 {
908 ASSERT(element); 910 ASSERT(element);
909 911
910 if (!element->parentNode() || !element->parentNode()->isContentEditable(Node ::UserSelectAllIsAlwaysNonEditable)) 912 if (!element->parentNode() || !element->parentNode()->isContentEditable(Node ::UserSelectAllIsAlwaysNonEditable))
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1134
1133 RefPtrWillBeRawPtr<Node> node = start.deprecatedNode(); 1135 RefPtrWillBeRawPtr<Node> node = start.deprecatedNode();
1134 while (node) { 1136 while (node) {
1135 RefPtrWillBeRawPtr<Node> next = nullptr; 1137 RefPtrWillBeRawPtr<Node> next = nullptr;
1136 if (editingIgnoresContent(node.get())) { 1138 if (editingIgnoresContent(node.get())) {
1137 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate dNode())); 1139 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate dNode()));
1138 next = NodeTraversal::nextSkippingChildren(*node); 1140 next = NodeTraversal::nextSkippingChildren(*node);
1139 } else { 1141 } else {
1140 next = NodeTraversal::next(*node); 1142 next = NodeTraversal::next(*node);
1141 } 1143 }
1142 if (node->isHTMLElement() && nodeFullySelected(node.get(), start, end)) { 1144 if (node->isHTMLElement() && elementFullySelected(toHTMLElement(*node), start, end)) {
1143 RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node); 1145 RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node);
1144 RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*el em); 1146 RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*el em);
1145 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem); 1147 RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem);
1146 RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = nullptr; 1148 RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = nullptr;
1147 RefPtrWillBeRawPtr<Node> childNode = nullptr; 1149 RefPtrWillBeRawPtr<Node> childNode = nullptr;
1148 if (isStyledInlineElementToRemove(elem.get())) { 1150 if (isStyledInlineElementToRemove(elem.get())) {
1149 styleToPushDown = EditingStyle::create(); 1151 styleToPushDown = EditingStyle::create();
1150 childNode = elem->firstChild(); 1152 childNode = elem->firstChild();
1151 } 1153 }
1152 1154
(...skipping 20 matching lines...) Expand all
1173 } 1175 }
1174 } 1176 }
1175 if (node == end.deprecatedNode()) 1177 if (node == end.deprecatedNode())
1176 break; 1178 break;
1177 node = next; 1179 node = next;
1178 } 1180 }
1179 1181
1180 updateStartEnd(s, e); 1182 updateStartEnd(s, e);
1181 } 1183 }
1182 1184
1183 bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, con st Position &end) const 1185 bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Positio n& start, const Position& end) const
1184 { 1186 {
1185 ASSERT(node); 1187 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout.
1186 ASSERT(node->isElementNode()); 1188 element.document().updateLayoutIgnorePendingStylesheets();
1187 1189
1188 // The tree may have changed and Position::upstream() relies on an up-to-dat e layout. 1190 return comparePositions(firstPositionInOrBeforeNode(&element), start) >= 0
1189 node->document().updateLayoutIgnorePendingStylesheets(); 1191 && comparePositions(lastPositionInOrAfterNode(&element).upstream(), end) <= 0;
1190
1191 return comparePositions(firstPositionInOrBeforeNode(node), start) >= 0
1192 && comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <= 0;
1193 } 1192 }
1194 1193
1195 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end) 1194 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end)
1196 { 1195 {
1197 ASSERT(start.containerNode()->isTextNode()); 1196 ASSERT(start.containerNode()->isTextNode());
1198 1197
1199 Position newEnd; 1198 Position newEnd;
1200 if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containe rNode() == end.containerNode()) 1199 if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containe rNode() == end.containerNode())
1201 newEnd = Position(end.containerText(), end.offsetInContainerNode() - sta rt.offsetInContainerNode()); 1200 newEnd = Position(end.containerText(), end.offsetInContainerNode() - sta rt.offsetInContainerNode());
1202 else 1201 else
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 } 1401 }
1403 setNodeAttribute(block, styleAttr, cssText.toAtomicString()); 1402 setNodeAttribute(block, styleAttr, cssText.toAtomicString());
1404 } 1403 }
1405 1404
1406 void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWi llBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, EAddStyled Element addStyledElement) 1405 void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWi llBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, EAddStyled Element addStyledElement)
1407 { 1406 {
1408 if (!passedStart || !passedEnd || !passedStart->inDocument() || !passedEnd-> inDocument()) 1407 if (!passedStart || !passedEnd || !passedStart->inDocument() || !passedEnd-> inDocument())
1409 return; 1408 return;
1410 1409
1411 RefPtrWillBeRawPtr<Node> start = passedStart; 1410 RefPtrWillBeRawPtr<Node> start = passedStart;
1412 RefPtrWillBeMember<Node> dummyElement = nullptr; 1411 RefPtrWillBeMember<HTMLSpanElement> dummyElement = nullptr;
1413 StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dum myElement)); 1412 StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dum myElement));
1414 1413
1415 if (dummyElement) 1414 if (dummyElement)
1416 removeNode(dummyElement); 1415 removeNode(dummyElement);
1417 1416
1418 applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement); 1417 applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement);
1419 } 1418 }
1420 1419
1421 Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeR awPtr<Node> startNode, RefPtrWillBeMember<Node>& dummyElement) 1420 Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeR awPtr<Node> startNode, RefPtrWillBeMember<HTMLSpanElement>& dummyElement)
1422 { 1421 {
1423 // It's okay to obtain the style at the startNode because we've removed all relevant styles from the current run. 1422 // It's okay to obtain the style at the startNode because we've removed all relevant styles from the current run.
1424 if (!startNode->isElementNode()) { 1423 if (!startNode->isElementNode()) {
1425 dummyElement = createStyleSpanElement(document()); 1424 dummyElement = createStyleSpanElement(document());
1426 insertNodeAt(dummyElement, positionBeforeNode(startNode.get())); 1425 insertNodeAt(dummyElement, positionBeforeNode(startNode.get()));
1427 return positionBeforeNode(dummyElement.get()); 1426 return positionBeforeNode(dummyElement.get());
1428 } 1427 }
1429 1428
1430 return firstPositionInOrBeforeNode(startNode.get()); 1429 return firstPositionInOrBeforeNode(startNode.get());
1431 } 1430 }
1432 1431
1433 void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> pass edStart, PassRefPtrWillBeRawPtr<Node> passedEnd, StyleChange& styleChange, EAddS tyledElement addStyledElement) 1432 void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> pass edStart, PassRefPtrWillBeRawPtr<Node> passedEnd, StyleChange& styleChange, EAddS tyledElement addStyledElement)
1434 { 1433 {
1435 RefPtrWillBeRawPtr<Node> startNode = passedStart; 1434 RefPtrWillBeRawPtr<Node> startNode = passedStart;
1436 RefPtrWillBeRawPtr<Node> endNode = passedEnd; 1435 RefPtrWillBeRawPtr<Node> endNode = passedEnd;
1437 ASSERT(startNode->inDocument()); 1436 ASSERT(startNode->inDocument());
1438 ASSERT(endNode->inDocument()); 1437 ASSERT(endNode->inDocument());
1439 1438
1440 // Find appropriate font and span elements top-down. 1439 // Find appropriate font and span elements top-down.
1441 HTMLElement* fontContainer = 0; 1440 HTMLFontElement* fontContainer = 0;
1442 HTMLElement* styleContainer = 0; 1441 HTMLElement* styleContainer = 0;
1443 for (Node* container = startNode.get(); container && startNode == endNode; c ontainer = container->firstChild()) { 1442 for (Node* container = startNode.get(); container && startNode == endNode; c ontainer = container->firstChild()) {
1444 if (isHTMLFontElement(*container)) 1443 if (isHTMLFontElement(*container))
1445 fontContainer = toHTMLElement(container); 1444 fontContainer = toHTMLFontElement(container);
1446 bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer); 1445 bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer);
1447 if (container->isHTMLElement()) { 1446 if (container->isHTMLElement()) {
1448 HTMLElement* containerElement = toHTMLElement(container); 1447 HTMLElement* containerElement = toHTMLElement(container);
1449 if (isHTMLSpanElement(*containerElement) || (styleContainerIsNotSpan && containerElement->hasChildren())) 1448 if (isHTMLSpanElement(*containerElement) || (styleContainerIsNotSpan && containerElement->hasChildren()))
1450 styleContainer = toHTMLElement(container); 1449 styleContainer = toHTMLElement(container);
1451 } 1450 }
1452 if (!container->firstChild()) 1451 if (!container->firstChild())
1453 break; 1452 break;
1454 startNode = container->firstChild(); 1453 startNode = container->firstChild();
1455 endNode = container->lastChild(); 1454 endNode = container->lastChild();
1456 } 1455 }
1457 1456
1458 // Font tags need to go outside of CSS so that CSS font sizes override leagc y font sizes. 1457 // Font tags need to go outside of CSS so that CSS font sizes override leagc y font sizes.
1459 if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChan ge.applyFontSize()) { 1458 if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChan ge.applyFontSize()) {
1460 if (fontContainer) { 1459 if (fontContainer) {
1461 if (styleChange.applyFontColor()) 1460 if (styleChange.applyFontColor())
1462 setNodeAttribute(fontContainer, colorAttr, AtomicString(styleCha nge.fontColor())); 1461 setNodeAttribute(fontContainer, colorAttr, AtomicString(styleCha nge.fontColor()));
1463 if (styleChange.applyFontFace()) 1462 if (styleChange.applyFontFace())
1464 setNodeAttribute(fontContainer, faceAttr, AtomicString(styleChan ge.fontFace())); 1463 setNodeAttribute(fontContainer, faceAttr, AtomicString(styleChan ge.fontFace()));
1465 if (styleChange.applyFontSize()) 1464 if (styleChange.applyFontSize())
1466 setNodeAttribute(fontContainer, sizeAttr, AtomicString(styleChan ge.fontSize())); 1465 setNodeAttribute(fontContainer, sizeAttr, AtomicString(styleChan ge.fontSize()));
1467 } else { 1466 } else {
1468 RefPtrWillBeRawPtr<Element> fontElement = createFontElement(document ()); 1467 RefPtrWillBeRawPtr<HTMLFontElement> fontElement = createFontElement( document());
1469 if (styleChange.applyFontColor()) 1468 if (styleChange.applyFontColor())
1470 fontElement->setAttribute(colorAttr, AtomicString(styleChange.fo ntColor())); 1469 fontElement->setAttribute(colorAttr, AtomicString(styleChange.fo ntColor()));
1471 if (styleChange.applyFontFace()) 1470 if (styleChange.applyFontFace())
1472 fontElement->setAttribute(faceAttr, AtomicString(styleChange.fon tFace())); 1471 fontElement->setAttribute(faceAttr, AtomicString(styleChange.fon tFace()));
1473 if (styleChange.applyFontSize()) 1472 if (styleChange.applyFontSize())
1474 fontElement->setAttribute(sizeAttr, AtomicString(styleChange.fon tSize())); 1473 fontElement->setAttribute(sizeAttr, AtomicString(styleChange.fon tSize()));
1475 surroundNodeRangeWithElement(startNode, endNode, fontElement.get()); 1474 surroundNodeRangeWithElement(startNode, endNode, fontElement.get());
1476 } 1475 }
1477 } 1476 }
1478 1477
1479 if (styleChange.cssStyle().length()) { 1478 if (styleChange.cssStyle().length()) {
1480 if (styleContainer) { 1479 if (styleContainer) {
1481 if (const StylePropertySet* existingStyle = styleContainer->inlineSt yle()) { 1480 if (const StylePropertySet* existingStyle = styleContainer->inlineSt yle()) {
1482 String existingText = existingStyle->asText(); 1481 String existingText = existingStyle->asText();
1483 StringBuilder cssText; 1482 StringBuilder cssText;
1484 cssText.append(existingText); 1483 cssText.append(existingText);
1485 if (!existingText.isEmpty()) 1484 if (!existingText.isEmpty())
1486 cssText.append(' '); 1485 cssText.append(' ');
1487 cssText.append(styleChange.cssStyle()); 1486 cssText.append(styleChange.cssStyle());
1488 setNodeAttribute(styleContainer, styleAttr, cssText.toAtomicStri ng()); 1487 setNodeAttribute(styleContainer, styleAttr, cssText.toAtomicStri ng());
1489 } else { 1488 } else {
1490 setNodeAttribute(styleContainer, styleAttr, AtomicString(styleCh ange.cssStyle())); 1489 setNodeAttribute(styleContainer, styleAttr, AtomicString(styleCh ange.cssStyle()));
1491 } 1490 }
1492 } else { 1491 } else {
1493 RefPtrWillBeRawPtr<Element> styleElement = createStyleSpanElement(do cument()); 1492 RefPtrWillBeRawPtr<HTMLSpanElement> styleElement = createStyleSpanEl ement(document());
1494 styleElement->setAttribute(styleAttr, AtomicString(styleChange.cssSt yle())); 1493 styleElement->setAttribute(styleAttr, AtomicString(styleChange.cssSt yle()));
1495 surroundNodeRangeWithElement(startNode, endNode, styleElement.releas e()); 1494 surroundNodeRangeWithElement(startNode, endNode, styleElement.releas e());
1496 } 1495 }
1497 } 1496 }
1498 1497
1499 if (styleChange.applyBold()) 1498 if (styleChange.applyBold())
1500 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum ent(), bTag)); 1499 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum ent(), bTag));
1501 1500
1502 if (styleChange.applyItalic()) 1501 if (styleChange.applyItalic())
1503 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum ent(), iTag)); 1502 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum ent(), iTag));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 void ApplyStyleCommand::trace(Visitor* visitor) 1571 void ApplyStyleCommand::trace(Visitor* visitor)
1573 { 1572 {
1574 visitor->trace(m_style); 1573 visitor->trace(m_style);
1575 visitor->trace(m_start); 1574 visitor->trace(m_start);
1576 visitor->trace(m_end); 1575 visitor->trace(m_end);
1577 visitor->trace(m_styledInlineElement); 1576 visitor->trace(m_styledInlineElement);
1578 CompositeEditCommand::trace(visitor); 1577 CompositeEditCommand::trace(visitor);
1579 } 1578 }
1580 1579
1581 } 1580 }
OLDNEW
« no previous file with comments | « Source/core/editing/ApplyStyleCommand.h ('k') | Source/core/editing/WrapContentsInDummySpanCommand.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698