Changeset 87400 in webkit


Ignore:
Timestamp:
May 26, 2011 10:49:36 AM (13 years ago)
Author:
rniwa@webkit.org
Message:

2011-05-25 Ryosuke Niwa <rniwa@webkit.org>

Reviewed by Enrica Casucci.

WebKit duplicates styles from css rules on copy and paste
https://bugs.webkit.org/show_bug.cgi?id=61466

Fixed the bug by removing duplicate properties from inline style declarations in ReplaceSelectionCommand.
Also moved the code to obtain style from rules from markup.cpp to EditingStyle.cpp to share code.

Test: editing/pasteboard/style-from-rules.html

  • editing/EditingStyle.cpp: (WebCore::EditingStyle::EditingStyle): Added a null check. (WebCore::EditingStyle::extractFontSizeDelta): Ditto. (WebCore::styleFromMatchedRulesForElement): Moved from markup.cpp. (WebCore::EditingStyle::mergeStyleFromRules): Extracted from StyledMarkupAccumulator::appendElement. (WebCore::EditingStyle::mergeStyleFromRulesForSerialization): Ditto. (WebCore::EditingStyle::removeStyleFromRules): Added.
  • editing/EditingStyle.h:
  • editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline): Renamed from negateStyleRulesThatAffectAppearance; Calls removeStyleFromRules.
  • editing/markup.cpp: (WebCore::StyledMarkupAccumulator::appendElement): Calls mergeStyleFromRulesForSerialization. (WebCore::styleFromMatchedRulesAndInlineDecl): Calls mergeStyleFromRules; changed the return type from CSSMutableStyleDeclaration to EditingStyle. (WebCore::isElementPresentational): Calls styleFromMatchedRulesAndInlineDecl. (WebCore::shouldIncludeWrapperForFullySelectedRoot): Ditto. (WebCore::highestAncestorToWrapMarkup): Calls shouldIncludeWrapperForFullySelectedRoot. (WebCore::createMarkup): Calls styleFromMatchedRulesAndInlineDecl.

2011-05-25 Ryosuke Niwa <rniwa@webkit.org>

Reviewed by Enrica Casucci.

WebKit duplicates styles from css rules on copy and paste
https://bugs.webkit.org/show_bug.cgi?id=61466

Added a test to ensure Webkit does not leave redundant inline style declarations after paste.
Also rebaselined several tests that progressed.

  • editing/pasteboard/4922709-expected.txt:
  • editing/pasteboard/5780697-2-expected.txt:
  • editing/pasteboard/paste-text-012-expected.txt:
  • editing/pasteboard/style-from-rules-expected.txt: Added.
  • editing/pasteboard/style-from-rules.html: Added.
  • platform/chromium-win/editing/pasteboard/5780697-2-expected.txt:
Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r87399 r87400  
     12011-05-25  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Enrica Casucci.
     4
     5        WebKit duplicates styles from css rules on copy and paste
     6        https://bugs.webkit.org/show_bug.cgi?id=61466
     7
     8        Added a test to ensure Webkit does not leave redundant inline style declarations after paste.
     9        Also rebaselined several tests that progressed.
     10
     11        * editing/pasteboard/4922709-expected.txt:
     12        * editing/pasteboard/5780697-2-expected.txt:
     13        * editing/pasteboard/paste-text-012-expected.txt:
     14        * editing/pasteboard/style-from-rules-expected.txt: Added.
     15        * editing/pasteboard/style-from-rules.html: Added.
     16        * platform/chromium-win/editing/pasteboard/5780697-2-expected.txt:
     17
    1182011-05-26  Michael Schneider  <michschn@google.com>
    219
  • trunk/LayoutTests/editing/pasteboard/4922709-expected.txt

    r38529 r87400  
    22
    33
    4 <blockquote id="blockquote" type="cite" style="border-left-width: 2px; border-left-style: solid; border-left-color: blue; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 10px; color: blue; ">Hello World</blockquote>
     4<blockquote id="blockquote" type="cite">Hello World</blockquote>
    55<br>
    66<div>On Tuesday, Dave wrote:</div>
  • trunk/LayoutTests/editing/pasteboard/5780697-2-expected.txt

    r39075 r87400  
    11This tests for a bug where copying content from a document in quirksmode and pasting it would produce overlapping text because of a height: 1%; overflow: visible; rule. To run manually, paste into a document not in quirksmode. The paragraphs should not overlap. When you inspect the source, the paragraphs should have pixel values for the height property.
    22
    3 <p style="height: 54px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 54px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 54px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p>
     3<p style="height: 54px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 54px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 54px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p>
  • trunk/LayoutTests/editing/pasteboard/paste-text-012-expected.txt

    r86983 r87400  
    77
    88execCopyCommand: <div id="test" class="editing"><div><blockquote>foo</blockquote></div></div> <div class="editing"></div>
    9 execPasteCommand: <div id="test" class="editing"><div><blockquote>foo</blockquote></div></div> <div class="editing"><span class="Apple-style-span" style="font-size: medium; "><div id="test" class="editing" style="border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: red; border-right-color: red; border-bottom-color: red; border-left-color: red; padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; font-size: 24px; "><div><blockquote>foo</blockquote></div><div><br></div></div></span></div>
     9execPasteCommand: <div id="test" class="editing"><div><blockquote>foo</blockquote></div></div> <div class="editing"><span class="Apple-style-span" style="font-size: medium; "><div id="test" class="editing"><div><blockquote>foo</blockquote></div><div><br></div></div></span></div>
  • trunk/LayoutTests/platform/chromium-win/editing/pasteboard/5780697-2-expected.txt

    r56271 r87400  
    11This tests for a bug where copying content from a document in quirksmode and pasting it would produce overlapping text because of a height: 1%; overflow: visible; rule. To run manually, paste into a document not in quirksmode. The paragraphs should not overlap. When you inspect the source, the paragraphs should have pixel values for the height property.
    22
    3 <p style="height: 60px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 60px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 60px; overflow-x: visible; overflow-y: visible; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p>
     3<p style="height: 60px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 60px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p><p style="height: 60px; ">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam interdum lacus id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque pulvinar, libero eu tincidunt adipiscing, quam arcu pharetra libero, sed aliquet leo eros vitae sapien.</p>
  • trunk/Source/WebCore/ChangeLog

    r87399 r87400  
     12011-05-25  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Enrica Casucci.
     4
     5        WebKit duplicates styles from css rules on copy and paste
     6        https://bugs.webkit.org/show_bug.cgi?id=61466
     7
     8        Fixed the bug by removing duplicate properties from inline style declarations in ReplaceSelectionCommand.
     9        Also moved the code to obtain style from rules from markup.cpp to EditingStyle.cpp to share code.
     10
     11        Test: editing/pasteboard/style-from-rules.html
     12
     13        * editing/EditingStyle.cpp:
     14        (WebCore::EditingStyle::EditingStyle): Added a null check.
     15        (WebCore::EditingStyle::extractFontSizeDelta): Ditto.
     16        (WebCore::styleFromMatchedRulesForElement): Moved from markup.cpp.
     17        (WebCore::EditingStyle::mergeStyleFromRules): Extracted from StyledMarkupAccumulator::appendElement.
     18        (WebCore::EditingStyle::mergeStyleFromRulesForSerialization): Ditto.
     19        (WebCore::EditingStyle::removeStyleFromRules): Added.
     20        * editing/EditingStyle.h:
     21        * editing/ReplaceSelectionCommand.cpp:
     22        (WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline): Renamed from
     23        negateStyleRulesThatAffectAppearance; Calls removeStyleFromRules.
     24        * editing/markup.cpp:
     25        (WebCore::StyledMarkupAccumulator::appendElement): Calls mergeStyleFromRulesForSerialization.
     26        (WebCore::styleFromMatchedRulesAndInlineDecl): Calls mergeStyleFromRules; changed the return type
     27        from CSSMutableStyleDeclaration to EditingStyle.
     28        (WebCore::isElementPresentational): Calls styleFromMatchedRulesAndInlineDecl.
     29        (WebCore::shouldIncludeWrapperForFullySelectedRoot): Ditto.
     30        (WebCore::highestAncestorToWrapMarkup): Calls shouldIncludeWrapperForFullySelectedRoot.
     31        (WebCore::createMarkup): Calls styleFromMatchedRulesAndInlineDecl.
     32
    1332011-05-26  Michael Schneider  <michschn@google.com>
    234
  • trunk/Source/WebCore/editing/EditingStyle.cpp

    r87082 r87400  
    3232#include "CSSMutableStyleDeclaration.h"
    3333#include "CSSParser.h"
     34#include "CSSStyleRule.h"
    3435#include "CSSStyleSelector.h"
    3536#include "CSSValueKeywords.h"
     
    284285
    285286EditingStyle::EditingStyle(const CSSStyleDeclaration* style)
    286     : m_mutableStyle(style->copy())
     287    : m_mutableStyle(style ? style->copy() : 0)
    287288    , m_shouldUseFixedDefaultFontSize(false)
    288289    , m_fontSizeDelta(NoFontDelta)
     
    383384void EditingStyle::extractFontSizeDelta()
    384385{
     386    if (!m_mutableStyle)
     387        return;
     388
    385389    if (m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize)) {
    386390        // Explicit font size overrides any delta.
     
    804808            textDecorations->append(lineThrough.get());
    805809    }
     810}
     811
     812static PassRefPtr<CSSMutableStyleDeclaration> styleFromMatchedRulesForElement(Element* element)
     813{
     814    RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
     815    RefPtr<CSSRuleList> matchedRules = element->document()->styleSelector()->styleRulesForElement(element,
     816        CSSStyleSelector::AuthorCSSRules | CSSStyleSelector::CrossOriginCSSRules);
     817    if (matchedRules) {
     818        for (unsigned i = 0; i < matchedRules->length(); i++) {
     819            if (matchedRules->item(i)->type() == CSSRule::STYLE_RULE) {
     820                RefPtr<CSSMutableStyleDeclaration> s = static_cast<CSSStyleRule*>(matchedRules->item(i))->style();
     821                style->merge(s.get(), true);
     822            }
     823        }
     824    }
     825   
     826    return style.release();
     827}
     828
     829void EditingStyle::mergeStyleFromRules(StyledElement* element)
     830{
     831    RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(element);
     832    // Styles from the inline style declaration, held in the variable "style", take precedence
     833    // over those from matched rules.
     834    if (m_mutableStyle)
     835        styleFromMatchedRules->merge(m_mutableStyle.get());
     836
     837    clear();
     838    m_mutableStyle = styleFromMatchedRules;
     839}
     840
     841void EditingStyle::mergeStyleFromRulesForSerialization(StyledElement* element)
     842{
     843    mergeStyleFromRules(element);
     844
     845    // The property value, if it's a percentage, may not reflect the actual computed value. 
     846    // For example: style="height: 1%; overflow: visible;" in quirksmode
     847    // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
     848    RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
     849    RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
     850    {
     851        CSSMutableStyleDeclaration::const_iterator end = m_mutableStyle->end();
     852        for (CSSMutableStyleDeclaration::const_iterator it = m_mutableStyle->begin(); it != end; ++it) {
     853            const CSSProperty& property = *it;
     854            CSSValue* value = property.value();
     855            if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
     856                if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
     857                    if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
     858                        fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
     859        }
     860    }
     861    m_mutableStyle->merge(fromComputedStyle.get());
     862}
     863
     864void EditingStyle::removeStyleFromRules(StyledElement* element)
     865{
     866    if (!m_mutableStyle)
     867        return;
     868
     869    RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(element);
     870    if (!styleFromMatchedRules)
     871        return;
     872
     873    m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), styleFromMatchedRules.get());
    806874}
    807875
  • trunk/Source/WebCore/editing/EditingStyle.h

    r87082 r87400  
    121121    void mergeTypingStyle(Document*);
    122122    void mergeInlineStyleOfElement(StyledElement*);
     123    void mergeStyleFromRules(StyledElement*);
     124    void mergeStyleFromRulesForSerialization(StyledElement*);
     125    void removeStyleFromRules(StyledElement*);
    123126
    124127    float fontSizeDelta() const { return m_fontSizeDelta; }
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r87248 r87400  
    477477// Style rules that match just inserted elements could change their appearance, like
    478478// a div inserted into a document with div { display:inline; }.
    479 void ReplaceSelectionCommand::negateStyleRulesThatAffectAppearance()
     479void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline()
    480480{
    481481    for (RefPtr<Node> node = m_firstNodeInserted.get(); node; node = node->traverseNextNode()) {
     
    493493            if (e->renderer() && e->renderer()->style()->floating() != FNONE)
    494494                e->getInlineStyleDecl()->setProperty(CSSPropertyFloat, CSSValueNone);
    495         }
     495        } else if (node->isStyledElement()) {
     496            StyledElement* element = static_cast<StyledElement*>(node.get());
     497            if (CSSMutableStyleDeclaration* inlineStyle = element->inlineStyleDecl()) {
     498                RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
     499                newInlineStyle->removeStyleFromRules(element);
     500                if (!newInlineStyle->style() || !newInlineStyle->style()->length())
     501                    removeNodeAttribute(element, styleAttr);
     502                else if (newInlineStyle->style()->length() < inlineStyle->length())
     503                    setNodeAttribute(element, styleAttr, newInlineStyle->style()->cssText());                   
     504            }
     505        }
     506
    496507        if (node == m_lastLeafInserted)
    497508            break;
     
    9961007    removeUnrenderedTextNodesAtEnds();
    9971008   
    998     negateStyleRulesThatAffectAppearance();
     1009    removeRedundantStylesAndKeepStyleSpanInline();
    9991010   
    10001011    if (!handledStyleSpans)
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.h

    r86983 r87400  
    7878    void removeUnrenderedTextNodesAtEnds();
    7979   
    80     void negateStyleRulesThatAffectAppearance();
     80    void removeRedundantStylesAndKeepStyleSpanInline();
    8181    void handleStyleSpans();
    8282    void copyStyleToChildren(Node* parentNode, const CSSMutableStyleDeclaration* parentStyle);
  • trunk/Source/WebCore/editing/markup.cpp

    r87317 r87400  
    137137    String renderedText(const Node*, const Range*);
    138138    String stringValueForRange(const Node*, const Range*);
    139     void removeExteriorStyles(CSSMutableStyleDeclaration*);
    140139    void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode);
    141140    void appendElement(Vector<UChar>& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
     
    240239}
    241240
    242 static PassRefPtr<CSSMutableStyleDeclaration> styleFromMatchedRulesForElement(Element* element)
    243 {
    244     RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
    245     RefPtr<CSSRuleList> matchedRules = element->document()->styleSelector()->styleRulesForElement(element,
    246         CSSStyleSelector::AuthorCSSRules | CSSStyleSelector::CrossOriginCSSRules);
    247     if (matchedRules) {
    248         for (unsigned i = 0; i < matchedRules->length(); i++) {
    249             if (matchedRules->item(i)->type() == CSSRule::STYLE_RULE) {
    250                 RefPtr<CSSMutableStyleDeclaration> s = static_cast<CSSStyleRule*>(matchedRules->item(i))->style();
    251                 style->merge(s.get(), true);
    252             }
    253         }
    254     }
    255 
    256     return style.release();
    257 }
    258 
    259241void StyledMarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
    260242{
     
    273255
    274256    if (element->isHTMLElement() && (shouldAnnotate() || addDisplayInline)) {
    275         RefPtr<CSSMutableStyleDeclaration> style = toHTMLElement(element)->getInlineStyleDecl()->copy();
    276         if (shouldAnnotate()) {
    277             RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(element));
    278             // Styles from the inline style declaration, held in the variable "style", take precedence
    279             // over those from matched rules.
    280             styleFromMatchedRules->merge(style.get());
    281             style = styleFromMatchedRules;
    282 
    283             RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);
    284             RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();
    285 
    286             {
    287                 CSSMutableStyleDeclaration::const_iterator end = style->end();
    288                 for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
    289                     const CSSProperty& property = *it;
    290                     CSSValue* value = property.value();
    291                     // The property value, if it's a percentage, may not reflect the actual computed value. 
    292                     // For example: style="height: 1%; overflow: visible;" in quirksmode
    293                     // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
    294                     if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
    295                         if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
    296                             if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
    297                                 fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
    298                 }
    299             }
    300             style->merge(fromComputedStyle.get());
    301         }
     257        RefPtr<EditingStyle> style = EditingStyle::create(toHTMLElement(element)->getInlineStyleDecl());
     258        if (shouldAnnotate())
     259            style->mergeStyleFromRulesForSerialization(toHTMLElement(element));
    302260        if (addDisplayInline)
    303             style->setProperty(CSSPropertyDisplay, CSSValueInline, true);
     261            style->style()->setProperty(CSSPropertyDisplay, CSSValueInline, true);
     262
    304263        // If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
    305264        // only the ones that affect it and the nodes within it.
    306265        if (rangeFullySelectsNode == DoesNotFullySelectNode)
    307             removeExteriorStyles(style.get());
    308         if (style->length() > 0) {
     266            style->style()->removeProperty(CSSPropertyFloat);
     267
     268        if (!style->isEmpty()) {
    309269            DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
    310270            append(out, stylePrefix);
    311             appendAttributeValue(out, style->cssText(), documentIsHTML);
     271            appendAttributeValue(out, style->style()->cssText(), documentIsHTML);
    312272            out.append('\"');
    313273        }
     
    315275
    316276    appendCloseTag(out, element);
    317 }
    318 
    319 void StyledMarkupAccumulator::removeExteriorStyles(CSSMutableStyleDeclaration* style)
    320 {
    321     style->removeProperty(CSSPropertyFloat);
    322277}
    323278
     
    448403}
    449404
    450 static PassRefPtr<CSSMutableStyleDeclaration> styleFromMatchedRulesAndInlineDecl(const Node* node)
     405static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
    451406{
    452407    if (!node->isHTMLElement())
     
    456411    // the non-const-ness of styleFromMatchedRulesForElement.
    457412    HTMLElement* element = const_cast<HTMLElement*>(static_cast<const HTMLElement*>(node));
    458     RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesForElement(element);
    459     RefPtr<CSSMutableStyleDeclaration> inlineStyleDecl = element->getInlineStyleDecl();
    460     style->merge(inlineStyleDecl.get());
     413    RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyleDecl());
     414    style->mergeStyleFromRules(element);
    461415    return style.release();
    462416}
     
    467421        || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
    468422        return true;
    469     RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesAndInlineDecl(node);
    470     if (!style)
    471         return false;
    472     return !propertyMissingOrEqualToNone(style.get(), CSSPropertyTextDecoration);
    473 }
    474 
    475 static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CSSMutableStyleDeclaration* style)
     423    RefPtr<EditingStyle> style = styleFromMatchedRulesAndInlineDecl(node);
     424    return style && style->style() && !propertyMissingOrEqualToNone(style->style(), CSSPropertyTextDecoration);
     425}
     426
     427static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot)
    476428{
    477429    if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
    478430        return true;
    479431   
    480     return style->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->getPropertyCSSValue(CSSPropertyBackgroundColor);
     432    RefPtr<EditingStyle> style = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
     433    if (!style || !style->style())
     434        return false;
     435
     436    return style->style()->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->style()->getPropertyCSSValue(CSSPropertyBackgroundColor);
    481437}
    482438
     
    516472        specialCommonAncestor = enclosingAnchor;
    517473
    518     if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot) {
    519         RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
    520         if (shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot, fullySelectedRootStyle.get()))
    521             specialCommonAncestor = fullySelectedRoot;
    522     }
     474    if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot && shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot))
     475        specialCommonAncestor = fullySelectedRoot;
     476
    523477    return specialCommonAncestor;
    524478}
     
    600554        for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
    601555            if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
    602                 RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
     556                RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
    603557
    604558                // Bring the background attribute over, but not as an attribute because a background attribute on a div
    605559                // appears to have no effect.
    606                 if (!fullySelectedRootStyle->getPropertyCSSValue(CSSPropertyBackgroundImage) && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
    607                     fullySelectedRootStyle->setProperty(CSSPropertyBackgroundImage, "url('" + static_cast<Element*>(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
    608                
    609                 if (fullySelectedRootStyle->length()) {
     560                if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundImage))
     561                    && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
     562                    fullySelectedRootStyle->style()->setProperty(CSSPropertyBackgroundImage, "url('" + static_cast<Element*>(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
     563
     564                if (fullySelectedRootStyle->style()) {
    610565                    // Reset the CSS properties to avoid an assertion error in addStyleMarkup().
    611566                    // This assertion is caused at least when we select all text of a <body> element whose
    612567                    // 'text-decoration' property is "inherit", and copy it.
    613                     if (!propertyMissingOrEqualToNone(fullySelectedRootStyle.get(), CSSPropertyTextDecoration))
    614                         fullySelectedRootStyle->setProperty(CSSPropertyTextDecoration, CSSValueNone);
    615                     if (!propertyMissingOrEqualToNone(fullySelectedRootStyle.get(), CSSPropertyWebkitTextDecorationsInEffect))
    616                         fullySelectedRootStyle->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
    617                     accumulator.wrapWithStyleNode(fullySelectedRootStyle.get(), document, true);
     568                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyTextDecoration))
     569                        fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
     570                    if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
     571                        fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
     572                    accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(), document, true);
    618573                }
    619574            } else {
Note: See TracChangeset for help on using the changeset viewer.