Changeset 120357 in webkit
- Timestamp:
- Jun 14, 2012 1:22:56 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 49 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r120354 r120357 1 2012-06-14 Jia Pu <jpu@apple.com> 2 3 Mark text with text alternative with blue underline. 4 https://bugs.webkit.org/show_bug.cgi?id=83047 5 6 Reviewed by Enrica Casucci. 7 8 * platform/mac-lion/Skipped: 9 * platform/mac-snowleopard/Skipped: 10 * platform/mac/editing/input/edit-dictated-text-with-alternative-expected.txt: Added. 11 * platform/mac/editing/input/edit-dictated-text-with-alternative.html: Added. 12 * platform/mac/editing/input/insert-dictated-text-expected.txt: Added. 13 * platform/mac/editing/input/insert-dictated-text.html: Added. 14 1 15 2012-06-14 Emil A Eklund <eae@chromium.org> 2 16 -
trunk/LayoutTests/platform/mac-lion/Skipped
r119659 r120357 35 35 # Pasting replaces the three periods with an ellipsis on Lion 36 36 editing/pasteboard/5478250.html 37 38 # Mountain Lion functionalities 39 platform/mac/editing/input/edit-dictated-text-with-alternative.html 40 platform/mac/editing/input/insert-dictated-text.html 37 41 38 42 # --- Media --- -
trunk/LayoutTests/platform/mac-snowleopard/Skipped
r119659 r120357 212 212 # https://bugs.webkit.org/show_bug.cgi?id=40361 213 213 editing/text-iterator/findString-selection-disabled.html 214 215 # Dictated text input is not supported on this platform 216 platform/mac/editing/input/edit-dictated-text-with-alternative.html 217 platform/mac/editing/input/insert-dictated-text.html -
trunk/Source/WebCore/ChangeLog
r120354 r120357 1 2012-06-14 Jia Pu <jpu@apple.com> 2 3 Mark text with text alternative with blue underline. 4 https://bugs.webkit.org/show_bug.cgi?id=83047 5 6 Reviewed by Enrica Casucci. 7 8 Tests: platform/mac/editing/input/edit-dictated-text-with-alternative.html 9 platform/mac/editing/input/insert-dictated-text.html 10 11 This patch implements visual indication on dictated text with alternatives, and provides UI 12 to show alternative text on OS X. Majority of the changes is for generalizing existing AlternativeTextController 13 class to handle dictation alternatives. The two new classes, AlternativeTextUIController and 14 TextAlternativeWithRange, are used by both WebKit and WK2. So WebCore seems to be the natural place 15 for them. 16 17 * WebCore.exp.in: 18 * WebCore.xcodeproj/project.pbxproj: 19 * editing/AlternativeTextController.cpp: Expanded exising class interface to support dictation alternatives. 20 (DictationAlternativeDetails): Marker detail class for dictation alternative mark. 21 (WebCore::DictationAlternativeDetails::create): 22 (WebCore::DictationAlternativeDetails::dictationContext): 23 (WebCore::DictationAlternativeDetails::DictationAlternativeDetails): 24 (WebCore::markerTypesForAppliedDictationAlternative): 25 (WebCore::AlternativeTextController::applyAlternativeTextToRange): Generalized existing applyAlternativeTextToRange() to handle dictation alternatives. 26 (WebCore::AlternativeTextController::timerFired): Expanded existing code to handle dictation alternatives. 27 (WebCore::AlternativeTextController::handleAlternativeTextUIResult): Expanded existing code to handle dictation alternatives. 28 (WebCore::AlternativeTextController::respondToChangedSelection): Moved part of the function into respondToMarkerAtEndOfWord() to improve readability. 29 (WebCore::AlternativeTextController::shouldStartTimerFor): 30 (WebCore::AlternativeTextController::respondToMarkerAtEndOfWord): 31 (WebCore::AlternativeTextController::markerDescriptionForAppliedAlternativeText): 32 (WebCore::AlternativeTextController::removeDictationAlternativesForMarker): 33 (WebCore::AlternativeTextController::dictationAlternativesForMarker): 34 (WebCore::AlternativeTextController::applyDictationAlternative): 35 * editing/AlternativeTextController.h: 36 * editing/Editor.cpp: 37 (WebCore::Editor::notifyComponentsOnChangedSelection): Renamed existing respondToChangedSelection() function to avoid naming collision. 38 (WebCore::Editor::appliedEditing): 39 (WebCore::Editor::unappliedEditing): 40 (WebCore::Editor::reappliedEditing): 41 (WebCore::Editor::updateMarkersForWordsAffectedByEditing): 42 (WebCore::Editor::changeSelectionAfterCommand): 43 (WebCore::Editor::respondToChangedSelection): 44 (WebCore::Editor::dictationAlternativesForMarker): 45 (WebCore::Editor::applyDictationAlternativelternative): 46 * editing/Editor.h: 47 * editing/FrameSelection.h: 48 * editing/mac/AlternativeTextUIController.h: Added. WK1 and WK2 use this class to keep track of text alternatives objects. 49 (AlternativeTextUIController): 50 (WebCore::AlternativeTextUIController::AlternativeTextUIController): 51 (AlernativeTextContextController): 52 (WebCore::AlternativeTextUIController::AlernativeTextContextController::AlernativeTextContextController): 53 * editing/mac/AlternativeTextUIController.mm: Added. 54 (WebCore::AlternativeTextUIController::AlernativeTextContextController::addAlternatives): 55 (WebCore::AlternativeTextUIController::AlernativeTextContextController::alternativesForContext): 56 (WebCore::AlternativeTextUIController::AlernativeTextContextController::removeAlternativesForContext): 57 (WebCore::AlternativeTextUIController::AlernativeTextContextController::clear): 58 (WebCore::AlternativeTextUIController::addAlternatives): 59 (WebCore::AlternativeTextUIController::alternativesForContext): 60 (WebCore::AlternativeTextUIController::clear): 61 (WebCore::AlternativeTextUIController::showAlternatives): 62 (WebCore::AlternativeTextUIController::handleAcceptedAlternative): 63 (WebCore::AlternativeTextUIController::dismissAlternatives): 64 (WebCore::AlternativeTextUIController::removeAlternatives): 65 * editing/mac/TextAlternativeWithRange.h: Added. A simple struct to make it easier to pass around a pair of text alternatives object and range. 66 * editing/mac/TextAlternativeWithRange.mm: Added. 67 (WebCore::TextAlternativeWithRange::TextAlternativeWithRange): 68 (WebCore::collectDictationTextAlternatives): 69 * page/AlternativeTextClient.h: 70 * page/ContextMenuController.cpp: Added code to show alternative dictated text in context menu. 71 (WebCore::ContextMenuController::contextMenuItemSelected): 72 (WebCore::ContextMenuController::populate): 73 (WebCore::ContextMenuController::checkOrEnableIfNeeded): 74 * platform/ContextMenuItem.h: 75 * rendering/HitTestResult.cpp: 76 (WebCore::HitTestResult::dictationAlternatives): 77 * rendering/HitTestResult.h: 78 * rendering/InlineTextBox.cpp: 79 (WebCore::InlineTextBox::paintDocumentMarker): 80 1 81 2012-06-14 Emil A Eklund <eae@chromium.org> 2 82 -
trunk/Source/WebCore/WebCore.exp.in
r120147 r120357 2527 2527 __ZNK7WebCore4KURL22protocolIsInHTTPFamilyEv 2528 2528 #endif 2529 2530 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) 2531 __ZN7WebCore27AlternativeTextUIController15addAlternativesERKN3WTF9RetainPtrI18NSTextAlternativesEE 2532 __ZN7WebCore27AlternativeTextUIController22alternativesForContextEy 2533 __ZN7WebCore27AlternativeTextUIController5clearEv 2534 __ZN7WebCore27AlternativeTextUIController19dismissAlternativesEv 2535 __ZN7WebCore27AlternativeTextUIController18removeAlternativesEy 2536 __ZN7WebCore27AlternativeTextUIController16showAlternativesEP6NSViewRKNS_9FloatRectEyU13block_pointerFvP8NSStringE 2537 __ZN7WebCore24TextAlternativeWithRangeC1EP18NSTextAlternatives8_NSRange 2538 __ZN7WebCore32collectDictationTextAlternativesEP18NSAttributedStringRN3WTF6VectorINS_24TextAlternativeWithRangeELm0EEE 2539 #endif -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r120260 r120357 5792 5792 CE08C3D2152B599A0021B8C2 /* AlternativeTextController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE08C3D0152B599A0021B8C2 /* AlternativeTextController.h */; settings = {ATTRIBUTES = (); }; }; 5793 5793 CE54FD381016D9A6008B44C8 /* ScriptSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CE54FD371016D9A6008B44C8 /* ScriptSourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5794 CE7B2DB31586ABAD0098B3FA /* AlternativeTextUIController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5795 CE7B2DB41586ABAD0098B3FA /* AlternativeTextUIController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */; }; 5796 CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5797 CE7B2DB61586ABAD0098B3FA /* TextAlternativeWithRange.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */; }; 5794 5798 CEA3949C11D45CDA003094CF /* StaticHashSetNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */; }; 5795 5799 CEA3949D11D45CDA003094CF /* StaticHashSetNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = CEA3949B11D45CDA003094CF /* StaticHashSetNodeList.h */; }; … … 12988 12992 CE54FD371016D9A6008B44C8 /* ScriptSourceProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptSourceProvider.h; sourceTree = "<group>"; }; 12989 12993 CE5CB1B314EDAB6F00BB2795 /* EventSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventSender.h; sourceTree = "<group>"; }; 12994 CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AlternativeTextUIController.h; path = mac/AlternativeTextUIController.h; sourceTree = "<group>"; }; 12995 CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AlternativeTextUIController.mm; path = mac/AlternativeTextUIController.mm; sourceTree = "<group>"; }; 12996 CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextAlternativeWithRange.h; path = mac/TextAlternativeWithRange.h; sourceTree = "<group>"; }; 12997 CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TextAlternativeWithRange.mm; path = mac/TextAlternativeWithRange.mm; sourceTree = "<group>"; }; 12990 12998 CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticHashSetNodeList.cpp; sourceTree = "<group>"; }; 12991 12999 CEA3949B11D45CDA003094CF /* StaticHashSetNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticHashSetNodeList.h; sourceTree = "<group>"; }; … … 20694 20702 isa = PBXGroup; 20695 20703 children = ( 20704 CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */, 20705 CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */, 20696 20706 ED501DC50B249F2900AE18D9 /* EditorMac.mm */, 20697 20707 4A8C96EA0BE69032004EEFF0 /* FrameSelectionMac.mm */, 20708 CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */, 20709 CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */, 20698 20710 ); 20699 20711 name = mac; … … 25062 25074 977E2E0F12F0FC9C00C13379 /* XSSAuditor.h in Headers */, 25063 25075 FD537353137B651800008DCE /* ZeroPole.h in Headers */, 25076 CE7B2DB31586ABAD0098B3FA /* AlternativeTextUIController.h in Headers */, 25077 CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */, 25064 25078 ); 25065 25079 runOnlyForDeploymentPostprocessing = 0; … … 28103 28117 FD537352137B651800008DCE /* ZeroPole.cpp in Sources */, 28104 28118 9A1B6F97158869C80011A8C4 /* JSDOMStringListCustom.cpp in Sources */, 28119 CE7B2DB41586ABAD0098B3FA /* AlternativeTextUIController.mm in Sources */, 28120 CE7B2DB61586ABAD0098B3FA /* TextAlternativeWithRange.mm in Sources */, 28105 28121 ); 28106 28122 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/WebCore/editing/AlternativeTextController.cpp
r114220 r120357 69 69 }; 70 70 71 class DictationAlternativeDetails : public AlternativeTextDetails { 72 public: 73 static PassRefPtr<DictationAlternativeDetails> create(uint64_t dictationContext) 74 { 75 return adoptRef(new DictationAlternativeDetails(dictationContext)); 76 } 77 78 uint64_t dictationContext() const { return m_dictationContext; } 79 80 private: 81 DictationAlternativeDetails(uint64_t dictationContext) 82 : m_dictationContext(dictationContext) 83 { } 84 85 uint64_t m_dictationContext; 86 }; 87 71 88 #if USE(AUTOCORRECTION_PANEL) 72 89 … … 91 108 } 92 109 return markerTypesForReplacement; 110 } 111 112 static const Vector<DocumentMarker::MarkerType>& markerTypesForAppliedDictationAlternative() 113 { 114 DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForAppliedDictationAlternative, ()); 115 if (markerTypesForAppliedDictationAlternative.isEmpty()) 116 markerTypesForAppliedDictationAlternative.append(DocumentMarker::SpellCheckingExemption); 117 return markerTypesForAppliedDictationAlternative; 93 118 } 94 119 … … 216 241 } 217 242 218 void AlternativeTextController::applyAlternativeText (const String& alternative, const Vector<DocumentMarker::MarkerType>& markerTypesToAdd)219 { 220 if (! m_alternativeTextInfo.rangeWithAlternative)243 void AlternativeTextController::applyAlternativeTextToRange(const Range* range, const String& alternative, AlternativeTextType alternativeType, const Vector<DocumentMarker::MarkerType>& markerTypesToAdd) 244 { 245 if (!range) 221 246 return; 222 247 223 248 ExceptionCode ec = 0; 224 RefPtr<Range> paragraphRangeContainingCorrection = m_alternativeTextInfo.rangeWithAlternative->cloneRange(ec);249 RefPtr<Range> paragraphRangeContainingCorrection = range->cloneRange(ec); 225 250 if (ec) 226 251 return; 227 252 228 setStart(paragraphRangeContainingCorrection.get(), startOfParagraph( m_alternativeTextInfo.rangeWithAlternative->startPosition()));229 setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph( m_alternativeTextInfo.rangeWithAlternative->endPosition()));253 setStart(paragraphRangeContainingCorrection.get(), startOfParagraph(range->startPosition())); 254 setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(range->endPosition())); 230 255 231 256 // After we replace the word at range rangeWithAlternative, we need to add markers to that range. … … 239 264 return; 240 265 241 Position startPositionOfrangeWithAlternative = m_alternativeTextInfo.rangeWithAlternative->startPosition();266 Position startPositionOfrangeWithAlternative = range->startPosition(); 242 267 correctionStartOffsetInParagraphAsRange->setEnd(startPositionOfrangeWithAlternative.containerNode(), startPositionOfrangeWithAlternative.computeOffsetInContainerNode(), ec); 243 268 if (ec) … … 248 273 249 274 // Clone the range, since the caller of this method may want to keep the original range around. 250 RefPtr<Range> rangeWithAlternative = m_alternativeTextInfo.rangeWithAlternative->cloneRange(ec);275 RefPtr<Range> rangeWithAlternative = range->cloneRange(ec); 251 276 applyCommand(SpellingCorrectionCommand::create(rangeWithAlternative, alternative)); 252 277 setEnd(paragraphRangeContainingCorrection.get(), m_frame->selection()->selection().start()); … … 260 285 DocumentMarkerController* markers = replacementRange->startContainer()->document()->markers(); 261 286 size_t size = markerTypesToAdd.size(); 262 for (size_t i = 0; i < size; ++i) { 263 DocumentMarker::MarkerType markerType = markerTypesToAdd[i]; 264 String description; 265 if (m_alternativeTextInfo.type != AlternativeTextTypeReversion && (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected)) 266 description = m_alternativeTextInfo.originalText; 267 markers->addMarker(replacementRange.get(), markerType, description); 268 } 287 for (size_t i = 0; i < size; ++i) 288 markers->addMarker(replacementRange.get(), markerTypesToAdd[i], markerDescriptionForAppliedAlternativeText(alternativeType, markerTypesToAdd[i])); 269 289 } 270 290 … … 349 369 } 350 370 break; 371 case AlternativeTextTypeDictationAlternatives: 372 { 373 #if USE(DICTATION_ALTERNATIVES) 374 const Range* rangeWithAlternative = m_alternativeTextInfo.rangeWithAlternative.get(); 375 const DictationAlternativeDetails* details = static_cast<const DictationAlternativeDetails*>(m_alternativeTextInfo.details.get()); 376 if (!rangeWithAlternative || !details || !details->dictationContext()) 377 return; 378 FloatRect boundingBox = rootViewRectForRange(rangeWithAlternative); 379 m_alternativeTextInfo.isActive = true; 380 if (!boundingBox.isEmpty()) { 381 if (AlternativeTextClient* client = alternativeTextClient()) 382 client->showDictationAlternativeUI(boundingBox, details->dictationContext()); 383 } 384 #endif 385 } 386 break; 351 387 } 352 388 } … … 354 390 void AlternativeTextController::handleAlternativeTextUIResult(const String& result) 355 391 { 356 Range* r eplacedRange = m_alternativeTextInfo.rangeWithAlternative.get();357 if (!r eplacedRange || m_frame->document() != replacedRange->ownerDocument())358 return; 359 360 String currentWord = plainText( m_alternativeTextInfo.rangeWithAlternative.get());392 Range* rangeWithAlternative = m_alternativeTextInfo.rangeWithAlternative.get(); 393 if (!rangeWithAlternative || m_frame->document() != rangeWithAlternative->ownerDocument()) 394 return; 395 396 String currentWord = plainText(rangeWithAlternative); 361 397 // Check to see if the word we are about to correct has been changed between timer firing and callback being triggered. 362 398 if (currentWord != m_alternativeTextInfo.originalText) … … 368 404 case AlternativeTextTypeCorrection: 369 405 if (result.length()) 370 applyAlternativeText (result, markerTypesForAutocorrection());406 applyAlternativeTextToRange(rangeWithAlternative, result, m_alternativeTextInfo.type, markerTypesForAutocorrection()); 371 407 else if (!m_isDismissedByEditing) 372 r eplacedRange->startContainer()->document()->markers()->addMarker(replacedRange, DocumentMarker::RejectedCorrection, m_alternativeTextInfo.originalText);408 rangeWithAlternative->startContainer()->document()->markers()->addMarker(rangeWithAlternative, DocumentMarker::RejectedCorrection, m_alternativeTextInfo.originalText); 373 409 break; 374 410 case AlternativeTextTypeReversion: 375 411 case AlternativeTextTypeSpellingSuggestions: 376 412 if (result.length()) 377 applyAlternativeText(result, markerTypesForReplacement()); 413 applyAlternativeTextToRange(rangeWithAlternative, result, m_alternativeTextInfo.type, markerTypesForReplacement()); 414 break; 415 case AlternativeTextTypeDictationAlternatives: 416 if (result.length()) 417 applyAlternativeTextToRange(rangeWithAlternative, result, m_alternativeTextInfo.type, markerTypesForAppliedDictationAlternative()); 378 418 break; 379 419 } … … 401 441 } 402 442 403 void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection )443 void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options) 404 444 { 405 445 VisibleSelection currentSelection(m_frame->selection()->selection()); … … 427 467 428 468 Node* node = position.containerNode(); 429 int endOffset = position.offsetInContainerNode();430 469 Vector<DocumentMarker*> markers = node->document()->markers()->markersFor(node); 431 470 size_t markerCount = markers.size(); 432 471 for (size_t i = 0; i < markerCount; ++i) { 433 472 const DocumentMarker* marker = markers[i]; 434 if (! shouldStartTimerFor(marker, endOffset))473 if (!marker) 435 474 continue; 436 RefPtr<Range> wordRange = Range::create(m_frame->document(), node, marker->startOffset(), node, marker->endOffset()); 437 String currentWord = plainText(wordRange.get()); 438 if (!currentWord.length()) 439 continue; 440 441 m_alternativeTextInfo.rangeWithAlternative = wordRange; 442 m_alternativeTextInfo.originalText = currentWord; 443 if (marker->type() == DocumentMarker::Spelling) 444 startAlternativeTextUITimer(AlternativeTextTypeSpellingSuggestions); 445 else { 446 m_alternativeTextInfo.details = AutocorrectionAlternativeDetails::create(marker->description()); 447 startAlternativeTextUITimer(AlternativeTextTypeReversion); 448 } 449 450 break; 475 476 if (respondToMarkerAtEndOfWord(*marker, position, options)) 477 break; 451 478 } 452 479 } … … 599 626 return true; 600 627 } 601 628 629 bool AlternativeTextController::shouldStartTimerFor(const WebCore::DocumentMarker &marker, int endOffset) const 630 { 631 return (((marker.type() == DocumentMarker::Replacement && !marker.description().isNull()) || marker.type() == DocumentMarker::Spelling || marker.type() == DocumentMarker::DictationAlternatives) && static_cast<int>(marker.endOffset()) == endOffset); 632 } 633 634 bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker& marker, const Position& endOfWordPosition, FrameSelection::SetSelectionOptions options) 635 { 636 if (options & FrameSelection::DictationTriggered) 637 return false; 638 if (!shouldStartTimerFor(marker, endOfWordPosition.offsetInContainerNode())) 639 return false; 640 Node* node = endOfWordPosition.containerNode(); 641 RefPtr<Range> wordRange = Range::create(m_frame->document(), node, marker.startOffset(), node, marker.endOffset()); 642 if (!wordRange) 643 return false; 644 String currentWord = plainText(wordRange.get()); 645 if (!currentWord.length()) 646 return false; 647 m_alternativeTextInfo.originalText = currentWord; 648 switch (marker.type()) { 649 case DocumentMarker::Spelling: 650 m_alternativeTextInfo.rangeWithAlternative = wordRange; 651 m_alternativeTextInfo.details = AutocorrectionAlternativeDetails::create(""); 652 startAlternativeTextUITimer(AlternativeTextTypeSpellingSuggestions); 653 break; 654 case DocumentMarker::Replacement: 655 m_alternativeTextInfo.rangeWithAlternative = wordRange; 656 m_alternativeTextInfo.details = AutocorrectionAlternativeDetails::create(marker.description()); 657 startAlternativeTextUITimer(AlternativeTextTypeReversion); 658 break; 659 case DocumentMarker::DictationAlternatives: { 660 const DictationMarkerDetails* markerDetails = static_cast<const DictationMarkerDetails*>(marker.details()); 661 if (!markerDetails) 662 return false; 663 if (currentWord != markerDetails->originalText()) 664 return false; 665 m_alternativeTextInfo.rangeWithAlternative = wordRange; 666 m_alternativeTextInfo.details = DictationAlternativeDetails::create(markerDetails->dictationContext()); 667 startAlternativeTextUITimer(AlternativeTextTypeDictationAlternatives); 668 } 669 break; 670 default: 671 ASSERT_NOT_REACHED(); 672 break; 673 } 674 return true; 675 } 676 677 String AlternativeTextController::markerDescriptionForAppliedAlternativeText(AlternativeTextType alternativeTextType, DocumentMarker::MarkerType markerType) 678 { 679 680 if (alternativeTextType != AlternativeTextTypeReversion && alternativeTextType != AlternativeTextTypeDictationAlternatives && (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected)) 681 return m_alternativeTextInfo.originalText; 682 return ""; 683 } 684 602 685 #endif 603 686 … … 625 708 } 626 709 710 void AlternativeTextController::removeDictationAlternativesForMarker(const DocumentMarker* marker) 711 { 712 #if USE(DICTATION_ALTERNATIVES) 713 DictationMarkerDetails* details = static_cast<DictationMarkerDetails*>(marker->details()); 714 if (AlternativeTextClient* client = alternativeTextClient()) 715 client->removeDictationAlternatives(details->dictationContext()); 716 #else 717 UNUSED_PARAM(marker); 718 #endif 719 } 720 721 Vector<String> AlternativeTextController::dictationAlternativesForMarker(const DocumentMarker* marker) 722 { 723 #if USE(DICTATION_ALTERNATIVES) 724 ASSERT(marker->type() == DocumentMarker::DictationAlternatives); 725 if (AlternativeTextClient* client = alternativeTextClient()) { 726 DictationMarkerDetails* details = static_cast<DictationMarkerDetails*>(marker->details()); 727 return client->dictationAlternatives(details->dictationContext()); 728 } 729 return Vector<String>(); 730 #else 731 UNUSED_PARAM(marker); 732 return Vector<String>(); 733 #endif 734 } 735 736 void AlternativeTextController::applyDictationAlternative(const String& alternativeString) 737 { 738 #if USE(DICTATION_ALTERNATIVES) 739 Editor* editor = m_frame->editor(); 740 RefPtr<Range> selection = editor->selectedRange(); 741 if (!selection || !editor->shouldInsertText(alternativeString, selection.get(), EditorInsertActionPasted)) 742 return; 743 DocumentMarkerController* markers = selection->startContainer()->document()->markers(); 744 Vector<DocumentMarker*> dictationAlternativesMarkers = markers->markersInRange(selection.get(), DocumentMarker::DictationAlternatives); 745 for (size_t i = 0; i < dictationAlternativesMarkers.size(); ++i) 746 removeDictationAlternativesForMarker(dictationAlternativesMarkers[i]); 747 748 applyAlternativeTextToRange(selection.get(), alternativeString, AlternativeTextTypeDictationAlternatives, markerTypesForAppliedDictationAlternative()); 749 #else 750 UNUSED_PARAM(alternativeString); 751 #endif 752 } 753 627 754 } // namespace WebCore -
trunk/Source/WebCore/editing/AlternativeTextController.h
r114220 r120357 29 29 #include "AlternativeTextClient.h" 30 30 #include "DocumentMarker.h" 31 #include "FrameSelection.h" 31 32 #include "Range.h" 32 33 #include "TextChecking.h" … … 109 110 void respondToAppliedEditing(CompositeEditCommand*) UNLESS_ENABLED({ }) 110 111 void respondToUnappliedEditing(EditCommandComposition*) UNLESS_ENABLED({ }) 111 void respondToChangedSelection(const VisibleSelection& oldSelection ) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); })112 void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); }) 112 113 113 114 void stopPendingCorrection(const VisibleSelection& oldSelection) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); }) … … 131 132 132 133 bool insertDictatedText(const String&, const Vector<DictationAlternative>&, Event*); 134 void removeDictationAlternativesForMarker(const DocumentMarker*); 135 Vector<String> dictationAlternativesForMarker(const DocumentMarker*); 136 void applyDictationAlternative(const String& alternativeString); 133 137 134 138 private: 135 139 #if USE(AUTOCORRECTION_PANEL) 136 140 String dismissSoon(ReasonForDismissingAlternativeText); 137 void applyAlternativeText (const String& alternative, const Vector<DocumentMarker::MarkerType>&);141 void applyAlternativeTextToRange(const Range*, const String& alternative, AlternativeTextType, const Vector<DocumentMarker::MarkerType>&); 138 142 void timerFired(Timer<AlternativeTextController>*); 139 143 void recordAutocorrectionResponseReversed(const String& replacedString, const String& replacementString); 140 144 void recordSpellcheckerResponseForModifiedCorrection(Range* rangeOfCorrection, const String& corrected, const String& correction); 145 String markerDescriptionForAppliedAlternativeText(AlternativeTextType, DocumentMarker::MarkerType); 141 146 142 bool shouldStartTimerFor(const DocumentMarker* marker, int endOffset) const 143 { 144 return (((marker->type() == DocumentMarker::Replacement && !marker->description().isNull()) 145 || marker->type() == DocumentMarker::Spelling) && static_cast<int>(marker->endOffset()) == endOffset); 146 } 147 bool shouldStartTimerFor(const DocumentMarker&, int endOffset) const; 148 bool respondToMarkerAtEndOfWord(const DocumentMarker&, const Position& endOfWordPosition, FrameSelection::SetSelectionOptions); 147 149 148 150 AlternativeTextClient* alternativeTextClient(); -
trunk/Source/WebCore/editing/Editor.cpp
r120279 r120357 481 481 } 482 482 483 void Editor:: respondToChangedSelection(const VisibleSelection& oldSelection)483 void Editor::notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options) 484 484 { 485 485 if (client()) … … 487 487 setStartNewKillRingSequence(true); 488 488 m_deleteButtonController->respondToChangedSelection(oldSelection); 489 m_alternativeTextController->respondToChangedSelection(oldSelection );489 m_alternativeTextController->respondToChangedSelection(oldSelection, options); 490 490 } 491 491 … … 790 790 791 791 // Don't clear the typing style with this selection change. We do those things elsewhere if necessary. 792 changeSelectionAfterCommand(newSelection, false, false); 792 FrameSelection::SetSelectionOptions options = cmd->isDictationCommand() ? FrameSelection::DictationTriggered : 0; 793 changeSelectionAfterCommand(newSelection, options); 793 794 794 795 if (!cmd->preservesTypingStyle()) … … 816 817 817 818 VisibleSelection newSelection(cmd->startingSelection()); 818 changeSelectionAfterCommand(newSelection, true, true);819 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); 819 820 m_alternativeTextController->respondToUnappliedEditing(cmd.get()); 820 821 … … 832 833 833 834 VisibleSelection newSelection(cmd->endingSelection()); 834 changeSelectionAfterCommand(newSelection, true, true);835 changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle); 835 836 836 837 m_lastEditCommand = 0; … … 2267 2268 RefPtr<Range> wordRange = Range::create(document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent()); 2268 2269 2270 Vector<DocumentMarker*> markers = document->markers()->markersInRange(wordRange.get(), DocumentMarker::DictationAlternatives); 2271 for (size_t i = 0; i < markers.size(); ++i) 2272 m_alternativeTextController->removeDictationAlternativesForMarker(markers[i]); 2273 2269 2274 document->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption | DocumentMarker::DictationAlternatives, DocumentMarkerController::RemovePartiallyOverlappingMarker); 2270 2275 document->markers()->clearDescriptionOnMarkersIntersectingRange(wordRange.get(), DocumentMarker::Replacement); … … 2414 2419 } 2415 2420 2416 void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle)2421 void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions options) 2417 2422 { 2418 2423 // If the new selection is orphaned, then don't update the selection. … … 2425 2430 // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid 2426 2431 bool selectionDidNotChangeDOMPosition = newSelection == m_frame->selection()->selection(); 2427 if (selectionDidNotChangeDOMPosition || m_frame->selection()->shouldChangeSelection(newSelection)) { 2428 FrameSelection::SetSelectionOptions options = 0; 2429 if (closeTyping) 2430 options |= FrameSelection::CloseTyping; 2431 if (clearTypingStyle) 2432 options |= FrameSelection::ClearTypingStyle; 2432 if (selectionDidNotChangeDOMPosition || m_frame->selection()->shouldChangeSelection(newSelection)) 2433 2433 m_frame->selection()->setSelection(newSelection, options); 2434 }2435 2434 2436 2435 // Some editing operations change the selection visually without affecting its position within the DOM. … … 2827 2826 m_frame->document()->markers()->removeMarkers(DocumentMarker::Grammar); 2828 2827 2829 respondToChangedSelection(oldSelection);2828 notifyComponentsOnChangedSelection(oldSelection, options); 2830 2829 } 2831 2830 … … 2918 2917 } 2919 2918 2919 Vector<String> Editor::dictationAlternativesForMarker(const DocumentMarker* marker) 2920 { 2921 return m_alternativeTextController->dictationAlternativesForMarker(marker); 2922 } 2923 2924 void Editor::applyDictationAlternativelternative(const String& alternativeString) 2925 { 2926 m_alternativeTextController->applyDictationAlternative(alternativeString); 2927 } 2928 2920 2929 } // namespace WebCore -
trunk/Source/WebCore/editing/Editor.h
r120005 r120357 135 135 bool shouldDeleteRange(Range*) const; 136 136 bool shouldApplyStyle(StylePropertySet*, Range*); 137 138 void respondToChangedSelection(const VisibleSelection& oldSelection); 137 139 138 void respondToChangedContents(const VisibleSelection& endingSelection); 140 139 … … 396 395 EditorParagraphSeparator defaultParagraphSeparator() const { return m_defaultParagraphSeparator; } 397 396 void setDefaultParagraphSeparator(EditorParagraphSeparator separator) { m_defaultParagraphSeparator = separator; } 398 397 Vector<String> dictationAlternativesForMarker(const DocumentMarker*); 398 void applyDictationAlternativelternative(const String& alternativeString); 399 399 private: 400 400 virtual void willDetachPage() OVERRIDE; … … 430 430 void setComposition(const String&, SetCompositionMode); 431 431 432 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle); 432 void changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions); 433 void notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions); 433 434 434 435 Node* findEventTargetFromSelection() const; -
trunk/Source/WebCore/editing/FrameSelection.h
r119705 r120357 119 119 SpellCorrectionTriggered = 1 << 3, 120 120 DoNotSetFocus = 1 << 4, 121 DictationTriggered = 1 << 5 121 122 }; 122 123 typedef unsigned SetSelectionOptions; // Union of values in SetSelectionOption and EUserTriggered -
trunk/Source/WebCore/page/AlternativeTextClient.h
r115369 r120357 32 32 #include <wtf/text/WTFString.h> 33 33 34 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) 35 // Some platforms provide UI for suggesting alternative dictation text. 36 #define WTF_USE_DICTATION_ALTERNATIVES 1 37 #endif // PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) 38 34 39 namespace WebCore { 35 40 … … 44 49 AlternativeTextTypeReversion, 45 50 AlternativeTextTypeSpellingSuggestions, 51 AlternativeTextTypeDictationAlternatives 46 52 }; 47 53 … … 55 61 virtual ~AlternativeTextClient() { } 56 62 virtual void pageDestroyed() = 0; 57 63 #if USE(AUTOCORRECTION_PANEL) 58 64 virtual void showCorrectionAlternative(AlternativeTextType, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacmentString, const Vector<String>& alternativeReplacementStrings) = 0; 59 65 virtual void dismissAlternative(ReasonForDismissingAlternativeText) = 0; 60 66 virtual String dismissAlternativeSoon(ReasonForDismissingAlternativeText) = 0; 61 67 virtual void recordAutocorrectionResponse(AutocorrectionResponseType, const String& replacedString, const String& replacementString) = 0; 68 #endif 69 #if USE(DICTATION_ALTERNATIVES) 70 virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) = 0; 71 virtual void dismissDictationAlternativeUI() = 0; 72 virtual void removeDictationAlternatives(uint64_t dictationContext) = 0; 73 virtual Vector<String> dictationAlternatives(uint64_t dictationContext) = 0; 74 #endif 62 75 }; 63 76 -
trunk/Source/WebCore/page/ContextMenuController.cpp
r119687 r120357 482 482 break; 483 483 #endif 484 case ContextMenuItemTagDictationAlternative: 485 frame->editor()->applyDictationAlternativelternative(item->title()); 486 break; 484 487 default: 485 488 break; … … 897 900 FrameSelection* selection = frame->selection(); 898 901 bool inPasswordField = selection->isInPasswordField(); 899 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node); 900 901 if (!inPasswordField && spellCheckingEnabled) { 902 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range 903 // is never considered a misspelling and bad grammar at the same time) 904 bool misspelling; 905 bool badGrammar; 906 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar); 907 if (misspelling || badGrammar) { 908 size_t size = guesses.size(); 909 if (size == 0) { 910 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions 911 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit) 912 if (misspelling) { 913 appendItem(NoGuessesItem, m_contextMenu.get()); 902 if (!inPasswordField) { 903 bool haveContextMenuItemsForMisspellingOrGrammer = false; 904 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node); 905 if (spellCheckingEnabled) { 906 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range 907 // is never considered a misspelling and bad grammar at the same time) 908 bool misspelling; 909 bool badGrammar; 910 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar); 911 if (misspelling || badGrammar) { 912 size_t size = guesses.size(); 913 if (!size) { 914 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions 915 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit) 916 if (misspelling) { 917 appendItem(NoGuessesItem, m_contextMenu.get()); 918 appendItem(*separatorItem(), m_contextMenu.get()); 919 } 920 } else { 921 for (unsigned i = 0; i < size; i++) { 922 const String &guess = guesses[i]; 923 if (!guess.isEmpty()) { 924 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess); 925 appendItem(item, m_contextMenu.get()); 926 } 927 } 914 928 appendItem(*separatorItem(), m_contextMenu.get()); 915 929 } 930 if (misspelling) { 931 appendItem(IgnoreSpellingItem, m_contextMenu.get()); 932 appendItem(LearnSpellingItem, m_contextMenu.get()); 933 } else 934 appendItem(IgnoreGrammarItem, m_contextMenu.get()); 935 appendItem(*separatorItem(), m_contextMenu.get()); 936 haveContextMenuItemsForMisspellingOrGrammer = true; 937 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) 916 938 } else { 917 for (unsigned i = 0; i < size; i++) { 918 const String &guess = guesses[i]; 919 if (!guess.isEmpty()) { 920 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess); 921 appendItem(item, m_contextMenu.get()); 922 } 939 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back. 940 String replacedString = m_hitTestResult.replacedString(); 941 if (!replacedString.isEmpty()) { 942 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString)); 943 appendItem(item, m_contextMenu.get()); 944 appendItem(*separatorItem(), m_contextMenu.get()); 945 haveContextMenuItemsForMisspellingOrGrammer = true; 923 946 } 924 appendItem(*separatorItem(), m_contextMenu.get()); 947 #endif 925 948 } 926 927 if (misspelling) { 928 appendItem(IgnoreSpellingItem, m_contextMenu.get()); 929 appendItem(LearnSpellingItem, m_contextMenu.get()); 930 } else 931 appendItem(IgnoreGrammarItem, m_contextMenu.get()); 932 appendItem(*separatorItem(), m_contextMenu.get()); 933 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) 934 } else { 935 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back. 936 String replacedString = m_hitTestResult.replacedString(); 937 if (!replacedString.isEmpty()) { 938 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString)); 939 appendItem(item, m_contextMenu.get()); 949 } 950 951 if (!haveContextMenuItemsForMisspellingOrGrammer) { 952 // Spelling and grammar checking is mutually exclusive with dictation alternatives. 953 Vector<String> dictationAlternatives = m_hitTestResult.dictationAlternatives(); 954 if (!dictationAlternatives.isEmpty()) { 955 for (size_t i = 0; i < dictationAlternatives.size(); ++i) { 956 ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, dictationAlternatives[i]); 957 appendItem(item, m_contextMenu.get()); 958 } 940 959 appendItem(*separatorItem(), m_contextMenu.get()); 941 960 } 942 #endif943 961 } 944 962 } … … 1353 1371 case ContextMenuItemLastCustomTag: 1354 1372 case ContextMenuItemBaseApplicationTag: 1373 case ContextMenuItemTagDictationAlternative: 1355 1374 break; 1356 1375 case ContextMenuItemTagMediaPlayPause: -
trunk/Source/WebCore/platform/ContextMenuItem.h
r117970 r120357 135 135 ContextMenuItemTagPDFSinglePageScrolling, 136 136 ContextMenuItemTagPDFFacingPagesScrolling, 137 ContextMenuItemTagDictationAlternative, 137 138 #if ENABLE(INSPECTOR) 138 139 ContextMenuItemTagInspectElement, -
trunk/Source/WebCore/rendering/HitTestResult.cpp
r119733 r120357 711 711 } 712 712 713 Vector<String> HitTestResult::dictationAlternatives() const 714 { 715 // Return the dictation context handle if the text at this point has DictationAlternative marker, which means this text is 716 if (!m_innerNonSharedNode) 717 return Vector<String>(); 718 719 DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(hitTestPoint().point(), DocumentMarker::DictationAlternatives); 720 if (!marker) 721 return Vector<String>(); 722 723 Frame* frame = innerNonSharedNode()->document()->frame(); 724 if (!frame) 725 return Vector<String>(); 726 727 return frame->editor()->dictationAlternativesForMarker(marker); 728 } 729 713 730 } // namespace WebCore -
trunk/Source/WebCore/rendering/HitTestResult.h
r117091 r120357 158 158 const NodeSet& rectBasedTestResult() const; 159 159 160 Vector<String> dictationAlternatives() const; 161 160 162 private: 161 163 NodeSet& mutableRectBasedTestResult(); // See above. -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r119528 r120357 1031 1031 markerSpansWholeBox = false; 1032 1032 1033 if (!markerSpansWholeBox || grammar) { 1033 bool isDictationMarker = marker->type() == DocumentMarker::DictationAlternatives; 1034 if (!markerSpansWholeBox || grammar || isDictationMarker) { 1034 1035 int startPosition = max<int>(marker->startOffset() - m_start, 0); 1035 1036 int endPosition = min<int>(marker->endOffset() - m_start, m_len); … … 1051 1052 // Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to 1052 1053 // display a toolTip. We don't do this for misspelling markers. 1053 if (grammar ) {1054 if (grammar || isDictationMarker) { 1054 1055 markerRect.move(-boxOrigin.x(), -boxOrigin.y()); 1055 1056 markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox(); -
trunk/Source/WebKit/mac/ChangeLog
r120029 r120357 1 2012-06-14 Jia Pu <jpu@apple.com> 2 3 Mark text with text alternative with blue underline. 4 https://bugs.webkit.org/show_bug.cgi?id=83047 5 6 Reviewed by Enrica Casucci. 7 8 Changes in WebKit include implementation of new functions declared in AlternativeTextClient, 9 and logic for calling Editor::insertDictatedText() instead of Editor::insertText() when there's 10 alternatives attached to the input string. 11 12 * WebCoreSupport/CorrectionPanel.mm: 13 (correctionIndicatorType): 14 (CorrectionPanel::handleAcceptedReplacement): 15 * WebCoreSupport/WebAlternativeTextClient.h: 16 (WebAlternativeTextClient): 17 * WebCoreSupport/WebAlternativeTextClient.mm: 18 (WebAlternativeTextClient::showCorrectionAlternative): 19 (WebAlternativeTextClient::dismissAlternative): 20 (WebAlternativeTextClient::dismissAlternativeSoon): 21 (WebAlternativeTextClient::recordAutocorrectionResponse): 22 (WebAlternativeTextClient::removeDictationAlternatives): 23 (WebAlternativeTextClient::showDictationAlternativeUI): 24 (WebAlternativeTextClient::dismissDictationAlternativeUI): 25 (WebAlternativeTextClient::dictationAlternatives): 26 * WebView/WebHTMLView.mm: 27 (-[WebHTMLView validAttributesForMarkedText]): 28 (-[WebHTMLView insertText:]): 29 * WebView/WebView.mm: 30 (-[WebView handleAcceptedAlternativeText:]): 31 (-[WebView _getWebCoreDictationAlternatives:fromTextAlternatives:]): 32 (-[WebView _showDictationAlternativeUI:WebCore::forDictationContext:]): 33 (-[WebView _dismissDictationAlternativeUI]): 34 (-[WebView _removeDictationAlternatives:]): 35 (-[WebView _dictationAlternatives:]): 36 * WebView/WebViewData.h: 37 * WebView/WebViewData.mm: 38 (-[WebViewPrivate init]): 39 * WebView/WebViewInternal.h: 40 * WebView/WebViewPrivate.h: 41 1 42 2012-06-11 Alexis Menard <alexis.menard@openbossa.org> 2 43 -
trunk/Source/WebKit/mac/WebCoreSupport/CorrectionPanel.mm
r113340 r120357 26 26 27 27 #import "WebViewInternal.h" 28 #import "WebViewPrivate.h"29 28 30 29 #if USE(AUTOCORRECTION_PANEL) … … 40 39 case AlternativeTextTypeSpellingSuggestions: 41 40 return NSCorrectionIndicatorTypeGuesses; 41 case AlternativeTextTypeDictationAlternatives: 42 ASSERT_NOT_REACHED(); 43 break; 42 44 } 43 45 ASSERT_NOT_REACHED(); … … 132 134 } 133 135 134 [m_view.get() handle CorrectionPanelResult:acceptedReplacement];136 [m_view.get() handleAcceptedAlternativeText:acceptedReplacement]; 135 137 m_view.clear(); 136 138 if (acceptedReplacement) -
trunk/Source/WebKit/mac/WebCoreSupport/WebAlternativeTextClient.h
r115369 r120357 38 38 virtual ~WebAlternativeTextClient(); 39 39 virtual void pageDestroyed() OVERRIDE; 40 #if USE(AUTOCORRECTION_PANEL) 40 41 virtual void showCorrectionAlternative(WebCore::AlternativeTextType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) OVERRIDE; 41 42 virtual void dismissAlternative(WebCore::ReasonForDismissingAlternativeText) OVERRIDE; 42 43 virtual String dismissAlternativeSoon(WebCore::ReasonForDismissingAlternativeText) OVERRIDE; 43 44 virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString) OVERRIDE; 45 #endif 46 #if USE(DICTATION_ALTERNATIVES) 47 virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) OVERRIDE; 48 virtual void dismissDictationAlternativeUI() OVERRIDE; 49 virtual void removeDictationAlternatives(uint64_t dictationContext) OVERRIDE; 50 virtual Vector<String> dictationAlternatives(uint64_t dictationContext) OVERRIDE; 51 #endif 44 52 private: 45 53 WebView* m_webView; -
trunk/Source/WebKit/mac/WebCoreSupport/WebAlternativeTextClient.mm
r115369 r120357 26 26 #include "WebAlternativeTextClient.h" 27 27 28 #include "WebViewInternal.h" 29 28 30 using namespace WebCore; 29 31 … … 45 47 } 46 48 49 #if USE(AUTOCORRECTION_PANEL) 47 50 void WebAlternativeTextClient::showCorrectionAlternative(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) 48 51 { 49 #if USE(AUTOCORRECTION_PANEL)50 52 m_correctionPanel.show(m_webView, type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings); 51 #endif52 53 } 53 54 54 55 void WebAlternativeTextClient::dismissAlternative(ReasonForDismissingAlternativeText reason) 55 56 { 56 #if USE(AUTOCORRECTION_PANEL)57 57 m_correctionPanel.dismiss(reason); 58 #endif59 58 } 60 59 61 60 String WebAlternativeTextClient::dismissAlternativeSoon(ReasonForDismissingAlternativeText reason) 62 61 { 63 #if USE(AUTOCORRECTION_PANEL)64 62 return m_correctionPanel.dismiss(reason); 65 #else66 return String();67 #endif68 63 } 69 64 70 65 void WebAlternativeTextClient::recordAutocorrectionResponse(AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString) 71 66 { 72 #if USE(AUTOCORRECTION_PANEL)73 67 NSCorrectionResponse response = responseType == AutocorrectionReverted ? NSCorrectionResponseReverted : NSCorrectionResponseEdited; 74 CorrectionPanel::recordAutocorrectionResponse(m_webView, response, replacedString, replacementString); 68 CorrectionPanel::recordAutocorrectionResponse(m_webView, response, replacedString, replacementString); 69 } 75 70 #endif 71 72 #if USE(DICTATION_ALTERNATIVES) 73 void WebAlternativeTextClient::removeDictationAlternatives(uint64_t dictationContext) 74 { 75 [m_webView _removeDictationAlternatives:dictationContext]; 76 76 } 77 78 void WebAlternativeTextClient::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 79 { 80 [m_webView _showDictationAlternativeUI:boundingBoxOfDictatedText forDictationContext:dictationContext]; 81 } 82 83 void WebAlternativeTextClient::dismissDictationAlternativeUI() 84 { 85 [m_webView _dismissDictationAlternativeUI]; 86 } 87 88 Vector<String> WebAlternativeTextClient::dictationAlternatives(uint64_t dictationContext) 89 { 90 return [m_webView _dictationAlternatives:dictationContext]; 91 } 92 #endif -
trunk/Source/WebKit/mac/WebView/WebHTMLView.mm
r117695 r120357 114 114 #import <WebCore/StylePropertySet.h> 115 115 #import <WebCore/Text.h> 116 #import <WebCore/TextAlternativeWithRange.h> 116 117 #import <WebCore/WebCoreObjCExtras.h> 117 118 #import <WebCore/WebFontCache.h> … … 5604 5605 validAttributes = [[NSArray alloc] initWithObjects: 5605 5606 NSUnderlineStyleAttributeName, NSUnderlineColorAttributeName, 5606 NSMarkedClauseSegmentAttributeName, NSTextInputReplacementRangeAttributeName, nil]; 5607 NSMarkedClauseSegmentAttributeName, NSTextInputReplacementRangeAttributeName, 5608 #if USE(DICTATION_ALTERNATIVES) 5609 NSTextAlternativesAttributeName, 5610 #endif 5611 nil]; 5607 5612 // NSText also supports the following attributes, but it's 5608 5613 // hard to tell which are really required for text input to … … 5924 5929 bool isFromInputMethod = coreFrame && coreFrame->editor()->hasComposition(); 5925 5930 5931 Vector<DictationAlternative> dictationAlternativeLocations; 5926 5932 if (isAttributedString) { 5933 #if USE(DICTATION_ALTERNATIVES) 5934 Vector<WebCore::TextAlternativeWithRange> textAlternatives; 5935 collectDictationTextAlternatives(string, textAlternatives); 5936 if (!textAlternatives.isEmpty()) 5937 [[self _webView] _getWebCoreDictationAlternatives:dictationAlternativeLocations fromTextAlternatives:textAlternatives]; 5938 #endif 5927 5939 // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data. 5928 5940 // It does not look like any input methods ever use insertText: with attributes other than NSTextInputReplacementRangeAttributeName. … … 5963 5975 // An insertText: might be handled by other responders in the chain if we don't handle it. 5964 5976 // One example is space bar that results in scrolling down the page. 5965 eventHandled = coreFrame->editor()->insertText(eventText, event); 5977 5978 if (!dictationAlternativeLocations.isEmpty()) 5979 eventHandled = coreFrame->editor()->insertDictatedText(eventText, dictationAlternativeLocations, event); 5980 else 5981 eventHandled = coreFrame->editor()->insertText(eventText, event); 5966 5982 } else { 5967 5983 eventHandled = true; -
trunk/Source/WebKit/mac/WebView/WebView.mm
r118086 r120357 112 112 #import <JavaScriptCore/JSValueRef.h> 113 113 #import <WebCore/AbstractDatabase.h> 114 #import <WebCore/AlternativeTextUIController.h> 114 115 #import <WebCore/ApplicationCacheStorage.h> 115 116 #import <WebCore/BackForwardListImpl.h> … … 5537 5538 #endif 5538 5539 5539 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)5540 - (void)handleCorrectionPanelResult:(NSString*)result5541 {5542 WebFrame *webFrame = [self _selectedOrMainFrame];5543 Frame* coreFrame = core(webFrame);5544 if (coreFrame)5545 coreFrame->editor()->handleAlternativeTextUIResult(result);5546 }5547 #endif5548 5549 5540 @end 5550 5541 … … 6411 6402 #endif 6412 6403 6404 #if USE(AUTOCORRECTION_PANEL) 6405 - (void)handleAcceptedAlternativeText:(NSString*)text 6406 { 6407 WebFrame *webFrame = [self _selectedOrMainFrame]; 6408 Frame* coreFrame = core(webFrame); 6409 if (coreFrame) 6410 coreFrame->editor()->handleAlternativeTextUIResult(text); 6411 } 6412 #endif 6413 6414 #if USE(DICTATION_ALTERNATIVES) 6415 - (void)_getWebCoreDictationAlternatives:(Vector<DictationAlternative>&)alternatives fromTextAlternatives:(const Vector<TextAlternativeWithRange>&)alternativesWithRange 6416 { 6417 for (size_t i = 0; i < alternativesWithRange.size(); ++i) { 6418 const TextAlternativeWithRange& alternativeWithRange = alternativesWithRange[i]; 6419 uint64_t dictationContext = _private->m_alternativeTextUIController->addAlternatives(alternativeWithRange.alternatives); 6420 if (dictationContext) 6421 alternatives.append(DictationAlternative(alternativeWithRange.range.location, alternativeWithRange.range.length, dictationContext)); 6422 } 6423 } 6424 6425 - (void)_showDictationAlternativeUI:(const WebCore::FloatRect&)boundingBoxOfDictatedText forDictationContext:(uint64_t)dictationContext 6426 { 6427 _private->m_alternativeTextUIController->showAlternatives(self, [self _convertRectFromRootView:boundingBoxOfDictatedText], dictationContext, ^(NSString* acceptedAlternative) { 6428 [self handleAcceptedAlternativeText:acceptedAlternative]; 6429 }); 6430 } 6431 6432 - (void)_dismissDictationAlternativeUI 6433 { 6434 _private->m_alternativeTextUIController->dismissAlternatives(); 6435 } 6436 6437 - (void)_removeDictationAlternatives:(uint64_t)dictationContext 6438 { 6439 _private->m_alternativeTextUIController->removeAlternatives(dictationContext); 6440 } 6441 6442 - (Vector<String>)_dictationAlternatives:(uint64_t)dictationContext 6443 { 6444 return _private->m_alternativeTextUIController->alternativesForContext(dictationContext); 6445 } 6446 #endif 6447 6413 6448 - (NSPoint)_convertPointFromRootView:(NSPoint)point 6414 6449 { -
trunk/Source/WebKit/mac/WebView/WebViewData.h
r108409 r120357 30 30 #import "WebTypesInternal.h" 31 31 #import "WebDelegateImplementationCaching.h" 32 #import <WebCore/AlternativeTextClient.h> 32 33 #import <WebCore/LayerFlushScheduler.h> 33 34 #import <WebCore/LayerFlushSchedulerClient.h> … … 39 40 40 41 namespace WebCore { 41 class HistoryItem; 42 class Page; 42 class AlternativeTextUIController; 43 class HistoryItem; 44 class Page; 43 45 } 44 46 … … 201 203 202 204 float customDeviceScaleFactor; 205 206 #if USE(DICTATION_ALTERNATIVES) 207 OwnPtr<WebCore::AlternativeTextUIController> m_alternativeTextUIController; 208 #endif 203 209 } 204 210 @end -
trunk/Source/WebKit/mac/WebView/WebViewData.mm
r105552 r120357 32 32 #import "WebKitLogging.h" 33 33 #import "WebPreferenceKeysPrivate.h" 34 #import <WebCore/AlternativeTextUIController.h> 34 35 #import <WebCore/WebCoreObjCExtras.h> 35 36 #import <WebCore/HistoryItem.h> … … 101 102 pluginDatabaseClientCount++; 102 103 104 #if USE(DICTATION_ALTERNATIVES) 105 m_alternativeTextUIController = adoptPtr(new WebCore::AlternativeTextUIController); 106 #endif 107 103 108 return self; 104 109 } -
trunk/Source/WebKit/mac/WebView/WebViewInternal.h
r104181 r120357 35 35 36 36 #ifdef __cplusplus 37 #import <WebCore/AlternativeTextClient.h> 37 38 #import <WebCore/FindOptions.h> 39 #import <WebCore/FloatRect.h> 40 #import <WebCore/TextAlternativeWithRange.h> 38 41 #import <WebCore/WebCoreKeyboardUIMode.h> 39 42 40 43 #include <wtf/Forward.h> 44 #include <wtf/RetainPtr.h> 41 45 42 46 namespace WebCore { 43 class Element; 44 class Frame; 45 class HistoryItem; 46 class KURL; 47 class KeyboardEvent; 48 class Page; 49 class RenderBox; 50 class Node; 47 class Element; 48 class Event; 49 class Frame; 50 class HistoryItem; 51 class KURL; 52 class KeyboardEvent; 53 class Page; 54 class RenderBox; 55 class Node; 56 struct DictationAlternative; 51 57 } 52 58 #endif … … 59 65 60 66 WebCore::FindOptions coreOptions(WebFindOptions options); 67 68 #if USE(DICTATION_ALTERNATIVES) 69 OBJC_CLASS NSTextAlternatives; 70 #endif 61 71 62 72 @interface WebView (WebViewEditingExtras) … … 94 104 #if ENABLE(GLIB_SUPPORT) 95 105 - (void)_scheduleGlibContextIterations; 106 #endif 107 108 #if USE(AUTOCORRECTION_PANEL) 109 - (void)handleAcceptedAlternativeText:(NSString*)text; 110 #endif 111 112 #if USE(DICTATION_ALTERNATIVES) 113 - (void)_getWebCoreDictationAlternatives:(Vector<WebCore::DictationAlternative>&)alternatives fromTextAlternatives:(const Vector<WebCore::TextAlternativeWithRange>&)alternativesWithRange; 114 - (void)_showDictationAlternativeUI:(const WebCore::FloatRect&)boundingBoxOfDictatedText forDictationContext:(uint64_t)dictationContext; 115 - (void)_dismissDictationAlternativeUI; 116 - (void)_removeDictationAlternatives:(uint64_t)dictationContext; 117 - (Vector<String>)_dictationAlternatives:(uint64_t)dictationContext; 96 118 #endif 97 119 -
trunk/Source/WebKit/mac/WebView/WebViewPrivate.h
r117460 r120357 688 688 - (void)toggleAutomaticSpellingCorrection:(id)sender; 689 689 #endif 690 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)691 - (void)handleCorrectionPanelResult:(NSString*)result;692 #endif693 690 @end 694 691 -
trunk/Source/WebKit2/ChangeLog
r120329 r120357 1 2012-06-14 Jia Pu <jpu@apple.com> 2 3 Mark text with text alternative with blue underline. 4 https://bugs.webkit.org/show_bug.cgi?id=83047 5 6 Reviewed by Enrica Casucci. 7 8 Changes in WebKit2 include implementation of new functions declared in AlternativeTextClient, 9 and logic for calling Editor::insertDictatedText() instead of Editor::insertText() when there's 10 alternatives attached to the input string. 11 12 * Shared/API/c/WKContextMenuItemTypes.h: 13 * Shared/API/c/WKSharedAPICast.h: 14 * Shared/WebCoreArgumentCoders.cpp: 15 * Shared/WebCoreArgumentCoders.h: 16 * UIProcess/API/mac/PageClientImpl.h: 17 * UIProcess/API/mac/PageClientImpl.mm: 18 (WebKit::PageClientImpl::PageClientImpl): 19 (WebKit::PageClientImpl::pageClosed): 20 (WebKit::PageClientImpl::addDictationAlternatives): 21 (WebKit::PageClientImpl::removeDictationAlternatives): 22 (WebKit::PageClientImpl::showDictationAlternativeUI): 23 (WebKit::PageClientImpl::dictationAlternatives): 24 (WebKit::PageClientImpl::dismissDictationAlternativeUI): 25 * UIProcess/API/mac/WKView.mm: 26 (-[WKView insertText:replacementRange:]): 27 (-[WKView validAttributesForMarkedText]): 28 (-[WKView handleAcceptedAlternativeText:]): 29 * UIProcess/API/mac/WKViewInternal.h: 30 * UIProcess/PageClient.h: 31 * UIProcess/WebPageProxy.cpp: 32 (WebKit::WebPageProxy::showDictationAlternativeUI): 33 (WebKit::WebPageProxy::dismissDictationAlternativeUI): 34 (WebKit::WebPageProxy::removeDictationAlternatives): 35 (WebKit::WebPageProxy::dictationAlternatives): 36 * UIProcess/WebPageProxy.h: 37 * UIProcess/WebPageProxy.messages.in: 38 * UIProcess/mac/CorrectionPanel.mm: 39 (correctionIndicatorType): 40 (WebKit::CorrectionPanel::handleAcceptedReplacement): 41 * UIProcess/mac/WebPageProxyMac.mm: 42 (WebKit::WebPageProxy::insertDictatedText): 43 * WebProcess/WebCoreSupport/WebAlternativeTextClient.h: 44 (WebAlternativeTextClient): 45 * WebProcess/WebCoreSupport/mac/WebAlternativeTextClient.cpp: 46 (WebKit::WebAlternativeTextClient::showCorrectionAlternative): 47 (WebKit::WebAlternativeTextClient::dismissAlternative): 48 (WebKit::WebAlternativeTextClient::dismissAlternativeSoon): 49 (WebKit::WebAlternativeTextClient::recordAutocorrectionResponse): 50 (WebKit::WebAlternativeTextClient::removeDictationAlternatives): 51 (WebKit::WebAlternativeTextClient::showDictationAlternativeUI): 52 (WebKit::WebAlternativeTextClient::dismissDictationAlternativeUI): 53 (WebKit::WebAlternativeTextClient::dictationAlternatives): 54 * WebProcess/WebPage/WebPage.h: 55 * WebProcess/WebPage/WebPage.messages.in: 56 * WebProcess/WebPage/mac/WebPageMac.mm: 57 (WebKit::WebPage::insertDictatedText): 58 1 59 2012-06-13 Andreas Kling <kling@webkit.org> 2 60 -
trunk/Source/WebKit2/Shared/API/c/WKContextMenuItemTypes.h
r95901 r120357 89 89 kWKContextMenuItemTagPDFSinglePageScrolling, 90 90 kWKContextMenuItemTagPDFFacingPagesScrolling, 91 kWKContextMenuItemTagDictationAlternative, 91 92 kWKContextMenuItemTagInspectElement, 92 93 kWKContextMenuItemTagTextDirectionMenu, -
trunk/Source/WebKit2/Shared/API/c/WKSharedAPICast.h
r105855 r120357 415 415 case WebCore::ContextMenuItemTagPDFFacingPagesScrolling: 416 416 return kWKContextMenuItemTagPDFFacingPagesScrolling; 417 case WebCore::ContextMenuItemTagDictationAlternative: 418 return kWKContextMenuItemTagDictationAlternative; 417 419 #if ENABLE(INSPECTOR) 418 420 case WebCore::ContextMenuItemTagInspectElement: … … 593 595 case kWKContextMenuItemTagPDFFacingPagesScrolling: 594 596 return WebCore::ContextMenuItemTagPDFFacingPagesScrolling; 597 case kWKContextMenuItemTagDictationAlternative: 598 return WebCore::ContextMenuItemTagDictationAlternative; 595 599 #if ENABLE(INSPECTOR) 596 600 case kWKContextMenuItemTagInspectElement: -
trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp
r118697 r120357 32 32 #include <WebCore/Cursor.h> 33 33 #include <WebCore/DatabaseDetails.h> 34 #include <WebCore/DictationAlternative.h> 34 35 #include <WebCore/DragSession.h> 35 36 #include <WebCore/Editor.h> … … 526 527 } 527 528 529 void ArgumentCoder<DictationAlternative>::encode(ArgumentEncoder* encoder, const DictationAlternative& dictationAlternative) 530 { 531 encoder->encode(dictationAlternative.rangeStart); 532 encoder->encode(dictationAlternative.rangeLength); 533 encoder->encode(dictationAlternative.dictationContext); 534 } 535 536 bool ArgumentCoder<DictationAlternative>::decode(ArgumentDecoder* decoder, DictationAlternative& dictationAlternative) 537 { 538 if (!decoder->decode(dictationAlternative.rangeStart)) 539 return false; 540 if (!decoder->decode(dictationAlternative.rangeLength)) 541 return false; 542 if (!decoder->decode(dictationAlternative.dictationContext)) 543 return false; 544 return true; 545 } 546 528 547 529 548 void ArgumentCoder<FileChooserSettings>::encode(ArgumentEncoder* encoder, const FileChooserSettings& settings) -
trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h
r118697 r120357 51 51 class ResourceResponse; 52 52 struct CompositionUnderline; 53 struct DictationAlternative; 53 54 struct DragSession; 54 55 struct FileChooserSettings; … … 210 211 }; 211 212 213 template<> struct ArgumentCoder<WebCore::DictationAlternative> { 214 static void encode(ArgumentEncoder*, const WebCore::DictationAlternative&); 215 static bool decode(ArgumentDecoder*, WebCore::DictationAlternative&); 216 }; 217 212 218 template<> struct ArgumentCoder<WebCore::FileChooserSettings> { 213 219 static void encode(ArgumentEncoder*, const WebCore::FileChooserSettings&); -
trunk/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h
r120021 r120357 34 34 @class WKView; 35 35 36 namespace WebCore { 37 class AlternativeTextUIController; 38 } 39 36 40 namespace WebKit { 37 38 41 class FindIndicatorWindow; 39 42 … … 131 134 virtual WKView* wkView() const { return m_wkView; } 132 135 136 #if USE(DICTATION_ALTERNATIVES) 137 virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&); 138 virtual void removeDictationAlternatives(uint64_t dictationContext); 139 virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext); 140 virtual void dismissDictationAlternativeUI(); 141 virtual Vector<String> dictationAlternatives(uint64_t dictationContext); 142 #endif 143 133 144 WKView* m_wkView; 134 145 RetainPtr<WKEditorUndoTargetObjC> m_undoTarget; 135 146 #if USE(AUTOCORRECTION_PANEL) 136 147 CorrectionPanel m_correctionPanel; 148 #endif 149 #if USE(DICTATION_ALTERNATIVES) 150 OwnPtr<WebCore::AlternativeTextUIController> m_alternativeTextUIController; 137 151 #endif 138 152 }; -
trunk/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm
r120021 r120357 27 27 #import "PageClientImpl.h" 28 28 29 #if USE(DICTATION_ALTERNATIVES) 30 #import <AppKit/NSTextAlternatives.h> 31 #endif 29 32 #import "ColorSpaceData.h" 30 33 #import "DataReference.h" … … 39 42 #import "WebEditCommandProxy.h" 40 43 #import "WebPopupMenuProxyMac.h" 44 #import <WebCore/AlternativeTextUIController.h> 41 45 #import <WebCore/BitmapImage.h> 42 46 #import <WebCore/Cursor.h> … … 124 128 : m_wkView(wkView) 125 129 , m_undoTarget(AdoptNS, [[WKEditorUndoTargetObjC alloc] init]) 130 #if USE(DICTATION_ALTERNATIVES) 131 , m_alternativeTextUIController(adoptPtr(new AlternativeTextUIController)) 132 #endif 126 133 { 127 134 } … … 216 223 [m_wkView _processDidCrash]; 217 224 } 218 225 219 226 void PageClientImpl::pageClosed() 220 227 { 221 228 [m_wkView _pageClosed]; 229 #if USE(DICTATION_ALTERNATIVES) 230 m_alternativeTextUIController->clear(); 231 #endif 222 232 } 223 233 … … 536 546 } 537 547 548 #if USE(DICTATION_ALTERNATIVES) 549 uint64_t PageClientImpl::addDictationAlternatives(const RetainPtr<NSTextAlternatives>& alternatives) 550 { 551 return m_alternativeTextUIController->addAlternatives(alternatives); 552 } 553 554 void PageClientImpl::removeDictationAlternatives(uint64_t dictationContext) 555 { 556 m_alternativeTextUIController->removeAlternatives(dictationContext); 557 } 558 559 void PageClientImpl::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 560 { 561 if (!isViewVisible() || !isViewInWindow()) 562 return; 563 m_alternativeTextUIController->showAlternatives(m_wkView, boundingBoxOfDictatedText, dictationContext, ^(NSString* acceptedAlternative){ 564 [m_wkView handleAcceptedAlternativeText:acceptedAlternative]; 565 }); 566 } 567 568 Vector<String> PageClientImpl::dictationAlternatives(uint64_t dictationContext) 569 { 570 return m_alternativeTextUIController->alternativesForContext(dictationContext); 571 } 572 573 void PageClientImpl::dismissDictationAlternativeUI() 574 { 575 m_alternativeTextUIController->dismissAlternatives(); 576 } 577 #endif 578 538 579 } // namespace WebKit -
trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm
r120021 r120357 26 26 #import "config.h" 27 27 #import "WKView.h" 28 29 #if USE(DICTATION_ALTERNATIVES) 30 #import <AppKit/NSTextAlternatives.h> 31 #import <AppKit/NSAttributedString.h> 32 #endif 28 33 29 34 #import "AttributedString.h" … … 75 80 #import <WebCore/RunLoop.h> 76 81 #import <WebCore/SharedBuffer.h> 82 #import <WebCore/TextAlternativeWithRange.h> 77 83 #import <WebCore/WebCoreNSStringExtras.h> 78 84 #import <WebCore/FileSystem.h> … … 1178 1184 bool isFromInputMethod = _data->_page->editorState().hasComposition; 1179 1185 1186 Vector<TextAlternativeWithRange> dictationAlternatives; 1187 1180 1188 if (isAttributedString) { 1189 #if USE(DICTATION_ALTERNATIVES) 1190 collectDictationTextAlternatives(string, dictationAlternatives); 1191 #endif 1181 1192 // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data. 1182 1193 text = [string string]; … … 1200 1211 String eventText = text; 1201 1212 eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore 1202 bool eventHandled = _data->_page->insertText(eventText, replacementRange.location, NSMaxRange(replacementRange)); 1213 bool eventHandled; 1214 if (!dictationAlternatives.isEmpty()) 1215 eventHandled = _data->_page->insertDictatedText(eventText, replacementRange.location, NSMaxRange(replacementRange), dictationAlternatives); 1216 else 1217 eventHandled = _data->_page->insertText(eventText, replacementRange.location, NSMaxRange(replacementRange)); 1203 1218 1204 1219 if (parameters) … … 1452 1467 validAttributes = [[NSArray alloc] initWithObjects: 1453 1468 NSUnderlineStyleAttributeName, NSUnderlineColorAttributeName, 1454 NSMarkedClauseSegmentAttributeName, nil]; 1469 NSMarkedClauseSegmentAttributeName, 1470 #if USE(DICTATION_ALTERNATIVES) 1471 NSTextAlternativesAttributeName, 1472 #endif 1473 nil]; 1455 1474 // NSText also supports the following attributes, but it's 1456 1475 // hard to tell which are really required for text input to … … 2907 2926 } 2908 2927 2909 - (void)handle CorrectionPanelResult:(NSString*)result2910 { 2911 _data->_page->handleAlternativeTextUIResult( result);2928 - (void)handleAcceptedAlternativeText:(NSString*)text 2929 { 2930 _data->_page->handleAlternativeTextUIResult(text); 2912 2931 } 2913 2932 -
trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h
r120021 r120357 100 100 101 101 - (NSInteger)spellCheckerDocumentTag; 102 - (void)handleCorrectionPanelResult:(NSString*)result; 102 - (void)handleAcceptedAlternativeText:(NSString*)text; 103 103 104 @end -
trunk/Source/WebKit2/UIProcess/PageClient.h
r120021 r120357 39 39 #if USE(APPKIT) 40 40 OBJC_CLASS WKView; 41 OBJC_CLASS NSTextAlternatives; 41 42 #endif 42 43 #endif … … 202 203 #if USE(APPKIT) 203 204 virtual WKView* wkView() const = 0; 204 #endif 205 #endif 205 #if USE(DICTATION_ALTERNATIVES) 206 virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&) = 0; 207 virtual void removeDictationAlternatives(uint64_t dictationContext) = 0; 208 virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) = 0; 209 virtual void dismissDictationAlternativeUI() = 0; 210 virtual Vector<String> dictationAlternatives(uint64_t dictationContext) = 0; 211 #endif // USE(DICTATION_ALTERNATIVES) 212 #endif // USE(APPKIT) 213 #endif // PLATFORM(MAC) 206 214 207 215 virtual void didChangeScrollbarsForMainFrame() const = 0; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r120301 r120357 3841 3841 #endif 3842 3842 } 3843 3844 #if USE(DICTATION_ALTERNATIVES) 3845 void WebPageProxy::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 3846 { 3847 m_pageClient->showDictationAlternativeUI(boundingBoxOfDictatedText, dictationContext); 3848 } 3849 3850 void WebPageProxy::dismissDictationAlternativeUI() 3851 { 3852 m_pageClient->dismissDictationAlternativeUI(); 3853 } 3854 3855 void WebPageProxy::removeDictationAlternatives(uint64_t dictationContext) 3856 { 3857 m_pageClient->removeDictationAlternatives(dictationContext); 3858 } 3859 3860 void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<String>& result) 3861 { 3862 result = m_pageClient->dictationAlternatives(dictationContext); 3863 } 3864 #endif 3865 3843 3866 #endif // PLATFORM(MAC) 3844 3867 -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r120301 r120357 59 59 #include "WebResourceLoadClient.h" 60 60 #include "WebUIClient.h" 61 #include <WebCore/AlternativeTextClient.h> 62 #include <WebCore/DragActions.h> 63 #include <WebCore/DragSession.h> 61 64 #include <WebCore/HitTestResult.h> 62 65 #include <WebCore/Page.h> … … 96 99 class ProtectionSpace; 97 100 struct FileChooserSettings; 101 struct TextAlternativeWithRange; 98 102 struct TextCheckingResult; 99 103 struct ViewportAttributes; … … 362 366 void cancelComposition(); 363 367 bool insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); 368 bool insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives); 364 369 void getMarkedRange(uint64_t& location, uint64_t& length); 365 370 void getSelectedRange(uint64_t& location, uint64_t& length); … … 922 927 void recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString); 923 928 #endif // !defined(BUILDING_ON_SNOW_LEOPARD) 929 930 #if USE(DICTATION_ALTERNATIVES) 931 void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext); 932 void dismissDictationAlternativeUI(); 933 void removeDictationAlternatives(uint64_t dictationContext); 934 void dictationAlternatives(uint64_t dictationContext, Vector<String>& result); 935 #endif 924 936 #endif // PLATFORM(MAC) 925 937 -
trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in
r120301 r120357 290 290 #endif 291 291 292 #if USE(DICTATION_ALTERNATIVES) 293 ShowDictationAlternativeUI(WebCore::FloatRect boundingBoxOfDictatedText, uint64_t dictationContext) 294 DismissDictationAlternativeUI() 295 RemoveDictationAlternatives(uint64_t dictationContext) 296 DictationAlternatives(uint64_t dictationContext) -> (Vector<String> alternatives) 297 #endif 298 292 299 #if PLATFORM(WIN) 293 300 # Windows 7 Gesture Messages -
trunk/Source/WebKit2/UIProcess/mac/CorrectionPanel.mm
r119349 r120357 44 44 case AlternativeTextTypeSpellingSuggestions: 45 45 return NSCorrectionIndicatorTypeGuesses; 46 case AlternativeTextTypeDictationAlternatives: 47 ASSERT_NOT_REACHED(); 48 break; 46 49 } 47 50 ASSERT_NOT_REACHED(); … … 139 142 } 140 143 141 [m_view.get() handle CorrectionPanelResult:acceptedReplacement];144 [m_view.get() handleAcceptedAlternativeText:acceptedReplacement]; 142 145 m_view.clear(); 143 146 if (acceptedReplacement) -
trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm
r120021 r120357 40 40 #import "WebPageMessages.h" 41 41 #import "WebProcessProxy.h" 42 #import <WebCore/DictationAlternative.h> 42 43 #import <WebCore/SharedBuffer.h> 44 #import <WebCore/TextAlternativeWithRange.h> 43 45 #import <WebKitSystemInterface.h> 44 46 #import <wtf/text/StringConcatenate.h> … … 200 202 } 201 203 204 bool WebPageProxy::insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<TextAlternativeWithRange>& dictationAlternativesWithRange) 205 { 206 #if USE(DICTATION_ALTERNATIVES) 207 if (dictationAlternativesWithRange.isEmpty()) 208 return insertText(text, replacementRangeStart, replacementRangeEnd); 209 210 if (!isValid()) 211 return true; 212 213 Vector<DictationAlternative> dictationAlternatives; 214 215 for (size_t i = 0; i < dictationAlternativesWithRange.size(); ++i) { 216 const TextAlternativeWithRange& alternativeWithRange = dictationAlternativesWithRange[i]; 217 uint64_t dictationContext = m_pageClient->addDictationAlternatives(alternativeWithRange.alternatives); 218 if (dictationContext) 219 dictationAlternatives.append(DictationAlternative(alternativeWithRange.range.location, alternativeWithRange.range.length, dictationContext)); 220 } 221 222 if (dictationAlternatives.isEmpty()) 223 return insertText(text, replacementRangeStart, replacementRangeEnd); 224 225 bool handled = true; 226 process()->sendSync(Messages::WebPage::InsertDictatedText(text, replacementRangeStart, replacementRangeEnd, dictationAlternatives), Messages::WebPage::InsertDictatedText::Reply(handled, m_editorState), m_pageID); 227 return handled; 228 #else 229 return insertText(text, replacementRangeStart, replacementRangeEnd); 230 #endif 231 } 232 202 233 void WebPageProxy::getMarkedRange(uint64_t& location, uint64_t& length) 203 234 { -
trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebAlternativeTextClient.h
r115369 r120357 39 39 virtual ~WebAlternativeTextClient(); 40 40 virtual void pageDestroyed() OVERRIDE; 41 #if USE(AUTOCORRECTION_PANEL) 41 42 virtual void showCorrectionAlternative(WebCore::AlternativeTextType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) OVERRIDE; 42 43 virtual void dismissAlternative(WebCore::ReasonForDismissingAlternativeText) OVERRIDE; 43 44 virtual String dismissAlternativeSoon(WebCore::ReasonForDismissingAlternativeText) OVERRIDE; 44 45 virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString) OVERRIDE; 46 #endif 47 #if USE(DICTATION_ALTERNATIVES) 48 virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) OVERRIDE; 49 virtual void dismissDictationAlternativeUI() OVERRIDE; 50 virtual void removeDictationAlternatives(uint64_t dictationContext) OVERRIDE; 51 virtual Vector<String> dictationAlternatives(uint64_t dictationContext) OVERRIDE; 52 #endif 45 53 private: 46 54 WebPage *m_page; -
trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebAlternativeTextClient.cpp
r115369 r120357 52 52 } 53 53 54 #if USE(AUTOCORRECTION_PANEL) 54 55 void WebAlternativeTextClient::showCorrectionAlternative(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) 55 56 { 56 #if USE(AUTOCORRECTION_PANEL)57 57 m_page->send(Messages::WebPageProxy::ShowCorrectionPanel(type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings)); 58 #endif59 58 } 60 59 61 60 void WebAlternativeTextClient::dismissAlternative(ReasonForDismissingAlternativeText reason) 62 61 { 63 #if USE(AUTOCORRECTION_PANEL)64 62 m_page->send(Messages::WebPageProxy::DismissCorrectionPanel(reason)); 65 #endif66 63 } 67 64 … … 69 66 { 70 67 String result; 71 #if USE(AUTOCORRECTION_PANEL)72 68 m_page->sendSync(Messages::WebPageProxy::DismissCorrectionPanelSoon(reason), Messages::WebPageProxy::DismissCorrectionPanelSoon::Reply(result)); 73 #endif74 69 return result; 75 70 } … … 77 72 void WebAlternativeTextClient::recordAutocorrectionResponse(AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString) 78 73 { 79 #if USE(AUTOCORRECTION_PANEL)80 74 m_page->send(Messages::WebPageProxy::RecordAutocorrectionResponse(responseType, replacedString, replacementString)); 75 } 76 #endif 77 78 #if USE(DICTATION_ALTERNATIVES) 79 void WebAlternativeTextClient::removeDictationAlternatives(uint64_t dictationContext) 80 { 81 m_page->send(Messages::WebPageProxy::RemoveDictationAlternatives(dictationContext)); 82 } 83 84 void WebAlternativeTextClient::showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) 85 { 86 m_page->send(Messages::WebPageProxy::ShowDictationAlternativeUI(boundingBoxOfDictatedText, dictationContext)); 87 } 88 89 void WebAlternativeTextClient::dismissDictationAlternativeUI() 90 { 91 m_page->send(Messages::WebPageProxy::DismissDictationAlternativeUI()); 92 } 93 94 Vector<String> WebAlternativeTextClient::dictationAlternatives(uint64_t dictationContext) 95 { 96 Vector<String> result; 97 m_page->sendSync(Messages::WebPageProxy::DictationAlternatives(dictationContext), Messages::WebPageProxy::DictationAlternatives::Reply(result)); 98 return result; 99 } 81 100 #endif 82 101 } 83 84 } -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h
r120262 r120357 49 49 #include "ShareableBitmap.h" 50 50 #include "WebUndoStep.h" 51 #include <WebCore/DictationAlternative.h> 51 52 #include <WebCore/DragData.h> 52 53 #include <WebCore/Editor.h> … … 420 421 void acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&, bool& result); 421 422 bool performNonEditingBehaviorForSelector(const String&); 422 423 void insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::DictationAlternative>& dictationAlternativeLocations, bool& handled, EditorState& newState); 423 424 #elif PLATFORM(WIN) 424 425 void confirmComposition(const String& compositionString); … … 508 509 void unmarkAllMisspellings(); 509 510 void unmarkAllBadGrammar(); 510 511 511 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) 512 512 void handleAlternativeTextUIResult(const String&); -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
r120262 r120357 251 251 ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result) 252 252 AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result) 253 InsertDictatedText(WTF::String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, WTF::Vector<WebCore::DictationAlternative> dictationAlternatives) -> (bool handled, WebKit::EditorState newState) 253 254 #endif 254 255 #if PLATFORM(WIN) -
trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
r117695 r120357 291 291 } 292 292 293 void WebPage::insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::DictationAlternative>& dictationAlternativeLocations, bool& handled, EditorState& newState) 294 { 295 Frame* frame = m_page->focusController()->focusedOrMainFrame(); 296 297 if (replacementRangeStart != NSNotFound) { 298 RefPtr<Range> replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart)); 299 if (replacementRange) 300 frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); 301 } 302 303 ASSERT(!frame->editor()->hasComposition()); 304 handled = frame->editor()->insertDictatedText(text, dictationAlternativeLocations, m_keyboardEventBeingInterpreted); 305 newState = editorState(); 306 } 307 293 308 void WebPage::getMarkedRange(uint64_t& location, uint64_t& length) 294 309 { -
trunk/Tools/ChangeLog
r120355 r120357 1 2012-06-14 Jia Pu <jpu@apple.com> 2 3 Mark text with text alternative with blue underline. 4 https://bugs.webkit.org/show_bug.cgi?id=83047 5 6 Reviewed by NOBODY Enrica Casucci. 7 8 * DumpRenderTree/mac/TextInputController.m: 9 (+[TextInputController isSelectorExcludedFromWebScript:]): 10 (+[TextInputController webScriptNameForSelector:]): 11 (-[TextInputController dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:]): 12 1 13 2012-06-14 Sheriff Bot <webkit.review.bot@gmail.com> 2 14 -
trunk/Tools/DumpRenderTree/mac/TextInputController.m
r69952 r120357 32 32 #import "DumpRenderTreeMac.h" 33 33 #import <AppKit/NSInputManager.h> 34 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) 35 #define SUPPORT_DICTATION_ALTERNATIVES 36 #import <AppKit/NSTextAlternatives.h> 37 #endif 34 38 #import <WebKit/WebDocument.h> 35 39 #import <WebKit/WebFrame.h> … … 171 175 || aSelector == @selector(validAttributesForMarkedText) 172 176 || aSelector == @selector(attributedStringWithString:) 173 || aSelector == @selector(setInputMethodHandler:)) 177 || aSelector == @selector(setInputMethodHandler:) 178 || aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:)) 174 179 return NO; 175 180 return YES; … … 195 200 return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput 196 201 else if (aSelector == @selector(setInputMethodHandler:)) 197 return @"setInputMethodHandler"; 202 return @"setInputMethodHandler"; 203 else if (aSelector == @selector(dictatedStringWithPrimaryString:alternative:alternativeOffset:alternativeLength:)) 204 return @"makeDictatedString"; 198 205 199 206 return nil; … … 374 381 { 375 382 return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease]; 383 } 384 385 - (NSMutableAttributedString*)dictatedStringWithPrimaryString:(NSString*)aString alternative:(NSString*)alternative alternativeOffset:(int)offset alternativeLength:(int)length 386 { 387 #if defined(SUPPORT_DICTATION_ALTERNATIVES) 388 NSMutableAttributedString* dictatedString = [self attributedStringWithString:aString]; 389 NSRange rangeWithAlternative = NSMakeRange((NSUInteger)offset, (NSUInteger)length); 390 NSString* subStringWithAlternative = [aString substringWithRange:rangeWithAlternative]; 391 if (!subStringWithAlternative) 392 return nil; 393 394 NSTextAlternatives* alternativeObject = [[[NSTextAlternatives alloc] initWithPrimaryString:subStringWithAlternative alternativeStrings:[NSArray arrayWithObject:alternative]] autorelease]; 395 if (!alternativeObject) 396 return nil; 397 398 [dictatedString addAttribute:NSTextAlternativesAttributeName value:alternativeObject range:rangeWithAlternative]; 399 400 return dictatedString; 401 #else 402 return nil; 403 #endif 376 404 } 377 405
Note: See TracChangeset
for help on using the changeset viewer.