WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Dec 2007 20:26:56 +0000 (20:26 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Dec 2007 20:26:56 +0000 (20:26 +0000)
        Reviewed by Geoff.

        - exposed many new commands to the DOM Document executeCommand function by
          merging the JSEditor and Editor executeCommand implementations
        - replaced the execCommand function with a EditorCommand class
        - replaced the WTF::StrHash<> class template with the WebCore::StringHash class
        - replaced the WTF::CaseInsensitiveHash<> class template with the
          WebCore::CaseFoldingHash class

        * WebCore.base.exp: Updated.
        * WebCore.pro: Added EditorCommand.cpp, removed JSEditor.cpp.
        * WebCore.vcproj/WebCore.vcproj: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * WebCoreSources.bkl: Ditto.

        * dom/Document.cpp:
        (WebCore::Document::Document): Removed code to set up m_jsEditor.
        (WebCore::Document::~Document): Removed code to delete m_jsEditor.
        (WebCore::command): Added. Helper function that gets an Editor::Command.
        (WebCore::Document::executeCommand): Changed to use Editor::Command instead of
        JSEditor.
        (WebCore::Document::queryCommandEnabled): Ditto.
        (WebCore::Document::queryCommandIndeterm):
        (WebCore::Document::queryCommandState): Ditto.
        (WebCore::Document::queryCommandSupported): Ditto.
        (WebCore::Document::queryCommandValue): Ditto.

        * dom/Document.h: Removed JSEditor, jsEditor, m_jsEditor. Changed to
        use CaseFoldingHash.

        * editing/Editor.cpp:
        (WebCore::Editor::selectionForCommand): Renamed from selectionForEvent and
        made into a member function so it is accessible from the new EditorCommand.cpp file.
        Also changed to get the selection from the passed-in frame instead of from the
        page, because this should work on the targeted frame unless the event overrides it.
        (WebCore::Editor::handleKeypress): Updated for selectionForCommand change.
        (WebCore::Editor::handleInputMethodKeypress): Ditto.
        (WebCore::imageElementFromImageDocument): Renamed and changed to return
        a HTMLImageElement instead of a Node*.
        (WebCore::Editor::canCopy): Updated for name change.
        (WebCore::Editor::selectionUnorderedListState): Updated for TriState change.
        (WebCore::Editor::selectionOrderedListState): Ditto.
        (WebCore::Editor::selectionStartHasStyle): Make type of local more specific.
        (WebCore::updateState): Moved here from Frame.
        (WebCore::Editor::selectionHasStyle): Ditto.
        (WebCore::Editor::Editor): Initialize m_shouldStartNewKillRingSequence.
        (WebCore::Editor::insertTextWithoutSendingTextEvent): Updated for
        selectionForCommand change.
        (WebCore::Editor::copy): Updated for imageElementFromImageDocument change.
        (WebCore::Editor::toggleBold): Call the ToggleBold command via the command
        machinery since it's no longer in this file as a local function.
        (WebCore::Editor::toggleUnderline): Call the ToggleUnderline command.
        (WebCore::Editor::setBaseWritingDirection): Change type of argument and of
        local variable.
        (WebCore::Editor::addToKillRing): Moved here from EditorMac. Not useful
        without a kill ring, but it's relatively straightforward to implement one.
        (WebCore::Editor::appendToKillRing): Put default implementation here for
        platforms other than Mac. We should probably put a simple kill ring
        implementation here -- doesn't need to be shared with the OS oh platforms
        other than Mac.
        (WebCore::Editor::prependToKillRing): Ditto.
        (WebCore::Editor::yankFromKillRing): Ditto.
        (WebCore::Editor::startNewKillRingSequence): Ditto.
        (WebCore::Editor::setKillRingToYankedState): Ditto.

        * editing/Editor.h: Moved the TriState enum here instead of inside the
        Frame class. Added EditorCommandSource enum. Moved selectionHasStyle
        here from the Frame class. Added Editor::Command class with five functions
        for the various things you can do with a command (execute it, check if it
        can be used, and its state and value). Changed hte parameter of
        setBaseWritingDirection to be a const String& rather than a String.
        Got rid of the kill-ring-related operations, but added the kill ring
        functions themselves. Made selectedRange() public. Made the
        m_startNewKillRingSequence not Mac-specific and added "should" to its
        name.

        * editing/EditorCommand.cpp: Copied from WebCore/editing/Editor.cpp.
        Retained only the editing commands.
        (WebCore::targetFrame): Moved to the top of the file.
        (WebCore::executeApplyStyle): Added. Helper function for commands
        that need to apply styles.
        (WebCore::executeToggleStyle): Added. Helper function for commands
        that need to toggle styles based on the style of the start of selection.
        (WebCore::executeApplyParagraphStyle): Added. Like executeApplyStyle, but
        for paragraph styles.
        (WebCore::executeInsertFragment): Added. Helper function for commands
        that need to insert a DOM fragment.
        (WebCore::executeInsertNode): Added. Helper function for commands that
        need to insert a tree rooted in a single DOM node.
        (WebCore::stateStyle): Added. Helper function for the state of commands
        that represent style.
        (WebCore::valueStyle): Added. Helper function for the value of commands
        that represent style.
        (WebCore::canScroll): Added. Helper functions for some move and scroll
        commands that need to determine if the renderer they are in can scroll.
        (WebCore::unionDOMRanges): Moved here from EditorMac.
        (WebCore::executeBackColor):
        (WebCore::executeBackwardDelete):
        (WebCore::executeCopy):
        (WebCore::executeCreateLink):
        (WebCore::executeCut):
        (WebCore::executeDelete):
        (WebCore::executeDeleteToMark):
        (WebCore::executeDeleteWordBackward):
        (WebCore::executeDeleteWordForward):
        (WebCore::executeFindString):
        (WebCore::executeFontName):
        (WebCore::executeFontSize):
        (WebCore::executeFontSizeDelta):
        (WebCore::executeForeColor):
        (WebCore::executeFormatBlock):
        (WebCore::executeForwardDelete):
        (WebCore::executeIndent):
        (WebCore::executeInsertBacktab):
        (WebCore::executeInsertHorizontalRule):
        (WebCore::executeInsertHTML):
        (WebCore::executeInsertImage):
        (WebCore::executeInsertLineBreak):
        (WebCore::executeInsertNewline):
        (WebCore::executeInsertNewlineInQuotedContent):
        (WebCore::executeInsertOrderedList):
        (WebCore::executeInsertParagraph):
        (WebCore::executeInsertTab):
        (WebCore::executeInsertText):
        (WebCore::executeInsertUnorderedList):
        (WebCore::executeJustifyCenter):
        (WebCore::executeJustifyFull):
        (WebCore::executeJustifyLeft):
        (WebCore::executeJustifyRight):
        (WebCore::executeMoveBackward):
        (WebCore::executeMoveBackwardAndModifySelection):
        (WebCore::executeMoveDown):
        (WebCore::executeMoveDownAndModifySelection):
        (WebCore::executeMoveDownByPageAndModifyCaret):
        (WebCore::executeMoveForward):
        (WebCore::executeMoveForwardAndModifySelection):
        (WebCore::executeMoveLeft):
        (WebCore::executeMoveLeftAndModifySelection):
        (WebCore::executeMoveRight):
        (WebCore::executeMoveRightAndModifySelection):
        (WebCore::executeMoveToBeginningOfDocument):
        (WebCore::executeMoveToBeginningOfDocumentAndModifySelection):
        (WebCore::executeMoveToBeginningOfLine):
        (WebCore::executeMoveToBeginningOfLineAndModifySelection):
        (WebCore::executeMoveToBeginningOfParagraph):
        (WebCore::executeMoveToBeginningOfParagraphAndModifySelection):
        (WebCore::executeMoveToBeginningOfSentence):
        (WebCore::executeMoveToBeginningOfSentenceAndModifySelection):
        (WebCore::executeMoveToEndOfDocument):
        (WebCore::executeMoveToEndOfDocumentAndModifySelection):
        (WebCore::executeMoveToEndOfSentence):
        (WebCore::executeMoveToEndOfSentenceAndModifySelection):
        (WebCore::executeMoveToEndOfLine):
        (WebCore::executeMoveToEndOfLineAndModifySelection):
        (WebCore::executeMoveToEndOfParagraph):
        (WebCore::executeMoveToEndOfParagraphAndModifySelection):
        (WebCore::executeMoveParagraphBackwardAndModifySelection):
        (WebCore::executeMoveParagraphForwardAndModifySelection):
        (WebCore::executeMoveUp):
        (WebCore::executeMoveUpAndModifySelection):
        (WebCore::executeMoveUpByPageAndModifyCaret):
        (WebCore::executeMoveWordBackward):
        (WebCore::executeMoveWordBackwardAndModifySelection):
        (WebCore::executeMoveWordForward):
        (WebCore::executeMoveWordForwardAndModifySelection):
        (WebCore::executeMoveWordLeft):
        (WebCore::executeMoveWordLeftAndModifySelection):
        (WebCore::executeMoveWordRight):
        (WebCore::executeMoveWordRightAndModifySelection):
        (WebCore::executeOutdent):
        (WebCore::executePaste):
        (WebCore::executePasteAndMatchStyle):
        (WebCore::executePrint):
        (WebCore::executeRedo):
        (WebCore::executeRemoveFormat):
        (WebCore::executeSelectAll):
        (WebCore::executeSelectToMark):
        (WebCore::executeSetMark):
        (WebCore::executeStrikethrough):
        (WebCore::executeSubscript):
        (WebCore::executeSuperscript):
        (WebCore::executeSwapWithMark):
        (WebCore::executeToggleBold):
        (WebCore::executeToggleItalic):
        (WebCore::executeTranspose):
        (WebCore::executeUnderline):
        (WebCore::executeUndo):
        (WebCore::executeUnlink):
        (WebCore::executeUnscript):
        (WebCore::executeUnselect):
        (WebCore::executeYank):
        (WebCore::executeYankAndSelect):
        (WebCore::supported):
        (WebCore::supportedPaste):
        (WebCore::enabled):
        (WebCore::enabledAnySelection):
        (WebCore::enabledAnySelectionAndMark):
        (WebCore::enableCaretInEditableText):
        (WebCore::enabledCopy):
        (WebCore::enabledCut):
        (WebCore::enabledInEditableText):
        (WebCore::enabledInRichlyEditableText):
        (WebCore::enabledPaste):
        (WebCore::enabledRangeInEditableText):
        (WebCore::enabledRangeInRichlyEditableText):
        (WebCore::enabledRedo):
        (WebCore::enabledUndo):
        (WebCore::stateNone):
        (WebCore::stateBold):
        (WebCore::stateItalic):
        (WebCore::stateOrderedList):
        (WebCore::stateStrikethrough):
        (WebCore::stateSubscript):
        (WebCore::stateSuperscript):
        (WebCore::stateUnderline):
        (WebCore::stateUnorderedList):
        (WebCore::valueNull):
        (WebCore::valueBackColor):
        (WebCore::valueFontName):
        (WebCore::valueFontSize):
        (WebCore::valueFontSizeDelta):
        (WebCore::valueForeColor):
        (WebCore::createCommandMap): Added lots of commands, including all the commands
        from JSEditor. A few commands needed different behavior based on whether they are
        invoked from the DOM or a keyboard binding.
        (WebCore::Editor::command): Added. Gets a command object given a name.
        (WebCore::Editor::Command::Command): Added.
        (WebCore::Editor::Command::execute): Added.
        (WebCore::Editor::Command::isSupported): Added.
        (WebCore::Editor::Command::isEnabled): Added.
        (WebCore::Editor::Command::state): Added.
        (WebCore::Editor::Command::value): Added.
        (WebCore::Editor::execCommand): Changed to call command().execute().

        * editing/JSEditor.cpp: Removed.
        * editing/JSEditor.h: Removed.

        * editing/mac/EditorMac.mm: Changed to provide kill ring primitives intead of
        kill ring commands, so the kill ring commands can be cross-platform.
        (WebCore::Editor::appendToKillRing): Added.
        (WebCore::Editor::prependToKillRing): Added.
        (WebCore::Editor::yankFromKillRing): Added.
        (WebCore::Editor::startNewKillRingSequence): Added.
        (WebCore::Editor::setKillRingToYankedState): Added.

        * page/Frame.cpp: Removed selectionHasStyle, TriState, and updateState.
        * page/Frame.h: Ditto.

        * page/mac/WebCoreFrameBridge.mm: Removed selectionHasStyle.
        * page/mac/WebCoreFrameBridge.h: Ditto.

        * platform/ContextMenu.cpp:
        (WebCore::ContextMenu::checkOrEnableIfNeeded): Updated for TriState change.

        * platform/text/StringHash.h:
        (WebCore::StringHash::hash): Merged the StrHash<> template classes into this.
        (WebCore::StringHash::equal): Ditto.
        (WebCore::CaseFoldingHash::hash): Merged the CaseInsensitiveHash<> template
        classes into this.
        (WebCore::CaseFoldingHash::equal): Ditto.

        * platform/text/StringImpl.cpp:
        (WebCore::equal): Changed to invoke StringHash.
        (WebCore::equalIgnoringCase): Changed to invoke CaseFoldingHash.

        * dom/DOMImplementation.cpp:
        (WebCore::addString): Updated to use StringHash and CaseFoldingHash.
        (WebCore::isSVG10Feature): Ditto.
        (WebCore::isSVG11Feature): Ditto.
        * loader/FrameLoader.cpp:
        (WebCore::localSchemes): Ditto.
        * platform/graphics/FontCache.cpp:
        (WebCore::computeHash): Ditto.
        * platform/network/HTTPHeaderMap.h: Ditto.
        * platform/text/PlatformString.h: Ditto.
        * platform/text/StringImpl.h: Ditto.
        * rendering/RenderPartObject.cpp:
        (WebCore::RenderPartObject::updateWidget): Ditto.
        * xml/XMLHttpRequest.cpp:
        (WebCore::canSetRequestHeader): Ditto.

        * rendering/RenderTreeAsText.cpp: Removed stray include of JSEditor.h.

WebKit/mac:

        Reviewed by Geoff.

        - change more editing commands to use WebCore::Editor
        - change to use the new WebCore::Editor::command() function

        * WebView/WebHTMLView.mm: Changed alignCenter, alignJustified, alignLeft,
        alignRight, cut, copy, deleteToMark, indent, insertNewlineIgnoringFieldEditor,
        insertTabIgnoringFieldEditor, outdent, selectAll, selectToMark, setMark,
        subscript, superscript, swapWithMark, underline, unscript, yank, and yankAndSelect
        to use the "forward to WebCore" macro instead of having hand-written implementations.
        (kit): Added function to change a TriState to an AppKit-style tri-state value.
        (-[WebHTMLView coreCommandBySelector:]): Added. No longer converts case of the
        first character or copies the selector name, since the Editor commands are not case
        sensitive any more. Returns a command object.
        (-[WebHTMLView coreCommandByName:]): Added.
        (-[WebHTMLView executeCoreCommandBySelector:]): Renamed from callWebCoreCommand:,
        and changed to use the new coreCommandBySelector: method.
        (-[WebHTMLView executeCoreCommandByName:]): Added.
        (-[WebHTMLView validateUserInterfaceItemWithoutDelegate:]): Changed all the
        methods that call through to WebCore to also use the state() and isEnabled()
        functions on the commands for the menu item state and user interface item enabling.
        (-[WebHTMLView _handleStyleKeyEquivalent:]): Use ToggleBold and ToggleItalic by
        name rather than having local methods for them; no need for methods with a single
        call site.
        (-[WebHTMLView insertParagraphSeparator:]): Use executeCoreCommandByName: rather
        than the deprecated execCommand().
        (-[WebHTMLView doCommandBySelector:]): Changed to use command().execute() rather
        than the deprecated execCommand().
        * WebView/WebHTMLViewInternal.h: Removed some unneeded method declarations.

WebKit/win:

        * WebView.cpp:
        (WebView::handleEditingKeyboardEvent): Update for change to Editor API.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28626 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
WebCore/ChangeLog
WebCore/WebCore.base.exp
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/dom/DOMImplementation.cpp
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/editing/Editor.cpp
WebCore/editing/Editor.h
WebCore/editing/EditorCommand.cpp [new file with mode: 0644]
WebCore/editing/JSEditor.cpp [deleted file]
WebCore/editing/JSEditor.h [deleted file]
WebCore/editing/mac/EditorMac.mm
WebCore/loader/FrameLoader.cpp
WebCore/page/Frame.cpp
WebCore/page/Frame.h
WebCore/page/mac/WebCoreFrameBridge.h
WebCore/page/mac/WebCoreFrameBridge.mm
WebCore/platform/ContextMenu.cpp
WebCore/platform/graphics/FontCache.cpp
WebCore/platform/network/HTTPHeaderMap.h
WebCore/platform/text/PlatformString.h
WebCore/platform/text/StringHash.h
WebCore/platform/text/StringImpl.cpp
WebCore/platform/text/StringImpl.h
WebCore/rendering/RenderPartObject.cpp
WebCore/rendering/RenderTreeAsText.cpp
WebCore/xml/XMLHttpRequest.cpp
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebHTMLView.mm
WebKit/mac/WebView/WebHTMLViewInternal.h
WebKit/win/ChangeLog
WebKit/win/WebView.cpp

index 230a7443adb22d43d34975be51b1301e8e7614e9..87f88d3c9ff217a76c6de341519da836d9be4a0d 100644 (file)
@@ -1,3 +1,288 @@
+2007-12-11  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - exposed many new commands to the DOM Document executeCommand function by
+          merging the JSEditor and Editor executeCommand implementations
+        - replaced the execCommand function with a EditorCommand class
+        - replaced the WTF::StrHash<> class template with the WebCore::StringHash class
+        - replaced the WTF::CaseInsensitiveHash<> class template with the
+          WebCore::CaseFoldingHash class
+
+        * WebCore.base.exp: Updated.
+        * WebCore.pro: Added EditorCommand.cpp, removed JSEditor.cpp.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * WebCoreSources.bkl: Ditto.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document): Removed code to set up m_jsEditor.
+        (WebCore::Document::~Document): Removed code to delete m_jsEditor.
+        (WebCore::command): Added. Helper function that gets an Editor::Command.
+        (WebCore::Document::executeCommand): Changed to use Editor::Command instead of
+        JSEditor.
+        (WebCore::Document::queryCommandEnabled): Ditto.
+        (WebCore::Document::queryCommandIndeterm):
+        (WebCore::Document::queryCommandState): Ditto.
+        (WebCore::Document::queryCommandSupported): Ditto.
+        (WebCore::Document::queryCommandValue): Ditto.
+
+        * dom/Document.h: Removed JSEditor, jsEditor, m_jsEditor. Changed to
+        use CaseFoldingHash.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::selectionForCommand): Renamed from selectionForEvent and
+        made into a member function so it is accessible from the new EditorCommand.cpp file.
+        Also changed to get the selection from the passed-in frame instead of from the
+        page, because this should work on the targeted frame unless the event overrides it.
+        (WebCore::Editor::handleKeypress): Updated for selectionForCommand change.
+        (WebCore::Editor::handleInputMethodKeypress): Ditto.
+        (WebCore::imageElementFromImageDocument): Renamed and changed to return
+        a HTMLImageElement instead of a Node*.
+        (WebCore::Editor::canCopy): Updated for name change.
+        (WebCore::Editor::selectionUnorderedListState): Updated for TriState change.
+        (WebCore::Editor::selectionOrderedListState): Ditto.
+        (WebCore::Editor::selectionStartHasStyle): Make type of local more specific.
+        (WebCore::updateState): Moved here from Frame.
+        (WebCore::Editor::selectionHasStyle): Ditto.
+        (WebCore::Editor::Editor): Initialize m_shouldStartNewKillRingSequence.
+        (WebCore::Editor::insertTextWithoutSendingTextEvent): Updated for
+        selectionForCommand change.
+        (WebCore::Editor::copy): Updated for imageElementFromImageDocument change.
+        (WebCore::Editor::toggleBold): Call the ToggleBold command via the command
+        machinery since it's no longer in this file as a local function.
+        (WebCore::Editor::toggleUnderline): Call the ToggleUnderline command.
+        (WebCore::Editor::setBaseWritingDirection): Change type of argument and of
+        local variable.
+        (WebCore::Editor::addToKillRing): Moved here from EditorMac. Not useful
+        without a kill ring, but it's relatively straightforward to implement one.
+        (WebCore::Editor::appendToKillRing): Put default implementation here for
+        platforms other than Mac. We should probably put a simple kill ring
+        implementation here -- doesn't need to be shared with the OS oh platforms
+        other than Mac.
+        (WebCore::Editor::prependToKillRing): Ditto.
+        (WebCore::Editor::yankFromKillRing): Ditto.
+        (WebCore::Editor::startNewKillRingSequence): Ditto.
+        (WebCore::Editor::setKillRingToYankedState): Ditto.
+
+        * editing/Editor.h: Moved the TriState enum here instead of inside the
+        Frame class. Added EditorCommandSource enum. Moved selectionHasStyle
+        here from the Frame class. Added Editor::Command class with five functions
+        for the various things you can do with a command (execute it, check if it
+        can be used, and its state and value). Changed hte parameter of
+        setBaseWritingDirection to be a const String& rather than a String.
+        Got rid of the kill-ring-related operations, but added the kill ring
+        functions themselves. Made selectedRange() public. Made the
+        m_startNewKillRingSequence not Mac-specific and added "should" to its
+        name.
+
+        * editing/EditorCommand.cpp: Copied from WebCore/editing/Editor.cpp.
+        Retained only the editing commands.
+        (WebCore::targetFrame): Moved to the top of the file.
+        (WebCore::executeApplyStyle): Added. Helper function for commands
+        that need to apply styles.
+        (WebCore::executeToggleStyle): Added. Helper function for commands
+        that need to toggle styles based on the style of the start of selection.
+        (WebCore::executeApplyParagraphStyle): Added. Like executeApplyStyle, but
+        for paragraph styles.
+        (WebCore::executeInsertFragment): Added. Helper function for commands
+        that need to insert a DOM fragment.
+        (WebCore::executeInsertNode): Added. Helper function for commands that
+        need to insert a tree rooted in a single DOM node.
+        (WebCore::stateStyle): Added. Helper function for the state of commands
+        that represent style.
+        (WebCore::valueStyle): Added. Helper function for the value of commands
+        that represent style.
+        (WebCore::canScroll): Added. Helper functions for some move and scroll
+        commands that need to determine if the renderer they are in can scroll.
+        (WebCore::unionDOMRanges): Moved here from EditorMac.
+        (WebCore::executeBackColor):
+        (WebCore::executeBackwardDelete):
+        (WebCore::executeCopy):
+        (WebCore::executeCreateLink):
+        (WebCore::executeCut):
+        (WebCore::executeDelete):
+        (WebCore::executeDeleteToMark):
+        (WebCore::executeDeleteWordBackward):
+        (WebCore::executeDeleteWordForward):
+        (WebCore::executeFindString):
+        (WebCore::executeFontName):
+        (WebCore::executeFontSize):
+        (WebCore::executeFontSizeDelta):
+        (WebCore::executeForeColor):
+        (WebCore::executeFormatBlock):
+        (WebCore::executeForwardDelete):
+        (WebCore::executeIndent):
+        (WebCore::executeInsertBacktab):
+        (WebCore::executeInsertHorizontalRule):
+        (WebCore::executeInsertHTML):
+        (WebCore::executeInsertImage):
+        (WebCore::executeInsertLineBreak):
+        (WebCore::executeInsertNewline):
+        (WebCore::executeInsertNewlineInQuotedContent):
+        (WebCore::executeInsertOrderedList):
+        (WebCore::executeInsertParagraph):
+        (WebCore::executeInsertTab):
+        (WebCore::executeInsertText):
+        (WebCore::executeInsertUnorderedList):
+        (WebCore::executeJustifyCenter):
+        (WebCore::executeJustifyFull):
+        (WebCore::executeJustifyLeft):
+        (WebCore::executeJustifyRight):
+        (WebCore::executeMoveBackward):
+        (WebCore::executeMoveBackwardAndModifySelection):
+        (WebCore::executeMoveDown):
+        (WebCore::executeMoveDownAndModifySelection):
+        (WebCore::executeMoveDownByPageAndModifyCaret):
+        (WebCore::executeMoveForward):
+        (WebCore::executeMoveForwardAndModifySelection):
+        (WebCore::executeMoveLeft):
+        (WebCore::executeMoveLeftAndModifySelection):
+        (WebCore::executeMoveRight):
+        (WebCore::executeMoveRightAndModifySelection):
+        (WebCore::executeMoveToBeginningOfDocument):
+        (WebCore::executeMoveToBeginningOfDocumentAndModifySelection):
+        (WebCore::executeMoveToBeginningOfLine):
+        (WebCore::executeMoveToBeginningOfLineAndModifySelection):
+        (WebCore::executeMoveToBeginningOfParagraph):
+        (WebCore::executeMoveToBeginningOfParagraphAndModifySelection):
+        (WebCore::executeMoveToBeginningOfSentence):
+        (WebCore::executeMoveToBeginningOfSentenceAndModifySelection):
+        (WebCore::executeMoveToEndOfDocument):
+        (WebCore::executeMoveToEndOfDocumentAndModifySelection):
+        (WebCore::executeMoveToEndOfSentence):
+        (WebCore::executeMoveToEndOfSentenceAndModifySelection):
+        (WebCore::executeMoveToEndOfLine):
+        (WebCore::executeMoveToEndOfLineAndModifySelection):
+        (WebCore::executeMoveToEndOfParagraph):
+        (WebCore::executeMoveToEndOfParagraphAndModifySelection):
+        (WebCore::executeMoveParagraphBackwardAndModifySelection):
+        (WebCore::executeMoveParagraphForwardAndModifySelection):
+        (WebCore::executeMoveUp):
+        (WebCore::executeMoveUpAndModifySelection):
+        (WebCore::executeMoveUpByPageAndModifyCaret):
+        (WebCore::executeMoveWordBackward):
+        (WebCore::executeMoveWordBackwardAndModifySelection):
+        (WebCore::executeMoveWordForward):
+        (WebCore::executeMoveWordForwardAndModifySelection):
+        (WebCore::executeMoveWordLeft):
+        (WebCore::executeMoveWordLeftAndModifySelection):
+        (WebCore::executeMoveWordRight):
+        (WebCore::executeMoveWordRightAndModifySelection):
+        (WebCore::executeOutdent):
+        (WebCore::executePaste):
+        (WebCore::executePasteAndMatchStyle):
+        (WebCore::executePrint):
+        (WebCore::executeRedo):
+        (WebCore::executeRemoveFormat):
+        (WebCore::executeSelectAll):
+        (WebCore::executeSelectToMark):
+        (WebCore::executeSetMark):
+        (WebCore::executeStrikethrough):
+        (WebCore::executeSubscript):
+        (WebCore::executeSuperscript):
+        (WebCore::executeSwapWithMark):
+        (WebCore::executeToggleBold):
+        (WebCore::executeToggleItalic):
+        (WebCore::executeTranspose):
+        (WebCore::executeUnderline):
+        (WebCore::executeUndo):
+        (WebCore::executeUnlink):
+        (WebCore::executeUnscript):
+        (WebCore::executeUnselect):
+        (WebCore::executeYank):
+        (WebCore::executeYankAndSelect):
+        (WebCore::supported):
+        (WebCore::supportedPaste):
+        (WebCore::enabled):
+        (WebCore::enabledAnySelection):
+        (WebCore::enabledAnySelectionAndMark):
+        (WebCore::enableCaretInEditableText):
+        (WebCore::enabledCopy):
+        (WebCore::enabledCut):
+        (WebCore::enabledInEditableText):
+        (WebCore::enabledInRichlyEditableText):
+        (WebCore::enabledPaste):
+        (WebCore::enabledRangeInEditableText):
+        (WebCore::enabledRangeInRichlyEditableText):
+        (WebCore::enabledRedo):
+        (WebCore::enabledUndo):
+        (WebCore::stateNone):
+        (WebCore::stateBold):
+        (WebCore::stateItalic):
+        (WebCore::stateOrderedList):
+        (WebCore::stateStrikethrough):
+        (WebCore::stateSubscript):
+        (WebCore::stateSuperscript):
+        (WebCore::stateUnderline):
+        (WebCore::stateUnorderedList):
+        (WebCore::valueNull):
+        (WebCore::valueBackColor):
+        (WebCore::valueFontName):
+        (WebCore::valueFontSize):
+        (WebCore::valueFontSizeDelta):
+        (WebCore::valueForeColor):
+        (WebCore::createCommandMap): Added lots of commands, including all the commands
+        from JSEditor. A few commands needed different behavior based on whether they are
+        invoked from the DOM or a keyboard binding.
+        (WebCore::Editor::command): Added. Gets a command object given a name.
+        (WebCore::Editor::Command::Command): Added.
+        (WebCore::Editor::Command::execute): Added.
+        (WebCore::Editor::Command::isSupported): Added.
+        (WebCore::Editor::Command::isEnabled): Added.
+        (WebCore::Editor::Command::state): Added.
+        (WebCore::Editor::Command::value): Added.
+        (WebCore::Editor::execCommand): Changed to call command().execute().
+
+        * editing/JSEditor.cpp: Removed.
+        * editing/JSEditor.h: Removed.
+
+        * editing/mac/EditorMac.mm: Changed to provide kill ring primitives intead of
+        kill ring commands, so the kill ring commands can be cross-platform.
+        (WebCore::Editor::appendToKillRing): Added.
+        (WebCore::Editor::prependToKillRing): Added.
+        (WebCore::Editor::yankFromKillRing): Added.
+        (WebCore::Editor::startNewKillRingSequence): Added.
+        (WebCore::Editor::setKillRingToYankedState): Added.
+
+        * page/Frame.cpp: Removed selectionHasStyle, TriState, and updateState.
+        * page/Frame.h: Ditto.
+
+        * page/mac/WebCoreFrameBridge.mm: Removed selectionHasStyle.
+        * page/mac/WebCoreFrameBridge.h: Ditto.
+
+        * platform/ContextMenu.cpp:
+        (WebCore::ContextMenu::checkOrEnableIfNeeded): Updated for TriState change.
+
+        * platform/text/StringHash.h:
+        (WebCore::StringHash::hash): Merged the StrHash<> template classes into this.
+        (WebCore::StringHash::equal): Ditto.
+        (WebCore::CaseFoldingHash::hash): Merged the CaseInsensitiveHash<> template
+        classes into this.
+        (WebCore::CaseFoldingHash::equal): Ditto.
+
+        * platform/text/StringImpl.cpp:
+        (WebCore::equal): Changed to invoke StringHash.
+        (WebCore::equalIgnoringCase): Changed to invoke CaseFoldingHash.
+
+        * dom/DOMImplementation.cpp:
+        (WebCore::addString): Updated to use StringHash and CaseFoldingHash.
+        (WebCore::isSVG10Feature): Ditto.
+        (WebCore::isSVG11Feature): Ditto.
+        * loader/FrameLoader.cpp:
+        (WebCore::localSchemes): Ditto.
+        * platform/graphics/FontCache.cpp:
+        (WebCore::computeHash): Ditto.
+        * platform/network/HTTPHeaderMap.h: Ditto.
+        * platform/text/PlatformString.h: Ditto.
+        * platform/text/StringImpl.h: Ditto.
+        * rendering/RenderPartObject.cpp:
+        (WebCore::RenderPartObject::updateWidget): Ditto.
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::canSetRequestHeader): Ditto.
+
+        * rendering/RenderTreeAsText.cpp: Removed stray include of JSEditor.h.
+
 2007-12-11  Darin Adler  <darin@apple.com>
 
         * platform/wx/KeyboardEventWx.cpp:
index 0c0d6b9a764ddc1b25093fbdebc1e8b20f3ab199..673102263b891be1fe001b96f5fc77aaebd85f79 100644 (file)
@@ -329,6 +329,7 @@ __ZN7WebCore16NavigationActionC1Ev
 __ZN7WebCore16colorFromNSColorEP7NSColor
 __ZN7WebCore18PlatformMouseEventC1EP7NSEvent
 __ZN7WebCore18SecurityOriginDataC1ERKNS_6StringES3_t
+__ZN7WebCore19CSSStyleDeclaration11setPropertyERKNS_6StringES3_Ri
 __ZN7WebCore19InspectorController11showConsoleEv
 __ZN7WebCore19InspectorController12attachWindowEv
 __ZN7WebCore19InspectorController12detachWindowEv
@@ -354,13 +355,14 @@ __ZN7WebCore20JavaScriptStatistics24setShouldPrintExceptionsEb
 __ZN7WebCore20JavaScriptStatistics31garbageCollectOnAlternateThreadEb
 __ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx
 __ZN7WebCore21ContextMenuController16clearContextMenuEv
-__ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
 __ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS0_4TypeEb
+__ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
 __ZN7WebCore21WindowsLatin1EncodingEv
 __ZN7WebCore21findEventWithKeyStateEPNS_5EventE
 __ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
 __ZN7WebCore21reportThreadViolationEPKc
 __ZN7WebCore24notifyHistoryItemChangedE
+__ZN7WebCore26CSSMutableStyleDeclarationC1Ev
 __ZN7WebCore26NetscapePlugInStreamLoader6createEPNS_5FrameEP11objc_object
 __ZN7WebCore26usesTestModeFocusRingColorEv
 __ZN7WebCore29setUsesTestModeFocusRingColorEb
@@ -414,20 +416,10 @@ __ZN7WebCore5equalEPKNS_10StringImplEPKc
 __ZN7WebCore5equalEPKNS_10StringImplES2_
 __ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
 __ZN7WebCore6Editor10insertTextERKNS_6StringEPNS_5EventE
-__ZN7WebCore6Editor11canDHTMLCutEv
-__ZN7WebCore6Editor22isTextInsertionCommandERKNS_12AtomicStringE
-__ZN7WebCore6Editor11execCommandERKNS_12AtomicStringEPNS_5EventE
-__ZN7WebCore6Editor11tryDHTMLCutEv
-__ZN7WebCore6Editor12canDHTMLCopyEv
-__ZN7WebCore6Editor12deleteToMarkEv
-__ZN7WebCore6Editor12selectToMarkEv
-__ZN7WebCore6Editor12swapWithMarkEv
-__ZN7WebCore6Editor12tryDHTMLCopyEv
 __ZN7WebCore6Editor13canDHTMLPasteEv
 __ZN7WebCore6Editor13performDeleteEv
 __ZN7WebCore6Editor13rangeForPointERKNS_8IntPointE
 __ZN7WebCore6Editor13tryDHTMLPasteEv
-__ZN7WebCore6Editor13yankAndSelectEv
 __ZN7WebCore6Editor14setCompositionERKNS_6StringERKN3WTF6VectorINS_20CompositionUnderlineELm0EEEjj
 __ZN7WebCore6Editor16pasteAsPlainTextEv
 __ZN7WebCore6Editor17insertOrderedListEv
@@ -452,15 +444,17 @@ __ZN7WebCore6Editor35setIgnoreCompositionSelectionChangeEb
 __ZN7WebCore6Editor3cutEv
 __ZN7WebCore6Editor44confirmCompositionWithoutDisturbingSelectionEv
 __ZN7WebCore6Editor4copyEv
-__ZN7WebCore6Editor4yankEv
 __ZN7WebCore6Editor5pasteEv
 __ZN7WebCore6Editor6indentEv
+__ZN7WebCore6Editor7CommandC1Ev
+__ZN7WebCore6Editor7commandERKNS_6StringE
+__ZN7WebCore6Editor7commandERKNS_6StringENS_19EditorCommandSourceE
 __ZN7WebCore6Editor7copyURLERKNS_4KURLERKNS_6StringE
 __ZN7WebCore6Editor7outdentEv
-__ZN7WebCore6Editor7setMarkEv
 __ZN7WebCore6String6appendERKS0_
 __ZN7WebCore6StringC1EP8NSString
 __ZN7WebCore6StringC1EPKc
+__ZN7WebCore6StringC1EPKcj
 __ZN7WebCore6StringC1ERKNS_16DeprecatedStringE
 __ZN7WebCore6Widget7setViewEP6NSView
 __ZN7WebCore6WidgetC1EP6NSView
@@ -677,10 +671,16 @@ __ZNK7WebCore5Range19boundaryPointsValidEv
 __ZNK7WebCore5Range9endOffsetERi
 __ZNK7WebCore5Range9startNodeEv
 __ZNK7WebCore6Editor13canEditRichlyEv
+__ZNK7WebCore6Editor17selectionHasStyleEPNS_19CSSStyleDeclarationE
 __ZNK7WebCore6Editor17shouldDeleteRangeEPNS_5RangeE
 __ZNK7WebCore6Editor22selectionStartHasStyleEPNS_19CSSStyleDeclarationE
 __ZNK7WebCore6Editor23getCompositionSelectionERjS1_
 __ZNK7WebCore6Editor6canCutEv
+__ZNK7WebCore6Editor7Command15isTextInsertionEv
+__ZNK7WebCore6Editor7Command5stateEPNS_5EventE
+__ZNK7WebCore6Editor7Command7executeEPNS_5EventE
+__ZNK7WebCore6Editor7Command7executeERKNS_6StringEPNS_5EventE
+__ZNK7WebCore6Editor7Command9isEnabledEPNS_5EventE
 __ZNK7WebCore6Editor7canCopyEv
 __ZNK7WebCore6Editor7canEditEv
 __ZNK7WebCore6Editor8canPasteEv
index b8abe46518fba30110e7e2de0e9d5fe5f54fbbb8..9908121e4e2766650ef99725af4f34d0df4ae967 100644 (file)
@@ -527,6 +527,7 @@ SOURCES += \
     editing/DeleteSelectionCommand.cpp \
     editing/EditCommand.cpp \
     editing/Editor.cpp \
+    editing/EditorCommand.cpp \
     editing/FormatBlockCommand.cpp \
     editing/htmlediting.cpp \
     editing/HTMLInterchange.cpp \
@@ -538,7 +539,6 @@ SOURCES += \
     editing/InsertParagraphSeparatorCommand.cpp \
     editing/InsertTextCommand.cpp \
     editing/JoinTextNodesCommand.cpp \
-    editing/JSEditor.cpp \
     editing/markup.cpp \
     editing/MergeIdenticalElementsCommand.cpp \
     editing/ModifySelectionListLevel.cpp \
index 816af8f650260de3bf5f09e836ce25f3217a2712..52fd43ae8aef39125a9e3a0dd09eca0177e26919 100644 (file)
                                RelativePath="..\editing\Editor.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\editing\EditorCommand.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\editing\EditorDeleteAction.h"\r
                                >\r
                                RelativePath="..\editing\JoinTextNodesCommand.h"\r
                                >\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\editing\JSEditor.cpp"\r
-                               >\r
-                       </File>\r
-                       <File\r
-                               RelativePath="..\editing\JSEditor.h"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\editing\markup.cpp"\r
                                >\r
index ef107625b9122dbb44ac041879f890f8f0228d5d..3e26b7783ae56b16abeffa12d9343378144d7f2c 100644 (file)
                93309DF2099E64920056E581 /* InsertTextCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DA3099E64910056E581 /* InsertTextCommand.h */; };
                93309DF3099E64920056E581 /* JoinTextNodesCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DA4099E64910056E581 /* JoinTextNodesCommand.cpp */; };
                93309DF4099E64920056E581 /* JoinTextNodesCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DA5099E64910056E581 /* JoinTextNodesCommand.h */; };
-               93309DF5099E64920056E581 /* JSEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DA6099E64910056E581 /* JSEditor.cpp */; };
-               93309DF6099E64920056E581 /* JSEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DA7099E64910056E581 /* JSEditor.h */; };
                93309DF7099E64920056E581 /* markup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DA8099E64910056E581 /* markup.cpp */; };
                93309DF8099E64920056E581 /* markup.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DA9099E64910056E581 /* markup.h */; };
                93309DF9099E64920056E581 /* MergeIdenticalElementsCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DAA099E64910056E581 /* MergeIdenticalElementsCommand.cpp */; };
                939885C408B7E3D100E707C4 /* EventNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 939885C208B7E3D100E707C4 /* EventNames.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93A1EAA00A5634C9006960A0 /* ImageDocumentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93A1EA9F0A5634C9006960A0 /* ImageDocumentMac.mm */; };
                93A1EAA80A563508006960A0 /* ImageDocumentMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 93A1EAA70A563508006960A0 /* ImageDocumentMac.h */; };
+               93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93A38B4A0D0E5808006872C2 /* EditorCommand.cpp */; };
                93B6A0E60B0BCA5C00F5027A /* ContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93B6A0E80B0BCA6700F5027A /* ContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */; };
                93B6A0EA0B0BCA8400F5027A /* ContextMenuMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93B6A0E90B0BCA8400F5027A /* ContextMenuMac.mm */; };
                93309DA3099E64910056E581 /* InsertTextCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsertTextCommand.h; sourceTree = "<group>"; };
                93309DA4099E64910056E581 /* JoinTextNodesCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JoinTextNodesCommand.cpp; sourceTree = "<group>"; };
                93309DA5099E64910056E581 /* JoinTextNodesCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JoinTextNodesCommand.h; sourceTree = "<group>"; };
-               93309DA6099E64910056E581 /* JSEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEditor.cpp; sourceTree = "<group>"; };
-               93309DA7099E64910056E581 /* JSEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEditor.h; sourceTree = "<group>"; };
                93309DA8099E64910056E581 /* markup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = markup.cpp; sourceTree = "<group>"; };
                93309DA9099E64910056E581 /* markup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markup.h; sourceTree = "<group>"; };
                93309DAA099E64910056E581 /* MergeIdenticalElementsCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MergeIdenticalElementsCommand.cpp; sourceTree = "<group>"; };
                939885C208B7E3D100E707C4 /* EventNames.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = EventNames.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                93A1EA9F0A5634C9006960A0 /* ImageDocumentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageDocumentMac.mm; sourceTree = "<group>"; };
                93A1EAA70A563508006960A0 /* ImageDocumentMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDocumentMac.h; sourceTree = "<group>"; };
+               93A38B4A0D0E5808006872C2 /* EditorCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditorCommand.cpp; sourceTree = "<group>"; };
                93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ContextMenu.h; sourceTree = "<group>"; };
                93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenu.cpp; sourceTree = "<group>"; };
                93B6A0E90B0BCA8400F5027A /* ContextMenuMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuMac.mm; sourceTree = "<group>"; };
                                93309D95099E64910056E581 /* EditCommand.h */,
                                4B3043CA0AE0373B00A82647 /* Editor.cpp */,
                                4B3043CB0AE0373B00A82647 /* Editor.h */,
+                               93A38B4A0D0E5808006872C2 /* EditorCommand.cpp */,
                                4BAE95B00B2FA9CE00AED8A0 /* EditorDeleteAction.h */,
                                93FDAFC90B11307400E2746F /* EditorInsertAction.h */,
                                D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */,
                                93309DA3099E64910056E581 /* InsertTextCommand.h */,
                                93309DA4099E64910056E581 /* JoinTextNodesCommand.cpp */,
                                93309DA5099E64910056E581 /* JoinTextNodesCommand.h */,
-                               93309DA6099E64910056E581 /* JSEditor.cpp */,
-                               93309DA7099E64910056E581 /* JSEditor.h */,
                                93309DA8099E64910056E581 /* markup.cpp */,
                                93309DA9099E64910056E581 /* markup.h */,
                                93309DAA099E64910056E581 /* MergeIdenticalElementsCommand.cpp */,
                                659DDC8309E198BA001BF3C6 /* JSDocument.h in Headers */,
                                1A494EDF0A123F4C00FDAFC1 /* JSDocumentFragment.h in Headers */,
                                65DF31F609D1CC60000BE325 /* JSDocumentType.h in Headers */,
-                               93309DF6099E64920056E581 /* JSEditor.h in Headers */,
                                65DF31FA09D1CC60000BE325 /* JSElement.h in Headers */,
                                65DF323009D1DDBC000BE325 /* JSEntity.h in Headers */,
                                93F9B7750BA5FDDD00854064 /* JSEntityReference.h in Headers */,
                                929264770B61FC7200B41D34 /* JSDocumentCustom.cpp in Sources */,
                                1A494EDE0A123F4C00FDAFC1 /* JSDocumentFragment.cpp in Sources */,
                                65DF31F509D1CC60000BE325 /* JSDocumentType.cpp in Sources */,
-                               93309DF5099E64920056E581 /* JSEditor.cpp in Sources */,
                                65DF31F909D1CC60000BE325 /* JSElement.cpp in Sources */,
                                BC2ED5550C6B9BD300920BFF /* JSElementCustom.cpp in Sources */,
                                65DF322F09D1DDBC000BE325 /* JSEntity.cpp in Sources */,
                                BCB16C2C0979C3BD00467741 /* loader.cpp in Sources */,
                                93309DF7099E64920056E581 /* markup.cpp in Sources */,
                                93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
+                               93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 69018b993ad4f8c403b27c42ac9f36966bb7f30a..7ce828be73e2c937456f0af626a8f61972cfd459 100644 (file)
@@ -350,6 +350,7 @@ This file contains the list of files needed to build WebCore.
         editing/DeleteSelectionCommand.cpp
         editing/EditCommand.cpp
         editing/Editor.cpp
+        editing/EditorCommand.cpp
         editing/FormatBlockCommand.cpp
         editing/HTMLInterchange.cpp
         editing/IndentOutdentCommand.cpp
@@ -359,7 +360,6 @@ This file contains the list of files needed to build WebCore.
         editing/InsertNodeBeforeCommand.cpp
         editing/InsertParagraphSeparatorCommand.cpp
         editing/InsertTextCommand.cpp
-        editing/JSEditor.cpp
         editing/JoinTextNodesCommand.cpp
         editing/MergeIdenticalElementsCommand.cpp
         editing/ModifySelectionListLevel.cpp
index 900383e71e9149af4afd43c5e29f190852cad6b0..b6474b05485affbb76525baffa13accc99adaa36 100644 (file)
@@ -65,7 +65,7 @@ static bool qualifiedNameIsMalformed(const String&)
 
 #if ENABLE(SVG)
 
-static void addString(HashSet<StringImpl*, CaseInsensitiveHash<StringImpl*> >& set, const
+static void addString(HashSet<StringImpl*, CaseFoldingHash>& set, const
 char* string)
 {
     StringImpl* s = new StringImpl(string);
@@ -76,7 +76,7 @@ char* string)
 static bool isSVG10Feature(const String &feature)
 {
     static bool initialized = false;
-    static HashSet<StringImpl*, CaseInsensitiveHash<StringImpl*> > svgFeatures;
+    static HashSet<StringImpl*, CaseFoldingHash> svgFeatures;
     if (!initialized) {
         // TODO: features need to be uncommented when we implement them
         // 1.0 features
@@ -99,7 +99,7 @@ static bool isSVG10Feature(const String &feature)
 static bool isSVG11Feature(const String &feature)
 {
     static bool initialized = false;
-    static HashSet<StringImpl*, CaseInsensitiveHash<StringImpl*> > svgFeatures;
+    static HashSet<StringImpl*, CaseFoldingHash> svgFeatures;
     if (!initialized) {
         // TODO: features need to be uncommented when we implement them
         // 1.1 features
index ad917cb486064bba14dd04071745c77eb65d9f96..10627383b8d5b181100383341fa5c0f3b02e4e7c 100644 (file)
@@ -68,7 +68,6 @@
 #include "HTTPParsers.h"
 #include "HitTestRequest.h"
 #include "HitTestResult.h"
-#include "JSEditor.h"
 #include "KeyboardEvent.h"
 #include "Logging.h"
 #include "MouseEvent.h"
@@ -338,8 +337,6 @@ Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
     m_startTime = currentTime();
     m_overMinimumLayoutThreshold = false;
     
-    m_jsEditor = 0;
-
     initSecurityOrigin();
 
     static int docID = 0;
@@ -431,11 +428,6 @@ Document::~Document()
     }
     m_decoder = 0;
     
-    if (m_jsEditor) {
-        delete m_jsEditor;
-        m_jsEditor = 0;
-    }
-    
     unsigned count = sizeof(m_nameCollectionInfo) / sizeof(m_nameCollectionInfo[0]);
     for (unsigned i = 0; i < count; i++)
         deleteAllValues(m_nameCollectionInfo[i]);
@@ -2857,46 +2849,48 @@ String Document::toString() const
 
 // Support for Javascript execCommand, and related methods
 
-JSEditor *Document::jsEditor()
+static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
 {
-    if (!m_jsEditor)
-        m_jsEditor = new JSEditor(this);
-    return m_jsEditor;
+    Frame* frame = document->frame();
+    if (!frame || frame->document() != document)
+        return Editor::Command();
+    return frame->editor()->command(commandName,
+        userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
 }
 
-bool Document::execCommand(const String &command, bool userInterface, const String &value)
+bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
 {
-    return jsEditor()->execCommand(command, userInterface, value);
+    return command(this, commandName, userInterface).execute(value);
 }
 
-bool Document::queryCommandEnabled(const String &command)
+bool Document::queryCommandEnabled(const String& commandName)
 {
-    return jsEditor()->queryCommandEnabled(command);
+    return command(this, commandName).isEnabled();
 }
 
-bool Document::queryCommandIndeterm(const String &command)
+bool Document::queryCommandIndeterm(const String& commandName)
 {
-    return jsEditor()->queryCommandIndeterm(command);
+    return command(this, commandName).state() == MixedTriState;
 }
 
-bool Document::queryCommandState(const String &command)
+bool Document::queryCommandState(const String& commandName)
 {
-    return jsEditor()->queryCommandState(command);
+    return command(this, commandName).state() != FalseTriState;
 }
 
-bool Document::queryCommandSupported(const String &command)
+bool Document::queryCommandSupported(const String& commandName)
 {
-    return jsEditor()->queryCommandSupported(command);
+    return command(this, commandName).isSupported();
 }
 
-String Document::queryCommandValue(const String &command)
+String Document::queryCommandValue(const String& commandName)
 {
-    return jsEditor()->queryCommandValue(command);
+    return command(this, commandName).value();
 }
 
-static IntRect placeholderRectForMarker(void)
+static IntRect placeholderRectForMarker()
 {
-    return IntRect(-1,-1,-1,-1);
+    return IntRect(-1, -1, -1, -1);
 }
 
 void Document::addMarker(Range *range, DocumentMarker::MarkerType type, String description)
index afa690d02d4650b4e6856d95877ee7a914bb72e2..097195a16cb386dfbc6ef6fd3ce90ef99f2f5518 100644 (file)
@@ -70,7 +70,6 @@ namespace WebCore {
     class HTMLInputElement;
     class HTMLMapElement;
     class IntPoint;
-    class JSEditor;
     class MouseEventWithHitTestResults;
     class NameNodeList;
     class NodeFilter;
@@ -868,9 +867,6 @@ private:
     void imageLoadEventTimerFired(Timer<Document>*);
     void updateFocusAppearanceTimerFired(Timer<Document>*);
 
-    JSEditor* jsEditor();
-    JSEditor* m_jsEditor;
-
     mutable String m_domain;
 
     SecurityOrigin m_securityOrigin;
@@ -886,7 +882,7 @@ private:
     mutable HashMap<AtomicStringImpl*, Element*> m_elementsById;
     mutable HashCountedSet<AtomicStringImpl*> m_duplicateIds;
     
-    mutable HashMap<StringImpl*, Element*, CaseInsensitiveHash<StringImpl*> > m_elementsByAccessKey;
+    mutable HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
     
     InheritedBool m_designMode;
     
index 5e7db132d1904ec595ecc9d7d467ead7d03abc45..7134735e3af25490f33412e75c96475034bc2f26 100644 (file)
 #include "CSSComputedStyleDeclaration.h"
 #include "CSSProperty.h"
 #include "CSSPropertyNames.h"
-#include "CharacterData.h"
-#include "Clipboard.h"
 #include "ClipboardEvent.h"
 #include "DeleteButtonController.h"
 #include "DeleteSelectionCommand.h"
 #include "DocLoader.h"
-#include "Document.h"
 #include "DocumentFragment.h"
-#include "EditCommand.h"
-#include "Editor.h"
 #include "EditorClient.h"
-#include "Event.h"
 #include "EventHandler.h"
 #include "EventNames.h"
 #include "FocusController.h"
 #include "FrameView.h"
-#include "HTMLElement.h"
 #include "HTMLInputElement.h"
-#include "HTMLNames.h"
 #include "HTMLTextAreaElement.h"
 #include "HitTestResult.h"
 #include "IndentOutdentCommand.h"
 #include "InsertListCommand.h"
 #include "KeyboardEvent.h"
-#include "KURL.h"
 #include "ModifySelectionListLevel.h"
 #include "Page.h"
 #include "Pasteboard.h"
-#include "Range.h"
 #include "RemoveFormatCommand.h"
 #include "ReplaceSelectionCommand.h"
-#include "SelectionController.h"
 #include "Sound.h"
 #include "Text.h"
 #include "TextIterator.h"
 
 namespace WebCore {
 
-class FontData;
-
 using namespace std;
 using namespace EventNames;
 using namespace HTMLNames;
 
 // When an event handler has moved the selection outside of a text control
 // we should use the target control's selection for this editing operation.
-static Selection selectionForEvent(Frame* frame, Event* event)
+Selection Editor::selectionForCommand(Event* event)
 {
-    Page* page = frame->page();
-    if (!page)
-        return Selection();
-    Selection selection = page->selection();
+    Selection selection = m_frame->selectionController()->selection();
     if (!event)
         return selection;
-    Node* target = event->target()->toNode();
-    Node* selectionStart = selection.start().node();
-    
     // If the target is a text control, and the current selection is outside of its shadow tree,
     // then use the saved selection for that text control.
+    Node* target = event->target()->toNode();
+    Node* selectionStart = selection.start().node();
     if (target && (!selectionStart || target->shadowAncestorNode() != selectionStart->shadowAncestorNode())) {
         if (target->hasTagName(inputTag) && static_cast<HTMLInputElement*>(target)->isTextField())
             return static_cast<HTMLInputElement*>(target)->selection();
@@ -114,14 +97,14 @@ EditorClient* Editor::client() const
 void Editor::handleKeyboardEvent(KeyboardEvent* event)
 {
     if (EditorClient* c = client())
-        if (selectionForEvent(m_frame, event).isContentEditable())
+        if (selectionForCommand(event).isContentEditable())
             c->handleKeyboardEvent(event);
 }
 
 void Editor::handleInputMethodKeydown(KeyboardEvent* event)
 {
     if (EditorClient* c = client())
-        if (selectionForEvent(m_frame, event).isContentEditable())
+        if (selectionForCommand(event).isContentEditable())
             c->handleInputMethodKeydown(event);
 }
 
@@ -160,11 +143,10 @@ bool Editor::canCut() const
     return canCopy() && canDelete();
 }
 
-static Node* imageNodeFromImageDocument(Document* document)
+static HTMLImageElement* imageElementFromImageDocument(Document* document)
 {
     if (!document)
         return 0;
-    
     if (!document->isImageDocument())
         return 0;
     
@@ -174,19 +156,16 @@ static Node* imageNodeFromImageDocument(Document* document)
     
     Node* node = body->firstChild();
     if (!node)
-        return 0;
-    
+        return 0;    
     if (!node->hasTagName(imgTag))
         return 0;
-    
-    return node;
+    return static_cast<HTMLImageElement*>(node);
 }
 
 bool Editor::canCopy() const
 {
-    if (imageNodeFromImageDocument(m_frame->document()))
+    if (imageElementFromImageDocument(m_frame->document()))
         return true;
-        
     SelectionController* selectionController = m_frame->selectionController();
     return selectionController->isRange() && !selectionController->isInPasswordField();
 }
@@ -479,36 +458,36 @@ const FontData* Editor::fontForSelection(bool& hasMultipleFonts) const
 #endif
 }
 
-Frame::TriState Editor::selectionUnorderedListState() const
+TriState Editor::selectionUnorderedListState() const
 {
     if (m_frame->selectionController()->isCaret()) {
         Node* selectionNode = m_frame->selectionController()->selection().start().node();
         if (enclosingNodeWithTag(selectionNode, ulTag))
-            return Frame::trueTriState;
+            return TrueTriState;
     } else if (m_frame->selectionController()->isRange()) {
         Node* startNode = enclosingNodeWithTag(m_frame->selectionController()->selection().start().node(), ulTag);
         Node* endNode = enclosingNodeWithTag(m_frame->selectionController()->selection().end().node(), ulTag);
         if (startNode && endNode && startNode == endNode)
-            return Frame::trueTriState;
+            return TrueTriState;
     }
 
-    return Frame::falseTriState;
+    return FalseTriState;
 }
 
-Frame::TriState Editor::selectionOrderedListState() const
+TriState Editor::selectionOrderedListState() const
 {
     if (m_frame->selectionController()->isCaret()) {
         Node* selectionNode = m_frame->selectionController()->selection().start().node();
         if (enclosingNodeWithTag(selectionNode, olTag))
-            return Frame::trueTriState;
+            return TrueTriState;
     } else if (m_frame->selectionController()->isRange()) {
         Node* startNode = enclosingNodeWithTag(m_frame->selectionController()->selection().start().node(), olTag);
         Node* endNode = enclosingNodeWithTag(m_frame->selectionController()->selection().end().node(), olTag);
         if (startNode && endNode && startNode == endNode)
-            return Frame::trueTriState;
+            return TrueTriState;
     }
 
-    return Frame::falseTriState;
+    return FalseTriState;
 }
 
 PassRefPtr<Node> Editor::insertOrderedList()
@@ -620,10 +599,9 @@ void Editor::applyStyle(CSSStyleDeclaration* style, EditAction editingAction)
         case Selection::NONE:
             // do nothing
             break;
-        case Selection::CARET: {
+        case Selection::CARET:
             m_frame->computeAndSetTypingStyle(style, editingAction);
             break;
-        }
         case Selection::RANGE:
             if (m_frame->document() && style)
                 applyCommand(new ApplyStyleCommand(m_frame->document(), style, editingAction));
@@ -676,7 +654,7 @@ bool Editor::clientIsEditable() const
 bool Editor::selectionStartHasStyle(CSSStyleDeclaration* style) const
 {
     Node* nodeToRemove;
-    RefPtr<CSSStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
+    RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
     if (!selectionStyle)
         return false;
     
@@ -701,6 +679,57 @@ bool Editor::selectionStartHasStyle(CSSStyleDeclaration* style) const
     return match;
 }
 
+static void updateState(CSSMutableStyleDeclaration* desiredStyle, CSSComputedStyleDeclaration* computedStyle, bool& atStart, TriState& state)
+{
+    DeprecatedValueListConstIterator<CSSProperty> end;
+    for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
+        int propertyID = (*it).id();
+        String desiredProperty = desiredStyle->getPropertyValue(propertyID);
+        String computedProperty = computedStyle->getPropertyValue(propertyID);
+        TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
+            ? TrueTriState : FalseTriState;
+        if (atStart) {
+            state = propertyState;
+            atStart = false;
+        } else if (state != propertyState) {
+            state = MixedTriState;
+            break;
+        }
+    }
+}
+
+TriState Editor::selectionHasStyle(CSSStyleDeclaration* style) const
+{
+    bool atStart = true;
+    TriState state = FalseTriState;
+
+    RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
+
+    if (!m_frame->selectionController()->isRange()) {
+        Node* nodeToRemove;
+        RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
+        if (!selectionStyle)
+            return FalseTriState;
+        updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
+        if (nodeToRemove) {
+            ExceptionCode ec = 0;
+            nodeToRemove->remove(ec);
+            ASSERT(ec == 0);
+        }
+    } else {
+        for (Node* node = m_frame->selectionController()->start().node(); node; node = node->traverseNextNode()) {
+            RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
+            if (computedStyle)
+                updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
+            if (state == MixedTriState)
+                break;
+            if (node == m_frame->selectionController()->end().node())
+                break;
+        }
+    }
+
+    return state;
+}
 void Editor::indent()
 {
     applyCommand(new IndentOutdentCommand(m_frame->document(), IndentOutdentCommand::Indent));
@@ -795,524 +824,11 @@ void Editor::reappliedEditing(PassRefPtr<EditCommand> cmd)
     respondToChangedContents(newSelection);    
 }
 
-// Execute command functions
-
-static bool execCopy(Frame* frame, Event*)
-{
-    frame->editor()->copy();
-    return true;
-}
-
-static bool execCut(Frame* frame, Event*)
-{
-    frame->editor()->cut();
-    return true;
-}
-
-static bool execDelete(Frame* frame, Event*)
-{
-    frame->editor()->performDelete();
-    return true;
-}
-
-static bool execDeleteWordBackward(Frame* frame, Event*)
-{
-    frame->editor()->deleteWithDirection(SelectionController::BACKWARD, WordGranularity, true, false);
-    return true;
-}
-
-static bool execDeleteWordForward(Frame* frame, Event*)
-{
-    frame->editor()->deleteWithDirection(SelectionController::FORWARD, WordGranularity, true, false);
-    return true;
-}
-
-static bool execBackwardDelete(Frame* frame, Event*)
-{
-    frame->editor()->deleteWithDirection(SelectionController::BACKWARD, CharacterGranularity, false, true);
-    return true;
-}
-
-static bool execForwardDelete(Frame* frame, Event*)
-{
-    frame->editor()->deleteWithDirection(SelectionController::FORWARD, CharacterGranularity, false, true);
-    return true;
-}
-
-static bool execMoveBackward(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveBackwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveUpByPageAndModifyCaret(Frame* frame, Event*)
-{
-    RenderObject* renderer = frame->document()->focusedNode()->renderer();
-    if (renderer->style()->overflowY() == OSCROLL
-        || renderer->style()->overflowY() == OAUTO
-        || renderer->isTextArea()) {
-        int height = -(frame->document()->focusedNode()->renderer()->clientHeight()-PAGE_KEEP);
-        bool handledScroll = renderer->scroll(ScrollUp, ScrollByPage);
-        bool handledCaretMove = frame->selectionController()->modify(SelectionController::MOVE, height);
-        return handledScroll || handledCaretMove;
-    }
-    return false;
-}
-
-static bool execMoveDown(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, LineGranularity, true);
-    return true;
-}
-
-static bool execMoveDownAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, LineGranularity, true);
-    return true;
-}
-
-static bool execMoveForward(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveForwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveDownByPageAndModifyCaret(Frame* frame, Event*)
-{
-    RenderObject* renderer = frame->document()->focusedNode()->renderer();
-    if (renderer->style()->overflowY() == OSCROLL
-        || renderer->style()->overflowY() == OAUTO
-        || renderer->isTextArea()) {
-        int height = frame->document()->focusedNode()->renderer()->clientHeight()-PAGE_KEEP;
-        bool handledScroll = renderer->scroll(ScrollDown, ScrollByPage);
-        bool handledCaretMove = frame->selectionController()->modify(SelectionController::MOVE, height);
-        return handledScroll || handledCaretMove;
-    }
-    return false;
-}
-
-static bool execMoveLeft(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveLeftAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::LEFT, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveRight(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveRightAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::RIGHT, CharacterGranularity, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfDocument(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, DocumentBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfDocumentAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, DocumentBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfSentence(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, SentenceBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfSentenceAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, SentenceBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfLine(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, LineBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfLineAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, LineBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfParagraph(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, ParagraphBoundary, true);
-    return true;
-}
-
-static bool execMoveToBeginningOfParagraphAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, ParagraphBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfDocument(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, DocumentBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfDocumentAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, DocumentBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfSentence(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, SentenceBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfSentenceAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, SentenceBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfLine(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, LineBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfLineAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, LineBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfParagraph(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, ParagraphBoundary, true);
-    return true;
-}
-
-static bool execMoveToEndOfParagraphAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, ParagraphBoundary, true);
-    return true;
-}
-
-static bool execMoveParagraphBackwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, ParagraphGranularity, true);
-    return true;
-}
-
-static bool execMoveParagraphForwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, ParagraphGranularity, true);
-    return true;
-}
-
-static bool execMoveUp(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, LineGranularity, true);
-    return true;
-}
-
-static bool execMoveUpAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, LineGranularity, true);
-    return true;
-}
-
-static bool execMoveWordBackward(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordBackwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordForward(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordForwardAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordLeft(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordLeftAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::LEFT, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordRight(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, WordGranularity, true);
-    return true;
-}
-
-static bool execMoveWordRightAndModifySelection(Frame* frame, Event*)
-{
-    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::RIGHT, WordGranularity, true);
-    return true;
-}
-
-static bool execPaste(Frame* frame, Event*)
-{
-    frame->editor()->paste();
-    return true;
-}
-
-static bool execSelectAll(Frame* frame, Event*)
-{
-    frame->selectionController()->selectAll();
-    return true;
-}
-
-static bool execToggleBold(Frame* frame, Event*)
-{
-    ExceptionCode ec;
-    
-    RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
-    style->setProperty(CSS_PROP_FONT_WEIGHT, "bold", false, ec);
-    if (frame->editor()->selectionStartHasStyle(style.get()))
-        style->setProperty(CSS_PROP_FONT_WEIGHT, "normal", false, ec);
-    frame->editor()->applyStyleToSelection(style.get(), EditActionSetFont);
-    return true;
-}
-
-static bool execToggleItalic(Frame* frame, Event*)
-{
-    ExceptionCode ec;
-    
-    RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
-    style->setProperty(CSS_PROP_FONT_STYLE, "italic", false, ec);
-    if (frame->editor()->selectionStartHasStyle(style.get()))
-        style->setProperty(CSS_PROP_FONT_STYLE, "normal", false, ec);
-    frame->editor()->applyStyleToSelection(style.get(), EditActionSetFont);
-    return true;
-}
-
-static bool execRedo(Frame* frame, Event*)
-{
-    frame->editor()->redo();
-    return true;
-}
-
-static bool execUndo(Frame* frame, Event*)
-{
-    frame->editor()->undo();
-    return true;
-}
-
-static bool execTranspose(Frame* frame, Event*)
-{
-    frame->editor()->transpose();
-    return true;
-}
-
-static inline Frame* targetFrame(Frame* frame, Event* evt)
-{
-    Node* node = evt ? evt->target()->toNode() : 0;
-    if (!node)
-        return frame;
-    return node->document()->frame();
-}
-
-static bool execInsertTab(Frame* frame, Event* evt)
-{
-    return targetFrame(frame, evt)->eventHandler()->handleTextInputEvent("\t", evt, false, false);
-}
-
-static bool execInsertBacktab(Frame* frame, Event* evt)
-{
-    return targetFrame(frame, evt)->eventHandler()->handleTextInputEvent("\t", evt, false, true);
-}
-
-static bool execInsertNewline(Frame* frame, Event* evt)
-{
-    Frame* targetFrame = WebCore::targetFrame(frame, evt);
-    return targetFrame->eventHandler()->handleTextInputEvent("\n", evt, !targetFrame->editor()->canEditRichly());
-}
-
-static bool execInsertLineBreak(Frame* frame, Event* evt)
-{
-    return targetFrame(frame, evt)->eventHandler()->handleTextInputEvent("\n", evt, true);
-}
-
-// Enabled functions
-
-static bool enabled(Frame*, Event*)
-{
-    return true;
-}
-
-static bool canPaste(Frame* frame, Event*)
-{
-    return frame->editor()->canPaste();
-}
-
-static bool hasEditableSelection(Frame* frame, Event* evt)
-{
-    if (evt)
-        return selectionForEvent(frame, evt).isContentEditable();
-    return frame->selectionController()->isContentEditable();
-}
-
-static bool hasEditableRangeSelection(Frame* frame, Event*)
-{
-    return frame->selectionController()->isRange() && frame->selectionController()->isContentEditable();
-}
-
-static bool hasRangeSelection(Frame* frame, Event*)
-{
-    return frame->selectionController()->isRange();
-}
-
-static bool hasRichlyEditableSelection(Frame* frame, Event*)
-{
-    return frame->selectionController()->isCaretOrRange() && frame->selectionController()->isContentRichlyEditable();
-}
-
-static bool canRedo(Frame* frame, Event*)
-{
-    return frame->editor()->canRedo();
-}
-
-static bool canUndo(Frame* frame, Event*)
-{
-    return frame->editor()->canUndo();
-}
-
-struct Command {
-    bool (*enabled)(Frame*, Event*);
-    bool (*exec)(Frame*, Event*);
-};
-
-typedef HashMap<RefPtr<AtomicStringImpl>, const Command*> CommandMap;
-
-static CommandMap* createCommandMap()
-{
-    struct CommandEntry { const char* name; Command command; };
-    
-    static const CommandEntry commands[] = {
-        { "BackwardDelete", { hasEditableSelection, execBackwardDelete } },
-        { "Copy", { hasRangeSelection, execCopy } },
-        { "Cut", { hasEditableRangeSelection, execCut } },
-        { "Delete", { hasEditableSelection, execDelete } },
-        { "DeleteWordBackward", { hasEditableSelection, execDeleteWordBackward } },
-        { "DeleteWordForward", { hasEditableSelection, execDeleteWordForward} },
-        { "ForwardDelete", { hasEditableSelection, execForwardDelete } },
-        { "InsertBacktab", { hasEditableSelection, execInsertBacktab } },
-        { "InsertTab", { hasEditableSelection, execInsertTab } },
-        { "InsertLineBreak", { hasEditableSelection, execInsertLineBreak } },        
-        { "InsertNewline", { hasEditableSelection, execInsertNewline } },        
-        { "MoveBackward", { hasEditableSelection, execMoveBackward } },
-        { "MoveBackwardAndModifySelection", { hasEditableSelection, execMoveBackwardAndModifySelection } },
-        { "MoveUpByPageAndModifyCaret", { hasEditableSelection, execMoveUpByPageAndModifyCaret } },
-        { "MoveDown", { hasEditableSelection, execMoveDown } },
-        { "MoveDownAndModifySelection", { hasEditableSelection, execMoveDownAndModifySelection } },
-        { "MoveForward", { hasEditableSelection, execMoveForward } },
-        { "MoveForwardAndModifySelection", { hasEditableSelection, execMoveForwardAndModifySelection } },
-        { "MoveDownByPageAndModifyCaret", { hasEditableSelection, execMoveDownByPageAndModifyCaret } },
-        { "MoveLeft", { hasEditableSelection, execMoveLeft } },
-        { "MoveLeftAndModifySelection", { hasEditableSelection, execMoveLeftAndModifySelection } },
-        { "MoveRight", { hasEditableSelection, execMoveRight } },
-        { "MoveRightAndModifySelection", { hasEditableSelection, execMoveRightAndModifySelection } },
-        { "MoveToBeginningOfDocument", { hasEditableSelection, execMoveToBeginningOfDocument } },
-        { "MoveToBeginningOfDocumentAndModifySelection", { hasEditableSelection, execMoveToBeginningOfDocumentAndModifySelection } },
-        { "MoveToBeginningOfSentence", { hasEditableSelection, execMoveToBeginningOfSentence } },
-        { "MoveToBeginningOfSentenceAndModifySelection", { hasEditableSelection, execMoveToBeginningOfSentenceAndModifySelection } },
-        { "MoveToBeginningOfLine", { hasEditableSelection, execMoveToBeginningOfLine } },
-        { "MoveToBeginningOfLineAndModifySelection", { hasEditableSelection, execMoveToBeginningOfLineAndModifySelection } },
-        { "MoveToBeginningOfParagraph", { hasEditableSelection, execMoveToBeginningOfParagraph } },
-        { "MoveToBeginningOfParagraphAndModifySelection", { hasEditableSelection, execMoveToBeginningOfParagraphAndModifySelection } },
-        { "MoveToEndOfDocument", { hasEditableSelection, execMoveToEndOfDocument } },
-        { "MoveToEndOfDocumentAndModifySelection", { hasEditableSelection, execMoveToEndOfDocumentAndModifySelection } },
-        { "MoveToEndOfSentence", { hasEditableSelection, execMoveToEndOfSentence } },
-        { "MoveToEndOfSentenceAndModifySelection", { hasEditableSelection, execMoveToEndOfSentenceAndModifySelection } },
-        { "MoveToEndOfLine", { hasEditableSelection, execMoveToEndOfLine } },
-        { "MoveToEndOfLineAndModifySelection", { hasEditableSelection, execMoveToEndOfLineAndModifySelection } },
-        { "MoveToEndOfParagraph", { hasEditableSelection, execMoveToEndOfParagraph } },
-        { "MoveToEndOfParagraphAndModifySelection", { hasEditableSelection, execMoveToEndOfParagraphAndModifySelection } },
-        { "MoveParagraphBackwardAndModifySelection", { hasEditableSelection, execMoveParagraphBackwardAndModifySelection } },
-        { "MoveParagraphForwardAndModifySelection", { hasEditableSelection, execMoveParagraphForwardAndModifySelection } },
-        { "MoveUp", { hasEditableSelection, execMoveUp } },
-        { "MoveUpAndModifySelection", { hasEditableSelection, execMoveUpAndModifySelection } },
-        { "MoveWordBackward", { hasEditableSelection, execMoveWordBackward } },
-        { "MoveWordBackwardAndModifySelection", { hasEditableSelection, execMoveWordBackwardAndModifySelection } },
-        { "MoveWordForward", { hasEditableSelection, execMoveWordForward } },
-        { "MoveWordForwardAndModifySelection", { hasEditableSelection, execMoveWordForwardAndModifySelection } },
-        { "MoveWordLeft", { hasEditableSelection, execMoveWordLeft } },
-        { "MoveWordLeftAndModifySelection", { hasEditableSelection, execMoveWordLeftAndModifySelection } },
-        { "MoveWordRight", { hasEditableSelection, execMoveWordRight } },
-        { "MoveWordRightAndModifySelection", { hasEditableSelection, execMoveWordRightAndModifySelection } },
-        { "Paste", { canPaste, execPaste } },
-        { "Redo", { canRedo, execRedo } },
-        { "SelectAll", { enabled, execSelectAll } },
-        { "ToggleBold", { hasRichlyEditableSelection, execToggleBold } },
-        { "ToggleItalic", { hasRichlyEditableSelection, execToggleItalic } },
-        { "Transpose", { hasEditableSelection, execTranspose } },
-        { "Undo", { canUndo, execUndo } }
-    };
-
-    CommandMap* commandMap = new CommandMap;
-
-    const unsigned numCommands = sizeof(commands) / sizeof(commands[0]);
-    for (unsigned i = 0; i < numCommands; i++)
-        commandMap->set(AtomicString(commands[i].name).impl(), &commands[i].command);
-
-    return commandMap;
-}
-
-// =============================================================================
-//
-// public editing commands
-//
-// =============================================================================
-
 Editor::Editor(Frame* frame)
     : m_frame(frame)
     , m_deleteButtonController(new DeleteButtonController(frame))
     , m_ignoreCompositionSelectionChange(false)
+    , m_shouldStartNewKillRingSequence(false)
 { 
 }
 
@@ -1326,37 +842,6 @@ void Editor::clear()
     m_customCompositionUnderlines.clear();
 }
 
-bool Editor::isTextInsertionCommand(const AtomicString& command)
-{
-    return command == "InsertBacktab"
-        || command == "InsertTab"
-        || command == "InsertLineBreak"
-        || command == "InsertNewline";
-}
-
-bool Editor::execCommand(const AtomicString& command, Event* triggeringEvent)
-{
-    if (!m_frame->document())
-        return false;
-
-    static CommandMap* commandMap;
-    if (!commandMap)
-        commandMap = createCommandMap();
-    
-    const Command* c = commandMap->get(command.impl());
-    if (!c)
-        return false;
-    
-    bool handled = false;
-    
-    if (c->enabled(m_frame, triggeringEvent)) {
-        m_frame->document()->updateLayoutIgnorePendingStylesheets();
-        handled = c->exec(m_frame, triggeringEvent);
-    }
-    
-    return handled;
-}
-
 bool Editor::insertText(const String& text, Event* triggeringEvent)
 {
     return m_frame->eventHandler()->handleTextInputEvent(text, triggeringEvent);
@@ -1367,7 +852,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
     if (text.isEmpty())
         return false;
 
-    Selection selection = selectionForEvent(m_frame, triggeringEvent);
+    Selection selection = selectionForCommand(triggeringEvent);
     if (!selection.isContentEditable())
         return false;
     RefPtr<Range> range = selection.toRange();
@@ -1378,7 +863,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
     // Get the selection to use for the event that triggered this insertText.
     // If the event handler changed the selection, we may want to use a different selection
     // that is contained in the event target.
-    selection = selectionForEvent(m_frame, triggeringEvent);
+    selection = selectionForCommand(triggeringEvent);
     if (selection.isContentEditable()) {
         if (Node* selectionStart = selection.start().node()) {
             RefPtr<Document> document = selectionStart->document();
@@ -1451,8 +936,8 @@ void Editor::copy()
     }
     
     Document* document = m_frame->document();
-    if (Node* node = imageNodeFromImageDocument(document))
-        Pasteboard::generalPasteboard()->writeImage(node, document->URL(), document->title());
+    if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
+        Pasteboard::generalPasteboard()->writeImage(imageElement, document->URL(), document->title());
     else
         Pasteboard::generalPasteboard()->writeSelection(selectedRange().get(), canSmartCopyOrDelete(), m_frame);
     
@@ -1604,25 +1089,19 @@ void Editor::didWriteSelectionToPasteboard()
 
 void Editor::toggleBold()
 {
-    execToggleBold(frame(), 0);
+    command("ToggleBold").execute();
 }
 
 void Editor::toggleUnderline()
 {
-    ExceptionCode ec = 0;
-
-    RefPtr<CSSStyleDeclaration> style = frame()->document()->createCSSStyleDeclaration();
-    style->setProperty(CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "underline", false, ec);
-    if (selectionStartHasStyle(style.get()))
-        style->setProperty(CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "none", false, ec);
-    applyStyleToSelection(style.get(), EditActionUnderline);
+    command("ToggleUnderline").execute();
 }
 
-void Editor::setBaseWritingDirection(String direction)
+void Editor::setBaseWritingDirection(const String& direction)
 {
     ExceptionCode ec = 0;
 
-    RefPtr<CSSStyleDeclaration> style = frame()->document()->createCSSStyleDeclaration();
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
     style->setProperty(CSS_PROP_DIRECTION, direction, false, ec);
     applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection);
 }
@@ -2415,4 +1894,42 @@ void Editor::transpose()
     replaceSelectionWithText(transposed, false, false);
 }
 
+void Editor::addToKillRing(Range* range, bool prepend)
+{
+    if (m_shouldStartNewKillRingSequence)
+        startNewKillRingSequence();
+
+    String text = plainText(range);
+    text.replace('\\', m_frame->backslashAsCurrencySymbol());
+    if (prepend)
+        prependToKillRing(text);
+    else
+        appendToKillRing(text);
+    m_shouldStartNewKillRingSequence = false;
+}
+
+#if !PLATFORM(MAC)
+
+void Editor::appendToKillRing(const String&)
+{
+}
+
+void Editor::prependToKillRing(const String&)
+{
+}
+
+String Editor::yankFromKillRing()
+{
+}
+
+void Editor::startNewKillRingSequence()
+{
+}
+
+void Editor::setKillRingToYankedState()
+{
+}
+
+#endif
+
 } // namespace WebCore
index a8262b24530fbab7ed232d6ef4da23610c1f0ba2..1abd4b4f10f8f35211c87cabb8badabf17c974a1 100644 (file)
@@ -46,6 +46,7 @@ class Clipboard;
 class DeleteButtonController;
 class DocumentFragment;
 class EditCommand;
+class EditorInternalCommand;
 class EditorClient;
 class EventTargetNode;
 class FontData;
@@ -67,6 +68,9 @@ struct CompositionUnderline {
     bool thick;
 };
 
+enum TriState { FalseTriState, TrueTriState, MixedTriState };
+enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
+
 class Editor {
 public:
     Editor(Frame*);
@@ -117,11 +121,12 @@ public:
     
     void respondToChangedSelection(const Selection& oldSelection);
     void respondToChangedContents(const Selection& endingSelection);
-    
+
+    TriState selectionHasStyle(CSSStyleDeclaration*) const;
     const FontData* fontForSelection(bool&) const;
     
-    Frame::TriState selectionUnorderedListState() const;
-    Frame::TriState selectionOrderedListState() const;
+    TriState selectionUnorderedListState() const;
+    TriState selectionOrderedListState() const;
     PassRefPtr<Node> insertOrderedList();
     PassRefPtr<Node> insertUnorderedList();
     bool canIncreaseSelectionListLevel();
@@ -157,10 +162,33 @@ public:
 
     bool clientIsEditable() const;
 
-    static bool isTextInsertionCommand(const AtomicString&);
+    class Command {
+    public:
+        Command();
+        Command(PassRefPtr<Frame>, const EditorInternalCommand*, EditorCommandSource);
+
+        bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
+        bool execute(Event* triggeringEvent) const;
+
+        bool isSupported() const;
+        bool isEnabled(Event* triggeringEvent = 0) const;
+
+        TriState state(Event* triggeringEvent = 0) const;
+        String value(Event* triggeringEvent = 0) const;
+
+        bool isTextInsertion() const;
+
+    private:
+        RefPtr<Frame> m_frame;
+        const EditorInternalCommand* m_command;
+        EditorCommandSource m_source;
+    };
+    Command command(const String& commandName); // Default is CommandFromMenuOrKeyBinding.
+    Command command(const String& commandName, EditorCommandSource);
+
+    // Deprecated, but used by old key binding code. Keep around until we have eliminated all callers.
+    bool execCommand(const AtomicString& commandName, Event* triggeringEvent = 0);
 
-    bool execCommand(const AtomicString&, Event* triggeringEvent = 0);
-    
     bool insertText(const String&, Event* triggeringEvent);
     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent = 0);
     bool insertLineBreak();
@@ -202,7 +230,7 @@ public:
     void showColorPanel();
     void toggleBold();
     void toggleUnderline();
-    void setBaseWritingDirection(String);
+    void setBaseWritingDirection(const String&);
 
     bool smartInsertDeleteEnabled();
     
@@ -226,21 +254,23 @@ public:
 
     void setStartNewKillRingSequence(bool);
 
-#if PLATFORM(MAC)
-    NSString* userVisibleString(NSURL*);
+    PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
+
+    void clear();
 
-    void yank();
-    void yankAndSelect();
-    void setMark();
-    void deleteToMark();
-    void selectToMark();
-    void swapWithMark();
+    Selection selectionForCommand(Event*);
 
+#if PLATFORM(MAC)
+    NSString* userVisibleString(NSURL*);
 #endif
 
-    PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
+    void appendToKillRing(const String&);
+    void prependToKillRing(const String&);
+    String yankFromKillRing();
+    void startNewKillRingSequence();
+    void setKillRingToYankedState();
 
-    void clear();
+    PassRefPtr<Range> selectedRange();
 
 private:
     Frame* m_frame;
@@ -253,11 +283,11 @@ private:
     unsigned m_compositionEnd;
     Vector<CompositionUnderline> m_customCompositionUnderlines;
     bool m_ignoreCompositionSelectionChange;
+    bool m_shouldStartNewKillRingSequence;
 
     bool canDeleteRange(Range*) const;
     bool canSmartReplaceWithPasteboard(Pasteboard*);
     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy);
-    PassRefPtr<Range> selectedRange();
     void pasteAsPlainTextWithPasteboard(Pasteboard*);
     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
@@ -270,26 +300,13 @@ private:
     void setIgnoreCompositionSelectionChange(bool ignore);
 
     void addToKillRing(Range*, bool prepend);
-
-#if PLATFORM(MAC)
-    bool m_startNewKillRingSequence;
-#endif
 };
 
-#if PLATFORM(MAC)
-
 inline void Editor::setStartNewKillRingSequence(bool flag)
 {
-    m_startNewKillRingSequence = flag;
+    m_shouldStartNewKillRingSequence = flag;
 }
 
-#else
-
-inline void Editor::setStartNewKillRingSequence(bool) { }
-inline void Editor::addToKillRing(Range*, bool) { }
-
-#endif
-
 } // namespace WebCore
 
 #endif // Editor_h
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp
new file mode 100644 (file)
index 0000000..3a9c236
--- /dev/null
@@ -0,0 +1,1275 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Trolltech ASA
+ *
+ * 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "AtomicString.h"
+#include "CSSPropertyNames.h"
+#include "CreateLinkCommand.h"
+#include "DocumentFragment.h"
+#include "Editor.h"
+#include "Event.h"
+#include "EventHandler.h"
+#include "FormatBlockCommand.h"
+#include "HTMLFontElement.h"
+#include "HTMLImageElement.h"
+#include "IndentOutdentCommand.h"
+#include "InsertListCommand.h"
+#include "Page.h"
+#include "ReplaceSelectionCommand.h"
+#include "Settings.h"
+#include "Sound.h"
+#include "TypingCommand.h"
+#include "UnlinkCommand.h"
+#include "htmlediting.h"
+#include "markup.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+class EditorInternalCommand {
+public:
+    bool (*execute)(Frame*, Event*, EditorCommandSource, const String&);
+    bool (*isSupported)(Frame*, EditorCommandSource);
+    bool (*isEnabled)(Frame*, Event*);
+    TriState (*state)(Frame*, Event*);
+    String (*value)(Frame*, Event*);
+    bool isTextInsertion;
+};
+
+typedef HashMap<String, const EditorInternalCommand*, CaseFoldingHash> CommandMap;
+
+static const bool notTextInsertion = false;
+static const bool isTextInsertion = true;
+
+// Related to Editor::selectionForCommand.
+// Certain operations continue to use the target control's selection even if the event handler
+// already moved the selection outside of the text control.
+static Frame* targetFrame(Frame* frame, Event* event)
+{
+    if (!event)
+        return frame;
+    Node* node = event->target()->toNode();
+    if (!node)
+        return frame;
+    return node->document()->frame();
+}
+
+static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const String& propertyValue)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+    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;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const char* propertyValue)
+{
+    return executeApplyStyle(frame, source, action, propertyID, String(propertyValue));
+}
+
+static bool executeApplyStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, int propertyValue)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+    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;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeToggleStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const char* offValue, const char* onValue)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+    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;
+}
+
+static bool executeApplyParagraphStyle(Frame* frame, EditorCommandSource source, EditAction action, int propertyID, const String& propertyValue)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+    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()->applyParagraphStyleToSelection(style.get(), action);
+            return true;
+        case CommandFromDOM:
+        case CommandFromDOMWithUserInterface:
+            frame->editor()->applyParagraphStyle(style.get());
+            return true;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeInsertFragment(Frame* frame, PassRefPtr<DocumentFragment> fragment)
+{
+    applyCommand(new ReplaceSelectionCommand(frame->document(), fragment,
+        false, false, false, true, false, EditActionUnspecified));
+    return true;
+}
+
+static bool executeInsertNode(Frame* frame, PassRefPtr<Node> content)
+{
+    RefPtr<DocumentFragment> fragment = new DocumentFragment(frame->document());
+    ExceptionCode ec = 0;
+    fragment->appendChild(content, ec);
+    if (ec)
+        return false;
+    return executeInsertFragment(frame, fragment.release());
+}
+
+static TriState stateStyle(Frame* frame, int propertyID, const char* desiredValue)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+    style->setProperty(propertyID, desiredValue);
+    return frame->editor()->selectionHasStyle(style.get());
+}
+
+static String valueStyle(Frame* frame, int propertyID)
+{
+    return frame->selectionStartStylePropertyValue(propertyID);
+}
+
+static bool canScroll(RenderObject* renderer)
+{
+    if (!renderer)
+        return false;
+    RenderStyle* style = renderer->style();
+    if (!style)
+        return false;
+    return style->overflowY() == OSCROLL || style->overflowY() == OAUTO || renderer->isTextArea();
+}
+
+static RefPtr<Range> unionDOMRanges(Range* a, Range* b)
+{
+    ExceptionCode ec = 0;
+    Range* start = a->compareBoundaryPoints(Range::START_TO_START, b, ec) <= 0 ? a : b;
+    ASSERT(!ec);
+    Range* end = a->compareBoundaryPoints(Range::END_TO_END, b, ec) <= 0 ? b : a;
+    ASSERT(!ec);
+
+    return new Range(a->startContainer(ec)->ownerDocument(), start->startContainer(ec), start->startOffset(ec), end->endContainer(ec), end->endOffset(ec));
+}
+
+// Execute command functions
+
+static bool executeBackColor(Frame* frame, Event*, EditorCommandSource source, const String& value)
+{
+    return executeApplyStyle(frame, source, EditActionSetBackgroundColor, CSS_PROP_BACKGROUND_COLOR, value);
+}
+
+static bool executeBackwardDelete(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->deleteWithDirection(SelectionController::BACKWARD, CharacterGranularity, false, true);
+    return true;
+}
+
+static bool executeCopy(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->copy();
+    return true;
+}
+
+static bool executeCreateLink(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    // FIXME: If userInterface is true, we should display a dialog box to let the user enter a URL.
+    if (value.isEmpty())
+        return false;
+    applyCommand(new CreateLinkCommand(frame->document(), value));
+    return true;
+}
+
+static bool executeCut(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->cut();
+    return true;
+}
+
+static bool executeDelete(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    // FIXME: Not sure there's a real reason to have this do something different when invoked from DOM.
+    // At some point we should either merge these or remove this comment.
+    switch (source) {
+        case CommandFromMenuOrKeyBinding:
+            frame->editor()->performDelete();
+            return true;
+        case CommandFromDOM:
+        case CommandFromDOMWithUserInterface:
+            TypingCommand::deleteKeyPressed(frame->document(), frame->selectionGranularity() == WordGranularity);
+            return true;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeDeleteToMark(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    RefPtr<Range> mark = frame->mark().toRange();
+    if (mark) {
+        SelectionController* selectionController = frame->selectionController();
+        bool selected = selectionController->setSelectedRange(unionDOMRanges(mark.get(), frame->editor()->selectedRange().get()).get(), DOWNSTREAM, true);
+        ASSERT(selected);
+        if (!selected)
+            return false;
+    }
+    frame->editor()->performDelete();
+    frame->setMark(frame->selectionController()->selection());
+    return true;
+}
+
+static bool executeDeleteWordBackward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->deleteWithDirection(SelectionController::BACKWARD, WordGranularity, true, false);
+    return true;
+}
+
+static bool executeDeleteWordForward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->deleteWithDirection(SelectionController::FORWARD, WordGranularity, true, false);
+    return true;
+}
+
+static bool executeFindString(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    return frame->findString(value, true, false, true, false);
+}
+
+static bool executeFontName(Frame* frame, Event*, EditorCommandSource source, const String& value)
+{
+    return executeApplyStyle(frame, source, EditActionSetFont, CSS_PROP_FONT_FAMILY, value);
+}
+
+static bool executeFontSize(Frame* frame, Event*, EditorCommandSource source, const String& value)
+{
+    int size;
+    if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
+        return false;
+    return executeApplyStyle(frame, source, EditActionChangeAttributes, CSS_PROP_FONT_SIZE, size);
+}
+
+static bool executeFontSizeDelta(Frame* frame, Event*, EditorCommandSource source, const String& value)
+{
+    return executeApplyStyle(frame, source, EditActionChangeAttributes, CSS_PROP__WEBKIT_FONT_SIZE_DELTA, value);
+}
+
+static bool executeForeColor(Frame* frame, Event*, EditorCommandSource source, const String& value)
+{
+    return executeApplyStyle(frame, source, EditActionSetColor, CSS_PROP_COLOR, value);
+}
+
+static bool executeFormatBlock(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    String tagName = value.lower();
+    if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
+        tagName = tagName.substring(1, tagName.length() - 2);
+    if (!validBlockTag(tagName))
+        return false;
+    applyCommand(new FormatBlockCommand(frame->document(), tagName));
+    return true;
+}
+
+static bool executeForwardDelete(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    // FIXME: Not sure there's a real reason to have this do something different when invoked from DOM.
+    // At some point we should either merge these or remove this comment.
+    switch (source) {
+        case CommandFromMenuOrKeyBinding:
+            frame->editor()->deleteWithDirection(SelectionController::FORWARD, CharacterGranularity, false, true);
+            return true;
+        case CommandFromDOM:
+        case CommandFromDOMWithUserInterface:
+            TypingCommand::forwardDeleteKeyPressed(frame->document());
+            return true;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeIndent(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    applyCommand(new IndentOutdentCommand(frame->document(), IndentOutdentCommand::Indent));
+    return true;
+}
+
+static bool executeInsertBacktab(Frame* frame, Event* event, EditorCommandSource, const String&)
+{
+    return targetFrame(frame, event)->eventHandler()->handleTextInputEvent("\t", event, false, true);
+}
+
+static bool executeInsertHorizontalRule(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    RefPtr<HTMLElement> hr = new HTMLElement(hrTag, frame->document());
+    if (!value.isEmpty())
+        hr->setId(value);
+    return executeInsertNode(frame, hr.release());
+}
+
+static bool executeInsertHTML(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    return executeInsertFragment(frame, createFragmentFromMarkup(frame->document(), value, ""));
+}
+
+static bool executeInsertImage(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    // FIXME: If userInterface is true, we should display a dialog box and let the user choose a local image.
+    RefPtr<HTMLImageElement> image = new HTMLImageElement(imgTag, frame->document());
+    image->setSrc(value);
+    return executeInsertNode(frame, image.release());
+}
+
+static bool executeInsertLineBreak(Frame* frame, Event* event, EditorCommandSource source, const String&)
+{
+    // FIXME: Not sure there's a real reason to have this do something different when invoked from DOM.
+    // At some point we should either merge these or remove this comment.
+    switch (source) {
+        case CommandFromMenuOrKeyBinding:
+            return targetFrame(frame, event)->eventHandler()->handleTextInputEvent("\n", event, true);
+        case CommandFromDOM:
+        case CommandFromDOMWithUserInterface:
+            TypingCommand::insertLineBreak(frame->document());
+            return true;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+static bool executeInsertNewline(Frame* frame, Event* event, EditorCommandSource, const String&)
+{
+    Frame* targetFrame = WebCore::targetFrame(frame, event);
+    return targetFrame->eventHandler()->handleTextInputEvent("\n", event, !targetFrame->editor()->canEditRichly());
+}
+
+static bool executeInsertNewlineInQuotedContent(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    TypingCommand::insertParagraphSeparatorInQuotedContent(frame->document());
+    return true;
+}
+
+static bool executeInsertOrderedList(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    applyCommand(new InsertListCommand(frame->document(), InsertListCommand::OrderedList, value));
+    return true;
+}
+
+static bool executeInsertParagraph(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    TypingCommand::insertParagraphSeparator(frame->document());
+    return true;
+}
+
+static bool executeInsertTab(Frame* frame, Event* event, EditorCommandSource, const String&)
+{
+    return targetFrame(frame, event)->eventHandler()->handleTextInputEvent("\t", event, false, false);
+}
+
+static bool executeInsertText(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    TypingCommand::insertText(frame->document(), value);
+    return true;
+}
+
+static bool executeInsertUnorderedList(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+    applyCommand(new InsertListCommand(frame->document(), InsertListCommand::UnorderedList, value));
+    return true;
+}
+
+static bool executeJustifyCenter(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyParagraphStyle(frame, source, EditActionCenter, CSS_PROP_TEXT_ALIGN, "center");
+}
+
+static bool executeJustifyFull(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyParagraphStyle(frame, source, EditActionJustify, CSS_PROP_TEXT_ALIGN, "justify");
+}
+
+static bool executeJustifyLeft(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyParagraphStyle(frame, source, EditActionAlignLeft, CSS_PROP_TEXT_ALIGN, "left");
+}
+
+static bool executeJustifyRight(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyParagraphStyle(frame, source, EditActionAlignRight, CSS_PROP_TEXT_ALIGN, "right");
+}
+
+static bool executeMoveBackward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveBackwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveDown(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, LineGranularity, true);
+    return true;
+}
+
+static bool executeMoveDownAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, LineGranularity, true);
+    return true;
+}
+
+static bool executeMoveDownByPageAndModifyCaret(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    Node* focusedNode = frame->document()->focusedNode();
+    if (!focusedNode)
+        return false;
+    RenderObject* renderer = focusedNode->renderer();
+    if (!canScroll(renderer))
+        return false;
+    bool handledScroll = renderer->scroll(ScrollDown, ScrollByPage);
+    bool handledCaretMove = frame->selectionController()->modify(SelectionController::MOVE, renderer->clientHeight() - PAGE_KEEP);
+    return handledScroll || handledCaretMove;
+}
+
+static bool executeMoveForward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveForwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveLeft(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveLeftAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::LEFT, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveRight(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveRightAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::RIGHT, CharacterGranularity, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfDocument(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, DocumentBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfDocumentAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, DocumentBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfLine(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, LineBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfLineAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, LineBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfParagraph(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, ParagraphBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfParagraphAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, ParagraphBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfSentence(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, SentenceBoundary, true);
+    return true;
+}
+
+static bool executeMoveToBeginningOfSentenceAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, SentenceBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfDocument(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, DocumentBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfDocumentAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, DocumentBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfSentence(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, SentenceBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfSentenceAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, SentenceBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfLine(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, LineBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfLineAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, LineBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfParagraph(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, ParagraphBoundary, true);
+    return true;
+}
+
+static bool executeMoveToEndOfParagraphAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, ParagraphBoundary, true);
+    return true;
+}
+
+static bool executeMoveParagraphBackwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, ParagraphGranularity, true);
+    return true;
+}
+
+static bool executeMoveParagraphForwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, ParagraphGranularity, true);
+    return true;
+}
+
+static bool executeMoveUp(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, LineGranularity, true);
+    return true;
+}
+
+static bool executeMoveUpAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, LineGranularity, true);
+    return true;
+}
+
+static bool executeMoveUpByPageAndModifyCaret(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    Node* focusedNode = frame->document()->focusedNode();
+    if (!focusedNode)
+        return false;
+    RenderObject* renderer = focusedNode->renderer();
+    if (!canScroll(renderer))
+        return false;
+    bool handledScroll = renderer->scroll(ScrollDown, ScrollByPage);
+    bool handledCaretMove = frame->selectionController()->modify(SelectionController::MOVE, -(renderer->clientHeight() - PAGE_KEEP));
+    return handledScroll || handledCaretMove;
+}
+
+static bool executeMoveWordBackward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordBackwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordForward(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordForwardAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordLeft(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordLeftAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::LEFT, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordRight(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, WordGranularity, true);
+    return true;
+}
+
+static bool executeMoveWordRightAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::RIGHT, WordGranularity, true);
+    return true;
+}
+
+static bool executeOutdent(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    applyCommand(new IndentOutdentCommand(frame->document(), IndentOutdentCommand::Outdent));
+    return true;
+}
+
+static bool executePaste(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->paste();
+    return true;
+}
+
+static bool executePasteAndMatchStyle(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->pasteAsPlainText();
+    return true;
+}
+
+static bool executePrint(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    Page* page = frame->page();
+    if (!page)
+        return false;
+    page->chrome()->print(frame);
+    return true;
+}
+
+static bool executeRedo(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->redo();
+    return true;
+}
+
+static bool executeRemoveFormat(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->removeFormattingAndStyle();
+    return true;
+}
+
+static bool executeSelectAll(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->selectAll();
+    return true;
+}
+
+static bool executeSelectToMark(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    RefPtr<Range> mark = frame->mark().toRange();
+    RefPtr<Range> selection = frame->editor()->selectedRange();
+    if (!mark || !selection) {
+        systemBeep();
+        return false;
+    }
+    frame->selectionController()->setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, true);
+    return true;
+}
+
+static bool executeSetMark(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->setMark(frame->selectionController()->selection());
+    return true;
+}
+
+static bool executeStrikethrough(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeToggleStyle(frame, source, EditActionChangeAttributes, CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "none", "line-through");
+}
+
+static bool executeSubscript(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyStyle(frame, source, EditActionSubscript, CSS_PROP_VERTICAL_ALIGN, "sub");
+}
+
+static bool executeSuperscript(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyStyle(frame, source, EditActionSuperscript, CSS_PROP_VERTICAL_ALIGN, "super");
+}
+
+static bool executeSwapWithMark(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    const Selection& mark = frame->mark();
+    Selection selection = frame->selectionController()->selection();
+    if (mark.isNone() || selection.isNone()) {
+        systemBeep();
+        return false;
+    }
+
+    frame->selectionController()->setSelection(mark);
+    frame->setMark(selection);
+    return true;
+}
+
+static bool executeToggleBold(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeToggleStyle(frame, source, EditActionChangeAttributes, CSS_PROP_FONT_WEIGHT, "normal", "bold");
+}
+
+static bool executeToggleItalic(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeToggleStyle(frame, source, EditActionChangeAttributes, CSS_PROP_FONT_STYLE, "normal", "italic");
+}
+
+static bool executeTranspose(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->transpose();
+    return true;
+}
+
+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, CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "none", "underline");
+}
+
+static bool executeUndo(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->undo();
+    return true;
+}
+
+static bool executeUnlink(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    applyCommand(new UnlinkCommand(frame->document()));
+    return true;
+}
+
+static bool executeUnscript(Frame* frame, Event*, EditorCommandSource source, const String&)
+{
+    return executeApplyStyle(frame, source, EditActionUnscript, CSS_PROP_VERTICAL_ALIGN, "baseline");
+}
+
+static bool executeUnselect(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->selectionController()->clear();
+    return true;
+}
+
+static bool executeYank(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->insertTextWithoutSendingTextEvent(frame->editor()->yankFromKillRing(), false);
+    frame->editor()->setKillRingToYankedState();
+    return true;
+}
+
+static bool executeYankAndSelect(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+    frame->editor()->insertTextWithoutSendingTextEvent(frame->editor()->yankFromKillRing(), true);
+    frame->editor()->setKillRingToYankedState();
+    return true;
+}
+
+// Supported functions
+
+static bool supported(Frame*, EditorCommandSource)
+{
+    return true;
+}
+
+static bool supportedPaste(Frame* frame, EditorCommandSource source)
+{
+    switch (source) {
+        case CommandFromMenuOrKeyBinding:
+            return true;
+        case CommandFromDOM:
+        case CommandFromDOMWithUserInterface: {
+            Settings* settings = frame ? frame->settings() : 0;
+            return settings && settings->isDOMPasteAllowed();
+        }
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+// Enabled functions
+
+static bool enabled(Frame*, Event*)
+{
+    return true;
+}
+
+static bool enabledAnySelection(Frame* frame, Event*)
+{
+    return frame->selectionController()->isCaretOrRange();
+}
+
+static bool enabledAnySelectionAndMark(Frame* frame, Event*)
+{
+    return frame->selectionController()->isCaretOrRange() && frame->mark().isCaretOrRange();
+}
+
+static bool enableCaretInEditableText(Frame* frame, Event* event)
+{
+    const Selection& selection = frame->editor()->selectionForCommand(event);
+    return selection.isCaret() && selection.isContentEditable();
+}
+
+static bool enabledCopy(Frame* frame, Event* source)
+{
+    return frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
+}
+
+static bool enabledCut(Frame* frame, Event* source)
+{
+    return frame->editor()->canDHTMLCut() || frame->editor()->canCut();
+}
+
+static bool enabledInEditableText(Frame* frame, Event* event)
+{
+    return frame->editor()->selectionForCommand(event).isContentEditable();
+}
+
+static bool enabledInRichlyEditableText(Frame* frame, Event*)
+{
+    return frame->selectionController()->isCaretOrRange() && frame->selectionController()->isContentRichlyEditable();
+}
+
+static bool enabledPaste(Frame* frame, Event*)
+{
+    return frame->editor()->canPaste();
+}
+
+static bool enabledRangeInEditableText(Frame* frame, Event*)
+{
+    return frame->selectionController()->isRange() && frame->selectionController()->isContentEditable();
+}
+
+static bool enabledRangeInRichlyEditableText(Frame* frame, Event*)
+{
+    return frame->selectionController()->isRange() && frame->selectionController()->isContentRichlyEditable();
+}
+
+static bool enabledRedo(Frame* frame, Event*)
+{
+    return frame->editor()->canRedo();
+}
+
+static bool enabledUndo(Frame* frame, Event*)
+{
+    return frame->editor()->canUndo();
+}
+
+// State functions
+
+static TriState stateNone(Frame*, Event*)
+{
+    return FalseTriState;
+}
+
+static TriState stateBold(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_FONT_WEIGHT, "bold");
+}
+
+static TriState stateItalic(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_FONT_STYLE, "italic");
+}
+
+static TriState stateOrderedList(Frame* frame, Event*)
+{
+    return frame->editor()->selectionOrderedListState();
+}
+
+static TriState stateStrikethrough(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_TEXT_DECORATION, "line-through");
+}
+
+static TriState stateSubscript(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_VERTICAL_ALIGN, "sub");
+}
+
+static TriState stateSuperscript(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_VERTICAL_ALIGN, "super");
+}
+
+static TriState stateUnderline(Frame* frame, Event*)
+{
+    return stateStyle(frame, CSS_PROP_TEXT_DECORATION, "underline");
+}
+
+static TriState stateUnorderedList(Frame* frame, Event*)
+{
+    return frame->editor()->selectionUnorderedListState();
+}
+
+// Value functions
+
+static String valueNull(Frame*, Event*)
+{
+    return String();
+}
+
+String valueBackColor(Frame* frame, Event*)
+{
+    return valueStyle(frame, CSS_PROP_BACKGROUND_COLOR);
+}
+
+String valueFontName(Frame* frame, Event*)
+{
+    return valueStyle(frame, CSS_PROP_FONT_FAMILY);
+}
+
+String valueFontSize(Frame* frame, Event*)
+{
+    return valueStyle(frame, CSS_PROP_FONT_SIZE);
+}
+
+String valueFontSizeDelta(Frame* frame, Event*)
+{
+    return valueStyle(frame, CSS_PROP__WEBKIT_FONT_SIZE_DELTA);
+}
+
+String valueForeColor(Frame* frame, Event*)
+{
+    return valueStyle(frame, CSS_PROP_COLOR);
+}
+
+// Map of functions
+
+static const CommandMap& createCommandMap()
+{
+    struct CommandEntry { const char* name; EditorInternalCommand command; };
+    
+    static const CommandEntry commands[] = {
+        { "AlignCenter", { executeJustifyCenter, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "AlignJustified", { executeJustifyFull, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "AlignLeft", { executeJustifyLeft, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "AlignRight", { executeJustifyRight, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "BackColor", { executeBackColor, supported, enabledRangeInRichlyEditableText, stateNone, valueBackColor, notTextInsertion } },
+        { "BackwardDelete", { executeBackwardDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Bold", { executeToggleBold, supported, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion } },
+        { "Copy", { executeCopy, supported, enabledCopy, stateNone, valueNull, notTextInsertion } },
+        { "CreateLink", { executeCreateLink, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Cut", { executeCut, supported, enabledCut, stateNone, valueNull, notTextInsertion } },
+        { "Delete", { executeDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "DeleteToMark", { executeDeleteToMark, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "DeleteWordBackward", { executeDeleteWordBackward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "DeleteWordForward", { executeDeleteWordForward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "FindString", { executeFindString, supported, enabled, stateNone, valueNull, notTextInsertion } },
+        { "FontName", { executeFontName, supported, enabledInEditableText, stateNone, valueFontName, notTextInsertion } },
+        { "FontSize", { executeFontSize, supported, enabledInEditableText, stateNone, valueFontSize, notTextInsertion } },
+        { "FontSizeDelta", { executeFontSizeDelta, supported, enabledInEditableText, stateNone, valueFontSizeDelta, notTextInsertion } },
+        { "ForeColor", { executeForeColor, supported, enabledInEditableText, stateNone, valueForeColor, notTextInsertion } },
+        { "FormatBlock", { executeFormatBlock, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "ForwardDelete", { executeForwardDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "HiliteColor", { executeBackColor, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Indent", { executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertBacktab", { executeInsertBacktab, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion } },
+        { "InsertHTML", { executeInsertHTML, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertHorizontalRule", { executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertImage", { executeInsertImage, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertLineBreak", { executeInsertLineBreak, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion } },
+        { "InsertNewline", { executeInsertNewline, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion } },    
+        { "InsertNewlineInQuotedContent", { executeInsertNewlineInQuotedContent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertOrderedList", { executeInsertOrderedList, supported, enabledInRichlyEditableText, stateOrderedList, valueNull, notTextInsertion } },
+        { "InsertParagraph", { executeInsertParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertTab", { executeInsertTab, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion } },
+        { "InsertText", { executeInsertText, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "InsertUnorderedList", { executeInsertUnorderedList, supported, enabledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion } },
+        { "Italic", { executeToggleItalic, supported, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion } },
+        { "JustifyCenter", { executeJustifyCenter, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "JustifyFull", { executeJustifyFull, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "JustifyLeft", { executeJustifyLeft, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "JustifyNone", { executeJustifyLeft, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "JustifyRight", { executeJustifyRight, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveBackward", { executeMoveBackward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveBackwardAndModifySelection", { executeMoveBackwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveDown", { executeMoveDown, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveDownAndModifySelection", { executeMoveDownAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveDownByPageAndModifyCaret", { executeMoveDownByPageAndModifyCaret, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveForward", { executeMoveForward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveForwardAndModifySelection", { executeMoveForwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveLeft", { executeMoveLeft, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveLeftAndModifySelection", { executeMoveLeftAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveParagraphBackwardAndModifySelection", { executeMoveParagraphBackwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveParagraphForwardAndModifySelection", { executeMoveParagraphForwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveRight", { executeMoveRight, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveRightAndModifySelection", { executeMoveRightAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfDocument", { executeMoveToBeginningOfDocument, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfDocumentAndModifySelection", { executeMoveToBeginningOfDocumentAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfLine", { executeMoveToBeginningOfLine, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfLineAndModifySelection", { executeMoveToBeginningOfLineAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfParagraph", { executeMoveToBeginningOfParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfParagraphAndModifySelection", { executeMoveToBeginningOfParagraphAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfSentence", { executeMoveToBeginningOfSentence, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToBeginningOfSentenceAndModifySelection", { executeMoveToBeginningOfSentenceAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfDocument", { executeMoveToEndOfDocument, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfDocumentAndModifySelection", { executeMoveToEndOfDocumentAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfLine", { executeMoveToEndOfLine, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfLineAndModifySelection", { executeMoveToEndOfLineAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfParagraph", { executeMoveToEndOfParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfParagraphAndModifySelection", { executeMoveToEndOfParagraphAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfSentence", { executeMoveToEndOfSentence, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveToEndOfSentenceAndModifySelection", { executeMoveToEndOfSentenceAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveUp", { executeMoveUp, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveUpAndModifySelection", { executeMoveUpAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveUpByPageAndModifyCaret", { executeMoveUpByPageAndModifyCaret, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordBackward", { executeMoveWordBackward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordBackwardAndModifySelection", { executeMoveWordBackwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordForward", { executeMoveWordForward, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordForwardAndModifySelection", { executeMoveWordForwardAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordLeft", { executeMoveWordLeft, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordLeftAndModifySelection", { executeMoveWordLeftAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordRight", { executeMoveWordRight, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "MoveWordRightAndModifySelection", { executeMoveWordRightAndModifySelection, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Outdent", { executeOutdent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Paste", { executePaste, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion } },
+        { "PasteAndMatchStyle", { executePasteAndMatchStyle, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion } },
+        { "Print", { executePrint, supported, enabled, stateNone, valueNull, notTextInsertion } },
+        { "Redo", { executeRedo, supported, enabledRedo, stateNone, valueNull, notTextInsertion } },
+        { "RemoveFormat", { executeRemoveFormat, supported, enabledRangeInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "SelectAll", { executeSelectAll, supported, enabled, stateNone, valueNull, notTextInsertion } },
+        { "SelectToMark", { executeSelectToMark, supported, enabledAnySelectionAndMark, stateNone, valueNull, notTextInsertion } },
+        { "SetMark", { executeSetMark, supported, enabledAnySelection, stateNone, valueNull, notTextInsertion } },
+        { "Strikethrough", { executeStrikethrough, supported, enabledInRichlyEditableText, stateStrikethrough, valueNull, notTextInsertion } },
+        { "Subscript", { executeSubscript, supported, enabledInRichlyEditableText, stateSubscript, valueNull, notTextInsertion } },
+        { "Superscript", { executeSuperscript, supported, enabledInRichlyEditableText, stateSuperscript, valueNull, notTextInsertion } },
+        { "SwapWithMark", { executeSwapWithMark, supported, enabledAnySelectionAndMark, stateNone, valueNull, notTextInsertion } },
+        { "ToggleBold", { executeToggleBold, supported, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion } },
+        { "ToggleItalic", { executeToggleItalic, supported, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion } },
+        { "ToggleUnderline", { executeUnderline, supported, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion } },
+        { "Transpose", { executeTranspose, supported, enableCaretInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Underline", { executeUnderline, supported, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion } },
+        { "Undo", { executeUndo, supported, enabledUndo, stateNone, valueNull, notTextInsertion } },
+        { "Unlink", { executeUnlink, supported, enabledRangeInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Unscript", { executeUnscript, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion } },
+        { "Unselect", { executeUnselect, supported, enabledAnySelection, stateNone, valueNull, notTextInsertion } },
+        { "Yank", { executeYank, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+        { "YankAndSelect", { executeYankAndSelect, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion } },
+    };
+
+    // These unsupported commands are listed here since they appear in the Microsoft
+    // documentation used as the starting point for our DOM executeCommand support.
+    //
+    // 2D-Position (not supported)
+    // AbsolutePosition (not supported)
+    // BlockDirLTR (not supported)
+    // BlockDirRTL (not supported)
+    // BrowseMode (not supported)
+    // ClearAuthenticationCache (not supported)
+    // CreateBookmark (not supported)
+    // DirLTR (not supported)
+    // DirRTL (not supported)
+    // EditMode (not supported)
+    // InlineDirLTR (not supported)
+    // InlineDirRTL (not supported)
+    // InsertButton (not supported)
+    // InsertFieldSet (not supported)
+    // InsertIFrame (not supported)
+    // InsertInputButton (not supported)
+    // InsertInputCheckbox (not supported)
+    // InsertInputFileUpload (not supported)
+    // InsertInputHidden (not supported)
+    // InsertInputImage (not supported)
+    // InsertInputPassword (not supported)
+    // InsertInputRadio (not supported)
+    // InsertInputReset (not supported)
+    // InsertInputSubmit (not supported)
+    // InsertInputText (not supported)
+    // InsertMarquee (not supported)
+    // InsertSelectDropDown (not supported)
+    // InsertSelectListBox (not supported)
+    // InsertTextArea (not supported)
+    // LiveResize (not supported)
+    // MultipleSelection (not supported)
+    // Open (not supported)
+    // Overwrite (not supported)
+    // PlayImage (not supported)
+    // Refresh (not supported)
+    // RemoveParaFormat (not supported)
+    // SaveAs (not supported)
+    // SizeToControl (not supported)
+    // SizeToControlHeight (not supported)
+    // SizeToControlWidth (not supported)
+    // Stop (not supported)
+    // StopImage (not supported)
+    // Unbookmark (not supported)
+
+    CommandMap& commandMap = *new CommandMap;
+
+    const unsigned numCommands = sizeof(commands) / sizeof(commands[0]);
+    for (unsigned i = 0; i < numCommands; i++) {
+        ASSERT(!commandMap.get(commands[i].name));
+        commandMap.set(commands[i].name, &commands[i].command);
+    }
+
+    return commandMap;
+}
+
+Editor::Command Editor::command(const String& commandName)
+{
+    return command(commandName, CommandFromMenuOrKeyBinding);
+}
+
+Editor::Command Editor::command(const String& commandName, EditorCommandSource source)
+{
+    static const CommandMap& commandMap = createCommandMap();
+    const EditorInternalCommand* internalCommand = commandMap.get(commandName);
+    return internalCommand ? Command(m_frame, internalCommand, source) : Command();
+}
+
+Editor::Command::Command()
+    : m_command(0)
+    , m_source()
+{
+}
+
+Editor::Command::Command(PassRefPtr<Frame> frame, const EditorInternalCommand* command, EditorCommandSource source)
+    : m_frame(frame)
+    , m_command(command)
+    , m_source(source)
+{
+    ASSERT(m_frame);
+    ASSERT(m_command);
+}
+
+bool Editor::Command::execute(const String& parameter, Event* triggeringEvent) const
+{
+    if (!isEnabled(triggeringEvent))
+        return false;
+    m_frame->document()->updateLayoutIgnorePendingStylesheets();
+    return m_command->execute(m_frame.get(), triggeringEvent, m_source, parameter);
+}
+
+bool Editor::Command::execute(Event* triggeringEvent) const
+{
+    return execute(String(), triggeringEvent);
+}
+
+bool Editor::Command::isSupported() const
+{
+    return m_command && m_command->isSupported(m_frame.get(), m_source);
+}
+
+bool Editor::Command::isEnabled(Event* triggeringEvent) const
+{
+    if (!isSupported() || !m_frame || !m_frame->document())
+        return false;
+    return m_command->isEnabled(m_frame.get(), triggeringEvent);
+}
+
+TriState Editor::Command::state(Event* triggeringEvent) const
+{
+    if (!isSupported() || !m_frame || !m_frame->document())
+        return FalseTriState;
+    return m_command->state(m_frame.get(), triggeringEvent);
+}
+
+String Editor::Command::value(Event* triggeringEvent) const
+{
+    if (!isSupported() || !m_frame || !m_frame->document())
+        return String();
+    return m_command->value(m_frame.get(), triggeringEvent);
+}
+
+bool Editor::Command::isTextInsertion() const
+{
+    return m_command && m_command->isTextInsertion;
+}
+
+bool Editor::execCommand(const AtomicString& commandName, Event* triggeringEvent)
+{
+    return command(commandName).execute(triggeringEvent);
+}
+
+} // namespace WebCore
diff --git a/WebCore/editing/JSEditor.cpp b/WebCore/editing/JSEditor.cpp
deleted file mode 100644 (file)
index 932e534..0000000
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
- *
- * 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "JSEditor.h"
-
-#include "CSSPropertyNames.h"
-#include "CreateLinkCommand.h"
-#include "Document.h"
-#include "DocumentFragment.h"
-#include "Editor.h"
-#include "EditorClient.h"
-#include "FormatBlockCommand.h"
-#include "Frame.h"
-#include "HTMLFontElement.h"
-#include "HTMLImageElement.h"
-#include "HTMLNames.h"
-#include "IndentOutdentCommand.h"
-#include "InsertListCommand.h"
-#include "Page.h"
-#include "ReplaceSelectionCommand.h"
-#include "SelectionController.h"
-#include "Settings.h"
-#include "TypingCommand.h"
-#include "UnlinkCommand.h"
-#include "htmlediting.h"
-#include "markup.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-class Document;
-
-namespace {
-
-struct CommandImp {
-    bool (*execFn)(Frame*, bool userInterface, const String& value);
-    bool (*enabledFn)(Frame*);
-    Frame::TriState (*stateFn)(Frame*);
-    String (*valueFn)(Frame*);
-};
-
-typedef HashMap<StringImpl*, const CommandImp*, CaseInsensitiveHash<StringImpl*> > CommandMap;
-
-CommandMap* createCommandDictionary();
-
-const CommandImp* commandImp(const String& command)
-{
-    static CommandMap* commandDictionary = createCommandDictionary();
-    return commandDictionary->get(command.impl());
-}
-
-} // anonymous namespace
-
-bool JSEditor::execCommand(const String& command, bool userInterface, const String& value)
-{
-    const CommandImp* cmd = commandImp(command);
-    if (!cmd)
-        return false;
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return false;
-    m_document->updateLayoutIgnorePendingStylesheets();
-    return cmd->enabledFn(frame) && cmd->execFn(frame, userInterface, value);
-}
-
-bool JSEditor::queryCommandEnabled(const String& command)
-{
-    const CommandImp* cmd = commandImp(command);
-    if (!cmd)
-        return false;
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return false;
-    m_document->updateLayoutIgnorePendingStylesheets();
-    return cmd->enabledFn(frame);
-}
-
-bool JSEditor::queryCommandIndeterm(const String& command)
-{
-    const CommandImp* cmd = commandImp(command);
-    if (!cmd)
-        return false;
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return false;
-    m_document->updateLayoutIgnorePendingStylesheets();
-    return cmd->stateFn(frame) == Frame::mixedTriState;
-}
-
-bool JSEditor::queryCommandState(const String& command)
-{
-    const CommandImp* cmd = commandImp(command);
-    if (!cmd)
-        return false;
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return false;
-    m_document->updateLayoutIgnorePendingStylesheets();
-    return cmd->stateFn(frame) != Frame::falseTriState;
-}
-
-bool JSEditor::queryCommandSupported(const String& command)
-{
-    Settings* settings = m_document->settings();
-    if ((!settings || !settings->isDOMPasteAllowed()) && command.lower() == "paste")
-        return false;
-    return commandImp(command) != 0;
-}
-
-String JSEditor::queryCommandValue(const String& command)
-{
-    const CommandImp* cmd = commandImp(command);
-    if (!cmd)
-        return String();
-    Frame* frame = m_document->frame();
-    if (!frame)
-        return String();
-    m_document->updateLayoutIgnorePendingStylesheets();
-    return cmd->valueFn(frame);
-}
-
-// =============================================================================================
-
-// Private stuff, all inside an anonymous namespace.
-
-namespace {
-
-bool execStyleChange(Frame* frame, int propertyID, const String& propertyValue)
-{
-    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
-    style->setProperty(propertyID, propertyValue);
-    frame->editor()->applyStyle(style.get());
-    return true;
-}
-
-bool execStyleChange(Frame* frame, int propertyID, const char* propertyValue)
-{
-    return execStyleChange(frame, propertyID, String(propertyValue));
-}
-
-bool execStyleChange(Frame* frame, int propertyID, int propertyValue)
-{
-    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
-    style->setProperty(propertyID, propertyValue);
-    frame->editor()->applyStyle(style.get());
-    return true;
-}
-
-Frame::TriState stateStyle(Frame* frame, int propertyID, const char* desiredValue)
-{
-    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
-    style->setProperty(propertyID, desiredValue);
-    return frame->selectionHasStyle(style.get());
-}
-
-bool selectionStartHasStyle(Frame* frame, int propertyID, const char* desiredValue)
-{
-    RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
-    style->setProperty(propertyID, desiredValue);
-    return frame->editor()->selectionStartHasStyle(style.get());
-}
-
-String valueStyle(Frame* frame, int propertyID)
-{
-    return frame->selectionStartStylePropertyValue(propertyID);
-}
-
-// =============================================================================================
-//
-// execCommand implementations
-//
-
-bool execBackColor(Frame* frame, bool, const String& value)
-{
-    return execStyleChange(frame, CSS_PROP_BACKGROUND_COLOR, value);
-}
-
-bool execBold(Frame* frame, bool, const String&)
-{
-    bool isBold = selectionStartHasStyle(frame, CSS_PROP_FONT_WEIGHT, "bold");
-    return execStyleChange(frame, CSS_PROP_FONT_WEIGHT, isBold ? "normal" : "bold");
-}
-
-bool execCopy(Frame* frame, bool, const String&)
-{
-    frame->editor()->copy();
-    return true;
-}
-
-bool execCreateLink(Frame* frame, bool userInterface, const String& value)
-{
-    // FIXME: If userInterface is true, we should display a dialog box to let the user enter a url.
-    if (userInterface)
-        LOG_ERROR("A dialog box for link creation is not yet implemented.\n");
-    
-    if (value.isEmpty())
-        return false;
-    
-    applyCommand(new CreateLinkCommand(frame->document(), value));
-    return true;
-}
-
-bool execCut(Frame* frame, bool, const String&)
-{
-    frame->editor()->cut();
-    return true;
-}
-
-bool execDelete(Frame* frame, bool, const String&)
-{
-    TypingCommand::deleteKeyPressed(frame->document(), frame->selectionGranularity() == WordGranularity);
-    return true;
-}
-
-bool execFindString(Frame* frame, bool, const String& value)
-{
-    return frame->findString(value, true, false, true, false);
-}
-
-bool execForwardDelete(Frame* frame, bool, const String&)
-{
-    TypingCommand::forwardDeleteKeyPressed(frame->document());
-    return true;
-}
-
-bool execFontName(Frame* frame, bool, const String& value)
-{
-    return execStyleChange(frame, CSS_PROP_FONT_FAMILY, value);
-}
-
-bool execFontSize(Frame* frame, bool, const String& value)
-{
-    int size;
-    if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
-        return false;
-        
-    return execStyleChange(frame, CSS_PROP_FONT_SIZE, size);
-}
-
-bool execFontSizeDelta(Frame* frame, bool, const String& value)
-{
-    return execStyleChange(frame, CSS_PROP__WEBKIT_FONT_SIZE_DELTA, value);
-}
-
-bool execForeColor(Frame* frame, bool, const String& value)
-{
-    return execStyleChange(frame, CSS_PROP_COLOR, value);
-}
-
-bool execFormatBlock(Frame* frame, bool, const String& value)
-{
-    String tagName = value.lower();
-    if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
-        tagName = tagName.substring(1, tagName.length() - 2);
-    if (!validBlockTag(tagName))
-        return false;
-    applyCommand(new FormatBlockCommand(frame->document(), tagName));
-    return true;
-}
-
-bool execInsertHorizontalRule(Frame* frame, bool userInterface, const String& value)
-{
-    RefPtr<HTMLElement> hr = new HTMLElement(hrTag, frame->document());
-    if (!value.isEmpty())
-        hr->setId(value);
-    RefPtr<DocumentFragment> fragment = new DocumentFragment(frame->document());
-    ExceptionCode ec = 0;
-    fragment->appendChild(hr, ec);
-    if (ec)
-        return false;
-    
-    applyCommand(new ReplaceSelectionCommand(frame->document(), fragment.release(),
-        false, false, false, true, false, EditActionUnspecified));
-    return true;
-}
-
-bool execInsertHTML(Frame* frame, bool userInterface, const String& value)
-{
-    Document* document = frame->document();
-    applyCommand(new ReplaceSelectionCommand(frame->document(), createFragmentFromMarkup(document, value, ""), false));
-    return true;
-}
-
-bool execInsertImage(Frame* frame, bool userInterface, const String& value)
-{
-    // FIXME: If userInterface is true, we should display a dialog box and let the user choose a local image.
-    if (userInterface)
-        LOG_ERROR("A dialog box for image insertion is not yet implemented.\n");
-    
-    RefPtr<HTMLImageElement> image = new HTMLImageElement(imgTag, frame->document());
-    image->setSrc(value);
-    RefPtr<DocumentFragment> fragment = new DocumentFragment(frame->document());
-    ExceptionCode ec = 0;
-    fragment->appendChild(image, ec);
-    if (ec)
-        return false;
-    
-    applyCommand(new ReplaceSelectionCommand(frame->document(), fragment.release(), false));
-    return true;
-}
-
-bool execIndent(Frame* frame, bool, const String&)
-{
-    applyCommand(new IndentOutdentCommand(frame->document(), IndentOutdentCommand::Indent));
-    return true;
-}
-
-bool execInsertLineBreak(Frame* frame, bool, const String&)
-{
-    TypingCommand::insertLineBreak(frame->document());
-    return true;
-}
-
-bool execInsertParagraph(Frame* frame, bool, const String&)
-{
-    TypingCommand::insertParagraphSeparator(frame->document());
-    return true;
-}
-
-bool execInsertNewlineInQuotedContent(Frame* frame, bool, const String&)
-{
-    TypingCommand::insertParagraphSeparatorInQuotedContent(frame->document());
-    return true;
-}
-
-bool execInsertText(Frame* frame, bool, const String& value)
-{
-    TypingCommand::insertText(frame->document(), value);
-    return true;
-}
-
-bool execInsertUnorderedList(Frame* frame, bool, const String& value)
-{
-    applyCommand(new InsertListCommand(frame->document(), InsertListCommand::UnorderedList, value));
-    return true;
-}
-
-bool execInsertOrderedList(Frame* frame, bool, const String& value)
-{
-    applyCommand(new InsertListCommand(frame->document(), InsertListCommand::OrderedList, value));
-    return true;
-}
-
-bool execItalic(Frame* frame, bool, const String&)
-{
-    bool isItalic = selectionStartHasStyle(frame, CSS_PROP_FONT_STYLE, "italic");
-    return execStyleChange(frame, CSS_PROP_FONT_STYLE, isItalic ? "normal" : "italic");
-}
-
-bool execJustifyCenter(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame, CSS_PROP_TEXT_ALIGN, "center");
-}
-
-bool execJustifyFull(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame, CSS_PROP_TEXT_ALIGN, "justify");
-}
-
-bool execJustifyLeft(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame, CSS_PROP_TEXT_ALIGN, "left");
-}
-
-bool execJustifyRight(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame, CSS_PROP_TEXT_ALIGN, "right");
-}
-
-bool execOutdent(Frame* frame, bool, const String&)
-{
-    applyCommand(new IndentOutdentCommand(frame->document(), IndentOutdentCommand::Outdent));
-    return true;
-}
-
-bool execPaste(Frame* frame, bool, const String&)
-{
-    frame->editor()->paste();
-    return true;
-}
-
-bool execPasteAndMatchStyle(Frame* frame, bool, const String&)
-{
-    frame->editor()->pasteAsPlainText();
-    return true;
-}
-
-bool execPrint(Frame* frame, bool, const String&)
-{
-    if (Page* page = frame->page())
-        page->chrome()->print(frame);
-    return true;
-}
-
-bool execRedo(Frame* frame, bool, const String&)
-{
-    frame->editor()->redo();
-    return true;
-}
-
-bool execRemoveFormat(Frame* frame, bool userInterface, const String& value)
-{
-    frame->editor()->removeFormattingAndStyle();
-    return true;
-}
-
-bool execSelectAll(Frame* frame, bool, const String&)
-{
-    frame->selectionController()->selectAll();
-    return true;
-}
-
-bool execStrikethrough(Frame* frame, bool, const String&)
-{
-    bool isStrikethrough = selectionStartHasStyle(frame,  CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "line-through");
-    return execStyleChange(frame, CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, isStrikethrough ? "none" : "line-through");
-}
-
-bool execSubscript(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame,  CSS_PROP_VERTICAL_ALIGN, "sub");
-}
-
-bool execSuperscript(Frame* frame, bool, const String&)
-{
-    return execStyleChange(frame,  CSS_PROP_VERTICAL_ALIGN, "super");
-}
-
-bool execTranspose(Frame* frame, bool, const String&)
-{
-    frame->editor()->transpose();
-    return true;
-}
-
-bool execUnderline(Frame* frame, bool, const String&)
-{
-    bool isUnderlined = selectionStartHasStyle(frame,  CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "underline");
-    return execStyleChange(frame,  CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, isUnderlined ? "none" : "underline");
-}
-
-bool execUndo(Frame* frame, bool, const String&)
-{
-    frame->editor()->undo();
-    return true;
-}
-
-bool execUnlink(Frame* frame, bool, const String&)
-{
-    applyCommand(new UnlinkCommand(frame->document()));
-    return true;
-}
-
-bool execUnselect(Frame* frame, bool, const String&)
-{
-    frame->selectionController()->clear();
-    return true;
-}
-
-// =============================================================================================
-//
-// queryCommandEnabled implementations
-//
-// It's a bit difficult to get a clear notion of the difference between
-// "supported" and "enabled" from reading the Microsoft documentation, but
-// what little I could glean from that seems to make some sense.
-//     Supported = The command is supported by this object.
-//     Enabled =   The command is available and enabled.
-
-bool enabled(Frame*)
-{
-    return true;
-}
-
-bool enabledAnyCaret(Frame* frame)
-{
-    return frame->selectionController()->isCaret() && frame->selectionController()->isContentEditable();
-}
-
-bool enabledAnySelection(Frame* frame)
-{
-    return frame->selectionController()->isCaretOrRange();
-}
-
-bool enabledAnyEditableSelection(Frame* frame)
-{
-    return frame->selectionController()->isCaretOrRange() && frame->selectionController()->isContentEditable();
-}
-
-bool enabledAnyRichlyEditableSelection(Frame* frame)
-{
-    return frame->selectionController()->isCaretOrRange() && frame->selectionController()->isContentRichlyEditable();
-}
-
-bool enabledCopy(Frame* frame)
-{
-    return !frame->selectionController()->isInPasswordField();
-}
-
-bool enabledPaste(Frame* frame)
-{
-    Settings* settings = frame ? frame->settings() : 0;
-    return settings && settings->isDOMPasteAllowed() && frame->editor()->canPaste();
-}
-
-bool enabledAnyRangeSelection(Frame* frame)
-{
-    return frame->selectionController()->isRange();
-}
-
-bool enabledAnyEditableRangeSelection(Frame* frame)
-{
-    return frame->selectionController()->isRange() && frame->selectionController()->isContentEditable();
-}
-
-bool enabledAnyRichlyEditableRangeSelection(Frame* frame)
-{
-    return frame->selectionController()->isRange() && frame->selectionController()->isContentRichlyEditable();
-}
-
-bool enabledRedo(Frame* frame)
-{
-    return frame->editor()->canRedo();
-}
-
-bool enabledUndo(Frame* frame)
-{
-    return frame->editor()->canUndo();
-}
-
-// =============================================================================================
-//
-// queryCommandIndeterm/State implementations
-//
-// It's a bit difficult to get a clear notion of what these methods are supposed
-// to do from reading the Microsoft documentation, but my current guess is this:
-//
-//     queryCommandState and queryCommandIndeterm work in concert to return
-//     the two bits of information that are needed to tell, for instance,
-//     if the text of a selection is bold. The answer can be "yes", "no", or
-//     "partially".
-//
-// If this is so, then queryCommandState should return "yes" in the case where
-// all the text is bold and "no" for non-bold or partially-bold text.
-// Then, queryCommandIndeterm should return "no" in the case where
-// all the text is either all bold or not-bold and and "yes" for partially-bold text.
-
-Frame::TriState stateNone(Frame*)
-{
-    return Frame::falseTriState;
-}
-
-Frame::TriState stateBold(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_FONT_WEIGHT, "bold");
-}
-
-Frame::TriState stateItalic(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_FONT_STYLE, "italic");
-}
-
-Frame::TriState stateUnorderedList(Frame* frame)
-{
-    return frame->editor()->selectionUnorderedListState();
-}
-
-Frame::TriState stateOrderedList(Frame* frame)
-{
-    return frame->editor()->selectionOrderedListState();
-}
-
-Frame::TriState stateStrikethrough(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_TEXT_DECORATION, "line-through");
-}
-
-Frame::TriState stateSubscript(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_VERTICAL_ALIGN, "sub");
-}
-
-Frame::TriState stateSuperscript(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_VERTICAL_ALIGN, "super");
-}
-
-Frame::TriState stateUnderline(Frame* frame)
-{
-    return stateStyle(frame, CSS_PROP_TEXT_DECORATION, "underline");
-}
-
-// =============================================================================================
-//
-// queryCommandValue implementations
-//
-
-String valueNull(Frame*)
-{
-    return String();
-}
-
-String valueBackColor(Frame* frame)
-{
-    return valueStyle(frame, CSS_PROP_BACKGROUND_COLOR);
-}
-
-String valueFontName(Frame* frame)
-{
-    return valueStyle(frame, CSS_PROP_FONT_FAMILY);
-}
-
-String valueFontSize(Frame* frame)
-{
-    return valueStyle(frame, CSS_PROP_FONT_SIZE);
-}
-
-String valueFontSizeDelta(Frame* frame)
-{
-    return valueStyle(frame, CSS_PROP__WEBKIT_FONT_SIZE_DELTA);
-}
-
-String valueForeColor(Frame* frame)
-{
-    return valueStyle(frame, CSS_PROP_COLOR);
-}
-
-// =============================================================================================
-
-CommandMap* createCommandDictionary()
-{
-    struct EditorCommand { const char* name; CommandImp imp; };
-
-    static const EditorCommand commands[] = {
-
-        { "BackColor", { execBackColor, enabledAnyRichlyEditableRangeSelection, stateNone, valueBackColor } },
-        { "Bold", { execBold, enabledAnyRichlyEditableSelection, stateBold, valueNull } },
-        { "Copy", { execCopy, enabledCopy, stateNone, valueNull } },
-        { "CreateLink", { execCreateLink, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "Cut", { execCut, enabledAnyEditableRangeSelection, stateNone, valueNull } },
-        { "Delete", { execDelete, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "FindString", { execFindString, enabled, stateNone, valueNull } },
-        { "FontName", { execFontName, enabledAnySelection, stateNone, valueFontName } },
-        { "FontSize", { execFontSize, enabledAnySelection, stateNone, valueFontSize } },
-        { "FontSizeDelta", { execFontSizeDelta, enabledAnySelection, stateNone, valueFontSizeDelta } },
-        { "ForeColor", { execForeColor, enabledAnySelection, stateNone, valueForeColor } },
-        { "FormatBlock", { execFormatBlock, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "ForwardDelete", { execForwardDelete, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "HiliteColor", { execBackColor, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "Indent", { execIndent, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "InsertHorizontalRule", { execInsertHorizontalRule, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "InsertHTML", { execInsertHTML, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "InsertImage", { execInsertImage, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "InsertLineBreak", { execInsertLineBreak, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "InsertOrderedList", { execInsertOrderedList, enabledAnyRichlyEditableSelection, stateOrderedList, valueNull } },
-        { "InsertParagraph", { execInsertParagraph, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "InsertNewlineInQuotedContent", { execInsertNewlineInQuotedContent, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "InsertText", { execInsertText, enabledAnyEditableSelection, stateNone, valueNull } },
-        { "InsertUnorderedList", { execInsertUnorderedList, enabledAnyRichlyEditableSelection, stateUnorderedList, valueNull } },
-        { "Italic", { execItalic, enabledAnyRichlyEditableSelection, stateItalic, valueNull } },
-        { "JustifyCenter", { execJustifyCenter, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "JustifyFull", { execJustifyFull, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "JustifyLeft", { execJustifyLeft, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "JustifyNone", { execJustifyLeft, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "JustifyRight", { execJustifyRight, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "Outdent", { execOutdent, enabledAnyRichlyEditableSelection, stateNone, valueNull } },
-        { "Paste", { execPaste, enabledPaste, stateNone, valueNull } },
-        { "PasteAndMatchStyle", { execPasteAndMatchStyle, enabledPaste, stateNone, valueNull } },
-        { "Print", { execPrint, enabled, stateNone, valueNull } },
-        { "Redo", { execRedo, enabledRedo, stateNone, valueNull } },
-        { "RemoveFormat", { execRemoveFormat, enabledAnyEditableRangeSelection, stateNone, valueNull } },
-        { "SelectAll", { execSelectAll, enabled, stateNone, valueNull } },
-        { "Strikethrough", { execStrikethrough, enabledAnyRichlyEditableSelection, stateStrikethrough, valueNull } },
-        { "Subscript", { execSubscript, enabledAnyRichlyEditableSelection, stateSubscript, valueNull } },
-        { "Superscript", { execSuperscript, enabledAnyRichlyEditableSelection, stateSuperscript, valueNull } },
-        { "Transpose", { execTranspose, enabledAnyCaret, stateNone, valueNull } },
-        { "Underline", { execUnderline, enabledAnyRichlyEditableSelection, stateUnderline, valueNull } },
-        { "Undo", { execUndo, enabledUndo, stateNone, valueNull } },
-        { "Unlink", { execUnlink, enabledAnyRichlyEditableRangeSelection, stateNone, valueNull } },
-        { "Unselect", { execUnselect, enabledAnySelection, stateNone, valueNull } }
-
-        //
-        // The "unsupported" commands are listed here since they appear in the Microsoft
-        // documentation used as the basis for the list.
-        //
-
-        // 2D-Position (not supported)
-        // AbsolutePosition (not supported)
-        // BlockDirLTR (not supported)
-        // BlockDirRTL (not supported)
-        // BrowseMode (not supported)
-        // ClearAuthenticationCache (not supported)
-        // CreateBookmark (not supported)
-        // DirLTR (not supported)
-        // DirRTL (not supported)
-        // EditMode (not supported)
-        // InlineDirLTR (not supported)
-        // InlineDirRTL (not supported)
-        // InsertButton (not supported)
-        // InsertFieldSet (not supported)
-        // InsertIFrame (not supported)
-        // InsertInputButton (not supported)
-        // InsertInputCheckbox (not supported)
-        // InsertInputFileUpload (not supported)
-        // InsertInputHidden (not supported)
-        // InsertInputImage (not supported)
-        // InsertInputPassword (not supported)
-        // InsertInputRadio (not supported)
-        // InsertInputReset (not supported)
-        // InsertInputSubmit (not supported)
-        // InsertInputText (not supported)
-        // InsertMarquee (not supported)
-        // InsertSelectDropDown (not supported)
-        // InsertSelectListBox (not supported)
-        // InsertTextArea (not supported)
-        // LiveResize (not supported)
-        // MultipleSelection (not supported)
-        // Open (not supported)
-        // Overwrite (not supported)
-        // PlayImage (not supported)
-        // Refresh (not supported)
-        // RemoveParaFormat (not supported)
-        // SaveAs (not supported)
-        // SizeToControl (not supported)
-        // SizeToControlHeight (not supported)
-        // SizeToControlWidth (not supported)
-        // Stop (not supported)
-        // StopImage (not supported)
-        // Unbookmark (not supported)
-    };
-
-    CommandMap* commandMap = new CommandMap;
-
-    const int numCommands = sizeof(commands) / sizeof(commands[0]);
-    for (int i = 0; i < numCommands; ++i) {
-        StringImpl *name = new StringImpl(commands[i].name);
-        name->ref();
-        commandMap->set(name, &commands[i].imp);
-    }
-    return commandMap;
-}
-
-} // anonymous namespace
-
-} // namespace WebCore
diff --git a/WebCore/editing/JSEditor.h b/WebCore/editing/JSEditor.h
deleted file mode 100644 (file)
index 369b4c3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 JSEditor_h
-#define JSEditor_h
-
-#include <wtf/Noncopyable.h>
-
-namespace WebCore {
-
-class Document;
-class String;
-
-class JSEditor : Noncopyable {
-public:
-    JSEditor(Document* document) : m_document(document) { }
-
-    bool execCommand(const String& command, bool userInterface, const String& parameter);
-    bool queryCommandEnabled(const String& command);
-    bool queryCommandIndeterm(const String& command);
-    bool queryCommandState(const String& command);
-    bool queryCommandSupported(const String& command);
-    String queryCommandValue(const String& command);
-
-private:
-    Document* m_document;
-};
-
-} // end namespace WebCore
-
-#endif
index 7bf06c3e7d388508603d47ed1d874b2e1ceeb1e4..f7ed539beaeb6a1d6aca6dd82ce744cfd2f27f9c 100644 (file)
 #import "config.h"
 #import "Editor.h"
 
-#import "ClipboardAccessPolicy.h"
-#import "Clipboard.h"
 #import "ClipboardMac.h"
-#import "Document.h"
 #import "EditorClient.h"
-#import "Element.h"
-#import "ExceptionHandlers.h"
-#import "Frame.h"
-#import "PlatformString.h"
-#import "Selection.h"
-#import "SelectionController.h"
-#import "Sound.h"
-#import "TypingCommand.h"
-#import "TextIterator.h"
-#import "htmlediting.h"
-#import "visible_units.h"
 
 namespace WebCore {
 
@@ -53,10 +39,8 @@ void _NSInitializeKillRing();
 void _NSAppendToKillRing(NSString *);
 void _NSPrependToKillRing(NSString *);
 NSString *_NSYankFromKillRing();
-NSString *_NSYankPreviousFromKillRing();
 void _NSNewKillRingSequence();
 void _NSSetKillRingToYankedState();
-void _NSResetKillRingOperationFlag();
 
 }
 
@@ -65,15 +49,6 @@ PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy)
     return new ClipboardMac(false, [NSPasteboard generalPasteboard], policy);
 }
 
-static void initializeKillRingIfNeeded()
-{
-    static bool initializedKillRing = false;
-    if (!initializedKillRing) {
-        initializedKillRing = true;
-        _NSInitializeKillRing();
-    }
-}
-
 NSString* Editor::userVisibleString(NSURL* nsURL)
 {
     if (client())
@@ -81,102 +56,43 @@ NSString* Editor::userVisibleString(NSURL* nsURL)
     return nil;
 }
 
-void Editor::addToKillRing(Range* range, bool prepend)
+static void initializeKillRingIfNeeded()
 {
-    initializeKillRingIfNeeded();
-
-    if (m_startNewKillRingSequence)
-        _NSNewKillRingSequence();
-
-    String text = plainText(range);
-    text.replace('\\', m_frame->backslashAsCurrencySymbol());
-    if (prepend)
-        _NSPrependToKillRing((NSString*)text);
-    else
-        _NSAppendToKillRing((NSString*)text);
-    m_startNewKillRingSequence = false;
+    static bool initializedKillRing = false;
+    if (!initializedKillRing) {
+        initializedKillRing = true;
+        _NSInitializeKillRing();
+    }
 }
 
-void Editor::yank()
+void Editor::appendToKillRing(const String& string)
 {
     initializeKillRingIfNeeded();
-
-    if (!canEdit())
-        return;
-
-    NSString* yankee = _NSYankFromKillRing();
-    insertTextWithoutSendingTextEvent(yankee, false);
-    _NSSetKillRingToYankedState();
+    _NSAppendToKillRing(string);
 }
 
-void Editor::yankAndSelect()
+void Editor::prependToKillRing(const String& string)
 {
     initializeKillRingIfNeeded();
-
-    if (!canEdit())
-        return;
-
-    NSString* yankee = _NSYankFromKillRing();
-    insertTextWithoutSendingTextEvent(yankee, true);
-    _NSSetKillRingToYankedState();
-}
-
-void Editor::setMark()
-{
-    m_frame->setMark(m_frame->selectionController()->selection());
-}
-
-static RefPtr<Range> unionDOMRanges(Range* a, Range* b)
-{
-    ExceptionCode ec = 0;
-    Range* start = a->compareBoundaryPoints(Range::START_TO_START, b, ec) <= 0 ? a : b;
-    ASSERT(!ec);
-    Range* end = a->compareBoundaryPoints(Range::END_TO_END, b, ec) <= 0 ? b : a;
-    ASSERT(!ec);
-
-    return new Range(a->startContainer(ec)->ownerDocument(), start->startContainer(ec), start->startOffset(ec), end->endContainer(ec), end->endOffset(ec));
+    _NSPrependToKillRing(string);
 }
 
-void Editor::deleteToMark()
+String Editor::yankFromKillRing()
 {
-    if (!canEdit())
-        return;
-
-    RefPtr<Range> mark = m_frame->mark().toRange();
-    if (mark) {
-        SelectionController* selectionController = m_frame->selectionController();
-        bool selected = selectionController->setSelectedRange(unionDOMRanges(mark.get(), selectedRange().get()).get(), DOWNSTREAM, true);
-        ASSERT(selected);
-        if (!selected)
-            return;
-    }
-
-    performDelete();
-    m_frame->setMark(m_frame->selectionController()->selection());
+    initializeKillRingIfNeeded();
+    return _NSYankFromKillRing();
 }
 
-void Editor::selectToMark()
+void Editor::startNewKillRingSequence()
 {
-    RefPtr<Range> mark = m_frame->mark().toRange();
-    RefPtr<Range> selection = selectedRange();
-    if (!mark || !selection) {
-        systemBeep();
-        return;
-    }
-    m_frame->selectionController()->setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, true);
+    initializeKillRingIfNeeded();
+    _NSNewKillRingSequence();
 }
 
-void Editor::swapWithMark()
+void Editor::setKillRingToYankedState()
 {
-    const Selection& mark = m_frame->mark();
-    Selection selection = m_frame->selectionController()->selection();
-    if (mark.isNone() || selection.isNone()) {
-        systemBeep();
-        return;
-    }
-
-    m_frame->selectionController()->setSelection(mark);
-    m_frame->setMark(selection);
+    initializeKillRingIfNeeded();
+    _NSSetKillRingToYankedState();
 }
 
 void Editor::showFontPanel()
index 0f8a0e831220db50544f67f3f083289b7abeab7d..69e88fa2ae8ff0e658efbc7a3daaa71978f36bb5 100644 (file)
@@ -1121,9 +1121,9 @@ void FrameLoader::setRestrictAccessToLocal(bool access)
     m_restrictAccessToLocal = access;
 }
 
-static HashSet<String, CaseInsensitiveHash<String> >& localSchemes()
+static HashSet<String, CaseFoldingHash>& localSchemes()
 {
-    static HashSet<String, CaseInsensitiveHash<String> > localSchemes;
+    static HashSet<String, CaseFoldingHash> localSchemes;
 
     if (localSchemes.isEmpty()) {
         localSchemes.add("file");
index a1ad7c71bb45fdd5d37c733e7e42274671da950b..71eb12e0f5ef84954f03d1afa87537716446c426 100644 (file)
@@ -879,58 +879,6 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
     d->m_typingStyle = mutableStyle.release();
 }
 
-static void updateState(CSSMutableStyleDeclaration *desiredStyle, CSSComputedStyleDeclaration *computedStyle, bool& atStart, Frame::TriState& state)
-{
-    DeprecatedValueListConstIterator<CSSProperty> end;
-    for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
-        int propertyID = (*it).id();
-        String desiredProperty = desiredStyle->getPropertyValue(propertyID);
-        String computedProperty = computedStyle->getPropertyValue(propertyID);
-        Frame::TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
-            ? Frame::trueTriState : Frame::falseTriState;
-        if (atStart) {
-            state = propertyState;
-            atStart = false;
-        } else if (state != propertyState) {
-            state = Frame::mixedTriState;
-            break;
-        }
-    }
-}
-
-Frame::TriState Frame::selectionHasStyle(CSSStyleDeclaration *style) const
-{
-    bool atStart = true;
-    TriState state = falseTriState;
-
-    RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
-
-    if (!selectionController()->isRange()) {
-        Node* nodeToRemove;
-        RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
-        if (!selectionStyle)
-            return falseTriState;
-        updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
-        if (nodeToRemove) {
-            ExceptionCode ec = 0;
-            nodeToRemove->remove(ec);
-            ASSERT(ec == 0);
-        }
-    } else {
-        for (Node* node = selectionController()->start().node(); node; node = node->traverseNextNode()) {
-            RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
-            if (computedStyle)
-                updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
-            if (state == mixedTriState)
-                break;
-            if (node == selectionController()->end().node())
-                break;
-        }
-    }
-
-    return state;
-}
-
 String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
 {
     Node *nodeToRemove;
index 71e091c43e6d6f09e36dcd8bd9deba26fed066f4..5697dd84b2bb5167aa28a8ab8ffe1f8b6b302f1b 100644 (file)
@@ -273,8 +273,6 @@ public:
     void setMark(const Selection&);
 
     void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
-    enum TriState { falseTriState, trueTriState, mixedTriState };
-    TriState selectionHasStyle(CSSStyleDeclaration*) const;
     String selectionStartStylePropertyValue(int stylePropertyID) const;
     void applyEditingStyleToBodyElement() const;
     void removeEditingStyleFromBodyElement() const;
index 9e528940af802f1312a698064351fd281536bb99..ba482746cc0677007b94cf42e2ff17321d1f64de 100644 (file)
@@ -212,7 +212,6 @@ enum WebScrollGranularity {
 
 - (DOMCSSStyleDeclaration *)typingStyle;
 - (void)setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebCore::EditAction)undoAction;
-- (NSCellStateValue)selectionHasStyle:(DOMCSSStyleDeclaration *)style;
 
 - (void)dragSourceMovedTo:(NSPoint)windowLoc;
 - (void)dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation;
index ff998fd9938abc24b59f85552856d19c0c6f1570..eae6e8074ddf15f0fe0cdced926c9da92533391e 100644 (file)
@@ -1161,21 +1161,6 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
     m_frame->computeAndSetTypingStyle([style _CSSStyleDeclaration], undoAction);
 }
 
-- (NSCellStateValue)selectionHasStyle:(DOMCSSStyleDeclaration *)style
-{
-    if (!m_frame)
-        return NSOffState;
-    switch (m_frame->selectionHasStyle([style _CSSStyleDeclaration])) {
-        case Frame::falseTriState:
-            return NSOffState;
-        case Frame::trueTriState:
-            return NSOnState;
-        case Frame::mixedTriState:
-            return NSMixedState;
-    }
-    return NSOffState;
-}
-
 - (NSFont *)fontForSelection:(BOOL *)hasMultipleFonts
 {
     bool multipleFonts = false;
index e514fbc3746b57d1a63fc8d24112354cd02778dc..d36a06554673bbf4cbb52cd7c08a9bd4341f7cb1 100644 (file)
@@ -406,11 +406,6 @@ void ContextMenu::addInspectElementItem()
     appendItem(InspectElementItem);
 }
 
-static bool triStateToBool(Frame::TriState state)
-{
-    return state == Frame::trueTriState;
-}
-
 void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
 {
     if (item.type() == SeparatorType)
@@ -437,7 +432,7 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
             RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
             String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
             style->setProperty(CSS_PROP_DIRECTION, direction, false, ec);
-            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
             shouldEnable = true;
             break;
         }
@@ -458,7 +453,7 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
             ExceptionCode ec = 0;
             RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
             style->setProperty(CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "underline", false, ec);
-            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
             shouldEnable = frame->editor()->canEditRichly();
             break;
         }
@@ -476,7 +471,7 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
             ExceptionCode ec = 0;
             RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
             style->setProperty(CSS_PROP_FONT_STYLE, "italic", false, ec);
-            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
             shouldEnable = frame->editor()->canEditRichly();
             break;
         }
@@ -484,7 +479,7 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
             ExceptionCode ec = 0;
             RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
             style->setProperty(CSS_PROP_FONT_WEIGHT, "bold", false, ec);
-            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
             shouldEnable = frame->editor()->canEditRichly();
             break;
         }
index 6b177ea871c7adafa89f814fea600fd356cebcf2..5a59e3ae16c90d6229251eaf6453a4ec7571ece7 100644 (file)
@@ -65,7 +65,7 @@ struct FontPlatformDataCacheKey {
 inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey)
 {
     unsigned hashCodes[3] = {
-        CaseInsensitiveHash<String>::hash(fontKey.m_family),
+        CaseFoldingHash::hash(fontKey.m_family),
         fontKey.m_size,
         static_cast<unsigned>(fontKey.m_bold) << 2 | static_cast<unsigned>(fontKey.m_italic) << 1 | static_cast<unsigned>(fontKey.m_printerFont)
     };
index 66ad62ddc2344c8638d349e1721bdd6e00f8871e..e740f2e6d528801a6adcb7af62a4c856fb7224cf 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-    typedef HashMap<String, String, CaseInsensitiveHash<String> > HTTPHeaderMap;
+    typedef HashMap<String, String, CaseFoldingHash> HTTPHeaderMap;
 
 } // namespace WebCore
 
index 4a9ac0de027a1c592569c2839916750262f4fd01..4109b43495dfa646a9ed3bd3e5002612b2244e66 100644 (file)
@@ -1,8 +1,6 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -45,7 +43,8 @@ class wxString;
 namespace WebCore {
 
 class CString;
-    
+struct StringHash;
+
 /**
  * Currently, strings are explicitly shared (they behave like pointers), meaning
  * that modifications to one instance will also modify all others. If you
@@ -242,11 +241,10 @@ inline NSString* nsStringNilIfEmpty(const String& str) {  return str.isEmpty() ?
 
 namespace WTF {
 
-    // StrHash is the default hash for String
+    // StringHash is the default hash for String
     template<typename T> struct DefaultHash;
-    template<typename T> struct StrHash;
     template<> struct DefaultHash<WebCore::String> {
-        typedef StrHash<WebCore::String> Hash;
+        typedef WebCore::StringHash Hash;
     };
 
 }
index 0783fc5842cda33be3727243c3ba6e7def525270..682db3338e05aabee49889d9d8771d57a6b05a5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #include <wtf/HashTraits.h>
 #include <wtf/unicode/Unicode.h>
 
-namespace WTF {
-
-    template<typename T> struct StrHash;
+namespace WebCore {
 
-    template<> struct StrHash<WebCore::StringImpl*> {
-        static unsigned hash(const WebCore::StringImpl* key) { return key->hash(); }
-        static bool equal(const WebCore::StringImpl* a, const WebCore::StringImpl* b)
+    struct StringHash {
+        static unsigned hash(const StringImpl* key) { return key->hash(); }
+        static bool equal(const StringImpl* a, const StringImpl* b)
         {
             if (a == b)
                 return true;
@@ -57,39 +55,30 @@ namespace WTF {
 
             return true;
         }
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
-    
-    template<> struct StrHash<WebCore::AtomicStringImpl*> : public StrHash<WebCore::StringImpl*> { };
 
-    template<> struct StrHash<RefPtr<WebCore::StringImpl> > {
-        static unsigned hash(const RefPtr<WebCore::StringImpl>& key) { return key->hash(); }
-        static bool equal(const RefPtr<WebCore::StringImpl>& a, const RefPtr<WebCore::StringImpl>& b)
+        static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); }
+        static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
         {
-            return StrHash<WebCore::StringImpl*>::equal(a.get(), b.get());
+            return equal(a.get(), b.get());
         }
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
 
-    template<> struct StrHash<WebCore::String> {
-        static unsigned hash(const WebCore::String& key) { return key.impl()->hash(); }
-        static bool equal(const WebCore::String& a, const WebCore::String& b)
+        static unsigned hash(const String& key) { return key.impl()->hash(); }
+        static bool equal(const String& a, const String& b)
         {
-            return StrHash<WebCore::StringImpl*>::equal(a.impl(), b.impl());
+            return equal(a.impl(), b.impl());
         }
+
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
-    template<typename T> struct CaseInsensitiveHash;
-
-    template<> class CaseInsensitiveHash<WebCore::StringImpl*> {
+    class CaseFoldingHash {
     private:
         // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
         static const unsigned PHI = 0x9e3779b9U;
     public:
         // Paul Hsieh's SuperFastHash
         // http://www.azillionmonkeys.com/qed/hash.html
-        static unsigned hash(const WebCore::StringImpl* str)
+        static unsigned hash(const StringImpl* str)
         {
             unsigned l = str->length();
             const UChar* s = str->characters();
@@ -177,7 +166,7 @@ namespace WTF {
             return hash;
         }
         
-        static bool equal(const WebCore::StringImpl* a, const WebCore::StringImpl* b)
+        static bool equal(const StringImpl* a, const StringImpl* b)
         {
             if (a == b)
                 return true;
@@ -189,38 +178,32 @@ namespace WTF {
             return WTF::Unicode::umemcasecmp(a->characters(), b->characters(), length) == 0;
         }
 
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
-
-    template<> struct CaseInsensitiveHash<WebCore::AtomicStringImpl*> : public CaseInsensitiveHash<WebCore::StringImpl*> { };
-
-    template<> struct CaseInsensitiveHash<RefPtr<WebCore::StringImpl> > {
-        static unsigned hash(const RefPtr<WebCore::StringImpl>& key) 
+        static unsigned hash(const RefPtr<StringImpl>& key) 
         {
-            return CaseInsensitiveHash<WebCore::StringImpl*>::hash(key.get());
+            return hash(key.get());
         }
 
-        static bool equal(const RefPtr<WebCore::StringImpl>& a, const RefPtr<WebCore::StringImpl>& b)
+        static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
         {
-            return CaseInsensitiveHash<WebCore::StringImpl*>::equal(a.get(), b.get());
+            return equal(a.get(), b.get());
         }
 
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
-
-    template<> struct CaseInsensitiveHash<WebCore::String> {
-        static unsigned hash(const WebCore::String& key)
+        static unsigned hash(const String& key)
         {
-            return CaseInsensitiveHash<WebCore::StringImpl*>::hash(key.impl());
+            return hash(key.impl());
         }
-        static bool equal(const WebCore::String& a, const WebCore::String& b)
+        static bool equal(const String& a, const String& b)
         {
-            return CaseInsensitiveHash<WebCore::StringImpl*>::equal(a.impl(), b.impl());
+            return equal(a.impl(), b.impl());
         }
 
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
+}
+
+namespace WTF {
+
     // store WebCore::String as StringImpl*
 
     template<> struct HashTraits<WebCore::String> : GenericHashTraits<WebCore::String> {
@@ -243,26 +226,24 @@ namespace WTF {
 
     // share code between StringImpl*, RefPtr<StringImpl>, and String
 
-    template<> struct HashKeyStorageTraits<StrHash<RefPtr<WebCore::StringImpl> >, HashTraits<RefPtr<WebCore::StringImpl> > > {
-        typedef StrHash<WebCore::StringImpl*> Hash;
+    template<> struct HashKeyStorageTraits<WebCore::StringHash, HashTraits<RefPtr<WebCore::StringImpl> > > {
+        typedef WebCore::StringHash Hash;
         typedef HashTraits<WebCore::StringImpl*> Traits;
     };
-    template<> struct HashKeyStorageTraits<StrHash<WebCore::String>, HashTraits<WebCore::String> > {
-        typedef StrHash<WebCore::StringImpl*> Hash;
+    template<> struct HashKeyStorageTraits<WebCore::StringHash, HashTraits<WebCore::String> > {
+        typedef WebCore::StringHash Hash;
         typedef HashTraits<WebCore::StringImpl*> Traits;
     };
 
-    template<> struct HashKeyStorageTraits<CaseInsensitiveHash<RefPtr<WebCore::StringImpl> >, HashTraits<RefPtr<WebCore::StringImpl> > > {
-        typedef CaseInsensitiveHash<WebCore::StringImpl*> Hash;
+    template<> struct HashKeyStorageTraits<WebCore::CaseFoldingHash, HashTraits<RefPtr<WebCore::StringImpl> > > {
+        typedef WebCore::CaseFoldingHash Hash;
         typedef HashTraits<WebCore::StringImpl*> Traits;
     };
-    template<> struct HashKeyStorageTraits<CaseInsensitiveHash<WebCore::String>, HashTraits<WebCore::String> > {
-        typedef CaseInsensitiveHash<WebCore::StringImpl*> Hash;
+    template<> struct HashKeyStorageTraits<WebCore::CaseFoldingHash, HashTraits<WebCore::String> > {
+        typedef WebCore::CaseFoldingHash Hash;
         typedef HashTraits<WebCore::StringImpl*> Traits;
     };
 
 }
 
-using WTF::CaseInsensitiveHash;
-
 #endif
index 4c9133ef4397078fad0c57b488605a475483ec94..997a3991aebec9f05fda85cd78fe1975540ecc3b 100644 (file)
@@ -1046,7 +1046,7 @@ StringImpl* StringImpl::replace(const StringImpl* pattern, const StringImpl* rep
 
 bool equal(const StringImpl* a, const StringImpl* b)
 {
-    return StrHash<StringImpl*>::equal(a, b);
+    return StringHash::equal(a, b);
 }
 
 bool equal(const StringImpl* a, const char* b)
@@ -1071,7 +1071,7 @@ bool equal(const StringImpl* a, const char* b)
 
 bool equalIgnoringCase(const StringImpl* a, const StringImpl* b)
 {
-    return CaseInsensitiveHash<StringImpl*>::equal(a, b);
+    return CaseFoldingHash::equal(a, b);
 }
 
 bool equalIgnoringCase(const StringImpl* a, const char* b)
index d7700121805bcb32840bd389f44345c0a85d7c4b..6a7688242a6f5b5de53713c5d0f82289a5660a0c 100644 (file)
@@ -1,8 +1,6 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -43,9 +41,10 @@ namespace WebCore {
 
 class AtomicString;
 class DeprecatedString;
-struct UCharBufferTranslator;
 struct CStringTranslator;
 struct Length;
+struct StringHash;
+struct UCharBufferTranslator;
 
 class StringImpl : public RefCounted<StringImpl> {
 private:
@@ -180,14 +179,13 @@ inline bool equalIgnoringCase(const char* a, const StringImpl* b) { return equal
 
 namespace WTF {
 
-    // StrHash is the default hash for StringImpl* and RefPtr<StringImpl>
+    // WebCore::StringHash is the default hash for StringImpl* and RefPtr<StringImpl>
     template<typename T> struct DefaultHash;
-    template<typename T> struct StrHash;
     template<> struct DefaultHash<WebCore::StringImpl*> {
-        typedef StrHash<WebCore::StringImpl*> Hash;
+        typedef WebCore::StringHash Hash;
     };
     template<> struct DefaultHash<RefPtr<WebCore::StringImpl> > {
-        typedef StrHash<RefPtr<WebCore::StringImpl> > Hash;
+        typedef WebCore::StringHash Hash;
     };
 
 }
index c8aaa3ed686565875e1cdb29d98f2e2b19331c9b..fe76af30e7ff4a78a008a2f22163cc3c0c524c8a 100644 (file)
@@ -150,7 +150,7 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
       if (serviceType.isEmpty())
           serviceType = o->m_serviceType;
       
-      HashSet<StringImpl*, CaseInsensitiveHash<StringImpl*> > uniqueParamNames;
+      HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
       
       // Scan the PARAM children.
       // Get the URL and type from the params if we don't already have them.
index d391749dbdd57b64bb4e8a4eed4c365551db4061..eef48665747f47d80ecc258644554b91e290604b 100644 (file)
@@ -33,7 +33,6 @@
 #include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "InlineTextBox.h"
-#include "JSEditor.h"
 #include "RenderBR.h"
 #include "RenderListMarker.h"
 #include "RenderTableCell.h"
index ef816d61a49fa79143312b1393736eda11198ce8..8737f5b8661a0b8b006cfcb8a7449ad97b1c0562 100644 (file)
@@ -91,7 +91,7 @@ static void removeFromRequestsByDocument(Document* doc, XMLHttpRequest* req)
 
 static bool canSetRequestHeader(const String& name)
 {
-    static HashSet<String, CaseInsensitiveHash<String> > forbiddenHeaders;
+    static HashSet<String, CaseFoldingHash> forbiddenHeaders;
     static String proxyString("proxy-");
     
     if (forbiddenHeaders.isEmpty()) {
index a678a112cadd5f421baec5f11793096b24ecd847..3a83d0cc60685dedfee11959f52e8462f76ba650 100644 (file)
@@ -1,3 +1,35 @@
+2007-12-11  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - change more editing commands to use WebCore::Editor
+        - change to use the new WebCore::Editor::command() function
+
+        * WebView/WebHTMLView.mm: Changed alignCenter, alignJustified, alignLeft,
+        alignRight, cut, copy, deleteToMark, indent, insertNewlineIgnoringFieldEditor,
+        insertTabIgnoringFieldEditor, outdent, selectAll, selectToMark, setMark,
+        subscript, superscript, swapWithMark, underline, unscript, yank, and yankAndSelect
+        to use the "forward to WebCore" macro instead of having hand-written implementations.
+        (kit): Added function to change a TriState to an AppKit-style tri-state value.
+        (-[WebHTMLView coreCommandBySelector:]): Added. No longer converts case of the
+        first character or copies the selector name, since the Editor commands are not case
+        sensitive any more. Returns a command object.
+        (-[WebHTMLView coreCommandByName:]): Added.
+        (-[WebHTMLView executeCoreCommandBySelector:]): Renamed from callWebCoreCommand:,
+        and changed to use the new coreCommandBySelector: method.
+        (-[WebHTMLView executeCoreCommandByName:]): Added.
+        (-[WebHTMLView validateUserInterfaceItemWithoutDelegate:]): Changed all the
+        methods that call through to WebCore to also use the state() and isEnabled()
+        functions on the commands for the menu item state and user interface item enabling.
+        (-[WebHTMLView _handleStyleKeyEquivalent:]): Use ToggleBold and ToggleItalic by
+        name rather than having local methods for them; no need for methods with a single
+        call site.
+        (-[WebHTMLView insertParagraphSeparator:]): Use executeCoreCommandByName: rather
+        than the deprecated execCommand().
+        (-[WebHTMLView doCommandBySelector:]): Changed to use command().execute() rather
+        than the deprecated execCommand().
+        * WebView/WebHTMLViewInternal.h: Removed some unneeded method declarations.
+
 2007-12-07  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index f173a21382d10d5538264c67e6e8c3c34bcbe4e9..8da8ae54bb541324042bdbbfdb6f3e05b7ff0ccf 100644 (file)
@@ -361,8 +361,21 @@ struct WebHTMLViewInterpretKeyEventsParameters {
     BOOL consumedByIM;
 };
 
-@implementation WebHTMLViewPrivate
+static NSCellStateValue kit(TriState state)
+{
+    switch (state) {
+        case FalseTriState:
+            return NSOffState;
+        case TrueTriState:
+            return NSOnState;
+        case MixedTriState:
+            return NSMixedState;
+    }
+    ASSERT_NOT_REACHED();
+    return NSOffState;
+}
 
+@implementation WebHTMLViewPrivate
 
 + (void)initialize
 {
@@ -2047,39 +2060,48 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     return [[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector];
 }
 
-static AtomicString selectorToCommandName(SEL selector)
+static String comandNameForSelector(SEL selector)
 {
-    // Capitalize the first letter of the selector, since we use capitalized command
-    // names in the Editor object (why?). And remove the trailing colon.
-    // And change a few command names into ones supported by WebCore::Editor.
-
+    // Change a few command names into ones supported by WebCore::Editor.
     if (selector == @selector(insertParagraphSeparator:) || selector == @selector(insertNewlineIgnoringFieldEditor:))
         return "InsertNewline";
     if (selector == @selector(insertTabIgnoringFieldEditor:))
         return "InsertTab";
 
+    // Remove the trailing colon.
     const char* selectorName = sel_getName(selector);
     size_t selectorNameLength = strlen(selectorName);
     ASSERT(selectorNameLength >= 2);
     ASSERT(selectorName[selectorNameLength - 1] == ':');
-    Vector<char, 256> commandName(selectorNameLength - 1 + 1);
-    commandName[0] = toASCIIUpper(selectorName[0]);
-    memcpy(&commandName[1], &selectorName[1], selectorNameLength - 2);
-    commandName[selectorNameLength - 1] = 0;
-
-    return AtomicString(commandName.data());
+    return String(selectorName, selectorNameLength - 1);
 }
 
-- (void)callWebCoreCommand:(SEL)selector
+- (Editor::Command)coreCommandBySelector:(SEL)selector
 {
-    if ([self callDelegateDoCommandBySelectorIfNeeded:selector])
-        return;
+    Frame* coreFrame = core([self _frame]);
+    if (!coreFrame)
+        return Editor::Command();
+    return coreFrame->editor()->command(comandNameForSelector(selector));
+}
 
+- (Editor::Command)coreCommandByName:(const char*)name
+{
     Frame* coreFrame = core([self _frame]);
     if (!coreFrame)
+        return Editor::Command();
+    return coreFrame->editor()->command(name);
+}
+
+- (void)executeCoreCommandBySelector:(SEL)selector
+{
+    if ([self callDelegateDoCommandBySelectorIfNeeded:selector])
         return;
+    [self coreCommandBySelector:selector].execute();
+}
 
-    coreFrame->editor()->execCommand(selectorToCommandName(selector));
+- (void)executeCoreCommandByName:(const char*)name
+{
+    [self coreCommandByName:name].execute();
 }
 
 // These commands are forwarded to the Editor object in WebCore.
@@ -2087,14 +2109,28 @@ static AtomicString selectorToCommandName(SEL selector)
 // should be moved from here to there, and more commands should be
 // added to this list.
 
-#define WEBCORE_COMMAND(command) - (void)command:(id)sender { [self callWebCoreCommand:_cmd]; }
+// FIXME: Maybe we should set things up so that all these share a single method implementation function.
+// The functions are identical.
 
+#define WEBCORE_COMMAND(command) - (void)command:(id)sender { [self executeCoreCommandBySelector:_cmd]; }
+
+WEBCORE_COMMAND(alignCenter)
+WEBCORE_COMMAND(alignJustified)
+WEBCORE_COMMAND(alignLeft)
+WEBCORE_COMMAND(alignRight)
+WEBCORE_COMMAND(cut)
+WEBCORE_COMMAND(copy)
+WEBCORE_COMMAND(deleteToMark)
 WEBCORE_COMMAND(deleteWordBackward)
 WEBCORE_COMMAND(deleteWordForward)
+WEBCORE_COMMAND(indent)
 WEBCORE_COMMAND(insertBacktab)
 WEBCORE_COMMAND(insertLineBreak)
 WEBCORE_COMMAND(insertNewline)
+WEBCORE_COMMAND(insertNewlineIgnoringFieldEditor)
+WEBCORE_COMMAND(insertParagraphSeparator)
 WEBCORE_COMMAND(insertTab)
+WEBCORE_COMMAND(insertTabIgnoringFieldEditor)
 WEBCORE_COMMAND(moveBackward)
 WEBCORE_COMMAND(moveBackwardAndModifySelection)
 WEBCORE_COMMAND(moveDown)
@@ -2133,7 +2169,18 @@ WEBCORE_COMMAND(moveWordLeft)
 WEBCORE_COMMAND(moveWordLeftAndModifySelection)
 WEBCORE_COMMAND(moveWordRight)
 WEBCORE_COMMAND(moveWordRightAndModifySelection)
+WEBCORE_COMMAND(outdent)
+WEBCORE_COMMAND(selectAll)
+WEBCORE_COMMAND(selectToMark)
+WEBCORE_COMMAND(setMark)
+WEBCORE_COMMAND(subscript)
+WEBCORE_COMMAND(superscript)
+WEBCORE_COMMAND(swapWithMark)
 WEBCORE_COMMAND(transpose)
+WEBCORE_COMMAND(underline)
+WEBCORE_COMMAND(unscript)
+WEBCORE_COMMAND(yank)
+WEBCORE_COMMAND(yankAndSelect)
 
 #undef WEBCORE_COMMAND
 
@@ -2180,13 +2227,6 @@ WEBCORE_COMMAND(transpose)
     return [[self nextResponder] validRequestorForSendType:sendType returnType:returnType];
 }
 
-- (void)selectAll:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    [self selectAll];
-}
-
 // jumpToSelection is the old name for what AppKit now calls centerSelectionInVisibleArea. Safari
 // was using the old jumpToSelection selector in its menu. Newer versions of Safari will us the
 // selector centerSelectionInVisibleArea. We'll leave this old selector in place for two reasons:
@@ -2200,6 +2240,14 @@ WEBCORE_COMMAND(transpose)
         coreFrame->revealSelection(RenderLayer::gAlignCenterAlways);
 }
 
+- (NSCellStateValue)selectionHasStyle:(CSSStyleDeclaration*)style
+{
+    Frame* coreFrame = core([self _frame]);
+    if (!coreFrame)
+        return NSOffState;
+    return kit(coreFrame->editor()->selectionHasStyle(style));
+}
+
 - (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item
 {
     SEL action = [item action];
@@ -2219,21 +2267,17 @@ WEBCORE_COMMAND(transpose)
             return NO;
         }
     }
-    
-    if (action == @selector(changeSpelling:)
-            || action == @selector(_changeSpellingFromMenu:)
-            || action == @selector(checkSpelling:)
-            || action == @selector(complete:)
-            || action == @selector(deleteBackward:)
-            || action == @selector(deleteBackwardByDecomposingPreviousCharacter:)
-            || action == @selector(deleteForward:)
-            || action == @selector(deleteToBeginningOfLine:)
-            || action == @selector(deleteToBeginningOfParagraph:)
-            || action == @selector(deleteToEndOfLine:)
-            || action == @selector(deleteToEndOfParagraph:)
+
+    if (action == @selector(alignCenter:)
+            || action == @selector(alignJustified:)
+            || action == @selector(alignLeft:)
+            || action == @selector(alignRight:)
+            || action == @selector(cut:)
+            || action == @selector(copy:)
             || action == @selector(deleteToMark:)
             || action == @selector(deleteWordBackward:)
             || action == @selector(deleteWordForward:)
+            || action == @selector(indent:)
             || action == @selector(insertBacktab:)
             || action == @selector(insertLineBreak:)
             || action == @selector(insertNewline:)
@@ -2255,20 +2299,20 @@ WEBCORE_COMMAND(transpose)
             || action == @selector(moveRightAndModifySelection:)
             || action == @selector(moveToBeginningOfDocument:)
             || action == @selector(moveToBeginningOfDocumentAndModifySelection:)
-            || action == @selector(moveToBeginningOfSentence:)
-            || action == @selector(moveToBeginningOfSentenceAndModifySelection:)
             || action == @selector(moveToBeginningOfLine:)
             || action == @selector(moveToBeginningOfLineAndModifySelection:)
             || action == @selector(moveToBeginningOfParagraph:)
             || action == @selector(moveToBeginningOfParagraphAndModifySelection:)
+            || action == @selector(moveToBeginningOfSentence:)
+            || action == @selector(moveToBeginningOfSentenceAndModifySelection:)
             || action == @selector(moveToEndOfDocument:)
             || action == @selector(moveToEndOfDocumentAndModifySelection:)
-            || action == @selector(moveToEndOfSentence:)
-            || action == @selector(moveToEndOfSentenceAndModifySelection:)
             || action == @selector(moveToEndOfLine:)
             || action == @selector(moveToEndOfLineAndModifySelection:)
             || action == @selector(moveToEndOfParagraph:)
             || action == @selector(moveToEndOfParagraphAndModifySelection:)
+            || action == @selector(moveToEndOfSentence:)
+            || action == @selector(moveToEndOfSentenceAndModifySelection:)
             || action == @selector(moveUp:)
             || action == @selector(moveUpAndModifySelection:)
             || action == @selector(moveWordBackward:)
@@ -2279,14 +2323,41 @@ WEBCORE_COMMAND(transpose)
             || action == @selector(moveWordLeftAndModifySelection:)
             || action == @selector(moveWordRight:)
             || action == @selector(moveWordRightAndModifySelection:)
+            || action == @selector(outdent:)
+            || action == @selector(selectAll:)
+            || action == @selector(selectToMark:)
+            || action == @selector(setMark:)
+            || action == @selector(subscript:)
+            || action == @selector(superscript:)
+            || action == @selector(swapWithMark:)
+            || action == @selector(transpose:)
+            || action == @selector(underline:)
+            || action == @selector(unscript:)
+            || action == @selector(yank:)
+            || action == @selector(yankAndSelect:)) {
+        Editor::Command command = [self coreCommandBySelector:action];
+        NSMenuItem *menuItem = (NSMenuItem *)item;
+        if ([menuItem isKindOfClass:[NSMenuItem class]])
+            [menuItem setState:kit(command.state())];
+        return command.isEnabled();
+    }
+
+    if (action == @selector(changeSpelling:)
+            || action == @selector(_changeSpellingFromMenu:)
+            || action == @selector(checkSpelling:)
+            || action == @selector(complete:)
+            || action == @selector(deleteBackward:)
+            || action == @selector(deleteBackwardByDecomposingPreviousCharacter:)
+            || action == @selector(deleteForward:)
+            || action == @selector(deleteToBeginningOfLine:)
+            || action == @selector(deleteToBeginningOfParagraph:)
+            || action == @selector(deleteToEndOfLine:)
+            || action == @selector(deleteToEndOfParagraph:)
             || action == @selector(pageDown:)
             || action == @selector(pageDownAndModifySelection:)
             || action == @selector(pageUp:)
             || action == @selector(pageUpAndModifySelection:)
-            || action == @selector(pasteFont:)
-            || action == @selector(transpose:)
-            || action == @selector(yank:)
-            || action == @selector(yankAndSelect:))
+            || action == @selector(pasteFont:))
         return [self _canEdit];
     
     if (action == @selector(showGuessPanel:)) {
@@ -2306,12 +2377,13 @@ WEBCORE_COMMAND(transpose)
         if ([menuItem isKindOfClass:[NSMenuItem class]]) {
             NSWritingDirection writingDirection = static_cast<NSWritingDirection>([item tag]);
             if (writingDirection == NSWritingDirectionNatural) {
-                [menuItem setState:NO];
+                [menuItem setState:NSOffState];
                 return NO;
             }
-            DOMCSSStyleDeclaration* style = [self _emptyStyle];
-            [style setDirection:writingDirection == NSWritingDirectionLeftToRight ? @"LTR" : @"RTL"];
-            [menuItem setState:[[self _bridge] selectionHasStyle:style]];
+            RefPtr<CSSStyleDeclaration> style = new CSSMutableStyleDeclaration;
+            ExceptionCode ec;
+            style->setProperty("direction", writingDirection == NSWritingDirectionLeftToRight ? "LTR" : "RTL", ec);
+            [menuItem setState:frame->editor()->selectionHasStyle(style.get())];
         }
         return [self _canEdit];
     }
@@ -2319,24 +2391,21 @@ WEBCORE_COMMAND(transpose)
     if (action == @selector(toggleBaseWritingDirection:)) {
         NSMenuItem *menuItem = (NSMenuItem *)item;
         if ([menuItem isKindOfClass:[NSMenuItem class]]) {
-            DOMCSSStyleDeclaration* rtl = [self _emptyStyle];
-            [rtl setDirection:@"RTL"];
+            RefPtr<CSSStyleDeclaration> style = new CSSMutableStyleDeclaration;
+            ExceptionCode ec;
+            style->setProperty("direction", "RTL", ec);
             // Take control of the title of the menu item, instead of just checking/unchecking it because otherwise
             // we don't know what the check would mean.
-            [menuItem setTitle:[[self _bridge] selectionHasStyle:rtl] ? UI_STRING("Left to Right", "Left to Right context menu item") : UI_STRING("Right to Left", "Right to Left context menu item")];
+            [menuItem setTitle:frame->editor()->selectionHasStyle(style.get())
+                ? UI_STRING("Left to Right", "Left to Right context menu item")
+                : UI_STRING("Right to Left", "Right to Left context menu item")];
         }
         return [self _canEdit];
     } 
     
-    if (action == @selector(alignCenter:)
-            || action == @selector(alignLeft:)
-            || action == @selector(alignJustified:)
-            || action == @selector(alignRight:)
-            || action == @selector(changeAttributes:)
+    if (action == @selector(changeAttributes:)
             || action == @selector(changeColor:)        
-            || action == @selector(changeFont:)
-            || action == @selector(indent:)
-            || action == @selector(outdent:))
+            || action == @selector(changeFont:))
         return [self _canEditRichly];
     
     if (action == @selector(capitalizeWord:)
@@ -2346,19 +2415,12 @@ WEBCORE_COMMAND(transpose)
     
     if (action == @selector(centerSelectionInVisibleArea:)
                || action == @selector(jumpToSelection:)
-               || action == @selector(copyFont:)
-               || action == @selector(setMark:))
+               || action == @selector(copyFont:))
         return [self _hasSelection] || ([self _isEditable] && [self _hasInsertionPoint]);
     
     if (action == @selector(changeDocumentBackgroundColor:))
         return [[self _webView] isEditable] && [self _canEditRichly];
     
-    if (action == @selector(copy:))
-        return frame && (frame->editor()->canDHTMLCopy() || frame->editor()->canCopy());
-    
-    if (action == @selector(cut:))
-        return frame && (frame->editor()->canDHTMLCut() || frame->editor()->canCut());
-    
     if (action == @selector(delete:))
         return frame && frame->editor()->canDelete();
     
@@ -2378,50 +2440,6 @@ WEBCORE_COMMAND(transpose)
         // FIXME: Not yet implemented.
         return NO;
     
-    if (action == @selector(selectToMark:)
-            || action == @selector(swapWithMark:))
-        return [self _hasSelectionOrInsertionPoint] && [[self _bridge] markDOMRange] != nil;
-    
-    if (action == @selector(subscript:)) {
-        NSMenuItem *menuItem = (NSMenuItem *)item;
-        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
-            DOMCSSStyleDeclaration *style = [self _emptyStyle];
-            [style setVerticalAlign:@"sub"];
-            [menuItem setState:[[self _bridge] selectionHasStyle:style]];
-        }
-        return [self _canEditRichly];
-    } 
-    
-    if (action == @selector(superscript:)) {
-        NSMenuItem *menuItem = (NSMenuItem *)item;
-        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
-            DOMCSSStyleDeclaration *style = [self _emptyStyle];
-            [style setVerticalAlign:@"super"];
-            [menuItem setState:[[self _bridge] selectionHasStyle:style]];
-        }
-        return [self _canEditRichly];
-    } 
-    
-    if (action == @selector(underline:)) {
-        NSMenuItem *menuItem = (NSMenuItem *)item;
-        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
-            DOMCSSStyleDeclaration *style = [self _emptyStyle];
-            [style setProperty:@"-khtml-text-decorations-in-effect" value:@"underline" priority:@""];
-            [menuItem setState:[[self _bridge] selectionHasStyle:style]];
-        }
-        return [self _canEditRichly];
-    } 
-    
-    if (action == @selector(unscript:)) {
-        NSMenuItem *menuItem = (NSMenuItem *)item;
-        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
-            DOMCSSStyleDeclaration *style = [self _emptyStyle];
-            [style setVerticalAlign:@"baseline"];
-            [menuItem setState:[[self _bridge] selectionHasStyle:style]];
-        }
-        return [self _canEditRichly];
-    } 
-    
     if (action == @selector(_lookUpInDictionaryFromMenu:)) {
         return [self _hasSelection];
     } 
@@ -3898,18 +3916,6 @@ noPromisedData:
         coreFrame->editor()->applyParagraphStyleToSelection(core(style), undoAction);
 }
 
-- (void)_toggleBold
-{
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->execCommand("ToggleBold");
-}
-
-- (void)_toggleItalic
-{
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->execCommand("ToggleItalic");
-}
-
 - (BOOL)_handleStyleKeyEquivalent:(NSEvent *)event
 {
     ASSERT([self _webView]);
@@ -3924,11 +3930,11 @@ noPromisedData:
     
     NSString *string = [event characters];
     if ([string caseInsensitiveCompare:@"b"] == NSOrderedSame) {
-        [self _toggleBold];
+        [self executeCoreCommandByName:"ToggleBold"];
         return YES;
     }
     if ([string caseInsensitiveCompare:@"i"] == NSOrderedSame) {
-        [self _toggleItalic];
+        [self executeCoreCommandByName:"ToggleItalic"];
         return YES;
     }
     
@@ -4260,52 +4266,6 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
                   withUndoAction:EditActionSetColor];
 }
 
-- (void)_alignSelectionUsingCSSValue:(NSString *)CSSAlignmentValue withUndoAction:(EditAction)undoAction
-{
-    if (![self _canEditRichly])
-        return;
-        
-    DOMCSSStyleDeclaration *style = [self _emptyStyle];
-    [style setTextAlign:CSSAlignmentValue];
-    [self _applyStyleToSelection:style withUndoAction:undoAction];
-}
-
-- (void)alignCenter:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    [self _alignSelectionUsingCSSValue:@"center" withUndoAction:EditActionCenter];
-}
-
-- (void)alignJustified:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    [self _alignSelectionUsingCSSValue:@"justify" withUndoAction:EditActionJustify];
-}
-
-- (void)alignLeft:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    [self _alignSelectionUsingCSSValue:@"left" withUndoAction:EditActionAlignLeft];
-}
-
-- (void)alignRight:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    [self _alignSelectionUsingCSSValue:@"right" withUndoAction:EditActionAlignRight];
-}
-
-- (void)insertParagraphSeparator:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->execCommand("InsertNewline");
-}
-
 - (void)_changeWordCaseWithSelector:(SEL)selector
 {
     if (![self _canEdit])
@@ -4534,113 +4494,6 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
     [NSApp stopSpeaking:sender];
 }
 
-- (void)insertNewlineIgnoringFieldEditor:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->execCommand("InsertNewline");
-}
-
-- (void)insertTabIgnoringFieldEditor:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->execCommand("InsertTab");
-}
-
-- (void)subscript:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    DOMCSSStyleDeclaration *style = [self _emptyStyle];
-    [style setVerticalAlign:@"sub"];
-    [self _applyStyleToSelection:style withUndoAction:EditActionSubscript];
-}
-
-- (void)superscript:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    DOMCSSStyleDeclaration *style = [self _emptyStyle];
-    [style setVerticalAlign:@"super"];
-    [self _applyStyleToSelection:style withUndoAction:EditActionSuperscript];
-}
-
-- (void)unscript:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    DOMCSSStyleDeclaration *style = [self _emptyStyle];
-    [style setVerticalAlign:@"baseline"];
-    [self _applyStyleToSelection:style withUndoAction:EditActionUnscript];
-}
-
-- (void)underline:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    Frame* coreFrame = core([self _frame]);
-    if (!coreFrame)
-        return;
-    // Despite the name, this method is actually supposed to toggle underline.
-    // FIXME: This currently clears overline, line-through, and blink as an unwanted side effect.
-    DOMCSSStyleDeclaration *style = [self _emptyStyle];
-    [style setProperty:@"-khtml-text-decorations-in-effect" value:@"underline" priority:@""];
-    if (coreFrame->editor()->selectionStartHasStyle(core(style)))
-        [style setProperty:@"-khtml-text-decorations-in-effect" value:@"none" priority:@""];
-    [self _applyStyleToSelection:style withUndoAction:EditActionUnderline];
-}
-
-- (void)yank:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->yank();
-}
-
-- (void)yankAndSelect:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->yankAndSelect();
-}
-
-- (void)setMark:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->setMark();
-}
-
-- (void)deleteToMark:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->deleteToMark();
-}
-
-- (void)selectToMark:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->selectToMark();
-}
-
-- (void)swapWithMark:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->swapWithMark();
-}
-
 - (void)toggleBaseWritingDirection:(id)sender
 {
     COMMAND_PROLOGUE
@@ -4685,22 +4538,6 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
     [self _applyParagraphStyleToSelection:style withUndoAction:EditActionSetWritingDirection];
 }
 
-- (void)indent:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->indent();
-}
-
-- (void)outdent:(id)sender
-{
-    COMMAND_PROLOGUE
-    
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->outdent();
-}
-
 #if 0
 
 // CSS does not have a way to specify an outline font, which may make this difficult to implement.
@@ -5014,22 +4851,6 @@ NSStrokeColorAttributeName        /* NSColor, default nil: same as foreground co
     return [_private->dataSource webFrame];
 }
 
-- (void)copy:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->copy();
-}
-
-- (void)cut:(id)sender
-{
-    COMMAND_PROLOGUE
-
-    if (Frame* coreFrame = core([self _frame]))
-        coreFrame->editor()->cut();
-}
-
 - (void)paste:(id)sender
 {
     COMMAND_PROLOGUE
@@ -5226,7 +5047,7 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
             // (e.g. Tab that inserts a Tab character, or Enter).
             bool haveTextInsertionCommands = false;
             for (size_t i = 0; i < size; ++i) {
-                if (Editor::isTextInsertionCommand(selectorToCommandName(NSSelectorFromString(command.commandNames[i]))))
+                if ([self coreCommandBySelector:NSSelectorFromString(command.commandNames[i])].isTextInsertion())
                     haveTextInsertionCommands = true;
             }
             if (!haveTextInsertionCommands)
@@ -5569,9 +5390,9 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
         WebView *webView = [self _webView];
         Frame* coreFrame = core([self _frame]);
         if (![[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector] && coreFrame) {
-            AtomicString commandName = selectorToCommandName(selector);
-            if (Editor::isTextInsertionCommand(commandName))
-                eventWasHandled = coreFrame->editor()->execCommand(commandName, event);
+            Editor::Command command = [self coreCommandBySelector:selector];
+            if (command.isTextInsertion())
+                eventWasHandled = command.execute(event);
             else {
                 _private->selectorForDoCommandBySelector = selector;
                 [super doCommandBySelector:selector];
index 443e4b76026568bff6e17905725c94183779c2d8..3ca5839bba2c266c3266338a9e97472ae22fdd6c 100644 (file)
@@ -116,10 +116,7 @@ struct WebHTMLViewInterpretKeyEventsParameters;
 - (void)_willMakeFirstResponderForNodeFocus;
 - (id<WebHTMLHighlighter>)_highlighterForType:(NSString*)type;
 - (WebFrame *)_frame;
-- (void)copy:(id)sender;
-- (void)cut:(id)sender;
 - (void)paste:(id)sender;
-- (void)pasteAsPlainText:(id)sender;
 - (void)closeIfNotCurrentView;
 - (void)_lookUpInDictionaryFromMenu:(id)sender;
 - (void)_hoverFeedbackSuspendedChanged;
index 377d1fbc1ae123c422066dbe361f1ba5d8b1e1de..a79055c56b6da7735462e5b5f49bf815628e5b1f 100644 (file)
@@ -1,3 +1,8 @@
+2007-12-11  Darin Adler  <darin@apple.com>
+
+        * WebView.cpp:
+        (WebView::handleEditingKeyboardEvent): Update for change to Editor API.
+
 2007-12-07  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index 51d728ca6c377a9a33a1dd6d019daa3d1b98aa80..150fbfe82a02218e6454cb0a64bb8353b2c45363 100644 (file)
@@ -1369,22 +1369,17 @@ bool WebView::handleEditingKeyboardEvent(KeyboardEvent* evt)
     if (!keyEvent || keyEvent->isSystemKey())  // do not treat this as text input if it's a system key event
         return false;
 
-    if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
-        String command = interpretKeyEvent(evt);
+    Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
 
+    if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
         // (e.g. Tab that inserts a Tab character, or Enter).
-        if (!command.isEmpty() && !Editor::isTextInsertionCommand(command))
-            if (frame->editor()->execCommand(command, evt))
-                return true;
-        return false;
+        return !command.isTextInsertion() && command.execute(evt);
     }
 
-    String command = interpretKeyEvent(evt);
-     if (!command.isEmpty())
-        if (frame->editor()->execCommand(command, evt))
-            return true;
+     if (command.execute(evt))
+        return true;
 
     // Don't insert null or control characters as they can result in unexpected behaviour
     if (evt->charCode() < ' ')