Commit 7e06f4ab authored by rniwa@webkit.org's avatar rniwa@webkit.org

2010-11-04 Ryosuke Niwa <rniwa@webkit.org>

        Reviewed by Darin Adler.

        Bug 46335 - Add EditingStyle
        https://bugs.webkit.org/show_bug.cgi?id=46335

        Added EditingStyle to WebCore/editing.  This class is intended to encapsulate getPropertiesNotIn, removeNonEditingProperties,
        editingStyleAtPosition, and prepareEditingStyleToApplyAt in ApplyStyleCommand.cpp once deployed everywhere.
        Deployed it in typing styles.

        No new tests are added since this is a refactoring in progress.

        * CMakeLists.txt: Added EditingStyle.cpp
        * GNUmakefile.am: Added EditingStyle.cpp and EditingStyle.h
        * WebCore.gypi: Ditto.
        * WebCore.pro: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * editing/CompositeEditCommand.cpp:
        (WebCore::CompositeEditCommand::moveParagraphs): Calls editingStyleIncludingTypingStyle.
        (WebCore::CompositeEditCommand::breakOutOfEmptyListItem): Uses EditingStyle.
        * editing/DeleteSelectionCommand.cpp:
        (WebCore::DeleteSelectionCommand::saveTypingStyleState): Ditto.
        (WebCore::DeleteSelectionCommand::calculateTypingStyleAfterDelete): Ditto.
        * editing/DeleteSelectionCommand.h:
        * editing/EditingStyle.cpp: Added.
        (WebCore::editingStyleFromComputedStyle): Added.
        (WebCore::EditingStyle::EditingStyle): Added.
        (WebCore::EditingStyle::init): Added; a clone of ApplyStyleCommand::editingStyleAtPosition.
        (WebCore::EditingStyle::removeTextFillAndStrokeColorsIfNeeded): Extracted from init.
        (WebCore::EditingStyle::replaceFontSizeByKeywordIfPossible): Extracted from init.
        (WebCore::EditingStyle::isEmpty): Added.
        (WebCore::EditingStyle::setStyle): Added.
        (WebCore::EditingStyle::clear): Added.
        (WebCore::EditingStyle::removeBlockProperties): Added.
        (WebCore::EditingStyle::prepareToApplyAt): Added.
        (WebCore::editingStyleIncludingTypingStyle): Added.
        * editing/EditingStyle.h: Added.
        (WebCore::EditingStyle::create): Added.
        (WebCore::EditingStyle::style): Added.
        * editing/RemoveFormatCommand.cpp:
        (WebCore::RemoveFormatCommand::doApply): Uses EditingStyle.
        * editing/SelectionController.h:
        (WebCore::SelectionController::typingStyle): Uses EditingStyle.
        (WebCore::SelectionController::clearTypingStyle): Uses EditingStyle.
        (WebCore::SelectionController::setTypingStyle): Uses EditingStyle.
        * rendering/style/RenderStyle.h: Added EditingStyle as a friend.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71469 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 147535a0
......@@ -900,6 +900,7 @@ SET(WebCore_SOURCES
editing/DeleteFromTextNodeCommand.cpp
editing/DeleteSelectionCommand.cpp
editing/EditCommand.cpp
editing/EditingStyle.cpp
editing/Editor.cpp
editing/EditorCommand.cpp
editing/FormatBlockCommand.cpp
......
2010-11-04 Ryosuke Niwa <rniwa@webkit.org>
Reviewed by Darin Adler.
Bug 46335 - Add EditingStyle
https://bugs.webkit.org/show_bug.cgi?id=46335
Added EditingStyle to WebCore/editing. This class is intended to encapsulate getPropertiesNotIn, removeNonEditingProperties,
editingStyleAtPosition, and prepareEditingStyleToApplyAt in ApplyStyleCommand.cpp once deployed everywhere.
Deployed it in typing styles.
No new tests are added since this is a refactoring in progress.
* CMakeLists.txt: Added EditingStyle.cpp
* GNUmakefile.am: Added EditingStyle.cpp and EditingStyle.h
* WebCore.gypi: Ditto.
* WebCore.pro: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::moveParagraphs): Calls editingStyleIncludingTypingStyle.
(WebCore::CompositeEditCommand::breakOutOfEmptyListItem): Uses EditingStyle.
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::saveTypingStyleState): Ditto.
(WebCore::DeleteSelectionCommand::calculateTypingStyleAfterDelete): Ditto.
* editing/DeleteSelectionCommand.h:
* editing/EditingStyle.cpp: Added.
(WebCore::editingStyleFromComputedStyle): Added.
(WebCore::EditingStyle::EditingStyle): Added.
(WebCore::EditingStyle::init): Added; a clone of ApplyStyleCommand::editingStyleAtPosition.
(WebCore::EditingStyle::removeTextFillAndStrokeColorsIfNeeded): Extracted from init.
(WebCore::EditingStyle::replaceFontSizeByKeywordIfPossible): Extracted from init.
(WebCore::EditingStyle::isEmpty): Added.
(WebCore::EditingStyle::setStyle): Added.
(WebCore::EditingStyle::clear): Added.
(WebCore::EditingStyle::removeBlockProperties): Added.
(WebCore::EditingStyle::prepareToApplyAt): Added.
(WebCore::editingStyleIncludingTypingStyle): Added.
* editing/EditingStyle.h: Added.
(WebCore::EditingStyle::create): Added.
(WebCore::EditingStyle::style): Added.
* editing/RemoveFormatCommand.cpp:
(WebCore::RemoveFormatCommand::doApply): Uses EditingStyle.
* editing/SelectionController.h:
(WebCore::SelectionController::typingStyle): Uses EditingStyle.
(WebCore::SelectionController::clearTypingStyle): Uses EditingStyle.
(WebCore::SelectionController::setTypingStyle): Uses EditingStyle.
* rendering/style/RenderStyle.h: Added EditingStyle as a friend.
2010-11-05 David Hyatt <hyatt@apple.com>
Reviewed by Dan Bernstein and Simon Fraser.
......@@ -1296,6 +1296,8 @@ webcore_sources += \
WebCore/editing/EditCommand.h \
WebCore/editing/EditingBehavior.h \
WebCore/editing/EditingBehaviorTypes.h \
WebCore/editing/EditingStyle.cpp \
WebCore/editing/EditingStyle.h \
WebCore/editing/EditorCommand.cpp \
WebCore/editing/Editor.cpp \
WebCore/editing/EditorDeleteAction.h \
......
......@@ -1383,6 +1383,8 @@
'editing/EditCommand.h',
'editing/EditingBehavior.h',
'editing/EditingBehaviorTypes.h',
'editing/EditingStyle.cpp',
'editing/EditingStyle.h',
'editing/Editor.cpp',
'editing/Editor.h',
'editing/EditorCommand.cpp',
......
......@@ -789,6 +789,7 @@ SOURCES += \
editing/DeleteFromTextNodeCommand.cpp \
editing/DeleteSelectionCommand.cpp \
editing/EditCommand.cpp \
editing/EditingStyle.cpp \
editing/Editor.cpp \
editing/EditorCommand.cpp \
editing/FormatBlockCommand.cpp \
......@@ -1700,6 +1701,7 @@ HEADERS += \
editing/DeleteFromTextNodeCommand.h \
editing/DeleteSelectionCommand.h \
editing/EditCommand.h \
editing/EditingStyle.h \
editing/EditingBehavior.h \
editing/Editor.h \
editing/FormatBlockCommand.h \
......
......@@ -46267,6 +46267,62 @@
RelativePath="..\editing\EditingBehaviorTypes.h"
>
</File>
<File
RelativePath="..\editing\EditingStyle.h"
>
</File>
<File
RelativePath="..\editing\EditingStyle.cpp"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug_Internal|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug_Cairo|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_Cairo|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug_All|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\editing\Editor.cpp"
>
......@@ -2988,6 +2988,8 @@
97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */; };
9B417064125662B3006B28FC /* ApplyBlockElementCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */; settings = {ATTRIBUTES = (Private, ); }; };
9B417065125662B3006B28FC /* ApplyBlockElementCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B417063125662B3006B28FC /* ApplyBlockElementCommand.cpp */; };
9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAB6C6A12550631001626D4 /* EditingStyle.h */; settings = {ATTRIBUTES = (Private, ); }; };
9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */; };
9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */; };
9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */; };
9F3B947E12241758005304E7 /* ScriptHeapSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */; };
......@@ -9089,6 +9091,8 @@
97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptControllerBase.cpp; sourceTree = "<group>"; };
9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplyBlockElementCommand.h; sourceTree = "<group>"; };
9B417063125662B3006B28FC /* ApplyBlockElementCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplyBlockElementCommand.cpp; sourceTree = "<group>"; };
9BAB6C6A12550631001626D4 /* EditingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingStyle.h; sourceTree = "<group>"; };
9BAB6C6B12550631001626D4 /* EditingStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditingStyle.cpp; sourceTree = "<group>"; };
9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProfilerAgent.cpp; sourceTree = "<group>"; };
9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProfilerAgent.h; sourceTree = "<group>"; };
9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptHeapSnapshot.h; sourceTree = "<group>"; };
......@@ -14526,6 +14530,8 @@
93309D95099E64910056E581 /* EditCommand.h */,
4F1534DD11B532EC0021FD86 /* EditingBehavior.h */,
4F1534DF11B533020021FD86 /* EditingBehaviorTypes.h */,
9BAB6C6A12550631001626D4 /* EditingStyle.h */,
9BAB6C6B12550631001626D4 /* EditingStyle.cpp */,
4B3043CA0AE0373B00A82647 /* Editor.cpp */,
4B3043CB0AE0373B00A82647 /* Editor.h */,
93A38B4A0D0E5808006872C2 /* EditorCommand.cpp */,
......@@ -19524,6 +19530,7 @@
93309DE4099E64920056E581 /* EditCommand.h in Headers */,
4F1534DE11B532EC0021FD86 /* EditingBehavior.h in Headers */,
4F1534E011B533020021FD86 /* EditingBehaviorTypes.h in Headers */,
9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */,
6550B6A4099DF0270090D781 /* EditingText.h in Headers */,
4B3043CD0AE0373B00A82647 /* Editor.h in Headers */,
1AF326790D78B9440068F0C4 /* EditorClient.h in Headers */,
......@@ -22175,6 +22182,7 @@
498771531243F9FA002226BA /* DrawingBufferMac.mm in Sources */,
BC7FA6200D1F0CBD00DB22A9 /* DynamicNodeList.cpp in Sources */,
93309DE3099E64920056E581 /* EditCommand.cpp in Sources */,
9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */,
6550B6A3099DF0270090D781 /* EditingText.cpp in Sources */,
4B3043CC0AE0373B00A82647 /* Editor.cpp in Sources */,
93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */,
......@@ -36,7 +36,6 @@
#include "Document.h"
#include "Editor.h"
#include "Frame.h"
#include "HTMLElement.h"
#include "HTMLFontElement.h"
#include "HTMLInterchange.h"
#include "HTMLNames.h"
......@@ -491,9 +490,9 @@ PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition
}
if (shouldIncludeTypingStyle == IncludeTypingStyle) {
CSSMutableStyleDeclaration* typingStyle = pos.node()->document()->frame()->selection()->typingStyle();
RefPtr<CSSMutableStyleDeclaration> typingStyle = pos.node()->document()->frame()->selection()->typingStyle();
if (typingStyle)
style->merge(typingStyle);
style->merge(typingStyle.get());
}
return style.release();
......
......@@ -27,6 +27,7 @@
#define ApplyStyleCommand_h
#include "CompositeEditCommand.h"
#include "HTMLElement.h"
namespace WebCore {
......
......@@ -937,9 +937,9 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// A non-empty paragraph's style is moved when we copy and move it. We don't move
// anything if we're given an empty paragraph, but an empty paragraph can have style
// too, <div><b><br></b></div> for example. Save it so that we can preserve it later.
RefPtr<CSSMutableStyleDeclaration> styleInEmptyParagraph;
RefPtr<EditingStyle> styleInEmptyParagraph;
if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) {
styleInEmptyParagraph = ApplyStyleCommand::editingStyleAtPosition(startOfParagraphToMove.deepEquivalent(), IncludeTypingStyle);
styleInEmptyParagraph = editingStyleIncludingTypingStyle(startOfParagraphToMove.deepEquivalent());
// The moved paragraph should assume the block style of the destination.
styleInEmptyParagraph->removeBlockProperties();
}
......@@ -983,8 +983,8 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// If the selection is in an empty paragraph, restore styles from the old empty paragraph to the new empty paragraph.
bool selectionIsEmptyParagraph = endingSelection().isCaret() && isStartOfParagraph(endingSelection().visibleStart()) && isEndOfParagraph(endingSelection().visibleStart());
if (styleInEmptyParagraph && selectionIsEmptyParagraph)
applyStyle(styleInEmptyParagraph.get());
applyStyle(styleInEmptyParagraph->style());
if (preserveSelection && startIndex != -1) {
// Fragment creation (using createMarkup) incorrectly uses regular
// spaces instead of nbsps for some spaces that were rendered (11475), which
......@@ -1005,7 +1005,7 @@ bool CompositeEditCommand::breakOutOfEmptyListItem()
if (!emptyListItem)
return false;
RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(endingSelection().start(), IncludeTypingStyle);
RefPtr<EditingStyle> style = editingStyleIncludingTypingStyle(endingSelection().start());
ContainerNode* listNode = emptyListItem->parentNode();
// FIXME: Can't we do something better when the immediate parent wasn't a list node?
......@@ -1054,10 +1054,10 @@ bool CompositeEditCommand::breakOutOfEmptyListItem()
appendBlockPlaceholder(newBlock);
setEndingSelection(VisibleSelection(Position(newBlock.get(), 0), DOWNSTREAM));
prepareEditingStyleToApplyAt(style.get(), endingSelection().start());
if (style->length())
applyStyle(style.get());
style->prepareToApplyAt(endingSelection().start());
if (!style->isEmpty())
applyStyle(style->style());
return true;
}
......
......@@ -294,14 +294,14 @@ void DeleteSelectionCommand::saveTypingStyleState()
return;
// Figure out the typing style in effect before the delete is done.
m_typingStyle = ApplyStyleCommand::editingStyleAtPosition(positionBeforeTabSpan(m_selectionToDelete.start()));
m_typingStyle = EditingStyle::create(positionBeforeTabSpan(m_selectionToDelete.start()));
removeEnclosingAnchorStyle(m_typingStyle.get(), m_selectionToDelete.start());
removeEnclosingAnchorStyle(m_typingStyle->style(), m_selectionToDelete.start());
// If we're deleting into a Mail blockquote, save the style at end() instead of start()
// We'll use this later in computeTypingStyleAfterDelete if we end up outside of a Mail blockquote
if (nearestMailBlockquote(m_selectionToDelete.start().node()))
m_deleteIntoBlockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(m_selectionToDelete.end());
m_deleteIntoBlockquoteStyle = EditingStyle::create(m_selectionToDelete.end());
else
m_deleteIntoBlockquoteStyle = 0;
}
......@@ -693,8 +693,8 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
m_typingStyle = m_deleteIntoBlockquoteStyle;
m_deleteIntoBlockquoteStyle = 0;
prepareEditingStyleToApplyAt(m_typingStyle.get(), m_endingPosition);
if (!m_typingStyle->length())
m_typingStyle->prepareToApplyAt(m_endingPosition);
if (m_typingStyle->isEmpty())
m_typingStyle = 0;
VisiblePosition visibleEnd(m_endingPosition);
if (m_typingStyle &&
......@@ -707,7 +707,7 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
// then move it back (which will clear typing style).
setEndingSelection(visibleEnd);
applyStyle(m_typingStyle.get(), EditActionUnspecified);
applyStyle(m_typingStyle->style(), EditActionUnspecified);
// applyStyle can destroy the placeholder that was at m_endingPosition if it needs to
// move it, but it will set an endingSelection() at [movedPlaceholder, 0] if it does so.
m_endingPosition = endingSelection().start();
......
......@@ -30,6 +30,8 @@
namespace WebCore {
class EditingStyle;
class DeleteSelectionCommand : public CompositeEditCommand {
public:
static PassRefPtr<DeleteSelectionCommand> create(Document* document, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false)
......@@ -86,8 +88,8 @@ private:
Position m_trailingWhitespace;
RefPtr<Node> m_startBlock;
RefPtr<Node> m_endBlock;
RefPtr<CSSMutableStyleDeclaration> m_typingStyle;
RefPtr<CSSMutableStyleDeclaration> m_deleteIntoBlockquoteStyle;
RefPtr<EditingStyle> m_typingStyle;
RefPtr<EditingStyle> m_deleteIntoBlockquoteStyle;
RefPtr<Node> m_startRoot;
RefPtr<Node> m_endRoot;
RefPtr<Node> m_startTableRow;
......
/*
* Copyright (C) 2007, 2008, 2009 Apple Computer, Inc.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "EditingStyle.h"
#include "ApplyStyleCommand.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSMutableStyleDeclaration.h"
#include "Frame.h"
#include "RenderStyle.h"
#include "SelectionController.h"
namespace WebCore {
static PassRefPtr<CSSMutableStyleDeclaration> editingStyleFromComputedStyle(CSSComputedStyleDeclaration* style)
{
if (!style)
return CSSMutableStyleDeclaration::create();
return ApplyStyleCommand::removeNonEditingProperties(style);
}
EditingStyle::EditingStyle()
: m_shouldUseFixedDefaultFontSize(false)
{
}
EditingStyle::EditingStyle(Node* node)
: m_shouldUseFixedDefaultFontSize(false)
{
init(node);
}
EditingStyle::EditingStyle(const Position& position)
: m_shouldUseFixedDefaultFontSize(false)
{
init(position.node());
}
EditingStyle::EditingStyle(const CSSStyleDeclaration* style)
: m_mutableStyle(style->copy())
, m_shouldUseFixedDefaultFontSize(false)
{
}
void EditingStyle::init(Node* node)
{
RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = computedStyle(node);
m_mutableStyle = editingStyleFromComputedStyle(computedStyleAtPosition.get());
if (node && node->computedStyle()) {
RenderStyle* renderStyle = node->computedStyle();
removeTextFillAndStrokeColorsIfNeeded(renderStyle);
replaceFontSizeByKeywordIfPossible(renderStyle, computedStyleAtPosition.get());
}
m_shouldUseFixedDefaultFontSize = computedStyleAtPosition->useFixedFontDefaultSize();
}
void EditingStyle::removeTextFillAndStrokeColorsIfNeeded(RenderStyle* renderStyle)
{
// If a node's text fill color is invalid, then its children use
// their font-color as their text fill color (they don't
// inherit it). Likewise for stroke color.
ExceptionCode ec = 0;
if (!renderStyle->textFillColor().isValid())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor, ec);
if (!renderStyle->textStrokeColor().isValid())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor, ec);
ASSERT(!ec);
}
void EditingStyle::replaceFontSizeByKeywordIfPossible(RenderStyle* renderStyle, CSSComputedStyleDeclaration* computedStyle)
{
ASSERT(renderStyle);
if (renderStyle->fontDescription().keywordSize())
m_mutableStyle->setProperty(CSSPropertyFontSize, computedStyle->getFontSizeCSSValuePreferringKeyword()->cssText());
}
bool EditingStyle::isEmpty() const
{
return !m_mutableStyle || m_mutableStyle->isEmpty();
}
void EditingStyle::setStyle(PassRefPtr<CSSMutableStyleDeclaration> style)
{
m_mutableStyle = style;
// FIXME: We should be able to figure out whether or not font is fixed width for mutable style.
// We need to check font-family is monospace as in FontDescription but we don't want to duplicate code here.
m_shouldUseFixedDefaultFontSize = false;
}
void EditingStyle::clear()
{
m_mutableStyle.clear();
m_shouldUseFixedDefaultFontSize = false;
}
void EditingStyle::removeBlockProperties()
{
if (!m_mutableStyle)
return;
m_mutableStyle->removeBlockProperties();
}
void EditingStyle::prepareToApplyAt(const Position& position)
{
// ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style.
// If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate
// which one of editingStyleAtPosition or computedStyle is called.
RefPtr<EditingStyle> style = EditingStyle::create(position);
style->m_mutableStyle->diff(m_mutableStyle.get());
// if alpha value is zero, we don't add the background color.
RefPtr<CSSValue> backgroundColor = m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor);
if (backgroundColor && backgroundColor->isPrimitiveValue()
&& !alphaChannel(static_cast<CSSPrimitiveValue*>(backgroundColor.get())->getRGBA32Value())) {
ExceptionCode ec;
m_mutableStyle->removeProperty(CSSPropertyBackgroundColor, ec);
}
}
PassRefPtr<EditingStyle> editingStyleIncludingTypingStyle(const Position& position)
{
RefPtr<EditingStyle> editingStyle = EditingStyle::create(position);
RefPtr<CSSMutableStyleDeclaration> typingStyle = position.node()->document()->frame()->selection()->typingStyle();
if (typingStyle) {
RefPtr<CSSMutableStyleDeclaration> inheritableTypingStyle = typingStyle->copy();
ApplyStyleCommand::removeNonEditingProperties(inheritableTypingStyle.get());
editingStyle->style()->merge(inheritableTypingStyle.get(), true);
}
return editingStyle;
}
}
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EditingStyle_h
#define EditingStyle_h
#include "CSSMutableStyleDeclaration.h"
#include "Document.h"
#include "Position.h"
namespace WebCore {
class CSSStyleDeclaration;
class CSSComputedStyleDeclaration;
class EditingStyle : public RefCounted<EditingStyle> {
public:
static PassRefPtr<EditingStyle> create()
{
return adoptRef(new EditingStyle());
}
static PassRefPtr<EditingStyle> create(Node* node)
{
return adoptRef(new EditingStyle(node));
}
static PassRefPtr<EditingStyle> create(const Position& position)
{
return adoptRef(new EditingStyle(position));
}
static PassRefPtr<EditingStyle> create(const CSSStyleDeclaration* style)
{
return adoptRef(new EditingStyle(style));
}
CSSMutableStyleDeclaration* style() { return m_mutableStyle.get(); }
bool isEmpty() const;
void setStyle(PassRefPtr<CSSMutableStyleDeclaration>);
void clear();
void removeBlockProperties();
void prepareToApplyAt(const Position&);
private:
EditingStyle();
EditingStyle(Node*);
EditingStyle(const Position&);
EditingStyle(const CSSStyleDeclaration*);
void init(Node*);
void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*);
void replaceFontSizeByKeywordIfPossible(RenderStyle*, CSSComputedStyleDeclaration*);
RefPtr<CSSMutableStyleDeclaration> m_mutableStyle;
bool m_shouldUseFixedDefaultFontSize;
};
PassRefPtr<EditingStyle> editingStyleIncludingTypingStyle(const Position&);
} // namespace WebCore
#endif // EditingStyle_h
......@@ -608,7 +608,8 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe
}
if (m_frame->selection()->isCaret()) {
if (CSSMutableStyleDeclaration* typingStyle = m_frame->selection()->typingStyle()) {
RefPtr<CSSMutableStyleDeclaration> typingStyle = m_frame->selection()->typingStyle();
if (typingStyle) {
RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
if (unicodeBidi) {
ASSERT(unicodeBidi->isPrimitiveValue());
......@@ -3053,7 +3054,7 @@ void Editor::computeAndSetTypingStyle(CSSStyleDeclaration* style, EditAction edi
applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction));
// Set the remaining style as the typing style.
m_frame->selection()->setTypingStyle(mutableStyle.release());
m_frame->selection()->setTypingStyle(EditingStyle::create(mutableStyle.get()));
}
PassRefPtr<CSSMutableStyleDeclaration> Editor::selectionComputedStyle(bool& shouldUseFixedFontDefaultSize) const
......
......@@ -165,14 +165,14 @@ void InsertLineBreakCommand::doApply()
// Handle the case where there is a typing style.
CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle();
if (typingStyle && typingStyle->length() > 0) {
// Apply the typing style to the inserted line break, so that if the selection
// leaves and then comes back, new input will have the right style.
// FIXME: We shouldn't always apply the typing style to the line break here,
// see <rdar://problem/5794462>.
applyStyle(typingStyle, firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get()));
applyStyle(typingStyle.get(), firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get()));
// Even though this applyStyle operates on a Range, it still sets an endingSelection().
// It tries to set a VisibleSelection around the content it operated on. So, that VisibleSelection
// will either (a) select the line break we inserted, or it will (b) be a caret just
......
......@@ -190,7 +190,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText)
setEndingSelection(forcedEndingSelection);
// Handle the case where there is a typing style.
CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle();
RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle();
RefPtr<CSSValue> unicodeBidi;
RefPtr<CSSValue> direction;
......@@ -198,7 +198,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText)
unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection);