Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| index 9500038092b8c8630da89909a8f4d2ae95452169..bdea5dba07454e58c31edc0e36a8044a6c2d0986 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| @@ -20,6 +20,7 @@ |
| #include "base/mac/sdk_forward_declarations.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/numerics/safe_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/sys_string_conversions.h" |
| @@ -1226,6 +1227,7 @@ void RenderWidgetHostViewMac::SelectionBoundsChanged( |
| const ViewHostMsg_SelectionBounds_Params& params) { |
| if (params.anchor_rect == params.focus_rect) |
| caret_rect_ = params.anchor_rect; |
| + first_selection_rect_ = params.anchor_rect; |
| } |
| void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) { |
| @@ -1446,16 +1448,26 @@ bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange( |
| TRACE_EVENT0("browser", |
| "RenderWidgetHostViewMac::GetFirstRectForCharacterRange"); |
| + const gfx::Range requested_range(range); |
| // If requested range is same as caret location, we can just return it. |
| - if (selection_range_.is_empty() && gfx::Range(range) == selection_range_) { |
| + if (selection_range_.is_empty() && requested_range == selection_range_) { |
| if (actual_range) |
| *actual_range = range; |
| *rect = NSRectFromCGRect(caret_rect_.ToCGRect()); |
| return true; |
| } |
| + if (composition_range_.is_empty()) { |
| + if (!selection_range_.Contains(requested_range)) |
| + return false; |
| + if (actual_range) |
| + *actual_range = selection_range_.ToNSRange(); |
| + *rect = NSRectFromCGRect(first_selection_rect_.ToCGRect()); |
| + return true; |
| + } |
| + |
| const gfx::Range request_range_in_composition = |
| - ConvertCharacterRangeToCompositionRange(gfx::Range(range)); |
| + ConvertCharacterRangeToCompositionRange(requested_range); |
| if (request_range_in_composition == gfx::Range::InvalidRange()) |
| return false; |
| @@ -2895,10 +2907,37 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. |
| if (actualRange) |
| *actualRange = range; |
| - NSAttributedString* str = |
| - TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( |
| - renderWidgetHostView_->render_widget_host_, range); |
| - return str; |
| + |
| + const gfx::Range requested_range(range); |
| + if (requested_range.is_reversed()) |
| + return nil; |
| + |
| + gfx::Range expected_range; |
| + const base::string16* expected_text; |
| + |
| + if (!renderWidgetHostView_->composition_range().is_empty()) { |
| + expected_text = &markedText_; |
| + expected_range = renderWidgetHostView_->composition_range(); |
| + } else { |
| + expected_text = &renderWidgetHostView_->selection_text(); |
| + size_t offset = renderWidgetHostView_->selection_text_offset(); |
| + expected_range = gfx::Range(offset, offset + expected_text->size()); |
| + } |
| + |
| + if (!expected_range.Contains(requested_range)) |
| + return nil; |
| + |
| + // Gets the raw bytes to avoid unnecessary string copies for generating |
| + // NSString. |
| + const base::char16* bytes = |
| + &(*expected_text)[requested_range.start() - expected_range.start()]; |
|
palmer
2015/09/02 20:17:22
I still don't understand this.
Shu Chen
2015/09/03 15:07:32
For example, expected_text == "hello world", expec
palmer
2015/09/03 23:03:59
So, it sounds like you should add a check to ensur
Shu Chen
2015/09/04 01:36:47
Is above check at line 2927 not enough?
palmer
2015/09/09 23:30:20
I'm sorry, I didn't see that check. Yes, it is goo
|
| + NSUInteger bytes_len = base::strict_cast<NSUInteger, size_t>( |
| + requested_range.length() * sizeof(base::char16)); |
|
palmer
2015/09/02 20:17:22
Could this multiplication result in integer overfl
Shu Chen
2015/09/03 15:07:32
It could, I've added the check.
|
| + base::scoped_nsobject<NSString> ns_string( |
| + [[NSString alloc] initWithBytes:bytes |
| + length:bytes_len |
| + encoding:NSUTF16LittleEndianStringEncoding]); |
| + return [[[NSAttributedString alloc] initWithString:ns_string] autorelease]; |
| } |
| - (NSInteger)conversationIdentifier { |