Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <QuartzCore/QuartzCore.h> | 5 #include <QuartzCore/QuartzCore.h> |
| 6 | 6 |
| 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
| 8 | 8 |
| 9 #include "app/app_switches.h" | 9 #include "app/app_switches.h" |
| 10 #include "app/surface/io_surface_support_mac.h" | 10 #include "app/surface/io_surface_support_mac.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/mac/scoped_cftyperef.h" | 13 #include "base/mac/scoped_cftyperef.h" |
| 14 #import "base/mac/scoped_nsautorelease_pool.h" | 14 #import "base/mac/scoped_nsautorelease_pool.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #import "base/scoped_nsobject.h" | 16 #import "base/scoped_nsobject.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/sys_info.h" | 18 #include "base/sys_info.h" |
| 19 #include "base/sys_string_conversions.h" | 19 #include "base/sys_string_conversions.h" |
| 20 #import "chrome/browser/accessibility/browser_accessibility_cocoa.h" | 20 #import "chrome/browser/accessibility/browser_accessibility_cocoa.h" |
| 21 #include "chrome/browser/accessibility/browser_accessibility_state.h" | 21 #include "chrome/browser/accessibility/browser_accessibility_state.h" |
| 22 #include "chrome/browser/browser_thread.h" | 22 #include "chrome/browser/browser_thread.h" |
| 23 #include "chrome/browser/browser_trial.h" | 23 #include "chrome/browser/browser_trial.h" |
| 24 #include "chrome/browser/gpu_process_host.h" | 24 #include "chrome/browser/gpu_process_host.h" |
| 25 #include "chrome/browser/plugin_process_host.h" | 25 #include "chrome/browser/plugin_process_host.h" |
| 26 #include "chrome/browser/renderer_host/backing_store_mac.h" | 26 #include "chrome/browser/renderer_host/backing_store_mac.h" |
| 27 #include "chrome/browser/renderer_host/render_process_host.h" | 27 #include "chrome/browser/renderer_host/render_process_host.h" |
| 28 #include "chrome/browser/renderer_host/render_view_host.h" | 28 #include "chrome/browser/renderer_host/render_view_host.h" |
| 29 #include "chrome/browser/renderer_host/render_widget_host.h" | 29 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 30 #import "chrome/browser/renderer_host/text_input_client_mac.h" | |
| 30 #include "chrome/browser/spellchecker_platform_engine.h" | 31 #include "chrome/browser/spellchecker_platform_engine.h" |
| 31 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" | 32 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" |
| 32 #import "chrome/browser/ui/cocoa/view_id_util.h" | 33 #import "chrome/browser/ui/cocoa/view_id_util.h" |
| 33 #include "chrome/common/chrome_switches.h" | 34 #include "chrome/common/chrome_switches.h" |
| 34 #include "chrome/common/native_web_keyboard_event.h" | 35 #include "chrome/common/native_web_keyboard_event.h" |
| 35 #include "chrome/common/edit_command.h" | 36 #include "chrome/common/edit_command.h" |
| 36 #include "chrome/common/gpu_messages.h" | 37 #include "chrome/common/gpu_messages.h" |
| 37 #include "chrome/common/plugin_messages.h" | 38 #include "chrome/common/plugin_messages.h" |
| 38 #include "chrome/common/render_messages.h" | 39 #include "chrome/common/render_messages.h" |
| 39 #include "skia/ext/platform_canvas.h" | 40 #include "skia/ext/platform_canvas.h" |
| 40 #include "third_party/skia/include/core/SkColor.h" | 41 #include "third_party/skia/include/core/SkColor.h" |
| 41 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h" | 42 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h" |
| 42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 44 #include "ui/gfx/point.h" | |
| 43 #include "webkit/glue/webaccessibility.h" | 45 #include "webkit/glue/webaccessibility.h" |
| 44 #include "webkit/plugins/npapi/webplugin.h" | 46 #include "webkit/plugins/npapi/webplugin.h" |
| 45 #import "third_party/mozilla/ComplexTextInputPanel.h" | 47 #import "third_party/mozilla/ComplexTextInputPanel.h" |
| 46 | 48 |
| 47 using WebKit::WebInputEvent; | 49 using WebKit::WebInputEvent; |
| 48 using WebKit::WebInputEventFactory; | 50 using WebKit::WebInputEventFactory; |
| 49 using WebKit::WebMouseEvent; | 51 using WebKit::WebMouseEvent; |
| 50 using WebKit::WebMouseWheelEvent; | 52 using WebKit::WebMouseWheelEvent; |
| 51 | 53 |
| 52 static inline int ToWebKitModifiers(NSUInteger flags) { | 54 static inline int ToWebKitModifiers(NSUInteger flags) { |
| 53 int modifiers = 0; | 55 int modifiers = 0; |
| 54 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 56 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
| 55 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; | 57 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; |
| 56 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; | 58 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; |
| 57 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 59 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
| 58 return modifiers; | 60 return modifiers; |
| 59 } | 61 } |
| 60 | 62 |
| 61 @interface RenderWidgetHostViewCocoa (Private) | 63 // Private methods: |
| 64 @interface RenderWidgetHostViewCocoa () | |
| 65 @property(nonatomic, assign) NSRange selectedRange; | |
| 66 @property(nonatomic, assign) NSRange markedRange; | |
| 67 | |
| 62 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; | 68 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; |
| 63 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 69 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
| 64 - (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; | 70 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; |
| 65 - (void)cancelChildPopups; | 71 - (void)cancelChildPopups; |
| 66 - (void)checkForPluginImeCancellation; | 72 - (void)checkForPluginImeCancellation; |
| 67 @end | 73 @end |
| 68 | 74 |
| 69 // This API was published since 10.6. Provide the declaration so it can be | 75 // This API was published since 10.6. Provide the declaration so it can be |
| 70 // // called below when building with the 10.5 SDK. | 76 // // called below when building with the 10.5 SDK. |
| 71 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 | 77 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 |
| 72 @class NSTextInputContext; | 78 @class NSTextInputContext; |
| 73 @interface NSResponder (AppKitDetails) | 79 @interface NSResponder (AppKitDetails) |
| 74 - (NSTextInputContext *)inputContext; | 80 - (NSTextInputContext *)inputContext; |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 813 } | 819 } |
| 814 | 820 |
| 815 void RenderWidgetHostViewMac::ImeUpdateTextInputState( | 821 void RenderWidgetHostViewMac::ImeUpdateTextInputState( |
| 816 WebKit::WebTextInputType type, | 822 WebKit::WebTextInputType type, |
| 817 const gfx::Rect& caret_rect) { | 823 const gfx::Rect& caret_rect) { |
| 818 if (text_input_type_ != type) { | 824 if (text_input_type_ != type) { |
| 819 text_input_type_ = type; | 825 text_input_type_ = type; |
| 820 if (HasFocus()) | 826 if (HasFocus()) |
| 821 SetTextInputActive(true); | 827 SetTextInputActive(true); |
| 822 } | 828 } |
| 823 | |
| 824 // We need to convert the coordinate of the cursor rectangle sent from the | |
| 825 // renderer and save it. Our input method backend uses a coordinate system | |
| 826 // whose origin is the upper-left corner of this view. On the other hand, | |
| 827 // Cocoa uses a coordinate system whose origin is the lower-left corner of | |
| 828 // this view. So, we convert the cursor rectangle and save it. | |
| 829 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; | |
| 830 } | 829 } |
| 831 | 830 |
| 832 void RenderWidgetHostViewMac::ImeCancelComposition() { | 831 void RenderWidgetHostViewMac::ImeCancelComposition() { |
| 833 [cocoa_view_ cancelComposition]; | 832 [cocoa_view_ cancelComposition]; |
| 834 } | 833 } |
| 835 | 834 |
| 835 void RenderWidgetHostViewMac::ImeCompositionRangeChanged(int start, int end) { | |
|
jeremy
2011/02/21 09:19:47
Why are start & end signed? The arguments to NSMa
Robert Sesek
2011/02/24 23:26:52
WebRange uses int rather than uint, so that's why
| |
| 836 // The RangeChanged message is only sent with valid values. The current | |
| 837 // caret position (start == end) will be sent if there is no IME range. | |
| 838 [cocoa_view_ setMarkedRange:NSMakeRange(start, end - start)]; | |
| 839 } | |
| 840 | |
| 836 void RenderWidgetHostViewMac::DidUpdateBackingStore( | 841 void RenderWidgetHostViewMac::DidUpdateBackingStore( |
| 837 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, | 842 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
| 838 const std::vector<gfx::Rect>& copy_rects) { | 843 const std::vector<gfx::Rect>& copy_rects) { |
| 839 if (!is_hidden_) { | 844 if (!is_hidden_) { |
| 840 std::vector<gfx::Rect> rects(copy_rects); | 845 std::vector<gfx::Rect> rects(copy_rects); |
| 841 | 846 |
| 842 // Because the findbar might be open, we cannot use scrollRect:by: here. For | 847 // Because the findbar might be open, we cannot use scrollRect:by: here. For |
| 843 // now, simply mark all of scroll rect as dirty. | 848 // now, simply mark all of scroll rect as dirty. |
| 844 if (!scroll_rect.IsEmpty()) | 849 if (!scroll_rect.IsEmpty()) |
| 845 rects.push_back(scroll_rect); | 850 rects.push_back(scroll_rect); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 | 948 |
| 944 NSString* tooltip_nsstring = base::SysWideToNSString(display_text); | 949 NSString* tooltip_nsstring = base::SysWideToNSString(display_text); |
| 945 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; | 950 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; |
| 946 } | 951 } |
| 947 } | 952 } |
| 948 | 953 |
| 949 // | 954 // |
| 950 // RenderWidgetHostViewCocoa uses the stored selection text, | 955 // RenderWidgetHostViewCocoa uses the stored selection text, |
| 951 // which implements NSServicesRequests protocol. | 956 // which implements NSServicesRequests protocol. |
| 952 // | 957 // |
| 953 void RenderWidgetHostViewMac::SelectionChanged(const std::string& text) { | 958 void RenderWidgetHostViewMac::SelectionChanged(const std::string& text, |
| 959 int range_start, | |
| 960 int range_end) { | |
| 954 selected_text_ = text; | 961 selected_text_ = text; |
| 962 NSRange range = NSMakeRange(range_start, range_end - range_start); | |
| 963 if (range_start == 0 && range_end == 0) | |
| 964 range.location = NSNotFound; | |
| 965 [cocoa_view_ setSelectedRange:range]; | |
| 955 } | 966 } |
| 956 | 967 |
| 957 BackingStore* RenderWidgetHostViewMac::AllocBackingStore( | 968 BackingStore* RenderWidgetHostViewMac::AllocBackingStore( |
| 958 const gfx::Size& size) { | 969 const gfx::Size& size) { |
| 959 return new BackingStoreMac(render_widget_host_, size); | 970 return new BackingStoreMac(render_widget_host_, size); |
| 960 } | 971 } |
| 961 | 972 |
| 962 // Sets whether or not to accept first responder status. | 973 // Sets whether or not to accept first responder status. |
| 963 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { | 974 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { |
| 964 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; | 975 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 } else { | 1374 } else { |
| 1364 if (text_input_type_ == WebKit::WebTextInputTypePassword) | 1375 if (text_input_type_ == WebKit::WebTextInputTypePassword) |
| 1365 DisablePasswordInput(); | 1376 DisablePasswordInput(); |
| 1366 } | 1377 } |
| 1367 } | 1378 } |
| 1368 | 1379 |
| 1369 // RenderWidgetHostViewCocoa --------------------------------------------------- | 1380 // RenderWidgetHostViewCocoa --------------------------------------------------- |
| 1370 | 1381 |
| 1371 @implementation RenderWidgetHostViewCocoa | 1382 @implementation RenderWidgetHostViewCocoa |
| 1372 | 1383 |
| 1373 @synthesize caretRect = caretRect_; | 1384 @synthesize selectedRange = selectedRange_; |
| 1385 @synthesize markedRange = markedRange_; | |
| 1374 | 1386 |
| 1375 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1387 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| 1376 self = [super initWithFrame:NSZeroRect]; | 1388 self = [super initWithFrame:NSZeroRect]; |
| 1377 if (self) { | 1389 if (self) { |
| 1378 editCommand_helper_.reset(new RWHVMEditCommandHelper); | 1390 editCommand_helper_.reset(new RWHVMEditCommandHelper); |
| 1379 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1391 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
| 1380 | 1392 |
| 1381 renderWidgetHostView_.reset(r); | 1393 renderWidgetHostView_.reset(r); |
| 1382 canBeKeyView_ = YES; | 1394 canBeKeyView_ = YES; |
| 1383 takesFocusOnlyOnMouseDown_ = NO; | 1395 takesFocusOnlyOnMouseDown_ = NO; |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2433 NSUnderlineStyleAttributeName, | 2445 NSUnderlineStyleAttributeName, |
| 2434 NSUnderlineColorAttributeName, | 2446 NSUnderlineColorAttributeName, |
| 2435 NSMarkedClauseSegmentAttributeName, | 2447 NSMarkedClauseSegmentAttributeName, |
| 2436 NSTextInputReplacementRangeAttributeName, | 2448 NSTextInputReplacementRangeAttributeName, |
| 2437 nil]); | 2449 nil]); |
| 2438 } | 2450 } |
| 2439 return validAttributesForMarkedText_.get(); | 2451 return validAttributesForMarkedText_.get(); |
| 2440 } | 2452 } |
| 2441 | 2453 |
| 2442 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { | 2454 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { |
| 2443 NOTIMPLEMENTED(); | 2455 DCHECK([self window]); |
| 2444 return NSNotFound; | 2456 // |thePoint| is in screen coordinates, but needs to be converted to WebKit |
| 2457 // coordinates (upper left origin). Scroll offsets will be taken care of in | |
| 2458 // the renderer. | |
| 2459 thePoint = [[self window] convertScreenToBase:thePoint]; | |
| 2460 thePoint = [self convertPoint:thePoint fromView:nil]; | |
| 2461 thePoint.y = NSHeight([self frame]) - thePoint.y; | |
| 2462 | |
| 2463 NSUInteger point = | |
| 2464 TextInputClientMac::GetInstance()->GetCharacterIndexAtPoint( | |
| 2465 renderWidgetHostView_->render_widget_host_, | |
| 2466 gfx::Point(thePoint.x, thePoint.y)); | |
| 2467 NSLog(@"%s:%@ -> %d", _cmd, NSStringFromPoint(thePoint), point); | |
|
jeremy
2011/02/21 09:19:47
Remove NSLog? Also, below
Robert Sesek
2011/02/24 23:26:52
I'll do this for landing, but I'm still working on
| |
| 2468 return point; | |
| 2445 } | 2469 } |
| 2446 | 2470 |
| 2447 - (NSRect)firstRectForCharacterRange:(NSRange)theRange { | 2471 - (NSRect)firstRectForCharacterRange:(NSRange)theRange { |
| 2448 // An input method requests a cursor rectangle to display its candidate | 2472 NSRect rect = TextInputClientMac::GetInstance()->GetFirstRectForRange( |
| 2449 // window. | 2473 renderWidgetHostView_->render_widget_host_, theRange); |
| 2450 // Calculate the screen coordinate of the cursor rectangle saved in | |
| 2451 // RenderWidgetHostViewMac::ImeUpdateTextInputState() and send it to the | |
| 2452 // input method. | |
| 2453 // Since this window may be moved since we receive the cursor rectangle last | |
| 2454 // time we sent the cursor rectangle to the input method, so we should map | |
| 2455 // from the view coordinate to the screen coordinate every time when an input | |
| 2456 // method need it. | |
| 2457 NSRect resultRect = [self convertRect:caretRect_ toView:nil]; | |
| 2458 NSWindow* window = [self window]; | |
| 2459 if (window) | |
| 2460 resultRect.origin = [window convertBaseToScreen:resultRect.origin]; | |
| 2461 | 2474 |
| 2462 return resultRect; | 2475 // The returned rectangle is in WebKit coordinates (upper left origin), so |
| 2463 } | 2476 // flip the coordinate system and then convert it into screen coordinates for |
| 2464 | 2477 // return. |
| 2465 - (NSRange)selectedRange { | 2478 NSRect viewFrame = [self frame]; |
| 2466 // Return the selected range saved in the setMarkedText method. | 2479 rect.origin.y = NSHeight(viewFrame) - rect.origin.y; |
| 2467 return hasMarkedText_ ? selectedRange_ : NSMakeRange(NSNotFound, 0); | 2480 rect.origin.y -= rect.size.height; |
| 2481 rect = [self convertRectToBase:rect]; | |
| 2482 rect.origin = [[self window] convertBaseToScreen:rect.origin]; | |
| 2483 NSLog(@"%s:%@ -> %@", _cmd, NSStringFromRange(theRange), NSStringFromRect(rect )); | |
| 2484 return rect; | |
| 2468 } | 2485 } |
| 2469 | 2486 |
| 2470 - (NSRange)markedRange { | 2487 - (NSRange)markedRange { |
| 2471 // An input method calls this method to check if an application really has | 2488 // An input method calls this method to check if an application really has |
| 2472 // a text being composed when hasMarkedText call returns true. | 2489 // a text being composed when hasMarkedText call returns true. |
| 2473 // Returns the range saved in the setMarkedText method so the input method | 2490 // Returns the range saved in the setMarkedText method so the input method |
| 2474 // calls the setMarkedText method and we can update the composition node | 2491 // calls the setMarkedText method and we can update the composition node |
| 2475 // there. (When this method returns an empty range, the input method doesn't | 2492 // there. (When this method returns an empty range, the input method doesn't |
| 2476 // call the setMarkedText method.) | 2493 // call the setMarkedText method.) |
| 2494 NSLog(@"%s -> %@", _cmd, NSStringFromRange(markedRange_)); | |
| 2477 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); | 2495 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); |
| 2478 } | 2496 } |
| 2479 | 2497 |
| 2480 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)range { | 2498 - (NSAttributedString*)attributedSubstringFromRange:(NSRange)range { |
| 2481 // TODO(hbono): Even though many input method works without implementing | 2499 NSAttributedString* str = |
| 2482 // this method, we need to save a copy of the string in the setMarkedText | 2500 TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( |
| 2483 // method and create a NSAttributedString with the given range. | 2501 renderWidgetHostView_->render_widget_host_, range); |
| 2484 // http://crbug.com/37715 | 2502 NSLog(@"%s:%@ -> %@", _cmd, NSStringFromRange(range), [str string]); |
| 2485 return nil; | 2503 return str; |
| 2486 } | 2504 } |
| 2487 | 2505 |
| 2488 - (NSInteger)conversationIdentifier { | 2506 - (NSInteger)conversationIdentifier { |
| 2489 return reinterpret_cast<NSInteger>(self); | 2507 return reinterpret_cast<NSInteger>(self); |
| 2490 } | 2508 } |
| 2491 | 2509 |
| 2492 // Each RenderWidgetHostViewCocoa has its own input context, but we return | 2510 // Each RenderWidgetHostViewCocoa has its own input context, but we return |
| 2493 // nil when the caret is in non-editable content or password box to avoid | 2511 // nil when the caret is in non-editable content or password box to avoid |
| 2494 // making input methods do their work. | 2512 // making input methods do their work. |
| 2495 - (NSTextInputContext *)inputContext { | 2513 - (NSTextInputContext *)inputContext { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2534 } | 2552 } |
| 2535 | 2553 |
| 2536 - (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange { | 2554 - (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange { |
| 2537 // An input method updates the composition string. | 2555 // An input method updates the composition string. |
| 2538 // We send the given text and range to the renderer so it can update the | 2556 // We send the given text and range to the renderer so it can update the |
| 2539 // composition node of WebKit. | 2557 // composition node of WebKit. |
| 2540 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; | 2558 BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; |
| 2541 NSString* im_text = isAttributedString ? [string string] : string; | 2559 NSString* im_text = isAttributedString ? [string string] : string; |
| 2542 int length = [im_text length]; | 2560 int length = [im_text length]; |
| 2543 | 2561 |
| 2544 markedRange_ = NSMakeRange(0, length); | 2562 // |markedRange_| will get set on a callback from ImeSetComposition(). |
| 2545 selectedRange_ = newSelRange; | 2563 selectedRange_ = newSelRange; |
| 2546 markedText_ = base::SysNSStringToUTF16(im_text); | 2564 markedText_ = base::SysNSStringToUTF16(im_text); |
| 2547 hasMarkedText_ = (length > 0); | 2565 hasMarkedText_ = (length > 0); |
| 2548 | 2566 |
| 2549 underlines_.clear(); | 2567 underlines_.clear(); |
| 2550 if (isAttributedString) { | 2568 if (isAttributedString) { |
| 2551 ExtractUnderlines(string, &underlines_); | 2569 ExtractUnderlines(string, &underlines_); |
| 2552 } else { | 2570 } else { |
| 2553 // Use a thin black underline by default. | 2571 // Use a thin black underline by default. |
| 2554 underlines_.push_back( | 2572 underlines_.push_back( |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2826 if (!string) return NO; | 2844 if (!string) return NO; |
| 2827 | 2845 |
| 2828 // If the user is currently using an IME, confirm the IME input, | 2846 // If the user is currently using an IME, confirm the IME input, |
| 2829 // and then insert the text from the service, the same as TextEdit and Safari. | 2847 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2830 [self confirmComposition]; | 2848 [self confirmComposition]; |
| 2831 [self insertText:string]; | 2849 [self insertText:string]; |
| 2832 return YES; | 2850 return YES; |
| 2833 } | 2851 } |
| 2834 | 2852 |
| 2835 @end | 2853 @end |
| OLD | NEW |