| OLD | NEW |
| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 } | 97 } |
| 98 | 98 |
| 99 bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldSt
yleAttributeBeEmpty) | 99 bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldSt
yleAttributeBeEmpty) |
| 100 { | 100 { |
| 101 if (!element || !element->hasTagName(fontTag)) | 101 if (!element || !element->hasTagName(fontTag)) |
| 102 return false; | 102 return false; |
| 103 | 103 |
| 104 return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyl
eAttributeBeEmpty); | 104 return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyl
eAttributeBeEmpty); |
| 105 } | 105 } |
| 106 | 106 |
| 107 static PassRefPtr<Element> createFontElement(Document* document) | 107 static PassRefPtr<Element> createFontElement(Document& document) |
| 108 { | 108 { |
| 109 RefPtr<Element> fontNode = createHTMLElement(document, fontTag); | 109 RefPtr<Element> fontNode = createHTMLElement(document, fontTag); |
| 110 return fontNode.release(); | 110 return fontNode.release(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 PassRefPtr<HTMLElement> createStyleSpanElement(Document* document) | 113 PassRefPtr<HTMLElement> createStyleSpanElement(Document& document) |
| 114 { | 114 { |
| 115 RefPtr<HTMLElement> styleElement = createHTMLElement(document, spanTag); | 115 RefPtr<HTMLElement> styleElement = createHTMLElement(document, spanTag); |
| 116 return styleElement.release(); | 116 return styleElement.release(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
le, EditAction editingAction, EPropertyLevel propertyLevel) | 119 ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
le, EditAction editingAction, EPropertyLevel propertyLevel) |
| 120 : CompositeEditCommand(document) | 120 : CompositeEditCommand(document) |
| 121 , m_style(style->copy()) | 121 , m_style(style->copy()) |
| 122 , m_editingAction(editingAction) | 122 , m_editingAction(editingAction) |
| 123 , m_propertyLevel(propertyLevel) | 123 , m_propertyLevel(propertyLevel) |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(n
ode)) { | 372 for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(n
ode)) { |
| 373 RefPtr<HTMLElement> element; | 373 RefPtr<HTMLElement> element; |
| 374 if (node->isHTMLElement()) { | 374 if (node->isHTMLElement()) { |
| 375 // Only work on fully selected nodes. | 375 // Only work on fully selected nodes. |
| 376 if (!nodeFullySelected(node, start, end)) | 376 if (!nodeFullySelected(node, start, end)) |
| 377 continue; | 377 continue; |
| 378 element = toHTMLElement(node); | 378 element = toHTMLElement(node); |
| 379 } else if (node->isTextNode() && node->renderer() && node->parentNode()
!= lastStyledNode) { | 379 } else if (node->isTextNode() && node->renderer() && node->parentNode()
!= lastStyledNode) { |
| 380 // Last styled node was not parent node of this text node, but we wi
sh to style this | 380 // Last styled node was not parent node of this text node, but we wi
sh to style this |
| 381 // text node. To make this possible, add a style span to surround th
is text node. | 381 // text node. To make this possible, add a style span to surround th
is text node. |
| 382 RefPtr<HTMLElement> span = createStyleSpanElement(&document()); | 382 RefPtr<HTMLElement> span = createStyleSpanElement(document()); |
| 383 surroundNodeRangeWithElement(node, node, span.get()); | 383 surroundNodeRangeWithElement(node, node, span.get()); |
| 384 element = span.release(); | 384 element = span.release(); |
| 385 } else { | 385 } else { |
| 386 // Only handle HTML elements and text nodes. | 386 // Only handle HTML elements and text nodes. |
| 387 continue; | 387 continue; |
| 388 } | 388 } |
| 389 lastStyledNode = node; | 389 lastStyledNode = node; |
| 390 | 390 |
| 391 RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(ele
ment->inlineStyle()); | 391 RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(ele
ment->inlineStyle()); |
| 392 float currentFontSize = computedFontSize(node); | 392 float currentFontSize = computedFontSize(node); |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1397 removeNode(dummyElement); | 1397 removeNode(dummyElement); |
| 1398 | 1398 |
| 1399 applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement); | 1399 applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement); |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtr<Node>
startNode, RefPtr<Node>& dummyElement) | 1402 Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtr<Node>
startNode, RefPtr<Node>& dummyElement) |
| 1403 { | 1403 { |
| 1404 // It's okay to obtain the style at the startNode because we've removed all
relevant styles from the current run. | 1404 // It's okay to obtain the style at the startNode because we've removed all
relevant styles from the current run. |
| 1405 Position positionForStyleComparison; | 1405 Position positionForStyleComparison; |
| 1406 if (!startNode->isElementNode()) { | 1406 if (!startNode->isElementNode()) { |
| 1407 dummyElement = createStyleSpanElement(&document()); | 1407 dummyElement = createStyleSpanElement(document()); |
| 1408 insertNodeAt(dummyElement, positionBeforeNode(startNode.get())); | 1408 insertNodeAt(dummyElement, positionBeforeNode(startNode.get())); |
| 1409 return positionBeforeNode(dummyElement.get()); | 1409 return positionBeforeNode(dummyElement.get()); |
| 1410 } | 1410 } |
| 1411 | 1411 |
| 1412 return firstPositionInOrBeforeNode(startNode.get()); | 1412 return firstPositionInOrBeforeNode(startNode.get()); |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
sRefPtr<Node> passedEnd, StyleChange& styleChange, EAddStyledElement addStyledEl
ement) | 1415 void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
sRefPtr<Node> passedEnd, StyleChange& styleChange, EAddStyledElement addStyledEl
ement) |
| 1416 { | 1416 { |
| 1417 RefPtr<Node> startNode = passedStart; | 1417 RefPtr<Node> startNode = passedStart; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1437 // Font tags need to go outside of CSS so that CSS font sizes override leagc
y font sizes. | 1437 // Font tags need to go outside of CSS so that CSS font sizes override leagc
y font sizes. |
| 1438 if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChan
ge.applyFontSize()) { | 1438 if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChan
ge.applyFontSize()) { |
| 1439 if (fontContainer) { | 1439 if (fontContainer) { |
| 1440 if (styleChange.applyFontColor()) | 1440 if (styleChange.applyFontColor()) |
| 1441 setNodeAttribute(fontContainer, colorAttr, styleChange.fontColor
()); | 1441 setNodeAttribute(fontContainer, colorAttr, styleChange.fontColor
()); |
| 1442 if (styleChange.applyFontFace()) | 1442 if (styleChange.applyFontFace()) |
| 1443 setNodeAttribute(fontContainer, faceAttr, styleChange.fontFace()
); | 1443 setNodeAttribute(fontContainer, faceAttr, styleChange.fontFace()
); |
| 1444 if (styleChange.applyFontSize()) | 1444 if (styleChange.applyFontSize()) |
| 1445 setNodeAttribute(fontContainer, sizeAttr, styleChange.fontSize()
); | 1445 setNodeAttribute(fontContainer, sizeAttr, styleChange.fontSize()
); |
| 1446 } else { | 1446 } else { |
| 1447 RefPtr<Element> fontElement = createFontElement(&document()); | 1447 RefPtr<Element> fontElement = createFontElement(document()); |
| 1448 if (styleChange.applyFontColor()) | 1448 if (styleChange.applyFontColor()) |
| 1449 fontElement->setAttribute(colorAttr, styleChange.fontColor()); | 1449 fontElement->setAttribute(colorAttr, styleChange.fontColor()); |
| 1450 if (styleChange.applyFontFace()) | 1450 if (styleChange.applyFontFace()) |
| 1451 fontElement->setAttribute(faceAttr, styleChange.fontFace()); | 1451 fontElement->setAttribute(faceAttr, styleChange.fontFace()); |
| 1452 if (styleChange.applyFontSize()) | 1452 if (styleChange.applyFontSize()) |
| 1453 fontElement->setAttribute(sizeAttr, styleChange.fontSize()); | 1453 fontElement->setAttribute(sizeAttr, styleChange.fontSize()); |
| 1454 surroundNodeRangeWithElement(startNode, endNode, fontElement.get()); | 1454 surroundNodeRangeWithElement(startNode, endNode, fontElement.get()); |
| 1455 } | 1455 } |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 if (styleChange.cssStyle().length()) { | 1458 if (styleChange.cssStyle().length()) { |
| 1459 if (styleContainer) { | 1459 if (styleContainer) { |
| 1460 if (const StylePropertySet* existingStyle = styleContainer->inlineSt
yle()) { | 1460 if (const StylePropertySet* existingStyle = styleContainer->inlineSt
yle()) { |
| 1461 String existingText = existingStyle->asText(); | 1461 String existingText = existingStyle->asText(); |
| 1462 StringBuilder cssText; | 1462 StringBuilder cssText; |
| 1463 cssText.append(existingText); | 1463 cssText.append(existingText); |
| 1464 if (!existingText.isEmpty()) | 1464 if (!existingText.isEmpty()) |
| 1465 cssText.append(' '); | 1465 cssText.append(' '); |
| 1466 cssText.append(styleChange.cssStyle()); | 1466 cssText.append(styleChange.cssStyle()); |
| 1467 setNodeAttribute(styleContainer, styleAttr, cssText.toString()); | 1467 setNodeAttribute(styleContainer, styleAttr, cssText.toString()); |
| 1468 } else | 1468 } else |
| 1469 setNodeAttribute(styleContainer, styleAttr, styleChange.cssStyle
()); | 1469 setNodeAttribute(styleContainer, styleAttr, styleChange.cssStyle
()); |
| 1470 } else { | 1470 } else { |
| 1471 RefPtr<Element> styleElement = createStyleSpanElement(&document()); | 1471 RefPtr<Element> styleElement = createStyleSpanElement(document()); |
| 1472 styleElement->setAttribute(styleAttr, styleChange.cssStyle()); | 1472 styleElement->setAttribute(styleAttr, styleChange.cssStyle()); |
| 1473 surroundNodeRangeWithElement(startNode, endNode, styleElement.releas
e()); | 1473 surroundNodeRangeWithElement(startNode, endNode, styleElement.releas
e()); |
| 1474 } | 1474 } |
| 1475 } | 1475 } |
| 1476 | 1476 |
| 1477 if (styleChange.applyBold()) | 1477 if (styleChange.applyBold()) |
| 1478 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), bTag)); | 1478 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), bTag)); |
| 1479 | 1479 |
| 1480 if (styleChange.applyItalic()) | 1480 if (styleChange.applyItalic()) |
| 1481 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), iTag)); | 1481 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), iTag)); |
| 1482 | 1482 |
| 1483 if (styleChange.applyUnderline()) | 1483 if (styleChange.applyUnderline()) |
| 1484 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), uTag)); | 1484 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), uTag)); |
| 1485 | 1485 |
| 1486 if (styleChange.applyLineThrough()) | 1486 if (styleChange.applyLineThrough()) |
| 1487 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), strikeTag)); | 1487 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), strikeTag)); |
| 1488 | 1488 |
| 1489 if (styleChange.applySubscript()) | 1489 if (styleChange.applySubscript()) |
| 1490 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), subTag)); | 1490 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), subTag)); |
| 1491 else if (styleChange.applySuperscript()) | 1491 else if (styleChange.applySuperscript()) |
| 1492 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(&docu
ment(), supTag)); | 1492 surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(docum
ent(), supTag)); |
| 1493 | 1493 |
| 1494 if (m_styledInlineElement && addStyledElement == AddStyledElement) | 1494 if (m_styledInlineElement && addStyledElement == AddStyledElement) |
| 1495 surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->
cloneElementWithoutChildren()); | 1495 surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->
cloneElementWithoutChildren()); |
| 1496 } | 1496 } |
| 1497 | 1497 |
| 1498 float ApplyStyleCommand::computedFontSize(Node* node) | 1498 float ApplyStyleCommand::computedFontSize(Node* node) |
| 1499 { | 1499 { |
| 1500 if (!node) | 1500 if (!node) |
| 1501 return 0; | 1501 return 0; |
| 1502 | 1502 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 String textToMove = nextText->data(); | 1541 String textToMove = nextText->data(); |
| 1542 insertTextIntoNode(childText, childText->length(), textToMove); | 1542 insertTextIntoNode(childText, childText->length(), textToMove); |
| 1543 removeNode(next); | 1543 removeNode(next); |
| 1544 // don't move child node pointer. it may want to merge with more text no
des. | 1544 // don't move child node pointer. it may want to merge with more text no
des. |
| 1545 } | 1545 } |
| 1546 | 1546 |
| 1547 updateStartEnd(newStart, newEnd); | 1547 updateStartEnd(newStart, newEnd); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 } | 1550 } |
| OLD | NEW |