Commit 3c8c74c9 authored by kinaba@chromium.org's avatar kinaba@chromium.org

Pepper IME API for surrounding text retrieval.

IME benefits from knowing what portion of text is selected inside a text editing plugin.
This change is to implement a Pepper API for doing it. It consists of three API functions:

1. Browser asks plugins by PPP_TextInput_Dev::RequestSurroundingText() to send such info.
2. Plugin must reply the query by PPB_TextInput_Dev::UpdateSurroundingText().
3. Additionally, plugin notifies the browser by PPB_TextInput_Dev::SelectionChanged() that the selection is changed. Typically triggers the steps 1->2.

Intention of the API design is (1) to avoid synchronous IPC, and (2) to keep the room to implement it in an optimal and right way, that is, expensive send of selection text happens only when needed (= "IME requiring the info is on" + "selection indeed changed in the plugin"), though the current impl in the patch is not necessary like that (for sake of simplicity).

The changes in the API is in:
* ppapi/c/dev/ppb_text_input_dev.h
* ppapi/c/dev/ppp_text_input_dev.h

The browser side implementation mostly resides in:
* content/renderer/render_view_impl.cc
* content/renderer/pepper/pepper_plugin_delegate_impl.{h,cc}
* webkit/plugins/ppapi/ppapi_plugin_instance.{h,cc}

The other files are for wiring necessary cables.

BUG=101101
TEST=Manual: make ppapi_example_ime and run ./your/chrome --register-pepper-plugins=\ 
"/path/to/ppapi_example_ime.plugin;application/x-ppapi-example-ime" \
--ppapi-out-of-process \
file:///path/to/ppapi/examples/ime/ime.html 
Try some IME that supports reconversion (e.g., Google Japanese Input on Windows).

Review URL: http://codereview.chromium.org/8769003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126862 0039d316-1c4b-4281-b951-d872f2087c98
parent 8cdb650a
......@@ -415,6 +415,12 @@ void PepperPluginDelegateImpl::PluginRequestedCancelComposition(
render_view_->PpapiPluginCancelComposition();
}
void PepperPluginDelegateImpl::PluginSelectionChanged(
webkit::ppapi::PluginInstance* instance) {
if (focused_plugin_ == instance && render_view_)
render_view_->PpapiPluginSelectionChanged();
}
void PepperPluginDelegateImpl::OnImeSetComposition(
const string16& text,
const std::vector<WebKit::WebCompositionUnderline>& underlines,
......@@ -486,6 +492,13 @@ ui::TextInputType PepperPluginDelegateImpl::GetTextInputType() const {
return focused_plugin_->text_input_type();
}
void PepperPluginDelegateImpl::GetSurroundingText(string16* text,
ui::Range* range) const {
if (!focused_plugin_)
return;
return focused_plugin_->GetSurroundingText(text, range);
}
bool PepperPluginDelegateImpl::IsPluginAcceptingCompositionEvents() const {
if (!focused_plugin_)
return false;
......
......@@ -47,6 +47,10 @@ namespace IPC {
struct ChannelHandle;
}
namespace ui {
class Range;
}
namespace webkit {
struct WebPluginInfo;
namespace ppapi {
......@@ -130,6 +134,7 @@ class PepperPluginDelegateImpl
ui::TextInputType GetTextInputType() const;
bool IsPluginAcceptingCompositionEvents() const;
bool CanComposeInline() const;
void GetSurroundingText(string16* text, ui::Range* range) const;
// IME events.
void OnImeSetComposition(
......@@ -151,6 +156,8 @@ class PepperPluginDelegateImpl
webkit::ppapi::PluginInstance* instance) OVERRIDE;
virtual void PluginRequestedCancelComposition(
webkit::ppapi::PluginInstance* instance) OVERRIDE;
virtual void PluginSelectionChanged(
webkit::ppapi::PluginInstance* instance) OVERRIDE;
virtual void PluginCrashed(webkit::ppapi::PluginInstance* instance) OVERRIDE;
virtual void InstanceCreated(
webkit::ppapi::PluginInstance* instance) OVERRIDE;
......
......@@ -3650,34 +3650,42 @@ void RenderViewImpl::SyncSelectionIfRequired() {
if (!frame)
return;
size_t location, length;
if (!webview()->caretOrSelectionRange(&location, &length))
return;
string16 text;
size_t offset;
ui::Range range(location, location + length);
if (webview()->textInputType() != WebKit::WebTextInputTypeNone) {
// If current focused element is editable, we will send 100 more chars
// before and after selection. It is for input method surrounding text
// feature.
if (location > kExtraCharsBeforeAndAfterSelection)
offset = location - kExtraCharsBeforeAndAfterSelection;
else
offset = 0;
length = location + length - offset + kExtraCharsBeforeAndAfterSelection;
WebRange webrange = WebRange::fromDocumentRange(frame, offset, length);
if (!webrange.isNull())
text = WebRange::fromDocumentRange(frame, offset, length).toPlainText();
ui::Range range;
if (pepper_delegate_.IsPluginFocused()) {
pepper_delegate_.GetSurroundingText(&text, &range);
offset = 0; // Pepper API does not support offset reporting.
// TODO(kinaba): cut as needed.
} else {
offset = location;
text = frame->selectionAsText();
// http://crbug.com/101435
// In some case, frame->selectionAsText() returned text's length is not
// equal to the length returned from webview()->caretOrSelectionRange().
// So we have to set the range according to text.length().
range.set_end(range.start() + text.length());
size_t location, length;
if (!webview()->caretOrSelectionRange(&location, &length))
return;
range = ui::Range(location, location + length);
if (webview()->textInputType() != WebKit::WebTextInputTypeNone) {
// If current focused element is editable, we will send 100 more chars
// before and after selection. It is for input method surrounding text
// feature.
if (location > kExtraCharsBeforeAndAfterSelection)
offset = location - kExtraCharsBeforeAndAfterSelection;
else
offset = 0;
length = location + length - offset + kExtraCharsBeforeAndAfterSelection;
WebRange webrange = WebRange::fromDocumentRange(frame, offset, length);
if (!webrange.isNull())
text = WebRange::fromDocumentRange(frame, offset, length).toPlainText();
} else {
offset = location;
text = frame->selectionAsText();
// http://crbug.com/101435
// In some case, frame->selectionAsText() returned text's length is not
// equal to the length returned from webview()->caretOrSelectionRange().
// So we have to set the range according to text.length().
range.set_end(range.start() + text.length());
}
}
// Sometimes we get repeated didChangeSelection calls from webkit when
......@@ -4767,6 +4775,10 @@ void RenderViewImpl::PpapiPluginCancelComposition() {
Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
}
void RenderViewImpl::PpapiPluginSelectionChanged() {
SyncSelectionIfRequired();
}
void RenderViewImpl::OnImeSetComposition(
const string16& text,
const std::vector<WebKit::WebCompositionUnderline>& underlines,
......
......@@ -271,6 +271,9 @@ class RenderViewImpl : public RenderWidget,
// Cancels current composition.
void PpapiPluginCancelComposition();
// Informs the render view that a PPAPI plugin has changed selection.
void PpapiPluginSelectionChanged();
// Retrieves the current caret position if a PPAPI plugin has focus.
bool GetPpapiPluginCaretBounds(gfx::Rect* rect);
......
......@@ -8,7 +8,8 @@
*/
label Chrome {
M16 = 0.1
M16 = 0.1,
M19 = 0.2
};
/**
......@@ -66,4 +67,43 @@ interface PPB_TextInput_Dev {
* Cancels the current composition in IME.
*/
void CancelCompositionText([in] PP_Instance instance);
/**
* In response to the <code>PPP_TextInput_Dev::RequestSurroundingText</code>
* call, informs the browser about the current text selection and surrounding
* text. <code>text</code> is a UTF-8 string that contains the current range
* of text selection in the plugin. <code>caret</code> is the byte-index of
* the caret poisition within <code>text</code>. <code>anchor</code> is the
* byte-index of the anchor position (i.e., if a range of text is selected,
* it is the other edge of selection diffrent from <code>caret</code>. If
* there are no selection, <code>anchor</code> is equal to <code>caret</code>.
*
* Typical use of this information in the browser is to enable "reconversion"
* features of IME that puts back the already committed text into the
* pre-commit composition state. Another use is to improve the precision
* of suggestion of IME by taking the context into account (e.g., if the caret
* looks to be on the begining of a sentense, suggest capital letters in a
* virtual keyboard).
*
* When the focus is not on text, call this function setting <code>text</code>
* to an empty string and <code>caret</code> and <code>anchor</code> to zero.
* Also, the plugin should send the empty text when it does not want to reveal
* the selection to IME (e.g., when the surrounding text is containing
* password text).
*/
[version=0.2]
void UpdateSurroundingText([in] PP_Instance instance,
[in] str_t text,
[in] uint32_t caret,
[in] uint32_t anchor);
/**
* Informs the browser when a range of text selection is changed in a plugin.
* When the browser needs to know the content of the updated selection, it
* pings back by <code>PPP_TextInput_Dev::RequestSurroundingText</code>. The
* plugin then should send the information with
* <code>UpdateSurroundingText</code>.
*/
[version=0.2]
void SelectionChanged([in] PP_Instance instance);
};
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* This file defines the <code>PPP_TextInput_Dev</code> interface.
*/
label Chrome {
M19 = 0.1
};
/**
* <code>PPP_TextInput_Dev</code> is a set of function pointers that the
* plugin has to implement to provide hints for text input system (IME).
*/
interface PPP_TextInput_Dev {
/**
* Requests the plugin to send back the text arround the current caret or
* selection by <code>PPB_TextInput_Dev::UpdateSurroundingText</code>.
* It is recommended to include the <code>desired_number_of_characters</code>
* characters before and after the selection, but not mandatory.
*/
void RequestSurroundingText([in] PP_Instance instance,
[in] uint32_t desired_number_of_characters);
};
......@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
/* From dev/ppb_text_input_dev.idl modified Wed Oct 5 14:06:02 2011. */
/* From dev/ppb_text_input_dev.idl modified Tue Mar 13 21:18:47 2012. */
#ifndef PPAPI_C_DEV_PPB_TEXT_INPUT_DEV_H_
#define PPAPI_C_DEV_PPB_TEXT_INPUT_DEV_H_
......@@ -16,7 +16,8 @@
#include "ppapi/c/pp_stdint.h"
#define PPB_TEXTINPUT_DEV_INTERFACE_0_1 "PPB_TextInput(Dev);0.1"
#define PPB_TEXTINPUT_DEV_INTERFACE PPB_TEXTINPUT_DEV_INTERFACE_0_1
#define PPB_TEXTINPUT_DEV_INTERFACE_0_2 "PPB_TextInput(Dev);0.2"
#define PPB_TEXTINPUT_DEV_INTERFACE PPB_TEXTINPUT_DEV_INTERFACE_0_2
/**
* @file
......@@ -66,7 +67,7 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_TextInput_Type, 4);
* to the browser about the text input status of plugins, and functions for
* controlling input method editors (IMEs).
*/
struct PPB_TextInput_Dev_0_1 {
struct PPB_TextInput_Dev_0_2 {
/**
* Informs the browser about the current text input mode of the plugin.
* Typical use of this information in the browser is to properly
......@@ -87,9 +88,52 @@ struct PPB_TextInput_Dev_0_1 {
* Cancels the current composition in IME.
*/
void (*CancelCompositionText)(PP_Instance instance);
/**
* In response to the <code>PPP_TextInput_Dev::RequestSurroundingText</code>
* call, informs the browser about the current text selection and surrounding
* text. <code>text</code> is a UTF-8 string that contains the current range
* of text selection in the plugin. <code>caret</code> is the byte-index of
* the caret poisition within <code>text</code>. <code>anchor</code> is the
* byte-index of the anchor position (i.e., if a range of text is selected,
* it is the other edge of selection diffrent from <code>caret</code>. If
* there are no selection, <code>anchor</code> is equal to <code>caret</code>.
*
* Typical use of this information in the browser is to enable "reconversion"
* features of IME that puts back the already committed text into the
* pre-commit composition state. Another use is to improve the precision
* of suggestion of IME by taking the context into account (e.g., if the caret
* looks to be on the begining of a sentense, suggest capital letters in a
* virtual keyboard).
*
* When the focus is not on text, call this function setting <code>text</code>
* to an empty string and <code>caret</code> and <code>anchor</code> to zero.
* Also, the plugin should send the empty text when it does not want to reveal
* the selection to IME (e.g., when the surrounding text is containing
* password text).
*/
void (*UpdateSurroundingText)(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor);
/**
* Informs the browser when a range of text selection is changed in a plugin.
* When the browser needs to know the content of the updated selection, it
* pings back by <code>PPP_TextInput_Dev::RequestSurroundingText</code>. The
* plugin then should send the information with
* <code>UpdateSurroundingText</code>.
*/
void (*SelectionChanged)(PP_Instance instance);
};
typedef struct PPB_TextInput_Dev_0_1 PPB_TextInput_Dev;
typedef struct PPB_TextInput_Dev_0_2 PPB_TextInput_Dev;
struct PPB_TextInput_Dev_0_1 {
void (*SetTextInputType)(PP_Instance instance, PP_TextInput_Type type);
void (*UpdateCaretPosition)(PP_Instance instance,
const struct PP_Rect* caret,
const struct PP_Rect* bounding_box);
void (*CancelCompositionText)(PP_Instance instance);
};
/**
* @}
*/
......
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* From dev/ppp_text_input_dev.idl modified Tue Mar 13 20:19:19 2012. */
#ifndef PPAPI_C_DEV_PPP_TEXT_INPUT_DEV_H_
#define PPAPI_C_DEV_PPP_TEXT_INPUT_DEV_H_
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_stdint.h"
#define PPP_TEXTINPUT_DEV_INTERFACE_0_1 "PPP_TextInput(Dev);0.1"
#define PPP_TEXTINPUT_DEV_INTERFACE PPP_TEXTINPUT_DEV_INTERFACE_0_1
/**
* @file
* This file defines the <code>PPP_TextInput_Dev</code> interface.
*/
/**
* @addtogroup Interfaces
* @{
*/
/**
* <code>PPP_TextInput_Dev</code> is a set of function pointers that the
* plugin has to implement to provide hints for text input system (IME).
*/
struct PPP_TextInput_Dev_0_1 {
/**
* Requests the plugin to send back the text arround the current caret or
* selection by <code>PPB_TextInput_Dev::UpdateSurroundingText</code>.
* It is recommended to include the <code>desired_number_of_characters</code>
* characters before and after the selection, but not mandatory.
*/
void (*RequestSurroundingText)(PP_Instance instance,
uint32_t desired_number_of_characters);
};
typedef struct PPP_TextInput_Dev_0_1 PPP_TextInput_Dev;
/**
* @}
*/
#endif /* PPAPI_C_DEV_PPP_TEXT_INPUT_DEV_H_ */
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/cpp/dev/text_input_dev.h"
#include "ppapi/c/dev/ppp_text_input_dev.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/rect.h"
......@@ -12,40 +14,95 @@ namespace pp {
namespace {
template <> const char* interface_name<PPB_TextInput_Dev>() {
return PPB_TEXTINPUT_DEV_INTERFACE;
static const char kPPPTextInputInterface[] = PPP_TEXTINPUT_DEV_INTERFACE;
void RequestSurroundingText(PP_Instance instance,
uint32_t desired_number_of_characters) {
void* object = Instance::GetPerInstanceObject(instance,
kPPPTextInputInterface);
if (!object)
return;
static_cast<TextInput_Dev*>(object)->RequestSurroundingText(
desired_number_of_characters);
}
const PPP_TextInput_Dev ppp_text_input = {
&RequestSurroundingText
};
template <> const char* interface_name<PPB_TextInput_Dev_0_2>() {
return PPB_TEXTINPUT_DEV_INTERFACE_0_2;
}
template <> const char* interface_name<PPB_TextInput_Dev_0_1>() {
return PPB_TEXTINPUT_DEV_INTERFACE_0_1;
}
} // namespace
TextInput_Dev::TextInput_Dev(const InstanceHandle& instance)
TextInput_Dev::TextInput_Dev(Instance* instance)
: instance_(instance) {
Module::Get()->AddPluginInterface(kPPPTextInputInterface,
&ppp_text_input);
instance->AddPerInstanceObject(kPPPTextInputInterface, this);
}
TextInput_Dev::~TextInput_Dev() {
Instance::RemovePerInstanceObject(instance_, kPPPTextInputInterface, this);
}
void TextInput_Dev::RequestSurroundingText(uint32_t) {
// Default implementation. Send a null range.
UpdateSurroundingText("", 0, 0);
}
void TextInput_Dev::SetTextInputType(PP_TextInput_Type type) {
if (!has_interface<PPB_TextInput_Dev>())
return;
get_interface<PPB_TextInput_Dev>()->SetTextInputType(
instance_.pp_instance(), type);
if (has_interface<PPB_TextInput_Dev_0_2>()) {
get_interface<PPB_TextInput_Dev_0_2>()->SetTextInputType(
instance_.pp_instance(), type);
} else if (has_interface<PPB_TextInput_Dev_0_1>()) {
get_interface<PPB_TextInput_Dev_0_1>()->SetTextInputType(
instance_.pp_instance(), type);
}
}
void TextInput_Dev::UpdateCaretPosition(const Rect& caret,
const Rect& bounding_box) {
if (!has_interface<PPB_TextInput_Dev>())
return;
get_interface<PPB_TextInput_Dev>()->UpdateCaretPosition(
instance_.pp_instance(), &caret.pp_rect(), &bounding_box.pp_rect());
if (has_interface<PPB_TextInput_Dev_0_2>()) {
get_interface<PPB_TextInput_Dev_0_2>()->UpdateCaretPosition(
instance_.pp_instance(), &caret.pp_rect(), &bounding_box.pp_rect());
} else if (has_interface<PPB_TextInput_Dev_0_1>()) {
get_interface<PPB_TextInput_Dev_0_1>()->UpdateCaretPosition(
instance_.pp_instance(), &caret.pp_rect(), &bounding_box.pp_rect());
}
}
void TextInput_Dev::CancelCompositionText() {
if (!has_interface<PPB_TextInput_Dev>())
return;
get_interface<PPB_TextInput_Dev>()->CancelCompositionText(
instance_.pp_instance());
if (has_interface<PPB_TextInput_Dev_0_2>()) {
get_interface<PPB_TextInput_Dev_0_2>()->CancelCompositionText(
instance_.pp_instance());
} else if (has_interface<PPB_TextInput_Dev_0_1>()) {
get_interface<PPB_TextInput_Dev_0_1>()->CancelCompositionText(
instance_.pp_instance());
}
}
void TextInput_Dev::SelectionChanged() {
if (has_interface<PPB_TextInput_Dev_0_2>()) {
get_interface<PPB_TextInput_Dev_0_2>()->SelectionChanged(
instance_.pp_instance());
}
}
void TextInput_Dev::UpdateSurroundingText(const std::string& text,
uint32_t caret,
uint32_t anchor) {
if (has_interface<PPB_TextInput_Dev_0_2>()) {
get_interface<PPB_TextInput_Dev_0_2>()->UpdateSurroundingText(
instance_.pp_instance(), text.c_str(), caret, anchor);
}
}
} // namespace pp
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PPAPI_CPP_DEV_TEXT_INPUT_DEV_H_
#define PPAPI_CPP_DEV_TEXT_INPUT_DEV_H_
#include <string>
#include "ppapi/c/dev/ppb_text_input_dev.h"
#include "ppapi/cpp/instance_handle.h"
/// @file
/// This file defines the API for controlling text input methods.
namespace pp {
class Rect;
class Instance;
// This class allows you to associate the PPP_TextInput_Dev and
// PPB_TextInput_Dev C-based interfaces with an object. It associates itself
// with the given instance, and registers as the global handler for handling the
// PPP_TextInput_Dev interface that the browser calls.
//
// You would typically use this either via inheritance on your instance:
// class MyInstance : public pp::Instance, public pp::TextInput_Dev {
// MyInstance() : pp::TextInput_Dev(this) {
// }
// ...
// };
//
// or by composition:
// class MyTextInput : public pp::TextInput_Dev {
// ...
// };
//
// class MyInstance : public pp::Instance {
// MyInstance() : text_input_(this) {
// }
//
// MyTextInput text_input_;
// };
class TextInput_Dev {
public:
explicit TextInput_Dev(const InstanceHandle& instance);
explicit TextInput_Dev(Instance* instance);
virtual ~TextInput_Dev();
virtual void RequestSurroundingText(uint32_t desired_number_of_characters);
void SetTextInputType(PP_TextInput_Type type);
void UpdateCaretPosition(const Rect& caret, const Rect& bounding_box);
void CancelCompositionText();
void SelectionChanged();
void UpdateSurroundingText(const std::string& text,
uint32_t caret, uint32_t anchor);
private:
InstanceHandle instance_;
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -92,15 +92,17 @@ class TextFieldStatusHandler {
virtual ~TextFieldStatusHandler() {}
virtual void FocusIn(const pp::Rect& caret, const pp::Rect& bounding_box) {}
virtual void FocusOut() {}
virtual void UpdateSelection(const std::string& text) {}
};
class TextFieldStatusNotifyingHanlder : public TextFieldStatusHandler {
class TextFieldStatusNotifyingHandler : public TextFieldStatusHandler {
public:
explicit TextFieldStatusNotifyingHanlder(pp::Instance* instance)
: instance_(instance),
textinput_control_(instance) {}
explicit TextFieldStatusNotifyingHandler(pp::Instance* instance)
: textinput_control_(instance) {
}
protected:
// Implement TextFieldStatusHandler.
virtual void FocusIn(const pp::Rect& caret, const pp::Rect& bounding_box) {
textinput_control_.SetTextInputType(PP_TEXTINPUT_TYPE_TEXT);
textinput_control_.UpdateCaretPosition(caret, bounding_box);
......@@ -109,10 +111,22 @@ class TextFieldStatusNotifyingHanlder : public TextFieldStatusHandler {
textinput_control_.CancelCompositionText();
textinput_control_.SetTextInputType(PP_TEXTINPUT_TYPE_NONE);
}
virtual void UpdateSelection(const std::string& text) {
textinput_control_.SetSelectionText(text);
textinput_control_.SelectionChanged();
}
private:
pp::Instance* instance_;
pp::TextInput_Dev textinput_control_;
class MyTextInput : public pp::TextInput_Dev {
public:
MyTextInput(pp::Instance* instance) : pp::TextInput_Dev(instance) {}
virtual void RequestSurroundingText(uint32_t characters) {
UpdateSurroundingText(selection_text_, 0, selection_text_.size());
}
void SetSelectionText(const std::string& text) { selection_text_ = text; }
std::string selection_text_;
};
MyTextInput textinput_control_;
};
// Hand-made text field for demonstrating text input API.
......@@ -361,6 +375,9 @@ class MyTextField {
int px = font_.MeasureSimpleText(str);
pp::Rect caret(area_.x() + px, area_.y(), 0, area_.height() + 2);
status_handler_->FocusIn(caret, area_);
status_handler_->UpdateSelection(
utf8_text_.substr(SelectionLeft(),
SelectionRight() - SelectionLeft()));
}
}
size_t SelectionLeft() const {
......@@ -430,14 +447,14 @@ class MyInstance : public pp::Instance {
// say, show virtual keyboards or IMEs only at appropriate timing
// that the plugin does need to accept text input.
delete status_handler_;
status_handler_ = new TextFieldStatusNotifyingHanlder(this);
status_handler_ = new TextFieldStatusNotifyingHandler(this);
} else if (argv[i] == std::string("full")) {
// Demonstrating the behavior of plugins fully supporting IME.
//
// It notifies updates of caret positions to the browser,
// and handles all text input events by itself.
delete status_handler_;
status_handler_ = new TextFieldStatusNotifyingHanlder(this);
status_handler_ = new TextFieldStatusNotifyingHandler(this);
RequestInputEvents(PP_INPUTEVENT_CLASS_IME);
}
break;
......
......@@ -141,6 +141,8 @@
'proxy/ppp_mouse_lock_proxy.h',
'proxy/ppp_printing_proxy.cc',
'proxy/ppp_printing_proxy.h',
'proxy/ppp_text_input_proxy.cc',
'proxy/ppp_text_input_proxy.h',
'proxy/ppp_video_decoder_proxy.cc',
'proxy/ppp_video_decoder_proxy.h',
'proxy/proxy_channel.cc',
......
......@@ -72,6 +72,7 @@
'c/dev/ppb_resource_array_dev.h',
'c/dev/ppb_scrollbar_dev.h',
'c/dev/ppb_testing_dev.h',
'c/dev/ppb_text_input_dev.h',
'c/dev/ppb_url_util_dev.h',
'c/dev/ppb_video_decoder_dev.h',
'c/dev/ppb_widget_dev.h',
......@@ -81,7 +82,7 @@
'c/dev/ppp_network_state_dev.h',
'c/dev/ppp_scrollbar_dev.h',
'c/dev/ppp_selection_dev.h',
'c/dev/ppb_text_input_dev.h',
'c/dev/ppp_text_input_dev.h',
'c/dev/ppp_video_decoder_dev.h',
'c/dev/ppp_widget_dev.h',
'c/dev/ppp_zoom_dev.h',
......
......@@ -109,6 +109,7 @@
#include "ppapi/proxy/ppp_messaging_proxy.h"
#include "ppapi/proxy/ppp_mouse_lock_proxy.h"
#include "ppapi/proxy/ppp_printing_proxy.h"
#include "ppapi/proxy/ppp_text_input_proxy.h"
#include "ppapi/proxy/ppp_video_decoder_proxy.h"
#include "ppapi/proxy/resource_creation_proxy.h"
#include "ppapi/shared_impl/ppb_opengles2_shared.h"
......@@ -222,6 +223,9 @@ InterfaceList::InterfaceList() {
AddProxy(API_ID_PPP_PRINTING, &ProxyFactory<PPP_Printing_Proxy>);
AddPPP(PPP_PRINTING_DEV_INTERFACE, API_ID_PPP_PRINTING,
PPP_Printing_Proxy::GetProxyInterface());
AddProxy(API_ID_PPP_TEXT_INPUT, &ProxyFactory<PPP_TextInput_Proxy>);
AddPPP(PPP_TEXTINPUT_DEV_INTERFACE, API_ID_PPP_TEXT_INPUT,
PPP_TextInput_Proxy::GetProxyInterface());
// Old-style GetInfo PPP interfaces.
// Do not add more stuff here, they should be added to interface_list*.h
......
......@@ -513,6 +513,11 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiMsg_PPPPrinting_IsScalingDisabled,
PP_Instance /* instance */,
bool /* result */)
// PPP_TextInput.
IPC_MESSAGE_ROUTED2(PpapiMsg_PPPTextInput_RequestSurroundingText,
PP_Instance /* instance */,
uint32_t /* desired_number_of_characters */)
// PPB_URLLoader
// (Messages from browser to plugin to notify it of changes in state.)
IPC_MESSAGE_ROUTED1(
......@@ -943,6 +948,13 @@ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBTextInput_UpdateCaretPosition,
PP_Rect /* bounding_box */)
IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBTextInput_CancelCompositionText,
PP_Instance /* instance */)
IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBTextInput_SelectionChanged,
PP_Instance /* instance */)
IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBTextInput_UpdateSurroundingText,
PP_Instance /* instance */,
std::string /* text */,
uint32_t /* caret */,
uint32_t /* anchor */)
// PPB_URLLoader.
IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_Create,
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -42,6 +42,19 @@ void PPB_TextInput_Proxy::CancelCompositionText(PP_Instance instance) {
API_ID_PPB_TEXT_INPUT, instance));
}
void PPB_TextInput_Proxy::SelectionChanged(PP_Instance instance) {
dispatcher()->Send(new PpapiHostMsg_PPBTextInput_SelectionChanged(
API_ID_PPB_TEXT_INPUT, instance));
}
void PPB_TextInput_Proxy::UpdateSurroundingText(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor) {
dispatcher()->Send(new PpapiHostMsg_PPBTextInput_UpdateSurroundingText(
API_ID_PPB_TEXT_INPUT, instance, text, caret, anchor));
}
bool PPB_TextInput_Proxy::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PPB_TextInput_Proxy, msg)
......@@ -51,6 +64,10 @@ bool PPB_TextInput_Proxy::OnMessageReceived(const IPC::Message& msg) {
OnMsgUpdateCaretPosition)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTextInput_CancelCompositionText,
OnMsgCancelCompositionText)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTextInput_SelectionChanged,
OnMsgSelectionChanged)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTextInput_UpdateSurroundingText,
OnMsgUpdateSurroundingText)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
......@@ -80,5 +97,23 @@ void PPB_TextInput_Proxy::OnMsgCancelCompositionText(PP_Instance instance) {
enter.functions()->CancelCompositionText(instance);
}
void PPB_TextInput_Proxy::OnMsgSelectionChanged(PP_Instance instance) {
ppapi::thunk::EnterFunctionNoLock<PPB_TextInput_FunctionAPI> enter(instance,
true);
if (enter.succeeded())
enter.functions()->SelectionChanged(instance);
}
void PPB_TextInput_Proxy::OnMsgUpdateSurroundingText(PP_Instance instance,
const std::string& text,
uint32_t caret,
uint32_t anchor) {
ppapi::thunk::EnterFunctionNoLock<PPB_TextInput_FunctionAPI> enter(instance,
true);
if (enter.succeeded())
enter.functions()->UpdateSurroundingText(instance,
text.c_str(), caret, anchor);
}
} // namespace proxy
} // namespace ppapi
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PPAPI_PROXY_PPB_TEXT_INPUT_PROXY_H_
#define PPAPI_PROXY_PPB_TEXT_INPUT_PROXY_H_
#include <string>
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/proxy/interface_proxy.h"
......@@ -31,6 +33,11 @@ class PPB_TextInput_Proxy
const PP_Rect& caret,
const PP_Rect& bounding_box) OVERRIDE;
virtual void CancelCompositionText(PP_Instance instance) OVERRIDE;
virtual void SelectionChanged(PP_Instance instance) OVERRIDE;
virtual void UpdateSurroundingText(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor) OVERRIDE;
// InterfaceProxy implementation.
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
......@@ -44,6 +51,11 @@ class PPB_TextInput_Proxy
PP_Rect caret,
PP_Rect bounding_box);
void OnMsgCancelCompositionText(PP_Instance instance);
void OnMsgSelectionChanged(PP_Instance instance);
void OnMsgUpdateSurroundingText(PP_Instance instance,
const std::string& text,
uint32_t caret,
uint32_t anchor);
DISALLOW_COPY_AND_ASSIGN(PPB_TextInput_Proxy);
};
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/proxy/ppp_text_input_proxy.h"
#include "ppapi/c/dev/ppp_text_input_dev.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/proxy_lock.h"
namespace ppapi {
namespace proxy {
namespace {
void RequestSurroundingText(PP_Instance instance,
uint32_t desired_number_of_characters) {
proxy::HostDispatcher* dispatcher =
proxy::HostDispatcher::GetForInstance(instance);
if (!dispatcher) {
// The dispatcher should always be valid.
NOTREACHED();
return;
}
dispatcher->Send(new PpapiMsg_PPPTextInput_RequestSurroundingText(
API_ID_PPP_TEXT_INPUT, instance, desired_number_of_characters));
}
const PPP_TextInput_Dev g_ppp_text_input_thunk = {
&RequestSurroundingText
};
} // namespace
// static
const PPP_TextInput_Dev* PPP_TextInput_Proxy::GetProxyInterface() {
return &g_ppp_text_input_thunk;
}
PPP_TextInput_Proxy::PPP_TextInput_Proxy(Dispatcher* dispatcher)
: InterfaceProxy(dispatcher),
ppp_text_input_impl_(NULL) {
if (dispatcher->IsPlugin()) {
ppp_text_input_impl_ = static_cast<const PPP_TextInput_Dev*>(
dispatcher->local_get_interface()(PPP_TEXTINPUT_DEV_INTERFACE));
}
}
PPP_TextInput_Proxy::~PPP_TextInput_Proxy() {
}
bool PPP_TextInput_Proxy::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PPP_TextInput_Proxy, msg)
IPC_MESSAGE_HANDLER(PpapiMsg_PPPTextInput_RequestSurroundingText,
OnMsgRequestSurroundingText)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void PPP_TextInput_Proxy::OnMsgRequestSurroundingText(
PP_Instance instance, uint32_t desired_number_of_characters) {
if (ppp_text_input_impl_) {
CallWhileUnlocked(ppp_text_input_impl_->RequestSurroundingText,
instance, desired_number_of_characters);
}
}
} // namespace proxy
} // namespace ppapi
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PPAPI_PROXY_PPP_TEXT_INPUT_PROXY_H_
#define PPAPI_PROXY_PPP_TEXT_INPUT_PROXY_H_
#include "ppapi/c/dev/ppp_text_input_dev.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/interface_proxy.h"
namespace ppapi {
namespace proxy {
class PPP_TextInput_Proxy : public InterfaceProxy {
public:
PPP_TextInput_Proxy(Dispatcher* dispatcher);
virtual ~PPP_TextInput_Proxy();
static const PPP_TextInput_Dev* GetProxyInterface();
// InterfaceProxy implementation.
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
private:
// Message handlers.
void OnMsgRequestSurroundingText(PP_Instance instance,
uint32_t desired_number_of_characters);
// When this proxy is in the plugin side, this value caches the interface
// pointer so we don't have to retrieve it from the dispatcher each time.
// In the host, this value is always NULL.
const PPP_TextInput_Dev* ppp_text_input_impl_;
DISALLOW_COPY_AND_ASSIGN(PPP_TextInput_Proxy);
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_PPP_TEXT_INPUT_PROXY_H_
......@@ -60,6 +60,7 @@ enum ApiID {
API_ID_PPP_MESSAGING,
API_ID_PPP_MOUSE_LOCK,
API_ID_PPP_PRINTING,
API_ID_PPP_TEXT_INPUT,
API_ID_PPP_VIDEO_CAPTURE_DEV,
API_ID_PPP_VIDEO_DECODER_DEV,
......
......@@ -56,6 +56,8 @@ UNPROXIED_IFACE(PPB_Scrollbar, PPB_SCROLLBAR_DEV_INTERFACE_0_5,
PPB_Scrollbar_Dev_0_5)
PROXIED_IFACE(PPB_TextInput, PPB_TEXTINPUT_DEV_INTERFACE_0_1,
PPB_TextInput_Dev_0_1)
PROXIED_IFACE(PPB_TextInput, PPB_TEXTINPUT_DEV_INTERFACE_0_2,
PPB_TextInput_Dev_0_2)
UNPROXIED_IFACE(PPB_Transport, PPB_TRANSPORT_DEV_INTERFACE_0_7,
PPB_Transport_Dev_0_7)
PROXIED_IFACE(PPB_VideoCapture, PPB_VIDEOCAPTURE_DEV_INTERFACE_0_1,
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -21,6 +21,11 @@ class PPB_TextInput_FunctionAPI {
const PP_Rect& caret,
const PP_Rect& bounding_box) = 0;
virtual void CancelCompositionText(PP_Instance instance) = 0;
virtual void SelectionChanged(PP_Instance instance) = 0;
virtual void UpdateSurroundingText(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor) = 0;
static const ApiID kApiID = API_ID_PPB_TEXT_INPUT;
};
......
......@@ -31,16 +31,41 @@ void CancelCompositionText(PP_Instance instance) {
enter.functions()->CancelCompositionText(instance);
}
const PPB_TextInput_Dev g_ppb_textinput_thunk = {
void UpdateSurroundingText(PP_Instance instance, const char* text,
uint32_t caret, uint32_t anchor) {
EnterFunction<PPB_TextInput_FunctionAPI> enter(instance, true);
if (enter.succeeded())
enter.functions()->UpdateSurroundingText(instance, text, caret, anchor);
}
void SelectionChanged(PP_Instance instance) {
EnterFunction<PPB_TextInput_FunctionAPI> enter(instance, true);
if (enter.succeeded())
enter.functions()->SelectionChanged(instance);
}
const PPB_TextInput_Dev_0_1 g_ppb_textinput_0_1_thunk = {
&SetTextInputType,
&UpdateCaretPosition,
&CancelCompositionText,
};
const PPB_TextInput_Dev g_ppb_textinput_0_2_thunk = {
&SetTextInputType,
&UpdateCaretPosition,
&CancelCompositionText,
&UpdateSurroundingText,
&SelectionChanged,
};
} // namespace
const PPB_TextInput_Dev_0_1* GetPPB_TextInput_Dev_0_1_Thunk() {
return &g_ppb_textinput_thunk;
return &g_ppb_textinput_0_1_thunk;
}
const PPB_TextInput_Dev_0_2* GetPPB_TextInput_Dev_0_2_Thunk() {
return &g_ppb_textinput_0_2_thunk;
}
} // namespace thunk
......
......@@ -5,4 +5,5 @@ include_rules = [
"+printing",
"+media/video",
"+ui/base/ime",
"+ui/base/range",
]
......@@ -34,6 +34,9 @@ void MockPluginDelegate::PluginRequestedCancelComposition(
PluginInstance* instance) {
}
void MockPluginDelegate::PluginSelectionChanged(PluginInstance* instance) {
}
void MockPluginDelegate::PluginCrashed(PluginInstance* instance) {
}
......
......@@ -22,6 +22,7 @@ class MockPluginDelegate : public PluginDelegate {
virtual void PluginTextInputTypeChanged(PluginInstance* instance);
virtual void PluginCaretPositionChanged(PluginInstance* instance);
virtual void PluginRequestedCancelComposition(PluginInstance* instance);
virtual void PluginSelectionChanged(PluginInstance* instance);
virtual void PluginCrashed(PluginInstance* instance);
virtual void InstanceCreated(PluginInstance* instance);
virtual void InstanceDeleted(PluginInstance* instance);
......
......@@ -297,6 +297,9 @@ class PluginDelegate {
// Notification that the plugin requested to cancel the current composition.
virtual void PluginRequestedCancelComposition(
webkit::ppapi::PluginInstance* instance) = 0;
// Notification that the text selection in the given plugin is changed.
virtual void PluginSelectionChanged(
webkit::ppapi::PluginInstance* instance) = 0;
// Notification that the given plugin has crashed. When a plugin crashes, all
// instances associated with that plugin will notify that they've crashed via
......
......@@ -17,6 +17,7 @@
#include "ppapi/c/dev/ppb_zoom_dev.h"
#include "ppapi/c/dev/ppp_find_dev.h"
#include "ppapi/c/dev/ppp_selection_dev.h"
#include "ppapi/c/dev/ppp_text_input_dev.h"
#include "ppapi/c/dev/ppp_zoom_dev.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/ppb_audio_config.h"
......@@ -55,6 +56,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/range/range.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/event_conversion.h"
#include "webkit/plugins/ppapi/fullscreen_container.h"
......@@ -155,6 +157,11 @@ namespace {
// that they don't accept texts.
const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT;
// The length of text to request as a surrounding context of selection.
// For now, the value is copied from the one with render_view_impl.cc.
// TODO(kinaba) implement a way to dynamically sync the requirement.
static const size_t kExtraCharsBeforeAndAfterSelection = 100;
#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \
COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \
== static_cast<int>(np_name), \
......@@ -286,6 +293,7 @@ PluginInstance::PluginInstance(
plugin_private_interface_(NULL),
plugin_pdf_interface_(NULL),
plugin_selection_interface_(NULL),
plugin_textinput_interface_(NULL),
plugin_zoom_interface_(NULL),
checked_for_plugin_input_event_interface_(false),
checked_for_plugin_messaging_interface_(false),
......@@ -303,6 +311,8 @@ PluginInstance::PluginInstance(
text_input_caret_(0, 0, 0, 0),
text_input_caret_bounds_(0, 0, 0, 0),
text_input_caret_set_(false),
selection_caret_(0),
selection_anchor_(0),
lock_mouse_callback_(PP_BlockUntilComplete()),
pending_user_gesture_(0.0) {
pp_instance_ = HostGlobals::Get()->AddInstance(this);
......@@ -636,6 +646,31 @@ void PluginInstance::SetTextInputType(ui::TextInputType type) {
delegate()->PluginTextInputTypeChanged(this);
}
void PluginInstance::SelectionChanged() {
// TODO(kinaba): currently the browser always calls RequestSurroundingText.
// It can be optimized so that it won't call it back until the information
// is really needed.
RequestSurroundingText(kExtraCharsBeforeAndAfterSelection);
}
void PluginInstance::UpdateSurroundingText(const std::string& text,
size_t caret, size_t anchor) {
surrounding_text_ = text;
selection_caret_ = caret;
selection_anchor_ = anchor;
delegate()->PluginSelectionChanged(this);
}
void PluginInstance::GetSurroundingText(string16* text,
ui::Range* range) const {
std::vector<size_t> offsets;
offsets.push_back(selection_anchor_);
offsets.push_back(selection_caret_);
*text = UTF8ToUTF16AndAdjustOffsets(surrounding_text_, &offsets);
range->set_start(offsets[0] == string16::npos ? text->size() : offsets[0]);
range->set_end(offsets[1] == string16::npos ? text->size() : offsets[1]);
}
bool PluginInstance::IsPluginAcceptingCompositionEvents() const {
return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) ||
(input_event_mask_ & PP_INPUTEVENT_CLASS_IME);
......@@ -904,6 +939,17 @@ string16 PluginInstance::GetLinkAtPosition(const gfx::Point& point) {
return link;
}
bool PluginInstance::RequestSurroundingText(
size_t desired_number_of_characters) {
// Keep a reference on the stack. See NOTE above.
scoped_refptr<PluginInstance> ref(this);
if (!LoadTextInputInterface())
return false;
plugin_textinput_interface_->RequestSurroundingText(
pp_instance(), desired_number_of_characters);
return true;
}
void PluginInstance::Zoom(double factor, bool text_only) {
// Keep a reference on the stack. See NOTE above.
scoped_refptr<PluginInstance> ref(this);
......@@ -1020,6 +1066,16 @@ bool PluginInstance::LoadSelectionInterface() {
return !!plugin_selection_interface_;
}
bool PluginInstance::LoadTextInputInterface() {
if (!plugin_textinput_interface_) {
plugin_textinput_interface_ =
static_cast<const PPP_TextInput_Dev*>(module_->GetPluginInterface(
PPP_TEXTINPUT_DEV_INTERFACE));
}
return !!plugin_textinput_interface_;
}
bool PluginInstance::LoadZoomInterface() {
if (!plugin_zoom_interface_) {
plugin_zoom_interface_ =
......
......@@ -19,6 +19,7 @@
#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/dev/ppp_find_dev.h"
#include "ppapi/c/dev/ppp_selection_dev.h"
#include "ppapi/c/dev/ppp_text_input_dev.h"
#include "ppapi/c/dev/ppp_zoom_dev.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_instance.h"
......@@ -65,6 +66,10 @@ struct PPP_Instance_Combined;
class Resource;
}
namespace ui {
class Range;
}
namespace webkit {
namespace ppapi {
......@@ -181,11 +186,15 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
void UpdateCaretPosition(const gfx::Rect& caret,
const gfx::Rect& bounding_box);
void SetTextInputType(ui::TextInputType type);
void SelectionChanged();
void UpdateSurroundingText(const std::string& text,
size_t caret, size_t anchor);
// Gets the current text input status.
ui::TextInputType text_input_type() const { return text_input_type_; }
gfx::Rect GetCaretBounds() const;
bool IsPluginAcceptingCompositionEvents() const;
void GetSurroundingText(string16* text, ui::Range* range) const;
// Notifications about focus changes, see has_webkit_focus_ below.
void SetWebKitFocus(bool has_focus);
......@@ -217,6 +226,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
string16 GetSelectedText(bool html);
string16 GetLinkAtPosition(const gfx::Point& point);
bool RequestSurroundingText(size_t desired_number_of_characters);
void Zoom(double factor, bool text_only);
bool StartFind(const string16& search_text,
bool case_sensitive,
......@@ -402,6 +412,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
bool LoadPrintInterface();
bool LoadPrivateInterface();
bool LoadSelectionInterface();
bool LoadTextInputInterface();
bool LoadZoomInterface();
// Determines if we think the plugin has focus, both content area and webkit
......@@ -530,6 +541,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
const PPP_Instance_Private* plugin_private_interface_;
const PPP_Pdf* plugin_pdf_interface_;
const PPP_Selection_Dev* plugin_selection_interface_;
const PPP_TextInput_Dev* plugin_textinput_interface_;
const PPP_Zoom_Dev* plugin_zoom_interface_;
// Flags indicating whether we have asked this plugin instance for the
......@@ -624,6 +636,11 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
gfx::Rect text_input_caret_bounds_;
bool text_input_caret_set_;
// Text selection status.
std::string surrounding_text_;
size_t selection_caret_;
size_t selection_anchor_;
PP_CompletionCallback lock_mouse_callback_;
// Track pending user gestures so out-of-process plugins can respond to
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -61,5 +61,17 @@ void PPB_TextInput_Impl::CancelCompositionText(PP_Instance instance) {
instance_->delegate()->PluginRequestedCancelComposition(instance_);
}
void PPB_TextInput_Impl::SelectionChanged(PP_Instance instance) {
instance_->SelectionChanged();
}
void PPB_TextInput_Impl::UpdateSurroundingText(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor) {
instance_->UpdateSurroundingText(text, caret, anchor);
}
} // namespace ppapi
} // namespace webkit
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -32,6 +32,11 @@ class PPB_TextInput_Impl
const PP_Rect& caret,
const PP_Rect& bounding_box) OVERRIDE;
virtual void CancelCompositionText(PP_Instance instance) OVERRIDE;
virtual void SelectionChanged(PP_Instance instance) OVERRIDE;
virtual void UpdateSurroundingText(PP_Instance instance,
const char* text,
uint32_t caret,
uint32_t anchor) OVERRIDE;
private:
PluginInstance* instance_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment