diff options
Diffstat (limited to 'WebCore/editing/EditorCommand.cpp')
-rw-r--r-- | WebCore/editing/EditorCommand.cpp | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp index 5a189d4..55750ff 100644 --- a/WebCore/editing/EditorCommand.cpp +++ b/WebCore/editing/EditorCommand.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "AtomicString.h" +#include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" @@ -89,64 +90,85 @@ static Frame* targetFrame(Frame* frame, Event* event) return node->document()->frame(); } -static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const String& propertyValue) +static bool applyCommandToFrame(Frame* frame, EditorCommandSource source, EditAction action, CSSMutableStyleDeclaration* style) { - RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create(); - style->setProperty(propertyID, propertyValue); // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that? switch (source) { case CommandFromMenuOrKeyBinding: - frame->editor()->applyStyleToSelection(style.get(), action); + frame->editor()->applyStyleToSelection(style, action); return true; case CommandFromDOM: case CommandFromDOMWithUserInterface: - frame->editor()->applyStyle(style.get()); + frame->editor()->applyStyle(style); return true; } ASSERT_NOT_REACHED(); return false; } -static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const char* propertyValue) +static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const String& propertyValue) { - return executeApplyStyle(frame, source, action, propertyID, String(propertyValue)); + RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create(); + style->setProperty(propertyID, propertyValue); + return applyCommandToFrame(frame, source, action, style.get()); } static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, int propertyValue) { RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create(); style->setProperty(propertyID, propertyValue); - // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that? - switch (source) { - case CommandFromMenuOrKeyBinding: - frame->editor()->applyStyleToSelection(style.get(), action); - return true; - case CommandFromDOM: - case CommandFromDOMWithUserInterface: - frame->editor()->applyStyle(style.get()); - return true; + return applyCommandToFrame(frame, source, action, style.get()); +} + +// FIXME: executeToggleStyleInList does not handle complicated cases such as <b><u>hello</u>world</b> properly. +// This function must use Editor::selectionHasStyle to determine the current style but we cannot fix this +// until https://bugs.webkit.org/show_bug.cgi?id=27818 is resolved. +static bool executeToggleStyleInList(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, CSSValue* value) +{ + ExceptionCode ec = 0; + Node* nodeToRemove = 0; + RefPtr<CSSComputedStyleDeclaration> selectionStyle = frame->selectionComputedStyle(nodeToRemove); + RefPtr<CSSValue> selectedCSSValue = selectionStyle->getPropertyCSSValue(propertyID); + String newStyle = "none"; + if (selectedCSSValue->isValueList()) { + RefPtr<CSSValueList> selectedCSSValueList = static_cast<CSSValueList*>(selectedCSSValue.get()); + if (!selectedCSSValueList->removeAll(value)) + selectedCSSValueList->append(value); + if (selectedCSSValueList->length()) + newStyle = selectedCSSValueList->cssText(); + + } else if (selectedCSSValue->cssText() == "none") + newStyle = value->cssText(); + + ASSERT(ec == 0); + if (nodeToRemove) { + nodeToRemove->remove(ec); + ASSERT(ec == 0); } - ASSERT_NOT_REACHED(); - return false; + + // FIXME: We shouldn't be having to convert new style into text. We should have setPropertyCSSValue. + RefPtr<CSSMutableStyleDeclaration> newMutableStyle = CSSMutableStyleDeclaration::create(); + newMutableStyle->setProperty(propertyID, newStyle,ec); + return applyCommandToFrame(frame, source, action, newMutableStyle.get()); } static bool executeToggleStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const char* offValue, const char* onValue) { RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create(); - style->setProperty(propertyID, onValue); - style->setProperty(propertyID, frame->editor()->selectionStartHasStyle(style.get()) ? offValue : onValue); - // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that? - switch (source) { - case CommandFromMenuOrKeyBinding: - frame->editor()->applyStyleToSelection(style.get(), action); - return true; - case CommandFromDOM: - case CommandFromDOMWithUserInterface: - frame->editor()->applyStyle(style.get()); - return true; - } - ASSERT_NOT_REACHED(); - return false; + style->setProperty(propertyID, onValue); // We need to add this style to pass it to selectionStartHasStyle / selectionHasStyle + + // Style is considered present when + // mac: present at the beginning of selection + // other: present throughout the selection + Settings* settings = frame->document()->settings(); + bool styleIsPresent; + if (settings && settings->editingBehavior() == EditingMacBehavior) + styleIsPresent = frame->editor()->selectionStartHasStyle(style.get()); + else + styleIsPresent = frame->editor()->selectionHasStyle(style.get()) == TrueTriState; + + style->setProperty(propertyID, styleIsPresent ? offValue : onValue); + return applyCommandToFrame(frame, source, action, style.get()); } static bool executeApplyParagraphStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const String& propertyValue) @@ -937,7 +959,8 @@ static bool executeSetMark(Frame* frame, Event*, EditorCommandSource, const Stri static bool executeStrikethrough(Frame* frame, Event*, EditorCommandSource source, const String&) { - return executeToggleStyle(frame, source, EditActionChangeAttributes, CSSPropertyWebkitTextDecorationsInEffect, "none", "line-through"); + RefPtr<CSSPrimitiveValue> lineThrough = CSSPrimitiveValue::createIdentifier(CSSValueLineThrough); + return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, lineThrough.get()); } static bool executeStyleWithCSS(Frame* frame, Event*, EditorCommandSource, const String& value) @@ -990,8 +1013,8 @@ static bool executeTranspose(Frame* frame, Event*, EditorCommandSource, const St static bool executeUnderline(Frame* frame, Event*, EditorCommandSource source, const String&) { - // FIXME: This currently clears overline, line-through, and blink as an unwanted side effect. - return executeToggleStyle(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, "none", "underline"); + RefPtr<CSSPrimitiveValue> underline = CSSPrimitiveValue::createIdentifier(CSSValueUnderline); + return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, underline.get()); } static bool executeUndo(Frame* frame, Event*, EditorCommandSource, const String&) |