WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Added two functions to DocumentMarkerController.
bug-83549-20120414091552.patch (text/plain), 79.96 KB, created by
Jia Pu
on 2012-04-14 09:15:55 PDT
(
hide
)
Description:
Added two functions to DocumentMarkerController.
Filename:
MIME Type:
Creator:
Jia Pu
Created:
2012-04-14 09:15:55 PDT
Size:
79.96 KB
patch
obsolete
>Subversion Revision: 114204 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 05093da4e626107ba387bb0963709907b17f3f78..1bf1b115e378f43c62f549bf1f1ed7490fa1e0dc 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,151 @@ >+2012-04-14 Jia Pu <jpu@apple.com> >+ >+ Introducing DictationCommand. >+ https://bugs.webkit.org/show_bug.cgi?id=83549 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ No new tests. This patch doesn't introduce any change of new functionality. It prepares for >+ additional changes which will inlude tests. >+ >+ On OS X, alternative dictation results need to be stored as document markers. This patch introduces >+ following changes to achieve this: >+ 1. Added DictationMarkDetails to store non-string type maker detail. >+ 2. Introduce DictationCommand, which is similor to TypingCommand, but allows inserting text with >+ attached markers. >+ 3. Added Editor::insertDictatedText as interaface to WebKit and WebKit2. >+ 4. Added struct DictationAlternative to pass dictation related info from WebKit to WebCore. >+ >+ Several fragments of code in TypingCommand can be also used by DictationCommand. So this patch >+ introduced a new class, TextInsertionBaseCommand. It's a subclass of CompositeEditCommmand, and >+ base class of both TypingCommand and DictationCommand. >+ >+ This patch also extends InsertTextCommand class. Its constructor will take an TextInsertionMarkerSupplier >+ object. After text is inserted to a node, InsertTextCommand would give marker supplier a chance to >+ add document markers to the inserted text. >+ >+ * CMakeLists.txt: >+ * GNUmakefile.list.am: >+ * Target.pri: >+ * WebCore.exp.in: >+ * WebCore.gypi: >+ * WebCore.vcproj/WebCore.vcproj: >+ * WebCore.xcodeproj/project.pbxproj: >+ * dom/Document.cpp: >+ (WebCore::eventTargetNodeForDocument): Moved this function from EventHandler so that it can be used >+ by AlternativeTextController. >+ (WebCore): >+ * dom/Document.h: >+ (WebCore): >+ * dom/DocumentMarker.cpp: >+ (WebCore::DocumentMarker::DocumentMarker): New constructor that takes a pointer to DocumentMarkerDetails object. >+ (WebCore): >+ * dom/DocumentMarker.h: >+ (WebCore::DocumentMarker::AllMarkers::AllMarkers): >+ (DocumentMarker): >+ * dom/DocumentMarkerController.cpp: >+ (WebCore::DocumentMarkerController::addMarker): >+ (WebCore): >+ * dom/DocumentMarkerController.h: >+ (DocumentMarkerController): >+ * dom/TextEvent.cpp: >+ (WebCore::TextEvent::createForDictation): >+ (WebCore): >+ (WebCore::TextEvent::TextEvent): >+ * dom/TextEvent.h: Added member variable for dictation alternatives. >+ (TextEvent): >+ (WebCore::TextEvent::isDictation): >+ (WebCore::TextEvent::dictationAlternatives): >+ * dom/TextEventInputType.h: >+ * editing/AlternativeTextController.cpp: >+ (WebCore::AlternativeTextController::AlternativeTextController): >+ (WebCore::AlternativeTextController::insertDictatedText): Used by Editor::insertDictatedText(). >+ (WebCore): >+ * editing/AlternativeTextController.h: >+ (WebCore): >+ (DictationMarkerDetails): >+ (WebCore::DictationMarkerDetails::create): >+ (WebCore::DictationMarkerDetails::originalText): >+ (WebCore::DictationMarkerDetails::dictationContext): >+ (WebCore::DictationMarkerDetails::DictationMarkerDetails): >+ (AlternativeTextController): >+ * editing/CompositeEditCommand.h: >+ (WebCore::CompositeEditCommand::isDictationCommand): >+ * editing/DictationAlternative.cpp: Added. >+ (WebCore): >+ (WebCore::DictationAlternative::DictationAlternative): >+ * editing/DictationAlternative.h: Added. Data structure for passing dictation related data from WebKit to WebCore. >+ (DictationAlternative): >+ (WebCore): >+ * editing/DictationCommand.cpp: Added. >+ (WebCore): >+ (DictationCommandLineOperation): >+ (WebCore::DictationCommandLineOperation::DictationCommandLineOperation): >+ (WebCore::DictationCommandLineOperation::operator()): >+ (DictationMarkerSupplier): >+ (WebCore::DictationMarkerSupplier::create): >+ (WebCore::DictationMarkerSupplier::addMarkersToTextNode): >+ (WebCore::DictationMarkerSupplier::DictationMarkerSupplier): >+ (WebCore::DictationCommand::DictationCommand): >+ (WebCore::DictationCommand::insertText): >+ (WebCore::DictationCommand::doApply): >+ (WebCore::DictationCommand::insertTextRunWithoutNewlines): >+ (WebCore::DictationCommand::insertParagraphSeparator): >+ (WebCore::DictationCommand::collectDictationAlternativesInRange): >+ * editing/DictationCommand.h: Added. >+ (WebCore): >+ (DictationCommand): >+ (WebCore::DictationCommand::isDictationCommand): >+ (WebCore::DictationCommand::create): >+ * editing/EditingAllInOne.cpp: >+ * editing/Editor.cpp: >+ (WebCore::Editor::insertDictatedText): Main interface that allows WebKit passes in text with attached dictation information. >+ (WebCore): >+ (WebCore::Editor::insertTextWithoutSendingTextEvent): >+ (WebCore::Editor::updateMarkersForWordsAffectedByEditing): >+ * editing/Editor.h: >+ (Editor): >+ * editing/InsertTextCommand.cpp: >+ (WebCore::InsertTextCommand::InsertTextCommand): >+ (WebCore): >+ (WebCore::InsertTextCommand::doApply): >+ * editing/InsertTextCommand.h: >+ (WebCore): >+ (TextInsertionMarkerSupplier): Interface to allow caller of InsertTextCommand to add document markers to inserted text. >+ (WebCore::TextInsertionMarkerSupplier::~TextInsertionMarkerSupplier): >+ (WebCore::TextInsertionMarkerSupplier::TextInsertionMarkerSupplier): >+ (WebCore::InsertTextCommand::createWithMarkerSupplier): >+ (InsertTextCommand): >+ * editing/TextInsertionBaseCommand.cpp: Added. This class contains functions shared by TypingCommand and DictationCommand. >+ (WebCore): >+ (WebCore::TextInsertionBaseCommand::TextInsertionBaseCommand): >+ (WebCore::TextInsertionBaseCommand::applyTextInsertionCommand): >+ (WebCore::dispatchBeforeTextInsertedEvent): >+ (WebCore::canAppendNewLineFeedToSelection): >+ * editing/TextInsertionBaseCommand.h: Added. >+ (WebCore): >+ (TextInsertionBaseCommand): >+ (WebCore::TextInsertionBaseCommand::~TextInsertionBaseCommand): >+ (WebCore::forEachLineInString): >+ * editing/TypingCommand.cpp: >+ (TypingCommandLineOperation): >+ (WebCore::TypingCommandLineOperation::TypingCommandLineOperation): >+ (WebCore::TypingCommandLineOperation::operator()): >+ (WebCore::TypingCommand::TypingCommand): >+ (WebCore::TypingCommand::insertText): >+ (WebCore::TypingCommand::insertLineBreak): >+ (WebCore::TypingCommand::insertParagraphSeparator): >+ * editing/TypingCommand.h: >+ * page/EventHandler.cpp: >+ * rendering/InlineTextBox.cpp: >+ (WebCore::lineStyleForMarkerType): >+ (WebCore::InlineTextBox::paintDocumentMarker): Renamed existing function to reflect new funcationality. >+ (WebCore::InlineTextBox::paintDocumentMarkers): >+ * rendering/InlineTextBox.h: >+ (InlineTextBox): >+ * testing/Internals.cpp: >+ (WebCore::markerTypesFrom): >+ > 2012-04-14 Noel Gordon <noel.gordon@gmail.com> > > [Cairo] ImageBuffer::toDataURL(): improve error handling, add mimeType ASSERTs >diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt >index 8c6bdf0534f98ab1fded5c1dc720ce5b42f05054..977518c60d545dd0b463a39874b4d13978a5df0e 100644 >--- a/Source/WebCore/CMakeLists.txt >+++ b/Source/WebCore/CMakeLists.txt >@@ -662,6 +662,8 @@ SET(WebCore_SOURCES > editing/DeleteButtonController.cpp > editing/DeleteFromTextNodeCommand.cpp > editing/DeleteSelectionCommand.cpp >+ editing/DictationAlternative.cpp >+ editing/DictationCommand.cpp > editing/EditCommand.cpp > editing/EditingStyle.cpp > editing/Editor.cpp >@@ -697,6 +699,7 @@ SET(WebCore_SOURCES > editing/SplitTextNodeCommand.cpp > editing/SplitTextNodeContainingElementCommand.cpp > editing/TextCheckingHelper.cpp >+ editing/TextInsertionBaseCommand.cpp > editing/TextIterator.cpp > editing/TypingCommand.cpp > editing/UnlinkCommand.cpp >diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am >index ab0bdd0b862371cbd158467a1a9bebc815bb53f7..574bb0466fdb830e2a408ccba4515f731974487d 100644 >--- a/Source/WebCore/GNUmakefile.list.am >+++ b/Source/WebCore/GNUmakefile.list.am >@@ -2024,6 +2024,10 @@ webcore_sources += \ > Source/WebCore/editing/DeleteFromTextNodeCommand.h \ > Source/WebCore/editing/DeleteSelectionCommand.cpp \ > Source/WebCore/editing/DeleteSelectionCommand.h \ >+ Source/WebCore/editing/DictationAlternative.cpp \ >+ Source/WebCore/editing/DictationAlternative.h \ >+ Source/WebCore/editing/DictationCommand.cpp \ >+ Source/WebCore/editing/DictationCommand.h \ > Source/WebCore/editing/EditAction.h \ > Source/WebCore/editing/EditCommand.cpp \ > Source/WebCore/editing/EditCommand.h \ >@@ -2107,6 +2111,8 @@ webcore_sources += \ > Source/WebCore/editing/TextCheckingHelper.cpp \ > Source/WebCore/editing/TextCheckingHelper.h \ > Source/WebCore/editing/TextGranularity.h \ >+ Source/WebCore/editing/TextInsertionBaseCommand.cpp \ >+ Source/WebCore/editing/TextInsertionBaseCommand.h \ > Source/WebCore/editing/TextIterator.cpp \ > Source/WebCore/editing/TextIterator.h \ > Source/WebCore/editing/TypingCommand.cpp \ >diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri >index 01719e23404a9ad964997dac251b4c7202271842..a4172c66528551fb004bd12ddecab93c8dd7ee17 100644 >--- a/Source/WebCore/Target.pri >+++ b/Source/WebCore/Target.pri >@@ -640,6 +640,8 @@ SOURCES += \ > editing/DeleteButton.cpp \ > editing/DeleteFromTextNodeCommand.cpp \ > editing/DeleteSelectionCommand.cpp \ >+ editing/DictationAlternative.cpp \ >+ editing/DictationCommand.cpp \ > editing/EditCommand.cpp \ > editing/EditingStyle.cpp \ > editing/Editor.cpp \ >@@ -676,6 +678,7 @@ SOURCES += \ > editing/SplitTextNodeCommand.cpp \ > editing/SplitTextNodeContainingElementCommand.cpp \ > editing/TextCheckingHelper.cpp \ >+ editing/TextInsertionBaseCommand.cpp \ > editing/TextIterator.cpp \ > editing/TypingCommand.cpp \ > editing/UnlinkCommand.cpp \ >@@ -1778,6 +1781,8 @@ HEADERS += \ > editing/DeleteButton.h \ > editing/DeleteFromTextNodeCommand.h \ > editing/DeleteSelectionCommand.h \ >+ editing/DictationAlternative.h \ >+ editing/DictationCommand.h \ > editing/EditCommand.h \ > editing/EditingStyle.h \ > editing/EditingBehavior.h \ >@@ -1813,6 +1818,8 @@ HEADERS += \ > editing/SplitElementCommand.h \ > editing/SplitTextNodeCommand.h \ > editing/SplitTextNodeContainingElementCommand.h \ >+ editing/StringHelper.h \ >+ editing/TextInsertionBaseCommand.h \ > editing/TextIterator.h \ > editing/TypingCommand.h \ > editing/UndoStep.h \ >diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in >index 54051f8c014c42ecfd423e935882e23c10ac10a1..7b474498d7dbe08c51daa68b073f509456660363 100644 >--- a/Source/WebCore/WebCore.exp.in >+++ b/Source/WebCore/WebCore.exp.in >@@ -604,6 +604,8 @@ __ZN7WebCore19TextResourceDecoder6decodeEPKcm > __ZN7WebCore19TextResourceDecoderC1ERKN3WTF6StringERKNS_12TextEncodingEb > __ZN7WebCore19TextResourceDecoderD1Ev > __ZN7WebCore19applicationIsSafariEv >+__ZN7WebCore20DictationAlternativeC1Eyyy >+__ZN7WebCore20DictationAlternativeC1Ev > __ZN7WebCore20DisplaySleepDisablerC1EPKc > __ZN7WebCore20DisplaySleepDisablerD1Ev > __ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE >@@ -874,6 +876,7 @@ __ZN7WebCore6Editor17insertOrderedListEv > __ZN7WebCore6Editor18confirmCompositionERKN3WTF6StringE > __ZN7WebCore6Editor18confirmCompositionEv > __ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringEPNS_5RangeEjjb >+__ZN7WebCore6Editor18insertDictatedTextERKN3WTF6StringERKNS1_6VectorINS_20DictationAlternativeELm0EEEPNS_5EventE > __ZN7WebCore6Editor19deleteWithDirectionENS_18SelectionDirectionENS_15TextGranularityEbb > __ZN7WebCore6Editor19insertUnorderedListEv > __ZN7WebCore6Editor21applyStyleToSelectionEPNS_16StylePropertySetENS_10EditActionE >diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi >index 1a27d63b69d95863d175dba48bc3554121f8b5d7..0d670ada2254ce4ca635513536c365af21e71c2a 100644 >--- a/Source/WebCore/WebCore.gypi >+++ b/Source/WebCore/WebCore.gypi >@@ -98,6 +98,7 @@ > 'editing/ApplyBlockElementCommand.h', > 'editing/CompositeEditCommand.h', > 'editing/DeleteSelectionCommand.h', >+ 'editing/DictationAlternative.h', > 'editing/EditAction.h', > 'editing/EditCommand.h', > 'editing/EditingBehavior.h', >@@ -2549,6 +2550,8 @@ > 'editing/DeleteFromTextNodeCommand.cpp', > 'editing/DeleteFromTextNodeCommand.h', > 'editing/DeleteSelectionCommand.cpp', >+ 'editing/DictationAlternative.cpp', >+ 'editing/DictationCommand.cpp', > 'editing/EditCommand.cpp', > 'editing/EditingAllInOne.cpp', > 'editing/EditingStyle.cpp', >@@ -2612,6 +2615,8 @@ > 'editing/SplitTextNodeContainingElementCommand.h', > 'editing/TextCheckingHelper.cpp', > 'editing/TextCheckingHelper.h', >+ 'editing/TextInsertionBaseCommand.cpp', >+ 'editing/TextInsertionBaseCommand.h', > 'editing/TextIterator.cpp', > 'editing/TypingCommand.cpp', > 'editing/UndoStep.h', >diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj >index d993032f6faf8da65b33e2fb080dc5f9b3fed9af..88e0d5e4993c9a4ae910b06dae1bcfe6fc941460 100755 >--- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj >+++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj >@@ -54670,6 +54670,118 @@ > > > </File> > <File >+ RelativePath="..\editing\DictationAlternative.cpp" >+ > >+ <FileConfiguration >+ Name="Debug|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_All|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Production|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ </File> >+ <File >+ RelativePath="..\editing\DictationAlternative.h" >+ > >+ </File> >+ <File >+ RelativePath="..\editing\DictationCommand.cpp" >+ > >+ <FileConfiguration >+ Name="Debug|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_All|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Production|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ </File> >+ <File >+ RelativePath="..\editing\DictationCommand.h" >+ > >+ </File> >+ <File > RelativePath="..\editing\EditAction.h" > > > </File> >@@ -56826,6 +56938,62 @@ > > > </File> > <File >+ RelativePath="..\editing\TextInsertionBaseCommand.cpp" >+ > >+ <FileConfiguration >+ Name="Debug|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Release_Cairo_CFLite|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Debug_All|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ <FileConfiguration >+ Name="Production|Win32" >+ ExcludedFromBuild="true" >+ > >+ <Tool >+ Name="VCCLCompilerTool" >+ /> >+ </FileConfiguration> >+ </File> >+ <File >+ RelativePath="..\editing\TextInsertionBaseCommand.h" >+ > >+ </File> >+ <File > RelativePath="..\editing\TextIterator.cpp" > > > <FileConfiguration >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 8d1a974af6cb9121566bbdb72028b5967cd88161..f26bf1ed80781e833b37ca42cd15168cae18700d 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -5743,6 +5743,12 @@ > CE54FD381016D9A6008B44C8 /* ScriptSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CE54FD371016D9A6008B44C8 /* ScriptSourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CEA3949C11D45CDA003094CF /* StaticHashSetNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */; }; > CEA3949D11D45CDA003094CF /* StaticHashSetNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = CEA3949B11D45CDA003094CF /* StaticHashSetNodeList.h */; }; >+ CECADFC6153778FF00E37068 /* DictationAlternative.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CECADFC2153778FF00E37068 /* DictationAlternative.cpp */; }; >+ CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC3153778FF00E37068 /* DictationAlternative.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ CECADFC8153778FF00E37068 /* DictationCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CECADFC4153778FF00E37068 /* DictationCommand.cpp */; }; >+ CECADFC9153778FF00E37068 /* DictationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC5153778FF00E37068 /* DictationCommand.h */; }; >+ CECADFCD1537791D00E37068 /* TextInsertionBaseCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CECADFCB1537791D00E37068 /* TextInsertionBaseCommand.cpp */; }; >+ CECADFCE1537791D00E37068 /* TextInsertionBaseCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFCC1537791D00E37068 /* TextInsertionBaseCommand.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CECCFC3B141973D5002A0AC1 /* DecodeEscapeSequences.h in Headers */ = {isa = PBXBuildFile; fileRef = CECCFC3A141973D5002A0AC1 /* DecodeEscapeSequences.h */; }; > CEDA12D7152CA1CB00D9E08D /* AlternativeTextClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CEDA12D6152CA1CB00D9E08D /* AlternativeTextClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; > CEF418CE1179678C009D112C /* ViewportArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEF418CC1179678C009D112C /* ViewportArguments.cpp */; }; >@@ -12858,6 +12864,12 @@ > CE5CB1B314EDAB6F00BB2795 /* EventSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventSender.h; sourceTree = "<group>"; }; > CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticHashSetNodeList.cpp; sourceTree = "<group>"; }; > CEA3949B11D45CDA003094CF /* StaticHashSetNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticHashSetNodeList.h; sourceTree = "<group>"; }; >+ CECADFC2153778FF00E37068 /* DictationAlternative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationAlternative.cpp; sourceTree = "<group>"; }; >+ CECADFC3153778FF00E37068 /* DictationAlternative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictationAlternative.h; sourceTree = "<group>"; }; >+ CECADFC4153778FF00E37068 /* DictationCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationCommand.cpp; sourceTree = "<group>"; }; >+ CECADFC5153778FF00E37068 /* DictationCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictationCommand.h; sourceTree = "<group>"; }; >+ CECADFCB1537791D00E37068 /* TextInsertionBaseCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextInsertionBaseCommand.cpp; sourceTree = "<group>"; }; >+ CECADFCC1537791D00E37068 /* TextInsertionBaseCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextInsertionBaseCommand.h; sourceTree = "<group>"; }; > CECCFC3A141973D5002A0AC1 /* DecodeEscapeSequences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodeEscapeSequences.h; sourceTree = "<group>"; }; > CEDA12D6152CA1CB00D9E08D /* AlternativeTextClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlternativeTextClient.h; sourceTree = "<group>"; }; > CEF418CC1179678C009D112C /* ViewportArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ViewportArguments.cpp; sourceTree = "<group>"; }; >@@ -16661,6 +16673,10 @@ > 93309D90099E64910056E581 /* DeleteFromTextNodeCommand.h */, > 93309D91099E64910056E581 /* DeleteSelectionCommand.cpp */, > 93309D92099E64910056E581 /* DeleteSelectionCommand.h */, >+ CECADFC2153778FF00E37068 /* DictationAlternative.cpp */, >+ CECADFC3153778FF00E37068 /* DictationAlternative.h */, >+ CECADFC4153778FF00E37068 /* DictationCommand.cpp */, >+ CECADFC5153778FF00E37068 /* DictationCommand.h */, > 93309D93099E64910056E581 /* EditAction.h */, > 93309D94099E64910056E581 /* EditCommand.cpp */, > 93309D95099E64910056E581 /* EditCommand.h */, >@@ -16744,6 +16760,8 @@ > A7DBF8DB1276919C006B6008 /* TextCheckingHelper.cpp */, > A7DBF8DC1276919C006B6008 /* TextCheckingHelper.h */, > 93309DC9099E64910056E581 /* TextGranularity.h */, >+ CECADFCB1537791D00E37068 /* TextInsertionBaseCommand.cpp */, >+ CECADFCC1537791D00E37068 /* TextInsertionBaseCommand.h */, > 93309DCC099E64910056E581 /* TextIterator.cpp */, > 93309DCD099E64910056E581 /* TextIterator.h */, > 93309DCA099E64910056E581 /* TypingCommand.cpp */, >@@ -24765,6 +24783,9 @@ > D72F6D7A153159A3001EE44E /* FlowThreadController.h in Headers */, > 5740E83D1532DE1700760628 /* TreeScopeAdjuster.h in Headers */, > 316023F01532C40C00D50FF4 /* Dictionary.h in Headers */, >+ CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */, >+ CECADFC9153778FF00E37068 /* DictationCommand.h in Headers */, >+ CECADFCE1537791D00E37068 /* TextInsertionBaseCommand.h in Headers */, > ); > runOnlyForDeploymentPostprocessing = 0; > }; >@@ -27771,6 +27792,9 @@ > D72F6D79153159A3001EE44E /* FlowThreadController.cpp in Sources */, > 5740E83C1532DE1700760628 /* TreeScopeAdjuster.cpp in Sources */, > 312D67B11535691F00563D0D /* Dictionary.cpp in Sources */, >+ CECADFC6153778FF00E37068 /* DictationAlternative.cpp in Sources */, >+ CECADFC8153778FF00E37068 /* DictationCommand.cpp in Sources */, >+ CECADFCD1537791D00E37068 /* TextInsertionBaseCommand.cpp in Sources */, > ); > runOnlyForDeploymentPostprocessing = 0; > }; >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index c4b1085cd57791ca568a9a1ad5f44936c25d4aa5..4d193bcfdcae65f1e2747f457580232c9935d05b 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -119,6 +119,7 @@ > #include "PageGroup.h" > #include "PageTransitionEvent.h" > #include "PlatformKeyboardEvent.h" >+#include "PluginDocument.h" > #include "PopStateEvent.h" > #include "ProcessingInstruction.h" > #include "RegisteredEventListener.h" >@@ -5826,4 +5827,20 @@ IntSize Document::viewportSize() const > return view()->visibleContentRect(/* includeScrollbars */ true).size(); > } > >+Node* eventTargetNodeForDocument(Document* doc) >+{ >+ if (!doc) >+ return 0; >+ Node* node = doc->focusedNode(); >+ if (!node && doc->isPluginDocument()) { >+ PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc); >+ node = pluginDocument->pluginNode(); >+ } >+ if (!node && doc->isHTMLDocument()) >+ node = doc->body(); >+ if (!node) >+ node = doc->documentElement(); >+ return node; >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h >index decf103eed9eaf0c0e1c73c969bf3ed61b195eb5..8950de537b98720af77934df91f2335f29e0411c 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -1505,6 +1505,8 @@ inline Node::Node(Document* document, ConstructionType type) > InspectorCounters::incrementCounter(InspectorCounters::NodeCounter); > } > >+Node* eventTargetNodeForDocument(Document*); >+ > } // namespace WebCore > > #endif // Document_h >diff --git a/Source/WebCore/dom/DocumentMarker.cpp b/Source/WebCore/dom/DocumentMarker.cpp >index b4f9994db4ef6aecfd8c567930b817788eebd61a..53d43e4eab5606a6cc65c78b3f7fea3b3341cf0e 100644 >--- a/Source/WebCore/dom/DocumentMarker.cpp >+++ b/Source/WebCore/dom/DocumentMarker.cpp >@@ -123,6 +123,14 @@ DocumentMarker::DocumentMarker(unsigned startOffset, unsigned endOffset, bool ac > { > } > >+DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned endOffset, PassRefPtr<DocumentMarkerDetails> details) >+ : m_type(type) >+ , m_startOffset(startOffset) >+ , m_endOffset(endOffset) >+ , m_details(details) >+{ >+} >+ > void DocumentMarker::shiftOffsets(int delta) > { > m_startOffset += delta; >diff --git a/Source/WebCore/dom/DocumentMarker.h b/Source/WebCore/dom/DocumentMarker.h >index 41ed8483640dce5f991fc736ac33bd7e56e96245..c1e738d436951d6e71448a00f009956cde4b77f4 100644 >--- a/Source/WebCore/dom/DocumentMarker.h >+++ b/Source/WebCore/dom/DocumentMarker.h >@@ -63,7 +63,10 @@ public: > // range that bears this marker. In some platforms, if the user later inserts the same original > // word again at this position, it will not be autocorrected again. The description of this > // marker is the original word before autocorrection was applied. >- DeletedAutocorrection = 1 << 8 >+ DeletedAutocorrection = 1 << 8, >+ // This marker indicates that the range of text spanned by the marker is entered by voice dictation, >+ // and it has alternative text. >+ DictationAlternatives = 1 << 9 > }; > > class MarkerTypes { >@@ -85,7 +88,7 @@ public: > class AllMarkers : public MarkerTypes { > public: > AllMarkers() >- : MarkerTypes(Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection | Autocorrected | SpellCheckingExemption | DeletedAutocorrection) >+ : MarkerTypes(Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection | Autocorrected | SpellCheckingExemption | DeletedAutocorrection | DictationAlternatives) > { > } > }; >@@ -94,6 +97,7 @@ public: > DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset); > DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, const String& description); > DocumentMarker(unsigned startOffset, unsigned endOffset, bool activeMatch); >+ DocumentMarker(MarkerType, unsigned startOffset, unsigned endOffset, PassRefPtr<DocumentMarkerDetails>); > > MarkerType type() const { return m_type; } > unsigned startOffset() const { return m_startOffset; } >diff --git a/Source/WebCore/dom/DocumentMarkerController.cpp b/Source/WebCore/dom/DocumentMarkerController.cpp >index c25023f2b8f1873c40da6a7c804c5380d162ff71..0551077114b4bc7ea7b8b1c4ece95e1043ed85de 100644 >--- a/Source/WebCore/dom/DocumentMarkerController.cpp >+++ b/Source/WebCore/dom/DocumentMarkerController.cpp >@@ -81,6 +81,16 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp > > } > >+void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type) >+{ >+ addMarker(node, DocumentMarker(type, startOffset, startOffset + length)); >+} >+ >+void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type, PassRefPtr<DocumentMarkerDetails> details) >+{ >+ addMarker(node, DocumentMarker(type, startOffset, startOffset + length, details)); >+} >+ > > void DocumentMarkerController::addTextMatchMarker(Range* range, bool activeMatch) > { >diff --git a/Source/WebCore/dom/DocumentMarkerController.h b/Source/WebCore/dom/DocumentMarkerController.h >index e0672d0d3d1fd8db7aea4bd91d36f4c67e2adacd..6a372480076bfacaebd130cbfda644ee37b8d9cc 100644 >--- a/Source/WebCore/dom/DocumentMarkerController.h >+++ b/Source/WebCore/dom/DocumentMarkerController.h >@@ -48,6 +48,8 @@ public: > void detach(); > void addMarker(Range*, DocumentMarker::MarkerType); > void addMarker(Range*, DocumentMarker::MarkerType, const String& description); >+ void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType); >+ void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, PassRefPtr<DocumentMarkerDetails>); > void addTextMatchMarker(Range*, bool activeMatch); > > void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta); >diff --git a/Source/WebCore/dom/TextEvent.cpp b/Source/WebCore/dom/TextEvent.cpp >index 1dffb014eed5f6b31045379730d8635f916f1df7..d8ea73891c7afd13ec83e603ef9577ab502c7ef0 100644 >--- a/Source/WebCore/dom/TextEvent.cpp >+++ b/Source/WebCore/dom/TextEvent.cpp >@@ -57,6 +57,11 @@ PassRefPtr<TextEvent> TextEvent::createForDrop(PassRefPtr<AbstractView> view, co > return adoptRef(new TextEvent(view, data, TextEventInputDrop)); > } > >+PassRefPtr<TextEvent> TextEvent::createForDictation(PassRefPtr<AbstractView> view, const String& data, const Vector<DictationAlternative>& dictationAlternatives) >+{ >+ return adoptRef(new TextEvent(view, data, dictationAlternatives)); >+} >+ > TextEvent::TextEvent() > : m_inputType(TextEventInputKeyboard) > , m_shouldSmartReplace(false) >@@ -85,6 +90,16 @@ TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefP > { > } > >+TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, const Vector<DictationAlternative>& dictationAlternatives) >+ : UIEvent(eventNames().textInputEvent, true, true, view, 0) >+ , m_inputType(TextEventInputDictation) >+ , m_data(data) >+ , m_shouldSmartReplace(false) >+ , m_shouldMatchStyle(false) >+ , m_dictationAlternatives(dictationAlternatives) >+{ >+} >+ > TextEvent::~TextEvent() > { > } >diff --git a/Source/WebCore/dom/TextEvent.h b/Source/WebCore/dom/TextEvent.h >index 9b0877ad4fecb21adfd748ca31d3cc876cf82a09..f0f93e8f7e2c9a7da9b6fb439af509ed2e1bbff9 100644 >--- a/Source/WebCore/dom/TextEvent.h >+++ b/Source/WebCore/dom/TextEvent.h >@@ -27,6 +27,7 @@ > #ifndef TextEvent_h > #define TextEvent_h > >+#include "DictationAlternative.h" > #include "TextEventInputType.h" > #include "UIEvent.h" > >@@ -42,6 +43,7 @@ namespace WebCore { > static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace); > static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle); > static PassRefPtr<TextEvent> createForDrop(PassRefPtr<AbstractView> view, const String& data); >+ static PassRefPtr<TextEvent> createForDictation(PassRefPtr<AbstractView>, const String& data, const Vector<DictationAlternative>& dictationAlternatives); > > virtual ~TextEvent(); > >@@ -56,10 +58,12 @@ namespace WebCore { > bool isBackTab() const { return m_inputType == TextEventInputBackTab; } > bool isPaste() const { return m_inputType == TextEventInputPaste; } > bool isDrop() const { return m_inputType == TextEventInputDrop; } >+ bool isDictation() const { return m_inputType == TextEventInputDictation; } > > bool shouldSmartReplace() const { return m_shouldSmartReplace; } > bool shouldMatchStyle() const { return m_shouldMatchStyle; } > DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); } >+ const Vector<DictationAlternative>& dictationAlternatives() const { return m_dictationAlternatives; } > > private: > TextEvent(); >@@ -67,6 +71,7 @@ namespace WebCore { > TextEvent(PassRefPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard); > TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment>, > bool shouldSmartReplace, bool shouldMatchStyle); >+ TextEvent(PassRefPtr<AbstractView>, const String& data, const Vector<DictationAlternative>& dictationAlternatives); > > TextEventInputType m_inputType; > String m_data; >@@ -74,6 +79,7 @@ namespace WebCore { > RefPtr<DocumentFragment> m_pastingFragment; > bool m_shouldSmartReplace; > bool m_shouldMatchStyle; >+ Vector<DictationAlternative> m_dictationAlternatives; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/dom/TextEventInputType.h b/Source/WebCore/dom/TextEventInputType.h >index 98bf3432d8b4693782eabfcc380aafeeda00a2ee..8be233c4bff0ba5f5f2f96d5030d188b5c56ba7a 100644 >--- a/Source/WebCore/dom/TextEventInputType.h >+++ b/Source/WebCore/dom/TextEventInputType.h >@@ -35,6 +35,7 @@ enum TextEventInputType { > TextEventInputBackTab, > TextEventInputPaste, > TextEventInputDrop, >+ TextEventInputDictation, > TextEventInputOther, > }; > >diff --git a/Source/WebCore/editing/AlternativeTextController.cpp b/Source/WebCore/editing/AlternativeTextController.cpp >index ec008fc832503eabdcab625c04055a8c49363fff..8d09ff1b998471ea61f389268e4924f704cf13b1 100644 >--- a/Source/WebCore/editing/AlternativeTextController.cpp >+++ b/Source/WebCore/editing/AlternativeTextController.cpp >@@ -27,9 +27,12 @@ > #include "config.h" > #include "AlternativeTextController.h" > >+#include "DictationAlternative.h" >+#include "Document.h" > #include "DocumentMarkerController.h" > #include "EditCommand.h" > #include "EditorClient.h" >+#include "Event.h" > #include "FloatQuad.h" > #include "Frame.h" > #include "FrameView.h" >@@ -37,6 +40,7 @@ > #include "SpellingCorrectionCommand.h" > #include "TextCheckerClient.h" > #include "TextCheckingHelper.h" >+#include "TextEvent.h" > #include "TextIterator.h" > #include "VisibleSelection.h" > #include "htmlediting.h" >@@ -102,8 +106,8 @@ static bool markersHaveIdenticalDescription(const Vector<DocumentMarker*>& marke > } > > AlternativeTextController::AlternativeTextController(Frame* frame) >- : m_frame(frame) >- , m_timer(this, &AlternativeTextController::timerFired) >+ : m_timer(this, &AlternativeTextController::timerFired) >+ , m_frame(frame) > { > } > >@@ -597,4 +601,27 @@ bool AlternativeTextController::processMarkersOnTextToBeReplacedByResult(const T > > #endif > >+bool AlternativeTextController::insertDictatedText(const String& text, const Vector<DictationAlternative>& dictationAlternatives, Event* triggeringEvent) >+{ >+ if (!m_frame) >+ return false; >+ EventTarget* target; >+ if (triggeringEvent) >+ target = triggeringEvent->target(); >+ else >+ target = eventTargetNodeForDocument(m_frame->document()); >+ if (!target) >+ return false; >+ >+ if (FrameView* view = m_frame->view()) >+ view->resetDeferredRepaintDelay(); >+ >+ RefPtr<TextEvent> event = TextEvent::createForDictation(m_frame->domWindow(), text, dictationAlternatives); >+ event->setUnderlyingEvent(triggeringEvent); >+ >+ ExceptionCode ec; >+ target->dispatchEvent(event, ec); >+ return event->defaultHandled(); >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/editing/AlternativeTextController.h b/Source/WebCore/editing/AlternativeTextController.h >index 8e31b1d5e503e43c4d7d3c33c58b8d0bcca282b8..28449efd93e5740a09e35b654b89b50c79808d9b 100644 >--- a/Source/WebCore/editing/AlternativeTextController.h >+++ b/Source/WebCore/editing/AlternativeTextController.h >@@ -41,8 +41,10 @@ class CompositeEditCommand; > class EditorClient; > class EditCommand; > class EditCommandComposition; >+class Event; > class Frame; > class TextCheckerClient; >+struct DictationAlternative; > > class AlternativeTextDetails : public RefCounted<AlternativeTextDetails> { > public: >@@ -58,6 +60,24 @@ struct AlternativeTextInfo { > RefPtr<AlternativeTextDetails> details; > }; > >+class DictationMarkerDetails : public DocumentMarkerDetails { >+public: >+ static PassRefPtr<DictationMarkerDetails> create(const String& originalText, uint64_t dictationContext) >+ { >+ return adoptRef(new DictationMarkerDetails(originalText, dictationContext)); >+ } >+ const String& originalText() const { return m_originalText; } >+ uint64_t dictationContext() const { return m_dictationContext; } >+private: >+ DictationMarkerDetails(const String& originalText, uint64_t dictationContext) >+ : m_dictationContext(dictationContext) >+ , m_originalText(originalText) >+ { } >+ >+ uint64_t m_dictationContext; >+ String m_originalText; >+}; >+ > struct TextCheckingResult; > > #if USE(AUTOCORRECTION_PANEL) >@@ -109,8 +129,10 @@ public: > bool processMarkersOnTextToBeReplacedByResult(const TextCheckingResult*, Range* rangeToBeReplaced, const String& stringToBeReplaced) UNLESS_ENABLED({ UNUSED_PARAM(rangeToBeReplaced); UNUSED_PARAM(stringToBeReplaced); return true; }); > void deletedAutocorrectionAtPosition(const Position&, const String& originalString) UNLESS_ENABLED({ UNUSED_PARAM(originalString); }) > >-#if USE(AUTOCORRECTION_PANEL) >+ bool insertDictatedText(const String&, const Vector<DictationAlternative>&, Event*); >+ > private: >+#if USE(AUTOCORRECTION_PANEL) > String dismissSoon(ReasonForDismissingAlternativeText); > void applyAlternativeText(const String& alternative, const Vector<DocumentMarker::MarkerType>&); > void timerFired(Timer<AlternativeTextController>*); >@@ -130,8 +152,6 @@ private: > FloatRect rootViewRectForRange(const Range*) const; > void markPrecedingWhitespaceForDeletedAutocorrectionAfterCommand(EditCommand*); > >- Frame* m_frame; >- > Timer<AlternativeTextController> m_timer; > AlternativeTextInfo m_alternativeTextInfo; > bool m_isDismissedByEditing; >@@ -139,6 +159,8 @@ private: > String m_originalStringForLastDeletedAutocorrection; > Position m_positionForLastDeletedAutocorrection; > #endif >+ >+ Frame* m_frame; > }; > > #undef UNLESS_ENABLED >diff --git a/Source/WebCore/editing/CompositeEditCommand.h b/Source/WebCore/editing/CompositeEditCommand.h >index f7d174943940b5e9c57f253a046f2f84518fc9c0..b81c4f0fe04086d552a43d95dede13578bbc1f75 100644 >--- a/Source/WebCore/editing/CompositeEditCommand.h >+++ b/Source/WebCore/editing/CompositeEditCommand.h >@@ -82,6 +82,7 @@ public: > > virtual bool isCreateLinkCommand() const; > virtual bool isTypingCommand() const; >+ virtual bool isDictationCommand() const { return false; } > virtual bool preservesTypingStyle() const; > virtual bool shouldRetainAutocorrectionIndicator() const; > virtual void setShouldRetainAutocorrectionIndicator(bool); >diff --git a/Source/WebCore/editing/DictationAlternative.cpp b/Source/WebCore/editing/DictationAlternative.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..b5c806b9dd48a547d23cd0552512bc5704de5091 >--- /dev/null >+++ b/Source/WebCore/editing/DictationAlternative.cpp >@@ -0,0 +1,43 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 "DictationAlternative.h" >+ >+namespace WebCore { >+ >+DictationAlternative::DictationAlternative(uint64_t start, uint64_t length, uint64_t context) >+: rangeStart(start) >+, rangeLength(length) >+, dictationContext(context) >+{ } >+ >+DictationAlternative::DictationAlternative() >+: rangeStart(0) >+, rangeLength(0) >+, dictationContext(0) >+{ } >+ >+} >diff --git a/Source/WebCore/editing/DictationAlternative.h b/Source/WebCore/editing/DictationAlternative.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9cb12ef4a9013bee6f0fa2a7b05e3d6c2a8769ad >--- /dev/null >+++ b/Source/WebCore/editing/DictationAlternative.h >@@ -0,0 +1,40 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 DictationAlternative_h >+#define DictationAlternative_h >+ >+namespace WebCore { >+struct DictationAlternative { >+ DictationAlternative(uint64_t start, uint64_t length, uint64_t context); >+ DictationAlternative(); >+ uint64_t rangeStart; >+ uint64_t rangeLength; >+ uint64_t dictationContext; >+}; >+ >+} >+ >+#endif // DictationAlternative_h >diff --git a/Source/WebCore/editing/DictationCommand.cpp b/Source/WebCore/editing/DictationCommand.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a15800e98ac512c67a494b3c9ce0c5d40743d487 >--- /dev/null >+++ b/Source/WebCore/editing/DictationCommand.cpp >@@ -0,0 +1,142 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 "DictationCommand.h" >+ >+#include "AlternativeTextController.h" >+#include "Document.h" >+#include "DocumentMarker.h" >+#include "DocumentMarkerController.h" >+#include "Frame.h" >+#include "InsertParagraphSeparatorCommand.h" >+#include "InsertTextCommand.h" >+#include "Text.h" >+ >+namespace WebCore { >+ >+class DictationCommandLineOperation { >+public: >+ DictationCommandLineOperation(DictationCommand* dictationCommand) >+ : m_dictationCommand(dictationCommand) >+ { } >+ >+ void operator()(size_t lineOffset, size_t lineLength, bool isLastLine) const >+ { >+ if (lineLength > 0) >+ m_dictationCommand->insertTextRunWithoutNewlines(lineOffset, lineLength); >+ if (!isLastLine) >+ m_dictationCommand->insertParagraphSeparator(); >+ } >+private: >+ DictationCommand* m_dictationCommand; >+}; >+ >+class DictationMarkerSupplier : public TextInsertionMarkerSupplier { >+public: >+ static PassRefPtr<DictationMarkerSupplier> create(const Vector<DictationAlternative>& alternatives) >+ { >+ return adoptRef(new DictationMarkerSupplier(alternatives)); >+ } >+ >+ virtual void addMarkersToTextNode(Text* textNode, unsigned offsetOfInsertion, const String& textToBeInserted) >+ { >+ Document* document = textNode->document(); >+ DocumentMarkerController* markerController =document->markers(); >+ for (size_t i = 0; i < m_alternatives.size(); ++i) { >+ const DictationAlternative& alternative = m_alternatives[i]; >+ markerController->addMarkerToNode(textNode, alternative.rangeStart + offsetOfInsertion, alternative.rangeLength, DocumentMarker::DictationAlternatives, DictationMarkerDetails::create(textToBeInserted.substring(alternative.rangeStart, alternative.rangeLength), alternative.dictationContext)); >+ markerController->addMarkerToNode(textNode, alternative.rangeStart + offsetOfInsertion, alternative.rangeLength, DocumentMarker::SpellCheckingExemption); >+ } >+ } >+ >+protected: >+ DictationMarkerSupplier(const Vector<DictationAlternative>& alternatives) >+ : m_alternatives(alternatives) >+ { >+ } >+private: >+ Vector<DictationAlternative> m_alternatives; >+}; >+ >+DictationCommand::DictationCommand(Document* document, const String& text, const Vector<DictationAlternative>& alternatives) >+ : TextInsertionBaseCommand(document) >+ , m_textToInsert(text) >+ , m_alternatives(alternatives) >+{ >+} >+ >+void DictationCommand::insertText(Document* document, const String& text, const Vector<DictationAlternative>& alternatives, const VisibleSelection& selectionForInsertion) >+{ >+ RefPtr<Frame> frame = document->frame(); >+ ASSERT(frame); >+ >+ VisibleSelection currentSelection = frame->selection()->selection(); >+ >+ String newText = dispatchBeforeTextInsertedEvent(text, selectionForInsertion, false); >+ >+ RefPtr<DictationCommand> cmd; >+ if (newText == text) >+ cmd = DictationCommand::create(document, newText, alternatives); >+ else >+ // If the text was modified before insertion, the location of dictation alternatives >+ // will not be valid anymore. We will just drop the alternatives. >+ cmd = DictationCommand::create(document, newText, Vector<DictationAlternative>()); >+ applyTextInsertionCommand(frame.get(), cmd, selectionForInsertion, currentSelection); >+} >+ >+void DictationCommand::doApply() >+{ >+ DictationCommandLineOperation operation(this); >+ forEachLineInString(m_textToInsert, operation); >+} >+ >+void DictationCommand::insertTextRunWithoutNewlines(size_t lineStart, size_t lineLength) >+{ >+ Vector<DictationAlternative> alternativesInLine; >+ collectDictationAlternativesInRange(lineStart, lineLength, alternativesInLine); >+ RefPtr<InsertTextCommand> command = InsertTextCommand::createWithMarkerSupplier(document(), m_textToInsert.substring(lineStart, lineLength), DictationMarkerSupplier::create(alternativesInLine)); >+ applyCommandToComposite(command, endingSelection()); >+} >+ >+void DictationCommand::insertParagraphSeparator() >+{ >+ if (!canAppendNewLineFeedToSelection(endingSelection())) >+ return; >+ >+ applyCommandToComposite(InsertParagraphSeparatorCommand::create(document())); >+} >+ >+void DictationCommand::collectDictationAlternativesInRange(size_t rangeStart, size_t rangeLength, Vector<DictationAlternative>& alternatives) >+{ >+ for (size_t i = 0; i < m_alternatives.size(); ++i) { >+ const DictationAlternative& alternative = m_alternatives[i]; >+ if (alternative.rangeStart >= rangeStart && (alternative.rangeStart + alternative.rangeLength) <= rangeStart + rangeLength) >+ alternatives.append(DictationAlternative(alternative.rangeStart - rangeStart, alternative.rangeLength, alternative.dictationContext)); >+ } >+ >+} >+ >+} >diff --git a/Source/WebCore/editing/DictationCommand.h b/Source/WebCore/editing/DictationCommand.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f22ac552d06a392cdf9d65933aefd469eee9ea4c >--- /dev/null >+++ b/Source/WebCore/editing/DictationCommand.h >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 DictationCommand_h >+#define DictationCommand_h >+ >+#include "DictationAlternative.h" >+#include "TextInsertionBaseCommand.h" >+ >+namespace WebCore { >+ >+class DocumentMarker; >+ >+class DictationCommand : public TextInsertionBaseCommand { >+ friend class DictationCommandLineOperation; >+public: >+ static void insertText(Document*, const String&, const Vector<DictationAlternative>& alternatives, const VisibleSelection&); >+ virtual bool isDictationCommand() const { return true; } >+private: >+ static PassRefPtr<DictationCommand> create(Document* document, const String& text, const Vector<DictationAlternative>& alternatives) >+ { >+ return adoptRef(new DictationCommand(document, text, alternatives)); >+ } >+ >+ DictationCommand(Document*, const String& text, const Vector<DictationAlternative>& alternatives); >+ >+ virtual void doApply(); >+ >+ void insertTextRunWithoutNewlines(size_t lineStart, size_t lineLength); >+ void insertParagraphSeparator(); >+ void collectDictationAlternativesInRange(size_t rangeStart, size_t rangeLength, Vector<DictationAlternative>&); >+ >+ String m_textToInsert; >+ Vector<DictationAlternative> m_alternatives; >+}; >+} >+ >+#endif // DictationCommand_h >diff --git a/Source/WebCore/editing/EditingAllInOne.cpp b/Source/WebCore/editing/EditingAllInOne.cpp >index 993cb8d177b759913bb886ce8f3183943260ca6e..9642418de8e17493c573ad9823bf9af9704c5ca0 100644 >--- a/Source/WebCore/editing/EditingAllInOne.cpp >+++ b/Source/WebCore/editing/EditingAllInOne.cpp >@@ -36,6 +36,8 @@ > #include <DeleteButtonController.cpp> > #include <DeleteFromTextNodeCommand.cpp> > #include <DeleteSelectionCommand.cpp> >+#include <DictationAlternative.cpp> >+#include <DictationCommand.cpp> > #include <EditCommand.cpp> > #include <EditingStyle.cpp> > #include <Editor.cpp> >@@ -72,6 +74,7 @@ > #include <SplitTextNodeCommand.cpp> > #include <SplitTextNodeContainingElementCommand.cpp> > #include <TextCheckingHelper.cpp> >+#include <TextInsertionBaseCommand.cpp> > #include <TextIterator.cpp> > #include <TypingCommand.cpp> > #include <UnlinkCommand.cpp> >diff --git a/Source/WebCore/editing/Editor.cpp b/Source/WebCore/editing/Editor.cpp >index b908220338008fc0ae4316a8635551e8df739aea..22884fa77edd844e54fbb89ca0a5f89aed441be9 100644 >--- a/Source/WebCore/editing/Editor.cpp >+++ b/Source/WebCore/editing/Editor.cpp >@@ -41,6 +41,8 @@ > #include "CreateLinkCommand.h" > #include "DeleteButtonController.h" > #include "DeleteSelectionCommand.h" >+#include "DictationAlternative.h" >+#include "DictationCommand.h" > #include "DocumentFragment.h" > #include "DocumentMarkerController.h" > #include "EditingText.h" >@@ -875,6 +877,11 @@ bool Editor::insertTextForConfirmedComposition(const String& text) > return m_frame->eventHandler()->handleTextInputEvent(text, 0, TextEventInputComposition); > } > >+bool Editor::insertDictatedText(const String& text, const Vector<DictationAlternative>& dictationAlternatives, Event* triggeringEvent) >+{ >+ return m_alternativeTextController->insertDictatedText(text, dictationAlternatives, triggeringEvent); >+} >+ > bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, TextEvent* triggeringEvent) > { > if (text.isEmpty()) >@@ -909,12 +916,16 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn > RefPtr<Document> document = selectionStart->document(); > > // Insert the text >- TypingCommand::Options options = 0; >- if (selectInsertedText) >- options |= TypingCommand::SelectInsertedText; >- if (autocorrectionWasApplied) >- options |= TypingCommand::RetainAutocorrectionIndicator; >- TypingCommand::insertText(document.get(), text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone); >+ if (triggeringEvent->isDictation()) >+ DictationCommand::insertText(document.get(), text, triggeringEvent->dictationAlternatives(), selection); >+ else { >+ TypingCommand::Options options = 0; >+ if (selectInsertedText) >+ options |= TypingCommand::SelectInsertedText; >+ if (autocorrectionWasApplied) >+ options |= TypingCommand::RetainAutocorrectionIndicator; >+ TypingCommand::insertText(document.get(), text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone); >+ } > > // Reveal the current selection > if (Frame* editedFrame = document->frame()) >@@ -2247,7 +2258,7 @@ void Editor::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionA > Document* document = m_frame->document(); > RefPtr<Range> wordRange = Range::create(document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent()); > >- document->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption, DocumentMarkerController::RemovePartiallyOverlappingMarker); >+ document->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption | DocumentMarker::DictationAlternatives, DocumentMarkerController::RemovePartiallyOverlappingMarker); > document->markers()->clearDescriptionOnMarkersIntersectingRange(wordRange.get(), DocumentMarker::Replacement); > } > >diff --git a/Source/WebCore/editing/Editor.h b/Source/WebCore/editing/Editor.h >index f06f05e68dceabade9afe29811fd3862c7a54bcc..0c51cfac259601f9de96543aa44ffa7016b1e581 100644 >--- a/Source/WebCore/editing/Editor.h >+++ b/Source/WebCore/editing/Editor.h >@@ -28,6 +28,7 @@ > > #include "ClipboardAccessPolicy.h" > #include "Color.h" >+#include "DictationAlternative.h" > #include "DocumentMarker.h" > #include "EditAction.h" > #include "EditingBehavior.h" >@@ -202,6 +203,7 @@ public: > > bool insertText(const String&, Event* triggeringEvent); > bool insertTextForConfirmedComposition(const String& text); >+ bool insertDictatedText(const String&, const Vector<DictationAlternative>& dictationAlternatives, Event* triggeringEvent); > bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent); > bool insertLineBreak(); > bool insertParagraphSeparator(); >diff --git a/Source/WebCore/editing/InsertTextCommand.cpp b/Source/WebCore/editing/InsertTextCommand.cpp >index 39fa2a897fb6c2a7a75c7af5d36829a05c436602..cf2497fd2083d00f3c4847102546e73076140a2e 100644 >--- a/Source/WebCore/editing/InsertTextCommand.cpp >+++ b/Source/WebCore/editing/InsertTextCommand.cpp >@@ -46,6 +46,15 @@ InsertTextCommand::InsertTextCommand(Document* document, const String& text, boo > { > } > >+InsertTextCommand::InsertTextCommand(Document* document, const String& text, PassRefPtr<TextInsertionMarkerSupplier> markerSupplier) >+ : CompositeEditCommand(document) >+ , m_text(text) >+ , m_selectInsertedText(false) >+ , m_rebalanceType(RebalanceLeadingAndTrailingWhitespaces) >+ , m_markerSupplier(markerSupplier) >+{ >+} >+ > Position InsertTextCommand::positionInsideTextNode(const Position& p) > { > Position pos = p; >@@ -167,6 +176,8 @@ void InsertTextCommand::doApply() > > insertTextIntoNode(textNode, offset, m_text); > endPosition = Position(textNode, offset + m_text.length()); >+ if (m_markerSupplier) >+ m_markerSupplier->addMarkersToTextNode(textNode.get(), offset, m_text); > > if (m_rebalanceType == RebalanceLeadingAndTrailingWhitespaces) { > // The insertion may require adjusting adjacent whitespace, if it is present. >diff --git a/Source/WebCore/editing/InsertTextCommand.h b/Source/WebCore/editing/InsertTextCommand.h >index 1adba44ae27705b601aa2d1ab425af65475849bd..e5b2e222fbb0b31aed8b1402a0ce9974c7b75de4 100644 >--- a/Source/WebCore/editing/InsertTextCommand.h >+++ b/Source/WebCore/editing/InsertTextCommand.h >@@ -30,6 +30,17 @@ > > namespace WebCore { > >+class DocumentMarkerController; >+class Text; >+ >+class TextInsertionMarkerSupplier : public RefCounted<TextInsertionMarkerSupplier> { >+public: >+ virtual ~TextInsertionMarkerSupplier() { } >+ virtual void addMarkersToTextNode(Text*, unsigned offsetOfInsertion, const String& textInserted) = 0; >+protected: >+ TextInsertionMarkerSupplier() { } >+}; >+ > class InsertTextCommand : public CompositeEditCommand { > public: > enum RebalanceType { >@@ -43,9 +54,15 @@ public: > return adoptRef(new InsertTextCommand(document, text, selectInsertedText, rebalanceType)); > } > >+ static PassRefPtr<InsertTextCommand> createWithMarkerSupplier(Document* document, const String& text, PassRefPtr<TextInsertionMarkerSupplier> markerSupplier) >+ { >+ return adoptRef(new InsertTextCommand(document, text, markerSupplier)); >+ } >+ > private: > > InsertTextCommand(Document*, const String& text, bool selectInsertedText, RebalanceType); >+ InsertTextCommand(Document*, const String& text, PassRefPtr<TextInsertionMarkerSupplier>); > > void deleteCharacter(); > >@@ -61,6 +78,7 @@ private: > String m_text; > bool m_selectInsertedText; > RebalanceType m_rebalanceType; >+ RefPtr<TextInsertionMarkerSupplier> m_markerSupplier; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/editing/TextInsertionBaseCommand.cpp b/Source/WebCore/editing/TextInsertionBaseCommand.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..e35494770adbed80e3bfeec67e63a4df3aa7d023 >--- /dev/null >+++ b/Source/WebCore/editing/TextInsertionBaseCommand.cpp >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 "TextInsertionBaseCommand.h" >+ >+#include "BeforeTextInsertedEvent.h" >+#include "Document.h" >+#include "Element.h" >+#include "Frame.h" >+#include "Node.h" >+ >+namespace WebCore { >+ >+TextInsertionBaseCommand::TextInsertionBaseCommand(Document* document) >+ : CompositeEditCommand(document) >+{ >+} >+ >+void TextInsertionBaseCommand::applyTextInsertionCommand(Frame* frame, PassRefPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection) >+{ >+ bool changeSelection = selectionForInsertion != endingSelection; >+ if (changeSelection) { >+ command->setStartingSelection(selectionForInsertion); >+ command->setEndingSelection(selectionForInsertion); >+ } >+ applyCommand(command); >+ if (changeSelection) { >+ command->setEndingSelection(endingSelection); >+ frame->selection()->setSelection(endingSelection); >+ } >+} >+ >+String dispatchBeforeTextInsertedEvent(const String& text, const VisibleSelection& selectionForInsertion, bool insertionIsForUpdatingComposition) >+{ >+ if (insertionIsForUpdatingComposition) >+ return text; >+ >+ String newText = text; >+ if (Node* startNode = selectionForInsertion.start().containerNode()) { >+ if (startNode->rootEditableElement()) { >+ // Send BeforeTextInsertedEvent. The event handler will update text if necessary. >+ ExceptionCode ec = 0; >+ RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text); >+ startNode->rootEditableElement()->dispatchEvent(evt, ec); >+ newText = evt->text(); >+ } >+ } >+ return newText; >+} >+ >+bool canAppendNewLineFeedToSelection(const VisibleSelection& selection) >+{ >+ Node* node = selection.rootEditableElement(); >+ if (!node) >+ return false; >+ >+ RefPtr<BeforeTextInsertedEvent> event = BeforeTextInsertedEvent::create(String("\n")); >+ ExceptionCode ec = 0; >+ node->dispatchEvent(event, ec); >+ return event->text().length(); >+} >+ >+} >diff --git a/Source/WebCore/editing/TextInsertionBaseCommand.h b/Source/WebCore/editing/TextInsertionBaseCommand.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9dff6dc4ec0069c73a0baaf599d9f25f0a0091d0 >--- /dev/null >+++ b/Source/WebCore/editing/TextInsertionBaseCommand.h >@@ -0,0 +1,71 @@ >+/* >+ * Copyright (C) 2012 Apple 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 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 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 TextInsertionBaseCommand_h >+#define TextInsertionBaseCommand_h >+ >+#include "CompositeEditCommand.h" >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+class Document; >+class VisibleSelection; >+ >+class TextInsertionBaseCommand : public CompositeEditCommand { >+public: >+ virtual ~TextInsertionBaseCommand() { }; >+ >+protected: >+ TextInsertionBaseCommand(Document*); >+ static void applyTextInsertionCommand(Frame*, PassRefPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection); >+}; >+ >+String dispatchBeforeTextInsertedEvent(const String& text, const VisibleSelection& selectionForInsertion, bool insertionIsForUpdatingComposition); >+bool canAppendNewLineFeedToSelection(const VisibleSelection&); >+ >+// LineOperation should define member function "opeartor (size_t lineOffset, size_t lineLength, bool isLastLine)". >+// lienLength doesn't include the newline character. So the value of lineLength could be 0. >+template <class LineOperation> >+void forEachLineInString(const String& string, const LineOperation& operation) >+{ >+ unsigned offset = 0; >+ size_t newline; >+ while ((newline = string.find('\n', offset)) != notFound) { >+ operation(offset, newline - offset, false); >+ offset = newline + 1; >+ } >+ if (!offset) >+ operation(0, string.length(), true); >+ else { >+ unsigned length = string.length(); >+ if (length != offset) >+ operation(offset, length - offset, true); >+ } >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/editing/TypingCommand.cpp b/Source/WebCore/editing/TypingCommand.cpp >index a0a6e00f18108e9a6d057d2554fcccdcce1c4af3..f3c42329fbfff60cf8a57d93247919849858ba2e 100644 >--- a/Source/WebCore/editing/TypingCommand.cpp >+++ b/Source/WebCore/editing/TypingCommand.cpp >@@ -26,7 +26,6 @@ > #include "config.h" > #include "TypingCommand.h" > >-#include "BeforeTextInsertedEvent.h" > #include "BreakBlockquoteCommand.h" > #include "DeleteSelectionCommand.h" > #include "Document.h" >@@ -48,21 +47,35 @@ namespace WebCore { > > using namespace HTMLNames; > >-static bool canAppendNewLineFeed(const VisibleSelection& selection) >+class TypingCommandLineOperation > { >- Node* node = selection.rootEditableElement(); >- if (!node) >- return false; >- >- String lineFeed("\n"); >- RefPtr<BeforeTextInsertedEvent> event = BeforeTextInsertedEvent::create(lineFeed); >- ExceptionCode ec = 0; >- node->dispatchEvent(event, ec); >- return event->text() == lineFeed; >-} >+public: >+ TypingCommandLineOperation(TypingCommand* typingCommand, bool selectInsertedText, const String& text) >+ : m_typingCommand(typingCommand) >+ , m_selectInsertedText(selectInsertedText) >+ , m_text(text) >+ { } >+ >+ void operator()(size_t lineOffset, size_t lineLength, bool isLastLine) const >+ { >+ if (isLastLine) { >+ if (!lineOffset || lineLength > 0) >+ m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), m_selectInsertedText); >+ } else { >+ if (lineLength > 0) >+ m_typingCommand->insertTextRunWithoutNewlines(m_text.substring(lineOffset, lineLength), false); >+ m_typingCommand->insertParagraphSeparator(); >+ } >+ } >+ >+private: >+ TypingCommand* m_typingCommand; >+ bool m_selectInsertedText; >+ const String& m_text; >+}; > > TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, const String &textToInsert, Options options, TextGranularity granularity, TextCompositionType compositionType) >- : CompositeEditCommand(document) >+ : TextInsertionBaseCommand(document) > , m_commandType(commandType) > , m_textToInsert(textToInsert) > , m_openForMoreTyping(true) >@@ -162,17 +175,8 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis > ASSERT(frame); > > VisibleSelection currentSelection = frame->selection()->selection(); >- bool changeSelection = currentSelection != selectionForInsertion; >- String newText = text; >- if (Node* startNode = selectionForInsertion.start().containerNode()) { >- if (startNode->rootEditableElement() && compositionType != TextCompositionUpdate) { >- // Send BeforeTextInsertedEvent. The event handler will update text if necessary. >- ExceptionCode ec = 0; >- RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text); >- startNode->rootEditableElement()->dispatchEvent(evt, ec); >- newText = evt->text(); >- } >- } >+ >+ String newText = dispatchBeforeTextInsertedEvent(text, selectionForInsertion, compositionType == TextCompositionUpdate); > > // Set the starting and ending selection appropriately if we are using a selection > // that is different from the current selection. In the future, we should change EditCommand >@@ -191,15 +195,7 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis > } > > RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, options, compositionType); >- if (changeSelection) { >- cmd->setStartingSelection(selectionForInsertion); >- cmd->setEndingSelection(selectionForInsertion); >- } >- applyCommand(cmd); >- if (changeSelection) { >- cmd->setEndingSelection(currentSelection); >- frame->selection()->setSelection(currentSelection); >- } >+ applyTextInsertionCommand(frame.get(), cmd, selectionForInsertion, currentSelection); > } > > void TypingCommand::insertLineBreak(Document *document, Options options) >@@ -359,21 +355,8 @@ void TypingCommand::insertText(const String &text, bool selectInsertedText) > // an existing selection; at the moment they can either put the caret after what's inserted or > // select what's inserted, but there's no way to "extend selection" to include both an old selection > // that ends just before where we want to insert text and the newly inserted text. >- unsigned offset = 0; >- size_t newline; >- while ((newline = text.find('\n', offset)) != notFound) { >- if (newline != offset) >- insertTextRunWithoutNewlines(text.substring(offset, newline - offset), false); >- insertParagraphSeparator(); >- offset = newline + 1; >- } >- if (!offset) >- insertTextRunWithoutNewlines(text, selectInsertedText); >- else { >- unsigned length = text.length(); >- if (length != offset) >- insertTextRunWithoutNewlines(text.substring(offset, length - offset), selectInsertedText); >- } >+ TypingCommandLineOperation operation(this, selectInsertedText, text); >+ forEachLineInString(text, operation); > } > > void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText) >@@ -388,7 +371,7 @@ void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool select > > void TypingCommand::insertLineBreak() > { >- if (!canAppendNewLineFeed(endingSelection())) >+ if (!canAppendNewLineFeedToSelection(endingSelection())) > return; > > applyCommandToComposite(InsertLineBreakCommand::create(document())); >@@ -397,7 +380,7 @@ void TypingCommand::insertLineBreak() > > void TypingCommand::insertParagraphSeparator() > { >- if (!canAppendNewLineFeed(endingSelection())) >+ if (!canAppendNewLineFeedToSelection(endingSelection())) > return; > > applyCommandToComposite(InsertParagraphSeparatorCommand::create(document())); >diff --git a/Source/WebCore/editing/TypingCommand.h b/Source/WebCore/editing/TypingCommand.h >index 1f8c181dfcebb259ce8d666c7cbd6854d644526a..950eec80a3ba0bab007a4487d2bf443129553dd1 100644 >--- a/Source/WebCore/editing/TypingCommand.h >+++ b/Source/WebCore/editing/TypingCommand.h >@@ -26,11 +26,11 @@ > #ifndef TypingCommand_h > #define TypingCommand_h > >-#include "CompositeEditCommand.h" >+#include "TextInsertionBaseCommand.h" > > namespace WebCore { > >-class TypingCommand : public CompositeEditCommand { >+class TypingCommand : public TextInsertionBaseCommand { > public: > enum ETypingCommand { > DeleteSelection, >diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp >index 9beb8204cc7e712ae781347f103bf6d27aefbfc1..64e18f8192912272bffb97c67a34d6e94b0ea809 100644 >--- a/Source/WebCore/page/EventHandler.cpp >+++ b/Source/WebCore/page/EventHandler.cpp >@@ -2678,22 +2678,6 @@ void EventHandler::hoverTimerFired(Timer<EventHandler>*) > } > } > >-static Node* eventTargetNodeForDocument(Document* doc) >-{ >- if (!doc) >- return 0; >- Node* node = doc->focusedNode(); >- if (!node && doc->isPluginDocument()) { >- PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc); >- node = pluginDocument->pluginNode(); >- } >- if (!node && doc->isHTMLDocument()) >- node = doc->body(); >- if (!node) >- node = doc->documentElement(); >- return node; >-} >- > bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt) > { > // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do. >diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp >index 784f5c776aca0b9bbcbc8b3c8ee7d7b852429a32..03d92de3feeee5000cbc592846ce06b2f27b3541 100644 >--- a/Source/WebCore/rendering/InlineTextBox.cpp >+++ b/Source/WebCore/rendering/InlineTextBox.cpp >@@ -992,13 +992,15 @@ static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM > return GraphicsContext::DocumentMarkerGrammarLineStyle; > case DocumentMarker::CorrectionIndicator: > return GraphicsContext::DocumentMarkerAutocorrectionReplacementLineStyle; >+ case DocumentMarker::DictationAlternatives: >+ return GraphicsContext::DocumentMarkerDictationAlternativesLineStyle; > default: > ASSERT_NOT_REACHED(); > return GraphicsContext::DocumentMarkerSpellingLineStyle; > } > } > >-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool grammar) >+void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool grammar) > { > // Never print spelling/grammar markers (5327887) > if (textRenderer()->document()->printing()) >@@ -1130,6 +1132,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& > case DocumentMarker::Spelling: > case DocumentMarker::CorrectionIndicator: > case DocumentMarker::Replacement: >+ case DocumentMarker::DictationAlternatives: > if (background) > continue; > break; >@@ -1153,17 +1156,16 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& > // marker intersects this run. Paint it. > switch (marker->type()) { > case DocumentMarker::Spelling: >- paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false); >+ case DocumentMarker::CorrectionIndicator: >+ case DocumentMarker::DictationAlternatives: >+ paintDocumentMarker(pt, boxOrigin, marker, style, font, false); > break; > case DocumentMarker::Grammar: >- paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, true); >+ paintDocumentMarker(pt, boxOrigin, marker, style, font, true); > break; > case DocumentMarker::TextMatch: > paintTextMatchMarker(pt, boxOrigin, marker, style, font); > break; >- case DocumentMarker::CorrectionIndicator: >- paintSpellingOrGrammarMarker(pt, boxOrigin, marker, style, font, false); >- break; > case DocumentMarker::Replacement: > computeRectForReplacementMarker(marker, style, font); > break; >diff --git a/Source/WebCore/rendering/InlineTextBox.h b/Source/WebCore/rendering/InlineTextBox.h >index 58972d134df241bc822dabf11b0bab63a0889678..a9bde74f0390976c5462af45c15e2b7d94a1847f 100644 >--- a/Source/WebCore/rendering/InlineTextBox.h >+++ b/Source/WebCore/rendering/InlineTextBox.h >@@ -182,7 +182,7 @@ protected: > private: > void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, int decoration, const ShadowData*); > void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&); >- void paintSpellingOrGrammarMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&, bool grammar); >+ void paintDocumentMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&, bool grammar); > void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&); > void computeRectForReplacementMarker(DocumentMarker*, RenderStyle*, const Font&); > >diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp >index 1c5331ab27abdad5ca007e9ee1994c30661c7a73..63da819738fcafe93ab9e7f44487e0c3d8755725 100644 >--- a/Source/WebCore/testing/Internals.cpp >+++ b/Source/WebCore/testing/Internals.cpp >@@ -109,6 +109,8 @@ static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerType > result = DocumentMarker::SpellCheckingExemption; > else if (equalIgnoringCase(markerType, "DeletedAutocorrection")) > result = DocumentMarker::DeletedAutocorrection; >+ else if (equalIgnoringCase(markerType, "DictationAlternatives")) >+ result = DocumentMarker::DictationAlternatives; > else > return false; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 83549
:
136402
|
136408
|
136457
|
136580
|
136770
|
136774
|
136783
|
136798
|
136806
|
136816
|
136832
|
136982
|
136988
|
137105
| 137211