Changeset 92695 in webkit


Ignore:
Timestamp:
Aug 9, 2011 12:10:32 PM (13 years ago)
Author:
rniwa@webkit.org
Message:

Source/WebCore: Repeated copy and paste result in nested font elements
https://bugs.webkit.org/show_bug.cgi?id=65824

Reviewed by Tony Chang.

Modified isInlineNodeWithStyle to match font element. Also made the function match strictly with those nodes that
ApplyStyleCommand may add to avoid removing non-styling elements. And fixed a regression from r81887 that
ReplaceSelectionCommand may remove non-editing styles such as border in the attempt to avoid nesting styling elements.

This patch paves the way to fix the bug 34564.

Tests: editing/pasteboard/paste-text-with-style-2.html

editing/pasteboard/paste-text-with-style-3.html
editing/pasteboard/paste-text-with-style-4.html

  • editing/EditingStyle.cpp:

(WebCore::HTMLElementEquivalent::matches): Takes const Element* instead of Element*.
(WebCore::HTMLAttributeEquivalent::matches): Ditto.
(WebCore::htmlElementEquivalents): Extracted from conflictsWithImplicitStyleOfElement.
(WebCore::EditingStyle::conflictsWithImplicitStyleOfElement): Calls htmlElementEquivalents.
(WebCore::EditingStyle::elementIsStyledSpanOrHTMLEquivalent): Added; determines whether an element is style span
or a styling element (e.g. b, i, font) possibly with editing style.

  • editing/EditingStyle.h:
  • editing/ReplaceSelectionCommand.cpp:

(WebCore::isInlineNodeWithStyle): Calls EditingStyle::elementIsStyledSpanOrHTMLEquivalent.
(WebCore::ReplaceSelectionCommand::doApply): More aggressively avoid nesting styling elements.

  • editing/htmlediting.cpp:

(WebCore::highestEnclosingNodeOfType):

  • editing/htmlediting.h:

LayoutTests: Repeated copy and paste result in nested style elements such as b and font
https://bugs.webkit.org/show_bug.cgi?id=65824

Reviewed by Tony Chang.

Added tests to ensure WebKit does not nest styling elements and does not remove elements with non-editing styles.
Also rebaselined several tests.

Because WebKit serializes all editing inheritable styles on copy, we should be able to remove all inline styles
at the insertion point on paste. And this patch removes inline style elements such as font and b more aggressively.
WebKit erroneously bolded the last words in paste-after-inline-style-element.html and paste-with-redundant-style.html
before this change set but this is no longer the case.

  • editing/pasteboard/5065605-expected.txt: Lost wrapping font and span elements.
  • editing/pasteboard/merge-end-1-expected.txt: Span is split but visually identical.
  • editing/pasteboard/merge-end-2-expected.txt: Ditto.
  • editing/pasteboard/paste-after-inline-style-element-expected.txt: No longer bolds "line 2" erroneously.
  • editing/pasteboard/paste-text-011-expected.txt: Lost wrapping font, b, and span elements.
  • editing/pasteboard/paste-text-with-style-2-expected.txt: Added.
  • editing/pasteboard/paste-text-with-style-2.html: Added.
  • editing/pasteboard/paste-text-with-style-3-expected.txt: Added.
  • editing/pasteboard/paste-text-with-style-3.html: Added.
  • editing/pasteboard/paste-text-with-style-4-expected.txt: Added.
  • editing/pasteboard/paste-text-with-style-4.html: Added.
  • editing/pasteboard/paste-with-redundant-style-expected.txt: Lost wrapping b.
  • editing/pasteboard/paste-with-redundant-style.html: Updated comments per rebaseline.
  • platform/chromium-win/editing/pasteboard/paste-text-011-expected.txt: Removed.
Location:
trunk
Files:
6 added
1 deleted
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r92692 r92695  
     12011-08-08  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Repeated copy and paste result in nested style elements such as b and font
     4        https://bugs.webkit.org/show_bug.cgi?id=65824
     5
     6        Reviewed by Tony Chang.
     7
     8        Added tests to ensure WebKit does not nest styling elements and does not remove elements with non-editing styles.
     9        Also rebaselined several tests.
     10
     11        Because WebKit serializes all editing inheritable styles on copy, we should be able to remove all inline styles
     12        at the insertion point on paste. And this patch removes inline style elements such as font and b more aggressively.
     13        WebKit erroneously bolded the last words in paste-after-inline-style-element.html and paste-with-redundant-style.html
     14        before this change set but this is no longer the case.
     15
     16        * editing/pasteboard/5065605-expected.txt: Lost wrapping font and span elements.
     17        * editing/pasteboard/merge-end-1-expected.txt: Span is split but visually identical.
     18        * editing/pasteboard/merge-end-2-expected.txt: Ditto.
     19        * editing/pasteboard/paste-after-inline-style-element-expected.txt: No longer bolds "line 2" erroneously.
     20        * editing/pasteboard/paste-text-011-expected.txt: Lost wrapping font, b, and span elements.
     21        * editing/pasteboard/paste-text-with-style-2-expected.txt: Added.
     22        * editing/pasteboard/paste-text-with-style-2.html: Added.
     23        * editing/pasteboard/paste-text-with-style-3-expected.txt: Added.
     24        * editing/pasteboard/paste-text-with-style-3.html: Added.
     25        * editing/pasteboard/paste-text-with-style-4-expected.txt: Added.
     26        * editing/pasteboard/paste-text-with-style-4.html: Added.
     27        * editing/pasteboard/paste-with-redundant-style-expected.txt: Lost wrapping b.
     28        * editing/pasteboard/paste-with-redundant-style.html: Updated comments per rebaseline.
     29        * platform/chromium-win/editing/pasteboard/paste-text-011-expected.txt: Removed.
     30
    1312011-08-09  Abhishek Arya  <inferno@chromium.org>
    232
  • trunk/LayoutTests/editing/pasteboard/5065605-expected.txt

    r92537 r92695  
    2222EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
    2323EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    24 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 24 of #text > FONT > DIV > SPAN > FONT > DIV > DIV > BODY > HTML > #document to 24 of #text > FONT > DIV > SPAN > FONT > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
     24EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 24 of #text > FONT > DIV > DIV > DIV > BODY > HTML > #document to 24 of #text > FONT > DIV > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    2525EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    2626EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     
    4141|     class="Apple-style-span"
    4242|     color="#ff0000"
    43 |     <span>
     43|     "This text should be red."
     44|   <div>
     45|     <font>
    4446|       class="Apple-style-span"
    45 |       style="color: rgb(0, 0, 0); "
    46 |       <font>
    47 |         class="Apple-style-span"
    48 |         color="#ff0000"
    49 |         "This text should be red."
    50 |       <div>
    51 |         <font>
    52 |           class="Apple-style-span"
    53 |           color="#ff0000"
    54 |           "This text should be red.<#selection-caret>"
     47|       color="#ff0000"
     48|       "This text should be red.<#selection-caret>"
  • trunk/LayoutTests/editing/pasteboard/merge-end-1-expected.txt

    r87477 r92695  
    33| <span>
    44|   "f"
    5 |   "bar"
     5| "bar"
     6| <span>
    67|   <br>
    7 |   "baz<#selection-caret>"
     8| "baz<#selection-caret>"
     9| <span>
    810|   "oo"
  • trunk/LayoutTests/editing/pasteboard/merge-end-2-expected.txt

    r87477 r92695  
    55EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    66EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    7 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > SPAN > DIV > BODY > HTML > #document to 3 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > SPAN > DIV > BODY > HTML > #document to 3 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
     7EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > DIV > BODY > HTML > #document to 3 of #text > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > DIV > BODY > HTML > #document to 3 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    88EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    99EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     
    1414| <span>
    1515|   "f"
    16 |   "bar"
     16| "bar"
     17| <span>
    1718|   <br>
    18 |   "baz<#selection-caret>"
     19| "baz<#selection-caret>"
     20| <span>
    1921|   "oo"
    2022| "bar"
  • trunk/LayoutTests/editing/pasteboard/paste-after-inline-style-element-expected.txt

    r86852 r92695  
    55|   <b>
    66|     "line 1 "
    7 |     "line 2<#selection-caret>"
    8 |     " "
     7|   "line 2<#selection-caret>"
     8|   " "
     9|   <b>
    910|     <br>
  • trunk/LayoutTests/editing/pasteboard/paste-text-011-expected.txt

    r92537 r92695  
    77EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of P > BODY > HTML > #document to 0 of P > BODY > HTML > #document givenAction:WebViewInsertActionPasted
    88EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    9 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 5 of #text > B > FONT > P > SPAN > B > FONT > P > BODY > HTML > #document to 5 of #text > B > FONT > P > SPAN > B > FONT > P > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
     9EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 5 of #text > B > FONT > P > P > BODY > HTML > #document to 5 of #text > B > FONT > P > P > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    1010EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    1111EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     
    2828|       "there"
    2929| <p>
    30 |   <font>
    31 |     face="Monaco"
    32 |     <b>
    33 |       <span>
    34 |         class="Apple-style-span"
    35 |         style="font-family: Times; font-weight: normal; "
    36 |         <p>
    37 |           <font>
    38 |             face="Monaco"
    39 |             <b>
    40 |               "hello"
    41 |         <p>
    42 |           <font>
    43 |             face="Monaco"
    44 |             <b>
    45 |               "there<#selection-caret>"
     30|   <p>
     31|     <font>
     32|       face="Monaco"
     33|       <b>
     34|         "hello"
     35|   <p>
     36|     <font>
     37|       face="Monaco"
     38|       <b>
     39|         "there<#selection-caret>"
    4640| "
    4741
  • trunk/LayoutTests/editing/pasteboard/paste-with-redundant-style-expected.txt

    r92620 r92695  
    11This tests pasting content with redundant inline style.
    2 You should not see any style attributes except one on the b element and there should be no spans.
     2You should not see any inline styles other than font-weight: bold and there should be exactly one span around WebKit.
     3| <em>
     4|   style="font-weight: bold; "
     5|   "hello world"
     6| <br>
     7| <span>
     8|   style="font-weight: bold;"
     9|   "WebKit"
     10| <br>
     11| <em>
     12|   "rocks<#selection-caret>"
    313| <b>
    414|   style="font-style: italic;"
    5 |   <em>
    6 |     "hello world"
    715|   <br>
    8 |   "WebKit"
    9 |   <br>
    10 |   <em>
    11 |     "rocks<#selection-caret>"
    12 |   <br>
  • trunk/LayoutTests/editing/pasteboard/paste-with-redundant-style.html

    r92620 r92695  
    1818
    1919Markup.description('This tests pasting content with redundant inline style.\n'
    20     + 'You should not see any style attributes except one on the b element and there should be no spans.');
     20    + 'You should not see any inline styles other than font-weight: bold and there should be exactly one span around WebKit.');
    2121Markup.dump('test');
    2222
  • trunk/Source/WebCore/ChangeLog

    r92694 r92695  
     12011-08-08  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Repeated copy and paste result in nested font elements
     4        https://bugs.webkit.org/show_bug.cgi?id=65824
     5
     6        Reviewed by Tony Chang.
     7
     8        Modified isInlineNodeWithStyle to match font element. Also made the function match strictly with those nodes that
     9        ApplyStyleCommand may add to avoid removing non-styling elements. And fixed a regression from r81887 that
     10        ReplaceSelectionCommand may remove non-editing styles such as border in the attempt to avoid nesting styling elements.
     11
     12        This patch paves the way to fix the bug 34564.
     13
     14        Tests: editing/pasteboard/paste-text-with-style-2.html
     15               editing/pasteboard/paste-text-with-style-3.html
     16               editing/pasteboard/paste-text-with-style-4.html
     17
     18        * editing/EditingStyle.cpp:
     19        (WebCore::HTMLElementEquivalent::matches): Takes const Element* instead of Element*.
     20        (WebCore::HTMLAttributeEquivalent::matches): Ditto.
     21        (WebCore::htmlElementEquivalents): Extracted from conflictsWithImplicitStyleOfElement.
     22        (WebCore::EditingStyle::conflictsWithImplicitStyleOfElement): Calls htmlElementEquivalents.
     23        (WebCore::EditingStyle::elementIsStyledSpanOrHTMLEquivalent): Added; determines whether an element is style span
     24        or a styling element (e.g. b, i, font) possibly with editing style.
     25        * editing/EditingStyle.h:
     26        * editing/ReplaceSelectionCommand.cpp:
     27        (WebCore::isInlineNodeWithStyle): Calls EditingStyle::elementIsStyledSpanOrHTMLEquivalent.
     28        (WebCore::ReplaceSelectionCommand::doApply): More aggressively avoid nesting styling elements.
     29        * editing/htmlediting.cpp:
     30        (WebCore::highestEnclosingNodeOfType):
     31        * editing/htmlediting.h:
     32
    1332011-08-09  Dmitry Lomov  <dslomov@google.com>
    234
  • trunk/Source/WebCore/editing/EditingStyle.cpp

    r92620 r92695  
    3939#include "FrameSelection.h"
    4040#include "HTMLFontElement.h"
     41#include "HTMLInterchange.h"
    4142#include "HTMLNames.h"
    4243#include "Node.h"
    4344#include "Position.h"
     45#include "QualifiedName.h"
    4446#include "RenderStyle.h"
    4547#include "StyledElement.h"
    4648#include "htmlediting.h"
     49#include <wtf/HashSet.h>
    4750
    4851namespace WebCore {
     
    97100
    98101    virtual ~HTMLElementEquivalent() { }
    99     virtual bool matches(Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
     102    virtual bool matches(const Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
    100103    virtual bool hasAttribute() const { return false; }
    101104    virtual bool propertyExistsInStyle(CSSStyleDeclaration* style) const { return style->getPropertyCSSValue(m_propertyID); }
     
    186189    }
    187190
    188     bool matches(Element* elem) const { return HTMLElementEquivalent::matches(elem) && elem->hasAttribute(m_attrName); }
     191    bool matches(const Element* elem) const { return HTMLElementEquivalent::matches(elem) && elem->hasAttribute(m_attrName); }
    189192    virtual bool hasAttribute() const { return true; }
    190193    virtual bool valueIsPresentInStyle(Element*, CSSStyleDeclaration*) const;
     
    633636}
    634637
     638static const Vector<OwnPtr<HTMLElementEquivalent> >& htmlElementEquivalents()
     639{
     640    DEFINE_STATIC_LOCAL(Vector<OwnPtr<HTMLElementEquivalent> >, HTMLElementEquivalents, ());
     641
     642    if (!HTMLElementEquivalents.size()) {
     643        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag));
     644        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag));
     645        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSub, HTMLNames::subTag));
     646        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSuper, HTMLNames::supTag));
     647        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::iTag));
     648        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::emTag));
     649
     650        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueUnderline, HTMLNames::uTag));
     651        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::sTag));
     652        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::strikeTag));
     653    }
     654
     655    return HTMLElementEquivalents;
     656}
     657
     658
    635659bool EditingStyle::conflictsWithImplicitStyleOfElement(HTMLElement* element, EditingStyle* extractedStyle, ShouldExtractMatchingStyle shouldExtractMatchingStyle) const
    636660{
     
    638662        return false;
    639663
    640     static const HTMLElementEquivalent* HTMLEquivalents[] = {
    641         HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag).leakPtr(),
    642         HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag).leakPtr(),
    643         HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSub, HTMLNames::subTag).leakPtr(),
    644         HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSuper, HTMLNames::supTag).leakPtr(),
    645         HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::iTag).leakPtr(),
    646         HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::emTag).leakPtr(),
    647 
    648         HTMLTextDecorationEquivalent::create(CSSValueUnderline, HTMLNames::uTag).leakPtr(),
    649         HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::sTag).leakPtr(),
    650         HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::strikeTag).leakPtr(),
    651     };
    652 
    653     for (size_t i = 0; i < WTF_ARRAY_LENGTH(HTMLEquivalents); ++i) {
    654         const HTMLElementEquivalent* equivalent = HTMLEquivalents[i];
     664    const Vector<OwnPtr<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
     665    for (size_t i = 0; i < HTMLElementEquivalents.size(); ++i) {
     666        const HTMLElementEquivalent* equivalent = HTMLElementEquivalents[i].get();
    655667        if (equivalent->matches(element) && equivalent->propertyExistsInStyle(m_mutableStyle.get())
    656668            && (shouldExtractMatchingStyle == ExtractMatchingStyle || !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) {
     
    668680
    669681    if (!HTMLAttributeEquivalents.size()) {
     682        // elementIsStyledSpanOrHTMLEquivalent depends on the fact each HTMLAttriuteEquivalent matches exactly one attribute
     683        // of exactly one element except dirAttr.
    670684        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr));
    671685        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr));
     
    729743{
    730744    return !m_mutableStyle || !getPropertiesNotIn(m_mutableStyle.get(), computedStyle(node).get())->length();
     745}
     746
     747bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* element)
     748{
     749    bool elementIsSpanOrElementEquivalent = false;
     750    if (element->hasTagName(HTMLNames::spanTag))
     751        elementIsSpanOrElementEquivalent = true;
     752    else {
     753        const Vector<OwnPtr<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
     754        size_t i;
     755        for (i = 0; i < HTMLElementEquivalents.size(); ++i) {
     756            if (HTMLElementEquivalents[i]->matches(element)) {
     757                elementIsSpanOrElementEquivalent = true;
     758                break;
     759            }
     760        }
     761    }
     762
     763    const NamedNodeMap* attributeMap = element->attributeMap();
     764    if (!attributeMap || attributeMap->isEmpty())
     765        return elementIsSpanOrElementEquivalent; // span, b, etc... without any attributes
     766
     767    unsigned matchedAttributes = 0;
     768    const Vector<OwnPtr<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
     769    for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
     770        if (HTMLAttributeEquivalents[i]->matches(element) && HTMLAttributeEquivalents[i]->attributeName() != HTMLNames::dirAttr)
     771            matchedAttributes++;
     772    }
     773
     774    if (!elementIsSpanOrElementEquivalent && !matchedAttributes)
     775        return false; // element is not a span, a html element equivalent, or font element.
     776   
     777    if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass)
     778        matchedAttributes++;
     779
     780    if (element->hasAttribute(HTMLNames::styleAttr)) {
     781        if (CSSMutableStyleDeclaration* style = element->inlineStyleDecl()) {
     782            CSSMutableStyleDeclaration::const_iterator end = style->end();
     783            for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
     784                bool matched = false;
     785                for (size_t i = 0; i < numEditingInheritableProperties; ++i) {
     786                    if (editingInheritableProperties[i] == it->id()) {
     787                        matched = true;
     788                        break;
     789                    }
     790                }
     791                if (!matched && it->id() != CSSPropertyBackgroundColor)
     792                    return false;
     793            }
     794        }
     795        matchedAttributes++;
     796    }
     797
     798    // font with color attribute, span with style attribute, etc...
     799    ASSERT(matchedAttributes <= attributeMap->length());
     800    return matchedAttributes >= attributeMap->length();
    731801}
    732802
  • trunk/Source/WebCore/editing/EditingStyle.h

    r92620 r92695  
    118118            Vector<QualifiedName>& conflictingAttributes, ShouldExtractMatchingStyle) const;
    119119    bool styleIsPresentInComputedStyleOfNode(Node*) const;
     120
     121    static bool elementIsStyledSpanOrHTMLEquivalent(const HTMLElement*);
     122
    120123    void prepareToApplyAt(const Position&, ShouldPreserveWritingDirection = DoNotPreserveWritingDirection);
    121124    void mergeTypingStyle(Document*);
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r92620 r92695  
    785785{
    786786    // We don't want to skip over any block elements.
    787     if (!node->renderer() || !node->renderer()->isInline())
     787    if (isBlock(node))
    788788        return false;
    789789
    790790    if (!node->isHTMLElement())
    791791        return false;
    792    
     792
    793793    // We can skip over elements whose class attribute is
    794794    // one of our internal classes.
    795795    const HTMLElement* element = static_cast<const HTMLElement*>(node);
    796796    AtomicString classAttributeValue = element->getAttribute(classAttr);
    797     if (classAttributeValue == AppleStyleSpanClass
    798         || classAttributeValue == AppleTabSpanClass
     797    if (classAttributeValue == AppleTabSpanClass
    799798        || classAttributeValue == AppleConvertedSpace
    800799        || classAttributeValue == ApplePasteAsQuotation)
    801800        return true;
    802801
    803     // We can skip inline elements that don't have attributes or whose only
    804     // attribute is the style attribute.
    805     const NamedNodeMap* attributeMap = element->attributeMap();
    806     if (!attributeMap || attributeMap->isEmpty() || (attributeMap->length() == 1 && element->hasAttribute(styleAttr)))
    807         return true;
    808 
    809     return false;
     802    return EditingStyle::elementIsStyledSpanOrHTMLEquivalent(element);
    810803}
    811804   
     
    959952    // our style spans and for positions inside list items
    960953    // since insertAsListItems already does the right thing.
    961     if (!m_matchStyle && !enclosingList(insertionPos.containerNode()) && isStyleSpan(fragment.firstChild())) {
     954    if (!m_matchStyle && !enclosingList(insertionPos.containerNode())) {
    962955        if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) {
    963             splitTextNodeContainingElement(insertionPos.containerText(), insertionPos.offsetInContainerNode());
     956            splitTextNode(insertionPos.containerText(), insertionPos.offsetInContainerNode());
    964957            insertionPos = firstPositionInNode(insertionPos.containerNode());
    965958        }
    966959
    967         // FIXME: isInlineNodeWithStyle does not check editability.
    968         if (RefPtr<Node> nodeToSplitTo = highestEnclosingNodeOfType(insertionPos, isInlineNodeWithStyle)) {
    969             if (insertionPos.containerNode() != nodeToSplitTo) {
    970                 nodeToSplitTo = splitTreeToNode(insertionPos.anchorNode(), nodeToSplitTo.get(), true).get();
     960        if (RefPtr<Node> nodeToSplitTo = highestEnclosingNodeOfType(insertionPos, isInlineNodeWithStyle, CannotCrossEditingBoundary,
     961            enclosingBlock(insertionPos.containerNode()))) {
     962            if (insertionPos.containerNode() != nodeToSplitTo->parentNode()) {
     963                nodeToSplitTo = splitTreeToNode(insertionPos.anchorNode(), nodeToSplitTo->parentNode()).get();
    971964                insertionPos = positionInParentBeforeNode(nodeToSplitTo.get());
    972965            }
  • trunk/Source/WebCore/editing/htmlediting.cpp

    r91788 r92695  
    608608}
    609609
    610 Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule)
     610Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule, Node* stayWithin)
    611611{
    612612    Node* highest = 0;
    613613    Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
    614     for (Node* n = p.containerNode(); n; n = n->parentNode()) {
     614    for (Node* n = p.containerNode(); n && n != stayWithin; n = n->parentNode()) {
    615615        if (root && !n->rendererIsEditable())
    616616            continue;
  • trunk/Source/WebCore/editing/htmlediting.h

    r91788 r92695  
    5656Node* highestAncestor(Node*);
    5757Node* highestEditableRoot(const Position&);
    58 Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
     58Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*),
     59    EditingBoundaryCrossingRule = CannotCrossEditingBoundary, Node* stayWithin = 0);
    5960Node* lowestEditableAncestor(Node*);   
    6061
Note: See TracChangeset for help on using the changeset viewer.